X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fcom%2Fstevesoft%2Fpat%2FFileRegex.java;h=fa57795cdf887258b1a2dbdfe24d9863c6fc83bf;hb=4d7f98a6dd54d9863ba449ec79dcd95d25ed863d;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:
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FileRegexRegex
*.*
.\.
{(?:
{?!(?!
{?=(?=
{??(??
)
?.
{,}(|)
+ *
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:
+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
FileRegexRegex
*.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; + } +}