2 // This software is now distributed according to
3 // the Lesser Gnu Public License. Please see
4 // http://www.gnu.org/copyleft/lesser.txt for
8 package com.stevesoft.pat;
11 import java.util.StringTokenizer;
12 import java.util.Vector;
15 * This class is a different form of Regex designed to work more like the file
16 * matching utility of a Unix shell. It is implemented by some simple string
17 * transformations: <center>
50 * </center> Note that a FileRegex pattern always ends with the Regex pattern
51 * element "$". If you like to experiment, try making FileRegex's and then
52 * printing them out. The toString() method does a decompile of the pattern to a
53 * standard Regex. Here are some more complete examples: <center>
62 * <td>*.{java,html}</td>
63 * <td>.*\.(java|html)$</td>
70 public class FileRegex extends Regex
72 /** Build an unitialized FileRegex. */
78 /** Build a FileRegex form String s. */
79 public FileRegex(String s)
86 * Compile a new pattern. Throws
88 * @exception com.stevesoft.pat.RegSyntax
89 * for nonsensical patterns like "[9-0]+" just as Regex does.
90 * @see com.stevesoft.pat#compile(java.lang.String)
92 public void compile(String s) throws RegSyntax
94 String npat = toFileRegex(s);
96 if (File.separatorChar == '\\') // MS-DOS
103 * This is the method required by FileNameFilter. To get a listing of files in
104 * the current directory ending in .java, do this:
107 * File dot = new File(".");
109 * FileRegex java_files = new FileRegex("*.java");
111 * String[] file_list = dot.list(java_files);
114 public boolean accept(File dir, String s)
116 if (dirflag != EITHER)
118 File f = new File(s);
119 if (f.isDirectory() && dirflag == NONDIR)
123 if (!f.isDirectory() && dirflag == DIR)
128 return matchAt(s, 0);
133 final static int EITHER = 0, DIR = 1, NONDIR = 2;
136 * Provides an alternative to File.list -- this separates its argument
137 * according to File.pathSeparator. To each path, it splits off a directory --
138 * all characters up to and including the first instance of File.separator --
139 * and a file pattern -- the part that comes after the directory. It then
140 * produces a list of all the pattern matches on all the paths. Thus
141 * "*.java:../*.java" would produce a list of all the java files in this
142 * directory and in the ".." directory on a Unix machine. "*.java;..\\*.java"
143 * would do the same thing on a Dos machine.
145 public static String[] list(String f)
147 return list(f, EITHER);
150 static String[] list(String f, int df)
152 // return list_(f,new FileRegex());
153 StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
154 Vector v = new Vector();
155 while (st.hasMoreTokens())
157 String path = st.nextToken();
158 list1(path, v, df, true);
160 String[] sa = new String[v.size()];
165 final static Regex root = new Regex(File.separatorChar == '/' ? "/$"
168 static void list1(String path, Vector v, int df, boolean rec)
170 // if path looks like a/b/c/ or d:\ then add .
171 if (root.matchAt(path, 0))
173 v.addElement(path + ".");
176 File f = new File(path);
177 if (f.getParent() != null && rec)
179 Vector v2 = new Vector();
180 list1(f.getParent(), v2, DIR, true);
181 for (int i = 0; i < v2.size(); i++)
183 String path2 = ((String) v2.elementAt(i)) + File.separator
185 list1(path2, v, df, false);
190 File base = new File(path);
192 String dir_s = base.getParent();
197 File dir = new File(dir_s);
199 FileRegex fr = new FileRegex(base.getName());
202 v.addElement(dir_s + File.separator + base.getName());
206 String[] sa = dir.list(fr);
211 for (int i = 0; i < sa.length; i++)
213 v.addElement(dir_s + File.separator + sa[i]);
219 * This method takes a file regular expression, and translates it into the
220 * type of pattern used by a normal Regex.
222 public static String toFileRegex(String s)
224 StrPos sp = new StrPos(s, 0);
225 StringBuffer sb = new StringBuffer();
226 if (sp.incMatch("{?e="))
228 char e = sp.thisChar();
230 if (sp.incMatch("}"))
232 sb.append("(?e=" + e + ")^");
243 if (File.separatorChar == '\\')
249 sp.dontMatch = false;
251 if (sp.incMatch("?"))
255 else if (sp.incMatch("."))
260 else if (sp.incMatch("{??"))
264 // allow negative lookahead to work
266 else if (sp.incMatch("{?!"))
270 // allow positive lookahead to work
272 else if (sp.incMatch("{?="))
277 else if (sp.incMatch("{"))
282 else if (sp.incMatch("}"))
287 else if (ParenLvl != 0 && sp.incMatch(","))
291 else if (sp.incMatch("*"))
297 sb.append(sp.thisChar());
302 return sb.toString();
305 public boolean isLiteral()
307 Pattern x = thePattern;
308 while (x != null && !(x instanceof End))
310 if (x instanceof oneChar)
314 else if (x instanceof Skipped)