Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package com.stevesoft.pat

File FileRegex.java

 

Coverage histogram

../../../img/srcFileCovDistChart0.png
56% of files have more coverage

Code metrics

58
100
9
1
326
209
43
0.43
11.11
9
4.78

Classes

Class Line # Actions
FileRegex 70 100 43
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    //
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
5    // the details.
6    // -- Happy Computing!
7    //
8    package com.stevesoft.pat;
9   
10    import java.io.File;
11    import java.util.StringTokenizer;
12    import java.util.Vector;
13   
14    /**
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>
18    * <table border=1>
19    * <tr>
20    * <td>FileRegex</td>
21    * <td>Regex</td>
22    * <tr>
23    * <td>*</td>
24    * <td>.*</td>
25    * <tr>
26    * <td>.</td>
27    * <td>\.</td>
28    * <tr>
29    * <td>{</td>
30    * <td>(?:</td>
31    * <tr>
32    * <td>{?!</td>
33    * <td>(?!</td>
34    * <tr>
35    * <td>{?=</td>
36    * <td>(?=</td>
37    * <tr>
38    * <td>{??</td>
39    * <td>(??</td>
40    * <tr>
41    * <td></td>
42    * <td>)</td>
43    * <tr>
44    * <td>?</td>
45    * <td>.</td>
46    * <tr>
47    * <td>{,}</td>
48    * <td>(|)</td>
49    * </table>
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>
54    * <table * border=3>
55    * <tr>
56    * <td>FileRegex</td>
57    * <td>Regex</td>
58    * <tr>
59    * <td>*.java</td>
60    * <td>.*\.java$</td>
61    * <tr>
62    * <td>*.{java,html}</td>
63    * <td>.*\.(java|html)$</td>
64    * <tr>
65    * <td>foo.[chC]</td>
66    * <td>foo.[chC]$</td>
67    * </table>
68    * </center>
69    */
 
