This is the mail archive of the java-patches@sources.redhat.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: More Java 2 compatibility


I'm checking this in.

This is another patch that adds some missing Java 2 methods.

The String.toUpperCase and String.toLowerCase changes are a bit odd.
The 1.2 online docs are apparently contradictory, and the
implementation I have doesn't agree with them.  Nevertheless I
followed them.  We can change this later if need be.

2000-11-17  Tom Tromey  <tromey@cygnus.com>

	* java/lang/natString.cc: Include Locale.h.
	(toUpperCase): Added `locale' argument.  Handle locale
	sensitivity.
	(toLowerCase): Added `locale' argument.  Handle locale
	sensitivity.
	(ESSET, CAPITAL_S, SMALL_I, CAPITAL_I_WITH_DOT, SMALL_DOTLESS_I,
	CAPITAL_I): New defines.
	* java/lang/String.java (CASE_INSENSITIVE_ORDER): Now public and
	final.
	Import Locale.
	(toUpperCase, toLowerCase): New methods.  Variants which accept
	locale now native.

	* java/lang/ExceptionInInitializerError.java (printStackTrace):
	New methods.

	* java/util/PropertyPermission.java: Re-merged from Classpath.

	* java/text/RuleBasedCollator.java (getCollationElementIterator):
	New method.
	* java/text/StringCharacterIterator.java: Reindented.
	(setText): New method.

Tom

Index: java/util/PropertyPermission.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/util/PropertyPermission.java,v
retrieving revision 1.1
diff -u -r1.1 PropertyPermission.java
--- PropertyPermission.java	2000/08/21 06:05:19	1.1
+++ PropertyPermission.java	2000/11/18 02:22:37
@@ -1,5 +1,5 @@
 /* java.util.PropertyPermission
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -7,7 +7,7 @@
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
- 
+
 GNU Classpath is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
@@ -68,13 +68,13 @@
 
   private static final long serialVersionUID = 885438825399942851L;
 
-  private static final int READ  = 1;
+  private static final int READ = 1;
   private static final int WRITE = 2;
   private transient int actions;
 
-  private static String actionStrings[] = 
-  { 
-    "", "read", "write", "read,write" 
+  private static final String actionStrings[] =
+  {
+    "", "read", "write", "read,write"
   };
 
   /**
@@ -109,7 +109,7 @@
 	else if ("write".equals(anAction))
 	  this.actions |= WRITE;
 	else
-	  throw new IllegalArgumentException("illegal action "+anAction);
+	  throw new IllegalArgumentException("illegal action " + anAction);
       }
   }
 
@@ -127,7 +127,7 @@
   {
     if (!(p instanceof PropertyPermission))
       return false;
-    
+
     // We have to check the actions.
     PropertyPermission pp = (PropertyPermission) p;
     if ((pp.actions & ~actions) != 0)
@@ -151,10 +151,24 @@
   }
 
   /**
+   * Check to see whether this object is the same as another
+   * PropertyPermission object.
+   *
+   * @param obj The other object
+   */
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof PropertyPermission))
+      return false;
+    PropertyPermission p = (PropertyPermission) obj;
+    return actions == p.actions && super.equals (p);
+  }
+
+  /**
    * Reads an object from the stream. This converts the external to the
    * internal representation.
    */
