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 }