mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			313 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Java
		
	
	
	
| // ChoiceFormat.java - Formatter for `switch'-like string substitution.
 | |
| 
 | |
| /* Copyright (C) 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.text;
 | |
| 
 | |
| import java.util.Vector;
 | |
| 
 | |
| /**
 | |
|  * @author Tom Tromey <tromey@cygnus.com>
 | |
|  * @date March 9, 1999
 | |
|  */
 | |
| /* Written using "Java Class Libraries", 2nd edition, plus online
 | |
|  * API docs for JDK 1.2 from http://www.javasoft.com.
 | |
|  * Status:  Believed complete and correct to 1.1.
 | |
|  */
 | |
| 
 | |
| public class ChoiceFormat extends NumberFormat
 | |
| {
 | |
|   // Note: we assume the same kind of quoting rules apply here.
 | |
|   // This isn't explicitly documented.  But for instance we accept
 | |
|   // '#' as a literal hash in a format string.
 | |
|   public void applyPattern (String newPattern)
 | |
|     {
 | |
|       int index = 0, max = newPattern.length();
 | |
|       Vector stringVec = new Vector ();
 | |
|       Vector limitVec = new Vector ();
 | |
|       StringBuffer buf = new StringBuffer ();
 | |
| 
 | |
|       while (true)
 | |
| 	{
 | |
| 	  // Find end of double.
 | |
| 	  int dstart = index;
 | |
| 	  while (index < max)
 | |
| 	    {
 | |
| 	      char c = newPattern.charAt(index);
 | |
| 	      if (c == '#' || c == '\u2064' || c == '<')
 | |
| 		break;
 | |
| 	      ++index;
 | |
| 	    }
 | |
| 
 | |
| 	  if (index == max)
 | |
| 	    throw new IllegalArgumentException ("unexpected end of text");
 | |
| 	  Double d = new Double (newPattern.substring(dstart, index));
 | |
| 
 | |
| 	  if (newPattern.charAt(index) == '<')
 | |
| 	    d = new Double (nextDouble (d.doubleValue()));
 | |
| 
 | |
| 	  limitVec.addElement(d);
 | |
| 
 | |
| 	  // Scan text.
 | |
| 	  ++index;
 | |
| 	  buf.setLength(0);
 | |
| 	  while (index < max)
 | |
| 	    {
 | |
| 	      char c = newPattern.charAt(index);
 | |
| 	      if (c == '\'' && index < max + 1
 | |
| 		  && newPattern.charAt(index + 1) == '\'')
 | |
| 		{
 | |
| 		  buf.append(c);
 | |
| 		  ++index;
 | |
| 		}
 | |
| 	      else if (c == '\'' && index < max + 2)
 | |
| 		{
 | |
| 		  buf.append(newPattern.charAt(index + 1));
 | |
| 		  index += 2;
 | |
| 		}
 | |
| 	      else if (c == '|')
 | |
| 		break;
 | |
| 	      else
 | |
| 		buf.append(c);
 | |
| 	      ++index;
 | |
| 	    }
 | |
| 
 | |
| 	  stringVec.addElement(buf.toString());
 | |
| 	  if (index == max)
 | |
| 	    break;
 | |
| 	  ++index;
 | |
| 	}
 | |
| 
 | |
|       choiceFormats = new String[stringVec.size()];
 | |
|       stringVec.copyInto(choiceFormats);
 | |
| 
 | |
|       choiceLimits = new double[limitVec.size()];
 | |
|       for (int i = 0; i < choiceLimits.length; ++i)
 | |
| 	{
 | |
| 	  Double d = (Double) limitVec.elementAt(i);
 | |
| 	  choiceLimits[i] = d.doubleValue();
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   public ChoiceFormat (String newPattern)
 | |
|     {
 | |
|       super ();
 | |
|       applyPattern (newPattern);
 | |
|     }
 | |
| 
 | |
|   public ChoiceFormat (double[] choiceLimits, String[] choiceFormats)
 | |
|     {
 | |
|       super ();
 | |
|       setChoices (choiceLimits, choiceFormats);
 | |
|     }
 | |
| 
 | |
|   public Object clone ()
 | |
|     {
 | |
|       return new ChoiceFormat (choiceLimits, choiceFormats);
 | |
|     }
 | |
| 
 | |
|   public boolean equals (Object obj)
 | |
|     {
 | |
|       if (! (obj instanceof ChoiceFormat))
 | |
| 	return false;
 | |
|       ChoiceFormat cf = (ChoiceFormat) obj;
 | |
|       if (choiceLimits.length != cf.choiceLimits.length)
 | |
| 	return false;
 | |
|       for (int i = choiceLimits.length - 1; i >= 0; --i)
 | |
| 	{
 | |
| 	  if (choiceLimits[i] != cf.choiceLimits[i]
 | |
| 	      || !choiceFormats[i].equals(cf.choiceFormats[i]))
 | |
| 	    return false;
 | |
| 	}
 | |
|       return true;
 | |
|     }
 | |
| 
 | |
|   public StringBuffer format (long num, StringBuffer appendBuf,
 | |
| 			      FieldPosition pos)
 | |
|     {
 | |
|       return format ((double) num, appendBuf, pos);
 | |
|     }
 | |
| 
 | |
|   public StringBuffer format (double num, StringBuffer appendBuf,
 | |
| 			      FieldPosition pos)
 | |
|     {
 | |
|       if (choiceLimits.length == 0)
 | |
| 	return appendBuf;
 | |
| 
 | |
|       int index =  0;
 | |
|       if (! Double.isNaN(num) && num >= choiceLimits[0])
 | |
| 	{
 | |
| 	  for (; index < choiceLimits.length - 1; ++index)
 | |
| 	    {
 | |
| 	      if (choiceLimits[index] <= num
 | |
| 		  && index != choiceLimits.length - 2
 | |
| 		  && num < choiceLimits[index + 1])
 | |
| 		break;
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
|       return appendBuf.append(choiceFormats[index]);
 | |
|     }
 | |
| 
 | |
|   public Object[] getFormats ()
 | |
|     {
 | |
|       return (Object[]) choiceFormats.clone();
 | |
|     }
 | |
| 
 | |
|   public double[] getLimits ()
 | |
|     {
 | |
|       return (double[]) choiceLimits.clone();
 | |
|     }
 | |
| 
 | |
|   public int hashCode ()
 | |
|     {
 | |
|       int hash = 0;
 | |
|       for (int i = 0; i < choiceLimits.length; ++i)
 | |
| 	{
 | |
| 	  long v = Double.doubleToLongBits(choiceLimits[i]);
 | |
| 	  hash ^= (v ^ (v >>> 32));
 | |
| 	  hash ^= choiceFormats[i].hashCode();
 | |
| 	}
 | |
|       return hash;
 | |
|     }
 | |
| 
 | |
|   public static final double nextDouble (double d)
 | |
|     {
 | |
|       return nextDouble (d, true);
 | |
|     }
 | |
| 
 | |
|   public static double nextDouble (double d, boolean next)
 | |
|     {
 | |
|       if (Double.isInfinite(d) || Double.isNaN(d))
 | |
| 	return d;
 | |
| 
 | |
|       long bits = Double.doubleToLongBits(d);
 | |
| 
 | |
|       long mantMask = (1L << mantissaBits) - 1;
 | |
|       long mantissa = bits & mantMask;
 | |
| 
 | |
|       long expMask = (1L << exponentBits) - 1;
 | |
|       long exponent = (bits >>> mantissaBits) & expMask;
 | |
| 
 | |
|       if (next ^ (bits < 0)) // Increment magnitude
 | |
| 	{
 | |
| 	  if (mantissa == (1L << mantissaBits) - 1)
 | |
| 	    {
 | |
| 	      mantissa = 0L;
 | |
| 	      exponent++;
 | |
| 	     
 | |
| 	      // Check for absolute overflow.
 | |
| 	      if (exponent >= (1L << mantissaBits))
 | |
| 		return (bits > 0) ? Double.POSITIVE_INFINITY 
 | |
| 		  : Double.NEGATIVE_INFINITY;		      
 | |
| 	    }
 | |
| 	  else
 | |
| 	    mantissa++;
 | |
| 	}
 | |
|       else // Decrement magnitude
 | |
| 	{
 | |
| 	  if (exponent == 0L && mantissa == 0L)
 | |
| 	    {
 | |
| 	      // The only case where there is a change of sign
 | |
| 	      return next ? Double.MIN_VALUE : -Double.MIN_VALUE;
 | |
| 	    }
 | |
| 	  else
 | |
| 	    {
 | |
| 	      if (mantissa == 0L)
 | |
| 		{
 | |
| 		  mantissa = (1L << mantissaBits) - 1;
 | |
| 		  exponent--;
 | |
| 		}
 | |
| 	      else
 | |
| 		mantissa--;
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
|       long result = bits < 0 ? 1 : 0;
 | |
|       result = (result << exponentBits) | exponent;
 | |
|       result = (result << mantissaBits) | mantissa;
 | |
|       return Double.longBitsToDouble(result);
 | |
|     }
 | |
| 
 | |
|   public Number parse (String sourceStr, ParsePosition pos)
 | |
|     {
 | |
|       int index = pos.getIndex();
 | |
|       for (int i = 0; i < choiceLimits.length; ++i)
 | |
| 	{
 | |
| 	  if (sourceStr.startsWith(choiceFormats[i], index))
 | |
| 	    {
 | |
| 	      pos.setIndex(index + choiceFormats[i].length());
 | |
| 	      return new Double (choiceLimits[i]);
 | |
| 	    }
 | |
| 	}
 | |
|       pos.setErrorIndex(index);
 | |
|       return new Double (Double.NaN);
 | |
|     }
 | |
| 
 | |
|   public static final double previousDouble (double d)
 | |
|     {
 | |
|       return nextDouble (d, false);
 | |
|     }
 | |
| 
 | |
|   public void setChoices (double[] choiceLimits, String[] choiceFormats)
 | |
|     {
 | |
|       if (choiceLimits == null || choiceFormats == null)
 | |
| 	throw new NullPointerException ();
 | |
|       if (choiceLimits.length != choiceFormats.length)
 | |
| 	throw new IllegalArgumentException ();
 | |
|       this.choiceFormats = (String[]) choiceFormats.clone();
 | |
|       this.choiceLimits = (double[]) choiceLimits.clone();
 | |
|     }
 | |
| 
 | |
|   private final void quoteString (StringBuffer dest, String text)
 | |
|     {
 | |
|       int max = text.length();
 | |
|       for (int i = 0; i < max; ++i)
 | |
| 	{
 | |
| 	  char c = text.charAt(i);
 | |
| 	  if (c == '\'')
 | |
| 	    {
 | |
| 	      dest.append(c);
 | |
| 	      dest.append(c);
 | |
| 	    }
 | |
| 	  else if (c == '#' || c == '|' || c == '\u2064' || c == '<')
 | |
| 	    {
 | |
| 	      dest.append('\'');
 | |
| 	      dest.append(c);
 | |
| 	      dest.append('\'');
 | |
| 	    }
 | |
| 	  else
 | |
| 	    dest.append(c);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   public String toPattern ()
 | |
|     {
 | |
|       StringBuffer result = new StringBuffer ();
 | |
|       for (int i = 0; i < choiceLimits.length; ++i)
 | |
| 	{
 | |
| 	  result.append(choiceLimits[i]);
 | |
| 	  result.append('#');
 | |
| 	  quoteString (result, choiceFormats[i]);
 | |
| 	}
 | |
|       return result.toString();
 | |
|     }
 | |
| 
 | |
|   // Formats and limits.
 | |
|   private String[] choiceFormats;
 | |
|   private double[] choiceLimits;
 | |
| 
 | |
|   // Number of mantissa bits in double.
 | |
|   private static final int mantissaBits = 52;
 | |
|   // Number of exponent bits in a double.
 | |
|   private static final int exponentBits = 11;
 | |
| 
 | |
|   private static final long serialVersionUID = 1795184449645032964L;
 | |
| }
 |