-  private void readObject(ObjectInputStream s) 
+  private void readObject(ObjectInputStream s)
     throws IOException, ClassNotFoundException
   {
     ObjectInputStream.GetField fields = s.readFields();
@@ -165,8 +179,7 @@
    * Writes an object to the stream. This converts the internal to the
    * external representation.
    */
-  private void writeObject(ObjectOutputStream s) 
-    throws IOException
+  private void writeObject(ObjectOutputStream s) throws IOException
   {
     ObjectOutputStream.PutField fields = s.putFields();
     fields.put("actions", getActions());
@@ -178,61 +191,61 @@
    * PropertyPermission objects.
    * @return a new empty PermissionCollection.  
    */
-  public PermissionCollection newPermissionCollection() 
+  public PermissionCollection newPermissionCollection()
   {
-    return new PermissionCollection() 
+    return new PermissionCollection()
+    {
+      Hashtable permissions = new Hashtable();
+      int allActions = 0;
+
+      public void add(Permission permission)
       {
-	Hashtable permissions = new Hashtable();
-	int allActions = 0;
-	
-	public void add(Permission permission) 
-	  {
-	    if (isReadOnly())
-	      throw new IllegalStateException("readonly");
+	if (isReadOnly())
+	  throw new IllegalStateException("readonly");
 
-	    // also check that permission is of correct type.
-	    PropertyPermission pp = (PropertyPermission) permission;
-	    String name = pp.getName();
-	    if (name.equals("*"))
-	      allActions |= pp.actions;
-	    permissions.put(name, pp);
-	  }
-	
-	public boolean implies(Permission permission)
-	  {
-	    if (!(permission instanceof PropertyPermission))
-	      return false;
+	// also check that permission is of correct type.
+	PropertyPermission pp = (PropertyPermission) permission;
+	String name = pp.getName();
+	if (name.equals("*"))
+	  allActions |= pp.actions;
+	permissions.put(name, pp);
+      }
 
-	    PropertyPermission toImply = (PropertyPermission) permission;
-	    if ((toImply.actions & ~allActions) == 0)
-	      return true;
+      public boolean implies(Permission permission)
+      {
+	if (!(permission instanceof PropertyPermission))
+	  return false;
 
-	    String name = toImply.getName();
-	    if (name.equals("*"))
-	      return false;
+	PropertyPermission toImply = (PropertyPermission) permission;
+	if ((toImply.actions & ~allActions) == 0)
+	  return true;
+
+	String name = toImply.getName();
+	if (name.equals("*"))
+	  return false;
+
+	int prefixLength = name.length();
+	if (name.endsWith("*"))
+	  prefixLength -= 2;
 
-	    int prefixLength = name.length();
-	    if (name.endsWith("*"))
-	      prefixLength -= 2;
-
-	    while (true) {
-	      PropertyPermission forName = 
-		(PropertyPermission) permissions.get(name);
-	      if (forName != null
-		  && (toImply.actions & ~forName.actions) == 0)
-		return true;
-
-	      prefixLength = name.lastIndexOf('.', prefixLength);
-	      if (prefixLength < 0)
-		return false;
-	      name = name.substring(0, prefixLength + 1) + '*';
-	    }
-	  }
-	
-	public Enumeration elements()
+	while (true)
 	  {
-	    return permissions.elements();
+	    PropertyPermission forName =
+	      (PropertyPermission) permissions.get(name);
+	    if (forName != null && (toImply.actions & ~forName.actions) == 0)
+	      return true;
+
+	    prefixLength = name.lastIndexOf('.', prefixLength);
+	    if (prefixLength < 0)
+	      return false;
+	    name = name.substring(0, prefixLength + 1) + '*';
 	  }
-      };
+      }
+
+      public Enumeration elements()
+      {
+	return permissions.elements();
+      }
+    };
   }
 }
Index: java/lang/ExceptionInInitializerError.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/ExceptionInInitializerError.java,v
retrieving revision 1.3
diff -u -r1.3 ExceptionInInitializerError.java
--- ExceptionInInitializerError.java	2000/03/07 19:55:26	1.3
+++ ExceptionInInitializerError.java	2000/11/18 02:22:37
@@ -1,15 +1,17 @@
 // ExceptionInInitializerError.java
 
