Mercurial > hg > Members > kono > jpf-core
comparison src/main/gov/nasa/jpf/util/LocationSpec.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 | |
19 package gov.nasa.jpf.util; | |
20 | |
21 import java.io.File; | |
22 | |
23 /** | |
24 * support for specification of source locations | |
25 * | |
26 * This maps sourcefile:line1-range strings into instructions that can be efficiently | |
27 * checked for by listeners. Example formats are: | |
28 * | |
29 * X.java (the whole of file X.java) | |
30 * MyClass.java:42 (file MyClass.java, line1 42) | |
31 * FooBar.java:42-48 (file FooBar.java, lines 42 to 48) | |
32 * FooBar.java:42+3 (range of lines from 42 to 45) | |
33 * x/y/z/whatever:42+ (file with pathname x/y/z/whatever, lines 42 to end) | |
34 * | |
35 * | |
36 * NOTE path names are given in Unix notation, to avoid the usual Java string | |
37 * quoting problem with backslashes | |
38 */ | |
39 public class LocationSpec { | |
40 | |
41 public static final int ANYLINE = -1; | |
42 | |
43 protected StringMatcher pathSpec; | |
44 protected StringMatcher fileSpec; | |
45 protected int fromLine = ANYLINE; // inclusive | |
46 protected int toLine = ANYLINE; // inclusive | |
47 | |
48 /** | |
49 * factory method that includes the parser | |
50 */ | |
51 public static LocationSpec createLocationSpec (String s){ | |
52 s = s.replace('\\', '/'); | |
53 | |
54 String pspec = null, fspec; | |
55 int line1 = -1, line2 = -1; | |
56 | |
57 int idx = s.lastIndexOf(':'); | |
58 // check if it is just a dreaded "drive letter" | |
59 if (idx == s.length()-1 || s.charAt(idx + 1) == '/') { | |
60 idx = -1; | |
61 } | |
62 | |
63 if (idx < 0){ // no line1 spec | |
64 fspec = s.trim(); | |
65 | |
66 } else if (idx > 0){ // line1 spec present | |
67 fspec = s.substring(0, idx).trim(); | |
68 | |
69 // now get the line1 (range) | |
70 s = s.substring(idx+1).trim(); | |
71 int len = s.length(); | |
72 | |
73 if (len > 0){ | |
74 int i = 0; | |
75 for (; i < len; i++) { | |
76 char c = s.charAt(i); | |
77 if (c == '-' || c == '+') { | |
78 line1 = Integer.parseInt(s.substring(0, i)); | |
79 | |
80 if (i == len - 1) { // open interval | |
81 line2 = Integer.MAX_VALUE; | |
82 } else { | |
83 line2 = Integer.parseInt(s.substring(i + 1)); | |
84 if (c == '+') { | |
85 line2 = line1 + line2; | |
86 } | |
87 } | |
88 break; | |
89 } | |
90 } | |
91 | |
92 if (i == len) { // single line | |
93 line1 = Integer.parseInt(s); | |
94 } | |
95 } | |
96 | |
97 } else { | |
98 throw new RuntimeException("no filename in LocationSpec: " + s); | |
99 } | |
100 | |
101 idx = fspec.lastIndexOf('/'); | |
102 if (idx > 0){ | |
103 pspec = fspec.substring(0, idx); | |
104 fspec = fspec.substring(idx+1); | |
105 } else if (idx == 0){ | |
106 pspec = "/"; | |
107 fspec = fspec.substring(1); | |
108 } else { | |
109 pspec = null; | |
110 } | |
111 | |
112 return new LocationSpec(pspec, fspec, line1, line2); | |
113 } | |
114 | |
115 public LocationSpec (String pspec, String fspec, int line1, int line2){ | |
116 if (pspec != null){ | |
117 pathSpec = new StringMatcher(pspec); | |
118 } | |
119 fileSpec = new StringMatcher(fspec); | |
120 | |
121 fromLine = line1; | |
122 toLine = line2; | |
123 } | |
124 | |
125 @Override | |
126 public String toString(){ | |
127 StringBuilder sb = new StringBuilder(); | |
128 | |
129 if (pathSpec != null){ | |
130 sb.append(pathSpec); | |
131 sb.append('/'); | |
132 } | |
133 | |
134 sb.append(fileSpec); | |
135 | |
136 if (fromLine != ANYLINE){ | |
137 sb.append(':'); | |
138 sb.append(fromLine); | |
139 } | |
140 if (toLine != ANYLINE){ | |
141 sb.append('-'); | |
142 if (toLine != Integer.MAX_VALUE){ | |
143 sb.append(toLine); | |
144 } | |
145 } | |
146 | |
147 return sb.toString(); | |
148 } | |
149 | |
150 public boolean matchesFile (File f){ | |
151 if (fileSpec.matches(f.getName())){ | |
152 if (pathSpec != null){ | |
153 String pspec = f.getParent(); | |
154 pspec = pspec.replace('\\', '/'); // use Unix '/' to avoid quoting issue | |
155 | |
156 return pathSpec.matches(pspec); | |
157 | |
158 } else { // no path | |
159 return true; | |
160 } | |
161 } | |
162 | |
163 return false; | |
164 } | |
165 | |
166 public boolean isAnyLine(){ | |
167 return fromLine == ANYLINE; | |
168 } | |
169 | |
170 public boolean isLineInterval(){ | |
171 return toLine != ANYLINE; | |
172 } | |
173 | |
174 public int getLine(){ // for specs that are single locations | |
175 return fromLine; | |
176 } | |
177 | |
178 public int getFromLine() { | |
179 return fromLine; | |
180 } | |
181 | |
182 // note - this is < 0 if there was only a | |
183 public int getToLine() { | |
184 if (toLine < 0){ | |
185 if (fromLine >= 0){ | |
186 return fromLine; | |
187 } | |
188 } | |
189 | |
190 return toLine; | |
191 } | |
192 | |
193 /** | |
194 * 'pathName' has to use '/' as separators | |
195 */ | |
196 public boolean matchesFile (String pathName){ | |
197 if (pathName != null){ | |
198 pathName = pathName.replace('\\', '/'); | |
199 int idx = pathName.lastIndexOf('/'); | |
200 | |
201 if (idx >= 0) { | |
202 String fname = pathName.substring(idx + 1); | |
203 | |
204 if (fileSpec.matches(fname)) { | |
205 if (pathSpec != null) { | |
206 String pname = idx > 0 ? pathName.substring(0, idx) : "/"; | |
207 return pathSpec.matches(pname); | |
208 } else { | |
209 return true; | |
210 } | |
211 } | |
212 | |
213 } else { // no path | |
214 return fileSpec.matches(pathName); | |
215 } | |
216 } | |
217 | |
218 return false; | |
219 } | |
220 | |
221 public boolean includesLine (int line){ | |
222 if (fromLine == ANYLINE){ | |
223 return true; | |
224 | |
225 } else { | |
226 if (fromLine == line){ | |
227 return true; | |
228 } else if (fromLine < line){ | |
229 if (toLine == ANYLINE){ // single location | |
230 return false; | |
231 } else { | |
232 return (line <= toLine); | |
233 } | |
234 } | |
235 } | |
236 | |
237 return false; | |
238 } | |
239 } |