summaryrefslogtreecommitdiff
path: root/src/proguard/util
diff options
context:
space:
mode:
authorJoe Onorato <joeo@android.com>2009-08-31 10:12:00 -0700
committerJoe Onorato <joeo@android.com>2009-08-31 10:12:00 -0700
commitb72c5c2e5482cf10117b2b25f642f7616b2326c3 (patch)
treef02ba1bc29f4fe6853d9b7008eed37cdcfb96e81 /src/proguard/util
parenta23344a828357fe4b6596f8af5fed467d72757ab (diff)
downloadproguard-b72c5c2e5482cf10117b2b25f642f7616b2326c3.tar.gz
Diffstat (limited to 'src/proguard/util')
-rw-r--r--src/proguard/util/AndMatcher.java49
-rw-r--r--src/proguard/util/ClassNameParser.java216
-rw-r--r--src/proguard/util/ConstantMatcher.java48
-rw-r--r--src/proguard/util/EmptyStringMatcher.java36
-rw-r--r--src/proguard/util/ExtensionMatcher.java63
-rw-r--r--src/proguard/util/FileNameParser.java121
-rw-r--r--src/proguard/util/FixedStringMatcher.java56
-rw-r--r--src/proguard/util/ListMatcher.java69
-rw-r--r--src/proguard/util/ListParser.java137
-rw-r--r--src/proguard/util/ListUtil.java173
-rw-r--r--src/proguard/util/NameParser.java106
-rw-r--r--src/proguard/util/NotMatcher.java46
-rw-r--r--src/proguard/util/OrMatcher.java49
-rw-r--r--src/proguard/util/SettableMatcher.java46
-rw-r--r--src/proguard/util/StringMatcher.java38
-rw-r--r--src/proguard/util/StringParser.java35
-rw-r--r--src/proguard/util/VariableStringMatcher.java126
-rw-r--r--src/proguard/util/package.html3
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>