-/* Copyright (C) 1998, 1999  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000  Free Software Foundation
 
    This file is part of libgcj.
 
 This software is copyrighted work licensed under the terms of the
 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
- 
+
 package java.lang;
- 
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
 /**
  * @author Tom Tromey <tromey@cygnus.com>
  * @date October 1, 1998 
@@ -43,6 +45,21 @@
   public Throwable getException ()
   {
     return exception;
+  }
+
+  public void printStackTrace ()
+  {
+    exception.printStackTrace ();
+  }
+
+  public void printStackTrace (PrintStream ps)
+  {
+    exception.printStackTrace (ps);
+  }
+
+  public void printStackTrace (PrintWriter pw)
+  {
+    exception.printStackTrace (pw);
   }
 
   // The exception that caused this error.
Index: java/lang/String.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/String.java,v
retrieving revision 1.11
diff -u -r1.11 String.java
--- String.java	2000/09/13 06:36:25	1.11
+++ String.java	2000/11/18 02:22:38
@@ -11,6 +11,7 @@
 import java.io.Serializable;
 import java.lang.Comparable;
 import java.util.Comparator;
+import java.util.Locale;
 
 /**
  * @author Per Bothner <bothner@cygnus.com>
@@ -31,13 +32,13 @@
   // but it will avoid showing up as a discrepancy when comparing SUIDs.
   private static final long serialVersionUID = -6849794470754667710L;
 
-  static Comparator CASE_INSENSITIVE_ORDER = new Comparator()
+  public static final Comparator CASE_INSENSITIVE_ORDER = new Comparator()
+  {
+    public int compare (Object o1, Object o2)
     {
-      public int compare (Object o1, Object o2)
-      {
-        return ((String) o1).compareToIgnoreCase ((String) o2);
-      }
-    };
+      return ((String) o1).compareToIgnoreCase ((String) o2);
+    }
+  };
 
   public String ()
   {
@@ -275,10 +276,27 @@
   public native String concat (String str);
 
   public native String replace (char oldChar, char newChar);
+
+  public native String toLowerCase (Locale locale);
+  public native String toUpperCase (Locale locale);
 
-  public native String toLowerCase ();
+  public String toLowerCase ()
+  {
+    // The JDK is a bit confused about what to do here.  If we pass in
+    // the default Locale then special Locale handling might be
+    // invoked.  However, the docs also say that Character.toLowerCase
+    // rules here.  We go with the latter.
+    return toLowerCase (null);
+  }
 
-  public native String toUpperCase ();
+  public String toUpperCase ()
+  {
+    // The JDK is a bit confused about what to do here.  If we pass in
+    // the default Locale then special Locale handling might be
+    // invoked.  However, the docs also say that Character.toLowerCase
+    // rules here.  We go with the latter.
+    return toUpperCase (null);
+  }
 
   public native String trim ();
 
Index: java/lang/natString.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natString.cc,v
retrieving revision 1.14
diff -u -r1.14 natString.cc
--- natString.cc	2000/05/19 17:55:32	1.14
+++ natString.cc	2000/11/18 02:22:39
@@ -24,6 +24,7 @@
 #include <java/io/OutputStreamWriter.h>
 #include <java/io/ByteArrayInputStream.h>
 #include <java/io/InputStreamReader.h>
+#include <java/util/Locale.h>
 #include <gnu/gcj/convert/UnicodeToBytes.h>
 #include <gnu/gcj/convert/BytesToUnicode.h>
 #include <jvm.h>
@@ -33,6 +34,14 @@
 static int strhash_size = 0;  /* Number of slots available in strhash.
                                * Assumed be power of 2! */
 
+// Some defines used by toUpperCase / toLowerCase.
+#define ESSET     0x00df
+#define CAPITAL_S 0x0053
+#define SMALL_I   0x0069
+#define CAPITAL_I_WITH_DOT 0x0130
+#define SMALL_DOTLESS_I    0x0131
+#define CAPITAL_I 0x0049
+
 #define DELETED_STRING ((jstring)(~0))
 #define SET_STRING_IS_INTERNED(STR) /* nothing */
 
@@ -755,16 +764,32 @@
 }
 
 jstring
