-/*\r
- * Cay S. Horstmann & Gary Cornell, Core Java\r
- * Published By Sun Microsystems Press/Prentice-Hall\r
- * Copyright (C) 1997 Sun Microsystems Inc.\r
- * All Rights Reserved.\r
- *\r
- * Permission to use, copy, modify, and distribute this\r
- * software and its documentation for NON-COMMERCIAL purposes\r
- * and without fee is hereby granted provided that this\r
- * copyright notice appears in all copies.\r
- *\r
- * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR\r
- * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
- * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS\r
- * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED\r
- * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING\r
- * THIS SOFTWARE OR ITS DERIVATIVES.\r
- */\r
-\r
-/**\r
- * A class for formatting numbers that follows printf conventions.\r
- * Also implements C-like atoi and atof functions\r
- * @version 1.03 25 Oct 1997\r
- * @author Cay Horstmann\r
- */\r
-\r
-package jalview.util;\r
-\r
-import java.io.*;\r
-\r
-public class Format {\r
- /**\r
- * Formats the number following printf conventions.\r
- * Main limitation: Can only handle one format parameter at a time\r
- * Use multiple Format objects to format more than one number\r
- * @param s the format string following printf conventions\r
- * The string has a prefix, a format code and a suffix. The prefix and suffix\r
- * become part of the formatted output. The format code directs the\r
- * formatting of the (single) parameter to be formatted. The code has the\r
- * following structure\r
- * <ul>\r
- * <li> a % (required)\r
- * <li> a modifier (optional)\r
- * <dl>\r
- * <dt> + <dd> forces display of + for positive numbers\r
- * <dt> 0 <dd> show leading zeroes\r
- * <dt> - <dd> align left in the field\r
- * <dt> space <dd> prepend a space in front of positive numbers\r
- * <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
- * </dl>\r
- * <li> an integer denoting field width (optional)\r
- * <li> a period followed by an integer denoting precision (optional)\r
- * <li> a format descriptor (required)\r
- * <dl>\r
- * <dt>f <dd> floating point number in fixed format\r
- * <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
- * <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
- * <dt>d, i <dd> integer in decimal\r
- * <dt>x <dd> integer in hexadecimal\r
- * <dt>o <dd> integer in octal\r
- * <dt>s <dd> string\r
- * <dt>c <dd> character\r
- * </dl>\r
- * </ul>\r
- * @exception IllegalArgumentException if bad format\r
- *\r
- */\r
-\r
- public static String getHexString(java.awt.Color color)\r
- {\r
- String r, g, b;\r
- r = Integer.toHexString(color.getRed());\r
- if (r.length() < 2)\r
- r = "0" + r;\r
- g = Integer.toHexString(color.getGreen());\r
- if (g.length() < 2)\r
- g = "0" + g;\r
- b = Integer.toHexString(color.getBlue());\r
- if (b.length() < 2)\r
- b = "0" + b;\r
-\r
- return r+g+b;\r
- }\r
-\r
-\r
- public Format(String s) {\r
- width = 0;\r
- precision = -1;\r
- pre = "";\r
- post = "";\r
- leading_zeroes = false;\r
- show_plus = false;\r
- alternate = false;\r
- show_space = false;\r
- left_align = false;\r
- fmt = ' ';\r
-\r
- int state = 0;\r
- int length = s.length();\r
- int parse_state = 0;\r
- // 0 = prefix, 1 = flags, 2 = width, 3 = precision,\r
- // 4 = format, 5 = end\r
- int i = 0;\r
-\r
- while (parse_state == 0) {\r
- if (i >= length)\r
- parse_state = 5;\r
- else if (s.charAt(i) == '%') {\r
- if (i < length - 1) {\r
- if (s.charAt(i + 1) == '%') {\r
- pre = pre + '%';\r
- i++;\r
- } else\r
- parse_state = 1;\r
- } else\r
- throw new java.lang.IllegalArgumentException();\r
- } else\r
- pre = pre + s.charAt(i);\r
- i++;\r
- }\r
- while (parse_state == 1) {\r
- if (i >= length)\r
- parse_state = 5;\r
- else if (s.charAt(i) == ' ')\r
- show_space = true;\r
- else if (s.charAt(i) == '-')\r
- left_align = true;\r
- else if (s.charAt(i) == '+')\r
- show_plus = true;\r
- else if (s.charAt(i) == '0')\r
- leading_zeroes = true;\r
- else if (s.charAt(i) == '#')\r
- alternate = true;\r
- else {\r
- parse_state = 2;\r
- i--;\r
- }\r
- i++;\r
- }\r
- while (parse_state == 2) {\r
- if (i >= length)\r
- parse_state = 5;\r
- else if ('0' <= s.charAt(i) && s.charAt(i) <= '9') {\r
- width = width * 10 + s.charAt(i) - '0';\r
- i++;\r
- } else if (s.charAt(i) == '.') {\r
- parse_state = 3;\r
- precision = 0;\r
- i++;\r
- } else\r
- parse_state = 4;\r
- }\r
- while (parse_state == 3) {\r
- if (i >= length)\r
- parse_state = 5;\r
- else if ('0' <= s.charAt(i) && s.charAt(i) <= '9') {\r
- precision = precision * 10 + s.charAt(i) - '0';\r
- i++;\r
- } else\r
- parse_state = 4;\r
- }\r
- if (parse_state == 4) {\r
- if (i >= length)\r
- parse_state = 5;\r
- else\r
- fmt = s.charAt(i);\r
- i++;\r
- }\r
- if (i < length)\r
- post = s.substring(i, length);\r
- }\r
-\r
- /**\r
- * prints a formatted number following printf conventions\r
- * @param s a PrintStream\r
- * @param fmt the format string\r
- * @param x the double to print\r
- */\r
-\r
- public static void print(java.io.PrintStream s, String fmt, double x) {\r
- s.print(new Format(fmt).form(x));\r
- }\r
-\r
- /**\r
- * prints a formatted number following printf conventions\r
- * @param s a PrintStream\r
- * @param fmt the format string\r
- * @param x the long to print\r
- */\r
- public static void print(java.io.PrintStream s, String fmt, long x) {\r
- s.print(new Format(fmt).form(x));\r
- }\r
-\r
- /**\r
- * prints a formatted number following printf conventions\r
- * @param s a PrintStream\r
- * @param fmt the format string\r
- * @param x the character to\r
- */\r
-\r
- public static void print(java.io.PrintStream s, String fmt, char x) {\r
- s.print(new Format(fmt).form(x));\r
- }\r
-\r
- /**\r
- * prints a formatted number following printf conventions\r
- * @param s a PrintStream, fmt the format string\r
- * @param x a string that represents the digits to print\r
- */\r
-\r
- public static void print(java.io.PrintStream s, String fmt, String x) {\r
- s.print(new Format(fmt).form(x));\r
- }\r
-\r
- /**\r
- * Converts a string of digits (decimal, octal or hex) to an integer\r
- * @param s a string\r
- * @return the numeric value of the prefix of s representing a base 10 integer\r
- */\r
-\r
- public static int atoi(String s) {\r
- return (int)atol(s);\r
- }\r
-\r
- /**\r
- * Converts a string of digits (decimal, octal or hex) to a long integer\r
- * @param s a string\r
- * @return the numeric value of the prefix of s representing a base 10 integer\r
- */\r
-\r
- public static long atol(String s) {\r
- int i = 0;\r
-\r
- while (i < s.length() && Character.isWhitespace(s.charAt(i)))\r
- i++;\r
- if (i < s.length() && s.charAt(i) == '0') {\r
- if (i + 1 < s.length() && (s.charAt(i + 1) == 'x' || s.charAt(i + 1) == 'X'))\r
- return parseLong(s.substring(i + 2), 16);\r
- else\r
- return parseLong(s, 8);\r
- } else\r
- return parseLong(s, 10);\r
- }\r
-\r
- private static long parseLong(String s, int base) {\r
- int i = 0;\r
- int sign = 1;\r
- long r = 0;\r
-\r
- while (i < s.length() && Character.isWhitespace(s.charAt(i)))\r
- i++;\r
- if (i < s.length() && s.charAt(i) == '-') {\r
- sign = -1;\r
- i++;\r
- } else if (i < s.length() && s.charAt(i) == '+') {\r
- i++;\r
- }\r
- while (i < s.length()) {\r
- char ch = s.charAt(i);\r
- if ('0' <= ch && ch < '0' + base)\r
- r = r * base + ch - '0';\r
- else if ('A' <= ch && ch < 'A' + base - 10)\r
- r = r * base + ch - 'A' + 10 ;\r
- else if ('a' <= ch && ch < 'a' + base - 10)\r
- r = r * base + ch - 'a' + 10 ;\r
- else\r
- return r * sign;\r
- i++;\r
- }\r
- return r * sign;\r
- }\r
-\r
- /**\r
- * Converts a string of digits to an double\r
- * @param s a string\r
- */\r
-\r
- public static double atof(String s) {\r
- int i = 0;\r
- int sign = 1;\r
- double r = 0; // integer part\r
- double f = 0; // fractional part\r
- double p = 1; // exponent of fractional part\r
- int state = 0; // 0 = int part, 1 = frac part\r
-\r
- while (i < s.length() && Character.isWhitespace(s.charAt(i)))\r
- i++;\r
- if (i < s.length() && s.charAt(i) == '-') {\r
- sign = -1;\r
- i++;\r
- } else if (i < s.length() && s.charAt(i) == '+') {\r
- i++;\r
- }\r
- while (i < s.length()) {\r
- char ch = s.charAt(i);\r
- if ('0' <= ch && ch <= '9') {\r
- if (state == 0)\r
- r = r * 10 + ch - '0';\r
- else if (state == 1) {\r
- p = p / 10;\r
- r = r + p * (ch - '0');\r
- }\r
- } else if (ch == '.') {\r
- if (state == 0)\r
- state = 1;\r
- else\r
- return sign * r;\r
- } else if (ch == 'e' || ch == 'E') {\r
- long e = (int)parseLong(s.substring(i + 1), 10);\r
- return sign * r * Math.pow(10, e);\r
- } else\r
- return sign * r;\r
- i++;\r
- }\r
- return sign * r;\r
- }\r
-\r
- /**\r
- * Formats a double into a string (like sprintf in C)\r
- * @param x the number to format\r
- * @return the formatted string\r
- * @exception IllegalArgumentException if bad argument\r
- */\r
-\r
- public String form(double x) {\r
- String r;\r
- if (precision < 0)\r
- precision = 6;\r
- int s = 1;\r
- if (x < 0) {\r
- x = -x;\r
- s = -1;\r
- }\r
- if (fmt == 'f')\r
- r = fixed_format(x);\r
- else if (fmt == 'e' || fmt == 'E' || fmt == 'g' || fmt == 'G')\r
- r = exp_format(x);\r
- else\r
- throw new java.lang.IllegalArgumentException();\r
-\r
- return pad(sign(s, r));\r
- }\r
-\r
- /**\r
- * Formats a long integer into a string (like sprintf in C)\r
- * @param x the number to format\r
- * @return the formatted string\r
- */\r
-\r
- public String form(long x) {\r
- String r;\r
- int s = 0;\r
- if (fmt == 'd' || fmt == 'i') {\r
- if (x < 0) {\r
- r = ("" + x).substring(1);\r
- s = -1;\r
- } else {\r
- r = "" + x;\r
- s = 1;\r
- }\r
- } else if (fmt == 'o')\r
- r = convert(x, 3, 7, "01234567");\r
- else if (fmt == 'x')\r
- r = convert(x, 4, 15, "0123456789abcdef");\r
- else if (fmt == 'X')\r
- r = convert(x, 4, 15, "0123456789ABCDEF");\r
- else\r
- throw new java.lang.IllegalArgumentException();\r
-\r
- return pad(sign(s, r));\r
- }\r
-\r
- /**\r
- * Formats a character into a string (like sprintf in C)\r
- * @param x the value to format\r
- * @return the formatted string\r
- */\r
-\r
- public String form(char c) {\r
- if (fmt != 'c')\r
- throw new java.lang.IllegalArgumentException();\r
-\r
- String r = "" + c;\r
- return pad(r);\r
- }\r
-\r
- /**\r
- * Formats a string into a larger string (like sprintf in C)\r
- * @param x the value to format\r
- * @return the formatted string\r
- */\r
-\r
- public String form(String s) {\r
- if (fmt != 's')\r
- throw new java.lang.IllegalArgumentException();\r
- if (precision >= 0)\r
- s = s.substring(0, precision);\r
- return pad(s);\r
- }\r
-\r
-\r
- /**\r
- * a test stub for the format class\r
- */\r
-\r
- public static void main(String[] a) {\r
- double x = 1.23456789012;\r
- double y = 123;\r
- double z = 1.2345e30;\r
- double w = 1.02;\r
- double u = 1.234e-5;\r
- int d = 0xCAFE;\r
- Format.print(System.out, "x = |%f|\n", x);\r
- Format.print(System.out, "u = |%20f|\n", u);\r
- Format.print(System.out, "x = |% .5f|\n", x);\r
- Format.print(System.out, "w = |%20.5f|\n", w);\r
- Format.print(System.out, "x = |%020.5f|\n", x);\r
- Format.print(System.out, "x = |%+20.5f|\n", x);\r
- Format.print(System.out, "x = |%+020.5f|\n", x);\r
- Format.print(System.out, "x = |% 020.5f|\n", x);\r
- Format.print(System.out, "y = |%#+20.5f|\n", y);\r
- Format.print(System.out, "y = |%-+20.5f|\n", y);\r
- Format.print(System.out, "z = |%20.5f|\n", z);\r
-\r
- Format.print(System.out, "x = |%e|\n", x);\r
- Format.print(System.out, "u = |%20e|\n", u);\r
- Format.print(System.out, "x = |% .5e|\n", x);\r
- Format.print(System.out, "w = |%20.5e|\n", w);\r
- Format.print(System.out, "x = |%020.5e|\n", x);\r
- Format.print(System.out, "x = |%+20.5e|\n", x);\r
- Format.print(System.out, "x = |%+020.5e|\n", x);\r
- Format.print(System.out, "x = |% 020.5e|\n", x);\r
- Format.print(System.out, "y = |%#+20.5e|\n", y);\r
- Format.print(System.out, "y = |%-+20.5e|\n", y);\r
-\r
- Format.print(System.out, "x = |%g|\n", x);\r
- Format.print(System.out, "z = |%g|\n", z);\r
- Format.print(System.out, "w = |%g|\n", w);\r
- Format.print(System.out, "u = |%g|\n", u);\r
- Format.print(System.out, "y = |%.2g|\n", y);\r
- Format.print(System.out, "y = |%#.2g|\n", y);\r
-\r
- Format.print(System.out, "d = |%d|\n", d);\r
- Format.print(System.out, "d = |%20d|\n", d);\r
- Format.print(System.out, "d = |%020d|\n", d);\r
- Format.print(System.out, "d = |%+20d|\n", d);\r
- Format.print(System.out, "d = |% 020d|\n", d);\r
- Format.print(System.out, "d = |%-20d|\n", d);\r
- Format.print(System.out, "d = |%20.8d|\n", d);\r
- Format.print(System.out, "d = |%x|\n", d);\r
- Format.print(System.out, "d = |%20X|\n", d);\r
- Format.print(System.out, "d = |%#20x|\n", d);\r
- Format.print(System.out, "d = |%020X|\n", d);\r
- Format.print(System.out, "d = |%20.8x|\n", d);\r
- Format.print(System.out, "d = |%o|\n", d);\r
- Format.print(System.out, "d = |%020o|\n", d);\r
- Format.print(System.out, "d = |%#20o|\n", d);\r
- Format.print(System.out, "d = |%#020o|\n", d);\r
- Format.print(System.out, "d = |%20.12o|\n", d);\r
-\r
- Format.print(System.out, "s = |%-20s|\n", "Hello");\r
- Format.print(System.out, "s = |%-20c|\n", '!');\r
-\r
- // regression test to confirm fix of reported bugs\r
-\r
- Format.print(System.out, "|%i|\n", Long.MIN_VALUE);\r
-\r
- Format.print(System.out, "|%6.2e|\n", 0.0);\r
- Format.print(System.out, "|%6.2g|\n", 0.0);\r
-\r
- Format.print(System.out, "|%6.2f|\n", 9.99);\r
- Format.print(System.out, "|%6.2f|\n", 9.999);\r
-\r
- Format.print(System.out, "|%6.0f|\n", 9.999);\r
- }\r
-\r
- private static String repeat(char c, int n) {\r
- if (n <= 0)\r
- return "";\r
- StringBuffer s = new StringBuffer(n);\r
- for (int i = 0; i < n; i++)\r
- s.append(c);\r
- return s.toString();\r
- }\r
-\r
- private static String convert(long x, int n, int m, String d) {\r
- if (x == 0)\r
- return "0";\r
- String r = "";\r
- while (x != 0) {\r
- r = d.charAt((int)(x & m)) + r;\r
- x = x >>> n;\r
- }\r
- return r;\r
- }\r
-\r
- private String pad(String r) {\r
- String p = repeat(' ', width - r.length());\r
- if (left_align)\r
- return pre + r + p + post;\r
- else\r
- return pre + p + r + post;\r
- }\r
-\r
- private String sign(int s, String r) {\r
- String p = "";\r
- if (s < 0)\r
- p = "-";\r
- else if (s > 0) {\r
- if (show_plus)\r
- p = "+";\r
- else if (show_space)\r
- p = " ";\r
- } else {\r
- if (fmt == 'o' && alternate && r.length() > 0 && r.charAt(0) != '0')\r
- p = "0";\r
- else if (fmt == 'x' && alternate)\r
- p = "0x";\r
- else if (fmt == 'X' && alternate)\r
- p = "0X";\r
- }\r
- int w = 0;\r
- if (leading_zeroes)\r
- w = width;\r
- else if ((fmt == 'd' || fmt == 'i' || fmt == 'x' || fmt == 'X' || fmt == 'o')\r
- && precision > 0)\r
- w = precision;\r
-\r
- return p + repeat('0', w - p.length() - r.length()) + r;\r
- }\r
-\r
- private String fixed_format(double d) {\r
- boolean removeTrailing\r
- = (fmt == 'G' || fmt == 'g') && !alternate;\r
- // remove trailing zeroes and decimal point\r
-\r
- if (d > 0x7FFFFFFFFFFFFFFFL)\r
- return exp_format(d);\r
- if (precision == 0)\r
- return (long)(d + 0.5) + (removeTrailing ? "" : ".");\r
-\r
- long whole = (long)d;\r
- double fr = d - whole; // fractional part\r
- if (fr >= 1 || fr < 0)\r
- return exp_format(d);\r
-\r
- double factor = 1;\r
- String leading_zeroes = "";\r
- for (int i = 1; i <= precision && factor <= 0x7FFFFFFFFFFFFFFFL; i++) {\r
- factor *= 10;\r
- leading_zeroes = leading_zeroes + "0";\r
- }\r
- long l = (long) (factor * fr + 0.5);\r
- if (l >= factor) {\r
- l = 0;\r
- whole++;\r
- } // CSH 10-25-97\r
-\r
- String z = leading_zeroes + l;\r
- z = "." + z.substring(z.length() - precision, z.length());\r
-\r
- if (removeTrailing) {\r
- int t = z.length() - 1;\r
- while (t >= 0 && z.charAt(t) == '0')\r
- t--;\r
- if (t >= 0 && z.charAt(t) == '.')\r
- t--;\r
- z = z.substring(0, t + 1);\r
- }\r
-\r
- return whole + z;\r
- }\r
-\r
- private String exp_format(double d) {\r
- String f = "";\r
- int e = 0;\r
- double dd = d;\r
- double factor = 1;\r
- if (d != 0) {\r
- while (dd > 10) {\r
- e++;\r
- factor /= 10;\r
- dd = dd / 10;\r
- }\r
- while (dd < 1) {\r
- e--;\r
- factor *= 10;\r
- dd = dd * 10;\r
- }\r
- }\r
- if ((fmt == 'g' || fmt == 'G') && e >= -4 && e < precision)\r
- return fixed_format(d);\r
-\r
- d = d * factor;\r
- f = f + fixed_format(d);\r
-\r
- if (fmt == 'e' || fmt == 'g')\r
- f = f + "e";\r
- else\r
- f = f + "E";\r
-\r
- String p = "000";\r
- if (e >= 0) {\r
- f = f + "+";\r
- p = p + e;\r
- } else {\r
- f = f + "-";\r
- p = p + (-e);\r
- }\r
-\r
- return f + p.substring(p.length() - 3, p.length());\r
- }\r
-\r
- private int width;\r
- private int precision;\r
- private String pre;\r
- private String post;\r
- private boolean leading_zeroes;\r
- private boolean show_plus;\r
- private boolean alternate;\r
- private boolean show_space;\r
- private boolean left_align;\r
- private char fmt; // one of cdeEfgGiosxXos\r
-}\r
-\r
-\r
-\r
-\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+/**
+ * A class for formatting numbers that follows printf conventions.
+ * Also implements C-like atoi and atof functions
+ * @version 1.03 25 Oct 1997
+ * @author Cay Horstmann
+ */
+package jalview.util;
+
+import java.util.Arrays;
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class Format
+{
+ private int width;
+
+ private int precision;
+
+ private String pre;
+
+ private String post;
+
+ private boolean leading_zeroes;
+
+ private boolean show_plus;
+
+ private boolean alternate;
+
+ private boolean show_space;
+
+ private boolean left_align;
+
+ private char fmt; // one of cdeEfgGiosxXos
+
+ private final String formatString;
+
+ /**
+ * Creates a new Format object.
+ *
+ * @param s
+ * DOCUMENT ME!
+ */
+ public Format(String s)
+ {
+ formatString = s;
+ width = 0;
+ precision = -1;
+ pre = "";
+ post = "";
+ leading_zeroes = false;
+ show_plus = false;
+ alternate = false;
+ show_space = false;
+ left_align = false;
+ fmt = ' ';
+
+ int length = s.length();
+ int parse_state = 0;
+
+ // 0 = prefix, 1 = flags, 2 = width, 3 = precision,
+ // 4 = format, 5 = end
+ int i = 0;
+
+ while (parse_state == 0)
+ {
+ if (i >= length)
+ {
+ parse_state = 5;
+ }
+ else if (s.charAt(i) == '%')
+ {
+ if (i < (length - 1))
+ {
+ if (s.charAt(i + 1) == '%')
+ {
+ pre = pre + '%';
+ i++;
+ }
+ else
+ {
+ parse_state = 1;
+ }
+ }
+ else
+ {
+ throw new java.lang.IllegalArgumentException();
+ }
+ }
+ else
+ {
+ pre = pre + s.charAt(i);
+ }
+
+ i++;
+ }
+
+ while (parse_state == 1)
+ {
+ if (i >= length)
+ {
+ parse_state = 5;
+ }
+ else if (s.charAt(i) == ' ')
+ {
+ show_space = true;
+ }
+ else if (s.charAt(i) == '-')
+ {
+ left_align = true;
+ }
+ else if (s.charAt(i) == '+')
+ {
+ show_plus = true;
+ }
+ else if (s.charAt(i) == '0')
+ {
+ leading_zeroes = true;
+ }
+ else if (s.charAt(i) == '#')
+ {
+ alternate = true;
+ }
+ else
+ {
+ parse_state = 2;
+ i--;
+ }
+
+ i++;
+ }
+
+ while (parse_state == 2)
+ {
+ if (i >= length)
+ {
+ parse_state = 5;
+ }
+ else if (('0' <= s.charAt(i)) && (s.charAt(i) <= '9'))
+ {
+ width = ((width * 10) + s.charAt(i)) - '0';
+ i++;
+ }
+ else if (s.charAt(i) == '.')
+ {
+ parse_state = 3;
+ precision = 0;
+ i++;
+ }
+ else
+ {
+ parse_state = 4;
+ }
+ }
+
+ while (parse_state == 3)
+ {
+ if (i >= length)
+ {
+ parse_state = 5;
+ }
+ else if (('0' <= s.charAt(i)) && (s.charAt(i) <= '9'))
+ {
+ precision = ((precision * 10) + s.charAt(i)) - '0';
+ i++;
+ }
+ else
+ {
+ parse_state = 4;
+ }
+ }
+
+ if (parse_state == 4)
+ {
+ if (i >= length)
+ {
+ parse_state = 5;
+ }
+ else
+ {
+ fmt = s.charAt(i);
+ }
+
+ i++;
+ }
+
+ if (i < length)
+ {
+ post = s.substring(i, length);
+ }
+ }
+
+ /**
+ * Formats the number following printf conventions. Main limitation: Can only
+ * handle one format parameter at a time Use multiple Format objects to format
+ * more than one number
+ *
+ * @param s
+ * the format string following printf conventions The string has a
+ * prefix, a format code and a suffix. The prefix and suffix become
+ * part of the formatted output. The format code directs the
+ * formatting of the (single) parameter to be formatted. The code has
+ * the following structure
+ * <ul>
+ * <li>a % (required)
+ * <li>a modifier (optional)
+ * <dl>
+ * <dt>+
+ * <dd>forces display of + for positive numbers
+ * <dt>0
+ * <dd>show leading zeroes
+ * <dt>-
+ * <dd>align left in the field
+ * <dt>space
+ * <dd>prepend a space in front of positive numbers
+ * <dt>#
+ * <dd>use "alternate" format. Add 0 or 0x for octal or hexadecimal
+ * numbers. Don't suppress trailing zeroes in general floating point
+ * format.
+ * </dl>
+ * <li>an integer denoting field width (optional)
+ * <li>a period followed by an integer denoting precision (optional)
+ * <li>a format descriptor (required)
+ * <dl>
+ * <dt>f
+ * <dd>floating point number in fixed format
+ * <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.
+ * <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.
+ * <dt>d, i
+ * <dd>integer in decimal
+ * <dt>x
+ * <dd>integer in hexadecimal
+ * <dt>o
+ * <dd>integer in octal
+ * <dt>s
+ * <dd>string
+ * <dt>c
+ * <dd>character
+ * </dl>
+ * </ul>
+ * @exception IllegalArgumentException
+ * if bad format
+ *
+ */
+ public static String getHexString(java.awt.Color color)
+ {
+ String r;
+ String g;
+ String b;
+ r = Integer.toHexString(color.getRed());
+
+ if (r.length() < 2)
+ {
+ r = "0" + r;
+ }
+
+ g = Integer.toHexString(color.getGreen());
+
+ if (g.length() < 2)
+ {
+ g = "0" + g;
+ }
+
+ b = Integer.toHexString(color.getBlue());
+
+ if (b.length() < 2)
+ {
+ b = "0" + b;
+ }
+
+ return r + g + b;
+ }
+
+ /**
+ * prints a formatted number following printf conventions
+ *
+ * @param s
+ * a PrintStream
+ * @param fmt
+ * the format string
+ * @param x
+ * the double to print
+ */
+ public static void print(java.io.PrintStream s, String fmt, double x)
+ {
+ s.print(new Format(fmt).form(x));
+ }
+
+ /**
+ * prints a formatted number following printf conventions
+ *
+ * @param s
+ * a PrintStream
+ * @param fmt
+ * the format string
+ * @param x
+ * the long to print
+ */
+ public static void print(java.io.PrintStream s, String fmt, long x)
+ {
+ s.print(new Format(fmt).form(x));
+ }
+
+ /**
+ * prints a formatted number following printf conventions
+ *
+ * @param s
+ * a PrintStream
+ * @param fmt
+ * the format string
+ * @param x
+ * the character to
+ */
+ public static void print(java.io.PrintStream s, String fmt, char x)
+ {
+ s.print(new Format(fmt).form(x));
+ }
+
+ /**
+ * prints a formatted number following printf conventions
+ *
+ * @param s
+ * a PrintStream, fmt the format string
+ * @param x
+ * a string that represents the digits to print
+ */
+ public static void print(java.io.PrintStream s, String fmt, String x)
+ {
+ s.print(new Format(fmt).form(x));
+ }
+
+ /**
+ * Converts a string of digits (decimal, octal or hex) to an integer
+ *
+ * @param s
+ * a string
+ * @return the numeric value of the prefix of s representing a base 10 integer
+ */
+ public static int atoi(String s)
+ {
+ return (int) atol(s);
+ }
+
+ /**
+ * Converts a string of digits (decimal, octal or hex) to a long integer
+ *
+ * @param s
+ * a string
+ * @return the numeric value of the prefix of s representing a base 10 integer
+ */
+ public static long atol(String s)
+ {
+ int i = 0;
+
+ while ((i < s.length()) && Character.isWhitespace(s.charAt(i)))
+ {
+ i++;
+ }
+
+ if ((i < s.length()) && (s.charAt(i) == '0'))
+ {
+ if (((i + 1) < s.length())
+ && ((s.charAt(i + 1) == 'x') || (s.charAt(i + 1) == 'X')))
+ {
+ return parseLong(s.substring(i + 2), 16);
+ }
+ else
+ {
+ return parseLong(s, 8);
+ }
+ }
+ else
+ {
+ return parseLong(s, 10);
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param s
+ * DOCUMENT ME!
+ * @param base
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private static long parseLong(String s, int base)
+ {
+ int i = 0;
+ int sign = 1;
+ long r = 0;
+
+ while ((i < s.length()) && Character.isWhitespace(s.charAt(i)))
+ {
+ i++;
+ }
+
+ if ((i < s.length()) && (s.charAt(i) == '-'))
+ {
+ sign = -1;
+ i++;
+ }
+ else if ((i < s.length()) && (s.charAt(i) == '+'))
+ {
+ i++;
+ }
+
+ while (i < s.length())
+ {
+ char ch = s.charAt(i);
+
+ if (('0' <= ch) && (ch < ('0' + base)))
+ {
+ r = ((r * base) + ch) - '0';
+ }
+ else if (('A' <= ch) && (ch < (('A' + base) - 10)))
+ {
+ r = ((r * base) + ch) - 'A' + 10;
+ }
+ else if (('a' <= ch) && (ch < (('a' + base) - 10)))
+ {
+ r = ((r * base) + ch) - 'a' + 10;
+ }
+ else
+ {
+ return r * sign;
+ }
+
+ i++;
+ }
+
+ return r * sign;
+ }
+
+ /**
+ * Converts a string of digits to an double
+ *
+ * @param s
+ * a string
+ */
+ public static double atof(String s)
+ {
+ int i = 0;
+ int sign = 1;
+ double r = 0; // integer part
+ // double f = 0; // fractional part
+ double p = 1; // exponent of fractional part
+ int state = 0; // 0 = int part, 1 = frac part
+
+ while ((i < s.length()) && Character.isWhitespace(s.charAt(i)))
+ {
+ i++;
+ }
+
+ if ((i < s.length()) && (s.charAt(i) == '-'))
+ {
+ sign = -1;
+ i++;
+ }
+ else if ((i < s.length()) && (s.charAt(i) == '+'))
+ {
+ i++;
+ }
+
+ while (i < s.length())
+ {
+ char ch = s.charAt(i);
+
+ if (('0' <= ch) && (ch <= '9'))
+ {
+ if (state == 0)
+ {
+ r = ((r * 10) + ch) - '0';
+ }
+ else if (state == 1)
+ {
+ p = p / 10;
+ r = r + (p * (ch - '0'));
+ }
+ }
+ else if (ch == '.')
+ {
+ if (state == 0)
+ {
+ state = 1;
+ }
+ else
+ {
+ return sign * r;
+ }
+ }
+ else if ((ch == 'e') || (ch == 'E'))
+ {
+ long e = (int) parseLong(s.substring(i + 1), 10);
+
+ return sign * r * Math.pow(10, e);
+ }
+ else
+ {
+ return sign * r;
+ }
+
+ i++;
+ }
+
+ return sign * r;
+ }
+
+ /**
+ * Formats a double into a string (like sprintf in C)
+ *
+ * @param x
+ * the number to format
+ * @return the formatted string
+ * @exception IllegalArgumentException
+ * if bad argument
+ */
+ public String form(double x)
+ {
+ String r;
+
+ if (precision < 0)
+ {
+ precision = 6;
+ }
+
+ int s = 1;
+
+ if (x < 0)
+ {
+ x = -x;
+ s = -1;
+ }
+
+ if (fmt == 'f')
+ {
+ r = fixed_format(x);
+ }
+ else if ((fmt == 'e') || (fmt == 'E') || (fmt == 'g') || (fmt == 'G'))
+ {
+ r = exp_format(x);
+ }
+ else
+ {
+ throw new java.lang.IllegalArgumentException();
+ }
+
+ return pad(sign(s, r));
+ }
+
+ /**
+ * Formats a long integer into a string (like sprintf in C)
+ *
+ * @param x
+ * the number to format
+ * @return the formatted string
+ */
+ public String form(long x)
+ {
+ String r;
+ int s = 0;
+
+ if ((fmt == 'd') || (fmt == 'i'))
+ {
+ if (x < 0)
+ {
+ r = ("" + x).substring(1);
+ s = -1;
+ }
+ else
+ {
+ r = "" + x;
+ s = 1;
+ }
+ }
+ else if (fmt == 'o')
+ {
+ r = convert(x, 3, 7, "01234567");
+ }
+ else if (fmt == 'x')
+ {
+ r = convert(x, 4, 15, "0123456789abcdef");
+ }
+ else if (fmt == 'X')
+ {
+ r = convert(x, 4, 15, "0123456789ABCDEF");
+ }
+ else
+ {
+ throw new java.lang.IllegalArgumentException();
+ }
+
+ return pad(sign(s, r));
+ }
+
+ /**
+ * Formats a character into a string (like sprintf in C)
+ *
+ * @param debounceTrap
+ * the value to format
+ * @return the formatted string
+ */
+ public String form(char c)
+ {
+ if (fmt != 'c')
+ {
+ throw new java.lang.IllegalArgumentException();
+ }
+
+ String r = "" + c;
+
+ return pad(r);
+ }
+
+ /**
+ * Formats a string into a larger string (like sprintf in C)
+ *
+ * @param debounceTrap
+ * the value to format
+ * @return the formatted string
+ */
+ public String form(String s)
+ {
+ if (fmt != 's')
+ {
+ throw new java.lang.IllegalArgumentException();
+ }
+
+ if (precision >= 0)
+ {
+ s = s.substring(0, precision);
+ }
+
+ return pad(s);
+ }
+
+ /**
+ * Returns a string consisting of n repeats of character c
+ *
+ * @param c
+ * @param n
+ *
+ * @return
+ */
+ static String repeat(char c, int n)
+ {
+ if (n <= 0)
+ {
+ return "";
+ }
+ char[] chars = new char[n];
+ Arrays.fill(chars, c);
+ return new String(chars);
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param x
+ * DOCUMENT ME!
+ * @param n
+ * DOCUMENT ME!
+ * @param m
+ * DOCUMENT ME!
+ * @param d
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private static String convert(long x, int n, int m, String d)
+ {
+ if (x == 0)
+ {
+ return "0";
+ }
+
+ String r = "";
+
+ while (x != 0)
+ {
+ r = d.charAt((int) (x & m)) + r;
+ x = x >>> n;
+ }
+
+ return r;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param r
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private String pad(String r)
+ {
+ String p = repeat(' ', width - r.length());
+
+ if (left_align)
+ {
+ return pre + r + p + post;
+ }
+ else
+ {
+ return pre + p + r + post;
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param s
+ * DOCUMENT ME!
+ * @param r
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private String sign(int s, String r)
+ {
+ String p = "";
+
+ if (s < 0)
+ {
+ p = "-";
+ }
+ else if (s > 0)
+ {
+ if (show_plus)
+ {
+ p = "+";
+ }
+ else if (show_space)
+ {
+ p = " ";
+ }
+ }
+ else
+ {
+ if ((fmt == 'o') && alternate && (r.length() > 0)
+ && (r.charAt(0) != '0'))
+ {
+ p = "0";
+ }
+ else if ((fmt == 'x') && alternate)
+ {
+ p = "0x";
+ }
+ else if ((fmt == 'X') && alternate)
+ {
+ p = "0X";
+ }
+ }
+
+ int w = 0;
+
+ if (leading_zeroes)
+ {
+ w = width;
+ }
+ else if (((fmt == 'd') || (fmt == 'i') || (fmt == 'x') || (fmt == 'X')
+ || (fmt == 'o')) && (precision > 0))
+ {
+ w = precision;
+ }
+
+ return p + repeat('0', w - p.length() - r.length()) + r;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param d
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private String fixed_format(double d)
+ {
+ boolean removeTrailing = ((fmt == 'G') || (fmt == 'g')) && !alternate;
+
+ // remove trailing zeroes and decimal point
+ if (d > 0x7FFFFFFFFFFFFFFFL)
+ {
+ return exp_format(d);
+ }
+
+ if (precision == 0)
+ {
+ return (long) (d + 0.5) + (removeTrailing ? "" : ".");
+ }
+
+ long whole = (long) d;
+ double fr = d - whole; // fractional part
+
+ if ((fr >= 1) || (fr < 0))
+ {
+ return exp_format(d);
+ }
+
+ double factor = 1;
+ String leading_zeroes = "";
+
+ for (int i = 1; (i <= precision)
+ && (factor <= 0x7FFFFFFFFFFFFFFFL); i++)
+ {
+ factor *= 10;
+ leading_zeroes = leading_zeroes + "0";
+ }
+
+ long l = (long) ((factor * fr) + 0.5);
+
+ if (l >= factor)
+ {
+ l = 0;
+ whole++;
+ }
+
+ // CSH 10-25-97
+ String z = leading_zeroes + l;
+ z = "." + z.substring(z.length() - precision, z.length());
+
+ if (removeTrailing)
+ {
+ int t = z.length() - 1;
+
+ while ((t >= 0) && (z.charAt(t) == '0'))
+ {
+ t--;
+ }
+
+ if ((t >= 0) && (z.charAt(t) == '.'))
+ {
+ t--;
+ }
+
+ z = z.substring(0, t + 1);
+ }
+
+ return whole + z;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param d
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private String exp_format(double d)
+ {
+ String f = "";
+ int e = 0;
+ double dd = d;
+
+ if (d != 0)
+ {
+ while (dd > 10)
+ {
+ e++;
+ dd = dd / 10;
+ }
+
+ while (dd < 1)
+ {
+ e--;
+ dd = dd * 10;
+ }
+ }
+
+ if (((fmt == 'g') || (fmt == 'G')) && (e >= -4) && (e < precision))
+ {
+ return fixed_format(d);
+ }
+
+ f = f + fixed_format(dd);
+
+ if ((fmt == 'e') || (fmt == 'g'))
+ {
+ f = f + "e";
+ }
+ else
+ {
+ f = f + "E";
+ }
+
+ String p = "000";
+
+ if (e >= 0)
+ {
+ f = f + "+";
+ p = p + e;
+ }
+ else
+ {
+ f = f + "-";
+ p = p + (-e);
+ }
+
+ return f + p.substring(p.length() - 3, p.length());
+ }
+
+ @Override
+ public String toString()
+ {
+ return formatString;
+ }
+
+ /**
+ * Bespoke method to format percentage float value to the specified number of
+ * decimal places. Avoids use of general-purpose format parsers as a
+ * processing hotspot.
+ *
+ * @param sb
+ * @param value
+ * @param dp
+ */
+ public static void appendPercentage(StringBuilder sb, float value, int dp)
+ {
+ /*
+ * rounding first
+ */
+ double d = value;
+ long factor = 1L;
+ for (int i = 0; i < dp; i++)
+ {
+ factor *= 10;
+ }
+ d *= factor;
+ d += 0.5;
+
+ /*
+ * integer part
+ */
+ value = (float) (d / factor);
+ sb.append((long) value);
+
+ /*
+ * decimal places
+ */
+ if (dp > 0)
+ {
+ sb.append(".");
+ while (dp > 0)
+ {
+ value = value - (int) value;
+ value *= 10;
+ sb.append((int) value);
+ dp--;
+ }
+ }
+ }
+}