14 * Description: |
14 * Description: |
15 * |
15 * |
16 */ |
16 */ |
17 package com.nokia.carbide.cdt.builder.builder; |
17 package com.nokia.carbide.cdt.builder.builder; |
18 |
18 |
19 import java.io.IOException; |
19 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin; |
20 import java.util.Properties; |
20 |
21 |
21 import org.eclipse.cdt.core.*; |
22 import org.eclipse.cdt.core.CCorePlugin; |
|
23 import org.eclipse.cdt.core.CommandLauncher; |
|
24 import org.eclipse.cdt.core.ConsoleOutputStream; |
|
25 import org.eclipse.cdt.core.ErrorParserManager; |
|
26 import org.eclipse.cdt.core.IMarkerGenerator; |
|
27 import org.eclipse.cdt.core.ProblemMarkerInfo; |
|
28 import org.eclipse.cdt.core.model.ICModelMarker; |
22 import org.eclipse.cdt.core.model.ICModelMarker; |
29 import org.eclipse.cdt.core.resources.IConsole; |
23 import org.eclipse.cdt.core.resources.IConsole; |
30 import org.eclipse.cdt.ui.CUIPlugin; |
24 import org.eclipse.cdt.ui.CUIPlugin; |
31 import org.eclipse.cdt.utils.spawner.EnvironmentReader; |
25 import org.eclipse.cdt.utils.spawner.EnvironmentReader; |
32 import org.eclipse.core.resources.IMarker; |
26 import org.eclipse.core.internal.resources.MarkerInfo; |
33 import org.eclipse.core.resources.IProject; |
27 import org.eclipse.core.internal.resources.Workspace; |
34 import org.eclipse.core.resources.IResource; |
28 import org.eclipse.core.resources.*; |
35 import org.eclipse.core.runtime.CoreException; |
29 import org.eclipse.core.runtime.*; |
36 import org.eclipse.core.runtime.IPath; |
30 |
37 import org.eclipse.core.runtime.IProgressMonitor; |
31 import java.io.IOException; |
38 import org.eclipse.core.runtime.Path; |
32 import java.util.*; |
39 import org.eclipse.core.runtime.SubProgressMonitor; |
|
40 |
|
41 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin; |
|
42 |
33 |
43 /** |
34 /** |
44 * A utility class to handle windows process execution. This utility class handles all the execution, |
35 * A utility class to handle windows process execution. This utility class handles all the execution, |
45 * error processing, and console output. |
36 * error processing, and console output. |
46 */ |
37 */ |
47 public class CarbideCommandLauncher extends CommandLauncher implements IMarkerGenerator { |
38 public class CarbideCommandLauncher extends CommandLauncher implements IMarkerGenerator { |
|
39 |
|
40 public class MarkerCacheElement { |
|
41 private int line; |
|
42 private int severity; |
|
43 private String message; |
|
44 |
|
45 public MarkerCacheElement(IMarker marker) throws CoreException { |
|
46 line = marker.getAttribute(IMarker.LINE_NUMBER, -1); |
|
47 severity = ((Integer) marker.getAttribute(IMarker.SEVERITY)).intValue(); |
|
48 message = (String) marker.getAttribute(IMarker.MESSAGE); |
|
49 } |
|
50 |
|
51 public MarkerCacheElement(ProblemMarkerInfo problemMarkerInfo) { |
|
52 line = problemMarkerInfo.lineNumber; |
|
53 severity = mapMarkerSeverity(problemMarkerInfo.severity); |
|
54 message = problemMarkerInfo.description; |
|
55 } |
|
56 |
|
57 @Override |
|
58 public int hashCode() { |
|
59 final int prime = 31; |
|
60 int result = 1; |
|
61 result = prime * result + line; |
|
62 result = prime * result + severity; |
|
63 result = prime * result |
|
64 + ((message == null) ? 0 : message.hashCode()); |
|
65 return result; |
|
66 } |
|
67 |
|
68 @Override |
|
69 public boolean equals(Object obj) { |
|
70 if (!(obj instanceof MarkerCacheElement)) |
|
71 return false; |
|
72 MarkerCacheElement other = (MarkerCacheElement) obj; |
|
73 if (line != other.line) |
|
74 return false; |
|
75 if (severity != other.severity) |
|
76 return false; |
|
77 if (message == null) { |
|
78 if (other.message != null) |
|
79 return false; |
|
80 } |
|
81 else if (!message.equals(other.message)) |
|
82 return false; |
|
83 return true; |
|
84 } |
|
85 } |
48 |
86 |
49 protected IProgressMonitor monitor; |
87 protected IProgressMonitor monitor; |
50 protected IConsole console; |
88 protected IConsole console; |
51 protected ErrorParserManager stdoutStream; |
89 protected ErrorParserManager stdoutStream; |
52 protected ErrorParserManager stderrStream; |
90 protected ErrorParserManager stderrStream; |
210 * @param env - Full list of environment variables |
250 * @param env - Full list of environment variables |
211 * @param workingDir - The current working directory the command is to be invoked in. |
251 * @param workingDir - The current working directory the command is to be invoked in. |
212 * @return 0 (zero) on success. returns the actual tool return status |
252 * @return 0 (zero) on success. returns the actual tool return status |
213 */ |
253 */ |
214 public int executeCommand(IPath command, String[] args, String[] env, IPath workingDir){ |
254 public int executeCommand(IPath command, String[] args, String[] env, IPath workingDir){ |
|
255 markerCache = null; |
|
256 markerCreationTime = System.currentTimeMillis(); |
215 int exitValue = -1; |
257 int exitValue = -1; |
216 String errMsg; |
258 String errMsg; |
217 try { |
259 try { |
218 |
260 |
219 Process proc = execute(command, args, env, workingDir); |
261 Process proc = execute(command, args, env, workingDir); |
297 ProblemMarkerInfo info = new ProblemMarkerInfo(file, lineNumber, errorDesc, severity, errorVar); |
339 ProblemMarkerInfo info = new ProblemMarkerInfo(file, lineNumber, errorDesc, severity, errorVar); |
298 addMarker(info); |
340 addMarker(info); |
299 } |
341 } |
300 |
342 |
301 public void addMarker(ProblemMarkerInfo problemMarkerInfo) { |
343 public void addMarker(ProblemMarkerInfo problemMarkerInfo) { |
302 |
344 if (markerCache == null) |
|
345 markerCache = new HashMap<IResource, Set<MarkerCacheElement>>(); |
|
346 |
303 try { |
347 try { |
304 IResource markerResource = problemMarkerInfo.file ; |
348 IResource markerResource = problemMarkerInfo.file ; |
305 if (markerResource == null) { |
349 if (markerResource == null) { |
306 markerResource = stdoutStream.getProject(); |
350 markerResource = stdoutStream.getProject(); |
307 } |
351 } |
308 IMarker[] cur = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE); |
352 |
309 |
353 Set<MarkerCacheElement> cacheElements = markerCache.get(markerResource); |
310 /* |
354 if (cacheElements == null) { |
311 * Try to find matching markers and don't put in duplicates |
355 cacheElements = new HashSet<MarkerCacheElement>(); |
312 */ |
356 markerCache.put(markerResource, cacheElements); |
313 if ((cur != null) && (cur.length > 0)) { |
357 IMarker[] cur = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE); |
314 for (int i = 0; i < cur.length; i++) { |
358 for (IMarker marker : cur) { |
315 int line = cur[i].getAttribute(IMarker.LINE_NUMBER, -1); |
359 cacheElements.add(new MarkerCacheElement(marker)); |
316 int sev = ((Integer) cur[i].getAttribute(IMarker.SEVERITY)).intValue(); |
|
317 String mesg = (String) cur[i].getAttribute(IMarker.MESSAGE); |
|
318 if (line == problemMarkerInfo.lineNumber && sev == mapMarkerSeverity(problemMarkerInfo.severity) && mesg.equals(problemMarkerInfo.description)) { |
|
319 return; |
|
320 } |
|
321 } |
360 } |
322 } |
361 } |
323 |
362 |
324 // need to pause briefly between marker creations so the creation timestamps |
363 if (!cacheElements.add(new MarkerCacheElement(problemMarkerInfo))) |
325 // are unique and sorting the problems view by creation time works properly. |
364 return; |
326 try { |
|
327 Thread.sleep(20); |
|
328 } catch (InterruptedException e1) { |
|
329 e1.printStackTrace(); |
|
330 } |
|
331 |
365 |
332 IMarker marker = markerResource.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER); |
366 IMarker marker = markerResource.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER); |
333 marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description); |
367 marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description); |
334 marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity)); |
368 marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity)); |
335 marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber); |
369 marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber); |
354 CarbideBuilderPlugin.log(e); |
388 CarbideBuilderPlugin.log(e); |
355 e.printStackTrace(); |
389 e.printStackTrace(); |
356 } |
390 } |
357 marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, absolutePath.toOSString()); |
391 marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, absolutePath.toOSString()); |
358 } |
392 } |
|
393 setUniqueCreationTime(marker); |
359 } |
394 } |
360 catch (CoreException e) { |
395 catch (CoreException e) { |
361 CCorePlugin.log(e.getStatus()); |
396 CCorePlugin.log(e.getStatus()); |
362 } |
397 } |
363 |
398 |
364 } |
399 } |
365 |
400 |
|
401 private void setUniqueCreationTime(IMarker marker) { |
|
402 // This is using internal platform APIs to avoid putting a delay into every marker creation |
|
403 // to ensure each marker gets a unique creation time (for sorting in the problems view). |
|
404 // The total delay could be significant when there are many problem markers |
|
405 IResource resource = marker.getResource(); |
|
406 Workspace workspace = (Workspace) resource.getWorkspace(); |
|
407 MarkerInfo markerInfo = workspace.getMarkerManager().findMarkerInfo(resource, marker.getId()); |
|
408 markerInfo.setCreationTime(markerCreationTime++); |
|
409 } |
|
410 |
366 int mapMarkerSeverity(int severity) { |
411 int mapMarkerSeverity(int severity) { |
367 |
412 |
368 switch (severity) { |
413 switch (severity) { |
369 case SEVERITY_ERROR_BUILD : |
414 case SEVERITY_ERROR_BUILD : |
370 case SEVERITY_ERROR_RESOURCE : |
415 case SEVERITY_ERROR_RESOURCE : |