-java::lang::String::toLowerCase ()
+java::lang::String::toLowerCase (java::util::Locale *locale)
 {
   jint i;
   jchar* chrs = JvGetStringChars(this);
   jchar ch;
+
+  bool handle_tr = false;
+  if (locale != NULL)
+    {
+      String *lang = locale->getLanguage ();
+      if (lang->length () == 2
+	  && lang->charAt (0) == 't'
+	  && lang->charAt (1) == 'r')
+	handle_tr = true;
+    }
+
   for (i = 0;  ;  i++)
     {
       if (i == count)
 	return this;
       jchar origChar = chrs[i];
+
+      if (handle_tr && (origChar == CAPITAL_I
+			|| origChar == CAPITAL_I_WITH_DOT))
+	break;
+
       ch = java::lang::Character::toLowerCase(origChar);
       if (ch != origChar)
 	break;
@@ -776,34 +801,80 @@
   *dPtr++ = ch;  i++;
   for (; i < count;  i++)
     {
-      *dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
+      if (handle_tr && chrs[i] == CAPITAL_I)
+	*dPtr++ = SMALL_DOTLESS_I;
+      else if (handle_tr && chrs[i] == CAPITAL_I_WITH_DOT)
+	*dPtr++ = SMALL_I;
+      else
+	*dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
     }
   return result;
 }
 
 jstring
-java::lang::String::toUpperCase ()
+java::lang::String::toUpperCase (java::util::Locale *locale)
 {
   jint i;
   jchar* chrs = JvGetStringChars(this);
   jchar ch;
+
+  // When handling a specific locale there might be special rules.
+  // Currently all existing rules are simply handled inline, as there
+  // are only two and they are documented in the online 1.2 docs.
+  bool handle_esset = locale != NULL;
+  bool handle_tr = false;
+  if (locale != NULL)
+    {
+      String *lang = locale->getLanguage ();
+      if (lang->length () == 2
+	  && lang->charAt (0) == 't'
+	  && lang->charAt (1) == 'r')
+	handle_tr = true;
+    }
+
+  int new_count = count;
+  bool new_string = false;
   for (i = 0;  ;  i++)
     {
       if (i == count)
-	return this;
+	break;
       jchar origChar = chrs[i];
-      ch = java::lang::Character::toUpperCase(origChar);
-      if (ch != origChar)
+
+      if (handle_esset && origChar == ESSET)
+	{
+	  ++new_count;
+	  new_string = true;
+	}
+      else if (handle_tr && (origChar == SMALL_I
+			     || origChar == SMALL_DOTLESS_I))
+	new_string = true;
+      else
+	{
+	  ch = java::lang::Character::toUpperCase(origChar);
+	  if (ch != origChar)
+	    new_string = true;
+	}
+
+      if (new_string && ! handle_esset)
 	break;
     }
-  jstring result = JvAllocString(count);
+  if (! new_string)
+    return this;
+  jstring result = JvAllocString(new_count);
   jchar *dPtr = JvGetStringChars (result);
-  for (int j = 0;  j < i;  j++)
-    *dPtr++ = chrs[j];
-  *dPtr++ = ch;  i++;
-  for (; i < count;  i++)
+  for (i = 0; i < count;  i++)
     {
-      *dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
+      if (handle_esset && chrs[i] == ESSET)
+	{
+	  *dPtr++ = CAPITAL_S;
+	  *dPtr++ = CAPITAL_S;
+	}
+      else if (handle_tr && chrs[i] == SMALL_I)
+	*dPtr++ = CAPITAL_I_WITH_DOT;
+      else if (handle_tr && chrs[i] == SMALL_DOTLESS_I)
+	*dPtr++ = CAPITAL_I;
+      else
+	*dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
     }
   return result;
 }
Index: java/text/RuleBasedCollator.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/text/RuleBasedCollator.java,v
retrieving revision 1.5
diff -u -r1.5 RuleBasedCollator.java
--- RuleBasedCollator.java	2000/04/11 20:02:48	1.5
+++ RuleBasedCollator.java	2000/11/18 02:22:39
@@ -176,6 +176,17 @@
     return new CollationElementIterator (expand.toString(), this);
   }
 