70    public class FileRegex extends Regex
71    {
72    /** Build an unitialized FileRegex. */
 
73  0 toggle public FileRegex()
74    {
75  0 dirflag = EITHER;
76    }
77   
78    /** Build a FileRegex form String s. */
 
79  0 toggle public FileRegex(String s)
80    {
81  0 super(s);
82  0 dirflag = EITHER;
83    }
84   
85    /**
86    * Compile a new pattern. Throws
87    *
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)
91    */
 
92  0 toggle public void compile(String s) throws RegSyntax
93    {
94  0 String npat = toFileRegex(s);
95  0 super.compile(npat);
96  0 if (File.separatorChar == '\\') // MS-DOS
97    {
98  0 ignoreCase = true;
99    }
100    }
101   
102    /**
103    * This is the method required by FileNameFilter. To get a listing of files in
104    * the current directory ending in .java, do this:
105    *
106    * <pre>
107    * File dot = new File(&quot;.&quot;);
108    *
109    * FileRegex java_files = new FileRegex(&quot;*.java&quot;);
110    *
111    * String[] file_list = dot.list(java_files);
112    * </pre>
113    */
 
114  0 toggle public boolean accept(File dir, String s)
115    {
116  0 if (dirflag != EITHER)
117    {
118  0 File f = new File(s);
119  0 if (f.isDirectory() && dirflag == NONDIR)
120    {
121  0 return false;
122    }
123  0 if (!f.isDirectory() && dirflag == DIR)
124    {
125  0 return false;
126    }
127    }
128  0 return matchAt(s, 0);
129    }
130   
131    int dirflag = 0;
132   
133    final static int EITHER = 0, DIR = 1, NONDIR = 2;
134   
135    /**
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.
144    */
 
145  0 toggle public static String[] list(String f)
146    {
147  0 return list(f, EITHER);
148    }
149   
 
150  0 toggle static String[] list(String f, int df)
151    {
152    // return list_(f,new FileRegex());
153  0 StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
154  0 Vector v = new Vector();
155  0 while (st.hasMoreTokens())
156    {
157  0 String path = st.nextToken();
158  0 list1(path, v, df, true);
159    }
160  0 String[] sa = new String[v.size()];
161  0 v.copyInto(sa);
162  0 return sa;
163    }
164   
165    final static Regex root = new Regex(File.separatorChar == '/' ? "/$"
166    : "(?:.:|)\\\\$");
167   
 
168  0 toggle static void list1(String path, Vector v, int df, boolean rec)
169    {
170    // if path looks like a/b/c/ or d:\ then add .
171  0 if (root.matchAt(path, 0))
172    {
173  0 v.addElement(path + ".");
174  0 return;
175    }
176  0 File f = new File(path);
177  0 if (f.getParent() != null && rec)
178    {
179  0 Vector v2 = new Vector();
180  0 list1(f.getParent(), v2, DIR, true);
181  0 for (int i = 0; i < v2.size(); i++)
182    {
183  0 String path2 = ((String) v2.elementAt(i)) + File.separator
184    + f.getName();
185  0 list1(path2, v, df, false);
186    }
187    }
188    else
189    {
190  0 File base = new File(path);
191   
192  0 String dir_s = base.getParent();
193  0 if (dir_s == null)
194    {
195  0 dir_s = ".";
196    }
197  0 File dir = new File(dir_s);
198   
199  0 FileRegex fr = new FileRegex(base.getName());
200  0 if (fr.isLiteral())
201    {
202  0 v.addElement(dir_s + File.separator + base.getName());
203  0 return;
204    }
205  0 fr.dirflag = df;
206  0 String[] sa = dir.list(fr);
207  0 if (sa == null)
208    {
209  0 return;
210    }
211  0 for (int i = 0; i < sa.length; i++)
212    {
213  0 v.addElement(dir_s + File.separator + sa[i]);
214    }
215    }
216    }
217   
218    /**
219    * This method takes a file regular expression, and translates it into the
220    * type of pattern used by a normal Regex.
221    */
 
222  0 toggle public static String toFileRegex(String s)
223    {
224  0 StrPos sp = new StrPos(s, 0);
225  0 StringBuffer sb = new StringBuffer();
226  0 if (sp.incMatch("{?e="))
227    {
228  0 char e = sp.thisChar();
229  0 sp.inc();
230  0 if (sp.incMatch("}"))
231    {
232  0 sb.append("(?e=" + e + ")^");
233    }
234    else
235    {
236  0 sb.append("^(?e=");
237    }
238  0 sp.esc = e;
239    }
240  0 int ParenLvl = 0;
241  0 while (!sp.eos())
242    {
243  0 if (File.separatorChar == '\\')
244    {
245  0 if (sp.escaped())
246    {
247  0 sb.append("\\\\");
248    }
249  0 sp.dontMatch = false;
250    }
251  0 if (sp.incMatch("?"))
252    {
253  0 sb.append(".");
254    }
255  0 else if (sp.incMatch("."))
256    {
257  0 sb.append(sp.esc);
258  0 sb.append('.');
259    }
260  0 else if (sp.incMatch("{??"))
261    {
262  0 sb.append("(??");
263  0 ParenLvl++;
264    // allow negative lookahead to work
265    }
266  0 else if (sp.incMatch("{?!"))
267    {
268  0 sb.append("(?!");
269  0 ParenLvl++;
270    // allow positive lookahead to work
271    }
272  0 else if (sp.incMatch("{?="))
273    {
274  0 sb.append("(?=");
275  0 ParenLvl++;
276    }
277  0 else if (sp.incMatch("{"))
278    {
279  0 sb.append("(?:");
280  0 ParenLvl++;
281    }
282  0 else if (sp.incMatch("}"))
283    {
284  0 sb.append(')');
285  0 ParenLvl--;
286    }
287  0 else if (ParenLvl != 0 && sp.incMatch(","))
288    {
289  0 sb.append('|');
290    }
291  0 else if (sp.incMatch("*"))
292    {
293  0 sb.append(".*");
294    }
295    else
296    {
297  0 sb.append(sp.thisChar());
298  0 sp.inc();
299    }
300    }
301  0 sb.append("$");
302  0 return sb.toString();
303    }
304   
 
305  0 toggle public boolean isLiteral()
306    {
307  0 Pattern x = thePattern;
308  0 while (x != null && !(x instanceof End))
309    {
310  0 if (x instanceof oneChar)
311    {
312  0 ;
313    }
314  0 else if (x instanceof Skipped)
315    {
316  0 ;
317    }
318    else
319    {
320  0 return false;
321    }
322  0 x = x.next;
323    }
324  0 return true;
325    }
326    }