Home » openjdk-7 » net.bonzoun » cocodonkey » [javadoc | source]

    1   package net.bonzoun.cocodonkey;
    2   
    3   
    4   
    5   //
    6   // (c) 2000 Sun Microsystems, Inc.
    7   // ALL RIGHTS RESERVED
    8   // 
    9   // License Grant-
   10   // 
   11   // 
   12   // Permission to use, copy, modify, and distribute this Software and its 
   13   // documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is 
   14   // hereby granted.  
   15   // 
   16   // This Software is provided "AS IS".  All express warranties, including any 
   17   // implied warranty of merchantability, satisfactory quality, fitness for a 
   18   // particular purpose, or non-infringement, are disclaimed, except to the extent 
   19   // that such disclaimers are held to be legally invalid.
   20   // 
   21   // You acknowledge that Software is not designed, licensed or intended for use in 
   22   // the design, construction, operation or maintenance of any nuclear facility 
   23   // ("High Risk Activities").  Sun disclaims any express or implied warranty of 
   24   // fitness for such uses.  
   25   //
   26   // Please refer to the file http://www.sun.com/policies/trademarks/ for further 
   27   // important trademark information and to 
   28   // http://java.sun.com/nav/business/index.html for further important licensing 
   29   // information for the Java Technology.
   30   //
   31   
   32   
   33   import java.util.Enumeration;
   34   import java.util.Vector;
   35   import java.util.Locale;
   36   import java.text.DecimalFormatSymbols;
   37   
   38   /**
   39    * PrintfFormat allows the formatting of an array of
   40    * objects embedded within a string.  Primitive types
   41    * must be passed using wrapper types.  The formatting
   42    * is controlled by a control string.
   43    *<p>
   44    * A control string is a Java string that contains a
   45    * control specification.  The control specification
   46    * starts at the first percent sign (%) in the string,
   47    * provided that this percent sign
   48    *<ol>
   49    *<li>is not escaped protected by a matching % or is
   50    * not an escape % character,
   51    *<li>is not at the end of the format string, and
   52    *<li>precedes a sequence of characters that parses as
   53    * a valid control specification.
   54    *</ol>
   55    *</p><p>
   56    * A control specification usually takes the form:
   57    *<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
   58    *                { [hlL] }+ [idfgGoxXeEcs]
   59    *</pre>
   60    * There are variants of this basic form that are
   61    * discussed below.</p>
   62    *<p>
   63    * The format is composed of zero or more directives
   64    * defined as follows:
   65    *<ul>
   66    *<li>ordinary characters, which are simply copied to
   67    * the output stream;
   68    *<li>escape sequences, which represent non-graphic
   69    * characters; and
   70    *<li>conversion specifications,  each of which
   71    * results in the fetching of zero or more arguments.
   72    *</ul></p>
   73    *<p>
   74    * The results are undefined if there are insufficient
   75    * arguments for the format.  Usually an unchecked
   76    * exception will be thrown.  If the format is
   77    * exhausted while arguments remain, the excess
   78    * arguments are evaluated but are otherwise ignored.
   79    * In format strings containing the % form of
   80    * conversion specifications, each argument in the
   81    * argument list is used exactly once.</p>
   82    * <p>
   83    * Conversions can be applied to the <code>n</code>th
   84    * argument after the format in the argument list,
   85    * rather than to the next unused argument.  In this
   86    * case, the conversion characer % is replaced by the
   87    * sequence %<code>n</code>$, where <code>n</code> is
   88    * a decimal integer giving the position of the
   89    * argument in the argument list.</p>
   90    * <p>
   91    * In format strings containing the %<code>n</code>$
   92    * form of conversion specifications, each argument
   93    * in the argument list is used exactly once.</p>
   94    *
   95    *<h4>Escape Sequences</h4>
   96    *<p>
   97    * The following table lists escape sequences and
   98    * associated actions on display devices capable of
   99    * the action.
  100    *<table>
  101    *<tr><th align=left>Sequence</th>
  102    *    <th align=left>Name</th>
  103    *    <th align=left>Description</th></tr>
  104    *<tr><td>\\</td><td>backlash</td><td>None.
  105    *</td></tr>
  106    *<tr><td>\a</td><td>alert</td><td>Attempts to alert
  107    *          the user through audible or visible
  108    *          notification.
  109    *</td></tr>
  110    *<tr><td>\b</td><td>backspace</td><td>Moves the
  111    *          printing position to one column before
  112    *          the current position, unless the
  113    *          current position is the start of a line.
  114    *</td></tr>
  115    *<tr><td>\f</td><td>form-feed</td><td>Moves the
  116    *          printing position to the initial 
  117    *          printing position of the next logical
  118    *          page.
  119    *</td></tr>
  120    *<tr><td>\n</td><td>newline</td><td>Moves the
  121    *          printing position to the start of the
  122    *          next line.
  123    *</td></tr>
  124    *<tr><td>\r</td><td>carriage-return</td><td>Moves
  125    *          the printing position to the start of
  126    *          the current line.
  127    *</td></tr>
  128    *<tr><td>\t</td><td>tab</td><td>Moves the printing
  129    *          position to the next implementation-
  130    *          defined horizontal tab position.
  131    *</td></tr>
  132    *<tr><td>\v</td><td>vertical-tab</td><td>Moves the
  133    *          printing position to the start of the
  134    *          next implementation-defined vertical
  135    *          tab position.
  136    *</td></tr>
  137    *</table></p>
  138    *<h4>Conversion Specifications</h4>
  139    *<p>
  140    * Each conversion specification is introduced by
  141    * the percent sign character (%).  After the character
  142    * %, the following appear in sequence:</p>
  143    *<p>
  144    * Zero or more flags (in any order), which modify the
  145    * meaning of the conversion specification.</p>
  146    *<p>
  147    * An optional minimum field width.  If the converted
  148    * value has fewer characters than the field width, it
  149    * will be padded with spaces by default on the left;
  150    * t will be padded on the right, if the left-
  151    * adjustment flag (-), described below, is given to
  152    * the field width.  The field width takes the form
  153    * of a decimal integer.  If the conversion character
  154    * is s, the field width is the the minimum number of
  155    * characters to be printed.</p>
  156    *<p>
  157    * An optional precision that gives the minumum number
  158    * of digits to appear for the d, i, o, x or X
  159    * conversions (the field is padded with leading
  160    * zeros); the number of digits to appear after the
  161    * radix character for the e, E, and f conversions,
  162    * the maximum number of significant digits for the g
  163    * and G conversions; or the maximum number of
  164    * characters to be written from a string is s and S
  165    * conversions.  The precision takes the form of an
  166    * optional decimal digit string, where a null digit
  167    * string is treated as 0.  If a precision appears
  168    * with a c conversion character the precision is
  169    * ignored.
  170    * </p>
  171    *<p>
  172    * An optional h specifies that a following d, i, o,
  173    * x, or X conversion character applies to a type 
  174    * short argument (the argument will be promoted
  175    * according to the integral promotions and its value
  176    * converted to type short before printing).</p>
  177    *<p>
  178    * An optional l (ell) specifies that a following
  179    * d, i, o, x, or X conversion character applies to a
  180    * type long argument.</p>
  181    *<p>
  182    * A field width or precision may be indicated by an
  183    * asterisk (*) instead of a digit string.  In this
  184    * case, an integer argument supplised the field width
  185    * precision.  The argument that is actually converted
  186    * is not fetched until the conversion letter is seen,
  187    * so the the arguments specifying field width or
  188    * precision must appear before the argument (if any)
  189    * to be converted.  If the precision argument is
  190    * negative, it will be changed to zero.  A negative
  191    * field width argument is taken as a - flag, followed
  192    * by a positive field width.</p>
  193    * <p>
  194    * In format strings containing the %<code>n</code>$
  195    * form of a conversion specification, a field width
  196    * or precision may be indicated by the sequence
  197    * *<code>m</code>$, where m is a decimal integer
  198    * giving the position in the argument list (after the
  199    * format argument) of an integer argument containing
  200    * the field width or precision.</p>
  201    * <p>
  202    * The format can contain either numbered argument
  203    * specifications (that is, %<code>n</code>$ and
  204    * *<code>m</code>$), or unnumbered argument
  205    * specifications (that is % and *), but normally not
  206    * both.  The only exception to this is that %% can
  207    * be mixed with the %<code>n</code>$ form.  The
  208    * results of mixing numbered and unnumbered argument
  209    * specifications in a format string are undefined.</p>
  210    *
  211    *<h4>Flag Characters</h4>
  212    *<p>
  213    * The flags and their meanings are:</p>
  214    *<dl>
  215    * <dt>'<dd> integer portion of the result of a
  216    *      decimal conversion (%i, %d, %f, %g, or %G) will
  217    *      be formatted with thousands' grouping
  218    *      characters.  For other conversions the flag
  219    *      is ignored.  The non-monetary grouping
  220    *      character is used.
  221    * <dt>-<dd> result of the conversion is left-justified
  222    *      within the field.  (It will be right-justified
  223    *      if this flag is not specified).</td></tr>
  224    * <dt>+<dd> result of a signed conversion always
  225    *      begins with a sign (+ or -).  (It will begin
  226    *      with a sign only when a negative value is
  227    *      converted if this flag is not specified.)
  228    * <dt>&lt;space&gt;<dd> If the first character of a
  229    *      signed conversion is not a sign, a space
  230    *      character will be placed before the result.
  231    *      This means that if the space character and +
  232    *      flags both appear, the space flag will be
  233    *      ignored.
  234    * <dt>#<dd> value is to be converted to an alternative
  235    *      form.  For c, d, i, and s conversions, the flag
  236    *      has no effect.  For o conversion, it increases
  237    *      the precision to force the first digit of the
  238    *      result to be a zero.  For x or X conversion, a
  239    *      non-zero result has 0x or 0X prefixed to it,
  240    *      respectively.  For e, E, f, g, and G
  241    *      conversions, the result always contains a radix
  242    *      character, even if no digits follow the radix
  243    *      character (normally, a decimal point appears in
  244    *      the result of these conversions only if a digit
  245    *      follows it).  For g and G conversions, trailing
  246    *      zeros will not be removed from the result as
  247    *      they normally are.
  248    * <dt>0<dd> d, i, o, x, X, e, E, f, g, and G
  249    *      conversions, leading zeros (following any
  250    *      indication of sign or base) are used to pad to
  251    *      the field width;  no space padding is
  252    *      performed.  If the 0 and - flags both appear,
  253    *      the 0 flag is ignored.  For d, i, o, x, and X
  254    *      conversions, if a precision is specified, the
  255    *      0 flag will be ignored. For c conversions,
  256    *      the flag is ignored.
  257    *</dl>
  258    *
  259    *<h4>Conversion Characters</h4>
  260    *<p>
  261    * Each conversion character results in fetching zero
  262    * or more arguments.  The results are undefined if
  263    * there are insufficient arguments for the format.
  264    * Usually, an unchecked exception will be thrown.
  265    * If the format is exhausted while arguments remain,
  266    * the excess arguments are ignored.</p>
  267    *
  268    *<p>
  269    * The conversion characters and their meanings are:
  270    *</p>
  271    *<dl>
  272    * <dt>d,i<dd>The int argument is converted to a
  273    *        signed decimal in the style [-]dddd.  The
  274    *        precision specifies the minimum number of
  275    *        digits to appear;  if the value being
  276    *        converted can be represented in fewer
  277    *        digits, it will be expanded with leading
  278    *        zeros.  The default precision is 1.  The
  279    *        result of converting 0 with an explicit
  280    *        precision of 0 is no characters.
  281    * <dt>o<dd> The int argument is converted to unsigned
  282    *        octal format in the style ddddd.  The
  283    *        precision specifies the minimum number of
  284    *        digits to appear;  if the value being
  285    *        converted can be represented in fewer
  286    *        digits, it will be expanded with leading
  287    *        zeros.  The default precision is 1.  The
  288    *        result of converting 0 with an explicit
  289    *        precision of 0 is no characters.
  290    * <dt>x<dd> The int argument is converted to unsigned
  291    *        hexadecimal format in the style dddd;  the
  292    *        letters abcdef are used.  The precision
  293    *        specifies the minimum numberof digits to
  294    *        appear; if the value being converted can be
  295    *        represented in fewer digits, it will be
  296    *        expanded with leading zeros.  The default
  297    *        precision is 1.  The result of converting 0
  298    *        with an explicit precision of 0 is no
  299    *        characters.
  300    * <dt>X<dd> Behaves the same as the x conversion
  301    *        character except that letters ABCDEF are
  302    *        used instead of abcdef.
  303    * <dt>f<dd> The floating point number argument is
  304    *        written in decimal notation in the style
  305    *        [-]ddd.ddd, where the number of digits after
  306    *        the radix character (shown here as a decimal
  307    *        point) is equal to the precision
  308    *        specification.  A Locale is used to determine
  309    *        the radix character to use in this format.
  310    *        If the precision is omitted from the
  311    *        argument, six digits are written after the
  312    *        radix character;  if the precision is
  313    *        explicitly 0 and the # flag is not specified,
  314    *        no radix character appears.  If a radix
  315    *        character appears, at least 1 digit appears
  316    *        before it.  The value is rounded to the
  317    *        appropriate number of digits.
  318    * <dt>e,E<dd>The floating point number argument is
  319    *        written in the style [-]d.ddde{+-}dd
  320    *        (the symbols {+-} indicate either a plus or
  321    *        minus sign), where there is one digit before
  322    *        the radix character (shown here as a decimal
  323    *        point) and the number of digits after it is
  324    *        equal to the precision.  A Locale is used to
  325    *        determine the radix character to use in this
  326    *        format.  When the precision is missing, six
  327    *        digits are written after the radix character;
  328    *        if the precision is 0 and the # flag is not
  329    *        specified, no radix character appears.  The
  330    *        E conversion will produce a number with E
  331    *        instead of e introducing the exponent.  The
  332    *        exponent always contains at least two digits.
  333    *        However, if the value to be written requires
  334    *        an exponent greater than two digits,
  335    *        additional exponent digits are written as
  336    *        necessary.  The value is rounded to the
  337    *        appropriate number of digits.
  338    * <dt>g,G<dd>The floating point number argument is
  339    *        written in style f or e (or in sytle E in the
  340    *        case of a G conversion character), with the
  341    *        precision specifying the number of
  342    *        significant digits.  If the precision is
  343    *        zero, it is taken as one.  The style used
  344    *        depends on the value converted:  style e
  345    *        (or E) will be used only if the exponent
  346    *        resulting from the conversion is less than
  347    *        -4 or greater than or equal to the precision.
  348    *        Trailing zeros are removed from the result.
  349    *        A radix character appears only if it is
  350    *        followed by a digit.
  351    * <dt>c,C<dd>The integer argument is converted to a
  352    *        char and the result is written.
  353    *
  354    * <dt>s,S<dd>The argument is taken to be a string and
  355    *        bytes from the string are written until the
  356    *        end of the string or the number of bytes 
  357    *        indicated by the precision specification of
  358    *        the argument is reached.  If the precision
  359    *        is omitted from the argument, it is taken to
  360    *        be infinite, so all characters up to the end
  361    *        of the string are written.
  362    * <dt>%<dd>Write a % character;  no argument is
  363    *        converted.
  364    *</dl>
  365    *<p>
  366    * If a conversion specification does not match one of
  367    * the above forms, an IllegalArgumentException is
  368    * thrown and the instance of PrintfFormat is not
  369    * created.</p>
  370    *<p>
  371    * If a floating point value is the internal
  372    * representation for infinity, the output is
  373    * [+]Infinity, where Infinity is either Infinity or
  374    * Inf, depending on the desired output string length.
  375    * Printing of the sign follows the rules described
  376    * above.</p>
  377    *<p>
  378    * If a floating point value is the internal
  379    * representation for "not-a-number," the output is
  380    * [+]NaN.  Printing of the sign follows the rules
  381    * described above.</p>
  382    *<p>
  383    * In no case does a non-existent or small field width
  384    * cause truncation of a field;  if the result of a
  385    * conversion is wider than the field width, the field
  386    * is simply expanded to contain the conversion result.
  387    *</p>
  388    *<p>
  389    * The behavior is like printf.  One exception is that
  390    * the minimum number of exponent digits is 3 instead
  391    * of 2 for e and E formats when the optional L is used
  392    * before the e, E, g, or G conversion character.  The
  393    * optional L does not imply conversion to a long long
  394    * double. </p>
  395    * <p>
  396    * The biggest divergence from the C printf
  397    * specification is in the use of 16 bit characters.
  398    * This allows the handling of characters beyond the
  399    * small ASCII character set and allows the utility to
  400    * interoperate correctly with the rest of the Java
  401    * runtime environment.</p>
  402    *<p>
  403    * Omissions from the C printf specification are
  404    * numerous.  All the known omissions are present
  405    * because Java never uses bytes to represent
  406    * characters and does not have pointers:</p>
  407    *<ul>
  408    * <li>%c is the same as %C.
  409    * <li>%s is the same as %S.
  410    * <li>u, p, and n conversion characters. 
  411    * <li>%ws format.
  412    * <li>h modifier applied to an n conversion character.
  413    * <li>l (ell) modifier applied to the c, n, or s
  414    * conversion characters.
  415    * <li>ll (ell ell) modifier to d, i, o, u, x, or X
  416    * conversion characters.
  417    * <li>ll (ell ell) modifier to an n conversion
  418    * character.
  419    * <li>c, C, d,i,o,u,x, and X conversion characters
  420    * apply to Byte, Character, Short, Integer, Long
  421    * types.
  422    * <li>f, e, E, g, and G conversion characters apply
  423    * to Float and Double types.
  424    * <li>s and S conversion characters apply to String
  425    * types.
  426    * <li>All other reference types can be formatted
  427    * using the s or S conversion characters only.
  428    *</ul>
  429    * <p>
  430    * Most of this specification is quoted from the Unix
  431    * man page for the sprintf utility.</p>
  432    *
  433    * @author Allan Jacobs
  434    * @version 1
  435    * Release 1: Initial release.
  436    * Release 2: Asterisk field widths and precisions    
  437    *            %n$ and *m$
  438    *            Bug fixes
  439    *              g format fix (2 digits in e form corrupt)
  440    *              rounding in f format implemented
  441    *              round up when digit not printed is 5
  442    *              formatting of -0.0f
  443    *              round up/down when last digits are 50000...
  444    */
  445   public class PrintfFormat {
  446     /**
  447      * Constructs an array of control specifications
  448      * possibly preceded, separated, or followed by
  449      * ordinary strings.  Control strings begin with
  450      * unpaired percent signs.  A pair of successive
  451      * percent signs designates a single percent sign in
  452      * the format.
  453      * @param fmtArg  Control string.
  454      * @exception IllegalArgumentException if the control
  455      * string is null, zero length, or otherwise
  456      * malformed.
  457      */
  458     public PrintfFormat(String fmtArg)
  459         throws IllegalArgumentException {
  460       this(Locale.getDefault(),fmtArg);
  461     }
  462     /**
  463      * Constructs an array of control specifications
  464      * possibly preceded, separated, or followed by
  465      * ordinary strings.  Control strings begin with
  466      * unpaired percent signs.  A pair of successive
  467      * percent signs designates a single percent sign in
  468      * the format.
  469      * @param fmtArg  Control string.
  470      * @exception IllegalArgumentException if the control
  471      * string is null, zero length, or otherwise
  472      * malformed.
  473      */
  474     public PrintfFormat(Locale locale,String fmtArg)
  475         throws IllegalArgumentException {
  476       dfs = new DecimalFormatSymbols(locale);
  477       int ePos=0;
  478       ConversionSpecification sFmt=null;
  479       String unCS = this.nonControl(fmtArg,0);
  480       if (unCS!=null) {
  481         sFmt = new ConversionSpecification();
  482         sFmt.setLiteral(unCS);
  483         vFmt.addElement(sFmt);
  484       }
  485       while(cPos!=-1 && cPos<fmtArg.length()) {
  486         for (ePos=cPos+1; ePos<fmtArg.length();
  487                       ePos++) {
  488           char c=0;
  489           c = fmtArg.charAt(ePos);
  490           if (c == 'i') break;
  491           if (c == 'd') break;
  492           if (c == 'f') break;
  493           if (c == 'g') break;
  494           if (c == 'G') break;
  495           if (c == 'o') break;
  496           if (c == 'x') break;
  497           if (c == 'X') break;
  498           if (c == 'e') break;
  499           if (c == 'E') break;
  500           if (c == 'c') break;
  501           if (c == 's') break;
  502           if (c == '%') break;
  503         }
  504         ePos=Math.min(ePos+1,fmtArg.length());
  505         sFmt = new ConversionSpecification(
  506           fmtArg.substring(cPos,ePos));
  507         vFmt.addElement(sFmt);
  508         unCS = this.nonControl(fmtArg,ePos);
  509         if (unCS!=null) {
  510           sFmt = new ConversionSpecification();
  511           sFmt.setLiteral(unCS);
  512           vFmt.addElement(sFmt);
  513         }
  514       }
  515     }
  516     /**
  517      * Return a substring starting at
  518      * <code>start</code> and ending at either the end
  519      * of the String <code>s</code>, the next unpaired
  520      * percent sign, or at the end of the String if the
  521      * last character is a percent sign.
  522      * @param s  Control string.
  523      * @param start Position in the string
  524      *     <code>s</code> to begin looking for the start
  525      *     of a control string.
  526      * @return the substring from the start position
  527      *     to the beginning of the control string.
  528      */
  529     private String nonControl(String s,int start) {
  530       String ret="";
  531       cPos=s.indexOf("%",start);
  532       if (cPos==-1) cPos=s.length();
  533       return s.substring(start,cPos);
  534     }
  535     /**
  536      * Format an array of objects.  Byte, Short,
  537      * Integer, Long, Float, Double, and Character
  538      * arguments are treated as wrappers for primitive
  539      * types.
  540      * @param o The array of objects to format.
  541      * @return  The formatted String.
  542      */
  543     public String sprintf(Object[] o) {
  544       Enumeration e = vFmt.elements();
  545       ConversionSpecification cs = null;
  546       char c = 0;
  547       int i=0;
  548       StringBuffer sb=new StringBuffer();
  549       while (e.hasMoreElements()) {
  550         cs = (ConversionSpecification)
  551           e.nextElement();
  552         c = cs.getConversionCharacter();
  553         if (c=='\0') sb.append(cs.getLiteral());
  554         else if (c=='%') sb.append("%");
  555         else {
  556           if (cs.isPositionalSpecification()) {
  557             i=cs.getArgumentPosition()-1;
  558             if (cs.isPositionalFieldWidth()) {
  559               int ifw=cs.getArgumentPositionForFieldWidth()-1;
  560               cs.setFieldWidthWithArg(((Integer)o[ifw]).intValue());
  561             }
  562             if (cs.isPositionalPrecision()) {
  563               int ipr=cs.getArgumentPositionForPrecision()-1;
  564               cs.setPrecisionWithArg(((Integer)o[ipr]).intValue());
  565             }
  566           }
  567           else {
  568             if (cs.isVariableFieldWidth()) {
  569               cs.setFieldWidthWithArg(((Integer)o[i]).intValue());
  570               i++;
  571             }
  572             if (cs.isVariablePrecision()) {
  573               cs.setPrecisionWithArg(((Integer)o[i]).intValue());
  574               i++;
  575             }
  576           }
  577           if (o[i] instanceof Byte)
  578             sb.append(cs.internalsprintf(
  579             ((Byte)o[i]).byteValue()));
  580           else if (o[i] instanceof Short)
  581             sb.append(cs.internalsprintf(
  582             ((Short)o[i]).shortValue()));
  583           else if (o[i] instanceof Integer)
  584             sb.append(cs.internalsprintf(
  585             ((Integer)o[i]).intValue()));
  586           else if (o[i] instanceof Long)
  587             sb.append(cs.internalsprintf(
  588             ((Long)o[i]).longValue()));
  589           else if (o[i] instanceof Float)
  590             sb.append(cs.internalsprintf(
  591             ((Float)o[i]).floatValue()));
  592           else if (o[i] instanceof Double)
  593             sb.append(cs.internalsprintf(
  594             ((Double)o[i]).doubleValue()));
  595           else if (o[i] instanceof Character)
  596             sb.append(cs.internalsprintf(
  597             ((Character)o[i]).charValue()));
  598           else if (o[i] instanceof String)
  599             sb.append(cs.internalsprintf(
  600             (String)o[i]));
  601           else
  602             sb.append(cs.internalsprintf(
  603             o[i]));
  604           if (!cs.isPositionalSpecification())
  605             i++;
  606         }
  607       }
  608       return sb.toString();
  609     }
  610     /**
  611      * Format nothing.  Just use the control string.
  612      * @return  the formatted String.
  613      */
  614     public String sprintf() {
  615       Enumeration e = vFmt.elements();
  616       ConversionSpecification cs = null;
  617       char c = 0;
  618       StringBuffer sb=new StringBuffer();
  619       while (e.hasMoreElements()) {
  620         cs = (ConversionSpecification)
  621           e.nextElement();
  622         c = cs.getConversionCharacter();
  623         if (c=='\0') sb.append(cs.getLiteral());
  624         else if (c=='%') sb.append("%");
  625       }
  626       return sb.toString();
  627     }
  628     /**
  629      * Format an int.
  630      * @param x The int to format.
  631      * @return  The formatted String.
  632      * @exception IllegalArgumentException if the
  633      *     conversion character is f, e, E, g, G, s,
  634      *     or S.
  635      */
  636     public String sprintf(int x)
  637         throws IllegalArgumentException {
  638       Enumeration e = vFmt.elements();
  639       ConversionSpecification cs = null;
  640       char c = 0;
  641       StringBuffer sb=new StringBuffer();
  642       while (e.hasMoreElements()) {
  643         cs = (ConversionSpecification)
  644           e.nextElement();
  645         c = cs.getConversionCharacter();
  646         if (c=='\0') sb.append(cs.getLiteral());
  647         else if (c=='%') sb.append("%");
  648         else sb.append(cs.internalsprintf(x));
  649       }
  650       return sb.toString();
  651     }
  652     /**
  653      * Format an long.
  654      * @param x The long to format.
  655      * @return  The formatted String.
  656      * @exception IllegalArgumentException if the
  657      *     conversion character is f, e, E, g, G, s,
  658      *     or S.
  659      */
  660     public String sprintf(long x)
  661         throws IllegalArgumentException {
  662       Enumeration e = vFmt.elements();
  663       ConversionSpecification cs = null;
  664       char c = 0;
  665       StringBuffer sb=new StringBuffer();
  666       while (e.hasMoreElements()) {
  667         cs = (ConversionSpecification)
  668           e.nextElement();
  669         c = cs.getConversionCharacter();
  670         if (c=='\0') sb.append(cs.getLiteral());
  671         else if (c=='%') sb.append("%");
  672         else sb.append(cs.internalsprintf(x));
  673       }
  674       return sb.toString();
  675     }
  676     /**
  677      * Format a double.
  678      * @param x The double to format.
  679      * @return  The formatted String.
  680      * @exception IllegalArgumentException if the
  681      *     conversion character is c, C, s, S,
  682      *     d, d, x, X, or o.
  683      */
  684     public String sprintf(double x)
  685         throws IllegalArgumentException {
  686       Enumeration e = vFmt.elements();
  687       ConversionSpecification cs = null;
  688       char c = 0;
  689       StringBuffer sb=new StringBuffer();
  690       while (e.hasMoreElements()) {
  691         cs = (ConversionSpecification)
  692           e.nextElement();
  693         c = cs.getConversionCharacter();
  694         if (c=='\0') sb.append(cs.getLiteral());
  695         else if (c=='%') sb.append("%");
  696         else sb.append(cs.internalsprintf(x));
  697       }
  698       return sb.toString();
  699     }
  700     /**
  701      * Format a String.
  702      * @param x The String to format.
  703      * @return  The formatted String.
  704      * @exception IllegalArgumentException if the
  705      *   conversion character is neither s nor S.
  706      */
  707     public String sprintf(String x)
  708         throws IllegalArgumentException {
  709       Enumeration e = vFmt.elements();
  710       ConversionSpecification cs = null;
  711       char c = 0;
  712       StringBuffer sb=new StringBuffer();
  713       while (e.hasMoreElements()) {
  714         cs = (ConversionSpecification)
  715           e.nextElement();
  716         c = cs.getConversionCharacter();
  717         if (c=='\0') sb.append(cs.getLiteral());
  718         else if (c=='%') sb.append("%");
  719         else sb.append(cs.internalsprintf(x));
  720       }
  721       return sb.toString();
  722     }
  723     /**
  724      * Format an Object.  Convert wrapper types to
  725      * their primitive equivalents and call the
  726      * appropriate internal formatting method. Convert
  727      * Strings using an internal formatting method for
  728      * Strings. Otherwise use the default formatter
  729      * (use toString).
  730      * @param x the Object to format.
  731      * @return  the formatted String.
  732      * @exception IllegalArgumentException if the
  733      *    conversion character is inappropriate for
  734      *    formatting an unwrapped value.
  735      */
  736     public String sprintf(Object x)
  737         throws IllegalArgumentException {
  738       Enumeration e = vFmt.elements();
  739       ConversionSpecification cs = null;
  740       char c = 0;
  741       StringBuffer sb=new StringBuffer();
  742       while (e.hasMoreElements()) {
  743         cs = (ConversionSpecification)
  744           e.nextElement();
  745         c = cs.getConversionCharacter();
  746         if (c=='\0') sb.append(cs.getLiteral());
  747         else if (c=='%') sb.append("%");
  748         else {
  749           if (x instanceof Byte)
  750             sb.append(cs.internalsprintf(
  751             ((Byte)x).byteValue()));
  752           else if (x instanceof Short)
  753             sb.append(cs.internalsprintf(
  754             ((Short)x).shortValue()));
  755           else if (x instanceof Integer)
  756             sb.append(cs.internalsprintf(
  757             ((Integer)x).intValue()));
  758           else if (x instanceof Long)
  759             sb.append(cs.internalsprintf(
  760             ((Long)x).longValue()));
  761           else if (x instanceof Float)
  762             sb.append(cs.internalsprintf(
  763             ((Float)x).floatValue()));
  764           else if (x instanceof Double)
  765             sb.append(cs.internalsprintf(
  766             ((Double)x).doubleValue()));
  767           else if (x instanceof Character)
  768             sb.append(cs.internalsprintf(
  769             ((Character)x).charValue()));
  770           else if (x instanceof String)
  771             sb.append(cs.internalsprintf(
  772             (String)x));
  773           else
  774             sb.append(cs.internalsprintf(x));
  775         }
  776       }
  777       return sb.toString();
  778     }
  779     /**
  780      *<p>
  781      * ConversionSpecification allows the formatting of
  782      * a single primitive or object embedded within a
  783      * string.  The formatting is controlled by a
  784      * format string.  Only one Java primitive or
  785      * object can be formatted at a time.
  786      *<p>
  787      * A format string is a Java string that contains
  788      * a control string.  The control string starts at
  789      * the first percent sign (%) in the string,
  790      * provided that this percent sign
  791      *<ol>
  792      *<li>is not escaped protected by a matching % or
  793      *     is not an escape % character,
  794      *<li>is not at the end of the format string, and
  795      *<li>precedes a sequence of characters that parses
  796      *     as a valid control string.
  797      *</ol>
  798      *<p>
  799      * A control string takes the form:
  800      *<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
  801      *                { [hlL] }+ [idfgGoxXeEcs]
  802      *</pre>
  803      *<p>
  804      * The behavior is like printf.  One (hopefully the
  805      * only) exception is that the minimum number of
  806      * exponent digits is 3 instead of 2 for e and E
  807      * formats when the optional L is used before the
  808      * e, E, g, or G conversion character.  The 
  809      * optional L does not imply conversion to a long
  810      * long double.
  811      */
  812     private class ConversionSpecification {
  813       /**
  814        * Constructor.  Used to prepare an instance
  815        * to hold a literal, not a control string.
  816        */
  817       ConversionSpecification() { }
  818       /**
  819        * Constructor for a conversion specification.
  820        * The argument must begin with a % and end
  821        * with the conversion character for the
  822        * conversion specification.
  823         * @param fmtArg  String specifying the
  824        *     conversion specification.
  825         * @exception IllegalArgumentException if the
  826        *     input string is null, zero length, or
  827        *     otherwise malformed.
  828        */
  829       ConversionSpecification(String fmtArg)
  830           throws IllegalArgumentException {
  831         if (fmtArg==null)
  832           throw new NullPointerException();
  833         if (fmtArg.length()==0)
  834           throw new IllegalArgumentException(
  835           "Control strings must have positive"+
  836           " lengths.");
  837         if (fmtArg.charAt(0)=='%') {
  838           fmt = fmtArg;
  839           pos=1;
  840           setArgPosition();
  841           setFlagCharacters();
  842           setFieldWidth();
  843           setPrecision();
  844           setOptionalHL();
  845           if (setConversionCharacter()) {
  846             if (pos==fmtArg.length()) {
  847               if(leadingZeros&&leftJustify)
  848                 leadingZeros=false;
  849               if(precisionSet&&leadingZeros){
  850                 if(conversionCharacter=='d'
  851                 ||conversionCharacter=='i'
  852                 ||conversionCharacter=='o'
  853                 ||conversionCharacter=='x')
  854                 {
  855                   leadingZeros=false;
  856                 }
  857               }
  858             }
  859             else
  860               throw new IllegalArgumentException(
  861               "Malformed conversion specification="+
  862               fmtArg);
  863           }
  864           else
  865             throw new IllegalArgumentException(
  866             "Malformed conversion specification="+
  867             fmtArg);
  868         }
  869         else
  870           throw new IllegalArgumentException(
  871           "Control strings must begin with %.");
  872       }
  873       /**
  874        * Set the String for this instance.
  875        * @param s the String to store.
  876        */
  877       void setLiteral(String s) {
  878         fmt = s;
  879       }
  880       /**
  881        * Get the String for this instance.  Translate
  882        * any escape sequences.
  883        *
  884        * @return s the stored String.
  885        */
  886       String getLiteral() {
  887         StringBuffer sb=new StringBuffer();
  888         int i=0;
  889         while (i<fmt.length()) {
  890           if (fmt.charAt(i)=='\\') {
  891             i++;
  892             if (i<fmt.length()) {
  893               char c=fmt.charAt(i);
  894               switch(c) {
  895               case 'a':
  896                 sb.append((char)0x07);
  897                 break;
  898               case 'b':
  899                 sb.append('\b');
  900                 break;
  901               case 'f':
  902                 sb.append('\f');
  903                 break;
  904               case 'n':
  905                 sb.append(System.getProperty("line.separator"));
  906                 break;
  907               case 'r':
  908                 sb.append('\r');
  909                 break;
  910               case 't':
  911                 sb.append('\t');
  912                 break;
  913               case 'v':
  914                 sb.append((char)0x0b);
  915                 break;
  916               case '\\':
  917                 sb.append('\\');
  918                 break;
  919               }
  920               i++;
  921             }
  922             else
  923               sb.append('\\');
  924           }
  925           else
  926             i++;
  927         }
  928         return fmt;
  929       }
  930       /**
  931        * Get the conversion character that tells what
  932        * type of control character this instance has.
  933        *
  934        * @return the conversion character.
  935        */
  936       char getConversionCharacter() {
  937         return conversionCharacter;
  938       }
  939       /**
  940        * Check whether the specifier has a variable
  941        * field width that is going to be set by an
  942        * argument.
  943        * @return <code>true</code> if the conversion
  944        *   uses an * field width; otherwise
  945        *   <code>false</code>.
  946        */
  947       boolean isVariableFieldWidth() {
  948         return variableFieldWidth;
  949       }
  950       /**
  951        * Set the field width with an argument.  A
  952        * negative field width is taken as a - flag
  953        * followed by a positive field width.
  954        * @param fw the field width.
  955        */
  956       void setFieldWidthWithArg(int fw) {
  957         if (fw<0) leftJustify = true;
  958         fieldWidthSet = true;
  959         fieldWidth = Math.abs(fw);
  960       }
  961       /**
  962        * Check whether the specifier has a variable
  963        * precision that is going to be set by an
  964        * argument.
  965        * @return <code>true</code> if the conversion
  966        *   uses an * precision; otherwise
  967        *   <code>false</code>.
  968        */
  969       boolean isVariablePrecision() {
  970         return variablePrecision;
  971       }
  972       /**
  973        * Set the precision with an argument.  A
  974        * negative precision will be changed to zero.
  975        * @param pr the precision.
  976        */
  977       void setPrecisionWithArg(int pr) {
  978         precisionSet = true;
  979         precision = Math.max(pr,0);
  980       }
  981       /**
  982        * Format an int argument using this conversion
  983         * specification.
  984        * @param s the int to format.
  985        * @return the formatted String.
  986        * @exception IllegalArgumentException if the
  987        *     conversion character is f, e, E, g, or G.
  988        */
  989       String internalsprintf(int s)
  990           throws IllegalArgumentException {
  991         String s2 = "";
  992         switch(conversionCharacter) {
  993         case 'd':
  994         case 'i':
  995           if (optionalh)
  996             s2 = printDFormat((short)s);
  997           else if (optionall)
  998             s2 = printDFormat((long)s);
  999           else
 1000             s2 = printDFormat(s);
 1001           break;
 1002         case 'x':
 1003         case 'X':
 1004           if (optionalh)
 1005             s2 = printXFormat((short)s);
 1006           else if (optionall)
 1007             s2 = printXFormat((long)s);
 1008           else
 1009             s2 = printXFormat(s);
 1010           break;
 1011         case 'o':
 1012           if (optionalh)
 1013             s2 = printOFormat((short)s);
 1014           else if (optionall)
 1015             s2 = printOFormat((long)s);
 1016           else
 1017             s2 = printOFormat(s);
 1018           break;
 1019         case 'c':
 1020         case 'C':
 1021           s2 = printCFormat((char)s);
 1022           break;
 1023         default:
 1024           throw new IllegalArgumentException(
 1025             "Cannot format a int with a format using a "+
 1026             conversionCharacter+
 1027             " conversion character.");
 1028         }
 1029         return s2;
 1030       }
 1031       /**
 1032        * Format a long argument using this conversion
 1033        * specification.
 1034        * @param s the long to format.
 1035        * @return the formatted String.
 1036        * @exception IllegalArgumentException if the
 1037        *     conversion character is f, e, E, g, or G.
 1038        */
 1039       String internalsprintf(long s)
 1040           throws IllegalArgumentException {
 1041         String s2 = "";
 1042         switch(conversionCharacter) {
 1043         case 'd':
 1044         case 'i':
 1045           if (optionalh)
 1046             s2 = printDFormat((short)s);
 1047           else if (optionall)
 1048             s2 = printDFormat(s);
 1049           else
 1050             s2 = printDFormat((int)s);
 1051           break;
 1052         case 'x':
 1053         case 'X':
 1054           if (optionalh)
 1055             s2 = printXFormat((short)s);
 1056           else if (optionall)
 1057             s2 = printXFormat(s);
 1058           else
 1059             s2 = printXFormat((int)s);
 1060           break;
 1061         case 'o':
 1062           if (optionalh)
 1063             s2 = printOFormat((short)s);
 1064           else if (optionall)
 1065             s2 = printOFormat(s);
 1066           else
 1067             s2 = printOFormat((int)s);
 1068           break;
 1069         case 'c':
 1070         case 'C':
 1071           s2 = printCFormat((char)s);
 1072           break;
 1073         default:
 1074           throw new IllegalArgumentException(
 1075           "Cannot format a long with a format using a "+
 1076           conversionCharacter+" conversion character.");
 1077         }
 1078         return s2;
 1079       }
 1080       /**
 1081        * Format a double argument using this conversion
 1082        * specification.
 1083        * @param s the double to format.
 1084        * @return the formatted String.
 1085        * @exception IllegalArgumentException if the
 1086        *     conversion character is c, C, s, S, i, d,
 1087        *     x, X, or o.
 1088        */
 1089       String internalsprintf(double s)
 1090           throws IllegalArgumentException {
 1091         String s2 = "";
 1092         switch(conversionCharacter) {
 1093         case 'f':
 1094           s2 = printFFormat(s);
 1095           break;
 1096         case 'E':
 1097         case 'e':
 1098           s2 = printEFormat(s);
 1099           break;
 1100         case 'G':
 1101         case 'g':
 1102           s2 = printGFormat(s);
 1103           break;
 1104         default:
 1105           throw new IllegalArgumentException("Cannot "+
 1106           "format a double with a format using a "+
 1107           conversionCharacter+" conversion character.");
 1108         }
 1109         return s2;
 1110       }
 1111       /**
 1112        * Format a String argument using this conversion
 1113        * specification.
 1114        * @param s the String to format.
 1115        * @return the formatted String.
 1116        * @exception IllegalArgumentException if the
 1117        *   conversion character is neither s nor S.
 1118        */
 1119       String internalsprintf(String s)
 1120           throws IllegalArgumentException {
 1121         String s2 = "";
 1122         if(conversionCharacter=='s'
 1123         || conversionCharacter=='S')
 1124           s2 = printSFormat(s);
 1125         else
 1126           throw new IllegalArgumentException("Cannot "+
 1127           "format a String with a format using a "+
 1128           conversionCharacter+" conversion character.");
 1129         return s2;
 1130       }
 1131       /**
 1132        * Format an Object argument using this conversion
 1133        * specification.
 1134        * @param s the Object to format.
 1135        * @return the formatted String.
 1136        * @exception IllegalArgumentException if the
 1137        *     conversion character is neither s nor S.
 1138        */
 1139       String internalsprintf(Object s) {
 1140         String s2 = "";
 1141         if(conversionCharacter=='s'
 1142         || conversionCharacter=='S')
 1143           s2 = printSFormat(s.toString());
 1144         else
 1145           throw new IllegalArgumentException(
 1146             "Cannot format a String with a format using"+
 1147             " a "+conversionCharacter+
 1148             " conversion character.");
 1149         return s2;
 1150       }
 1151       /**
 1152        * For f format, the flag character '-', means that
 1153        * the output should be left justified within the
 1154        * field.  The default is to pad with blanks on the
 1155        * left.  '+' character means that the conversion
 1156        * will always begin with a sign (+ or -).  The
 1157        * blank flag character means that a non-negative
 1158        * input will be preceded with a blank.  If both
 1159        * a '+' and a ' ' are specified, the blank flag
 1160        * is ignored.  The '0' flag character implies that
 1161        * padding to the field width will be done with
 1162        * zeros instead of blanks.
 1163        *
 1164        * The field width is treated as the minimum number
 1165        * of characters to be printed.  The default is to
 1166        * add no padding.  Padding is with blanks by
 1167        * default.
 1168        *
 1169        * The precision, if set, is the number of digits
 1170        * to appear after the radix character.  Padding is
 1171        * with trailing 0s.
 1172        */
 1173       private char[] fFormatDigits(double x) {
 1174         // int defaultDigits=6;
 1175         String sx,sxOut;
 1176         int i,j,k;
 1177         int n1In,n2In;
 1178         int expon=0;
 1179         boolean minusSign=false;
 1180         if (x>0.0)
 1181           sx = Double.toString(x);
 1182         else if (x<0.0) {
 1183           sx = Double.toString(-x);
 1184           minusSign=true;
 1185         }
 1186         else {
 1187           sx = Double.toString(x);
 1188           if (sx.charAt(0)=='-') {
 1189             minusSign=true;
 1190             sx=sx.substring(1);
 1191           }
 1192         }
 1193         int ePos = sx.indexOf('E');
 1194         int rPos = sx.indexOf('.');
 1195         if (rPos!=-1) n1In=rPos;
 1196         else if (ePos!=-1) n1In=ePos;
 1197         else n1In=sx.length();
 1198         if (rPos!=-1) {
 1199           if (ePos!=-1) n2In = ePos-rPos-1;
 1200           else n2In = sx.length()-rPos-1;
 1201         }
 1202         else
 1203           n2In = 0;
 1204         if (ePos!=-1) {
 1205           int ie=ePos+1;
 1206           expon=0;
 1207           if (sx.charAt(ie)=='-') {
 1208             for (++ie; ie<sx.length(); ie++)
 1209               if (sx.charAt(ie)!='0') break;
 1210             if (ie<sx.length())
 1211               expon=-Integer.parseInt(sx.substring(ie));
 1212           }
 1213           else {
 1214             if (sx.charAt(ie)=='+') ++ie;
 1215             for (; ie<sx.length(); ie++)
 1216               if (sx.charAt(ie)!='0') break;
 1217             if (ie<sx.length())
 1218               expon=Integer.parseInt(sx.substring(ie));
 1219           }
 1220         }
 1221         int p;
 1222         if (precisionSet) p = precision;
 1223         else p = defaultDigits-1;
 1224         char[] ca1 = sx.toCharArray();
 1225         char[] ca2 = new char[n1In+n2In];
 1226         char[] ca3,ca4,ca5;
 1227         for (j=0; j<n1In; j++)
 1228           ca2[j] = ca1[j];
 1229         i = j+1;
 1230         for (k=0; k<n2In; j++,i++,k++)
 1231           ca2[j] = ca1[i];
 1232         if (n1In+expon<=0) {
 1233           ca3 = new char[-expon+n2In];
 1234           for (j=0,k=0; k<(-n1In-expon); k++,j++)
 1235             ca3[j]='0';
 1236           for (i=0; i<(n1In+n2In); i++,j++)
 1237             ca3[j]=ca2[i];
 1238         }
 1239         else
 1240           ca3 = ca2;
 1241         boolean carry=false;
 1242         if (p<-expon+n2In) {
 1243           if (expon<0) i = p;
 1244           else i = p+n1In;
 1245           carry=checkForCarry(ca3,i);
 1246           if (carry)
 1247             carry=startSymbolicCarry(ca3,i-1,0);
 1248         }
 1249         if (n1In+expon<=0) {
 1250           ca4 = new char[2+p];
 1251           if (!carry) ca4[0]='0';
 1252           else ca4[0]='1';
 1253           if(alternateForm||!precisionSet||precision!=0){
 1254             ca4[1]='.';
 1255             for(i=0,j=2;i<Math.min(p,ca3.length);i++,j++)
 1256               ca4[j]=ca3[i];
 1257             for (; j<ca4.length; j++) ca4[j]='0';
 1258           }
 1259         }
 1260         else {
 1261           if (!carry) {
 1262             if(alternateForm||!precisionSet
 1263             ||precision!=0)
 1264               ca4 = new char[n1In+expon+p+1];
 1265             else
 1266               ca4 = new char[n1In+expon];
 1267             j=0;
 1268           }
 1269           else {
 1270             if(alternateForm||!precisionSet
 1271             ||precision!=0)
 1272               ca4 = new char[n1In+expon+p+2];
 1273             else
 1274               ca4 = new char[n1In+expon+1];
 1275             ca4[0]='1';
 1276             j=1;
 1277           }
 1278           for (i=0; i<Math.min(n1In+expon,ca3.length); i++,j++)
 1279             ca4[j]=ca3[i];
 1280           for (; i<n1In+expon; i++,j++)
 1281             ca4[j]='0';
 1282           if(alternateForm||!precisionSet||precision!=0){
 1283             ca4[j]='.'; j++;
 1284             for (k=0; i<ca3.length && k<p; i++,j++,k++)
 1285               ca4[j]=ca3[i];
 1286             for (; j<ca4.length; j++) ca4[j]='0';
 1287           }
 1288         }
 1289         int nZeros=0;
 1290         if (!leftJustify && leadingZeros) {
 1291           int xThousands=0;
 1292           if (thousands) {
 1293             int xlead=0;
 1294             if (ca4[0]=='+'||ca4[0]=='-'||ca4[0]==' ')
 1295               xlead=1;
 1296             int xdp=xlead;
 1297             for (; xdp<ca4.length; xdp++)
 1298               if (ca4[xdp]=='.') break;
 1299             xThousands=(xdp-xlead)/3;
 1300           }
 1301           if (fieldWidthSet)
 1302             nZeros = fieldWidth-ca4.length;
 1303           if ((!minusSign&&(leadingSign||leadingSpace))||minusSign)
 1304             nZeros--;
 1305           nZeros-=xThousands;
 1306           if (nZeros<0) nZeros=0;
 1307         }
 1308         j=0;
 1309         if ((!minusSign&&(leadingSign||leadingSpace))||minusSign) {
 1310           ca5 = new char[ca4.length+nZeros+1];
 1311           j++;
 1312         }
 1313         else
 1314           ca5 = new char[ca4.length+nZeros];
 1315         if (!minusSign) {
 1316           if (leadingSign) ca5[0]='+';
 1317           if (leadingSpace) ca5[0]=' ';
 1318         }
 1319         else
 1320           ca5[0]='-';
 1321         for (i=0; i<nZeros; i++,j++)
 1322           ca5[j]='0';
 1323         for (i=0; i<ca4.length; i++,j++) ca5[j]=ca4[i];
 1324     
 1325         int lead=0;
 1326         if (ca5[0]=='+'||ca5[0]=='-'||ca5[0]==' ')
 1327           lead=1;
 1328         int dp=lead;
 1329         for (; dp<ca5.length; dp++)
 1330           if (ca5[dp]=='.') break;
 1331         int nThousands=(dp-lead)/3;
 1332         // Localize the decimal point.
 1333         if (dp<ca5.length)
 1334           ca5[dp]=dfs.getDecimalSeparator();
 1335         char[] ca6 = ca5;
 1336         if (thousands && nThousands>0) {
 1337           ca6 = new char[ca5.length+nThousands+lead];
 1338           ca6[0]=ca5[0];
 1339           for (i=lead,k=lead; i<dp; i++) {
 1340             if (i>0 && (dp-i)%3==0) {
 1341               // ca6[k]=',';
 1342               ca6[k]=dfs.getGroupingSeparator();
 1343               ca6[k+1]=ca5[i];
 1344               k+=2;
 1345             }
 1346             else {
 1347               ca6[k]=ca5[i]; k++;
 1348             }
 1349           }
 1350           for (; i<ca5.length; i++,k++) {
 1351             ca6[k]=ca5[i];
 1352   		}
 1353         }
 1354         return ca6;
 1355       }
 1356   	/**
 1357   	 * An intermediate routine on the way to creating
 1358   	 * an f format String.  The method decides whether
 1359   	 * the input double value is an infinity,
 1360   	 * not-a-number, or a finite double and formats
 1361   	 * each type of input appropriately.
 1362   	 * @param x the double value to be formatted.
 1363   	 * @return the converted double value.
 1364   	 */
 1365       private String fFormatString(double x) {
 1366         boolean noDigits=false;
 1367         char[] ca6,ca7;
 1368         if (Double.isInfinite(x)) {
 1369           if (x==Double.POSITIVE_INFINITY) {
 1370             if (leadingSign) ca6 = "+Inf".toCharArray();
 1371             else if (leadingSpace)
 1372               ca6 = " Inf".toCharArray();
 1373             else ca6 = "Inf".toCharArray();
 1374           }
 1375           else
 1376             ca6 = "-Inf".toCharArray();
 1377           noDigits = true;
 1378         }
 1379         else if (Double.isNaN(x)) {
 1380           if (leadingSign) ca6 = "+NaN".toCharArray();
 1381           else if (leadingSpace)
 1382             ca6 = " NaN".toCharArray();
 1383           else ca6 = "NaN".toCharArray();
 1384           noDigits = true;
 1385         }
 1386         else
 1387           ca6 = fFormatDigits(x);
 1388         ca7 = applyFloatPadding(ca6,false);
 1389         return new String(ca7);
 1390       }
 1391       /**
 1392        * For e format, the flag character '-', means that
 1393        * the output should be left justified within the
 1394        * field.  The default is to pad with blanks on the
 1395        * left.  '+' character means that the conversion
 1396        * will always begin with a sign (+ or -).  The
 1397        * blank flag character means that a non-negative
 1398        * input will be preceded with a blank.  If both a
 1399        * '+' and a ' ' are specified, the blank flag is
 1400        * ignored.  The '0' flag character implies that
 1401        * padding to the field width will be done with
 1402        * zeros instead of blanks.
 1403        *
 1404        * The field width is treated as the minimum number
 1405        * of characters to be printed.  The default is to
 1406        * add no padding.  Padding is with blanks by
 1407        * default.
 1408        *
 1409        * The precision, if set, is the minimum number of
 1410        * digits to appear after the radix character.
 1411        * Padding is with trailing 0s.
 1412        *
 1413        * The behavior is like printf.  One (hopefully the
 1414        * only) exception is that the minimum number of
 1415        * exponent digits is 3 instead of 2 for e and E
 1416        * formats when the optional L is used before the
 1417        * e, E, g, or G conversion character. The optional
 1418        * L does not imply conversion to a long long
 1419        * double.
 1420        */
 1421       private char[] eFormatDigits(double x,char eChar) {
 1422         char[] ca1,ca2,ca3;
 1423         // int defaultDigits=6;
 1424         String sx,sxOut;
 1425         int i,j,k,p;
 1426         int n1In,n2In;
 1427         int expon=0;
 1428         int ePos,rPos,eSize;
 1429         boolean minusSign=false;
 1430         if (x>0.0)
 1431           sx = Double.toString(x);
 1432         else if (x<0.0) {
 1433           sx = Double.toString(-x);
 1434           minusSign=true;
 1435         }
 1436         else {
 1437           sx = Double.toString(x);
 1438           if (sx.charAt(0)=='-') {
 1439             minusSign=true;
 1440             sx=sx.substring(1);
 1441           }
 1442         }
 1443         ePos = sx.indexOf('E');
 1444         if (ePos==-1) ePos = sx.indexOf('e');
 1445         rPos = sx.indexOf('.');
 1446         if (rPos!=-1) n1In=rPos;
 1447         else if (ePos!=-1) n1In=ePos;
 1448         else n1In=sx.length();
 1449         if (rPos!=-1) {
 1450           if (ePos!=-1) n2In = ePos-rPos-1;
 1451           else n2In = sx.length()-rPos-1;
 1452         }
 1453         else
 1454           n2In = 0;
 1455         if (ePos!=-1) {
 1456           int ie=ePos+1;
 1457           expon=0;
 1458           if (sx.charAt(ie)=='-') {
 1459             for (++ie; ie<sx.length(); ie++)
 1460               if (sx.charAt(ie)!='0') break;
 1461             if (ie<sx.length())
 1462               expon=-Integer.parseInt(sx.substring(ie));
 1463           }
 1464           else {
 1465             if (sx.charAt(ie)=='+') ++ie;
 1466             for (; ie<sx.length(); ie++)
 1467               if (sx.charAt(ie)!='0') break;
 1468             if (ie<sx.length())
 1469               expon=Integer.parseInt(sx.substring(ie));
 1470           }
 1471         }
 1472         if (rPos!=-1) expon += rPos-1;
 1473         if (precisionSet) p = precision;
 1474         else p = defaultDigits-1;
 1475         if (rPos!=-1 && ePos!=-1)
 1476           ca1=(sx.substring(0,rPos)+
 1477             sx.substring(rPos+1,ePos)).toCharArray();
 1478         else if (rPos!=-1)
 1479           ca1 = (sx.substring(0,rPos)+
 1480               sx.substring(rPos+1)).toCharArray();
 1481         else if (ePos!=-1)
 1482           ca1 = sx.substring(0,ePos).toCharArray();
 1483         else
 1484           ca1 = sx.toCharArray();
 1485         boolean carry=false;
 1486         int i0=0;
 1487         if (ca1[0]!='0')
 1488           i0 = 0;
 1489         else
 1490           for (i0=0; i0<ca1.length; i0++)
 1491             if (ca1[i0]!='0') break;
 1492         if (i0+p<ca1.length-1) {
 1493           carry=checkForCarry(ca1,i0+p+1);
 1494           if (carry)
 1495             carry = startSymbolicCarry(ca1,i0+p,i0);
 1496           if (carry) {
 1497             ca2 = new char[i0+p+1];
 1498             ca2[i0]='1';
 1499             for (j=0; j<i0; j++) ca2[j]='0';
 1500             for (i=i0,j=i0+1; j<p+1; i++,j++)
 1501               ca2[j] = ca1[i];
 1502             expon++;
 1503             ca1 = ca2;
 1504           }
 1505         }
 1506         if (Math.abs(expon)<100 && !optionalL) eSize=4;
 1507         else eSize=5;
 1508         if (alternateForm||!precisionSet||precision!=0)
 1509           ca2 = new char[2+p+eSize];
 1510         else
 1511           ca2 = new char[1+eSize];
 1512         if (ca1[0]!='0') {
 1513           ca2[0] = ca1[0];
 1514           j=1;
 1515         }
 1516         else {
 1517           for (j=1; j<(ePos==-1?ca1.length:ePos); j++)
 1518             if (ca1[j]!='0') break;
 1519           if ((ePos!=-1 && j<ePos)||
 1520               (ePos==-1 && j<ca1.length)) {
 1521             ca2[0] = ca1[j];
 1522             expon -= j;
 1523             j++;
 1524           }
 1525           else {
 1526             ca2[0]='0';
 1527             j=2;
 1528           }
 1529         }
 1530         if (alternateForm||!precisionSet||precision!=0) {
 1531           ca2[1] = '.';
 1532           i=2;
 1533         }
 1534         else
 1535           i=1;
 1536         for (k=0; k<p && j<ca1.length; j++,i++,k++)
 1537           ca2[i] = ca1[j];
 1538         for (;i<ca2.length-eSize; i++)
 1539           ca2[i] = '0';
 1540         ca2[i++] = eChar;
 1541         if (expon<0) ca2[i++]='-';
 1542         else ca2[i++]='+';
 1543         expon = Math.abs(expon);
 1544         if (expon>=100) {
 1545           switch(expon/100) {
 1546           case 1: ca2[i]='1'; break;
 1547           case 2: ca2[i]='2'; break;
 1548           case 3: ca2[i]='3'; break;
 1549           case 4: ca2[i]='4'; break;
 1550           case 5: ca2[i]='5'; break;
 1551           case 6: ca2[i]='6'; break;
 1552           case 7: ca2[i]='7'; break;
 1553           case 8: ca2[i]='8'; break;
 1554           case 9: ca2[i]='9'; break;
 1555           }
 1556           i++;
 1557         }
 1558         switch((expon%100)/10) {
 1559         case 0: ca2[i]='0'; break;
 1560         case 1: ca2[i]='1'; break;
 1561         case 2: ca2[i]='2'; break;
 1562         case 3: ca2[i]='3'; break;
 1563         case 4: ca2[i]='4'; break;
 1564         case 5: ca2[i]='5'; break;
 1565         case 6: ca2[i]='6'; break;
 1566         case 7: ca2[i]='7'; break;
 1567         case 8: ca2[i]='8'; break;
 1568         case 9: ca2[i]='9'; break;
 1569         }
 1570         i++;
 1571         switch(expon%10) {
 1572         case 0: ca2[i]='0'; break;
 1573         case 1: ca2[i]='1'; break;
 1574         case 2: ca2[i]='2'; break;
 1575         case 3: ca2[i]='3'; break;
 1576         case 4: ca2[i]='4'; break;
 1577         case 5: ca2[i]='5'; break;
 1578         case 6: ca2[i]='6'; break;
 1579         case 7: ca2[i]='7'; break;
 1580         case 8: ca2[i]='8'; break;
 1581         case 9: ca2[i]='9'; break;
 1582         }
 1583         int nZeros=0;
 1584         if (!leftJustify && leadingZeros) {
 1585           int xThousands=0;
 1586           if (thousands) {
 1587             int xlead=0;
 1588             if (ca2[0]=='+'||ca2[0]=='-'||ca2[0]==' ')
 1589               xlead=1;
 1590             int xdp=xlead;
 1591             for (; xdp<ca2.length; xdp++)
 1592               if (ca2[xdp]=='.') break;
 1593             xThousands=(xdp-xlead)/3;
 1594           }
 1595           if (fieldWidthSet)
 1596             nZeros = fieldWidth-ca2.length;
 1597           if ((!minusSign&&(leadingSign||leadingSpace))||minusSign)
 1598             nZeros--;
 1599           nZeros-=xThousands;
 1600           if (nZeros<0) nZeros=0;
 1601         }
 1602         j=0;
 1603         if ((!minusSign&&(leadingSign || leadingSpace))||minusSign) {
 1604           ca3 = new char[ca2.length+nZeros+1];
 1605           j++;
 1606         }
 1607         else
 1608           ca3 = new char[ca2.length+nZeros];
 1609         if (!minusSign) {
 1610           if (leadingSign) ca3[0]='+';
 1611           if (leadingSpace) ca3[0]=' ';
 1612         }
 1613         else
 1614           ca3[0]='-';
 1615         for (k=0; k<nZeros; j++,k++)
 1616           ca3[j]='0';
 1617         for (i=0; i<ca2.length && j<ca3.length; i++,j++)
 1618           ca3[j]=ca2[i];
 1619     
 1620         int lead=0;
 1621         if (ca3[0]=='+'||ca3[0]=='-'||ca3[0]==' ')
 1622           lead=1;
 1623         int dp=lead;
 1624         for (; dp<ca3.length; dp++)
 1625           if (ca3[dp]=='.') break;
 1626         int nThousands=dp/3;
 1627         // Localize the decimal point.
 1628         if (dp < ca3.length)
 1629           ca3[dp] = dfs.getDecimalSeparator();
 1630         char[] ca4 = ca3;
 1631         if (thousands && nThousands>0) {
 1632           ca4 = new char[ca3.length+nThousands+lead];
 1633           ca4[0]=ca3[0];
 1634           for (i=lead,k=lead; i<dp; i++) {
 1635             if (i>0 && (dp-i)%3==0) {
 1636               // ca4[k]=',';
 1637               ca4[k]=dfs.getGroupingSeparator();
 1638               ca4[k+1]=ca3[i];
 1639               k+=2;
 1640             }
 1641             else {
 1642               ca4[k]=ca3[i]; k++;
 1643             }
 1644           }
 1645           for (; i<ca3.length; i++,k++)
 1646             ca4[k]=ca3[i];
 1647         }
 1648         return ca4;
 1649       }
 1650       /**
 1651        * Check to see if the digits that are going to
 1652        * be truncated because of the precision should
 1653        * force a round in the preceding digits.
 1654        * @param ca1 the array of digits
 1655        * @param icarry the index of the first digit that
 1656        *     is to be truncated from the print
 1657        * @return <code>true</code> if the truncation forces
 1658        *     a round that will change the print
 1659        */
 1660       private boolean checkForCarry(char[] ca1,int icarry) {
 1661         boolean carry=false;
 1662         if (icarry<ca1.length) {
 1663           if (ca1[icarry]=='6'||ca1[icarry]=='7'
 1664           ||ca1[icarry]=='8'||ca1[icarry]=='9') carry=true;
 1665           else if (ca1[icarry]=='5') {
 1666             int ii=icarry+1;
 1667             for (;ii<ca1.length; ii++)
 1668               if (ca1[ii]!='0') break;
 1669             carry=ii<ca1.length;
 1670             if (!carry&&icarry>0) {
 1671               carry=(ca1[icarry-1]=='1'||ca1[icarry-1]=='3'
 1672                 ||ca1[icarry-1]=='5'||ca1[icarry-1]=='7'
 1673                 ||ca1[icarry-1]=='9');
 1674             }
 1675           }
 1676         }
 1677         return carry;
 1678       }
 1679       /**
 1680        * Start the symbolic carry process.  The process
 1681        * is not quite finished because the symbolic
 1682        * carry may change the length of the string and
 1683        * change the exponent (in e format).
 1684        * @param cLast index of the last digit changed
 1685        *     by the round
 1686        * @param cFirst index of the first digit allowed
 1687        *     to be changed by this phase of the round
 1688        * @return <code>true</code> if the carry forces
 1689        *     a round that will change the print still
 1690        *     more
 1691        */
 1692       private boolean startSymbolicCarry(
 1693                 char[] ca,int cLast,int cFirst) {
 1694         boolean carry=true;
 1695         for (int i=cLast; carry && i>=cFirst; i--) {
 1696           carry = false;
 1697           switch(ca[i]) {
 1698           case '0': ca[i]='1'; break;
 1699           case '1': ca[i]='2'; break;
 1700           case '2': ca[i]='3'; break;
 1701           case '3': ca[i]='4'; break;
 1702           case '4': ca[i]='5'; break;
 1703           case '5': ca[i]='6'; break;
 1704           case '6': ca[i]='7'; break;
 1705           case '7': ca[i]='8'; break;
 1706           case '8': ca[i]='9'; break;
 1707           case '9': ca[i]='0'; carry=true; break;
 1708           }
 1709         }
 1710         return carry;
 1711       }
 1712   	/**
 1713   	 * An intermediate routine on the way to creating
 1714   	 * an e format String.  The method decides whether
 1715   	 * the input double value is an infinity,
 1716   	 * not-a-number, or a finite double and formats
 1717   	 * each type of input appropriately.
 1718   	 * @param x the double value to be formatted.
 1719   	 * @param eChar an 'e' or 'E' to use in the
 1720   	 *     converted double value.
 1721   	 * @return the converted double value.
 1722   	 */
 1723       private String eFormatString(double x,char eChar) {
 1724         boolean noDigits=false;
 1725         char[] ca4,ca5;
 1726         if (Double.isInfinite(x)) {
 1727           if (x==Double.POSITIVE_INFINITY) {
 1728             if (leadingSign) ca4 = "+Inf".toCharArray();
 1729             else if (leadingSpace)
 1730               ca4 = " Inf".toCharArray();
 1731             else ca4 = "Inf".toCharArray();
 1732           }
 1733           else
 1734             ca4 = "-Inf".toCharArray();
 1735           noDigits = true;
 1736         }
 1737         else if (Double.isNaN(x)) {
 1738           if (leadingSign) ca4 = "+NaN".toCharArray();
 1739           else if (leadingSpace)
 1740             ca4 = " NaN".toCharArray();
 1741           else ca4 = "NaN".toCharArray();
 1742           noDigits = true;
 1743         }
 1744         else
 1745           ca4 = eFormatDigits(x,eChar);
 1746         ca5 = applyFloatPadding(ca4,false);
 1747         return new String(ca5);
 1748       }
 1749       /**
 1750        * Apply zero or blank, left or right padding.
 1751        * @param ca4 array of characters before padding is
 1752        *     finished
 1753        * @param noDigits NaN or signed Inf
 1754        * @return a padded array of characters
 1755        */
 1756       private char[] applyFloatPadding(
 1757             char[] ca4,boolean noDigits) {
 1758         char[] ca5 = ca4;
 1759         if (fieldWidthSet) {
 1760           int i,j,nBlanks;
 1761           if (leftJustify) {
 1762             nBlanks = fieldWidth-ca4.length;
 1763             if (nBlanks > 0) {
 1764               ca5 = new char[ca4.length+nBlanks];
 1765               for (i=0; i<ca4.length; i++)
 1766                 ca5[i] = ca4[i];
 1767               for (j=0; j<nBlanks; j++,i++)
 1768                 ca5[i] = ' ';
 1769             }
 1770           }
 1771           else if (!leadingZeros || noDigits) {
 1772             nBlanks = fieldWidth-ca4.length;
 1773             if (nBlanks > 0) {
 1774               ca5 = new char[ca4.length+nBlanks];
 1775               for (i=0; i<nBlanks; i++)
 1776                 ca5[i] = ' ';
 1777               for (j=0; j<ca4.length; i++,j++)
 1778                 ca5[i] = ca4[j];
 1779             }
 1780           }
 1781           else if (leadingZeros) {
 1782             nBlanks = fieldWidth-ca4.length;
 1783             if (nBlanks > 0) {
 1784               ca5 = new char[ca4.length+nBlanks];
 1785               i=0; j=0;
 1786               if (ca4[0]=='-') { ca5[0]='-'; i++; j++; }
 1787               for (int k=0; k<nBlanks; i++,k++)
 1788                 ca5[i] = '0';
 1789               for (; j<ca4.length; i++,j++)
 1790                 ca5[i] = ca4[j];
 1791             }
 1792           }
 1793         }
 1794         return ca5;
 1795       }
 1796       /**
 1797        * Format method for the f conversion character.
 1798        * @param x the double to format.
 1799        * @return the formatted String.
 1800        */
 1801       private String printFFormat(double x) {
 1802         return fFormatString(x);
 1803       }
 1804       /**
 1805        * Format method for the e or E conversion
 1806        * character.
 1807        * @param x the double to format.
 1808        * @return the formatted String.
 1809        */
 1810       private String printEFormat(double x) {
 1811         if (conversionCharacter=='e')
 1812           return eFormatString(x,'e');
 1813         else
 1814           return eFormatString(x,'E');
 1815       }
 1816       /**
 1817        * Format method for the g conversion character.
 1818        *
 1819        * For g format, the flag character '-', means that
 1820        *  the output should be left justified within the
 1821        * field.  The default is to pad with blanks on the
 1822        * left.  '+' character means that the conversion
 1823        * will always begin with a sign (+ or -).  The
 1824        * blank flag character means that a non-negative
 1825        * input will be preceded with a blank.  If both a
 1826        * '+' and a ' ' are specified, the blank flag is
 1827        * ignored.  The '0' flag character implies that
 1828        * padding to the field width will be done with
 1829        * zeros instead of blanks.
 1830        *
 1831        * The field width is treated as the minimum number
 1832        * of characters to be printed.  The default is to
 1833        * add no padding.  Padding is with blanks by
 1834        * default.
 1835        *
 1836        * The precision, if set, is the minimum number of
 1837        * digits to appear after the radix character.
 1838        * Padding is with trailing 0s.
 1839        * @param x the double to format.
 1840        * @return the formatted String.
 1841        */
 1842       private String printGFormat(double x) {
 1843         String sx,sy,sz,ret;
 1844         int savePrecision=precision;
 1845         int i;
 1846         char[] ca4,ca5;
 1847         boolean noDigits=false;
 1848         if (Double.isInfinite(x)) {
 1849           if (x==Double.POSITIVE_INFINITY) {
 1850             if (leadingSign) ca4 = "+Inf".toCharArray();
 1851             else if (leadingSpace)
 1852               ca4 = " Inf".toCharArray();
 1853             else ca4 = "Inf".toCharArray();
 1854           }
 1855           else
 1856             ca4 = "-Inf".toCharArray();
 1857           noDigits = true;
 1858         }
 1859         else if (Double.isNaN(x)) {
 1860           if (leadingSign) ca4 = "+NaN".toCharArray();
 1861           else if (leadingSpace)
 1862             ca4 = " NaN".toCharArray();
 1863           else ca4 = "NaN".toCharArray();
 1864           noDigits = true;
 1865         }
 1866         else {
 1867           if (!precisionSet) precision=defaultDigits;
 1868           if (precision==0) precision=1;
 1869           int ePos=-1;
 1870           if (conversionCharacter=='g') {
 1871             sx = eFormatString(x,'e').trim();
 1872             ePos=sx.indexOf('e');
 1873           }
 1874           else {
 1875             sx = eFormatString(x,'E').trim();
 1876             ePos=sx.indexOf('E');
 1877           }
 1878           i=ePos+1;
 1879           int expon=0;
 1880           if (sx.charAt(i)=='-') {
 1881             for (++i; i<sx.length(); i++)
 1882               if (sx.charAt(i)!='0') break;
 1883             if (i<sx.length())
 1884               expon=-Integer.parseInt(sx.substring(i));
 1885           }
 1886           else {
 1887             if (sx.charAt(i)=='+') ++i;
 1888             for (; i<sx.length(); i++)
 1889               if (sx.charAt(i)!='0') break;
 1890             if (i<sx.length())
 1891               expon=Integer.parseInt(sx.substring(i));
 1892           }
 1893           // Trim trailing zeros.
 1894           // If the radix character is not followed by
 1895           // a digit, trim it, too.
 1896           if (!alternateForm) {
 1897             if (expon>=-4 && expon<precision)
 1898               sy = fFormatString(x).trim();
 1899             else
 1900               sy = sx.substring(0,ePos);
 1901             i=sy.length()-1;
 1902             for (; i>=0; i--)
 1903               if (sy.charAt(i)!='0') break;
 1904             if (i>=0 && sy.charAt(i)=='.') i--;
 1905             if (i==-1) sz="0";
 1906             else if (!Character.isDigit(sy.charAt(i)))
 1907               sz=sy.substring(0,i+1)+"0";
 1908             else sz=sy.substring(0,i+1);
 1909             if (expon>=-4 && expon<precision)
 1910               ret=sz;
 1911             else
 1912               ret=sz+sx.substring(ePos);
 1913           }
 1914           else {
 1915             if (expon>=-4 && expon<precision)
 1916               ret = fFormatString(x).trim();
 1917             else
 1918               ret = sx;
 1919           }
 1920           // leading space was trimmed off during
 1921           // construction
 1922           if (leadingSpace) if (x>=0) ret = " "+ret;
 1923           ca4 = ret.toCharArray();
 1924         }
 1925         // Pad with blanks or zeros.
 1926         ca5 = applyFloatPadding(ca4,false);
 1927         precision=savePrecision;
 1928         return new String(ca5);
 1929       }
 1930       /**
 1931        * Format method for the d conversion specifer and
 1932        * short argument.
 1933        *
 1934        * For d format, the flag character '-', means that
 1935        * the output should be left justified within the
 1936        * field.  The default is to pad with blanks on the
 1937        * left.  A '+' character means that the conversion
 1938        * will always begin with a sign (+ or -).  The
 1939        * blank flag character means that a non-negative
 1940        * input will be preceded with a blank.  If both a
 1941        * '+' and a ' ' are specified, the blank flag is
 1942        * ignored.  The '0' flag character implies that
 1943        * padding to the field width will be done with
 1944        * zeros instead of blanks.
 1945        *
 1946        * The field width is treated as the minimum number
 1947        * of characters to be printed.  The default is to
 1948        * add no padding.  Padding is with blanks by
 1949        * default.
 1950        *
 1951        * The precision, if set, is the minimum number of
 1952        * digits to appear.  Padding is with leading 0s.
 1953        * @param x the short to format.
 1954        * @return the formatted String.
 1955        */
 1956       private String printDFormat(short x) {
 1957         return printDFormat(Short.toString(x));
 1958       }
 1959       /**
 1960        * Format method for the d conversion character and
 1961        * long argument.
 1962        *
 1963        * For d format, the flag character '-', means that
 1964        * the output should be left justified within the
 1965        * field.  The default is to pad with blanks on the
 1966        * left.  A '+' character means that the conversion
 1967        * will always begin with a sign (+ or -).  The
 1968        * blank flag character means that a non-negative
 1969        * input will be preceded with a blank.  If both a
 1970        * '+' and a ' ' are specified, the blank flag is
 1971        * ignored.  The '0' flag character implies that
 1972        * padding to the field width will be done with
 1973        * zeros instead of blanks.
 1974        *
 1975        * The field width is treated as the minimum number
 1976        * of characters to be printed.  The default is to
 1977        * add no padding.  Padding is with blanks by
 1978        * default.
 1979        *
 1980        * The precision, if set, is the minimum number of
 1981        * digits to appear.  Padding is with leading 0s.
 1982        * @param x the long to format.
 1983        * @return the formatted String.
 1984        */
 1985       private String printDFormat(long x) {
 1986         return printDFormat(Long.toString(x));
 1987       }
 1988       /**
 1989        * Format method for the d conversion character and
 1990        * int argument.
 1991        *
 1992        * For d format, the flag character '-', means that
 1993        * the output should be left justified within the
 1994        * field.  The default is to pad with blanks on the
 1995        * left.  A '+' character means that the conversion
 1996        * will always begin with a sign (+ or -).  The
 1997        * blank flag character means that a non-negative
 1998        * input will be preceded with a blank.  If both a
 1999        * '+' and a ' ' are specified, the blank flag is
 2000        * ignored.  The '0' flag character implies that
 2001        * padding to the field width will be done with
 2002        * zeros instead of blanks.
 2003        *
 2004        * The field width is treated as the minimum number
 2005        * of characters to be printed.  The default is to
 2006        * add no padding.  Padding is with blanks by
 2007        * default.
 2008        *
 2009        * The precision, if set, is the minimum number of
 2010        * digits to appear.  Padding is with leading 0s.
 2011        * @param x the int to format.
 2012        * @return the formatted String.
 2013        */
 2014       private String printDFormat(int x) {
 2015         return printDFormat(Integer.toString(x));
 2016       }
 2017       /**
 2018        * Utility method for formatting using the d
 2019        * conversion character.
 2020        * @param sx the String to format, the result of
 2021        *     converting a short, int, or long to a
 2022        *     String.
 2023        * @return the formatted String.
 2024        */
 2025       private String printDFormat(String sx) {
 2026         int nLeadingZeros=0;
 2027         int nBlanks=0,n=0;
 2028         int i=0,jFirst=0;
 2029         boolean neg = sx.charAt(0)=='-';
 2030         if (sx.equals("0")&&precisionSet&&precision==0)
 2031           sx="";
 2032         if (!neg) {
 2033           if (precisionSet && sx.length() < precision)
 2034             nLeadingZeros = precision-sx.length();
 2035         }
 2036         else {
 2037           if (precisionSet&&(sx.length()-1)<precision)
 2038             nLeadingZeros = precision-sx.length()+1;
 2039         }
 2040         if (nLeadingZeros<0) nLeadingZeros=0;
 2041         if (fieldWidthSet) {
 2042           nBlanks = fieldWidth-nLeadingZeros-sx.length();
 2043           if (!neg&&(leadingSign||leadingSpace))
 2044             nBlanks--;
 2045         }
 2046         if (nBlanks<0) nBlanks=0;
 2047         if (leadingSign) n++;
 2048         else if (leadingSpace) n++;
 2049         n += nBlanks;
 2050         n += nLeadingZeros;
 2051         n += sx.length();
 2052         char[] ca = new char[n];
 2053         if (leftJustify) {
 2054           if (neg) ca[i++] = '-';
 2055           else if (leadingSign) ca[i++] = '+';
 2056           else if (leadingSpace) ca[i++] = ' ';
 2057           char[] csx = sx.toCharArray();
 2058           jFirst = neg?1:0;
 2059           for (int j=0; j<nLeadingZeros; i++,j++) 
 2060             ca[i]='0';
 2061           for (int j=jFirst; j<csx.length; j++,i++)
 2062             ca[i] = csx[j];
 2063           for (int j=0; j<nBlanks; i++,j++)
 2064             ca[i] = ' ';
 2065         }
 2066         else {
 2067           if (!leadingZeros) {
 2068             for (i=0; i<nBlanks; i++)
 2069               ca[i] = ' ';
 2070             if (neg) ca[i++] = '-';
 2071             else if (leadingSign) ca[i++] = '+';
 2072             else if (leadingSpace) ca[i++] = ' ';
 2073           }
 2074           else {
 2075             if (neg) ca[i++] = '-';
 2076             else if (leadingSign) ca[i++] = '+';
 2077             else if (leadingSpace) ca[i++] = ' ';
 2078             for (int j=0; j<nBlanks; j++,i++)
 2079               ca[i] = '0';
 2080           }
 2081           for (int j=0; j<nLeadingZeros; j++,i++)
 2082             ca[i] = '0';
 2083           char[] csx = sx.toCharArray();
 2084           jFirst = neg?1:0;
 2085           for (int j=jFirst; j<csx.length; j++,i++)
 2086             ca[i] = csx[j];
 2087         }
 2088         return new String(ca);
 2089       }
 2090       /**
 2091        * Format method for the x conversion character and
 2092        * short argument.
 2093        *
 2094        * For x format, the flag character '-', means that
 2095        * the output should be left justified within the
 2096        * field.  The default is to pad with blanks on the
 2097        * left.  The '#' flag character means to lead with
 2098        * '0x'.
 2099        *
 2100        * The field width is treated as the minimum number
 2101        * of characters to be printed.  The default is to
 2102        * add no padding.  Padding is with blanks by
 2103        * default.
 2104        *
 2105        * The precision, if set, is the minimum number of
 2106        * digits to appear.  Padding is with leading 0s.
 2107        * @param x the short to format.
 2108        * @return the formatted String.
 2109        */
 2110       private String printXFormat(short x) {
 2111         String sx=null;
 2112         if (x == Short.MIN_VALUE)
 2113           sx = "8000";
 2114         else if (x < 0) {
 2115           String t;
 2116           if (x==Short.MIN_VALUE)
 2117             t = "0";
 2118           else {
 2119             t = Integer.toString(
 2120               (~(-x-1))^Short.MIN_VALUE,16);
 2121             if (t.charAt(0)=='F'||t.charAt(0)=='f')
 2122               t = t.substring(16,32);
 2123           }
 2124           switch (t.length()) {
 2125           case 1:
 2126             sx = "800"+t;
 2127             break;
 2128           case 2:
 2129             sx = "80"+t;
 2130             break;
 2131           case 3:
 2132             sx = "8"+t;
 2133             break;
 2134           case 4:
 2135             switch (t.charAt(0)) {
 2136             case '1':
 2137               sx = "9"+t.substring(1,4);
 2138               break;
 2139             case '2':
 2140               sx = "a"+t.substring(1,4);
 2141               break;
 2142             case '3':
 2143               sx = "b"+t.substring(1,4);
 2144               break;
 2145             case '4':
 2146               sx = "c"+t.substring(1,4);
 2147               break;
 2148             case '5':
 2149               sx = "d"+t.substring(1,4);
 2150               break;
 2151             case '6':
 2152               sx = "e"+t.substring(1,4);
 2153               break;
 2154             case '7':
 2155               sx = "f"+t.substring(1,4);
 2156               break;
 2157             }
 2158             break;
 2159           }
 2160         }
 2161         else
 2162           sx = Integer.toString((int)x,16);
 2163         return printXFormat(sx);
 2164       }
 2165       /**
 2166        * Format method for the x conversion character and
 2167        * long argument.
 2168        *
 2169        * For x format, the flag character '-', means that
 2170        * the output should be left justified within the
 2171        * field.  The default is to pad with blanks on the
 2172        * left.  The '#' flag character means to lead with
 2173        * '0x'.
 2174        *
 2175        * The field width is treated as the minimum number
 2176        * of characters to be printed.  The default is to
 2177        * add no padding.  Padding is with blanks by
 2178        * default.
 2179        *
 2180        * The precision, if set, is the minimum number of
 2181        * digits to appear.  Padding is with leading 0s.
 2182        * @param x the long to format.
 2183        * @return the formatted String.
 2184        */
 2185       private String printXFormat(long x) {
 2186         String sx=null;
 2187         if (x == Long.MIN_VALUE)
 2188           sx = "8000000000000000";
 2189         else if (x < 0) {
 2190           String t = Long.toString(
 2191             (~(-x-1))^Long.MIN_VALUE,16);
 2192           switch (t.length()) {
 2193           case 1:
 2194             sx = "800000000000000"+t;
 2195             break;
 2196           case 2:
 2197             sx = "80000000000000"+t;
 2198             break;
 2199           case 3:
 2200             sx = "8000000000000"+t;
 2201             break;
 2202           case 4:
 2203             sx = "800000000000"+t;
 2204             break;
 2205           case 5:
 2206             sx = "80000000000"+t;
 2207             break;
 2208           case 6:
 2209             sx = "8000000000"+t;
 2210             break;
 2211           case 7:
 2212             sx = "800000000"+t;
 2213             break;
 2214           case 8:
 2215             sx = "80000000"+t;
 2216             break;
 2217           case 9:
 2218             sx = "8000000"+t;
 2219             break;
 2220           case 10:
 2221             sx = "800000"+t;
 2222             break;
 2223           case 11:
 2224             sx = "80000"+t;
 2225             break;
 2226           case 12:
 2227             sx = "8000"+t;
 2228             break;
 2229           case 13:
 2230             sx = "800"+t;
 2231             break;
 2232           case 14:
 2233             sx = "80"+t;
 2234             break;
 2235           case 15:
 2236             sx = "8"+t;
 2237             break;
 2238           case 16:
 2239             switch (t.charAt(0)) {
 2240             case '1':
 2241               sx = "9"+t.substring(1,16);
 2242               break;
 2243             case '2':
 2244               sx = "a"+t.substring(1,16);
 2245               break;
 2246             case '3':
 2247               sx = "b"+t.substring(1,16);
 2248               break;
 2249             case '4':
 2250               sx = "c"+t.substring(1,16);
 2251               break;
 2252             case '5':
 2253               sx = "d"+t.substring(1,16);
 2254               break;
 2255             case '6':
 2256               sx = "e"+t.substring(1,16);
 2257               break;
 2258             case '7':
 2259               sx = "f"+t.substring(1,16);
 2260               break;
 2261             }
 2262             break;
 2263           }
 2264         }
 2265         else
 2266           sx = Long.toString(x,16);
 2267         return printXFormat(sx);
 2268       }
 2269       /**
 2270        * Format method for the x conversion character and
 2271        * int argument.
 2272        *
 2273        * For x format, the flag character '-', means that
 2274        * the output should be left justified within the
 2275        * field.  The default is to pad with blanks on the
 2276        * left.  The '#' flag character means to lead with
 2277        * '0x'.
 2278        *
 2279        * The field width is treated as the minimum number
 2280        * of characters to be printed.  The default is to
 2281        * add no padding.  Padding is with blanks by
 2282        * default.
 2283        *
 2284        * The precision, if set, is the minimum number of
 2285        * digits to appear.  Padding is with leading 0s.
 2286        * @param x the int to format.
 2287        * @return the formatted String.
 2288        */
 2289       private String printXFormat(int x) {
 2290         String sx=null;
 2291         if (x == Integer.MIN_VALUE)
 2292           sx = "80000000";
 2293         else if (x < 0) {
 2294           String t = Integer.toString(
 2295             (~(-x-1))^Integer.MIN_VALUE,16);
 2296           switch (t.length()) {
 2297           case 1:
 2298             sx = "8000000"+t;
 2299             break;
 2300           case 2:
 2301             sx = "800000"+t;
 2302             break;
 2303           case 3:
 2304             sx = "80000"+t;
 2305             break;
 2306           case 4:
 2307             sx = "8000"+t;
 2308             break;
 2309           case 5:
 2310             sx = "800"+t;
 2311             break;
 2312           case 6:
 2313             sx = "80"+t;
 2314             break;
 2315           case 7:
 2316             sx = "8"+t;
 2317             break;
 2318           case 8:
 2319             switch (t.charAt(0)) {
 2320             case '1':
 2321               sx = "9"+t.substring(1,8);
 2322               break;
 2323             case '2':
 2324               sx = "a"+t.substring(1,8);
 2325               break;
 2326             case '3':
 2327               sx = "b"+t.substring(1,8);
 2328               break;
 2329             case '4':
 2330               sx = "c"+t.substring(1,8);
 2331               break;
 2332             case '5':
 2333               sx = "d"+t.substring(1,8);
 2334               break;
 2335             case '6':
 2336               sx = "e"+t.substring(1,8);
 2337               break;
 2338             case '7':
 2339               sx = "f"+t.substring(1,8);
 2340               break;
 2341             }
 2342             break;
 2343           }
 2344         }
 2345         else
 2346           sx = Integer.toString(x,16);
 2347         return printXFormat(sx);
 2348       }
 2349       /**
 2350        * Utility method for formatting using the x
 2351        * conversion character.
 2352        * @param sx the String to format, the result of
 2353        *     converting a short, int, or long to a
 2354        *     String.
 2355        * @return the formatted String.
 2356        */
 2357       private String printXFormat(String sx) {
 2358         int nLeadingZeros = 0;
 2359         int nBlanks = 0;
 2360         if (sx.equals("0")&&precisionSet&&precision==0)
 2361           sx="";
 2362         if (precisionSet)
 2363           nLeadingZeros = precision-sx.length();
 2364         if (nLeadingZeros<0) nLeadingZeros=0;
 2365         if (fieldWidthSet) {
 2366           nBlanks = fieldWidth-nLeadingZeros-sx.length();
 2367           if (alternateForm) nBlanks = nBlanks - 2;
 2368         }
 2369         if (nBlanks<0) nBlanks=0;
 2370         int n=0;
 2371         if (alternateForm) n+=2;
 2372         n += nLeadingZeros;
 2373         n += sx.length();
 2374         n += nBlanks;
 2375         char[] ca = new char[n];
 2376         int i=0;
 2377         if (leftJustify) {
 2378           if (alternateForm) {
 2379             ca[i++]='0'; ca[i++]='x';
 2380           }
 2381           for (int j=0; j<nLeadingZeros; j++,i++)
 2382             ca[i]='0';
 2383           char[] csx = sx.toCharArray();
 2384           for (int j=0; j<csx.length; j++,i++)
 2385             ca[i] = csx[j];
 2386           for (int j=0; j<nBlanks; j++,i++)
 2387             ca[i] = ' ';
 2388         }
 2389         else {
 2390           if (!leadingZeros)
 2391             for (int j=0; j<nBlanks; j++,i++)
 2392               ca[i] = ' ';
 2393           if (alternateForm) {
 2394             ca[i++]='0'; ca[i++]='x';
 2395           }
 2396           if (leadingZeros)
 2397             for (int j=0; j<nBlanks; j++,i++)
 2398               ca[i] = '0';
 2399           for (int j=0; j<nLeadingZeros; j++,i++)
 2400             ca[i]='0';
 2401           char[] csx = sx.toCharArray();
 2402           for (int j=0; j<csx.length; j++,i++)
 2403             ca[i] = csx[j];
 2404         }
 2405         String caReturn=new String(ca);
 2406         if (conversionCharacter=='X')
 2407           caReturn = caReturn.toUpperCase();
 2408         return caReturn;
 2409       }
 2410       /**
 2411        * Format method for the o conversion character and
 2412        * short argument.
 2413        *
 2414        * For o format, the flag character '-', means that
 2415        * the output should be left justified within the
 2416        * field.  The default is to pad with blanks on the 
 2417        * left.  The '#' flag character means that the
 2418        * output begins with a leading 0 and the precision
 2419        * is increased by 1.
 2420        *
 2421        * The field width is treated as the minimum number
 2422        * of characters to be printed.  The default is to
 2423        * add no padding.  Padding is with blanks by
 2424        * default.
 2425        *
 2426        * The precision, if set, is the minimum number of
 2427        * digits to appear.  Padding is with leading 0s.
 2428        * @param x the short to format.
 2429        * @return the formatted String.
 2430        */
 2431       private String printOFormat(short x) {
 2432         String sx=null;
 2433         if (x == Short.MIN_VALUE)
 2434           sx = "100000";
 2435         else if (x < 0) {
 2436           String t = Integer.toString(
 2437             (~(-x-1))^Short.MIN_VALUE,8);
 2438           switch (t.length()) {
 2439           case 1:
 2440             sx = "10000"+t;
 2441             break;
 2442           case 2:
 2443             sx = "1000"+t;
 2444             break;
 2445           case 3:
 2446             sx = "100"+t;
 2447             break;
 2448           case 4:
 2449             sx = "10"+t;
 2450             break;
 2451           case 5:
 2452             sx = "1"+t;
 2453             break;
 2454           }
 2455         }
 2456         else
 2457           sx = Integer.toString((int)x,8);
 2458         return printOFormat(sx);
 2459       }
 2460       /**
 2461        * Format method for the o conversion character and
 2462        * long argument.
 2463        *
 2464        * For o format, the flag character '-', means that
 2465        * the output should be left justified within the
 2466        * field.  The default is to pad with blanks on the 
 2467        * left.  The '#' flag character means that the
 2468        * output begins with a leading 0 and the precision
 2469        * is increased by 1.
 2470        *
 2471        * The field width is treated as the minimum number
 2472        * of characters to be printed.  The default is to
 2473        * add no padding.  Padding is with blanks by
 2474        * default.
 2475        *
 2476        * The precision, if set, is the minimum number of
 2477        * digits to appear.  Padding is with leading 0s.
 2478        * @param x the long to format.
 2479        * @return the formatted String.
 2480        */
 2481       private String printOFormat(long x) {
 2482         String sx=null;
 2483         if (x == Long.MIN_VALUE)
 2484           sx = "1000000000000000000000";
 2485         else if (x < 0) {
 2486           String t = Long.toString(
 2487             (~(-x-1))^Long.MIN_VALUE,8);
 2488           switch (t.length()) {
 2489           case 1:
 2490             sx = "100000000000000000000"+t;
 2491             break;
 2492           case 2:
 2493             sx = "10000000000000000000"+t;
 2494             break;
 2495           case 3:
 2496             sx = "1000000000000000000"+t;
 2497             break;
 2498           case 4:
 2499             sx = "100000000000000000"+t;
 2500             break;
 2501           case 5:
 2502             sx = "10000000000000000"+t;
 2503             break;
 2504           case 6:
 2505             sx = "1000000000000000"+t;
 2506             break;
 2507           case 7:
 2508             sx = "100000000000000"+t;
 2509             break;
 2510           case 8:
 2511             sx = "10000000000000"+t;
 2512             break;
 2513           case 9:
 2514             sx = "1000000000000"+t;
 2515             break;
 2516           case 10:
 2517             sx = "100000000000"+t;
 2518             break;
 2519           case 11:
 2520             sx = "10000000000"+t;
 2521             break;
 2522           case 12:
 2523             sx = "1000000000"+t;
 2524             break;
 2525           case 13:
 2526             sx = "100000000"+t;
 2527             break;
 2528           case 14:
 2529             sx = "10000000"+t;
 2530             break;
 2531           case 15:
 2532             sx = "1000000"+t;
 2533             break;
 2534           case 16:
 2535             sx = "100000"+t;
 2536             break;
 2537           case 17:
 2538             sx = "10000"+t;
 2539             break;
 2540           case 18:
 2541             sx = "1000"+t;
 2542             break;
 2543           case 19:
 2544             sx = "100"+t;
 2545             break;
 2546           case 20:
 2547             sx = "10"+t;
 2548             break;
 2549           case 21:
 2550             sx = "1"+t;
 2551             break;
 2552           }
 2553         }
 2554         else
 2555           sx = Long.toString(x,8);
 2556         return printOFormat(sx);
 2557       }
 2558       /**
 2559        * Format method for the o conversion character and
 2560        * int argument.
 2561        *
 2562        * For o format, the flag character '-', means that
 2563        * the output should be left justified within the
 2564        * field.  The default is to pad with blanks on the
 2565        * left.  The '#' flag character means that the
 2566        * output begins with a leading 0 and the precision
 2567        * is increased by 1.
 2568        *
 2569        * The field width is treated as the minimum number
 2570        * of characters to be printed.  The default is to
 2571        * add no padding.  Padding is with blanks by
 2572        * default.
 2573        *
 2574        * The precision, if set, is the minimum number of
 2575        * digits to appear.  Padding is with leading 0s.
 2576        * @param x the int to format.
 2577        * @return the formatted String.
 2578        */
 2579       private String printOFormat(int x) {
 2580         String sx=null;
 2581         if (x == Integer.MIN_VALUE)
 2582           sx = "20000000000";
 2583         else if (x < 0) {
 2584           String t = Integer.toString(
 2585             (~(-x-1))^Integer.MIN_VALUE,8);
 2586           switch (t.length()) {
 2587           case 1:
 2588             sx = "2000000000"+t;
 2589             break;
 2590           case 2:
 2591             sx = "200000000"+t;
 2592             break;
 2593           case 3:
 2594             sx = "20000000"+t;
 2595             break;
 2596           case 4:
 2597             sx = "2000000"+t;
 2598             break;
 2599           case 5:
 2600             sx = "200000"+t;
 2601             break;
 2602           case 6:
 2603             sx = "20000"+t;
 2604             break;
 2605           case 7:
 2606             sx = "2000"+t;
 2607             break;
 2608           case 8:
 2609             sx = "200"+t;
 2610             break;
 2611           case 9:
 2612             sx = "20"+t;
 2613             break;
 2614           case 10:
 2615             sx = "2"+t;
 2616             break;
 2617           case 11:
 2618             sx = "3"+t.substring(1);
 2619             break;
 2620           }
 2621         }
 2622         else
 2623           sx = Integer.toString(x,8);
 2624         return printOFormat(sx);
 2625       }
 2626       /**
 2627        * Utility method for formatting using the o
 2628        * conversion character.
 2629        * @param sx the String to format, the result of
 2630        *     converting a short, int, or long to a
 2631        *     String.
 2632        * @return the formatted String.
 2633        */
 2634       private String printOFormat(String sx) {
 2635         int nLeadingZeros = 0;
 2636         int nBlanks = 0;
 2637         if (sx.equals("0")&&precisionSet&&precision==0)
 2638           sx="";
 2639         if (precisionSet)
 2640           nLeadingZeros = precision-sx.length();
 2641         if (alternateForm) nLeadingZeros++;
 2642         if (nLeadingZeros<0) nLeadingZeros=0;
 2643         if (fieldWidthSet)
 2644           nBlanks = fieldWidth-nLeadingZeros-sx.length();
 2645         if (nBlanks<0) nBlanks=0;
 2646         int n=nLeadingZeros+sx.length()+nBlanks;
 2647         char[] ca = new char[n];
 2648         int i;
 2649         if (leftJustify) {
 2650           for (i=0; i<nLeadingZeros; i++) ca[i]='0';
 2651           char[] csx = sx.toCharArray();
 2652           for (int j=0; j<csx.length; j++,i++)
 2653             ca[i] = csx[j];
 2654           for (int j=0; j<nBlanks; j++,i++) ca[i] = ' ';
 2655         }
 2656         else {
 2657           if (leadingZeros)
 2658             for (i=0; i<nBlanks; i++) ca[i]='0';
 2659           else
 2660             for (i=0; i<nBlanks; i++) ca[i]=' ';
 2661           for (int j=0; j<nLeadingZeros; j++,i++)
 2662             ca[i]='0';
 2663           char[] csx = sx.toCharArray();
 2664           for (int j=0; j<csx.length; j++,i++)
 2665             ca[i] = csx[j];
 2666         }
 2667         return new String(ca);
 2668       }
 2669       /**
 2670        * Format method for the c conversion character and
 2671        * char argument.
 2672        *
 2673        * The only flag character that affects c format is
 2674        * the '-', meaning that the output should be left
 2675        * justified within the field.  The default is to
 2676        * pad with blanks on the left.
 2677        *
 2678        * The field width is treated as the minimum number
 2679        * of characters to be printed.  Padding is with
 2680        * blanks by default.  The default width is 1.
 2681        *
 2682        * The precision, if set, is ignored.
 2683        * @param x the char to format.
 2684        * @return the formatted String.
 2685        */
 2686       private String printCFormat(char x) {
 2687         int nPrint = 1;
 2688         int width = fieldWidth;
 2689         if (!fieldWidthSet) width = nPrint;
 2690         char[] ca = new char[width];
 2691         int i=0;
 2692         if (leftJustify) {
 2693           ca[0] = x;
 2694           for (i=1; i<=width-nPrint; i++) ca[i]=' ';
 2695         }
 2696         else {
 2697           for (i=0; i<width-nPrint; i++) ca[i]=' ';
 2698           ca[i] = x;
 2699         }
 2700         return new String(ca);
 2701       }
 2702       /**
 2703        * Format method for the s conversion character and
 2704        * String argument.
 2705        *
 2706        * The only flag character that affects s format is
 2707        * the '-', meaning that the output should be left
 2708        * justified within the field.  The default is to
 2709        * pad with blanks on the left.
 2710        *
 2711        * The field width is treated as the minimum number
 2712        * of characters to be printed.  The default is the
 2713        * smaller of the number of characters in the the
 2714        * input and the precision.  Padding is with blanks
 2715        * by default.
 2716        *
 2717        * The precision, if set, specifies the maximum
 2718        * number of characters to be printed from the
 2719        * string.  A null digit string is treated
 2720        * as a 0.  The default is not to set a maximum
 2721        * number of characters to be printed.
 2722        * @param x the String to format.
 2723        * @return the formatted String.
 2724        */
 2725       private String printSFormat(String x) {
 2726         int nPrint = x.length();
 2727         int width = fieldWidth;
 2728         if (precisionSet && nPrint>precision)
 2729           nPrint=precision;
 2730         if (!fieldWidthSet) width = nPrint;
 2731         int n=0;
 2732         if (width>nPrint) n+=width-nPrint;
 2733         if (nPrint>=x.length()) n+= x.length();
 2734         else n+= nPrint;
 2735         char[] ca = new char[n];
 2736         int i=0;
 2737         if (leftJustify) {
 2738           if (nPrint>=x.length()) {
 2739             char[] csx = x.toCharArray();
 2740             for (i=0; i<x.length(); i++) ca[i]=csx[i];
 2741           }
 2742           else {
 2743             char[] csx =
 2744               x.substring(0,nPrint).toCharArray();
 2745             for (i=0; i<nPrint; i++) ca[i]=csx[i];
 2746           }
 2747           for (int j=0; j<width-nPrint; j++,i++)
 2748             ca[i]=' ';
 2749         }
 2750         else {
 2751           for (i=0; i<width-nPrint; i++) ca[i]=' ';
 2752           if (nPrint>=x.length()) {
 2753             char[] csx = x.toCharArray();
 2754             for (int j=0; j<x.length(); i++,j++)
 2755               ca[i]=csx[j];
 2756           }
 2757           else {
 2758             char[] csx =
 2759               x.substring(0,nPrint).toCharArray();
 2760             for (int j=0; j<nPrint; i++,j++)
 2761               ca[i]=csx[j];
 2762           }
 2763         }
 2764         return new String(ca);
 2765       }
 2766       /**
 2767        * Check for a conversion character.  If it is
 2768        * there, store it.
 2769        * @param x the String to format.
 2770        * @return <code>true</code> if the conversion
 2771        *     character is there, and
 2772        *     <code>false</code> otherwise.
 2773        */
 2774       private boolean setConversionCharacter() {
 2775         /* idfgGoxXeEcs */
 2776         boolean ret = false;
 2777         conversionCharacter='\0';
 2778         if (pos < fmt.length()) {
 2779           char c = fmt.charAt(pos);
 2780           if (c=='i'||c=='d'||c=='f'||c=='g'||c=='G'
 2781           || c=='o' || c=='x' || c=='X' || c=='e'
 2782           || c=='E' || c=='c' || c=='s' || c=='%') {
 2783             conversionCharacter = c;
 2784             pos++;
 2785             ret = true;
 2786           }
 2787         }
 2788         return ret;
 2789       }
 2790       /**
 2791        * Check for an h, l, or L in a format.  An L is
 2792        * used to control the minimum number of digits
 2793        * in an exponent when using floating point
 2794        * formats.  An l or h is used to control
 2795        * conversion of the input to a long or short,
 2796        * respectively, before formatting.  If any of
 2797        * these is present, store them.
 2798        */
 2799       private void setOptionalHL() {
 2800         optionalh=false;
 2801         optionall=false;
 2802         optionalL=false;
 2803         if (pos < fmt.length()) {
 2804           char c = fmt.charAt(pos);
 2805           if (c=='h') { optionalh=true; pos++; }
 2806           else if (c=='l') { optionall=true; pos++; }
 2807           else if (c=='L') { optionalL=true; pos++; }
 2808         }
 2809       }
 2810       /**
 2811        * Set the precision.
 2812        */
 2813       private void setPrecision() {
 2814         int firstPos = pos;
 2815         precisionSet = false;
 2816         if (pos<fmt.length()&&fmt.charAt(pos)=='.') {
 2817           pos++;
 2818           if ((pos < fmt.length())
 2819           && (fmt.charAt(pos)=='*')) {
 2820             pos++;
 2821             if (!setPrecisionArgPosition()) {
 2822               variablePrecision = true;
 2823               precisionSet = true;
 2824             }
 2825             return;
 2826           }
 2827           else {
 2828             while (pos < fmt.length()) {
 2829               char c = fmt.charAt(pos);
 2830               if (Character.isDigit(c)) pos++;
 2831               else break;
 2832             }
 2833             if (pos > firstPos+1) {
 2834               String sz = fmt.substring(firstPos+1,pos);
 2835               precision = Integer.parseInt(sz);
 2836               precisionSet = true;
 2837             }
 2838           }
 2839         }
 2840       }
 2841       /**
 2842        * Set the field width.
 2843        */
 2844       private void setFieldWidth() {
 2845         int firstPos = pos;
 2846         fieldWidth = 0;
 2847         fieldWidthSet = false;
 2848         if ((pos < fmt.length())
 2849         && (fmt.charAt(pos)=='*')) {
 2850           pos++;
 2851           if (!setFieldWidthArgPosition()) {
 2852             variableFieldWidth = true;
 2853             fieldWidthSet = true;
 2854           }
 2855         }
 2856         else {
 2857           while (pos < fmt.length()) {
 2858             char c = fmt.charAt(pos);
 2859             if (Character.isDigit(c)) pos++;
 2860             else break;
 2861           }
 2862           if (firstPos<pos && firstPos < fmt.length()) {
 2863             String sz = fmt.substring(firstPos,pos);
 2864             fieldWidth = Integer.parseInt(sz);
 2865             fieldWidthSet = true;
 2866           }
 2867         }
 2868       }
 2869       /**
 2870        * Store the digits <code>n</code> in %n$ forms.
 2871        */
 2872       private void setArgPosition() {
 2873         int xPos;
 2874         for (xPos=pos; xPos<fmt.length(); xPos++) {
 2875           if (!Character.isDigit(fmt.charAt(xPos)))
 2876             break;
 2877         }
 2878         if (xPos>pos && xPos<fmt.length()) {
 2879           if (fmt.charAt(xPos)=='$') {
 2880             positionalSpecification = true;
 2881             argumentPosition=
 2882               Integer.parseInt(fmt.substring(pos,xPos));
 2883             pos=xPos+1;
 2884           }
 2885         }
 2886       }
 2887       /**
 2888        * Store the digits <code>n</code> in *n$ forms.
 2889        */
 2890       private boolean setFieldWidthArgPosition() {
 2891         boolean ret=false;
 2892         int xPos;
 2893         for (xPos=pos; xPos<fmt.length(); xPos++) {
 2894           if (!Character.isDigit(fmt.charAt(xPos)))
 2895             break;
 2896         }
 2897         if (xPos>pos && xPos<fmt.length()) {
 2898           if (fmt.charAt(xPos)=='$') {
 2899             positionalFieldWidth = true;
 2900             argumentPositionForFieldWidth=
 2901               Integer.parseInt(fmt.substring(pos,xPos));
 2902             pos=xPos+1;
 2903             ret=true;
 2904           }
 2905         }
 2906         return ret;
 2907       }
 2908       /**
 2909        * Store the digits <code>n</code> in *n$ forms.
 2910        */
 2911       private boolean setPrecisionArgPosition() {
 2912         boolean ret=false;
 2913         int xPos;
 2914         for (xPos=pos; xPos<fmt.length(); xPos++) {
 2915           if (!Character.isDigit(fmt.charAt(xPos)))
 2916             break;
 2917         }
 2918         if (xPos>pos && xPos<fmt.length()) {
 2919           if (fmt.charAt(xPos)=='$') {
 2920             positionalPrecision = true;
 2921             argumentPositionForPrecision=
 2922               Integer.parseInt(fmt.substring(pos,xPos));
 2923             pos=xPos+1;
 2924             ret=true;
 2925           }
 2926         }
 2927         return ret;
 2928       }
 2929       boolean isPositionalSpecification() {
 2930         return positionalSpecification;
 2931       }
 2932       int getArgumentPosition() { return argumentPosition; }
 2933       boolean isPositionalFieldWidth() {
 2934         return positionalFieldWidth;
 2935       }
 2936       int getArgumentPositionForFieldWidth() {
 2937         return argumentPositionForFieldWidth;
 2938       }
 2939       boolean isPositionalPrecision() {
 2940         return positionalPrecision;
 2941       }
 2942       int getArgumentPositionForPrecision() {
 2943         return argumentPositionForPrecision;
 2944       }
 2945       /**
 2946        * Set flag characters, one of '-+#0 or a space.
 2947        */
 2948       private void setFlagCharacters() {
 2949         /* '-+ #0 */
 2950         thousands = false;
 2951         leftJustify = false;
 2952         leadingSign = false;
 2953         leadingSpace = false;
 2954         alternateForm = false;
 2955         leadingZeros = false;
 2956         for ( ; pos < fmt.length(); pos++) {
 2957           char c = fmt.charAt(pos);
 2958           if (c == '\'') thousands = true;
 2959           else if (c == '-') {
 2960             leftJustify = true;
 2961             leadingZeros = false;
 2962           }
 2963           else if (c == '+') {
 2964             leadingSign = true;
 2965             leadingSpace = false;
 2966           }
 2967           else if (c == ' ') {
 2968             if (!leadingSign) leadingSpace = true;
 2969           }
 2970           else if (c == '#') alternateForm = true;
 2971           else if (c == '0') {
 2972             if (!leftJustify) leadingZeros = true;
 2973           }
 2974           else break;
 2975         }
 2976       }
 2977       /**
 2978        * The integer portion of the result of a decimal
 2979        * conversion (i, d, u, f, g, or G) will be
 2980        * formatted with thousands' grouping characters.
 2981        * For other conversions the flag is ignored.
 2982        */
 2983       private boolean thousands = false;
 2984       /**
 2985        * The result of the conversion will be
 2986        * left-justified within the field.
 2987        */
 2988       private boolean leftJustify = false;
 2989       /**
 2990        * The result of a signed conversion will always
 2991        * begin with a sign (+ or -).
 2992        */
 2993       private boolean leadingSign = false;
 2994       /**
 2995        * Flag indicating that left padding with spaces is
 2996        * specified.
 2997        */
 2998       private boolean leadingSpace = false;
 2999       /**
 3000        * For an o conversion, increase the precision to
 3001        * force the first digit of the result to be a
 3002        * zero.  For x (or X) conversions, a non-zero
 3003        * result will have 0x (or 0X) prepended to it.
 3004        * For e, E, f, g, or G conversions, the result
 3005        * will always contain a radix character, even if
 3006        * no digits follow the point.  For g and G
 3007        * conversions, trailing zeros will not be removed
 3008        * from the result.
 3009        */
 3010       private boolean alternateForm = false;
 3011       /**
 3012        * Flag indicating that left padding with zeroes is
 3013        * specified.
 3014        */
 3015       private boolean leadingZeros = false;
 3016       /**
 3017        * Flag indicating that the field width is *.
 3018        */
 3019       private boolean variableFieldWidth = false;
 3020       /**
 3021        * If the converted value has fewer bytes than the
 3022        * field width, it will be padded with spaces or
 3023        * zeroes.
 3024        */
 3025       private int fieldWidth = 0;
 3026       /**
 3027        * Flag indicating whether or not the field width
 3028        * has been set.
 3029        */
 3030       private boolean fieldWidthSet = false;
 3031       /**
 3032        * The minimum number of digits to appear for the
 3033        * d, i, o, u, x, or X conversions.  The number of
 3034        * digits to appear after the radix character for
 3035        * the e, E, and f conversions.  The maximum number
 3036        *  of significant digits for the g and G 
 3037        * conversions.  The maximum number of bytes to be
 3038        * printed from a string in s and S conversions.
 3039        */
 3040       private int precision = 0;
 3041       /** Default precision. */
 3042       private final static int defaultDigits=6; 
 3043       /**
 3044        * Flag indicating that the precision is *.
 3045        */
 3046       private boolean variablePrecision = false;
 3047       /**
 3048        * Flag indicating whether or not the precision has
 3049        * been set.
 3050        */
 3051       private boolean precisionSet = false;
 3052       /*
 3053        */
 3054       private boolean positionalSpecification=false;
 3055       private int argumentPosition=0;
 3056       private boolean positionalFieldWidth=false;
 3057       private int argumentPositionForFieldWidth=0;
 3058       private boolean positionalPrecision=false;
 3059       private int argumentPositionForPrecision=0;
 3060       /**
 3061        * Flag specifying that a following d, i, o, u, x,
 3062        * or X conversion character applies to a type
 3063        * short int.
 3064        */
 3065       private boolean optionalh = false;
 3066       /**
 3067        * Flag specifying that a following d, i, o, u, x,
 3068        * or X conversion character applies to a type lont
 3069        * int argument.
 3070        */
 3071       private boolean optionall = false;
 3072       /**
 3073        * Flag specifying that a following e, E, f, g, or
 3074        * G conversion character applies to a type double
 3075        * argument.  This is a noop in Java.
 3076        */
 3077       private boolean optionalL = false;
 3078       /** Control string type. */
 3079       private char conversionCharacter = '\0';
 3080       /**
 3081        * Position within the control string.  Used by
 3082        * the constructor.
 3083        */
 3084       private int pos = 0;
 3085       /** Literal or control format string. */
 3086       private String fmt;
 3087     }
 3088     /** Vector of control strings and format literals. */
 3089     private Vector vFmt = new Vector();
 3090     /** Character position.  Used by the constructor. */
 3091     private int cPos=0;
 3092     /** Character position.  Used by the constructor. */
 3093     private DecimalFormatSymbols dfs=null;
 3094   }

Home » openjdk-7 » net.bonzoun » cocodonkey » [javadoc | source]