+  public CollationElementIterator getCollationElementIterator (CharacterIterator source)
+  {
+    StringBuffer expand = new StringBuffer ();
+    for (char c = source.first ();
+	 c != CharacterIterator.DONE;
+	 c = source.next ())
+      decomposeCharacter (c, expand);
+
+    return new CollationElementIterator (expand.toString(), this);
+  }
+
   public CollationKey getCollationKey (String source)
   {
     return new CollationKey (getCollationElementIterator (source), source,
Index: java/text/StringCharacterIterator.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/text/StringCharacterIterator.java,v
retrieving revision 1.4
diff -u -r1.4 StringCharacterIterator.java
--- StringCharacterIterator.java	2000/05/04 15:50:34	1.4
+++ StringCharacterIterator.java	2000/11/18 02:22:39
@@ -22,108 +22,121 @@
 public final class StringCharacterIterator implements CharacterIterator
 {
   public Object clone ()
-    {
-      return (Object) new StringCharacterIterator (text, begin, end, pos);
-    }
+  {
+    return (Object) new StringCharacterIterator (text, begin, end, pos);
+  }
 
   public char current ()
-    {
-      // This follows JDK 1.2 semantics and not 1.1 semantics.
-      // In 1.1 we would throw an exception if begin==end.
-      return (pos < end) ? text.charAt(pos) : CharacterIterator.DONE;
-    }
+  {
+    // This follows JDK 1.2 semantics and not 1.1 semantics.
+    // In 1.1 we would throw an exception if begin==end.
+    return (pos < end) ? text.charAt(pos) : CharacterIterator.DONE;
+  }
 
   public boolean equals (Object obj)
-    {
-      if (! (obj instanceof StringCharacterIterator))
-	return false;
-      StringCharacterIterator sci = (StringCharacterIterator) obj;
-      // The spec says "the same text".  We take this to mean equals,
-      // not ==.
-      return (pos == sci.pos
-	      && begin == sci.begin
-	      && end == sci.end
-	      && text.equals(sci.text));
-    }
+  {
+    if (! (obj instanceof StringCharacterIterator))
+      return false;
+    StringCharacterIterator sci = (StringCharacterIterator) obj;
+    // The spec says "the same text".  We take this to mean equals,
+    // not ==.
+    return (pos == sci.pos
+	    && begin == sci.begin
+	    && end == sci.end
+	    && text.equals(sci.text));
+  }
 
   public char first ()
-    {
-      pos = begin;
-      return current ();
-    }
+  {
+    pos = begin;
+    return current ();
+  }
 
   public int getBeginIndex ()
-    {
-      return begin;
-    }
+  {
+    return begin;
+  }
 
   public int getEndIndex ()
-    {
-      return end;
-    }
+  {
+    return end;
+  }
 
   public int getIndex ()
-    {
-      return pos;
-    }
+  {
+    return pos;
+  }
 
   public int hashCode ()
-    {
-      // FIXME: this is a terrible hash code.  Find a better one.
-      return text.hashCode() + pos + begin + end;
-    }
+  {
+    // FIXME: this is a terrible hash code.  Find a better one.
+    return text.hashCode() + pos + begin + end;
+  }
 
   public char last ()
-    {
-      pos = end;
-      return current ();
-    }
+  {
+    pos = end;
+    return current ();
+  }
 
   public char next ()
-    {
-      if (pos == end)
-	return CharacterIterator.DONE;
-      ++pos;
-      return current ();
-    }
+  {
+    if (pos == end)
+      return CharacterIterator.DONE;
+    ++pos;
+    return current ();
+  }
 
   public char previous ()
-    {
-      if (pos == begin)
-	return CharacterIterator.DONE;
-      --pos;
-      return current ();
-    }
+  {
+    if (pos == begin)
+      return CharacterIterator.DONE;
+    --pos;
+    return current ();
+  }
 
   public char setIndex (int idx)
-    {
-      // In 1.1 we would throw an error if `idx == end'.
-      if (idx < begin || idx > end)
-	throw new IllegalArgumentException ();
-      pos = idx;
-      return current ();
-    }
+  {
+    // In 1.1 we would throw an error if `idx == end'.
+    if (idx < begin || idx > end)
+      throw new IllegalArgumentException ();
+    pos = idx;
+    return current ();
+  }
 
   public StringCharacterIterator (String text)
-    {
-      this (text, 0, text.length(), 0);
-    }
+  {
+    this (text, 0, text.length(), 0);
+  }
+
   public StringCharacterIterator (String text, int pos)
-    {
-      this (text, 0, text.length(), pos);
-    }
+  {
+    this (text, 0, text.length(), pos);
+  }
+
   public StringCharacterIterator (String text, int begin, int end, int pos)
-    {
-      if (begin < 0 || begin > end || end > text.length()
-	  // In 1.1 we would also throw if `pos == end'.
-	  || pos < begin || pos > end)
-	throw new IllegalArgumentException ();
-
-      this.text = text;
-      this.begin = begin;
-      this.end = end;
-      this.pos = pos;
-    }
+  {
+    if (begin < 0 || begin > end || end > text.length()
+	// In 1.1 we would also throw if `pos == end'.
+	|| pos < begin || pos > end)
+      throw new IllegalArgumentException ();
+
+    this.text = text;
+    this.begin = begin;
+    this.end = end;
+    this.pos = pos;
+  }
+
+  // The online 1.2 docs say that this is "package visible" in the
+  // method description, but they also say it is public.  We choose
+  // the latter for compatibility with the actual implementation.
+  public void setText (String text)
+  {
+    this.text = text;
+    this.begin = 0;
+    this.end = text.length ();
+    this.pos = 0;
+  }
 
   // String to iterate over.
   private String text;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]