Lines 41-46
Link Here
|
41 |
private String[] compilerInvocation; |
41 |
private String[] compilerInvocation; |
42 |
private GCCPerFileBOPConsoleParserUtility fUtil; |
42 |
private GCCPerFileBOPConsoleParserUtility fUtil; |
43 |
|
43 |
|
|
|
44 |
/* (non-Javadoc) |
45 |
* @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IPath, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector, org.eclipse.cdt.core.IMarkerGenerator) |
46 |
*/ |
44 |
public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { |
47 |
public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { |
45 |
fUtil = (project != null && workingDirectory != null && markerGenerator != null) ? |
48 |
fUtil = (project != null && workingDirectory != null && markerGenerator != null) ? |
46 |
new GCCPerFileBOPConsoleParserUtility(project, workingDirectory, markerGenerator) : null; |
49 |
new GCCPerFileBOPConsoleParserUtility(project, workingDirectory, markerGenerator) : null; |
Lines 50-59
Link Here
|
50 |
compilerInvocation = getCompilerCommands(); |
53 |
compilerInvocation = getCompilerCommands(); |
51 |
} |
54 |
} |
52 |
|
55 |
|
|
|
56 |
/* (non-Javadoc) |
57 |
* @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility() |
58 |
*/ |
53 |
protected AbstractGCCBOPConsoleParserUtility getUtility() { |
59 |
protected AbstractGCCBOPConsoleParserUtility getUtility() { |
54 |
return fUtil; |
60 |
return fUtil; |
55 |
} |
61 |
} |
56 |
|
62 |
|
|
|
63 |
/* (non-Javadoc) |
64 |
* @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String) |
65 |
*/ |
57 |
protected boolean processSingleLine(String line) { |
66 |
protected boolean processSingleLine(String line) { |
58 |
boolean rc = false; |
67 |
boolean rc = false; |
59 |
// GCC C/C++ compiler invocation |
68 |
// GCC C/C++ compiler invocation |
Lines 66-151
Link Here
|
66 |
if (compilerInvocationIndex == -1) |
75 |
if (compilerInvocationIndex == -1) |
67 |
return rc; |
76 |
return rc; |
68 |
|
77 |
|
69 |
// Search for the compiler invocation command |
78 |
// split and unquote all segments; supports build command such as |
70 |
|
79 |
// sh -c 'gcc -g -O0 -I"includemath" -I "include abc" -Iincludeprint -c impl/testmath.c' |
71 |
// expecting that compiler invocation is the first token in the line |
80 |
ArrayList split = splitLine(line, compilerInvocationIndex); |
72 |
String[] split = line.split("\\s+"); //$NON-NLS-1$ |
81 |
|
73 |
boolean found = false; |
82 |
// get the position of the compiler command in the build command |
74 |
for (int i = 0; i < split.length; ++i) { |
83 |
for (compilerInvocationIndex=0; compilerInvocationIndex<split.size(); compilerInvocationIndex++) { |
75 |
String command = split[i]; |
84 |
String command = (String)split.get(compilerInvocationIndex); |
76 |
// verify that it is compiler invocation |
85 |
// verify that it is compiler invocation |
|
|
86 |
int cii2 = -1; |
77 |
for (int cii = 0; cii < compilerInvocation.length; ++cii) { |
87 |
for (int cii = 0; cii < compilerInvocation.length; ++cii) { |
78 |
if (command.indexOf(compilerInvocation[cii]) >= 0) { |
88 |
cii2 = command.indexOf(compilerInvocation[cii]); |
79 |
found = true; |
89 |
if (cii2 >= 0) |
80 |
if (i > 0) { |
90 |
break; |
81 |
// strip off anything before the compiler command |
|
|
82 |
String[] old = split; |
83 |
split = new String[old.length - i]; |
84 |
System.arraycopy(old, i, split, 0, split.length); |
85 |
} |
86 |
break; |
87 |
} |
88 |
} |
91 |
} |
89 |
if (found) |
92 |
if (cii2 >= 0) |
90 |
break; |
93 |
break; |
91 |
} |
94 |
} |
92 |
if (!found) { |
95 |
if (compilerInvocationIndex >= split.size()) { |
93 |
TraceUtil.outputTrace("Error identifying compiler command", line, TraceUtil.EOL); //$NON-NLS-1$ |
96 |
TraceUtil.outputTrace("Error identifying compiler command", line, TraceUtil.EOL); //$NON-NLS-1$ |
94 |
return rc; |
97 |
return rc; |
95 |
} |
98 |
} |
96 |
|
|
|
97 |
// find a file name |
99 |
// find a file name |
98 |
int extensionsIndex = -1; |
100 |
int extensionsIndex = -1; |
99 |
found = false; |
101 |
boolean found = false; |
100 |
String filePath = null; |
102 |
String filePath = null; |
101 |
for (int i = 1; i < split.length; ++i) { |
103 |
for (int i = compilerInvocationIndex+1; i < split.size(); ++i) { |
102 |
int k = split[i].lastIndexOf('.'); |
104 |
String segment = (String)split.get(i); |
103 |
if (k != -1 && (split[i].length() - k < 5)) { |
105 |
int k = segment.lastIndexOf('.'); |
104 |
String fileExtension = split[i].substring(k); |
106 |
if (k != -1 && (segment.length() - k < 5)) { |
|
|
107 |
String fileExtension = segment.substring(k); |
105 |
extensionsIndex = FILE_EXTENSIONS_LIST.indexOf(fileExtension); |
108 |
extensionsIndex = FILE_EXTENSIONS_LIST.indexOf(fileExtension); |
106 |
if (extensionsIndex != -1) { |
109 |
if (extensionsIndex != -1) { |
107 |
filePath = split[i]; |
110 |
filePath = segment; |
108 |
found = true; |
111 |
found = true; |
109 |
break; |
112 |
break; |
110 |
} |
113 |
} |
111 |
} |
114 |
} |
112 |
} |
115 |
} |
113 |
|
116 |
// for (int j = 0; j < FILE_EXTENSIONS.length; ++j) { |
|
|
117 |
// if (split[i].endsWith(FILE_EXTENSIONS[j])) { |
118 |
// filePath = split[i]; |
119 |
// extensionsIndex = j; |
120 |
// found = true; |
121 |
// break; |
122 |
// } |
123 |
// } |
124 |
// if (found) break; |
114 |
if (!found) { |
125 |
if (!found) { |
115 |
TraceUtil.outputTrace("Error identifying file name :1", line, TraceUtil.EOL); //$NON-NLS-1$ |
126 |
TraceUtil.outputTrace("Error identifying file name :1", line, TraceUtil.EOL); //$NON-NLS-1$ |
116 |
return rc; |
127 |
return rc; |
117 |
} |
128 |
} |
118 |
|
|
|
119 |
// sanity check |
129 |
// sanity check |
120 |
if (filePath.indexOf(FILE_EXTENSIONS[extensionsIndex]) == -1) { |
130 |
if (filePath.indexOf(FILE_EXTENSIONS[extensionsIndex]) == -1) { |
121 |
TraceUtil.outputTrace("Error identifying file name :2", line, TraceUtil.EOL); //$NON-NLS-1$ |
131 |
TraceUtil.outputTrace("Error identifying file name :2", line, TraceUtil.EOL); //$NON-NLS-1$ |
122 |
return rc; |
132 |
return rc; |
123 |
} |
133 |
} |
124 |
|
|
|
125 |
if (fUtil != null) { |
134 |
if (fUtil != null) { |
126 |
IPath pFilePath = fUtil.getAbsolutePath(filePath); |
135 |
IPath pFilePath = fUtil.getAbsolutePath(filePath); |
127 |
String shortFileName = pFilePath.removeFileExtension().lastSegment(); |
136 |
String shortFileName = pFilePath.removeFileExtension().lastSegment(); |
128 |
|
137 |
|
129 |
// generalize occurances of the file name |
138 |
// generalize occurances of the file name |
130 |
StringBuffer genericLine = new StringBuffer(); |
139 |
for (int i = 0; i < split.size(); i++) { |
131 |
for (int i = 0; i < split.length; i++) { |
140 |
String token = (String)split.get(i); |
132 |
String token = split[i]; |
141 |
if (token.equals("-include")) { //$NON-NLS-1$ |
133 |
if (token.equals("-include") || token.equals("-imacros")) { //$NON-NLS-1$ //$NON-NLS-2$ |
142 |
++i; |
|
|
143 |
} |
144 |
else if (token.equals("-imacros")) { //$NON-NLS-1$ |
134 |
++i; |
145 |
++i; |
135 |
genericLine.append(token); |
|
|
136 |
genericLine.append(' '); |
137 |
} |
146 |
} |
138 |
else if (token.equals(filePath)) { |
147 |
else if (token.equals(filePath)) { |
139 |
split[i] = "LONG_NAME"; //$NON-NLS-1$ |
148 |
split.set(i, "LONG_NAME"); //$NON-NLS-1$ |
140 |
} |
149 |
} |
141 |
else if (token.startsWith(shortFileName)) { |
150 |
else if (token.startsWith(shortFileName)) { |
142 |
split[i] = token.replaceFirst(shortFileName, "SHORT_NAME"); //$NON-NLS-1$ |
151 |
split.set(i, token.replaceFirst(shortFileName, "SHORT_NAME")); //$NON-NLS-1$ |
143 |
} |
152 |
} |
144 |
genericLine.append(split[i]); |
|
|
145 |
genericLine.append(' '); |
146 |
} |
153 |
} |
147 |
|
154 |
|
148 |
CCommandDSC cmd = fUtil.getNewCCommandDSC(genericLine.toString(), extensionsIndex > 0); |
155 |
CCommandDSC cmd = fUtil.getNewCCommandDSC((String[])split.toArray(new String[split.size()]), extensionsIndex > 0); |
149 |
IPath baseDirectory = fUtil.getBaseDirectory(); |
156 |
IPath baseDirectory = fUtil.getBaseDirectory(); |
150 |
if (baseDirectory.isPrefixOf(pFilePath)) { |
157 |
if (baseDirectory.isPrefixOf(pFilePath)) { |
151 |
List cmdList = new ArrayList(); |
158 |
List cmdList = new ArrayList(); |
Lines 173-176
Link Here
|
173 |
return rc; |
180 |
return rc; |
174 |
} |
181 |
} |
175 |
|
182 |
|
|
|
183 |
/** |
184 |
* Splits and unquotes all compiler command segments; supports build command such as |
185 |
* sh -c 'gcc -g -O0 -I"includemath" -I "include abc" -Iincludeprint -c impl/testmath.c' |
186 |
*/ |
187 |
private ArrayList<String> splitLine(String line, int compilerInvocationIndex) { |
188 |
ArrayList<String> split = new ArrayList<String>(); |
189 |
boolean bSingleQuotes = false; |
190 |
boolean bIgnoreSingleQuotes = false; |
191 |
boolean bDoubleQuotes = false; |
192 |
boolean bIgnoreDoubleQuotes = false; |
193 |
char[] chars = line.toCharArray(); |
194 |
int charPos = 0; |
195 |
int length = line.length(); |
196 |
boolean quit = false; |
197 |
boolean acceptExtraSingleQuote = false; |
198 |
boolean acceptExtraDoubleQuote = false; |
199 |
|
200 |
// eat whitespace |
201 |
while (charPos < length) { |
202 |
char ch = chars[charPos]; |
203 |
if (!Character.isWhitespace(ch)) { |
204 |
break; |
205 |
} |
206 |
charPos++; |
207 |
} |
208 |
// read token |
209 |
while (charPos<length && !quit) { |
210 |
int startPos = -1; |
211 |
int endPos = -1; |
212 |
while (charPos<length && !quit) { |
213 |
char ch = chars[charPos]; |
214 |
if (ch == '\'') { |
215 |
// ignore quotes before the actual compiler command (the command itself including its options |
216 |
// could be within quotes--in this case we nevertheless want to split the compiler command into segments) |
217 |
if (charPos <= compilerInvocationIndex) { |
218 |
bIgnoreSingleQuotes = !bIgnoreSingleQuotes; |
219 |
} |
220 |
else { |
221 |
if (bIgnoreSingleQuotes) { |
222 |
bIgnoreSingleQuotes = false; |
223 |
if (startPos >= 0) { |
224 |
endPos = charPos; // end of a token |
225 |
} |
226 |
quit = true; // quit after closed quote containing the actual compiler command |
227 |
} |
228 |
else { |
229 |
bSingleQuotes = !bSingleQuotes; |
230 |
} |
231 |
} |
232 |
// do split token here: allow -DMYKEY='MYVALUE' or-DMYKEY=\'MYVALUE\' |
233 |
if (startPos >= 0) { |
234 |
char prevch = charPos > 0 ? chars[charPos-1] : '\0'; |
235 |
if (acceptExtraSingleQuote) { |
236 |
acceptExtraSingleQuote = false; |
237 |
} |
238 |
else if (prevch != '=' && prevch != '\\') { |
239 |
endPos = charPos; // end of a token |
240 |
} |
241 |
else { |
242 |
acceptExtraSingleQuote = true; |
243 |
} |
244 |
} |
245 |
} |
246 |
else if (ch == '"') { |
247 |
// ignore quotes before the actual compiler command (the command itself including its options |
248 |
// could be within quotes--in this case we nevertheless want to split the compiler command into segments) |
249 |
if (charPos <= compilerInvocationIndex) { |
250 |
bIgnoreDoubleQuotes = !bIgnoreDoubleQuotes; |
251 |
} |
252 |
else { |
253 |
if (bIgnoreDoubleQuotes) { |
254 |
bIgnoreDoubleQuotes = false; |
255 |
if (startPos >= 0) { |
256 |
endPos = charPos; // end of a token |
257 |
} |
258 |
quit = true; // quit after closed quote containing the actual compiler command |
259 |
} |
260 |
else { |
261 |
bDoubleQuotes = !bDoubleQuotes; |
262 |
} |
263 |
} |
264 |
// do split token here: allow -DMYKEY="MYVALUE" or-DMYKEY=\"MYVALUE\" |
265 |
if (startPos >= 0) { |
266 |
char prevch = charPos > 0 ? chars[charPos-1] : '\0'; |
267 |
if (acceptExtraDoubleQuote) { |
268 |
acceptExtraDoubleQuote = false; |
269 |
} |
270 |
else if (prevch != '=' && prevch != '\\') { |
271 |
endPos = charPos; // end of a token |
272 |
} |
273 |
else { |
274 |
acceptExtraDoubleQuote = true; |
275 |
} |
276 |
} |
277 |
} |
278 |
else if (Character.isWhitespace(ch) || ch == ';') { |
279 |
if (startPos < 0 && (bSingleQuotes || bDoubleQuotes)) { |
280 |
startPos = charPos; |
281 |
} |
282 |
else if (startPos >= 0 && !bSingleQuotes && !bDoubleQuotes) { |
283 |
endPos = charPos; // end of a token |
284 |
} |
285 |
} |
286 |
else { // a valid character, starts or continues a token |
287 |
if (startPos < 0) { |
288 |
startPos = charPos; |
289 |
} |
290 |
if (charPos == length-1) { |
291 |
endPos = charPos+1; // end of token |
292 |
} |
293 |
} |
294 |
charPos++; |
295 |
// a complete token has been found |
296 |
if (startPos >= 0 && endPos > startPos) { |
297 |
break; |
298 |
} |
299 |
} |
300 |
if (startPos >= 0 && endPos >= 0 && startPos >= compilerInvocationIndex) { |
301 |
split.add(line.substring(startPos, endPos)); |
302 |
} |
303 |
} |
304 |
return split; |
305 |
} |
176 |
} |
306 |
} |