Formatting changes
[jalview.git] / src / jalview / util / Format.java
1 /*\r
2  * Cay S. Horstmann & Gary Cornell, Core Java\r
3  * Published By Sun Microsystems Press/Prentice-Hall\r
4  * Copyright (C) 1997 Sun Microsystems Inc.\r
5  * All Rights Reserved.\r
6  *\r
7  * Permission to use, copy, modify, and distribute this\r
8  * software and its documentation for NON-COMMERCIAL purposes\r
9  * and without fee is hereby granted provided that this\r
10  * copyright notice appears in all copies.\r
11  *\r
12  * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR\r
13  * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER\r
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\r
15  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
16  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS\r
17  * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED\r
18  * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING\r
19  * THIS SOFTWARE OR ITS DERIVATIVES.\r
20  */\r
21 \r
22 /**\r
23  * A class for formatting numbers that follows printf conventions.\r
24  * Also implements C-like atoi and atof functions\r
25  * @version 1.03 25 Oct 1997\r
26  * @author Cay Horstmann\r
27  */\r
28 package jalview.util;\r
29 \r
30 import java.io.*;\r
31 \r
32 \r
33 /**\r
34  * DOCUMENT ME!\r
35  *\r
36  * @author $author$\r
37  * @version $Revision$\r
38  */\r
39 public class Format\r
40 {\r
41     private int width;\r
42     private int precision;\r
43     private String pre;\r
44     private String post;\r
45     private boolean leading_zeroes;\r
46     private boolean show_plus;\r
47     private boolean alternate;\r
48     private boolean show_space;\r
49     private boolean left_align;\r
50     private char fmt; // one of cdeEfgGiosxXos\r
51 \r
52     /**\r
53      * Creates a new Format object.\r
54      *\r
55      * @param s DOCUMENT ME!\r
56      */\r
57     public Format(String s)\r
58     {\r
59         width = 0;\r
60         precision = -1;\r
61         pre = "";\r
62         post = "";\r
63         leading_zeroes = false;\r
64         show_plus = false;\r
65         alternate = false;\r
66         show_space = false;\r
67         left_align = false;\r
68         fmt = ' ';\r
69 \r
70         int state = 0;\r
71         int length = s.length();\r
72         int parse_state = 0;\r
73 \r
74         // 0 = prefix, 1 = flags, 2 = width, 3 = precision,\r
75         // 4 = format, 5 = end\r
76         int i = 0;\r
77 \r
78         while (parse_state == 0)\r
79         {\r
80             if (i >= length)\r
81             {\r
82                 parse_state = 5;\r
83             }\r
84             else if (s.charAt(i) == '%')\r
85             {\r
86                 if (i < (length - 1))\r
87                 {\r
88                     if (s.charAt(i + 1) == '%')\r
89                     {\r
90                         pre = pre + '%';\r
91                         i++;\r
92                     }\r
93                     else\r
94                     {\r
95                         parse_state = 1;\r
96                     }\r
97                 }\r
98                 else\r
99                 {\r
100                     throw new java.lang.IllegalArgumentException();\r
101                 }\r
102             }\r
103             else\r
104             {\r
105                 pre = pre + s.charAt(i);\r
106             }\r
107 \r
108             i++;\r
109         }\r
110 \r
111         while (parse_state == 1)\r
112         {\r
113             if (i >= length)\r
114             {\r
115                 parse_state = 5;\r
116             }\r
117             else if (s.charAt(i) == ' ')\r
118             {\r
119                 show_space = true;\r
120             }\r
121             else if (s.charAt(i) == '-')\r
122             {\r
123                 left_align = true;\r
124             }\r
125             else if (s.charAt(i) == '+')\r
126             {\r
127                 show_plus = true;\r
128             }\r
129             else if (s.charAt(i) == '0')\r
130             {\r
131                 leading_zeroes = true;\r
132             }\r
133             else if (s.charAt(i) == '#')\r
134             {\r
135                 alternate = true;\r
136             }\r
137             else\r
138             {\r
139                 parse_state = 2;\r
140                 i--;\r
141             }\r
142 \r
143             i++;\r
144         }\r
145 \r
146         while (parse_state == 2)\r
147         {\r
148             if (i >= length)\r
149             {\r
150                 parse_state = 5;\r
151             }\r
152             else if (('0' <= s.charAt(i)) && (s.charAt(i) <= '9'))\r
153             {\r
154                 width = ((width * 10) + s.charAt(i)) - '0';\r
155                 i++;\r
156             }\r
157             else if (s.charAt(i) == '.')\r
158             {\r
159                 parse_state = 3;\r
160                 precision = 0;\r
161                 i++;\r
162             }\r
163             else\r
164             {\r
165                 parse_state = 4;\r
166             }\r
167         }\r
168 \r
169         while (parse_state == 3)\r
170         {\r
171             if (i >= length)\r
172             {\r
173                 parse_state = 5;\r
174             }\r
175             else if (('0' <= s.charAt(i)) && (s.charAt(i) <= '9'))\r
176             {\r
177                 precision = ((precision * 10) + s.charAt(i)) - '0';\r
178                 i++;\r
179             }\r
180             else\r
181             {\r
182                 parse_state = 4;\r
183             }\r
184         }\r
185 \r
186         if (parse_state == 4)\r
187         {\r
188             if (i >= length)\r
189             {\r
190                 parse_state = 5;\r
191             }\r
192             else\r
193             {\r
194                 fmt = s.charAt(i);\r
195             }\r
196 \r
197             i++;\r
198         }\r
199 \r
200         if (i < length)\r
201         {\r
202             post = s.substring(i, length);\r
203         }\r
204     }\r
205 \r
206     /**\r
207      * Formats the number following printf conventions.\r
208      * Main limitation: Can only handle one format parameter at a time\r
209      * Use multiple Format objects to format more than one number\r
210      * @param s the format string following printf conventions\r
211      * The string has a prefix, a format code and a suffix. The prefix and suffix\r
212      * become part of the formatted output. The format code directs the\r
213      * formatting of the (single) parameter to be formatted. The code has the\r
214      * following structure\r
215      * <ul>\r
216      * <li> a % (required)\r
217      * <li> a modifier (optional)\r
218      * <dl>\r
219      * <dt> + <dd> forces display of + for positive numbers\r
220      * <dt> 0 <dd> show leading zeroes\r
221      * <dt> - <dd> align left in the field\r
222      * <dt> space <dd> prepend a space in front of positive numbers\r
223      * <dt> # <dd> use "alternate" format. Add 0 or 0x for octal or hexadecimal numbers. Don't suppress trailing zeroes in general floating point format.\r
224      * </dl>\r
225      * <li> an integer denoting field width (optional)\r
226      * <li> a period followed by an integer denoting precision (optional)\r
227      * <li> a format descriptor (required)\r
228      * <dl>\r
229      * <dt>f <dd> floating point number in fixed format\r
230      * <dt>e, E <dd> floating point number in exponential notation (scientific format). The E format results in an uppercase E for the exponent (1.14130E+003), the e format in a lowercase e.\r
231      * <dt>g, G <dd> floating point number in general format (fixed format for small numbers, exponential format for large numbers). Trailing zeroes are suppressed. The G format results in an uppercase E for the exponent (if any), the g format in a lowercase e.\r
232      * <dt>d, i <dd> integer in decimal\r
233      * <dt>x <dd> integer in hexadecimal\r
234      * <dt>o <dd> integer in octal\r
235      * <dt>s <dd> string\r
236      * <dt>c <dd> character\r
237      * </dl>\r
238      * </ul>\r
239      * @exception IllegalArgumentException if bad format\r
240      *\r
241      */\r
242     public static String getHexString(java.awt.Color color)\r
243     {\r
244         String r;\r
245         String g;\r
246         String b;\r
247         r = Integer.toHexString(color.getRed());\r
248 \r
249         if (r.length() < 2)\r
250         {\r
251             r = "0" + r;\r
252         }\r
253 \r
254         g = Integer.toHexString(color.getGreen());\r
255 \r
256         if (g.length() < 2)\r
257         {\r
258             g = "0" + g;\r
259         }\r
260 \r
261         b = Integer.toHexString(color.getBlue());\r
262 \r
263         if (b.length() < 2)\r
264         {\r
265             b = "0" + b;\r
266         }\r
267 \r
268         return r + g + b;\r
269     }\r
270 \r
271     /**\r
272     * prints a formatted number following printf conventions\r
273     * @param s a PrintStream\r
274     * @param fmt the format string\r
275     * @param x the double to print\r
276     */\r
277     public static void print(java.io.PrintStream s, String fmt, double x)\r
278     {\r
279         s.print(new Format(fmt).form(x));\r
280     }\r
281 \r
282     /**\r
283     * prints a formatted number following printf conventions\r
284     * @param s a PrintStream\r
285     * @param fmt the format string\r
286     * @param x the long to print\r
287     */\r
288     public static void print(java.io.PrintStream s, String fmt, long x)\r
289     {\r
290         s.print(new Format(fmt).form(x));\r
291     }\r
292 \r
293     /**\r
294     * prints a formatted number following printf conventions\r
295     * @param s a PrintStream\r
296     * @param fmt the format string\r
297     * @param x the character to\r
298     */\r
299     public static void print(java.io.PrintStream s, String fmt, char x)\r
300     {\r
301         s.print(new Format(fmt).form(x));\r
302     }\r
303 \r
304     /**\r
305     * prints a formatted number following printf conventions\r
306     * @param s a PrintStream, fmt the format string\r
307     * @param x a string that represents the digits to print\r
308     */\r
309     public static void print(java.io.PrintStream s, String fmt, String x)\r
310     {\r
311         s.print(new Format(fmt).form(x));\r
312     }\r
313 \r
314     /**\r
315     * Converts a string of digits (decimal, octal or hex) to an integer\r
316     * @param s a string\r
317     * @return the numeric value of the prefix of s representing a base 10 integer\r
318     */\r
319     public static int atoi(String s)\r
320     {\r
321         return (int) atol(s);\r
322     }\r
323 \r
324     /**\r
325     * Converts a string of digits (decimal, octal or hex) to a long integer\r
326     * @param s a string\r
327     * @return the numeric value of the prefix of s representing a base 10 integer\r
328     */\r
329     public static long atol(String s)\r
330     {\r
331         int i = 0;\r
332 \r
333         while ((i < s.length()) && Character.isWhitespace(s.charAt(i)))\r
334             i++;\r
335 \r
336         if ((i < s.length()) && (s.charAt(i) == '0'))\r
337         {\r
338             if (((i + 1) < s.length()) &&\r
339                     ((s.charAt(i + 1) == 'x') || (s.charAt(i + 1) == 'X')))\r
340             {\r
341                 return parseLong(s.substring(i + 2), 16);\r
342             }\r
343             else\r
344             {\r
345                 return parseLong(s, 8);\r
346             }\r
347         }\r
348         else\r
349         {\r
350             return parseLong(s, 10);\r
351         }\r
352     }\r
353 \r
354     /**\r
355      * DOCUMENT ME!\r
356      *\r
357      * @param s DOCUMENT ME!\r
358      * @param base DOCUMENT ME!\r
359      *\r
360      * @return DOCUMENT ME!\r
361      */\r
362     private static long parseLong(String s, int base)\r
363     {\r
364         int i = 0;\r
365         int sign = 1;\r
366         long r = 0;\r
367 \r
368         while ((i < s.length()) && Character.isWhitespace(s.charAt(i)))\r
369             i++;\r
370 \r
371         if ((i < s.length()) && (s.charAt(i) == '-'))\r
372         {\r
373             sign = -1;\r
374             i++;\r
375         }\r
376         else if ((i < s.length()) && (s.charAt(i) == '+'))\r
377         {\r
378             i++;\r
379         }\r
380 \r
381         while (i < s.length())\r
382         {\r
383             char ch = s.charAt(i);\r
384 \r
385             if (('0' <= ch) && (ch < ('0' + base)))\r
386             {\r
387                 r = ((r * base) + ch) - '0';\r
388             }\r
389             else if (('A' <= ch) && (ch < (('A' + base) - 10)))\r
390             {\r
391                 r = ((r * base) + ch) - 'A' + 10;\r
392             }\r
393             else if (('a' <= ch) && (ch < (('a' + base) - 10)))\r
394             {\r
395                 r = ((r * base) + ch) - 'a' + 10;\r
396             }\r
397             else\r
398             {\r
399                 return r * sign;\r
400             }\r
401 \r
402             i++;\r
403         }\r
404 \r
405         return r * sign;\r
406     }\r
407 \r
408     /**\r
409     * Converts a string of digits to an double\r
410     * @param s a string\r
411     */\r
412     public static double atof(String s)\r
413     {\r
414         int i = 0;\r
415         int sign = 1;\r
416         double r = 0; // integer part\r
417         double f = 0; // fractional part\r
418         double p = 1; // exponent of fractional part\r
419         int state = 0; // 0 = int part, 1 = frac part\r
420 \r
421         while ((i < s.length()) && Character.isWhitespace(s.charAt(i)))\r
422             i++;\r
423 \r
424         if ((i < s.length()) && (s.charAt(i) == '-'))\r
425         {\r
426             sign = -1;\r
427             i++;\r
428         }\r
429         else if ((i < s.length()) && (s.charAt(i) == '+'))\r
430         {\r
431             i++;\r
432         }\r
433 \r
434         while (i < s.length())\r
435         {\r
436             char ch = s.charAt(i);\r
437 \r
438             if (('0' <= ch) && (ch <= '9'))\r
439             {\r
440                 if (state == 0)\r
441                 {\r
442                     r = ((r * 10) + ch) - '0';\r
443                 }\r
444                 else if (state == 1)\r
445                 {\r
446                     p = p / 10;\r
447                     r = r + (p * (ch - '0'));\r
448                 }\r
449             }\r
450             else if (ch == '.')\r
451             {\r
452                 if (state == 0)\r
453                 {\r
454                     state = 1;\r
455                 }\r
456                 else\r
457                 {\r
458                     return sign * r;\r
459                 }\r
460             }\r
461             else if ((ch == 'e') || (ch == 'E'))\r
462             {\r
463                 long e = (int) parseLong(s.substring(i + 1), 10);\r
464 \r
465                 return sign * r * Math.pow(10, e);\r
466             }\r
467             else\r
468             {\r
469                 return sign * r;\r
470             }\r
471 \r
472             i++;\r
473         }\r
474 \r
475         return sign * r;\r
476     }\r
477 \r
478     /**\r
479     * Formats a double into a string (like sprintf in C)\r
480     * @param x the number to format\r
481     * @return the formatted string\r
482     * @exception IllegalArgumentException if bad argument\r
483     */\r
484     public String form(double x)\r
485     {\r
486         String r;\r
487 \r
488         if (precision < 0)\r
489         {\r
490             precision = 6;\r
491         }\r
492 \r
493         int s = 1;\r
494 \r
495         if (x < 0)\r
496         {\r
497             x = -x;\r
498             s = -1;\r
499         }\r
500 \r
501         if (fmt == 'f')\r
502         {\r
503             r = fixed_format(x);\r
504         }\r
505         else if ((fmt == 'e') || (fmt == 'E') || (fmt == 'g') || (fmt == 'G'))\r
506         {\r
507             r = exp_format(x);\r
508         }\r
509         else\r
510         {\r
511             throw new java.lang.IllegalArgumentException();\r
512         }\r
513 \r
514         return pad(sign(s, r));\r
515     }\r
516 \r
517     /**\r
518     * Formats a long integer into a string (like sprintf in C)\r
519     * @param x the number to format\r
520     * @return the formatted string\r
521     */\r
522     public String form(long x)\r
523     {\r
524         String r;\r
525         int s = 0;\r
526 \r
527         if ((fmt == 'd') || (fmt == 'i'))\r
528         {\r
529             if (x < 0)\r
530             {\r
531                 r = ("" + x).substring(1);\r
532                 s = -1;\r
533             }\r
534             else\r
535             {\r
536                 r = "" + x;\r
537                 s = 1;\r
538             }\r
539         }\r
540         else if (fmt == 'o')\r
541         {\r
542             r = convert(x, 3, 7, "01234567");\r
543         }\r
544         else if (fmt == 'x')\r
545         {\r
546             r = convert(x, 4, 15, "0123456789abcdef");\r
547         }\r
548         else if (fmt == 'X')\r
549         {\r
550             r = convert(x, 4, 15, "0123456789ABCDEF");\r
551         }\r
552         else\r
553         {\r
554             throw new java.lang.IllegalArgumentException();\r
555         }\r
556 \r
557         return pad(sign(s, r));\r
558     }\r
559 \r
560     /**\r
561     * Formats a character into a string (like sprintf in C)\r
562     * @param x the value to format\r
563     * @return the formatted string\r
564     */\r
565     public String form(char c)\r
566     {\r
567         if (fmt != 'c')\r
568         {\r
569             throw new java.lang.IllegalArgumentException();\r
570         }\r
571 \r
572         String r = "" + c;\r
573 \r
574         return pad(r);\r
575     }\r
576 \r
577     /**\r
578     * Formats a string into a larger string (like sprintf in C)\r
579     * @param x the value to format\r
580     * @return the formatted string\r
581     */\r
582     public String form(String s)\r
583     {\r
584         if (fmt != 's')\r
585         {\r
586             throw new java.lang.IllegalArgumentException();\r
587         }\r
588 \r
589         if (precision >= 0)\r
590         {\r
591             s = s.substring(0, precision);\r
592         }\r
593 \r
594         return pad(s);\r
595     }\r
596 \r
597     /**\r
598     * a test stub for the format class\r
599     */\r
600     public static void main(String[] a)\r
601     {\r
602         double x = 1.23456789012;\r
603         double y = 123;\r
604         double z = 1.2345e30;\r
605         double w = 1.02;\r
606         double u = 1.234e-5;\r
607         int d = 0xCAFE;\r
608         Format.print(System.out, "x = |%f|\n", x);\r
609         Format.print(System.out, "u = |%20f|\n", u);\r
610         Format.print(System.out, "x = |% .5f|\n", x);\r
611         Format.print(System.out, "w = |%20.5f|\n", w);\r
612         Format.print(System.out, "x = |%020.5f|\n", x);\r
613         Format.print(System.out, "x = |%+20.5f|\n", x);\r
614         Format.print(System.out, "x = |%+020.5f|\n", x);\r
615         Format.print(System.out, "x = |% 020.5f|\n", x);\r
616         Format.print(System.out, "y = |%#+20.5f|\n", y);\r
617         Format.print(System.out, "y = |%-+20.5f|\n", y);\r
618         Format.print(System.out, "z = |%20.5f|\n", z);\r
619 \r
620         Format.print(System.out, "x = |%e|\n", x);\r
621         Format.print(System.out, "u = |%20e|\n", u);\r
622         Format.print(System.out, "x = |% .5e|\n", x);\r
623         Format.print(System.out, "w = |%20.5e|\n", w);\r
624         Format.print(System.out, "x = |%020.5e|\n", x);\r
625         Format.print(System.out, "x = |%+20.5e|\n", x);\r
626         Format.print(System.out, "x = |%+020.5e|\n", x);\r
627         Format.print(System.out, "x = |% 020.5e|\n", x);\r
628         Format.print(System.out, "y = |%#+20.5e|\n", y);\r
629         Format.print(System.out, "y = |%-+20.5e|\n", y);\r
630 \r
631         Format.print(System.out, "x = |%g|\n", x);\r
632         Format.print(System.out, "z = |%g|\n", z);\r
633         Format.print(System.out, "w = |%g|\n", w);\r
634         Format.print(System.out, "u = |%g|\n", u);\r
635         Format.print(System.out, "y = |%.2g|\n", y);\r
636         Format.print(System.out, "y = |%#.2g|\n", y);\r
637 \r
638         Format.print(System.out, "d = |%d|\n", d);\r
639         Format.print(System.out, "d = |%20d|\n", d);\r
640         Format.print(System.out, "d = |%020d|\n", d);\r
641         Format.print(System.out, "d = |%+20d|\n", d);\r
642         Format.print(System.out, "d = |% 020d|\n", d);\r
643         Format.print(System.out, "d = |%-20d|\n", d);\r
644         Format.print(System.out, "d = |%20.8d|\n", d);\r
645         Format.print(System.out, "d = |%x|\n", d);\r
646         Format.print(System.out, "d = |%20X|\n", d);\r
647         Format.print(System.out, "d = |%#20x|\n", d);\r
648         Format.print(System.out, "d = |%020X|\n", d);\r
649         Format.print(System.out, "d = |%20.8x|\n", d);\r
650         Format.print(System.out, "d = |%o|\n", d);\r
651         Format.print(System.out, "d = |%020o|\n", d);\r
652         Format.print(System.out, "d = |%#20o|\n", d);\r
653         Format.print(System.out, "d = |%#020o|\n", d);\r
654         Format.print(System.out, "d = |%20.12o|\n", d);\r
655 \r
656         Format.print(System.out, "s = |%-20s|\n", "Hello");\r
657         Format.print(System.out, "s = |%-20c|\n", '!');\r
658 \r
659         // regression test to confirm fix of reported bugs\r
660         Format.print(System.out, "|%i|\n", Long.MIN_VALUE);\r
661 \r
662         Format.print(System.out, "|%6.2e|\n", 0.0);\r
663         Format.print(System.out, "|%6.2g|\n", 0.0);\r
664 \r
665         Format.print(System.out, "|%6.2f|\n", 9.99);\r
666         Format.print(System.out, "|%6.2f|\n", 9.999);\r
667 \r
668         Format.print(System.out, "|%6.0f|\n", 9.999);\r
669     }\r
670 \r
671     /**\r
672      * DOCUMENT ME!\r
673      *\r
674      * @param c DOCUMENT ME!\r
675      * @param n DOCUMENT ME!\r
676      *\r
677      * @return DOCUMENT ME!\r
678      */\r
679     private static String repeat(char c, int n)\r
680     {\r
681         if (n <= 0)\r
682         {\r
683             return "";\r
684         }\r
685 \r
686         StringBuffer s = new StringBuffer(n);\r
687 \r
688         for (int i = 0; i < n; i++)\r
689             s.append(c);\r
690 \r
691         return s.toString();\r
692     }\r
693 \r
694     /**\r
695      * DOCUMENT ME!\r
696      *\r
697      * @param x DOCUMENT ME!\r
698      * @param n DOCUMENT ME!\r
699      * @param m DOCUMENT ME!\r
700      * @param d DOCUMENT ME!\r
701      *\r
702      * @return DOCUMENT ME!\r
703      */\r
704     private static String convert(long x, int n, int m, String d)\r
705     {\r
706         if (x == 0)\r
707         {\r
708             return "0";\r
709         }\r
710 \r
711         String r = "";\r
712 \r
713         while (x != 0)\r
714         {\r
715             r = d.charAt((int) (x & m)) + r;\r
716             x = x >>> n;\r
717         }\r
718 \r
719         return r;\r
720     }\r
721 \r
722     /**\r
723      * DOCUMENT ME!\r
724      *\r
725      * @param r DOCUMENT ME!\r
726      *\r
727      * @return DOCUMENT ME!\r
728      */\r
729     private String pad(String r)\r
730     {\r
731         String p = repeat(' ', width - r.length());\r
732 \r
733         if (left_align)\r
734         {\r
735             return pre + r + p + post;\r
736         }\r
737         else\r
738         {\r
739             return pre + p + r + post;\r
740         }\r
741     }\r
742 \r
743     /**\r
744      * DOCUMENT ME!\r
745      *\r
746      * @param s DOCUMENT ME!\r
747      * @param r DOCUMENT ME!\r
748      *\r
749      * @return DOCUMENT ME!\r
750      */\r
751     private String sign(int s, String r)\r
752     {\r
753         String p = "";\r
754 \r
755         if (s < 0)\r
756         {\r
757             p = "-";\r
758         }\r
759         else if (s > 0)\r
760         {\r
761             if (show_plus)\r
762             {\r
763                 p = "+";\r
764             }\r
765             else if (show_space)\r
766             {\r
767                 p = " ";\r
768             }\r
769         }\r
770         else\r
771         {\r
772             if ((fmt == 'o') && alternate && (r.length() > 0) &&\r
773                     (r.charAt(0) != '0'))\r
774             {\r
775                 p = "0";\r
776             }\r
777             else if ((fmt == 'x') && alternate)\r
778             {\r
779                 p = "0x";\r
780             }\r
781             else if ((fmt == 'X') && alternate)\r
782             {\r
783                 p = "0X";\r
784             }\r
785         }\r
786 \r
787         int w = 0;\r
788 \r
789         if (leading_zeroes)\r
790         {\r
791             w = width;\r
792         }\r
793         else if (((fmt == 'd') || (fmt == 'i') || (fmt == 'x') || (fmt == 'X') ||\r
794                 (fmt == 'o')) && (precision > 0))\r
795         {\r
796             w = precision;\r
797         }\r
798 \r
799         return p + repeat('0', w - p.length() - r.length()) + r;\r
800     }\r
801 \r
802     /**\r
803      * DOCUMENT ME!\r
804      *\r
805      * @param d DOCUMENT ME!\r
806      *\r
807      * @return DOCUMENT ME!\r
808      */\r
809     private String fixed_format(double d)\r
810     {\r
811         boolean removeTrailing = ((fmt == 'G') || (fmt == 'g')) && !alternate;\r
812 \r
813         // remove trailing zeroes and decimal point\r
814         if (d > 0x7FFFFFFFFFFFFFFFL)\r
815         {\r
816             return exp_format(d);\r
817         }\r
818 \r
819         if (precision == 0)\r
820         {\r
821             return (long) (d + 0.5) + (removeTrailing ? "" : ".");\r
822         }\r
823 \r
824         long whole = (long) d;\r
825         double fr = d - whole; // fractional part\r
826 \r
827         if ((fr >= 1) || (fr < 0))\r
828         {\r
829             return exp_format(d);\r
830         }\r
831 \r
832         double factor = 1;\r
833         String leading_zeroes = "";\r
834 \r
835         for (int i = 1; (i <= precision) && (factor <= 0x7FFFFFFFFFFFFFFFL);\r
836                 i++)\r
837         {\r
838             factor *= 10;\r
839             leading_zeroes = leading_zeroes + "0";\r
840         }\r
841 \r
842         long l = (long) ((factor * fr) + 0.5);\r
843 \r
844         if (l >= factor)\r
845         {\r
846             l = 0;\r
847             whole++;\r
848         }\r
849 \r
850         // CSH 10-25-97\r
851         String z = leading_zeroes + l;\r
852         z = "." + z.substring(z.length() - precision, z.length());\r
853 \r
854         if (removeTrailing)\r
855         {\r
856             int t = z.length() - 1;\r
857 \r
858             while ((t >= 0) && (z.charAt(t) == '0'))\r
859                 t--;\r
860 \r
861             if ((t >= 0) && (z.charAt(t) == '.'))\r
862             {\r
863                 t--;\r
864             }\r
865 \r
866             z = z.substring(0, t + 1);\r
867         }\r
868 \r
869         return whole + z;\r
870     }\r
871 \r
872     /**\r
873      * DOCUMENT ME!\r
874      *\r
875      * @param d DOCUMENT ME!\r
876      *\r
877      * @return DOCUMENT ME!\r
878      */\r
879     private String exp_format(double d)\r
880     {\r
881         String f = "";\r
882         int e = 0;\r
883         double dd = d;\r
884         double factor = 1;\r
885 \r
886         if (d != 0)\r
887         {\r
888             while (dd > 10)\r
889             {\r
890                 e++;\r
891                 factor /= 10;\r
892                 dd = dd / 10;\r
893             }\r
894 \r
895             while (dd < 1)\r
896             {\r
897                 e--;\r
898                 factor *= 10;\r
899                 dd = dd * 10;\r
900             }\r
901         }\r
902 \r
903         if (((fmt == 'g') || (fmt == 'G')) && (e >= -4) && (e < precision))\r
904         {\r
905             return fixed_format(d);\r
906         }\r
907 \r
908         d = d * factor;\r
909         f = f + fixed_format(d);\r
910 \r
911         if ((fmt == 'e') || (fmt == 'g'))\r
912         {\r
913             f = f + "e";\r
914         }\r
915         else\r
916         {\r
917             f = f + "E";\r
918         }\r
919 \r
920         String p = "000";\r
921 \r
922         if (e >= 0)\r
923         {\r
924             f = f + "+";\r
925             p = p + e;\r
926         }\r
927         else\r
928         {\r
929             f = f + "-";\r
930             p = p + (-e);\r
931         }\r
932 \r
933         return f + p.substring(p.length() - 3, p.length());\r
934     }\r
935 }\r