diff options
Diffstat (limited to 'src/proguard/ConfigurationParser.java')
-rw-r--r-- | src/proguard/ConfigurationParser.java | 172 |
1 files changed, 72 insertions, 100 deletions
diff --git a/src/proguard/ConfigurationParser.java b/src/proguard/ConfigurationParser.java index 0a6e296..e01809e 100644 --- a/src/proguard/ConfigurationParser.java +++ b/src/proguard/ConfigurationParser.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * 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 @@ -58,21 +58,9 @@ public class ConfigurationParser public ConfigurationParser(String[] args, File baseDir) throws IOException { - this(new ArgumentWordReader(args, baseDir)); - } - + reader = new ArgumentWordReader(args, baseDir); - /** - * Creates a new ConfigurationParser for the given lines, - * with the given base directory. - */ - public ConfigurationParser(String lines, - String description, - File baseDir) throws IOException - { - this(new LineWordReader(new LineNumberReader(new StringReader(lines)), - description, - baseDir)); + readNextWord(); } @@ -81,7 +69,9 @@ public class ConfigurationParser */ public ConfigurationParser(File file) throws IOException { - this(new FileWordReader(file)); + reader = new FileWordReader(file); + + readNextWord(); } @@ -90,16 +80,7 @@ public class ConfigurationParser */ public ConfigurationParser(URL url) throws IOException { - this(new FileWordReader(url)); - } - - - /** - * Creates a new ConfigurationParser for the given word reader. - */ - public ConfigurationParser(WordReader reader) throws IOException - { - this.reader = reader; + reader = new FileWordReader(url); readNextWord(); } @@ -129,7 +110,6 @@ public class ConfigurationParser else if (ConfigurationConstants.OUTJARS_OPTION .startsWith(nextWord)) configuration.programJars = parseClassPathArgument(configuration.programJars, true); else if (ConfigurationConstants.LIBRARYJARS_OPTION .startsWith(nextWord)) configuration.libraryJars = parseClassPathArgument(configuration.libraryJars, false); else if (ConfigurationConstants.RESOURCEJARS_OPTION .startsWith(nextWord)) throw new ParseException("The '-resourcejars' option is no longer supported. Please use the '-injars' option for all input"); - else if (ConfigurationConstants.SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION .startsWith(nextWord)) configuration.skipNonPublicLibraryClasses = parseNoArgument(true); else if (ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION .startsWith(nextWord)) configuration.skipNonPublicLibraryClasses = parseNoArgument(false); else if (ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION.startsWith(nextWord)) configuration.skipNonPublicLibraryClassMembers = parseNoArgument(false); else if (ConfigurationConstants.TARGET_OPTION .startsWith(nextWord)) configuration.targetClassVersion = parseClassVersion(); @@ -144,7 +124,7 @@ public class ConfigurationParser else if (ConfigurationConstants.PRINT_SEEDS_OPTION .startsWith(nextWord)) configuration.printSeeds = parseOptionalFile(); // After '-keep'. - else if (ConfigurationConstants.KEEP_DIRECTORIES_OPTION .startsWith(nextWord)) configuration.keepDirectories = parseCommaSeparatedList("directory name", true, true, false, true, false, true, false, false, configuration.keepDirectories); + else if (ConfigurationConstants.KEEP_DIRECTORIES_OPTION .startsWith(nextWord)) configuration.keepDirectories = parseCommaSeparatedList("directory name", true, true, false, false, true, false, false, configuration.keepDirectories); else if (ConfigurationConstants.DONT_SHRINK_OPTION .startsWith(nextWord)) configuration.shrink = parseNoArgument(false); else if (ConfigurationConstants.PRINT_USAGE_OPTION .startsWith(nextWord)) configuration.printUsage = parseOptionalFile(); @@ -152,7 +132,7 @@ public class ConfigurationParser else if (ConfigurationConstants.DONT_OPTIMIZE_OPTION .startsWith(nextWord)) configuration.optimize = parseNoArgument(false); else if (ConfigurationConstants.OPTIMIZATION_PASSES .startsWith(nextWord)) configuration.optimizationPasses = parseIntegerArgument(); - else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, false, false, false, configuration.optimizations); + else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, false, false, configuration.optimizations); else if (ConfigurationConstants.ASSUME_NO_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoSideEffects = parseClassSpecificationArguments(configuration.assumeNoSideEffects); else if (ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION .startsWith(nextWord)) configuration.allowAccessModification = parseNoArgument(true); else if (ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.mergeInterfacesAggressively = parseNoArgument(true); @@ -166,23 +146,22 @@ public class ConfigurationParser else if (ConfigurationConstants.OVERLOAD_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.overloadAggressively = parseNoArgument(true); else if (ConfigurationConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION .startsWith(nextWord)) configuration.useUniqueClassMemberNames = parseNoArgument(true); else if (ConfigurationConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION .startsWith(nextWord)) configuration.useMixedCaseClassNames = parseNoArgument(false); - else if (ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION .startsWith(nextWord)) configuration.keepPackageNames = parseCommaSeparatedList("package name", true, true, false, false, true, false, true, false, configuration.keepPackageNames); + else if (ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION .startsWith(nextWord)) configuration.keepPackageNames = parseCommaSeparatedList("package name", true, true, false, true, false, true, false, configuration.keepPackageNames); else if (ConfigurationConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION .startsWith(nextWord)) configuration.flattenPackageHierarchy = ClassUtil.internalClassName(parseOptionalArgument()); else if (ConfigurationConstants.REPACKAGE_CLASSES_OPTION .startsWith(nextWord)) configuration.repackageClasses = ClassUtil.internalClassName(parseOptionalArgument()); else if (ConfigurationConstants.DEFAULT_PACKAGE_OPTION .startsWith(nextWord)) configuration.repackageClasses = ClassUtil.internalClassName(parseOptionalArgument()); - else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION .startsWith(nextWord)) configuration.keepAttributes = parseCommaSeparatedList("attribute name", true, true, false, false, true, false, false, false, configuration.keepAttributes); - else if (ConfigurationConstants.KEEP_PARAMETER_NAMES_OPTION .startsWith(nextWord)) configuration.keepParameterNames = parseNoArgument(true); + else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION .startsWith(nextWord)) configuration.keepAttributes = parseCommaSeparatedList("attribute name", true, true, false, true, false, false, false, configuration.keepAttributes); else if (ConfigurationConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION .startsWith(nextWord)) configuration.newSourceFileAttribute = parseOptionalArgument(); - else if (ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION .startsWith(nextWord)) configuration.adaptClassStrings = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.adaptClassStrings); - else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION .startsWith(nextWord)) configuration.adaptResourceFileNames = parseCommaSeparatedList("resource file name", true, true, false, true, false, false, false, false, configuration.adaptResourceFileNames); - else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION .startsWith(nextWord)) configuration.adaptResourceFileContents = parseCommaSeparatedList("resource file name", true, true, false, true, false, false, false, false, configuration.adaptResourceFileContents); + else if (ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION .startsWith(nextWord)) configuration.adaptClassStrings = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.adaptClassStrings); + else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION .startsWith(nextWord)) configuration.adaptResourceFileNames = parseCommaSeparatedList("resource file name", true, true, false, false, false, false, false, configuration.adaptResourceFileNames); + else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION .startsWith(nextWord)) configuration.adaptResourceFileContents = parseCommaSeparatedList("resource file name", true, true, false, false, false, false, false, configuration.adaptResourceFileContents); else if (ConfigurationConstants.DONT_PREVERIFY_OPTION .startsWith(nextWord)) configuration.preverify = parseNoArgument(false); else if (ConfigurationConstants.MICRO_EDITION_OPTION .startsWith(nextWord)) configuration.microEdition = parseNoArgument(true); else if (ConfigurationConstants.VERBOSE_OPTION .startsWith(nextWord)) configuration.verbose = parseNoArgument(true); - else if (ConfigurationConstants.DONT_NOTE_OPTION .startsWith(nextWord)) configuration.note = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.note); - else if (ConfigurationConstants.DONT_WARN_OPTION .startsWith(nextWord)) configuration.warn = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.warn); + else if (ConfigurationConstants.DONT_NOTE_OPTION .startsWith(nextWord)) configuration.note = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.note); + else if (ConfigurationConstants.DONT_WARN_OPTION .startsWith(nextWord)) configuration.warn = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.warn); else if (ConfigurationConstants.IGNORE_WARNINGS_OPTION .startsWith(nextWord)) configuration.ignoreWarnings = parseNoArgument(true); else if (ConfigurationConstants.PRINT_CONFIGURATION_OPTION .startsWith(nextWord)) configuration.printConfiguration = parseOptionalFile(); else if (ConfigurationConstants.DUMP_OPTION .startsWith(nextWord)) configuration.dump = parseOptionalFile(); @@ -211,7 +190,7 @@ public class ConfigurationParser private long parseIncludeArgument(long lastModified) throws ParseException, IOException { // Read the configuation file name. - readNextWord("configuration file name", true, false); + readNextWord("configuration file name"); File file = file(nextWord); reader.includeWordReader(new FileWordReader(file)); @@ -225,7 +204,7 @@ public class ConfigurationParser private void parseBaseDirectoryArgument() throws ParseException, IOException { // Read the base directory name. - readNextWord("base directory name", true, false); + readNextWord("base directory name"); reader.setBaseDir(file(nextWord)); @@ -246,7 +225,7 @@ public class ConfigurationParser while (true) { // Read the next jar name. - readNextWord("jar or directory name", true, false); + readNextWord("jar or directory name"); // Create a new class path entry. ClassPathEntry entry = new ClassPathEntry(file(nextWord), isOutput); @@ -266,7 +245,7 @@ public class ConfigurationParser { // Read the filter. filters[counter++] = - parseCommaSeparatedList("filter", true, false, true, true, false, true, false, false, null); + parseCommaSeparatedList("filter", true, false, true, false, true, false, false, null); } while (counter < filters.length && ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord)); @@ -364,7 +343,7 @@ public class ConfigurationParser throws ParseException, IOException { // Read the obligatory file name. - readNextWord("file name", true, false); + readNextWord("file name"); // Make sure the file is properly resolved. File file = file(nextWord); @@ -379,7 +358,7 @@ public class ConfigurationParser throws ParseException, IOException { // Read the optional file name. - readNextWord(true); + readNextWord(); // Didn't the user specify a file name? if (configurationEnd()) @@ -407,11 +386,11 @@ public class ConfigurationParser return ""; } - String argument = nextWord; + String fileName = nextWord; readNextWord(); - return argument; + return fileName; } @@ -452,8 +431,7 @@ public class ConfigurationParser { readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD + "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE + - "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", - false, true); + "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true); if (!ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD.equals(nextWord)) { @@ -513,8 +491,7 @@ public class ConfigurationParser // Read and add the class configuration. readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD + "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE + - "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", - false, true); + "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true); classSpecifications.add(parseClassSpecificationArguments()); @@ -535,21 +512,30 @@ public class ConfigurationParser // Parse the class annotations and access modifiers until the class keyword. while (!ConfigurationConstants.CLASS_KEYWORD.equals(nextWord)) { - // Strip the negating sign, if any. - boolean negated = - nextWord.startsWith(ConfigurationConstants.NEGATOR_KEYWORD); + // Parse the annotation type, if any. +// if (ConfigurationConstants.ANNOTATION_KEYWORD.equals(nextWord)) +// { +// annotationType = +// ClassUtil.internalType( +// ListUtil.commaSeparatedString( +// parseCommaSeparatedList("annotation type", +// true, false, false, true, false, null))); +// +// continue; +// } - String strippedWord = negated ? + // Strip the negating sign, if any. + String strippedWord = nextWord.startsWith(ConfigurationConstants.NEGATOR_KEYWORD) ? nextWord.substring(1) : nextWord; // Parse the class access modifiers. + // TODO: Distinguish annotation from annotation modifier. int accessFlag = strippedWord.equals(ClassConstants.EXTERNAL_ACC_PUBLIC) ? ClassConstants.INTERNAL_ACC_PUBLIC : strippedWord.equals(ClassConstants.EXTERNAL_ACC_FINAL) ? ClassConstants.INTERNAL_ACC_FINAL : strippedWord.equals(ClassConstants.EXTERNAL_ACC_INTERFACE) ? ClassConstants.INTERNAL_ACC_INTERFACE : strippedWord.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT : - strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC : strippedWord.equals(ClassConstants.EXTERNAL_ACC_ANNOTATION) ? ClassConstants.INTERNAL_ACC_ANNOTATTION : strippedWord.equals(ClassConstants.EXTERNAL_ACC_ENUM) ? ClassConstants.INTERNAL_ACC_ENUM : unknownAccessFlag(); @@ -557,11 +543,9 @@ public class ConfigurationParser // Is it an annotation modifier? if (accessFlag == ClassConstants.INTERNAL_ACC_ANNOTATTION) { - // Already read the next word. - readNextWord("annotation type or keyword '" + ClassConstants.EXTERNAL_ACC_INTERFACE + "'", - false, false); - // Is the next word actually an annotation type? + readNextWord("annotation type or keyword '" + ClassConstants.EXTERNAL_ACC_INTERFACE + "'", false); + if (!nextWord.equals(ClassConstants.EXTERNAL_ACC_INTERFACE) && !nextWord.equals(ClassConstants.EXTERNAL_ACC_ENUM) && !nextWord.equals(ConfigurationConstants.CLASS_KEYWORD)) @@ -570,17 +554,13 @@ public class ConfigurationParser annotationType = ListUtil.commaSeparatedString( parseCommaSeparatedList("annotation type", - false, false, false, false, true, false, false, true, null), false); + false, false, false, true, false, false, true, null)); - // Continue parsing the access modifier that we just read - // in the next cycle. continue; } - - // Otherwise just handle the annotation modifier. } - if (!negated) + if (strippedWord.equals(nextWord)) { requiredSetClassAccessFlags |= accessFlag; } @@ -589,6 +569,7 @@ public class ConfigurationParser requiredUnsetClassAccessFlags |= accessFlag; } + if ((requiredSetClassAccessFlags & requiredUnsetClassAccessFlags) != 0) { @@ -604,21 +585,16 @@ public class ConfigurationParser break; } - // Should we read the next word? - if (accessFlag != ClassConstants.INTERNAL_ACC_ANNOTATTION) - { - readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD + - "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE + - "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", - false, true); - } + readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD + + "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE + + "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true); } // Parse the class name part. String externalClassName = ListUtil.commaSeparatedString( parseCommaSeparatedList("class name or interface name", - true, false, false, false, true, false, false, false, null), false); + true, false, false, true, false, false, false, null)); // For backward compatibility, allow a single "*" wildcard to match any // class. @@ -636,7 +612,7 @@ public class ConfigurationParser if (ConfigurationConstants.IMPLEMENTS_KEYWORD.equals(nextWord) || ConfigurationConstants.EXTENDS_KEYWORD.equals(nextWord)) { - readNextWord("class name or interface name", false, true); + readNextWord("class name or interface name", true); // Parse the annotation type, if any. if (ConfigurationConstants.ANNOTATION_KEYWORD.equals(nextWord)) @@ -644,13 +620,13 @@ public class ConfigurationParser extendsAnnotationType = ListUtil.commaSeparatedString( parseCommaSeparatedList("annotation type", - true, false, false, false, true, false, false, true, null), false); + true, false, false, true, false, false, true, null)); } String externalExtendsClassName = ListUtil.commaSeparatedString( parseCommaSeparatedList("class name or interface name", - false, false, false, false, true, false, false, false, null), false); + false, false, false, true, false, false, false, null)); extendsClassName = ConfigurationConstants.ANY_CLASS_KEYWORD.equals(externalExtendsClassName) ? null : @@ -683,8 +659,7 @@ public class ConfigurationParser while (true) { readNextWord("class member description" + - " or closing '" + ConfigurationConstants.CLOSE_KEYWORD + "'", - false, true); + " or closing '" + ConfigurationConstants.CLOSE_KEYWORD + "'", true); if (nextWord.equals(ConfigurationConstants.CLOSE_KEYWORD)) { @@ -722,7 +697,8 @@ public class ConfigurationParser annotationType = ListUtil.commaSeparatedString( parseCommaSeparatedList("annotation type", - true, false, false, false, true, false, false, true, null), false); + true, false, false, true, false, false, true, null)); + continue; } @@ -740,12 +716,9 @@ public class ConfigurationParser strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED) ? ClassConstants.INTERNAL_ACC_SYNCHRONIZED : strippedWord.equals(ClassConstants.EXTERNAL_ACC_VOLATILE) ? ClassConstants.INTERNAL_ACC_VOLATILE : strippedWord.equals(ClassConstants.EXTERNAL_ACC_TRANSIENT) ? ClassConstants.INTERNAL_ACC_TRANSIENT : - strippedWord.equals(ClassConstants.EXTERNAL_ACC_BRIDGE) ? ClassConstants.INTERNAL_ACC_BRIDGE : - strippedWord.equals(ClassConstants.EXTERNAL_ACC_VARARGS) ? ClassConstants.INTERNAL_ACC_VARARGS : strippedWord.equals(ClassConstants.EXTERNAL_ACC_NATIVE) ? ClassConstants.INTERNAL_ACC_NATIVE : strippedWord.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT : strippedWord.equals(ClassConstants.EXTERNAL_ACC_STRICT) ? ClassConstants.INTERNAL_ACC_STRICT : - strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC : 0; if (accessFlag == 0) { @@ -902,7 +875,7 @@ public class ConfigurationParser // Parse the method arguments. String descriptor = ClassUtil.internalMethodDescriptor(type, - parseCommaSeparatedList("argument", true, true, true, false, true, false, false, false, null)); + parseCommaSeparatedList("argument", true, true, true, true, false, false, false, null)); if (!ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD.equals(nextWord)) { @@ -948,7 +921,6 @@ public class ConfigurationParser boolean readFirstWord, boolean allowEmptyList, boolean expectClosingParenthesis, - boolean isFileName, boolean checkJavaIdentifiers, boolean replaceSystemProperties, boolean replaceExternalClassNames, @@ -966,12 +938,12 @@ public class ConfigurationParser if (expectClosingParenthesis || !allowEmptyList) { // Read the first list entry. - readNextWord(expectedDescription, isFileName, false); + readNextWord(expectedDescription); } else { // Read the first list entry, if there is any. - readNextWord(isFileName); + readNextWord(); // Check if the list is empty. if (configurationEnd() || @@ -1033,7 +1005,7 @@ public class ConfigurationParser } // Read the next list entry. - readNextWord(expectedDescription, isFileName, false); + readNextWord(expectedDescription); } return list; @@ -1063,6 +1035,16 @@ public class ConfigurationParser file = new File(reader.getBaseDir(), fileName); } + // Try to get a canonical representation. + try + { + file = file.getCanonicalFile(); + } + catch (IOException ex) + { + // Just keep the original representation. + } + return file; } @@ -1114,7 +1096,7 @@ public class ConfigurationParser private void readNextWord(String expectedDescription) throws ParseException, IOException { - readNextWord(expectedDescription, false, false); + readNextWord(expectedDescription, false); } @@ -1123,11 +1105,10 @@ public class ConfigurationParser * throwing an exception if there is no next word. */ private void readNextWord(String expectedDescription, - boolean isFileName, boolean expectingAtCharacter) throws ParseException, IOException { - readNextWord(isFileName); + readNextWord(); if (configurationEnd(expectingAtCharacter)) { throw new ParseException("Expecting " + expectedDescription + @@ -1141,16 +1122,7 @@ public class ConfigurationParser */ private void readNextWord() throws IOException { - readNextWord(false); - } - - - /** - * Reads the next word of the configuration in the 'nextWord' field. - */ - private void readNextWord(boolean isFileName) throws IOException - { - nextWord = reader.nextWord(isFileName); + nextWord = reader.nextWord(); } |