pax_global_header 0000666 0000000 0000000 00000000064 12251210002 0014473 g ustar 00root root 0000000 0000000 52 comment=9565bff72c5f5b7cd1ecefe8eead5dd19e3b7c5e
jformatstring-0.10~20131207/ 0000775 0000000 0000000 00000000000 12251210002 0015322 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/README 0000664 0000000 0000000 00000000000 12251210002 0016170 0 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/build.xml 0000664 0000000 0000000 00000004050 12251210002 0017142 0 ustar 00root root 0000000 0000000
FB home ${findbugs.home}
FB ant ${anttask.jar}
jformatstring-0.10~20131207/src/ 0000775 0000000 0000000 00000000000 12251210002 0016111 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/ 0000775 0000000 0000000 00000000000 12251210002 0017032 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/ 0000775 0000000 0000000 00000000000 12251210002 0017607 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/ 0000775 0000000 0000000 00000000000 12251210002 0020374 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/ 0000775 0000000 0000000 00000000000 12251210002 0021001 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/ 0000775 0000000 0000000 00000000000 12251210002 0022602 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/ 0000775 0000000 0000000 00000000000 12251210002 0026546 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/Conversion.java 0000664 0000000 0000000 00000010421 12251210002 0031534 0 ustar 00root root 0000000 0000000 /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
class Conversion {
// Byte, Short, Integer, Long, BigInteger
// (and associated primitives due to autoboxing)
static final char DECIMAL_INTEGER = 'd';
static final char OCTAL_INTEGER = 'o';
static final char HEXADECIMAL_INTEGER = 'x';
static final char HEXADECIMAL_INTEGER_UPPER = 'X';
// Float, Double, BigDecimal
// (and associated primitives due to autoboxing)
static final char SCIENTIFIC = 'e';
static final char SCIENTIFIC_UPPER = 'E';
static final char GENERAL = 'g';
static final char GENERAL_UPPER = 'G';
static final char DECIMAL_FLOAT = 'f';
static final char HEXADECIMAL_FLOAT = 'a';
static final char HEXADECIMAL_FLOAT_UPPER = 'A';
// Character, Byte, Short, Integer
// (and associated primitives due to autoboxing)
static final char CHARACTER = 'c';
static final char CHARACTER_UPPER = 'C';
// java.util.Date, java.util.Calendar, long
static final char DATE_TIME = 't';
static final char DATE_TIME_UPPER = 'T';
// if (arg.TYPE != boolean) return boolean
// if (arg != null) return true; else return false;
static final char BOOLEAN = 'b';
static final char BOOLEAN_UPPER = 'B';
// if (arg instanceof Formattable) arg.formatTo()
// else arg.toString();
static final char STRING = 's';
static final char STRING_UPPER = 'S';
// arg.hashCode()
static final char HASHCODE = 'h';
static final char HASHCODE_UPPER = 'H';
static final char LINE_SEPARATOR = 'n';
static final char PERCENT_SIGN = '%';
static boolean isValid(char c) {
return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c)
|| c == 't' || isCharacter(c));
}
// Returns true iff the Conversion is applicable to all objects.
static boolean isGeneral(char c) {
switch (c) {
case BOOLEAN:
case BOOLEAN_UPPER:
case STRING:
case STRING_UPPER:
case HASHCODE:
case HASHCODE_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion is applicable to character.
static boolean isCharacter(char c) {
switch (c) {
case CHARACTER:
case CHARACTER_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion is an integer type.
static boolean isInteger(char c) {
switch (c) {
case DECIMAL_INTEGER:
case OCTAL_INTEGER:
case HEXADECIMAL_INTEGER:
case HEXADECIMAL_INTEGER_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion is a floating-point type.
static boolean isFloat(char c) {
switch (c) {
case SCIENTIFIC:
case SCIENTIFIC_UPPER:
case GENERAL:
case GENERAL_UPPER:
case DECIMAL_FLOAT:
case HEXADECIMAL_FLOAT:
case HEXADECIMAL_FLOAT_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion does not require an argument
static boolean isText(char c) {
switch (c) {
case LINE_SEPARATOR:
case PERCENT_SIGN:
return true;
default:
return false;
}
}
} jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/DateTime.java 0000664 0000000 0000000 00000011375 12251210002 0031114 0 ustar 00root root 0000000 0000000 /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
class DateTime {
static final char HOUR_OF_DAY_0 = 'H'; // (00 - 23)
static final char HOUR_0 = 'I'; // (01 - 12)
static final char HOUR_OF_DAY = 'k'; // (0 - 23) -- like H
static final char HOUR = 'l'; // (1 - 12) -- like I
static final char MINUTE = 'M'; // (00 - 59)
static final char NANOSECOND = 'N'; // (000000000 - 999999999)
static final char MILLISECOND = 'L'; // jdk, not in gnu (000 - 999)
static final char MILLISECOND_SINCE_EPOCH = 'Q'; // (0 - 99...?)
static final char AM_PM = 'p'; // (am or pm)
static final char SECONDS_SINCE_EPOCH = 's'; // (0 - 99...?)
static final char SECOND = 'S'; // (00 - 60 - leap second)
static final char TIME = 'T'; // (24 hour hh:mm:ss)
static final char ZONE_NUMERIC = 'z'; // (-1200 - +1200) - ls minus?
static final char ZONE = 'Z'; // (symbol)
// Date
static final char NAME_OF_DAY_ABBREV = 'a'; // 'a'
static final char NAME_OF_DAY = 'A'; // 'A'
static final char NAME_OF_MONTH_ABBREV = 'b'; // 'b'
static final char NAME_OF_MONTH = 'B'; // 'B'
static final char CENTURY = 'C'; // (00 - 99)
static final char DAY_OF_MONTH_0 = 'd'; // (01 - 31)
static final char DAY_OF_MONTH = 'e'; // (1 - 31) -- like d
// * static final char ISO_WEEK_OF_YEAR_2 = 'g'; // cross %y %V
// * static final char ISO_WEEK_OF_YEAR_4 = 'G'; // cross %Y %V
static final char NAME_OF_MONTH_ABBREV_X = 'h'; // -- same b
static final char DAY_OF_YEAR = 'j'; // (001 - 366)
static final char MONTH = 'm'; // (01 - 12)
// * static final char DAY_OF_WEEK_1 = 'u'; // (1 - 7) Monday
// * static final char WEEK_OF_YEAR_SUNDAY = 'U'; // (0 - 53) Sunday+
// * static final char WEEK_OF_YEAR_MONDAY_01 = 'V'; // (01 - 53) Monday+
// * static final char DAY_OF_WEEK_0 = 'w'; // (0 - 6) Sunday
// * static final char WEEK_OF_YEAR_MONDAY = 'W'; // (00 - 53) Monday
static final char YEAR_2 = 'y'; // (00 - 99)
static final char YEAR_4 = 'Y'; // (0000 - 9999)
// Composites
static final char TIME_12_HOUR = 'r'; // (hh:mm:ss [AP]M)
static final char TIME_24_HOUR = 'R'; // (hh:mm same as %H:%M)
// * static final char LOCALE_TIME = 'X'; // (%H:%M:%S) - parse format?
static final char DATE_TIME = 'c';
// (Sat Nov 04 12:02:33 EST 1999)
static final char DATE = 'D'; // (mm/dd/yy)
static final char ISO_STANDARD_DATE = 'F'; // (%Y-%m-%d)
// * static final char LOCALE_DATE = 'x'; // (mm/dd/yy)
static boolean isValid(char c) {
switch (c) {
case HOUR_OF_DAY_0:
case HOUR_0:
case HOUR_OF_DAY:
case HOUR:
case MINUTE:
case NANOSECOND:
case MILLISECOND:
case MILLISECOND_SINCE_EPOCH:
case AM_PM:
case SECONDS_SINCE_EPOCH:
case SECOND:
case TIME:
case ZONE_NUMERIC:
case ZONE:
// Date
case NAME_OF_DAY_ABBREV:
case NAME_OF_DAY:
case NAME_OF_MONTH_ABBREV:
case NAME_OF_MONTH:
case CENTURY:
case DAY_OF_MONTH_0:
case DAY_OF_MONTH:
// * case ISO_WEEK_OF_YEAR_2:
// * case ISO_WEEK_OF_YEAR_4:
case NAME_OF_MONTH_ABBREV_X:
case DAY_OF_YEAR:
case MONTH:
// * case DAY_OF_WEEK_1:
// * case WEEK_OF_YEAR_SUNDAY:
// * case WEEK_OF_YEAR_MONDAY_01:
// * case DAY_OF_WEEK_0:
// * case WEEK_OF_YEAR_MONDAY:
case YEAR_2:
case YEAR_4:
// Composites
case TIME_12_HOUR:
case TIME_24_HOUR:
// * case LOCALE_TIME:
case DATE_TIME:
case DATE:
case ISO_STANDARD_DATE:
// * case LOCALE_DATE:
return true;
default:
return false;
}
}
} ExtraFormatArgumentsException.java 0000664 0000000 0000000 00000003363 12251210002 0035340 0 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
public class ExtraFormatArgumentsException extends FormatterException {
private static final long serialVersionUID = 1L;
public final int provided;
public final int used;
public ExtraFormatArgumentsException(int provided, int used) {
this.provided = provided;
this.used = used;
}
} jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/Flags.java 0000664 0000000 0000000 00000007640 12251210002 0030454 0 ustar 00root root 0000000 0000000 /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
import java.util.DuplicateFormatFlagsException;
import java.util.UnknownFormatFlagsException;
class Flags {
private int flags;
static final Flags NONE = new Flags(0); // ''
// duplicate declarations from Formattable.java
static final Flags LEFT_JUSTIFY = new Flags(1 << 0); // '-'
static final Flags UPPERCASE = new Flags(1 << 1); // '^'
static final Flags ALTERNATE = new Flags(1 << 2); // '#'
// numerics
static final Flags PLUS = new Flags(1 << 3); // '+'
static final Flags LEADING_SPACE = new Flags(1 << 4); // ' '
static final Flags ZERO_PAD = new Flags(1 << 5); // '0'
static final Flags GROUP = new Flags(1 << 6); // ','
static final Flags PARENTHESES = new Flags(1 << 7); // '('
// indexing
static final Flags PREVIOUS = new Flags(1 << 8); // '<'
private Flags(int f) {
flags = f;
}
public int valueOf() {
return flags;
}
public boolean contains(Flags f) {
return (flags & f.valueOf()) == f.valueOf();
}
public Flags dup() {
return new Flags(flags);
}
Flags add(Flags f) {
flags |= f.valueOf();
return this;
}
public Flags remove(Flags f) {
flags &= ~f.valueOf();
return this;
}
public static Flags parse(String s) {
char[] ca = s.toCharArray();
Flags f = new Flags(0);
for (int i = 0; i < ca.length; i++) {
Flags v = parse(ca[i]);
if (f.contains(v))
throw new DuplicateFormatFlagsException(v.toString());
f.add(v);
}
return f;
}
// parse those flags which may be provided by users
private static Flags parse(char c) {
switch (c) {
case '-':
return LEFT_JUSTIFY;
case '#':
return ALTERNATE;
case '+':
return PLUS;
case ' ':
return LEADING_SPACE;
case '0':
return ZERO_PAD;
case ',':
return GROUP;
case '(':
return PARENTHESES;
case '<':
return PREVIOUS;
default:
throw new UnknownFormatFlagsException(String.valueOf(c));
}
}
// Returns a string representation of the current Flags.
public static String toString(Flags f) {
return f.toString();
}
public String toString() {
StringBuilder sb = new StringBuilder();
if (contains(LEFT_JUSTIFY))
sb.append('-');
if (contains(UPPERCASE))
sb.append('^');
if (contains(ALTERNATE))
sb.append('#');
if (contains(PLUS))
sb.append('+');
if (contains(LEADING_SPACE))
sb.append(' ');
if (contains(ZERO_PAD))
sb.append('0');
if (contains(GROUP))
sb.append(',');
if (contains(PARENTHESES))
sb.append('(');
if (contains(PREVIOUS))
sb.append('<');
return sb.toString();
}
} jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/FormatSpecifier.java 0000664 0000000 0000000 00000027771 12251210002 0032511 0 ustar 00root root 0000000 0000000 /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.FormatFlagsConversionMismatchException;
import java.util.GregorianCalendar;
import java.util.IllegalFormatFlagsException;
import java.util.IllegalFormatPrecisionException;
import java.util.IllegalFormatWidthException;
import java.util.MissingFormatWidthException;
import java.util.UnknownFormatConversionException;
public class FormatSpecifier {
private int index = -1;
private Flags f = Flags.NONE;
private int width;
private int precision;
private boolean dt = false;
private char c;
private final String source;
public String toString() {
return source;
}
private int index(String s) throws FormatterNumberFormatException {
if (s != null) {
try {
index = Integer.parseInt(s.substring(0, s.length() - 1));
} catch (NumberFormatException x) {
throw new FormatterNumberFormatException(s, "index");
}
} else {
index = 0;
}
return index;
}
public int index() {
return index;
}
private Flags flags(String s) {
f = Flags.parse(s);
if (f.contains(Flags.PREVIOUS))
index = -1;
return f;
}
Flags flags() {
return f;
}
private int width(String s) throws FormatterNumberFormatException {
width = -1;
if (s != null) {
try {
width = Integer.parseInt(s);
if (width < 0)
throw new IllegalFormatWidthException(width);
} catch (NumberFormatException x) {
throw new FormatterNumberFormatException(s, "width");
}
}
return width;
}
private int precision(String s) throws FormatterNumberFormatException {
precision = -1;
if (s != null) {
try {
// remove the '.'
precision = Integer.parseInt(s.substring(1));
if (precision < 0)
throw new IllegalFormatPrecisionException(precision);
} catch (NumberFormatException x) {
throw new FormatterNumberFormatException(s, "precision");
}
}
return precision;
}
int precision() {
return precision;
}
private char conversion(String s) {
c = s.charAt(0);
if (!dt) {
if (!Conversion.isValid(c))
throw new UnknownFormatConversionException(String.valueOf(c));
if (Character.isUpperCase(c))
f.add(Flags.UPPERCASE);
c = Character.toLowerCase(c);
if (Conversion.isText(c))
index = -2;
}
return c;
}
FormatSpecifier(String source, String[] sa)
throws FormatFlagsConversionMismatchException,
FormatterNumberFormatException {
int idx = 0;
this.source = source;
index(sa[idx++]);
flags(sa[idx++]);
width(sa[idx++]);
precision(sa[idx++]);
if (sa[idx] != null) {
dt = true;
if (sa[idx].equals("T"))
f.add(Flags.UPPERCASE);
}
conversion(sa[++idx]);
if (dt)
checkDateTime();
else if (Conversion.isGeneral(c))
checkGeneral();
else if (Conversion.isCharacter(c))
checkCharacter();
else if (Conversion.isInteger(c))
checkInteger();
else if (Conversion.isFloat(c))
checkFloat();
else if (Conversion.isText(c))
checkText();
else
throw new UnknownFormatConversionException(String.valueOf(c));
}
private void checkGeneral() throws FormatFlagsConversionMismatchException {
if ((c == Conversion.BOOLEAN || c == Conversion.HASHCODE)
&& f.contains(Flags.ALTERNATE))
failMismatch(Flags.ALTERNATE, c);
// '-' requires a width
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
throw new MissingFormatWidthException(toString());
checkBadFlags(Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD,
Flags.GROUP, Flags.PARENTHESES);
}
private void checkDateTime() throws FormatFlagsConversionMismatchException {
if (precision != -1)
throw new IllegalFormatPrecisionException(precision);
if (!DateTime.isValid(c))
throw new UnknownFormatConversionException("t" + c);
checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE,
Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES);
// '-' requires a width
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
throw new MissingFormatWidthException(toString());
}
private void checkCharacter() throws FormatFlagsConversionMismatchException {
if (precision != -1)
throw new IllegalFormatPrecisionException(precision);
checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE,
Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES);
// '-' requires a width
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
throw new MissingFormatWidthException(toString());
}
private void checkInteger() throws FormatFlagsConversionMismatchException {
checkNumeric();
if (precision != -1)
throw new IllegalFormatPrecisionException(precision);
if (c == Conversion.DECIMAL_INTEGER)
checkBadFlags(Flags.ALTERNATE);
else
checkBadFlags(Flags.GROUP);
}
private void checkBadFlags(Flags... badFlags)
throws FormatFlagsConversionMismatchException {
for (int i = 0; i < badFlags.length; i++)
if (f.contains(badFlags[i]))
failMismatch(badFlags[i], c);
}
private void checkFloat() throws FormatFlagsConversionMismatchException {
checkNumeric();
if (c == Conversion.DECIMAL_FLOAT) {
} else if (c == Conversion.HEXADECIMAL_FLOAT) {
checkBadFlags(Flags.PARENTHESES, Flags.GROUP);
} else if (c == Conversion.SCIENTIFIC) {
checkBadFlags(Flags.GROUP);
} else if (c == Conversion.GENERAL) {
checkBadFlags(Flags.ALTERNATE);
}
}
private void checkNumeric() {
if (width != -1 && width < 0)
throw new IllegalFormatWidthException(width);
if (precision != -1 && precision < 0)
throw new IllegalFormatPrecisionException(precision);
// '-' and '0' require a width
if (width == -1
&& (f.contains(Flags.LEFT_JUSTIFY) || f
.contains(Flags.ZERO_PAD)))
throw new MissingFormatWidthException(toString());
// bad combination
if ((f.contains(Flags.PLUS) && f.contains(Flags.LEADING_SPACE))
|| (f.contains(Flags.LEFT_JUSTIFY) && f
.contains(Flags.ZERO_PAD)))
throw new IllegalFormatFlagsException(f.toString());
}
private void checkText() {
if (precision != -1)
throw new IllegalFormatPrecisionException(precision);
switch (c) {
case Conversion.PERCENT_SIGN:
if (f.valueOf() != Flags.LEFT_JUSTIFY.valueOf()
&& f.valueOf() != Flags.NONE.valueOf())
throw new IllegalFormatFlagsException(f.toString());
// '-' requires a width
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
throw new MissingFormatWidthException(toString());
break;
case Conversion.LINE_SEPARATOR:
if (width != -1)
throw new IllegalFormatWidthException(width);
if (f.valueOf() != Flags.NONE.valueOf())
throw new IllegalFormatFlagsException(f.toString());
break;
default:
throw new UnknownFormatConversionException(String.valueOf(c));
}
}
public void print(String arg, int argIndex)
throws IllegalFormatConversionException,
FormatFlagsConversionMismatchException {
try {
if (arg.charAt(0) == '[')
failConversion(arg);
if (dt) {
printDateTime(arg);
return;
}
switch (c) {
case Conversion.DECIMAL_INTEGER:
case Conversion.OCTAL_INTEGER:
case Conversion.HEXADECIMAL_INTEGER:
printInteger(arg);
break;
case Conversion.SCIENTIFIC:
case Conversion.GENERAL:
case Conversion.DECIMAL_FLOAT:
case Conversion.HEXADECIMAL_FLOAT:
printFloat(arg);
break;
case Conversion.CHARACTER:
case Conversion.CHARACTER_UPPER:
printCharacter(arg);
break;
case Conversion.BOOLEAN:
printBoolean(arg);
break;
case Conversion.STRING:
case Conversion.HASHCODE:
case Conversion.LINE_SEPARATOR:
case Conversion.PERCENT_SIGN:
break;
default:
throw new UnknownFormatConversionException(String.valueOf(c));
}
} catch (IllegalFormatConversionException e) {
e.setArgIndex(argIndex);
throw e;
}
}
private boolean matchSig(String signature, Class>... classes) {
for (Class> c : classes)
if (matchSig(signature, c))
return true;
return false;
}
private boolean matchSig(String signature, Class> c) {
return signature.equals("L" + c.getName().replace('.', '/') + ";");
}
private boolean mightBeUnknown(String arg) {
if (matchSig(arg, Object.class) || matchSig(arg, Number.class)
|| matchSig(arg, Serializable.class)
|| matchSig(arg, Comparable.class))
return true;
return false;
}
private void printInteger(String arg)
throws IllegalFormatConversionException,
FormatFlagsConversionMismatchException {
if (mightBeUnknown(arg))
return;
if (matchSig(arg, Byte.class, Short.class, Integer.class, Long.class))
printLong();
else if (matchSig(arg, BigInteger.class)) {
} else
failConversion(arg);
}
private void printFloat(String arg) throws IllegalFormatConversionException {
if (mightBeUnknown(arg))
return;
if (matchSig(arg, Float.class, Double.class)) {
} else if (matchSig(arg, BigDecimal.class)) {
printBigDecimal(arg);
} else
failConversion(arg);
}
private void printDateTime(String arg)
throws IllegalFormatConversionException {
if (mightBeUnknown(arg))
return;
if (matchSig(arg, Long.class, Date.class, java.sql.Date.class,
java.sql.Time.class, java.sql.Timestamp.class, Calendar.class,
GregorianCalendar.class)) {
} else {
failConversion(arg);
}
}
private void printCharacter(String arg)
throws IllegalFormatConversionException {
if (mightBeUnknown(arg))
return;
if (matchSig(arg, Character.class, Byte.class, Short.class,
Integer.class)) {
} else {
failConversion(arg);
}
}
private void printBoolean(String arg)
throws IllegalFormatConversionException {
if (mightBeUnknown(arg))
return;
if (matchSig(arg, Boolean.class))
return;
failConversion(arg);
}
private void printLong() throws FormatFlagsConversionMismatchException {
if (c == Conversion.OCTAL_INTEGER) {
checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE, Flags.PLUS);
} else if (c == Conversion.HEXADECIMAL_INTEGER) {
checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE, Flags.PLUS);
}
}
private void printBigDecimal(String arg)
throws IllegalFormatConversionException {
if (c == Conversion.HEXADECIMAL_FLOAT)
failConversion(arg);
}
private void failMismatch(Flags f, char c)
throws FormatFlagsConversionMismatchException {
String fs = f.toString();
throw new FormatFlagsConversionMismatchException(fs, c);
}
private void failConversion(String arg)
throws IllegalFormatConversionException {
if (dt)
throw new IllegalFormatConversionException(this.toString(),
f.contains(Flags.UPPERCASE) ? 'T' : 't', arg);
throw new IllegalFormatConversionException(this.toString(), c, arg);
}
} jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/Formatter.java 0000664 0000000 0000000 00000011346 12251210002 0031361 0 ustar 00root root 0000000 0000000 /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
import java.util.ArrayList;
import java.util.FormatFlagsConversionMismatchException;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.UnknownFormatConversionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class Formatter {
public static void check(String format, String... args)
throws ExtraFormatArgumentsException,
IllegalFormatConversionException, IllegalFormatException,
FormatFlagsConversionMismatchException,
MissingFormatArgumentException, FormatterNumberFormatException {
// index of last argument referenced
int last = -1;
// last ordinary index
int lasto = -1;
// last index used
int maxIndex = -1;
for (FormatSpecifier fs : parse(format)) {
int index = fs.index();
switch (index) {
case -2:
// ignore it
break;
case -1: // relative index
if (last < 0 || last > args.length - 1)
throw new MissingFormatArgumentException(last,
fs.toString());
fs.print(args[last], last);
break;
case 0: // ordinary index
lasto++;
last = lasto;
if (lasto > args.length - 1)
throw new MissingFormatArgumentException(lasto,
fs.toString());
maxIndex = Math.max(maxIndex, lasto);
fs.print(args[lasto], lasto);
break;
default: // explicit index
last = index - 1;
if (last > args.length - 1)
throw new MissingFormatArgumentException(last,
fs.toString());
maxIndex = Math.max(maxIndex, last);
fs.print(args[last], last);
break;
}
}
if (maxIndex < args.length - 1) {
throw new ExtraFormatArgumentsException(args.length, maxIndex + 1);
}
}
// %[argument_index$][flags][width][.precision][t]conversion
private static final String formatSpecifier = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
private static Pattern fsPattern = Pattern.compile(formatSpecifier);
// Look for format specifiers in the format string.
private static List parse(String s)
throws FormatFlagsConversionMismatchException,
FormatterNumberFormatException {
ArrayList al = new ArrayList();
Matcher m = fsPattern.matcher(s);
int i = 0;
while (i < s.length()) {
if (m.find(i)) {
// Anything between the start of the string and the beginning
// of the format specifier is either fixed text or contains
// an invalid format string.
if (m.start() != i) {
// Make sure we didn't miss any invalid format specifiers
checkText(s.substring(i, m.start()));
}
// Expect 6 groups in regular expression
String[] sa = new String[6];
for (int j = 0; j < m.groupCount(); j++) {
sa[j] = m.group(j + 1);
}
al.add(new FormatSpecifier(m.group(0), sa));
i = m.end();
} else {
// No more valid format specifiers. Check for possible invalid
// format specifiers.
checkText(s.substring(i));
// The rest of the string is fixed text
break;
}
}
return al;
}
private static void checkText(String s) {
int idx;
// If there are any '%' in the given string, we got a bad format
// specifier.
if ((idx = s.indexOf('%')) != -1) {
char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
throw new UnknownFormatConversionException(String.valueOf(c));
}
}
}
jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/FormatterException.java0000664 0000000 0000000 00000003102 12251210002 0033227 0 ustar 00root root 0000000 0000000 /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
public abstract class FormatterException extends Exception {
private static final long serialVersionUID = 1L;
}
FormatterNumberFormatException.java 0000664 0000000 0000000 00000002434 12251210002 0035501 0 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker /*
* Copyright 2013 by Bill Pugh.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. This
* particular file as subject to the "Classpath" exception.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
public class FormatterNumberFormatException extends FormatterException {
private static final long serialVersionUID = 1L;
final String txt, kind;
/**
* @return the txt
*/
public String getTxt() {
return txt;
}
/**
* @return the msg
*/
public String getKind() {
return kind;
}
public FormatterNumberFormatException(String txt, String kind) {
this.txt = txt;
this.kind = kind;
}
}
IllegalFormatConversionException.java 0000664 0000000 0000000 00000005613 12251210002 0036006 0 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
public class IllegalFormatConversionException extends FormatterException {
private static final long serialVersionUID = 1L;
final private String formatSpecifier;
final private char conversion;
final private String signature;
int argIndex = -1;
/**
* Constructs an instance of this class with the mismatched conversion and
* the corresponding argument class.
*
* @param formatSpecifier
* Inapplicable format specifier
*
* @param signature
* Signature of the mismatched argument
*/
public IllegalFormatConversionException(String formatSpecifier,
char conversion, String signature) {
if (signature == null)
throw new NullPointerException();
this.conversion = conversion;
this.formatSpecifier = formatSpecifier;
this.signature = signature;
}
public void setArgIndex(int argIndex) {
if (argIndex == -1)
throw new IllegalStateException("arg index already set");
this.argIndex = argIndex;
}
public int getArgIndex() {
return argIndex;
}
public String getFormatSpecifier() {
return formatSpecifier;
}
public char getConversion() {
return conversion;
}
/**
* Returns the class of the mismatched argument.
*
* @return The class of the mismatched argument
*/
public String getArgumentSignature() {
return signature;
}
// javadoc inherited from Throwable.java
public String getMessage() {
return String.format("%s can't format %s", formatSpecifier, signature);
}
}
MissingFormatArgumentException.java 0000664 0000000 0000000 00000003422 12251210002 0035477 0 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* This file has been extensively modified from the original Sun implementation
* to provide for compile time checking of Format Strings.
*
* These modifications were performed by Bill Pugh, this code is free software.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
public class MissingFormatArgumentException extends FormatterException {
private static final long serialVersionUID = 1L;
public final int pos;
public final String formatSpecifier;
public MissingFormatArgumentException(int pos, String formatSpecifier) {
this.pos = pos;
this.formatSpecifier = formatSpecifier;
}
} jformatstring-0.10~20131207/src/junit/ 0000775 0000000 0000000 00000000000 12251210002 0017242 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/junit/edu/ 0000775 0000000 0000000 00000000000 12251210002 0020017 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/junit/edu/umd/ 0000775 0000000 0000000 00000000000 12251210002 0020604 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/junit/edu/umd/cs/ 0000775 0000000 0000000 00000000000 12251210002 0021211 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/junit/edu/umd/cs/findbugs/ 0000775 0000000 0000000 00000000000 12251210002 0023012 5 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/junit/edu/umd/cs/findbugs/formatStringChecker/ 0000775 0000000 0000000 00000000000 12251210002 0026756 5 ustar 00root root 0000000 0000000 FormatterCompileTimeTest.java 0000664 0000000 0000000 00000007111 12251210002 0034475 0 ustar 00root root 0000000 0000000 jformatstring-0.10~20131207/src/junit/edu/umd/cs/findbugs/formatStringChecker /*
* Copyright 2013 by Bill Pugh.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. This
* particular file as subject to the "Classpath" exception.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package edu.umd.cs.findbugs.formatStringChecker;
import org.junit.Test;
public class FormatterCompileTimeTest {
@Test
public void shouldWork()
throws FormatterException {
Formatter.check("%d%n%d", "Ljava/lang/Integer;", "Ljava/lang/Short;");
Formatter.check("%d\n", "Ljava/math/BigInteger;");
Formatter.check("%f\n", "Ljava/math/BigDecimal;");
}
@Test(expected = IllegalFormatConversionException.class)
public void stringWhereIntegerExpected()
throws FormatterException {
Formatter.check("%d", "Ljava/lang/String;");
}
@Test(expected = MissingFormatArgumentException.class)
public void notEnoughParameters()
throws FormatterException {
Formatter.check("%s%s", "Ljava/lang/String;");
}
@Test(expected = IllegalFormatConversionException.class)
public void passingAnArray()
throws FormatterException {
Formatter.check("%s", "[I");
}
@Test(expected = IllegalFormatConversionException.class)
public void passingAnIntToABoolean()
throws FormatterException {
Formatter.check("%b", "Ljava/lang/Integer;");
}
@Test(expected = ExtraFormatArgumentsException.class)
public void tooManyParameters()
throws FormatterException {
Formatter.check("%s%s", "Ljava/lang/String;", "Ljava/lang/String;",
"Ljava/lang/String;");
}
@Test
public void testBug1874856FalsePositive()
throws FormatterException {
Formatter.check("s1 Duke's Birthday: %1$tm %1$te, %1$tY",
"Ljava/util/GregorianCalendar;");
Formatter.check("s2 Duke's Birthday: %1$tm %