X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Fcom%2Fstevesoft%2Fpat%2FFileRegex.java;h=fa57795cdf887258b1a2dbdfe24d9863c6fc83bf;hb=970956e40635fd5a86d46e399532abda64ccdf92;hp=37729eb4b9b6c54659fed314d8fe3c314a9a3fc7;hpb=7bc226b58110fa26d9dbd3f0c78095d06909ffc3;p=jalview.git
diff --git a/src/com/stevesoft/pat/FileRegex.java b/src/com/stevesoft/pat/FileRegex.java
index 37729eb..fa57795 100755
--- a/src/com/stevesoft/pat/FileRegex.java
+++ b/src/com/stevesoft/pat/FileRegex.java
@@ -1,293 +1,326 @@
-//
-// This software is now distributed according to
-// the Lesser Gnu Public License. Please see
-// http://www.gnu.org/copyleft/lesser.txt for
-// the details.
-// -- Happy Computing!
-//
-package com.stevesoft.pat;
-
-import java.io.*;
-import java.util.*;
-
-/** This class is a different form of Regex designed to work more
- like the file matching utility of a Unix shell. It is implemented
- by some simple string transformations:
-
-
- FileRegex | Regex |
-
* | .* |
-
. | \. |
-
{ | (?: |
-
{?! | (?! |
-
{?= | (?= |
-
{?? | (?? |
-
} | ) |
-
? | . |
-
{,} | (|) |
-
-
- Note that a FileRegex pattern always ends with the Regex
- pattern element "$". If you like to experiment, try making
- FileRegex's and then printing them out. The toString() method
- does a decompile of the pattern to a standard Regex. Here are
- some more complete examples:
-
-
- FileRegex | Regex |
-
*.java | .*\.java$ |
-
*.{java,html} | .*\.(java|html)$ |
-
foo.[chC] | foo.[chC]$ |
-
-
- */
-public class FileRegex
- extends Regex
-{
- /** Build an unitialized FileRegex. */
- public FileRegex()
- {
- dirflag = EITHER;
- }
-
- /** Build a FileRegex form String s. */
- public FileRegex(String s)
- {
- super(s);
- dirflag = EITHER;
- }
-
- /** Compile a new pattern.
- Throws @exception com.stevesoft.pat.RegSyntax for
- nonsensical patterns like "[9-0]+" just as Regex does.
- @see com.stevesoft.pat#compile(java.lang.String)
- */
- public void compile(String s)
- throws RegSyntax
- {
- String npat = toFileRegex(s);
- super.compile(npat);
- if (File.separatorChar == '\\') // MS-DOS
- {
- ignoreCase = true;
- }
- }
-
- /** This is the method required by FileNameFilter.
- To get a listing of files in the current directory
- ending in .java, do this:
-
- File dot = new File(".");
- FileRegex java_files = new FileRegex("*.java");
- String[] file_list = dot.list(java_files);
-
- */
- public boolean accept(File dir, String s)
- {
- if (dirflag != EITHER)
- {
- File f = new File(s);
- if (f.isDirectory() && dirflag == NONDIR)
- {
- return false;
- }
- if (!f.isDirectory() && dirflag == DIR)
- {
- return false;
- }
- }
- return matchAt(s, 0);
- }
-
- int dirflag = 0;
- final static int EITHER = 0, DIR = 1, NONDIR = 2;
-
- /** Provides an alternative to File.list -- this
- separates its argument according to File.pathSeparator.
- To each path, it splits off a directory -- all characters
- up to and including the first instance of File.separator --
- and a file pattern -- the part that comes after the directory.
- It then produces a list of all the pattern matches on all
- the paths. Thus "*.java:../*.java" would produce a list of
- all the java files in this directory and in the ".." directory
- on a Unix machine. "*.java;..\\*.java" would do the same thing
- on a Dos machine. */
- public static String[] list(String f)
- {
- return list(f, EITHER);
- }
-
- static String[] list(String f, int df)
- {
- //return list_(f,new FileRegex());
- StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
- Vector v = new Vector();
- while (st.hasMoreTokens())
- {
- String path = st.nextToken();
- list1(path, v, df, true);
- }
- String[] sa = new String[v.size()];
- v.copyInto(sa);
- return sa;
- }
-
- final static Regex root = new Regex(File.separatorChar == '/' ?
- "/$" : "(?:.:|)\\\\$");
- static void list1(String path, Vector v, int df, boolean rec)
- {
- // if path looks like a/b/c/ or d:\ then add .
- if (root.matchAt(path, 0))
- {
- v.addElement(path + ".");
- return;
- }
- File f = new File(path);
- if (f.getParent() != null && rec)
- {
- Vector v2 = new Vector();
- list1(f.getParent(), v2, DIR, true);
- for (int i = 0; i < v2.size(); i++)
- {
- String path2 = ( (String) v2.elementAt(i)) +
- File.separator + f.getName();
- list1(path2, v, df, false);
- }
- }
- else
- {
- File base = new File(path);
-
- String dir_s = base.getParent();
- if (dir_s == null)
- {
- dir_s = ".";
- }
- File dir = new File(dir_s);
-
- FileRegex fr = new FileRegex(base.getName());
- if (fr.isLiteral())
- {
- v.addElement(dir_s + File.separator + base.getName());
- return;
- }
- fr.dirflag = df;
- String[] sa = dir.list(fr);
- if (sa == null)
- {
- return;
- }
- for (int i = 0; i < sa.length; i++)
- {
- v.addElement(dir_s + File.separator + sa[i]);
- }
- }
- }
-
- /** This method takes a file regular expression, and translates it
- into the type of pattern used by a normal Regex. */
- public static String toFileRegex(String s)
- {
- StrPos sp = new StrPos(s, 0);
- StringBuffer sb = new StringBuffer();
- if (sp.incMatch("{?e="))
- {
- char e = sp.thisChar();
- sp.inc();
- if (sp.incMatch("}"))
- {
- sb.append("(?e=" + e + ")^");
- }
- else
- {
- sb.append("^(?e=");
- }
- sp.esc = e;
- }
- int ParenLvl = 0;
- while (!sp.eos())
- {
- if (File.separatorChar == '\\')
- {
- if (sp.escaped())
- {
- sb.append("\\\\");
- }
- sp.dontMatch = false;
- }
- if (sp.incMatch("?"))
- {
- sb.append(".");
- }
- else if (sp.incMatch("."))
- {
- sb.append(sp.esc);
- sb.append('.');
- }
- else if (sp.incMatch("{??"))
- {
- sb.append("(??");
- ParenLvl++;
- // allow negative lookahead to work
- }
- else if (sp.incMatch("{?!"))
- {
- sb.append("(?!");
- ParenLvl++;
- // allow positive lookahead to work
- }
- else if (sp.incMatch("{?="))
- {
- sb.append("(?=");
- ParenLvl++;
- }
- else if (sp.incMatch("{"))
- {
- sb.append("(?:");
- ParenLvl++;
- }
- else if (sp.incMatch("}"))
- {
- sb.append(')');
- ParenLvl--;
- }
- else if (ParenLvl != 0 && sp.incMatch(","))
- {
- sb.append('|');
- }
- else if (sp.incMatch("*"))
- {
- sb.append(".*");
- }
- else
- {
- sb.append(sp.thisChar());
- sp.inc();
- }
- }
- sb.append("$");
- return sb.toString();
- }
-
- public boolean isLiteral()
- {
- Pattern x = thePattern;
- while (x != null && ! (x instanceof End))
- {
- if (x instanceof oneChar)
- {
- ;
- }
- else if (x instanceof Skipped)
- {
- ;
- }
- else
- {
- return false;
- }
- x = x.next;
- }
- return true;
- }
-}
+//
+// This software is now distributed according to
+// the Lesser Gnu Public License. Please see
+// http://www.gnu.org/copyleft/lesser.txt for
+// the details.
+// -- Happy Computing!
+//
+package com.stevesoft.pat;
+
+import java.io.File;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * This class is a different form of Regex designed to work more like the file
+ * matching utility of a Unix shell. It is implemented by some simple string
+ * transformations:
+ *
+ *
+ * FileRegex |
+ * Regex |
+ *
+ * * |
+ * .* |
+ *
+ * . |
+ * \. |
+ *
+ * { |
+ * (?: |
+ *
+ * {?! |
+ * (?! |
+ *
+ * {?= |
+ * (?= |
+ *
+ * {?? |
+ * (?? |
+ *
+ * |
+ * ) |
+ *
+ * ? |
+ * . |
+ *
+ * {,} |
+ * (|) |
+ *
+ * Note that a FileRegex pattern always ends with the Regex pattern
+ * element "$". If you like to experiment, try making FileRegex's and then
+ * printing them out. The toString() method does a decompile of the pattern to a
+ * standard Regex. Here are some more complete examples:
+ *
+ *
+ * FileRegex |
+ * Regex |
+ *
+ * *.java |
+ * .*\.java$ |
+ *
+ * *.{java,html} |
+ * .*\.(java|html)$ |
+ *
+ * foo.[chC] |
+ * foo.[chC]$ |
+ *
+ *
+ */
+public class FileRegex extends Regex
+{
+ /** Build an unitialized FileRegex. */
+ public FileRegex()
+ {
+ dirflag = EITHER;
+ }
+
+ /** Build a FileRegex form String s. */
+ public FileRegex(String s)
+ {
+ super(s);
+ dirflag = EITHER;
+ }
+
+ /**
+ * Compile a new pattern. Throws
+ *
+ * @exception com.stevesoft.pat.RegSyntax
+ * for nonsensical patterns like "[9-0]+" just as Regex does.
+ * @see com.stevesoft.pat#compile(java.lang.String)
+ */
+ public void compile(String s) throws RegSyntax
+ {
+ String npat = toFileRegex(s);
+ super.compile(npat);
+ if (File.separatorChar == '\\') // MS-DOS
+ {
+ ignoreCase = true;
+ }
+ }
+
+ /**
+ * This is the method required by FileNameFilter. To get a listing of files in
+ * the current directory ending in .java, do this:
+ *
+ *
+ * File dot = new File(".");
+ *
+ * FileRegex java_files = new FileRegex("*.java");
+ *
+ * String[] file_list = dot.list(java_files);
+ *
+ */
+ public boolean accept(File dir, String s)
+ {
+ if (dirflag != EITHER)
+ {
+ File f = new File(s);
+ if (f.isDirectory() && dirflag == NONDIR)
+ {
+ return false;
+ }
+ if (!f.isDirectory() && dirflag == DIR)
+ {
+ return false;
+ }
+ }
+ return matchAt(s, 0);
+ }
+
+ int dirflag = 0;
+
+ final static int EITHER = 0, DIR = 1, NONDIR = 2;
+
+ /**
+ * Provides an alternative to File.list -- this separates its argument
+ * according to File.pathSeparator. To each path, it splits off a directory --
+ * all characters up to and including the first instance of File.separator --
+ * and a file pattern -- the part that comes after the directory. It then
+ * produces a list of all the pattern matches on all the paths. Thus
+ * "*.java:../*.java" would produce a list of all the java files in this
+ * directory and in the ".." directory on a Unix machine. "*.java;..\\*.java"
+ * would do the same thing on a Dos machine.
+ */
+ public static String[] list(String f)
+ {
+ return list(f, EITHER);
+ }
+
+ static String[] list(String f, int df)
+ {
+ // return list_(f,new FileRegex());
+ StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
+ Vector v = new Vector();
+ while (st.hasMoreTokens())
+ {
+ String path = st.nextToken();
+ list1(path, v, df, true);
+ }
+ String[] sa = new String[v.size()];
+ v.copyInto(sa);
+ return sa;
+ }
+
+ final static Regex root = new Regex(File.separatorChar == '/' ? "/$"
+ : "(?:.:|)\\\\$");
+
+ static void list1(String path, Vector v, int df, boolean rec)
+ {
+ // if path looks like a/b/c/ or d:\ then add .
+ if (root.matchAt(path, 0))
+ {
+ v.addElement(path + ".");
+ return;
+ }
+ File f = new File(path);
+ if (f.getParent() != null && rec)
+ {
+ Vector v2 = new Vector();
+ list1(f.getParent(), v2, DIR, true);
+ for (int i = 0; i < v2.size(); i++)
+ {
+ String path2 = ((String) v2.elementAt(i)) + File.separator
+ + f.getName();
+ list1(path2, v, df, false);
+ }
+ }
+ else
+ {
+ File base = new File(path);
+
+ String dir_s = base.getParent();
+ if (dir_s == null)
+ {
+ dir_s = ".";
+ }
+ File dir = new File(dir_s);
+
+ FileRegex fr = new FileRegex(base.getName());
+ if (fr.isLiteral())
+ {
+ v.addElement(dir_s + File.separator + base.getName());
+ return;
+ }
+ fr.dirflag = df;
+ String[] sa = dir.list(fr);
+ if (sa == null)
+ {
+ return;
+ }
+ for (int i = 0; i < sa.length; i++)
+ {
+ v.addElement(dir_s + File.separator + sa[i]);
+ }
+ }
+ }
+
+ /**
+ * This method takes a file regular expression, and translates it into the
+ * type of pattern used by a normal Regex.
+ */
+ public static String toFileRegex(String s)
+ {
+ StrPos sp = new StrPos(s, 0);
+ StringBuffer sb = new StringBuffer();
+ if (sp.incMatch("{?e="))
+ {
+ char e = sp.thisChar();
+ sp.inc();
+ if (sp.incMatch("}"))
+ {
+ sb.append("(?e=" + e + ")^");
+ }
+ else
+ {
+ sb.append("^(?e=");
+ }
+ sp.esc = e;
+ }
+ int ParenLvl = 0;
+ while (!sp.eos())
+ {
+ if (File.separatorChar == '\\')
+ {
+ if (sp.escaped())
+ {
+ sb.append("\\\\");
+ }
+ sp.dontMatch = false;
+ }
+ if (sp.incMatch("?"))
+ {
+ sb.append(".");
+ }
+ else if (sp.incMatch("."))
+ {
+ sb.append(sp.esc);
+ sb.append('.');
+ }
+ else if (sp.incMatch("{??"))
+ {
+ sb.append("(??");
+ ParenLvl++;
+ // allow negative lookahead to work
+ }
+ else if (sp.incMatch("{?!"))
+ {
+ sb.append("(?!");
+ ParenLvl++;
+ // allow positive lookahead to work
+ }
+ else if (sp.incMatch("{?="))
+ {
+ sb.append("(?=");
+ ParenLvl++;
+ }
+ else if (sp.incMatch("{"))
+ {
+ sb.append("(?:");
+ ParenLvl++;
+ }
+ else if (sp.incMatch("}"))
+ {
+ sb.append(')');
+ ParenLvl--;
+ }
+ else if (ParenLvl != 0 && sp.incMatch(","))
+ {
+ sb.append('|');
+ }
+ else if (sp.incMatch("*"))
+ {
+ sb.append(".*");
+ }
+ else
+ {
+ sb.append(sp.thisChar());
+ sp.inc();
+ }
+ }
+ sb.append("$");
+ return sb.toString();
+ }
+
+ public boolean isLiteral()
+ {
+ Pattern x = thePattern;
+ while (x != null && !(x instanceof End))
+ {
+ if (x instanceof oneChar)
+ {
+ ;
+ }
+ else if (x instanceof Skipped)
+ {
+ ;
+ }
+ else
+ {
+ return false;
+ }
+ x = x.next;
+ }
+ return true;
+ }
+}