diff options
15 files changed, 1637 insertions, 9 deletions
@@ -130,6 +130,7 @@ genrule( srcs = [ ":create_embedded_tools.sh", "//tools:embedded_tools_srcs", + "//third_party:gpl-srcs", "//third_party/iossim:srcs", "//third_party/java/jarjar:srcs", "//third_party/java/jdk/langtools:srcs", diff --git a/third_party/BUILD b/third_party/BUILD index dd43335c96..d4afc7f070 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -16,6 +16,7 @@ filegroup( "//third_party/java/jdk/langtools:srcs", "//third_party/java/jdk/javabuilder:srcs", "//third_party/javascript/bootstrap:srcs", + "//third_party/jformatstring:srcs", "//third_party/protobuf:srcs", "//third_party/py/concurrent:srcs", "//third_party/py/gflags:srcs", @@ -25,6 +26,16 @@ filegroup( ], ) +# Filegroup to ship the sources to the Bazel embededded tools +# This filegroup should contains all GPL with classpath exception +# and LGPL code that we use in Bazel. +filegroup( + name = "gpl-srcs", + srcs = [ + "//third_party/jformatstring:srcs", + ], +) + filegroup( name = "d3-js", srcs = glob(["javascript/d3/**/*.js"]), @@ -274,9 +285,9 @@ java_import( ":checker_framework_dataflow", ":guava", ":jcip_annotations", - ":jformatstring", ":jsr305", ":pcollections", + "//third_party/jformatstring", ], ) @@ -295,13 +306,6 @@ java_import( ) java_import( - name = "jformatstring", - jars = [ - "jformatstring/jFormatString-3.0.0.jar", - ], -) - -java_import( name = "checker_framework_dataflow", jars = [ "checker_framework_dataflow/dataflow-1.8.10.jar", @@ -318,9 +322,9 @@ filegroup( "error_prone/error_prone_core-2.0.9-20160129.jar", "guava/guava-19.0.jar", "jcip_annotations/jcip-annotations-1.0-1.jar", - "jformatstring/jFormatString-3.0.0.jar", "jsr305/jsr-305.jar", "pcollections/pcollections-2.1.2.jar", + "//third_party/jformatstring:bootstrap", ], ) diff --git a/third_party/jformatstring/BUILD b/third_party/jformatstring/BUILD new file mode 100644 index 0000000000..f3f1d35b94 --- /dev/null +++ b/third_party/jformatstring/BUILD @@ -0,0 +1,20 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["restricted"]) # GNU GPL v2 with Classpath exception + +filegroup( + name = "srcs", + srcs = glob(["**"]), +) + +java_library( + name = "jformatstring", + srcs = glob(["java/**"]), +) + +load("//tools/build_rules:java_rules_skylark.bzl", "bootstrap_java_library") + +bootstrap_java_library( + name = "bootstrap", + srcs = glob(["java/**"]), +) diff --git a/third_party/jformatstring/LICENSE b/third_party/jformatstring/LICENSE new file mode 100644 index 0000000000..b40a0f457d --- /dev/null +++ b/third_party/jformatstring/LICENSE @@ -0,0 +1,347 @@ +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) <year> <name of author> + + This program 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 2 of the License, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. diff --git a/third_party/jformatstring/jFormatString-3.0.0.jar b/third_party/jformatstring/jFormatString-3.0.0.jar Binary files differdeleted file mode 100644 index bdcb8466ba..0000000000 --- a/third_party/jformatstring/jFormatString-3.0.0.jar +++ /dev/null diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Conversion.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Conversion.java new file mode 100644 index 0000000000..ae87af6c4f --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Conversion.java @@ -0,0 +1,145 @@ +/* + * 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; + } + } +}
\ No newline at end of file diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/DateTime.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/DateTime.java new file mode 100644 index 0000000000..c71592e5fb --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/DateTime.java @@ -0,0 +1,132 @@ +/* + * 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; + } + } +}
\ No newline at end of file diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/ExtraFormatArgumentsException.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/ExtraFormatArgumentsException.java new file mode 100644 index 0000000000..c3acfbb043 --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/ExtraFormatArgumentsException.java @@ -0,0 +1,43 @@ +/* + * 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; + } +}
\ No newline at end of file diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Flags.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Flags.java new file mode 100644 index 0000000000..9ddfc21a77 --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Flags.java @@ -0,0 +1,145 @@ +/* + * 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 <tt>Flags</tt>. + 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(); + } +}
\ No newline at end of file diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatSpecifier.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatSpecifier.java new file mode 100644 index 0000000000..24ac3d067d --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatSpecifier.java @@ -0,0 +1,425 @@ +/* + * 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); + } + +}
\ No newline at end of file diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Formatter.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Formatter.java new file mode 100644 index 0000000000..e906d5e980 --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/Formatter.java @@ -0,0 +1,147 @@ +/* + * 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<FormatSpecifier> parse(String s) + throws FormatFlagsConversionMismatchException, + FormatterNumberFormatException { + ArrayList<FormatSpecifier> al = new ArrayList<FormatSpecifier>(); + 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)); + } + } +} diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatterException.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatterException.java new file mode 100644 index 0000000000..3619e69fa5 --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatterException.java @@ -0,0 +1,37 @@ +/* + * 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; + +} diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatterNumberFormatException.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatterNumberFormatException.java new file mode 100644 index 0000000000..19af64f6c4 --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/FormatterNumberFormatException.java @@ -0,0 +1,46 @@ +/* + * 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; + + } +} diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/IllegalFormatConversionException.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/IllegalFormatConversionException.java new file mode 100644 index 0000000000..2878f92395 --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/IllegalFormatConversionException.java @@ -0,0 +1,94 @@ +/* + * 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); + } + +} diff --git a/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/MissingFormatArgumentException.java b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/MissingFormatArgumentException.java new file mode 100644 index 0000000000..ceef78a5ac --- /dev/null +++ b/third_party/jformatstring/java/edu/umd/cs/findbugs/formatStringChecker/MissingFormatArgumentException.java @@ -0,0 +1,42 @@ +/* + * 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; + } +}
\ No newline at end of file |