Mercurial > hg > Members > kono > jpf-core
comparison src/main/gov/nasa/jpf/util/PathnameExpander.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:61d41facf527 |
---|---|
1 /* | |
2 * Copyright (C) 2014, United States Government, as represented by the | |
3 * Administrator of the National Aeronautics and Space Administration. | |
4 * All rights reserved. | |
5 * | |
6 * The Java Pathfinder core (jpf-core) platform is licensed under the | |
7 * Apache License, Version 2.0 (the "License"); you may not use this file except | |
8 * in compliance with the License. You may obtain a copy of the License at | |
9 * | |
10 * http://www.apache.org/licenses/LICENSE-2.0. | |
11 * | |
12 * Unless required by applicable law or agreed to in writing, software | |
13 * distributed under the License is distributed on an "AS IS" BASIS, | |
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 * See the License for the specific language governing permissions and | |
16 * limitations under the License. | |
17 */ | |
18 package gov.nasa.jpf.util; | |
19 | |
20 import java.io.File; | |
21 import java.util.ArrayList; | |
22 import java.util.regex.Matcher; | |
23 import java.util.regex.Pattern; | |
24 | |
25 /** | |
26 * utility to perform pathname expansion | |
27 * the following patterns are supported so far: | |
28 * | |
29 * (1) brace expansion ala bash: foo{Boo,Shoo} => fooBoo, fooShoo | |
30 * (this doesn't check for existence, its simply lexical) | |
31 * | |
32 * (2) '*' wildcard pathname expansion ala bash: "*.java" | "*\Main*.java" | |
33 * (supports wildcards in mutiple path elements and within file/dir name) | |
34 * | |
35 * (3) recursive dir expansion ala Ant: "**\*.jar" | |
36 * | |
37 */ | |
38 public class PathnameExpander { | |
39 | |
40 public String[] expandPath (String s) { | |
41 if (s == null || s.length() == 0) { | |
42 return null; | |
43 } | |
44 | |
45 boolean hasWildcards = (s.indexOf('*') >= 0); | |
46 | |
47 int i = s.indexOf('{'); | |
48 if (i >= 0){ | |
49 ArrayList<String> list = new ArrayList<String>(); | |
50 | |
51 int j=0, jLast = s.length(); | |
52 for (; (i = s.indexOf('{', j)) >= 0;) { | |
53 if ((j = s.indexOf('}', i)) > 0) { | |
54 String[] choices = s.substring(i + 1, j).split(","); | |
55 | |
56 if (list.isEmpty()) { | |
57 String prefix = s.substring(0, i); | |
58 for (String c : choices) { | |
59 list.add(prefix + c); | |
60 } | |
61 } else { | |
62 String prefix = s.substring(jLast, i); | |
63 ArrayList<String> newList = new ArrayList<String>(); | |
64 for (String e : list) { | |
65 for (String c : choices) { | |
66 newList.add(e + prefix + c); | |
67 } | |
68 } | |
69 list = newList; | |
70 } | |
71 jLast = j+1; | |
72 } else { | |
73 throw new IllegalArgumentException("illegal path spec (missing '}'): " + s); | |
74 } | |
75 } | |
76 | |
77 if (jLast < s.length()) { | |
78 String postfix = s.substring(jLast); | |
79 ArrayList<String> newList = new ArrayList<String>(); | |
80 for (String e : list) { | |
81 newList.add(e + postfix); | |
82 } | |
83 list = newList; | |
84 } | |
85 | |
86 if (hasWildcards){ | |
87 ArrayList<String> newList = new ArrayList<String>(); | |
88 for (String p : list) { | |
89 for (String c : expandWildcards(p)) { | |
90 newList.add(c); | |
91 } | |
92 } | |
93 list = newList; | |
94 } | |
95 | |
96 return list.toArray(new String[list.size()]); | |
97 | |
98 } else { // no bracket expansion required | |
99 | |
100 if (hasWildcards){ | |
101 return expandWildcards(s); | |
102 | |
103 } else { // nothing to expand at all | |
104 return (new String[] {s}); | |
105 } | |
106 } | |
107 } | |
108 | |
109 protected String[] expandWildcards (String s){ | |
110 int i = s.indexOf('*'); | |
111 | |
112 if (i >= 0){ // Ok, we have at least one wildcard | |
113 String[] a = s.split("\\/"); | |
114 ArrayList<File> list = new ArrayList<File>(); | |
115 | |
116 int j= initializeMatchList(list, a[0]); | |
117 for (; j<a.length; j++){ | |
118 ArrayList<File> newList = new ArrayList<File>(); | |
119 | |
120 String e = a[j]; | |
121 if (e.indexOf('*') >= 0){ | |
122 | |
123 if (e.equals("**")){ // matches all subdirs recursively | |
124 collectDirs(list, newList); | |
125 | |
126 } else { // file/dir name match | |
127 collectMatchingNames(list, newList, getPattern(e)); | |
128 } | |
129 | |
130 } else { // no wildcard | |
131 collectExistingFile(list, newList, e); | |
132 } | |
133 | |
134 if (newList.isEmpty()){ // shortcut, nothing more to match | |
135 return new String[0]; | |
136 } | |
137 list = newList; | |
138 } | |
139 | |
140 return getPaths(list); | |
141 | |
142 } else { // no wildcards, nothing to expand | |
143 return new String[] {s}; | |
144 } | |
145 } | |
146 | |
147 private int initializeMatchList (ArrayList<File> list, String path){ | |
148 if (path.isEmpty()){ // absolute pathname (ignoring drive letters for now) | |
149 list.add(new File(File.separator)); | |
150 return 1; | |
151 } else if (path.equals("..") || path.equals(".")){ | |
152 list.add(new File(path)); | |
153 return 1; | |
154 } else { | |
155 list.add(new File(".")); | |
156 return 0; | |
157 } | |
158 } | |
159 | |
160 private void collectMatchingNames(ArrayList<File> list, ArrayList<File> newList, Pattern pattern){ | |
161 for (File dir : list) { | |
162 if (dir.isDirectory()){ | |
163 for (String c : dir.list()){ | |
164 Matcher m = pattern.matcher(c); | |
165 if (m.matches()){ | |
166 newList.add(new File(dir,c)); | |
167 } | |
168 } | |
169 } | |
170 } | |
171 } | |
172 | |
173 private void collectExistingFile(ArrayList<File> list, ArrayList<File> newList, String fname) { | |
174 for (File dir : list) { | |
175 if (dir.isDirectory()){ | |
176 File nf = new File(dir, fname); | |
177 if (nf.exists()) { | |
178 newList.add(nf); | |
179 } | |
180 } | |
181 } | |
182 } | |
183 | |
184 private void collectDirs(ArrayList<File> list, ArrayList<File> newList){ | |
185 for (File dir : list) { | |
186 if (dir.isDirectory()){ | |
187 newList.add(dir); // this includes the dir itself! | |
188 collectSubdirs(newList,dir); | |
189 } | |
190 } | |
191 } | |
192 private void collectSubdirs(ArrayList<File> newList, File dir) { | |
193 for (File f : dir.listFiles()){ | |
194 if (f.isDirectory()){ | |
195 newList.add(f); | |
196 collectSubdirs(newList, f); | |
197 } | |
198 } | |
199 } | |
200 | |
201 protected String[] getPaths(ArrayList<File> list) { | |
202 String[] result = new String[list.size()]; | |
203 int k=0; | |
204 for (File f : list){ | |
205 String p = f.getPath(); | |
206 if ((p.length() > 1) && (p.charAt(0) == '.')){ // remove leading "./" | |
207 char c = p.charAt(1); | |
208 if (c == '\\' || c == '/'){ | |
209 p = p.substring(2); | |
210 } | |
211 } | |
212 result[k++] = p; | |
213 } | |
214 return result; | |
215 } | |
216 | |
217 protected Pattern getPattern(String s){ | |
218 Pattern p; | |
219 | |
220 StringBuilder sb = new StringBuilder(); | |
221 | |
222 int len = s.length(); | |
223 for (int j=0; j<len; j++){ | |
224 char c = s.charAt(j); | |
225 switch (c){ | |
226 case '.' : sb.append("\\."); break; | |
227 case '$' : sb.append("\\$"); break; | |
228 case '[' : sb.append("\\["); break; | |
229 case ']' : sb.append("\\]"); break; | |
230 case '*' : sb.append(".*"); break; | |
231 // <2do> and probably more.. | |
232 default: sb.append(c); | |
233 } | |
234 } | |
235 | |
236 p = Pattern.compile(sb.toString()); | |
237 return p; | |
238 } | |
239 } |