1 /*******************************************************************************
2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $(date) The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
20 *******************************************************************************/
22 // This software is now distributed according to
23 // the Lesser Gnu Public License. Please see
24 // http://www.gnu.org/copyleft/lesser.txt for
26 // -- Happy Computing!
28 package com.stevesoft.pat;
31 import java.util.StringTokenizer;
32 import java.util.Vector;
35 * This class is a different form of Regex designed to work more like the file
36 * matching utility of a Unix shell. It is implemented by some simple string
37 * transformations: <center>
70 * </center> Note that a FileRegex pattern always ends with the Regex pattern
71 * element "$". If you like to experiment, try making FileRegex's and then
72 * printing them out. The toString() method does a decompile of the pattern to a
73 * standard Regex. Here are some more complete examples: <center>
82 * <td>*.{java,html}</td>
83 * <td>.*\.(java|html)$</td>
90 public class FileRegex extends Regex
92 /** Build an unitialized FileRegex. */
98 /** Build a FileRegex form String s. */
99 public FileRegex(String s)
106 * Compile a new pattern. Throws
108 * @exception com.stevesoft.pat.RegSyntax
109 * for nonsensical patterns like "[9-0]+" just as Regex does.
110 * @see com.stevesoft.pat#compile(java.lang.String)
112 public void compile(String s) throws RegSyntax
114 String npat = toFileRegex(s);
116 if (File.separatorChar == '\\') // MS-DOS
123 * This is the method required by FileNameFilter. To get a listing of files in
124 * the current directory ending in .java, do this:
127 * File dot = new File(".");
129 * FileRegex java_files = new FileRegex("*.java");
131 * String[] file_list = dot.list(java_files);
134 public boolean accept(File dir, String s)
136 if (dirflag != EITHER)
138 File f = new File(s);
139 if (f.isDirectory() && dirflag == NONDIR)
143 if (!f.isDirectory() && dirflag == DIR)
148 return matchAt(s, 0);
153 final static int EITHER = 0, DIR = 1, NONDIR = 2;
156 * Provides an alternative to File.list -- this separates its argument
157 * according to File.pathSeparator. To each path, it splits off a directory --
158 * all characters up to and including the first instance of File.separator --
159 * and a file pattern -- the part that comes after the directory. It then
160 * produces a list of all the pattern matches on all the paths. Thus
161 * "*.java:../*.java" would produce a list of all the java files in this
162 * directory and in the ".." directory on a Unix machine. "*.java;..\\*.java"
163 * would do the same thing on a Dos machine.
165 public static String[] list(String f)
167 return list(f, EITHER);
170 static String[] list(String f, int df)
172 // return list_(f,new FileRegex());
173 StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
174 Vector v = new Vector();
175 while (st.hasMoreTokens())
177 String path = st.nextToken();
178 list1(path, v, df, true);
180 String[] sa = new String[v.size()];
185 final static Regex root = new Regex(File.separatorChar == '/' ? "/$"
188 static void list1(String path, Vector v, int df, boolean rec)
190 // if path looks like a/b/c/ or d:\ then add .
191 if (root.matchAt(path, 0))
193 v.addElement(path + ".");
196 File f = new File(path);
197 if (f.getParent() != null && rec)
199 Vector v2 = new Vector();
200 list1(f.getParent(), v2, DIR, true);
201 for (int i = 0; i < v2.size(); i++)
203 String path2 = ((String) v2.elementAt(i)) + File.separator
205 list1(path2, v, df, false);
210 File base = new File(path);
212 String dir_s = base.getParent();
217 File dir = new File(dir_s);
219 FileRegex fr = new FileRegex(base.getName());
222 v.addElement(dir_s + File.separator + base.getName());
226 String[] sa = dir.list(fr);
231 for (int i = 0; i < sa.length; i++)
233 v.addElement(dir_s + File.separator + sa[i]);
239 * This method takes a file regular expression, and translates it into the
240 * type of pattern used by a normal Regex.
242 public static String toFileRegex(String s)
244 StrPos sp = new StrPos(s, 0);
245 StringBuffer sb = new StringBuffer();
246 if (sp.incMatch("{?e="))
248 char e = sp.thisChar();
250 if (sp.incMatch("}"))
252 sb.append("(?e=" + e + ")^");
263 if (File.separatorChar == '\\')
269 sp.dontMatch = false;
271 if (sp.incMatch("?"))
275 else if (sp.incMatch("."))
280 else if (sp.incMatch("{??"))
284 // allow negative lookahead to work
286 else if (sp.incMatch("{?!"))
290 // allow positive lookahead to work
292 else if (sp.incMatch("{?="))
297 else if (sp.incMatch("{"))
302 else if (sp.incMatch("}"))
307 else if (ParenLvl != 0 && sp.incMatch(","))
311 else if (sp.incMatch("*"))
317 sb.append(sp.thisChar());
322 return sb.toString();
325 public boolean isLiteral()
327 Pattern x = thePattern;
328 while (x != null && !(x instanceof End))
330 if (x instanceof oneChar)
334 else if (x instanceof Skipped)