diff options
author | Joe Onorato <joeo@android.com> | 2009-08-31 10:12:00 -0700 |
---|---|---|
committer | Joe Onorato <joeo@android.com> | 2009-08-31 10:12:00 -0700 |
commit | b72c5c2e5482cf10117b2b25f642f7616b2326c3 (patch) | |
tree | f02ba1bc29f4fe6853d9b7008eed37cdcfb96e81 /src/proguard/util | |
parent | a23344a828357fe4b6596f8af5fed467d72757ab (diff) | |
download | proguard-b72c5c2e5482cf10117b2b25f642f7616b2326c3.tar.gz |
ProGuard 4.4android-sdk-tools_r4android-sdk-tools_r3android-sdk-2.1_r1android-sdk-2.0_r1android-sdk-2.0.1_r1android-sdk-2.0.1-docs_r1android-2.1_r2.1sandroid-2.1_r2.1p2android-2.1_r2.1pandroid-2.1_r2android-2.1_r1android-2.0_r1android-2.0.1_r1eclair-sholes-release2eclair-sholes-releaseeclair-releaseeclair-passion-release
Diffstat (limited to 'src/proguard/util')
-rw-r--r-- | src/proguard/util/AndMatcher.java | 49 | ||||
-rw-r--r-- | src/proguard/util/ClassNameParser.java | 216 | ||||
-rw-r--r-- | src/proguard/util/ConstantMatcher.java | 48 | ||||
-rw-r--r-- | src/proguard/util/EmptyStringMatcher.java | 36 | ||||
-rw-r--r-- | src/proguard/util/ExtensionMatcher.java | 63 | ||||
-rw-r--r-- | src/proguard/util/FileNameParser.java | 121 | ||||
-rw-r--r-- | src/proguard/util/FixedStringMatcher.java | 56 | ||||
-rw-r--r-- | src/proguard/util/ListMatcher.java | 69 | ||||
-rw-r--r-- | src/proguard/util/ListParser.java | 137 | ||||
-rw-r--r-- | src/proguard/util/ListUtil.java | 173 | ||||
-rw-r--r-- | src/proguard/util/NameParser.java | 106 | ||||
-rw-r--r-- | src/proguard/util/NotMatcher.java | 46 | ||||
-rw-r--r-- | src/proguard/util/OrMatcher.java | 49 | ||||
-rw-r--r-- | src/proguard/util/SettableMatcher.java | 46 | ||||
-rw-r--r-- | src/proguard/util/StringMatcher.java | 38 | ||||
-rw-r--r-- | src/proguard/util/StringParser.java | 35 | ||||
-rw-r--r-- | src/proguard/util/VariableStringMatcher.java | 126 | ||||
-rw-r--r-- | src/proguard/util/package.html | 3 |
18 files changed, 1417 insertions, 0 deletions
diff --git a/src/proguard/util/AndMatcher.java b/src/proguard/util/AndMatcher.java new file mode 100644 index 0000000..94a37e5 --- /dev/null +++ b/src/proguard/util/AndMatcher.java @@ -0,0 +1,49 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings matches both given StringMatcher + * instances. + * + * @author Eric Lafortune + */ +public class AndMatcher implements StringMatcher +{ + private final StringMatcher matcher1; + private final StringMatcher matcher2; + + + public AndMatcher(StringMatcher matcher1, StringMatcher matcher2) + { + this.matcher1 = matcher1; + this.matcher2 = matcher2; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return matcher1.matches(string) && + matcher2.matches(string); + } +} diff --git a/src/proguard/util/ClassNameParser.java b/src/proguard/util/ClassNameParser.java new file mode 100644 index 0000000..ee972f0 --- /dev/null +++ b/src/proguard/util/ClassNameParser.java @@ -0,0 +1,216 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +import proguard.classfile.ClassConstants; + +/** + * This StringParser can create StringMatcher instances for regular expressions + * matching internal class names (or descriptors containing class names). + * The regular expressions can contain the following wildcards: + * '%' for a single internal primitive type character (V, Z, B, C, S, I, F, + * J, or D), + * '?' for a single regular class name character, + * '*' for any number of regular class name characters, + * '**' for any number of regular class name characters or package separator + * characters ('/'), + * 'L***;' for a single internal type (class name or primitive type, + * array or non-array), and + * 'L///;' for any number of internal types (class names and primitive + * types). + * + * @author Eric Lafortune + */ +public class ClassNameParser implements StringParser +{ + private static final char[] INTERNAL_PRIMITIVE_TYPES = new char[] + { + ClassConstants.INTERNAL_TYPE_VOID, + ClassConstants.INTERNAL_TYPE_BOOLEAN, + ClassConstants.INTERNAL_TYPE_BYTE, + ClassConstants.INTERNAL_TYPE_CHAR, + ClassConstants.INTERNAL_TYPE_SHORT, + ClassConstants.INTERNAL_TYPE_INT, + ClassConstants.INTERNAL_TYPE_LONG, + ClassConstants.INTERNAL_TYPE_FLOAT, + ClassConstants.INTERNAL_TYPE_DOUBLE, + }; + + + // Implementations for StringParser. + + public StringMatcher parse(String regularExpression) + { + int index; + StringMatcher nextMatcher = new EmptyStringMatcher(); + + // Look for wildcards. + for (index = 0; index < regularExpression.length(); index++) + { + // Is there an 'L///;' wildcard? + if (regularExpression.regionMatches(index, "L///;", 0, 5)) + { + SettableMatcher settableMatcher = new SettableMatcher(); + + // Create a matcher, recursively, for the remainder of the + // string, optionally preceded by any type. + nextMatcher = + new OrMatcher(parse(regularExpression.substring(index + 5)), + createAnyTypeMatcher(settableMatcher)); + + settableMatcher.setMatcher(nextMatcher); + + break; + } + + // Is there an 'L***;' wildcard? + if (regularExpression.regionMatches(index, "L***;", 0, 5)) + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + createAnyTypeMatcher(parse(regularExpression.substring(index + 5))); + break; + } + + // Is there a '**' wildcard? + if (regularExpression.regionMatches(index, "**", 0, 2)) + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + new char[] { ClassConstants.INTERNAL_TYPE_CLASS_END }, + 0, + Integer.MAX_VALUE, + parse(regularExpression.substring(index + 2))); + break; + } + + // Is there a '*' wildcard? + else if (regularExpression.charAt(index) == '*') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + new char[] { ClassConstants.INTERNAL_TYPE_CLASS_END, ClassConstants.INTERNAL_PACKAGE_SEPARATOR }, + 0, + Integer.MAX_VALUE, + parse(regularExpression.substring(index + 1))); + break; + } + + // Is there a '?' wildcard? + else if (regularExpression.charAt(index) == '?') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + new char[] { ClassConstants.INTERNAL_TYPE_CLASS_END, ClassConstants.INTERNAL_PACKAGE_SEPARATOR }, + 1, + 1, + parse(regularExpression.substring(index + 1))); + break; + } + + // Is there a '%' wildcard? + else if (regularExpression.charAt(index) == '%') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(INTERNAL_PRIMITIVE_TYPES, + null, + 1, + 1, + parse(regularExpression.substring(index + 1))); + break; + } + } + + // Return a matcher for the fixed first part of the regular expression, + // if any, and the remainder. + return index != 0 ? + (StringMatcher)new FixedStringMatcher(regularExpression.substring(0, index), nextMatcher) : + (StringMatcher)nextMatcher; + } + + + // Small utility methods. + + + /** + * Creates a StringMatcher that matches any type (class or primitive type, + * array or non-array) and then the given matcher. + */ + private VariableStringMatcher createAnyTypeMatcher(StringMatcher nextMatcher) + { + return new VariableStringMatcher(new char[] { ClassConstants.INTERNAL_TYPE_ARRAY }, + null, + 0, + 255, + new OrMatcher( + new VariableStringMatcher(INTERNAL_PRIMITIVE_TYPES, + null, + 1, + 1, + nextMatcher), + new VariableStringMatcher(new char[] { ClassConstants.INTERNAL_TYPE_CLASS_START }, + null, + 1, + 1, + new VariableStringMatcher(null, + new char[] { ClassConstants.INTERNAL_TYPE_CLASS_END }, + 0, + Integer.MAX_VALUE, + new VariableStringMatcher(new char[] { ClassConstants.INTERNAL_TYPE_CLASS_END }, + null, + 1, + 1, + nextMatcher))))); + } + + + /** + * A main method for testing class name matching. + */ + public static void main(String[] args) + { + try + { + System.out.println("Regular expression ["+args[0]+"]"); + ClassNameParser parser = new ClassNameParser(); + StringMatcher matcher = parser.parse(args[0]); + for (int index = 1; index < args.length; index++) + { + String string = args[index]; + System.out.print("String ["+string+"]"); + System.out.println(" -> match = "+matcher.matches(args[index])); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/src/proguard/util/ConstantMatcher.java b/src/proguard/util/ConstantMatcher.java new file mode 100644 index 0000000..1764caa --- /dev/null +++ b/src/proguard/util/ConstantMatcher.java @@ -0,0 +1,48 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher matches any string or no string at all. + * + * @author Eric Lafortune + */ +public class ConstantMatcher implements StringMatcher +{ + private boolean matches; + + + /** + * Creates a new ConstantMatcher that always returns the given result. + */ + public ConstantMatcher(boolean matches) + { + this.matches = matches; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return matches; + } +}
\ No newline at end of file diff --git a/src/proguard/util/EmptyStringMatcher.java b/src/proguard/util/EmptyStringMatcher.java new file mode 100644 index 0000000..543f446 --- /dev/null +++ b/src/proguard/util/EmptyStringMatcher.java @@ -0,0 +1,36 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings are empty. + * + * @author Eric Lafortune + */ +public class EmptyStringMatcher implements StringMatcher +{ + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return string.length() == 0; + } +} diff --git a/src/proguard/util/ExtensionMatcher.java b/src/proguard/util/ExtensionMatcher.java new file mode 100644 index 0000000..5a9f658 --- /dev/null +++ b/src/proguard/util/ExtensionMatcher.java @@ -0,0 +1,63 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings end in a given extension, ignoring + * its case. + * + * @author Eric Lafortune + */ +public class ExtensionMatcher implements StringMatcher +{ + private final String extension; + + + /** + * Creates a new StringMatcher. + * @param extension the extension against which strings will be matched. + */ + public ExtensionMatcher(String extension) + { + this.extension = extension; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return endsWithIgnoreCase(string, extension); + } + + + /** + * Returns whether the given string ends with the given suffix, ignoring its + * case. + */ + private static boolean endsWithIgnoreCase(String string, String suffix) + { + int stringLength = string.length(); + int suffixLength = suffix.length(); + + return string.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength); + } +} diff --git a/src/proguard/util/FileNameParser.java b/src/proguard/util/FileNameParser.java new file mode 100644 index 0000000..913f22d --- /dev/null +++ b/src/proguard/util/FileNameParser.java @@ -0,0 +1,121 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +import java.io.File; + +/** + * This StringParser can create StringMatcher instances for regular expressions + * matching file names. The regular expressions can contain the following + * wildcards: + * '?' for a single regular file name character, + * '*' for any number of regular file name characters, and + * '**' for any number of regular file name characters or directory separator + * characters (always including '/'). + * + * @author Eric Lafortune + */ +public class FileNameParser implements StringParser +{ + // Implementations for StringParser. + + public StringMatcher parse(String regularExpression) + { + int index; + StringMatcher nextMatcher = new EmptyStringMatcher(); + + // Look for wildcards. + for (index = 0; index < regularExpression.length(); index++) + { + // Is there a '**' wildcard? + if (regularExpression.regionMatches(index, "**", 0, 2)) + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + null, + 0, + Integer.MAX_VALUE, + parse(regularExpression.substring(index + 2))); + break; + } + + // Is there a '*' wildcard? + else if (regularExpression.charAt(index) == '*') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + new char[] { File.pathSeparatorChar, '/' }, + 0, + Integer.MAX_VALUE, + parse(regularExpression.substring(index + 1))); + break; + } + + // Is there a '?' wildcard? + else if (regularExpression.charAt(index) == '?') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + new char[] { File.pathSeparatorChar, '/' }, + 1, + 1, + parse(regularExpression.substring(index + 1))); + break; + } + } + + // Return a matcher for the fixed first part of the regular expression, + // if any, and the remainder. + return index != 0 ? + (StringMatcher)new FixedStringMatcher(regularExpression.substring(0, index), nextMatcher) : + (StringMatcher)nextMatcher; + } + + + /** + * A main method for testing file name matching. + */ + public static void main(String[] args) + { + try + { + System.out.println("Regular expression ["+args[0]+"]"); + FileNameParser parser = new FileNameParser(); + StringMatcher matcher = parser.parse(args[0]); + for (int index = 1; index < args.length; index++) + { + String string = args[index]; + System.out.print("String ["+string+"]"); + System.out.println(" -> match = "+matcher.matches(args[index])); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/src/proguard/util/FixedStringMatcher.java b/src/proguard/util/FixedStringMatcher.java new file mode 100644 index 0000000..c1eb3f4 --- /dev/null +++ b/src/proguard/util/FixedStringMatcher.java @@ -0,0 +1,56 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings start with a given fixed string + * and then match another optional given StringMatcher. + * + * @author Eric Lafortune + */ +public class FixedStringMatcher implements StringMatcher +{ + private final String fixedString; + private final StringMatcher nextMatcher; + + + public FixedStringMatcher(String fixedString) + { + this(fixedString, null); + } + + + public FixedStringMatcher(String fixedString, StringMatcher nextMatcher) + { + this.fixedString = fixedString; + this.nextMatcher = nextMatcher; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return string.startsWith(fixedString) && + (nextMatcher == null || + nextMatcher.matches(string.substring(fixedString.length()))); + } +} diff --git a/src/proguard/util/ListMatcher.java b/src/proguard/util/ListMatcher.java new file mode 100644 index 0000000..b2559c8 --- /dev/null +++ b/src/proguard/util/ListMatcher.java @@ -0,0 +1,69 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings match a given list of StringMatcher + * instances. The instances are considered sequentially. Each instance in the + * list can optionally be negated, meaning that a match makes the entire + * remaining match fail. + * + * @author Eric Lafortune + */ +public class ListMatcher implements StringMatcher +{ + private final StringMatcher[] matchers; + private final boolean[] negate; + + + public ListMatcher(StringMatcher[] matchers) + { + this(matchers, null); + } + + + public ListMatcher(StringMatcher[] matchers, boolean[] negate) + { + this.matchers = matchers; + this.negate = negate; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + // Check the list of matchers. + for (int index = 0; index < matchers.length; index++) + { + StringMatcher matcher = matchers[index]; + if (matcher.matches(string)) + { + return negate == null || + !negate[index]; + } + } + + return negate != null && + negate[negate.length - 1]; + + } +} diff --git a/src/proguard/util/ListParser.java b/src/proguard/util/ListParser.java new file mode 100644 index 0000000..cec803b --- /dev/null +++ b/src/proguard/util/ListParser.java @@ -0,0 +1,137 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +import java.util.List; + +/** + * This StringParser can create StringMatcher instances for regular expressions. + * The regular expressions are either presented as a list, or they are + * interpreted as comma-separated lists, optionally prefixed with '!' negators. + * If an entry with a negator matches, a negative match is returned, without + * considering any subsequent entries in the list. The creation of StringMatcher + * instances for the entries is delegated to the given StringParser. + * + * @author Eric Lafortune + */ +public class ListParser implements StringParser +{ + private final StringParser stringParser; + + + /** + * Creates a new ListParser that parses individual elements in the + * comma-separated list with the given StringParser. + */ + public ListParser(StringParser stringParser) + { + this.stringParser = stringParser; + } + + + // Implementations for StringParser. + + public StringMatcher parse(String regularExpression) + { + // Does the regular expression contain a ',' list separator? + return parse(ListUtil.commaSeparatedList(regularExpression)); + } + + + /** + * Creates a StringMatcher for the given regular expression, which can + * be a list of optionally negated simple entries. + * <p> + * An empty list results in a StringMatcher that matches any string. + */ + public StringMatcher parse(List regularExpressions) + { + StringMatcher listMatcher = null; + + // Loop over all simple regular expressions, backward, creating a + // linked list of matchers. + for (int index = regularExpressions.size()-1; index >=0; index--) + { + String regularExpression = (String)regularExpressions.get(index); + + StringMatcher entryMatcher = parseEntry(regularExpression); + + // Prepend the entry matcher. + listMatcher = + listMatcher == null ? + (StringMatcher)entryMatcher : + isNegated(regularExpression) ? + (StringMatcher)new AndMatcher(entryMatcher, listMatcher) : + (StringMatcher)new OrMatcher(entryMatcher, listMatcher); + } + + return listMatcher != null ? listMatcher : new ConstantMatcher(true); + } + + + // Small utility methods. + + /** + * Creates a StringMatcher for the given regular expression, which is a + * an optionally negated simple expression. + */ + private StringMatcher parseEntry(String regularExpression) + { + // Wrap the matcher if the regular expression starts with a '!' negator. + return isNegated(regularExpression) ? + new NotMatcher(stringParser.parse(regularExpression.substring(1))) : + stringParser.parse(regularExpression); + } + + + /** + * Returns whether the given simple regular expression is negated. + */ + private boolean isNegated(String regularExpression) + { + return regularExpression.length() > 0 && + regularExpression.charAt(0) == '!'; + } + + + /** + * A main method for testing name matching. + */ + public static void main(String[] args) + { + try + { + System.out.println("Regular expression ["+args[0]+"]"); + ListParser parser = new ListParser(new NameParser()); + StringMatcher matcher = parser.parse(args[0]); + for (int index = 1; index < args.length; index++) + { + String string = args[index]; + System.out.print("String ["+string+"]"); + System.out.println(" -> match = "+matcher.matches(args[index])); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/src/proguard/util/ListUtil.java b/src/proguard/util/ListUtil.java new file mode 100644 index 0000000..570dbe8 --- /dev/null +++ b/src/proguard/util/ListUtil.java @@ -0,0 +1,173 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +import java.util.*; + + +/** + * This class provides some utility methods for working with + * <code>java.util.List</code> objects. + * + * @author Eric Lafortune + */ +public class ListUtil +{ + /** + * Creates a comma-separated String from the given List of String objects. + */ + public static String commaSeparatedString(List list) + { + if (list == null) + { + return null; + } + + StringBuffer buffer = new StringBuffer(); + + for (int index = 0; index < list.size(); index++) + { + if (index > 0) + { + buffer.append(','); + } + + buffer.append(quotedString((String)list.get(index))); + } + + return buffer.toString(); + } + + + /** + * Creates a List of String objects from the given comma-separated String. + */ + public static List commaSeparatedList(String string) + { + if (string == null) + { + return null; + } + + List list = new ArrayList(); + int index = 0; + while ((index = skipWhitespace(string, index)) < string.length()) + { + int nextIndex; + + // Do we have an opening quote? + if (string.charAt(index) == '\'') + { + // Parse a quoted string. + nextIndex = string.indexOf('\'', index + 1); + if (nextIndex < 0) + { + nextIndex = string.length(); + } + + list.add(string.substring(index + 1, nextIndex)); + } + else + { + // Parse a non-quoted string. + nextIndex = string.indexOf(',', index); + if (nextIndex < 0) + { + nextIndex = string.length(); + } + + String substring = string.substring(index, nextIndex).trim(); + if (substring.length() > 0) + { + list.add(substring); + } + } + + index = nextIndex + 1; + } + + return list; + } + + + /** + * Skips any whitespace characters. + */ + private static int skipWhitespace(String string, int index) + { + while (index < string.length() && + Character.isWhitespace(string.charAt(index))) + { + index++; + } + return index; + } + + + /** + * Returns a quoted version of the given string, if necessary. + */ + private static String quotedString(String string) + { + return string.length() == 0 || + string.indexOf(' ') >= 0 || + string.indexOf('@') >= 0 || + string.indexOf('{') >= 0 || + string.indexOf('}') >= 0 || + string.indexOf('(') >= 0 || + string.indexOf(')') >= 0 || + string.indexOf(':') >= 0 || + string.indexOf(';') >= 0 || + string.indexOf(',') >= 0 ? ("'" + string + "'") : + ( string ); + } + + + public static void main(String[] args) + { + if (args.length == 1) + { + System.out.println("Input string: ["+args[0]+"]"); + + List list = commaSeparatedList(args[0]); + + System.out.println("Resulting list:"); + for (int index = 0; index < list.size(); index++) + { + System.out.println("["+list.get(index)+"]"); + } + } + else + { + List list = Arrays.asList(args); + + System.out.println("Input list:"); + for (int index = 0; index < list.size(); index++) + { + System.out.println("["+list.get(index)+"]"); + } + + String string = commaSeparatedString(list); + + System.out.println("Resulting string: ["+string+"]"); + } + } +} diff --git a/src/proguard/util/NameParser.java b/src/proguard/util/NameParser.java new file mode 100644 index 0000000..e311fbf --- /dev/null +++ b/src/proguard/util/NameParser.java @@ -0,0 +1,106 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringParser can create StringMatcher instances for regular expressions + * matching names. The regular expressions are interpreted as comma-separated + * lists of names, optionally prefixed with '!' negators. + * If a name with a negator matches, a negative match is returned, without + * considering any subsequent entries in the list. + * Names can contain the following wildcards: + * '?' for a single character, and + * '*' for any number of characters. + * + * @author Eric Lafortune + */ +public class NameParser implements StringParser +{ + // Implementations for StringParser. + + public StringMatcher parse(String regularExpression) + { + int index; + StringMatcher nextMatcher = new EmptyStringMatcher(); + + // Look for wildcards. + for (index = 0; index < regularExpression.length(); index++) + { + // Is there a '*' wildcard? + if (regularExpression.charAt(index) == '*') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + null, + 0, + Integer.MAX_VALUE, + parse(regularExpression.substring(index + 1))); + break; + } + + // Is there a '?' wildcard? + else if (regularExpression.charAt(index) == '?') + { + // Create a matcher for the wildcard and, recursively, for the + // remainder of the string. + nextMatcher = + new VariableStringMatcher(null, + null, + 1, + 1, + parse(regularExpression.substring(index + 1))); + break; + } + } + + // Return a matcher for the fixed first part of the regular expression, + // if any, and the remainder. + return index != 0 ? + (StringMatcher)new FixedStringMatcher(regularExpression.substring(0, index), nextMatcher) : + (StringMatcher)nextMatcher; + } + + + /** + * A main method for testing name matching. + */ + public static void main(String[] args) + { + try + { + System.out.println("Regular expression ["+args[0]+"]"); + NameParser parser = new NameParser(); + StringMatcher matcher = parser.parse(args[0]); + for (int index = 1; index < args.length; index++) + { + String string = args[index]; + System.out.print("String ["+string+"]"); + System.out.println(" -> match = "+matcher.matches(args[index])); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } +} diff --git a/src/proguard/util/NotMatcher.java b/src/proguard/util/NotMatcher.java new file mode 100644 index 0000000..f2a9a51 --- /dev/null +++ b/src/proguard/util/NotMatcher.java @@ -0,0 +1,46 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings does not match the given + * StringMatcher. + * + * @author Eric Lafortune + */ +public class NotMatcher implements StringMatcher +{ + private final StringMatcher matcher; + + + public NotMatcher(StringMatcher matcher) + { + this.matcher = matcher; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return !matcher.matches(string); + } +} diff --git a/src/proguard/util/OrMatcher.java b/src/proguard/util/OrMatcher.java new file mode 100644 index 0000000..097c6c6 --- /dev/null +++ b/src/proguard/util/OrMatcher.java @@ -0,0 +1,49 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings matches either of the given + * StringMatcher instances. + * + * @author Eric Lafortune + */ +public class OrMatcher implements StringMatcher +{ + private final StringMatcher matcher1; + private final StringMatcher matcher2; + + + public OrMatcher(StringMatcher matcher1, StringMatcher matcher2) + { + this.matcher1 = matcher1; + this.matcher2 = matcher2; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return matcher1.matches(string) || + matcher2.matches(string); + } +} diff --git a/src/proguard/util/SettableMatcher.java b/src/proguard/util/SettableMatcher.java new file mode 100644 index 0000000..9557f62 --- /dev/null +++ b/src/proguard/util/SettableMatcher.java @@ -0,0 +1,46 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher delegates to a another StringMatcher that can be set + * after this StringMatcher has been constructed. + * + * @author Eric Lafortune + */ +public class SettableMatcher implements StringMatcher +{ + private StringMatcher matcher; + + + public void setMatcher(StringMatcher matcher) + { + this.matcher = matcher; + } + + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + return matcher.matches(string); + } +} diff --git a/src/proguard/util/StringMatcher.java b/src/proguard/util/StringMatcher.java new file mode 100644 index 0000000..bd66dcc --- /dev/null +++ b/src/proguard/util/StringMatcher.java @@ -0,0 +1,38 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + + +/** + * This interface provides a method to determine whether strings match a given + * criterion, which is specified by the implementation. + * + * @author Eric Lafortune + */ +public interface StringMatcher +{ + /** + * Checks whether the given string matches. + * @param string the string to match. + * @return a boolean indicating whether the string matches the criterion. + */ + public boolean matches(String string); +} diff --git a/src/proguard/util/StringParser.java b/src/proguard/util/StringParser.java new file mode 100644 index 0000000..29f4f16 --- /dev/null +++ b/src/proguard/util/StringParser.java @@ -0,0 +1,35 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This interface provides a method to create a SringMatcher for a given + * regular expression. + * + * @author Eric Lafortune + */ +public interface StringParser +{ + /** + * Creates a StringMatcher for the given regular expression. + */ + public StringMatcher parse(String regularExpression); +} diff --git a/src/proguard/util/VariableStringMatcher.java b/src/proguard/util/VariableStringMatcher.java new file mode 100644 index 0000000..1e41323 --- /dev/null +++ b/src/proguard/util/VariableStringMatcher.java @@ -0,0 +1,126 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * 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 + * 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 + */ +package proguard.util; + +/** + * This StringMatcher tests whether strings start with a specified variable + * string and then match another given StringMatcher. + * + * @author Eric Lafortune + */ +public class VariableStringMatcher implements StringMatcher +{ + private final char[] allowedCharacters; + private final char[] disallowedCharacters; + private final int minimumLength; + private final int maximumLength; + private final StringMatcher nextMatcher; + + + public VariableStringMatcher(char[] allowedCharacters, + char[] disallowedCharacters, + int minimumLength, + int maximumLength, + StringMatcher nextMatcher) + { + this.allowedCharacters = allowedCharacters; + this.disallowedCharacters = disallowedCharacters; + this.minimumLength = minimumLength; + this.maximumLength = maximumLength; + this.nextMatcher = nextMatcher; + } + + // Implementations for StringMatcher. + + public boolean matches(String string) + { + if (string.length() < minimumLength) + { + return false; + } + + // Check the first minimum number of characters. + for (int index = 0; index < minimumLength; index++) + { + if (!isAllowedCharacter(string.charAt(index))) + { + return false; + } + } + + int maximumLength = Math.min(this.maximumLength, string.length()); + + // Check the remaining characters, up to the maximum number. + for (int index = minimumLength; index < maximumLength; index++) + { + if (nextMatcher.matches(string.substring(index))) + { + return true; + } + + if (!isAllowedCharacter(string.charAt(index))) + { + return false; + } + } + + // Check the remaining characters in the string. + return nextMatcher.matches(string.substring(maximumLength)); + } + + + // Small utility methods. + + /** + * Returns whether the given character is allowed in the variable string. + */ + private boolean isAllowedCharacter(char character) + { + // Check the allowed characters. + if (allowedCharacters != null) + { + for (int index = 0; index < allowedCharacters.length; index++) + { + if (allowedCharacters[index] == character) + { + return true; + } + } + + return false; + } + + // Check the disallowed characters. + if (disallowedCharacters != null) + { + for (int index = 0; index < disallowedCharacters.length; index++) + { + if (disallowedCharacters[index] == character) + { + return false; + } + } + } + + // Any remaining character is allowed. + return true; + } +} diff --git a/src/proguard/util/package.html b/src/proguard/util/package.html new file mode 100644 index 0000000..cb14fdc --- /dev/null +++ b/src/proguard/util/package.html @@ -0,0 +1,3 @@ +<body> +This package contains utility classes for regular expression matching,... +</body> |