Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Sennikovsky2007-03-06 18:48:55 +0000
committerMikhail Sennikovsky2007-03-06 18:48:55 +0000
commit6524989ba78457a202af744c22008c53ccad4e9f (patch)
tree922dfe896b75ab331dc66fecbb37a265cb302a1a /build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig
parent99affdf6462618d31cea71ef9fc79d145f84db0f (diff)
downloadorg.eclipse.cdt-6524989ba78457a202af744c22008c53ccad4e9f.tar.gz
org.eclipse.cdt-6524989ba78457a202af744c22008c53ccad4e9f.tar.xz
org.eclipse.cdt-6524989ba78457a202af744c22008c53ccad4e9f.zip
1. Build System Backward Compatibility
Diffstat (limited to 'build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig')
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java89
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java209
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInitializer.java47
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java354
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredScannerInfoStore.java437
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/PerFileDiscoveredPathContainer.java110
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java384
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigUtil.java290
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java180
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java146
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java198
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java177
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java253
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileSIPConsoleParser.java132
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java58
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java343
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java104
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java306
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/BuildOutputReaderJob.java71
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/SCJobsUtil.java207
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java312
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java145
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java45
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVStringPair.java59
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/LogWriter.java213
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java108
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java162
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/TraceUtil.java166
28 files changed, 5305 insertions, 0 deletions
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java
new file mode 100644
index 00000000000..d952523e24d
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.core.model.IPathEntryContainer;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public class DiscoveredPathContainer implements IPathEntryContainer {
+ public static final IPath CONTAINER_ID = new Path("org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"); //$NON-NLS-1$
+
+ protected final IProject fProject;
+ private IPathEntry[] fPathEntries;
+
+ public DiscoveredPathContainer(IProject project) {
+ fProject = project;
+ fPathEntries = null;
+ }
+
+// public IPathEntry[] getPathEntries() {
+// IPathEntry[] fPathEntries;
+// try {
+// fPathEntries = getPathEntries(getPathEntryMap());
+// } catch (CoreException e) {
+// MakeCorePlugin.log(e);
+// return new IPathEntry[0];
+// }
+// return fPathEntries;
+// }
+
+ public String getDescription() {
+ return MakeMessages.getString("DiscoveredContainer.description"); //$NON-NLS-1$
+ }
+
+ public IPath getPath() {
+ return CONTAINER_ID;
+ }
+
+ public IPathEntry[] getPathEntries() {
+ if (fPathEntries == null) {
+ try {
+ fPathEntries = computeNewPathEntries();
+ }
+ catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ return new IPathEntry[0];
+ }
+ }
+ return fPathEntries;
+ }
+
+ private IPathEntry[] computeNewPathEntries() throws CoreException {
+ IDiscoveredPathInfo info = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(fProject);
+ IPath[] includes = info.getIncludePaths();
+ Map syms = info.getSymbols();
+ List entries = new ArrayList(includes.length + syms.size());
+ for (int i = 0; i < includes.length; i++) {
+ entries.add(CoreModel.newIncludeEntry(Path.EMPTY, Path.EMPTY, includes[i], true)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ Iterator iter = syms.entrySet().iterator();
+ while (iter.hasNext()) {
+ Entry entry = (Entry)iter.next();
+ entries.add(CoreModel.newMacroEntry(Path.EMPTY, (String)entry.getKey(), (String)entry.getValue())); //$NON-NLS-1$
+ }
+ return (IPathEntry[])entries.toArray(new IPathEntry[entries.size()]);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java
new file mode 100644
index 00000000000..cecddaa0b95
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredScannerInfoSerializable;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerProjectDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.PerProjectSICollector;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+public class DiscoveredPathInfo implements IPerProjectDiscoveredPathInfo, IDiscoveredScannerInfoSerializable {
+ public static final String INCLUDE_PATH = "includePath"; //$NON-NLS-1$
+ public static final String PATH = "path"; //$NON-NLS-1$
+ public static final String DEFINED_SYMBOL = "definedSymbol"; //$NON-NLS-1$
+ public static final String SYMBOL = "symbol"; //$NON-NLS-1$
+ public static final String REMOVED = "removed"; //$NON-NLS-1$
+
+ final private IProject project;
+ private LinkedHashMap discoveredPaths;
+ private LinkedHashMap discoveredSymbols;
+
+ private List activePaths;
+ private Map activeSymbols;
+
+ public DiscoveredPathInfo(IProject project) {
+ this.project = project;
+ discoveredPaths = new LinkedHashMap();
+ discoveredSymbols = new LinkedHashMap();
+ }
+
+ public IProject getProject() {
+ return project;
+ }
+
+ public synchronized Map getSymbols() {
+ if (activeSymbols == null) {
+ createSymbolsMap();
+ }
+ Map dSymbols = ScannerConfigUtil.scSymbolEntryMap2Map(discoveredSymbols);
+ return dSymbols;
+ }
+
+ public synchronized IPath[] getIncludePaths() {
+ if ( activePaths == null) {
+ createPathLists();
+ }
+ return (IPath[])activePaths.toArray(new IPath[activePaths.size()]);
+ }
+
+ public LinkedHashMap getIncludeMap() {
+ return new LinkedHashMap(discoveredPaths);
+ }
+
+ public synchronized void setIncludeMap(LinkedHashMap paths) {
+ discoveredPaths = new LinkedHashMap(paths);
+ activePaths = null;
+ }
+
+ /**
+ * Populates active and removed include path lists
+ */
+ private void createPathLists() {
+ List aPaths = getActivePathList();
+ aPaths.clear();
+
+ for (Iterator i = discoveredPaths.keySet().iterator(); i.hasNext(); ) {
+ String path = (String) i.next();
+ Boolean removed = (Boolean) discoveredPaths.get(path);
+ if (removed == null || removed.booleanValue() == false) {
+ aPaths.add(new Path(path));
+ }
+ }
+ }
+
+ public LinkedHashMap getSymbolMap() {
+ return new LinkedHashMap(discoveredSymbols);
+ }
+
+ public synchronized void setSymbolMap(LinkedHashMap symbols) {
+ discoveredSymbols = new LinkedHashMap(symbols);
+ activeSymbols = null;
+ }
+
+ /**
+ * Populates active symbols sets
+ */
+ private void createSymbolsMap() {
+ Map aSymbols = getActiveSymbolsMap();
+ aSymbols.clear();
+
+ aSymbols.putAll(ScannerConfigUtil.scSymbolEntryMap2Map(discoveredSymbols));
+ }
+
+ private List getActivePathList() {
+ if (activePaths == null) {
+ activePaths = new ArrayList();
+ }
+ return activePaths;
+ }
+
+ private Map getActiveSymbolsMap() {
+ if (activeSymbols == null) {
+ activeSymbols = new HashMap();
+ }
+ return activeSymbols;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#serialize(org.w3c.dom.Element)
+ */
+ public void serialize(Element collectorElem) {
+ Document doc = collectorElem.getOwnerDocument();
+
+ Map includes = getIncludeMap();
+ Iterator iter = includes.keySet().iterator();
+ while (iter.hasNext()) {
+ Element pathElement = doc.createElement(INCLUDE_PATH);
+ String include = (String)iter.next();
+ pathElement.setAttribute(PATH, include);
+ Boolean removed = (Boolean)includes.get(include);
+ if (removed != null && removed.booleanValue() == true) {
+ pathElement.setAttribute(REMOVED, "true"); //$NON-NLS-1$
+ }
+ collectorElem.appendChild(pathElement);
+ }
+ // Now do the same for the symbols
+ Map symbols = getSymbolMap();
+ iter = symbols.keySet().iterator();
+ while (iter.hasNext()) {
+ String symbol = (String)iter.next();
+ SymbolEntry se = (SymbolEntry)symbols.get(symbol);
+ for (Iterator i = se.getActiveRaw().iterator(); i.hasNext();) {
+ String value = (String)i.next();
+ Element symbolElement = doc.createElement(DEFINED_SYMBOL);
+ symbolElement.setAttribute(SYMBOL, value);
+ collectorElem.appendChild(symbolElement);
+ }
+ for (Iterator i = se.getRemovedRaw().iterator(); i.hasNext();) {
+ String value = (String)i.next();
+ Element symbolElement = doc.createElement(DEFINED_SYMBOL);
+ symbolElement.setAttribute(SYMBOL, value);
+ symbolElement.setAttribute(REMOVED, "true"); //$NON-NLS-1$
+ collectorElem.appendChild(symbolElement);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#deserialize(org.w3c.dom.Element)
+ */
+ public void deserialize(Element collectorElem) {
+ LinkedHashMap includes = getIncludeMap();
+ LinkedHashMap symbols = getSymbolMap();
+
+ Node child = collectorElem.getFirstChild();
+ while (child != null) {
+ if (child.getNodeName().equals(INCLUDE_PATH)) {
+ // Add the path to the property list
+ includes.put( ((Element)child).getAttribute(PATH), Boolean.valueOf( ((Element)child).getAttribute(REMOVED)));
+ } else if (child.getNodeName().equals(DEFINED_SYMBOL)) {
+ // Add the symbol to the symbol list
+ String symbol = ((Element)child).getAttribute(SYMBOL);
+ String removed = ((Element)child).getAttribute(REMOVED);
+ boolean bRemoved = (removed != null && removed.equals("true")); //$NON-NLS-1$
+ ScannerConfigUtil.scAddSymbolString2SymbolEntryMap(symbols, symbol, !bRemoved);
+ }
+ child = child.getNextSibling();
+ }
+
+ setIncludeMap(includes);
+ setSymbolMap(symbols);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#getCollectorId()
+ */
+ public String getCollectorId() {
+ return PerProjectSICollector.COLLECTOR_ID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSerializable()
+ */
+ public IDiscoveredScannerInfoSerializable getSerializable() {
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInitializer.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInitializer.java
new file mode 100644
index 00000000000..ac3d3ccd4e9
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInitializer.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.PathEntryContainerInitializer;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigScope;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+
+public class DiscoveredPathInitializer extends PathEntryContainerInitializer {
+
+ public void initialize(IPath containerPath, ICProject cProject) throws CoreException {
+ IProject project = cProject.getProject();
+ IScannerConfigBuilderInfo2 buildInfo = ScannerConfigProfileManager.createScannerConfigBuildInfo2(project);
+ ScannerConfigScope profileScope = ScannerConfigProfileManager.getInstance().
+ getSCProfileConfiguration(buildInfo.getSelectedProfileId()).getProfileScope();
+ if (ScannerConfigScope.PROJECT_SCOPE.equals(profileScope)) {
+ CoreModel.setPathEntryContainer(new ICProject[]{cProject}, new DiscoveredPathContainer(project), null);
+ }
+ else if (ScannerConfigScope.FILE_SCOPE.equals(profileScope)) {
+ CoreModel.setPathEntryContainer(new ICProject[]{cProject}, new PerFileDiscoveredPathContainer(project), null);
+ }
+ else {
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), 1,
+ MakeMessages.getString("DiscoveredContainer.ScopeErrorMessage"), null)); //$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java
new file mode 100644
index 00000000000..755c1c07227
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.PathEntryContainerChanged;
+import org.eclipse.cdt.core.settings.model.util.PathSettingsContainer;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2Set;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigScope;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+
+
+public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceChangeListener {
+
+ private Map fDiscoveredInfoHolderMap = new HashMap();
+ private List listeners = Collections.synchronizedList(new ArrayList());
+
+ private static final int INFO_CHANGED = 1;
+ private static final int INFO_REMOVED = 2;
+
+ private static class DiscoveredInfoHolder {
+ Map fInfoMap = new HashMap();
+// PathSettingsContainer fContainer = PathSettingsContainer.createRootContainer();
+
+ public IDiscoveredPathInfo getInfo(InfoContext context){
+ return (IDiscoveredPathInfo)fInfoMap.get(context);
+ }
+
+// private Map getMap(IPath path, boolean create, boolean exactPath){
+// PathSettingsContainer child = fContainer.getChildContainer(path, create, exactPath);
+// Map map = null;
+// if(child != null){
+// map = (Map)child.getValue();
+// if(map == null && create){
+// map = new HashMap();
+// child.setValue(map);
+// }
+// }
+//
+// return map;
+// }
+
+// public IDiscoveredPathInfo getInfo(IFile file, String instanceId){
+// IPath path = file.getProjectRelativePath();
+// Map map = getMap(path, false, false);
+// for(Iterator iter = map.entrySet().iterator(); iter.hasNext();){
+// Map.Entry entry = (Map.Entry)iter.next();
+// InfoContext context = (InfoContext)entry.getKey();
+// if(context.matches(file))
+// return (IDiscoveredPathInfo)entry.getValue();
+// }
+// return null;
+// }
+
+ public IDiscoveredPathInfo setInfo(InfoContext context, IDiscoveredPathInfo info){
+ if(info != null)
+ return (IDiscoveredPathInfo)fInfoMap.put(context, info);
+ return (IDiscoveredPathInfo)fInfoMap.remove(context);
+ }
+
+ }
+
+ public DiscoveredPathManager() {
+
+ }
+
+ public void startup() {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+ }
+
+ public void shutdown() {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+ */
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getSource() instanceof IWorkspace) {
+ IResource resource = event.getResource();
+
+ switch (event.getType()) {
+ case IResourceChangeEvent.POST_CHANGE :
+ DiscoveredScannerInfoStore.getInstance().updateScannerConfigStore(event.getDelta());
+ break;
+ case IResourceChangeEvent.PRE_DELETE :
+ case IResourceChangeEvent.PRE_CLOSE :
+ if (resource.getType() == IResource.PROJECT) {
+ //TODO: better handlind of resource remove/rename
+ fDiscoveredInfoHolderMap.remove(resource);
+ }
+ break;
+ }
+ }
+ }
+
+
+
+ public IDiscoveredPathInfo getDiscoveredInfo(IProject project) throws CoreException {
+ return getDiscoveredInfo(project, new InfoContext(project));
+ }
+
+ public IDiscoveredPathInfo getDiscoveredInfo(IProject project, InfoContext context) throws CoreException{
+ DiscoveredInfoHolder holder = getHolder(project, true);
+ IDiscoveredPathInfo info = holder.getInfo(context);
+
+ if(info == null){
+ info = loadPathInfo(project, context);
+ holder.setInfo(context, info);
+ }
+
+ return info;
+ }
+
+ private DiscoveredInfoHolder getHolder(IProject project, boolean create){
+ DiscoveredInfoHolder holder = (DiscoveredInfoHolder)fDiscoveredInfoHolderMap.get(project);
+ if(holder == null && create){
+ holder = new DiscoveredInfoHolder();
+ fDiscoveredInfoHolderMap.put(project, holder);
+ }
+ return holder;
+ }
+
+ private IDiscoveredPathInfo loadPathInfo(IProject project, InfoContext context) throws CoreException {
+ IDiscoveredPathInfo pathInfo = null;
+
+ IScannerConfigBuilderInfo2Set container = ScannerConfigProfileManager.createScannerConfigBuildInfo2Set(project);
+ IScannerConfigBuilderInfo2 buildInfo = container.getInfo(context);
+ if(buildInfo != null){
+ String profileId = buildInfo.getSelectedProfileId();
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(project, context, profileId);
+ IScannerInfoCollector collector = profileInstance.getScannerInfoCollector();
+
+ if (collector instanceof IScannerInfoCollector2) {
+ IScannerInfoCollector2 collector2 = (IScannerInfoCollector2) collector;
+ pathInfo = collector2.createPathInfoObject();
+ }
+ }
+ if(pathInfo == null) {
+ pathInfo = new DiscoveredPathInfo(project);
+ }
+ return pathInfo;
+ }
+
+
+
+
+// private DiscoveredInfoHolder getHolder
+
+// private IDiscoveredPathInfo loadPathInfo(IProject project) throws CoreException {
+// IDiscoveredPathInfo pathInfo = null;
+//
+// IScannerConfigBuilderInfo2 buildInfo = ScannerConfigProfileManager.createScannerConfigBuildInfo2(project);
+// String profileId = buildInfo.getSelectedProfileId();
+// SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+// getSCProfileInstance(project, profileId);
+// IScannerInfoCollector collector = profileInstance.getScannerInfoCollector();
+//
+// if (collector instanceof IScannerInfoCollector2) {
+// IScannerInfoCollector2 collector2 = (IScannerInfoCollector2) collector;
+// pathInfo = collector2.createPathInfoObject();
+// }
+// else {
+// pathInfo = new DiscoveredPathInfo(project);
+// }
+// return pathInfo;
+// }
+
+ public void removeDiscoveredInfo(IProject project) {
+ removeDiscoveredInfo(project, new InfoContext(project));
+ }
+
+ public void removeDiscoveredInfo(IProject project, InfoContext context) {
+ DiscoveredInfoHolder holder = getHolder(project, false);
+ if(holder != null){
+ IDiscoveredPathInfo info = holder.setInfo(context, null);
+ if (info != null) {
+ fireUpdate(INFO_REMOVED, info);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager#updateDiscoveredInfo(org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo, java.util.List)
+ */
+ public void updateDiscoveredInfo(IDiscoveredPathInfo info, List changedResources) throws CoreException {
+ updateDiscoveredInfo(new InfoContext(info.getProject()), info, true, changedResources);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager#updateDiscoveredInfo(org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo, java.util.List)
+ */
+ public void updateDiscoveredInfo(InfoContext context, IDiscoveredPathInfo info, boolean updateContainer, List changedResources) throws CoreException {
+ DiscoveredInfoHolder holder = getHolder(info.getProject(), false);
+ if (holder != null && holder.getInfo(context) != null) {
+ IDiscoveredScannerInfoSerializable serializable = info.getSerializable();
+ if (serializable != null) {
+ IProject project = info.getProject();
+ DiscoveredScannerInfoStore.getInstance().saveDiscoveredScannerInfoToState(project, context, serializable);
+ fireUpdate(INFO_CHANGED, info);
+
+ if(updateContainer){
+// ICProject cProject = CoreModel.getDefault().create(info.getProject());
+// if (cProject != null) {
+// CoreModel.setPathEntryContainer(new ICProject[]{cProject},
+// new DiscoveredPathContainer(info.getProject()), null);
+// }
+ IScannerConfigBuilderInfo2 buildInfo = ScannerConfigProfileManager.createScannerConfigBuildInfo2(project);
+ String profileId = buildInfo.getSelectedProfileId();
+ ScannerConfigScope profileScope = ScannerConfigProfileManager.getInstance().
+ getSCProfileConfiguration(profileId).getProfileScope();
+ changeDiscoveredContainer(project, profileScope, changedResources);
+ }
+ }
+ else {
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.Info_Not_Serializable"), null)); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager#changeDiscoveredContainer(org.eclipse.core.resources.IProject, java.lang.String)
+ */
+ public void changeDiscoveredContainer(final IProject project, final ScannerConfigScope profileScope, final List changedResources) {
+ // order here is of essence
+ // 1. clear DiscoveredPathManager's path info cache
+ DiscoveredInfoHolder holder = getHolder(project, false);
+ InfoContext context = new InfoContext(project);
+ IDiscoveredPathInfo oldInfo = (IDiscoveredPathInfo) holder.getInfo(context);
+
+ // 2. switch the containers
+ try {
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ ICProject cProject = CoreModel.getDefault().create(project);
+ if (ScannerConfigScope.PROJECT_SCOPE.equals(profileScope)) {
+ CoreModel.setPathEntryContainer(new ICProject[]{cProject},
+ new DiscoveredPathContainer(project), null);
+ }
+ else if (ScannerConfigScope.FILE_SCOPE.equals(profileScope)) {
+ PerFileDiscoveredPathContainer container = new PerFileDiscoveredPathContainer(project);
+ CoreModel.setPathEntryContainer(new ICProject[]{cProject},
+ container, null);
+ if (changedResources != null) {
+ List changeDelta = new ArrayList(changedResources.size());
+ for (Iterator i = changedResources.iterator(); i.hasNext(); ) {
+ IResource resource = (IResource) i.next();
+ IPath path = resource.getFullPath();
+ changeDelta.add(new PathEntryContainerChanged(path,
+ PathEntryContainerChanged.INCLUDE_CHANGED |
+ PathEntryContainerChanged.MACRO_CHANGED)); // both include paths and symbols changed
+ }
+ CoreModel.pathEntryContainerUpdates(container,
+ (PathEntryContainerChanged[]) changeDelta.toArray(new PathEntryContainerChanged[changeDelta.size()]),
+ null);
+ }
+ }
+ else {
+ MakeCorePlugin.log(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), 1,
+ MakeMessages.getString("DiscoveredContainer.ScopeErrorMessage"), null)); //$NON-NLS-1$
+ }
+
+ }
+ };
+ CoreModel.run(runnable, null);
+ }
+ catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+
+ // 3. clear the container's path entry cache
+ if (oldInfo != null) {
+ fireUpdate(INFO_REMOVED, oldInfo);
+ }
+ }
+
+ private void fireUpdate(final int type, final IDiscoveredPathInfo info) {
+ Object[] list = listeners.toArray();
+ for (int i = 0; i < list.length; i++) {
+ final IDiscoveredInfoListener listener = (IDiscoveredInfoListener)list[i];
+ if (listener != null) {
+ Platform.run(new ISafeRunnable() {
+
+ public void handleException(Throwable exception) {
+ IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1,
+ CCorePlugin.getResourceString("CDescriptorManager.exception.listenerError"), exception); //$NON-NLS-1$
+ CCorePlugin.log(status);
+ }
+
+ public void run() throws Exception {
+ switch (type) {
+ case INFO_CHANGED :
+ listener.infoChanged(info);
+ break;
+ case INFO_REMOVED :
+ listener.infoRemoved(info);
+ break;
+ }
+ }
+ });
+ }
+ }
+ }
+
+ public void addDiscoveredInfoListener(IDiscoveredInfoListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeDiscoveredInfoListener(IDiscoveredInfoListener listener) {
+ listeners.remove(listener);
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredScannerInfoStore.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredScannerInfoStore.java
new file mode 100644
index 00000000000..e27be5792e7
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredScannerInfoStore.java
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredScannerInfoSerializable;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.PerProjectSICollector;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.xml.sax.SAXException;
+
+/**
+ * Discovered scanner info persistance store
+ *
+ * @author vhirsl
+ */
+public class DiscoveredScannerInfoStore {
+ private static final QualifiedName dscFileNameProperty = new
+ QualifiedName(MakeCorePlugin.getUniqueIdentifier(), "discoveredScannerConfigFileName"); //$NON-NLS-1$
+ private static final String CDESCRIPTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".discoveredScannerInfo"; //$NON-NLS-1$
+ public static final String SCD_STORE_VERSION = "scdStore"; //$NON-NLS-1$
+ public static final String SI_ELEM = "scannerInfo"; //$NON-NLS-1$
+ public static final String COLLECTOR_ELEM = "collector"; //$NON-NLS-1$
+ public static final String ID_ATTR = "id"; //$NON-NLS-1$
+
+ private static final String INSTANCE_ELEM = "instance"; //$NON-NLS-1$
+
+ private static DiscoveredScannerInfoStore instance;
+
+ private Map fDocumentMap = new HashMap();
+
+ public static DiscoveredScannerInfoStore getInstance() {
+ if (instance == null) {
+ instance = new DiscoveredScannerInfoStore();
+ }
+ return instance;
+ }
+ /**
+ *
+ */
+ private DiscoveredScannerInfoStore() {
+ }
+
+ public void loadDiscoveredScannerInfoFromState(IProject project, IDiscoveredScannerInfoSerializable serializable)
+ throws CoreException {
+ loadDiscoveredScannerInfoFromState(project, new InfoContext(project), serializable);
+ }
+
+ public void loadDiscoveredScannerInfoFromState(IProject project, InfoContext context, IDiscoveredScannerInfoSerializable serializable)
+ throws CoreException {
+ // Get the document
+ Element rootElem = getRootElement(project, context, serializable);
+
+ if(rootElem != null){
+ // get the collector element
+ NodeList collectorList = rootElem.getElementsByTagName(COLLECTOR_ELEM);
+ if (collectorList.getLength() > 0) {
+ // find the collector element
+ for (int i = 0; i < collectorList.getLength(); ++i) {
+ Element collectorElem = (Element) collectorList.item(i);
+ String collectorId = collectorElem.getAttribute(ID_ATTR);
+ if (serializable.getCollectorId().equals(collectorId)) {
+ serializable.deserialize(collectorElem);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public boolean hasInfo(IProject project, InfoContext context, IDiscoveredScannerInfoSerializable serializable){
+ try {
+ if(getRootElement(project, context, serializable) != null)
+ return true;
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+ return false;
+ }
+
+ private Element getRootElement(IProject project, InfoContext context, IDiscoveredScannerInfoSerializable serializable) throws CoreException{
+ if(serializable == null)
+ return null;
+
+ Document document = getDocument(project);
+ Element rootElem = null;
+ if (document != null) {
+ NodeList rootList = document.getElementsByTagName(SI_ELEM);
+ if (rootList.getLength() > 0) {
+ rootElem = (Element) rootList.item(0);
+
+ if(!context.isDefaultContext()){
+ String instanceId = context.getInstanceId();
+
+ Element instanceElem = findChild(rootElem, INSTANCE_ELEM, ID_ATTR, instanceId);
+
+ rootElem = instanceElem;
+ }
+ }
+ }
+
+ return rootElem;
+ }
+
+ private Document getDocument(IProject project) throws CoreException {
+ // Get the document
+ Document document = (Document) fDocumentMap.get(project);
+ if (document == null) {
+ try {
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ IPath path = getDiscoveredScannerConfigStore(project);
+ if (path.toFile().exists()) {
+ // read form file
+ FileInputStream file = new FileInputStream(path.toFile());
+ document = builder.parse(file);
+ Node rootElem = document.getFirstChild();
+ if (rootElem.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE) {
+ // no version info; upgrade
+ upgradeDocument(document, project);
+ }
+ }
+ else {
+ // create new document
+ document = builder.newDocument();
+ ProcessingInstruction pi = document.createProcessingInstruction(SCD_STORE_VERSION, "version=\"2\""); //$NON-NLS-1$
+ document.appendChild(pi);
+ Element rootElement = document.createElement(SI_ELEM); //$NON-NLS-1$
+ rootElement.setAttribute(ID_ATTR, CDESCRIPTOR_ID); //$NON-NLS-1$
+ document.appendChild(rootElement);
+ }
+ fDocumentMap.put(project, document);
+ }
+ catch (IOException e) {
+ MakeCorePlugin.log(e);
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.File_Error_Message"), e)); //$NON-NLS-1$
+ }
+ catch (ParserConfigurationException e) {
+ MakeCorePlugin.log(e);
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.File_Error_Message"), e)); //$NON-NLS-1$
+ }
+ catch (SAXException e) {
+ MakeCorePlugin.log(e);
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.File_Error_Message"), e)); //$NON-NLS-1$
+ }
+ }
+ return document;
+ }
+
+ /**
+ * @param document
+ * @param project
+ */
+ private void upgradeDocument(Document document, IProject project) {
+ Element rootElem = (Element) document.getElementsByTagName(SI_ELEM).item(0); //$NON-NLS-1$
+ ProcessingInstruction pi = document.createProcessingInstruction(SCD_STORE_VERSION, "version=\"2.0\""); //$NON-NLS-1$
+ document.insertBefore(pi, rootElem);
+
+ Element collectorElem = document.createElement(COLLECTOR_ELEM);
+ collectorElem.setAttribute(ID_ATTR, PerProjectSICollector.COLLECTOR_ID);
+ for (Node child = rootElem.getFirstChild(); child != null; child = rootElem.getFirstChild()) {
+ collectorElem.appendChild(rootElem.removeChild(child));
+ }
+ rootElem.appendChild(collectorElem);
+ }
+
+ private Element findChild(Element parentElem, String name, String attr, String attrValue){
+ Element cfgElem = null;
+ NodeList cfgList = parentElem.getElementsByTagName(name);
+ if (cfgList.getLength() > 0) {
+ // find per file collector element and remove children
+ for (int i = 0; i < cfgList.getLength(); ++i) {
+ Element cElem = (Element) cfgList.item(i);
+ String value = cElem.getAttribute(attr);
+ if (value.equals(attrValue)) {
+ cfgElem = cElem;
+ break;
+ }
+ }
+ }
+
+ return cfgElem;
+ }
+
+ private void clearChildren(Element cElem){
+ for (Node child = cElem.getFirstChild(); child != null;
+ child = cElem.getFirstChild()) {
+ cElem.removeChild(child);
+ }
+ }
+
+
+
+ /**
+ * @param scannerInfo
+ * @param rootElement
+ * @param doc
+ */
+ private void saveDiscoveredScannerInfo(InfoContext context, IDiscoveredScannerInfoSerializable serializable, Document doc) {
+ NodeList rootList = doc.getElementsByTagName(SI_ELEM);
+ if (rootList.getLength() > 0) {
+ Element rootElem = (Element) rootList.item(0);
+
+ // get the collector element
+ if(!context.isDefaultContext()){
+ String instanceId = context.getInstanceId();
+
+ Element instanceElem = findChild(rootElem, INSTANCE_ELEM, ID_ATTR, instanceId);
+
+ if(instanceElem == null){
+ instanceElem = doc.createElement(INSTANCE_ELEM);
+ instanceElem.setAttribute(ID_ATTR, instanceId);
+ rootElem.appendChild(instanceElem);
+ }
+
+ rootElem = instanceElem;
+ }
+
+ // get the collector element
+ Element collectorElem = null;
+ NodeList collectorList = rootElem.getElementsByTagName(COLLECTOR_ELEM);
+ if (collectorList.getLength() > 0) {
+ // find per file collector element and remove children
+ for (int i = 0; i < collectorList.getLength(); ++i) {
+ Element cElem = (Element) collectorList.item(i);
+ String collectorId = cElem.getAttribute(ID_ATTR);
+ if (serializable.getCollectorId().equals(collectorId)) {
+ for (Node child = cElem.getFirstChild(); child != null;
+ child = cElem.getFirstChild()) {
+ cElem.removeChild(child);
+ }
+ collectorElem = cElem;
+ break;
+ }
+ }
+ }
+ if (collectorElem == null) {
+ // create per profile element
+ collectorElem = doc.createElement(COLLECTOR_ELEM);
+ collectorElem.setAttribute(ID_ATTR, serializable.getCollectorId());
+ rootElem.appendChild(collectorElem);
+ }
+
+ // Save the discovered scanner info
+ serializable.serialize(collectorElem);
+ }
+ }
+ public void saveDiscoveredScannerInfoToState(IProject project, IDiscoveredScannerInfoSerializable serializable) throws CoreException {
+ saveDiscoveredScannerInfoToState(project, new InfoContext(project), serializable);
+ }
+
+ public void saveDiscoveredScannerInfoToState(IProject project, InfoContext context, IDiscoveredScannerInfoSerializable serializable) throws CoreException {
+ Document document = getDocument(project);
+ // Create document
+ try {
+ saveDiscoveredScannerInfo(context, serializable, document);
+
+ // Transform the document to something we can save in a file
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ DOMSource source = new DOMSource(document);
+ StreamResult result = new StreamResult(stream);
+ transformer.transform(source, result);
+
+ // Save the document
+ try {
+ IPath path = getDiscoveredScannerConfigStore(project);
+ FileOutputStream file = new FileOutputStream(path.toFile());
+ file.write(stream.toByteArray());
+ file.close();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.File_Error_Message"), e)); //$NON-NLS-1$
+ }
+
+ // Close the streams
+ stream.close();
+ } catch (TransformerException e) {
+ MakeCorePlugin.log(e);
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.File_Error_Message"), e)); //$NON-NLS-1$
+ } catch (IOException e) {
+ MakeCorePlugin.log(e);
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("DiscoveredPathManager.File_Error_Message"), e)); //$NON-NLS-1$
+ }
+ }
+
+ public IPath getDiscoveredScannerConfigStore(IProject project) {
+ String fileName = project.getName() + ".sc"; //$NON-NLS-1$
+ String storedFileName = null;
+ try {
+ storedFileName = project.getPersistentProperty(dscFileNameProperty);
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e.getStatus());
+ }
+ if (storedFileName != null && !storedFileName.equals(fileName)) {
+ // try to move 2.x file name format to 3.x file name format
+ movePluginStateFile(storedFileName, fileName);
+ }
+ try {
+ project.setPersistentProperty(dscFileNameProperty, fileName);
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e.getStatus());
+ }
+
+ return MakeCorePlugin.getWorkingDirectory().append(fileName);
+ }
+
+ /**
+ * @param delta
+ */
+ public void updateScannerConfigStore(IResourceDelta delta) {
+ try {
+ delta.accept(new IResourceDeltaVisitor() {
+
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource resource = delta.getResource();
+ if (resource instanceof IProject) {
+ IProject project = (IProject) resource;
+ int kind = delta.getKind();
+ switch (kind) {
+ case IResourceDelta.REMOVED:
+ if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+ // project renamed
+ IPath newPath = delta.getMovedToPath();
+ IProject newProject = delta.getResource().getWorkspace().
+ getRoot().getProject(newPath.toString());
+ scProjectRenamed(project, newProject);
+ }
+ else {
+ // project deleted
+ scProjectDeleted(project);
+ }
+ // remove from cache
+ fDocumentMap.put(project, null);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ });
+ }
+ catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+ }
+
+ private void scProjectDeleted(IProject project) {
+ String scFileName = project.getName() + ".sc"; //$NON-NLS-1$
+ deletePluginStateFile(scFileName);
+ }
+
+ /**
+ * @param scFileName
+ */
+ private void deletePluginStateFile(String scFileName) {
+ IPath path = MakeCorePlugin.getWorkingDirectory().append(scFileName);
+ File file = path.toFile();
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+
+ private void scProjectRenamed(IProject project, IProject newProject) {
+ String scOldFileName = project.getName() + ".sc"; //$NON-NLS-1$
+ String scNewFileName = newProject.getName() + ".sc"; //$NON-NLS-1$
+ movePluginStateFile(scOldFileName, scNewFileName);
+ try {
+ newProject.setPersistentProperty(dscFileNameProperty, scNewFileName);
+ }
+ catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+ }
+
+ /**
+ * @param oldFileName
+ * @param newFileName
+ */
+ private void movePluginStateFile(String oldFileName, String newFileName) {
+ IPath oldPath = MakeCorePlugin.getWorkingDirectory().append(oldFileName);
+ IPath newPath = MakeCorePlugin.getWorkingDirectory().append(newFileName);
+ File oldFile = oldPath.toFile();
+ File newFile = newPath.toFile();
+ if (oldFile.exists()) {
+ oldFile.renameTo(newFile);
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/PerFileDiscoveredPathContainer.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/PerFileDiscoveredPathContainer.java
new file mode 100644
index 00000000000..0248fd7ec72
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/PerFileDiscoveredPathContainer.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.core.model.IPathEntryContainerExtension;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public class PerFileDiscoveredPathContainer extends DiscoveredPathContainer
+ implements IPathEntryContainerExtension {
+
+ public PerFileDiscoveredPathContainer(IProject project) {
+ super(project);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.model.IPathEntryContainerExtension#getPathEntries(org.eclipse.core.runtime.IPath, int)
+ */
+ public IPathEntry[] getPathEntries(IPath path, int mask) {
+ ArrayList entries = new ArrayList();
+ try {
+ IDiscoveredPathInfo info = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(fProject);
+ if (info instanceof IPerFileDiscoveredPathInfo) {
+ IPerFileDiscoveredPathInfo filePathInfo = (IPerFileDiscoveredPathInfo) info;
+
+ if ((mask & IPathEntry.CDT_INCLUDE) != 0) {
+ IPath[] includes = filePathInfo.getIncludePaths(path);
+ for (int i = 0; i < includes.length; i++) {
+ // add as a system include path
+ entries.add(CoreModel.newIncludeEntry(path, Path.EMPTY, includes[i], true));
+ }
+ includes = filePathInfo.getQuoteIncludePaths(path);
+ for (int i = 0; i < includes.length; i++) {
+ // add as a local include path
+ entries.add(CoreModel.newIncludeEntry(path, Path.EMPTY, includes[i], false));
+ }
+ }
+ if ((mask & IPathEntry.CDT_MACRO) != 0) {
+ Map syms = filePathInfo.getSymbols(path);
+ for (Iterator iter = syms.entrySet().iterator(); iter.hasNext(); ) {
+ Entry entry = (Entry)iter.next();
+ entries.add(CoreModel.newMacroEntry(path, (String)entry.getKey(), (String)entry.getValue())); //$NON-NLS-1$
+ }
+ }
+ // compare the resource with include and macros files
+ IPath fullResPath = fProject.getWorkspace().getRoot().getFile(path).getLocation();
+ if (fullResPath == null) {
+ fullResPath = path;
+ }
+ if ((mask & IPathEntry.CDT_INCLUDE_FILE) != 0) {
+ IPath[] includeFiles = filePathInfo.getIncludeFiles(path);
+ for (int i = 0; i < includeFiles.length; i++) {
+ if (!includeFiles[i].equals(fullResPath)) {
+ entries.add(CoreModel.newIncludeFileEntry(path, includeFiles[i]));
+ }
+ }
+ }
+ if ((mask & IPathEntry.CDT_MACRO_FILE) != 0) {
+ IPath[] imacrosFiles = filePathInfo.getMacroFiles(path);
+ for (int i = 0; i < imacrosFiles.length; i++) {
+ if (!imacrosFiles[i].equals(fullResPath)) {
+ entries.add(CoreModel.newMacroFileEntry(path, imacrosFiles[i]));
+ }
+ }
+ }
+ }
+ }
+ catch (CoreException e) {
+ //
+ }
+ return (IPathEntry[]) entries.toArray(new IPathEntry[entries.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.model.IPathEntryContainerExtension#isEmpty(org.eclipse.core.runtime.IPath)
+ */
+ public boolean isEmpty(IPath path) {
+ IDiscoveredPathInfo info;
+ try {
+ info = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(fProject);
+ if (info instanceof IPerFileDiscoveredPathInfo) {
+ IPerFileDiscoveredPathInfo filePathInfo = (IPerFileDiscoveredPathInfo) info;
+ return filePathInfo.isEmpty(path);
+ }
+ } catch (CoreException e) {
+ }
+ return false;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java
new file mode 100644
index 00000000000..170adaf22cc
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.MakeProjectNature;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager;
+
+/**
+ * Creates a ScannerConfigBuilderInfo variant
+ * @author vhirsl
+ */
+public class ScannerConfigInfoFactory {
+ private static final String PREFIX = MakeCorePlugin.getUniqueIdentifier();
+
+ static final String BUILD_SCANNER_CONFIG_ENABLED = PREFIX + ".ScannerConfigDiscoveryEnabled"; //$NON-NLS-1$
+ static final String MAKE_BUILDER_PARSER_ENABLED = PREFIX + ".makeBuilderParserEnabled"; //$NON-NLS-1$
+ static final String MAKE_BUILDER_PARSER_ID = PREFIX + ".makeBuilderParserId"; //$NON-NLS-1$
+ static final String ESI_PROVIDER_COMMAND_ENABLED = PREFIX + ".esiProviderCommandEnabled"; //$NON-NLS-1$
+ static final String USE_DEFAULT_ESI_PROVIDER_CMD = PREFIX + ".useDefaultESIProviderCmd"; //$NON-NLS-1$
+ static final String ESI_PROVIDER_COMMAND = PREFIX + ".esiProviderCommand"; //$NON-NLS-1$
+ static final String ESI_PROVIDER_ARGUMENTS = PREFIX + ".esiProviderArguments"; //$NON-NLS-1$
+ static final String ESI_PROVIDER_PARSER_ID = PREFIX + ".esiProviderParserId"; //$NON-NLS-1$
+ static final String SI_PROBLEM_GENERATION_ENABLED = PREFIX + ".siProblemGenerationEnabled"; //$NON-NLS-1$
+ /**
+ * @since 3.0
+ */
+ static final String SI_PROFILE_ID = PREFIX + ".siProfileId"; //$NON-NLS-1$
+
+ /**
+ *
+ * @author vhirsl
+ */
+ private abstract static class Store implements IScannerConfigBuilderInfo {
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isAutoDiscoveryEnabled()
+ */
+ public boolean isAutoDiscoveryEnabled() {
+ return getBoolean(BUILD_SCANNER_CONFIG_ENABLED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setAutoDiscoveryEnabled(boolean)
+ */
+ public void setAutoDiscoveryEnabled(boolean enabled) throws CoreException {
+ putString(BUILD_SCANNER_CONFIG_ENABLED, Boolean.toString(enabled));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isMakeBuilderConsoleParserEnabled()
+ */
+ public boolean isMakeBuilderConsoleParserEnabled() {
+ if (getString(MAKE_BUILDER_PARSER_ENABLED) == null ||
+ getString(MAKE_BUILDER_PARSER_ENABLED).length() == 0) { // if no property then default to true
+ return true;
+ }
+ return getBoolean(MAKE_BUILDER_PARSER_ENABLED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setMakeBuilderConsoleParserEnabled(boolean)
+ */
+ public void setMakeBuilderConsoleParserEnabled(boolean enabled) throws CoreException {
+ putString(MAKE_BUILDER_PARSER_ENABLED, Boolean.toString(enabled));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getMakeBuilderConsoleParserId()
+ */
+ public String getMakeBuilderConsoleParserId() {
+ String parserId = getString(MAKE_BUILDER_PARSER_ID);
+ if (parserId == null || parserId.length() == 0) {
+ String[] parserIds = MakeCorePlugin.getDefault().
+ getScannerInfoConsoleParserIds("makeBuilder"); //$NON-NLS-1$
+ // the default is the first one in the registry
+ parserId = parserIds[0];
+ }
+ return parserId;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setMakeBuilderConsoleParserId(java.lang.String)
+ */
+ public void setMakeBuilderConsoleParserId(String parserId) throws CoreException {
+ putString(MAKE_BUILDER_PARSER_ID, parserId);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isESIProviderCommandEnabled()
+ */
+ public boolean isESIProviderCommandEnabled() {
+ if (getString(ESI_PROVIDER_COMMAND_ENABLED) == null ||
+ getString(ESI_PROVIDER_COMMAND_ENABLED).length() == 0) { // if no property then default to true
+ return true;
+ }
+ return getBoolean(ESI_PROVIDER_COMMAND_ENABLED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderCommandEnabled(boolean)
+ */
+ public void setESIProviderCommandEnabled(boolean enabled) throws CoreException {
+ putString(ESI_PROVIDER_COMMAND_ENABLED, Boolean.toString(enabled));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isDefaultESIProviderCmd()
+ */
+ public boolean isDefaultESIProviderCmd() {
+ if (getString(USE_DEFAULT_ESI_PROVIDER_CMD) == null ||
+ getString(USE_DEFAULT_ESI_PROVIDER_CMD).length() == 0) { // if no property then default to true
+ return true;
+ }
+ return getBoolean(USE_DEFAULT_ESI_PROVIDER_CMD);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setUseDefaultESIProviderCmd(boolean)
+ */
+ public void setUseDefaultESIProviderCmd(boolean on) throws CoreException {
+ putString(USE_DEFAULT_ESI_PROVIDER_CMD, Boolean.toString(on));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getESIProviderCommand()
+ */
+ public IPath getESIProviderCommand() {
+ if (isDefaultESIProviderCmd()) {
+ String command = getESIProviderParameter("defaultCommand"); //$NON-NLS-1$
+ if (command == null) {
+ return new Path("gcc"); //$NON-NLS-1$
+ }
+ return new Path(command);
+ }
+ return new Path(getString(ESI_PROVIDER_COMMAND));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderCommand(org.eclipse.core.runtime.IPath)
+ */
+ public void setESIProviderCommand(IPath command) throws CoreException {
+ putString(ESI_PROVIDER_COMMAND, command.toString());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getESIProviderArguments()
+ */
+ public String getESIProviderArguments() {
+ if (isDefaultESIProviderCmd()) {
+ String attributes = getESIProviderParameter("defaultAttributes"); //$NON-NLS-1$
+ if (attributes == null) {
+ attributes = "-E -P -v -dD ${plugin_state_location}/${specs_file}"; //$NON-NLS-1$
+ }
+ return attributes;
+ }
+ return getString(ESI_PROVIDER_ARGUMENTS);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderArguments(java.lang.String)
+ */
+ public void setESIProviderArguments(String args) throws CoreException {
+ putString(ESI_PROVIDER_ARGUMENTS, args);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getESIProviderConsoleParserId()
+ */
+ public String getESIProviderConsoleParserId() {
+ String parserId = getString(ESI_PROVIDER_PARSER_ID);
+ if (parserId == null || parserId.length() == 0) {
+ String[] parserIds = MakeCorePlugin.getDefault().
+ getScannerInfoConsoleParserIds("externalScannerInfoProvider"); //$NON-NLS-1$
+ // the default is the first one in the registry
+ parserId = parserIds[0];
+ }
+ return parserId;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderConsoleParserId(java.lang.String)
+ */
+ public void setESIProviderConsoleParserId(String parserId) throws CoreException {
+ putString(ESI_PROVIDER_PARSER_ID, parserId);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isSIProblemGenerationEnabled()
+ */
+ public boolean isSIProblemGenerationEnabled() {
+ if (getString(SI_PROBLEM_GENERATION_ENABLED) == null ||
+ getString(SI_PROBLEM_GENERATION_ENABLED).length() == 0) { // if no property then default to true
+ return true;
+ }
+ return getBoolean(SI_PROBLEM_GENERATION_ENABLED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setSIProblemGenerationEnabled(boolean)
+ */
+ public void setSIProblemGenerationEnabled(boolean enabled) throws CoreException {
+ putString(SI_PROBLEM_GENERATION_ENABLED, Boolean.toString(enabled));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getProfileId()
+ */
+ public String getProfileId() {
+ String profileId = getString(SI_PROFILE_ID);
+ if (profileId == null || profileId.length() == 0) {
+ profileId = ScannerConfigProfileManager.getDefaultSIProfileId();
+ // the default is the first one in the registry
+ }
+ return profileId;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setProfileId(java.lang.String)
+ */
+ public void setProfileId(String profileId) throws CoreException {
+ putString(SI_PROFILE_ID, profileId);
+ }
+
+ protected boolean getBoolean(String property) {
+ return Boolean.valueOf(getString(property)).booleanValue();
+ }
+
+ protected abstract String getBuilderID();
+ protected abstract String getString(String property);
+ protected abstract void putString(String name, String value) throws CoreException;
+
+ protected String getESIProviderParameter(String name) {
+ IExtension extension =
+ Platform.getExtensionRegistry().getExtension(
+ MakeCorePlugin.getUniqueIdentifier(),
+ MakeCorePlugin.EXTERNAL_SI_PROVIDER_SIMPLE_ID,
+ // TODO VMIR make this configurable
+ MakeCorePlugin.DEFAULT_EXTERNAL_SI_PROVIDER_ID);
+ if (extension == null)
+ return null;
+ IConfigurationElement[] configs = extension.getConfigurationElements();
+ if (configs.length == 0)
+ return null;
+ IConfigurationElement[] runElement = configs[0].getChildren("run"); //$NON-NLS-1$
+ IConfigurationElement[] paramElement = runElement[0].getChildren("parameter"); //$NON-NLS-1$
+ for (int i = 0; i < paramElement.length; i++) {
+ if (paramElement[i].getAttribute("name").equals(name)) { //$NON-NLS-1$
+ return paramElement[i].getAttribute("value"); //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+ }
+
+ private static class Preference extends Store {
+ private Preferences prefs;
+ private String builderID;
+ private boolean useDefaults;
+
+ Preference(Preferences prefs, String builderID, boolean useDefaults) {
+ this.prefs = prefs;
+ this.builderID = builderID;
+ this.useDefaults = useDefaults;
+ }
+
+ protected void putString(String name, String value) {
+ if (useDefaults) {
+ prefs.setDefault(name, value);
+ } else {
+ prefs.setValue(name, value);
+ }
+ }
+
+ protected String getString(String property) {
+ if (useDefaults) {
+ return prefs.getDefaultString(property);
+ }
+ return prefs.getString(property);
+ }
+
+ protected String getBuilderID() {
+ return builderID;
+ }
+ }
+
+ private static class BuildProperty extends Store {
+ private IProject project;
+ private String builderID;
+ private Map args;
+
+ BuildProperty(IProject project, String builderID) throws CoreException {
+ this.project = project;
+ this.builderID = builderID;
+ ICommand builder = ScannerConfigNature.getBuildSpec(project.getDescription(), builderID);
+ if (builder == null) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("ScannerConfigInfoFactory.Missing_Builder")//$NON-NLS-1$
+ + builderID, null));
+ }
+ args = builder.getArguments();
+ }
+
+ protected void putString(String name, String value) throws CoreException {
+ String curValue = (String) args.get(name);
+ if (curValue != null && curValue.equals(value)) {
+ return;
+ }
+ IProjectDescription description = project.getDescription();
+ ICommand builder = ScannerConfigNature.getBuildSpec(description, builderID);
+ args.put(name, value);
+ builder.setArguments(args);
+ MakeProjectNature.setBuildSpec(description, builder);
+ project.setDescription(description, null);
+ }
+
+ protected String getString(String name) {
+ String value = (String) args.get(name);
+ return value == null ? "" : value; //$NON-NLS-1$
+ }
+
+ protected String getBuilderID() {
+ return builderID;
+ }
+ }
+
+ private static class BuildArguments extends Store {
+ private Map args;
+ private String builderID;
+
+ BuildArguments(Map args, String builderID) {
+ this.args = args;
+ this.builderID = builderID;
+ }
+
+ protected void putString(String name, String value) {
+ args.put(name, value);
+ }
+
+ protected String getString(String name) {
+ return (String) args.get(name);
+ }
+
+ protected String getBuilderID() {
+ return builderID;
+ }
+ }
+
+ public static IScannerConfigBuilderInfo create(Preferences prefs, String builderID, boolean useDefaults) {
+ return new ScannerConfigInfoFactory.Preference(prefs, builderID, useDefaults);
+ }
+
+ public static IScannerConfigBuilderInfo create(IProject project, String builderID) throws CoreException {
+ return new ScannerConfigInfoFactory.BuildProperty(project, builderID);
+ }
+
+ public static IScannerConfigBuilderInfo create(Map args, String builderID) {
+ return new ScannerConfigInfoFactory.BuildArguments(args, builderID);
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigUtil.java
new file mode 100644
index 00000000000..476d5d66b88
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigUtil.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Utility class that handles some Scanner Config specifig collection conversions
+ *
+ * @author vhirsl
+ */
+public final class ScannerConfigUtil {
+ /**
+ * Adds all new discovered symbols/values to the existing ones.
+ *
+ * @param sumSymbols - a map of [String, Map] where Map is a SymbolEntry
+ * @param symbols
+ * @return boolean
+ */
+ public static boolean scAddSymbolsList2SymbolEntryMap(Map sumSymbols, List symbols, boolean active) {
+ boolean rc = false;
+ for (Iterator i = symbols.iterator(); i.hasNext(); ) {
+ String symbol = (String) i.next();
+ String key;
+ String value = null;
+ int index = symbol.indexOf("="); //$NON-NLS-1$
+ if (index != -1) {
+ key = symbol.substring(0, index).trim();
+ value = symbol.substring(index + 1).trim();
+ } else {
+ key = symbol.trim();
+ }
+ SymbolEntry sEntry = (SymbolEntry) sumSymbols.get(key);
+ if (sEntry == null) {
+ // make only the first one to be active
+ sEntry = new SymbolEntry(key, value, true);
+ rc = true;
+ }
+ else {
+ rc |= sEntry.add(value, active);
+ }
+ sumSymbols.put(key, sEntry);
+ }
+ return rc;
+ }
+
+ /**
+ * Gets all discovered symbols with either active or removed values
+ * @param sumSymbols
+ * @param active - false = removed
+ * @return
+ */
+ public static List scSymbolsSymbolEntryMap2List(Map sumSymbols, boolean active) {
+ Set symbols = sumSymbols.entrySet();
+ List rv = new ArrayList(symbols.size());
+ for (Iterator i = symbols.iterator(); i.hasNext(); ) {
+ SymbolEntry sEntry = (SymbolEntry) ((Map.Entry) i.next()).getValue();
+ if (active) {
+ rv.addAll(sEntry.getActiveRaw());
+ }
+ else {
+ rv.addAll(sEntry.getRemovedRaw());
+ }
+ }
+ return rv;
+ }
+
+ /**
+ * MapsSymbolEntryMap to a plain Map
+ *
+ * @param sumSymbols (in) - discovered symbols in SymbolEntryMap
+ * @return - active symbols as a plain Map
+ */
+ public static Map scSymbolEntryMap2Map(Map sumSymbols) {
+ Map rv = new HashMap();
+ for (Iterator i = sumSymbols.keySet().iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ SymbolEntry values = (SymbolEntry) sumSymbols.get(key);
+ for (Iterator j = values.getValuesOnly(true).iterator(); j.hasNext(); ) {
+ String value = (String) j.next();
+ rv.put(key, value); // multiple active values will be condensed to one !!!
+ }
+ }
+ return rv;
+ }
+
+ /**
+ * Adds a single symbol definition string ("DEBUG_LEVEL=4") to the SymbolEntryMap
+ *
+ * @param symbols
+ * @param symbol
+ * @param active
+ */
+ public static boolean scAddSymbolString2SymbolEntryMap(Map symbols, String symbol, boolean active) {
+ boolean rc = false;
+ String key;
+ String value = null;
+ int index = symbol.indexOf("="); //$NON-NLS-1$
+ if (index != -1) {
+ key = getSymbolKey(symbol);
+ value = getSymbolValue(symbol);
+ } else {
+ key = symbol.trim();
+ }
+ SymbolEntry sEntry = (SymbolEntry) symbols.get(key);
+ if (sEntry == null) {
+ // make only the first one to be active
+ sEntry = new SymbolEntry(key, value, active);
+ rc = true;
+ }
+ else {
+ rc |= sEntry.add(value, active);
+ }
+ symbols.put(key, sEntry);
+ return rc;
+ }
+
+ /**
+ * @param result (out)
+ * @param addend (in)
+ * @return
+ */
+ public static boolean scAddSymbolEntryMap2SymbolEntryMap(Map result, Map addend) {
+ boolean rc = false;
+ for (Iterator i = addend.keySet().iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ if (result.keySet().contains(key)) {
+ SymbolEntry rSE = (SymbolEntry) result.get(key);
+ SymbolEntry aSE = (SymbolEntry) addend.get(key);
+ List activeValues = rSE.getActiveRaw();
+ for (Iterator j = aSE.getActiveRaw().iterator(); j.hasNext(); ) {
+ String aValue = (String) j.next();
+ if (!activeValues.contains(aValue)) {
+ // result does not contain addend's value; add it
+ rSE.add(getSymbolValue(aValue), true);
+ rc |= true;
+ }
+ }
+ List removedValues = rSE.getRemovedRaw();
+ for (Iterator j = aSE.getRemovedRaw().iterator(); j.hasNext(); ) {
+ String aValue = (String) j.next();
+ if (!removedValues.contains(aValue)) {
+ // result does not contain addend's value; add it
+ rSE.add(getSymbolValue(aValue), false);
+ rc |= true;
+ }
+ }
+ }
+ else {
+ // result does not contain the symbol; add it
+ // shallow copy
+ SymbolEntry aSymbolEntry = (SymbolEntry) addend.get(key);
+ result.put(key, aSymbolEntry);
+ rc |= true;
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Returns a symbol key (i.e. for DEF=1 returns DEF)
+ *
+ * @param symbol - in
+ * @param key - out
+ */
+ public static String getSymbolKey(String symbol) {
+ int index = symbol.indexOf('=');
+ if (index != -1) {
+ return symbol.substring(0, index).trim();
+ }
+ return symbol;
+ }
+
+ /**
+ * Returns a symbol value (i.e. for DEF=1 returns 1)
+ *
+ * @param symbol - in
+ * @param key - out (may be null)
+ */
+ public static String getSymbolValue(String symbol) {
+ int index = symbol.indexOf('=');
+ if (index != -1) {
+ return symbol.substring(index+1).trim();
+ }
+ return null;
+ }
+
+ /**
+ * Removes a symbol value from the symbol entry. If it was an only value than
+ * it symbol entry will be removed alltogether.
+ *
+ * @param symbol
+ * @param symbolEntryMap map of [symbol's key, symbolEntry]
+ */
+ public static void removeSymbolEntryValue(String symbol, Map symbolEntryMap) {
+ String key = getSymbolKey(symbol);
+ String value = getSymbolValue(symbol);
+ // find it in the discoveredSymbols Map of SymbolEntries
+ SymbolEntry se = (SymbolEntry) symbolEntryMap.get(key);
+ if (se != null) {
+ se.remove(value);
+ if (se.numberOfValues() == 0) {
+ symbolEntryMap.remove(key);
+ }
+ }
+ }
+
+ /**
+ * Swaps two include paths in the include paths Map.
+ * Used by Up/Down discovered paths
+ *
+ * @param sumPaths
+ * @param index1
+ * @param index2
+ * @return new map of include paths
+ */
+ public static LinkedHashMap swapIncludePaths(LinkedHashMap sumPaths, int index1, int index2) {
+ int size = sumPaths.size();
+ if (index1 == index2 ||
+ !(index1 >= 0 && index1 < size &&
+ index2 >= 0 && index2 < size)) {
+ return sumPaths;
+ }
+ ArrayList pathKeyList = new ArrayList(sumPaths.keySet());
+ String temp1 = (String) pathKeyList.get(index1);
+ String temp2 = (String) pathKeyList.get(index2);
+ pathKeyList.set(index1, temp2);
+ pathKeyList.set(index2, temp1);
+
+ LinkedHashMap newSumPaths = new LinkedHashMap(sumPaths.size());
+ for (Iterator i = pathKeyList.iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ newSumPaths.put(key, sumPaths.get(key));
+ }
+ return newSumPaths;
+ }
+
+ /**
+ * Tokenizes string with quuotes
+ *
+ * @param String
+ * @return String[]
+ */
+ public static String[] tokenizeStringWithQuotes(String line, String quoteStyle) {
+ ArrayList allTokens = new ArrayList();
+ String[] tokens = line.split(quoteStyle);
+ for (int i = 0; i < tokens.length; ++i) {
+ if (i % 2 == 0) { // even tokens need further tokenization
+ String[] sTokens = tokens[i].split("\\s+"); //$NON-NLS-1$
+ for (int j = 0; j < sTokens.length; allTokens.add(sTokens[j++]));
+ }
+ else {
+ allTokens.add(tokens[i]);
+ }
+ }
+ return (String[]) allTokens.toArray(new String[allTokens.size()]);
+ }
+
+ /**
+ * Converts array of IPath-s to array of String-s
+ *
+ * @param paths
+ * @return
+ */
+ public static String[] iPathArray2StringArray(IPath[] paths) {
+ String[] rv = new String[paths.length];
+ for (int i = 0; i < paths.length; ++i) {
+ rv[i] = paths[i].toString();
+ }
+ return rv;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java
new file mode 100644
index 00000000000..200a4172b07
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136)
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig;
+
+import java.io.OutputStream;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.internal.core.ConsoleOutputSniffer;
+import org.eclipse.cdt.make.core.MakeBuilderUtil;
+import org.eclipse.cdt.make.core.MakeBuilder;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2Set;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * A factory that creates a ConsoleOutputStreamSniffer,
+ * ScannerInfoConsoleParser and optionally a ScannerInfoConsoleParserUtility.
+ *
+ * @author vhirsl
+ */
+public class ScannerInfoConsoleParserFactory {
+
+ /**
+ * Creates a ConsoleOutputStreamSniffer, make builder scanner info console parser
+ * and a utility.
+ *
+ * @param outputStream
+ * @param errorStream
+ * @param currentProject
+ * @param providerId
+ * @param scBuildInfo
+ * @param markerGenerator
+ * @return ConsoleOutputSniffer
+ */
+ public static ConsoleOutputSniffer getESIProviderOutputSniffer(
+ OutputStream outputStream,
+ OutputStream errorStream,
+ IProject currentProject,
+ String providerId,
+ IScannerConfigBuilderInfo2 scBuildInfo,
+ IScannerInfoCollector collector,
+ IMarkerGenerator markerGenerator) {
+ return getESIProviderOutputSniffer(outputStream, errorStream, currentProject, new InfoContext(currentProject), providerId, scBuildInfo, collector, markerGenerator);
+ }
+ /**
+ * Creates a ConsoleOutputStreamSniffer, make builder scanner info console parser
+ * and a utility.
+ *
+ * @param outputStream
+ * @param errorStream
+ * @param currentProject
+ * @param providerId
+ * @param scBuildInfo
+ * @param markerGenerator
+ * @return ConsoleOutputSniffer
+ */
+ public static ConsoleOutputSniffer getESIProviderOutputSniffer(
+ OutputStream outputStream,
+ OutputStream errorStream,
+ IProject currentProject,
+ InfoContext context,
+ String providerId,
+ IScannerConfigBuilderInfo2 scBuildInfo,
+ IScannerInfoCollector collector,
+ IMarkerGenerator markerGenerator) {
+ if (scBuildInfo.isProviderOutputParserEnabled(providerId)) {
+ // get the ESIProvider console parser
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(currentProject, context, scBuildInfo.getSelectedProfileId());
+ IScannerInfoConsoleParser clParser = profileInstance.createExternalScannerInfoParser(providerId);
+ IPath buildDirectory = MakeBuilderUtil.getBuildDirectory(currentProject, MakeBuilder.BUILDER_ID);
+ clParser.startup(currentProject, buildDirectory, collector, markerGenerator);
+ // create an output stream sniffer
+ return new ConsoleOutputSniffer(outputStream, errorStream, new
+ IScannerInfoConsoleParser[] {clParser});
+ }
+ return null;
+ }
+
+ /**
+ * Creates a ConsoleOutputStreamSniffer, ESI provider scanner info console parser
+ * and a utility.
+ *
+ * @param outputStream
+ * @param errorStream
+ * @param currentProject
+ * @param workingDirectory
+ * @param buildInfo
+ * @param markerGenerator
+ * @param IScannerInfoCollector2
+ * @return ConsoleOutputSniffer
+ */
+ public static ConsoleOutputSniffer getMakeBuilderOutputSniffer(
+ OutputStream outputStream,
+ OutputStream errorStream,
+ IProject currentProject,
+ IPath workingDirectory,
+ IScannerConfigBuilderInfo2 scBuildInfo,
+ IMarkerGenerator markerGenerator,
+ IScannerInfoCollector collector) {
+ return getMakeBuilderOutputSniffer(outputStream, errorStream, currentProject, new InfoContext(currentProject), workingDirectory, scBuildInfo, markerGenerator, collector);
+ }
+
+ /**
+ * Creates a ConsoleOutputStreamSniffer, ESI provider scanner info console parser
+ * and a utility.
+ *
+ * @param outputStream
+ * @param errorStream
+ * @param currentProject
+ * @param workingDirectory
+ * @param buildInfo
+ * @param markerGenerator
+ * @param IScannerInfoCollector2
+ * @return ConsoleOutputSniffer
+ */
+ public static ConsoleOutputSniffer getMakeBuilderOutputSniffer(
+ OutputStream outputStream,
+ OutputStream errorStream,
+ IProject currentProject,
+ InfoContext context,
+ IPath workingDirectory,
+ IScannerConfigBuilderInfo2 scBuildInfo,
+ IMarkerGenerator markerGenerator,
+ IScannerInfoCollector collector) {
+ try {
+ // get the SC builder settings
+ if (currentProject.hasNature(ScannerConfigNature.NATURE_ID)) {
+ if (scBuildInfo == null) {
+ try {
+ IScannerConfigBuilderInfo2Set container = ScannerConfigProfileManager.
+ createScannerConfigBuildInfo2Set(currentProject);
+ scBuildInfo = container.getInfo(context);
+ }
+ catch (CoreException e) {
+ // builder not installed or disabled
+ }
+ }
+ if (scBuildInfo != null &&
+ scBuildInfo.isAutoDiscoveryEnabled() &&
+ scBuildInfo.isBuildOutputParserEnabled()) {
+ // get the make builder console parser
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(currentProject, context, scBuildInfo.getSelectedProfileId());
+ IScannerInfoConsoleParser clParser = profileInstance.createBuildOutputParser();
+ if (collector == null) {
+ collector = profileInstance.getScannerInfoCollector();
+ }
+ clParser.startup(currentProject, workingDirectory, collector,
+ scBuildInfo.isProblemReportingEnabled() ? markerGenerator : null);
+ // create an output stream sniffer
+ return new ConsoleOutputSniffer(outputStream, errorStream, new
+ IScannerInfoConsoleParser[] {clParser});
+ }
+ }
+ }
+ catch (CoreException e) {
+ MakeCorePlugin.log(e.getStatus());
+ }
+ return null;
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java
new file mode 100644
index 00000000000..586f3771272
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile.BuildOutputProvider;
+import org.eclipse.core.resources.IProject;
+
+/**
+ * Common stuff for all GNU build output parsers
+ *
+ * @author vhirsl
+ */
+public abstract class AbstractGCCBOPConsoleParser implements IScannerInfoConsoleParser {
+ private static final String[] COMPILER_INVOCATION = {
+ "gcc", "g++", "cc", "c++" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ };
+
+ private IProject project;
+ private IScannerInfoCollector collector;
+
+ private boolean bMultiline = false;
+ private String sMultiline = ""; //$NON-NLS-1$
+
+ /**
+ * @return Returns the project.
+ */
+ protected IProject getProject() {
+ return project;
+ }
+ /**
+ * @return Returns the collector.
+ */
+ protected IScannerInfoCollector getCollector() {
+ return collector;
+ }
+
+ public void startup(IProject project, IScannerInfoCollector collector) {
+ this.project = project;
+ this.collector = collector;
+ }
+
+ /**
+ * Returns array of additional compiler commands to look for
+ *
+ * @return String[]
+ */
+ public String[] getCompilerCommands() {
+ if (project != null) {
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(project, ScannerConfigProfileManager.NULL_PROFILE_ID);
+ BuildOutputProvider boProvider = profileInstance.getProfile().getBuildOutputProviderElement();
+ if (boProvider != null) {
+ String compilerCommandsString = boProvider.getScannerInfoConsoleParser().getCompilerCommands();
+ if (compilerCommandsString != null && compilerCommandsString.length() > 0) {
+ String[] compilerCommands = compilerCommandsString.split(",\\s+"); //$NON-NLS-1$
+ if (compilerCommands.length > 0) {
+ String[] compilerInvocation = new String[COMPILER_INVOCATION.length + compilerCommands.length];
+ System.arraycopy(COMPILER_INVOCATION, 0, compilerInvocation, 0, COMPILER_INVOCATION.length);
+ System.arraycopy(compilerCommands, 0, compilerInvocation, COMPILER_INVOCATION.length, compilerCommands.length);
+ return compilerInvocation;
+ }
+ }
+ }
+ }
+ return COMPILER_INVOCATION;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#processLine(java.lang.String)
+ */
+ public boolean processLine(String line) {
+ boolean rc = false;
+ // check for multiline commands (ends with '\')
+ if (line.endsWith("\\")) { //$NON-NLS-1$
+ sMultiline += line.substring(0, line.length()-1);// + " ";
+ bMultiline = true;
+ return rc;
+ }
+ if (bMultiline) {
+ line = sMultiline + line;
+ bMultiline = false;
+ sMultiline = ""; //$NON-NLS-1$
+ }
+ TraceUtil.outputTrace("AbstractGCCBOPConsoleParser parsing line: [", line, "]"); //$NON-NLS-1$ //$NON-NLS-2$
+ // make\[[0-9]*\]: error_desc
+ int firstColon= line.indexOf(':');
+ String make = line.substring(0, firstColon + 1);
+ if (firstColon != -1 && make.indexOf("make") != -1) { //$NON-NLS-1$
+ boolean enter = false;
+ String msg = line.substring(firstColon + 1).trim();
+ if ((enter = msg.startsWith("Entering directory")) || //$NON-NLS-1$
+ (msg.startsWith("Leaving directory"))) { //$NON-NLS-1$
+ int s = msg.indexOf('`');
+ int e = msg.indexOf('\'');
+ if (s != -1 && e != -1) {
+ String dir = msg.substring(s+1, e);
+ if (getUtility() != null) {
+ getUtility().changeMakeDirectory(dir, getDirectoryLevel(line), enter);
+ }
+ return rc;
+ }
+ }
+ }
+ // call sublclass to process a single line
+ return processSingleLine(line);
+ }
+
+ private int getDirectoryLevel(String line) {
+ int s = line.indexOf('[');
+ int num = 0;
+ if (s != -1) {
+ int e = line.indexOf(']');
+ String number = line.substring(s + 1, e).trim();
+ try {
+ num = Integer.parseInt(number);
+ } catch (NumberFormatException exc) {
+ }
+ }
+ return num;
+ }
+
+ protected abstract boolean processSingleLine(String line);
+ protected abstract AbstractGCCBOPConsoleParserUtility getUtility();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#shutdown()
+ */
+ public void shutdown() {
+ if (getUtility() != null) {
+ getUtility().reportProblems();
+ }
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java
new file mode 100644
index 00000000000..60a029e8aea
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Common utilities for GCC build output console parsers
+ *
+ * @author vhirsl
+ */
+public abstract class AbstractGCCBOPConsoleParserUtility {
+ private IProject project;
+ private IPath fBaseDirectory;
+ private Vector fDirectoryStack;
+ private IMarkerGenerator fMarkerGenerator;
+ private ArrayList fErrors;
+
+ /**
+ *
+ */
+ public AbstractGCCBOPConsoleParserUtility(IProject project, IPath workingDirectory,
+ IMarkerGenerator markerGenerator) {
+ fDirectoryStack = new Vector();
+ fErrors = new ArrayList();
+ this.project = project;
+ fBaseDirectory = project.getLocation();
+ if (workingDirectory != null) {
+ pushDirectory(workingDirectory);
+ }
+ }
+
+ /**
+ * @return Returns the fBaseDirectory.
+ */
+ protected IPath getBaseDirectory() {
+ return fBaseDirectory;
+ }
+ /**
+ * @return Returns the fDirectoryStack.
+ */
+ protected Vector getDirectoryStack() {
+ return fDirectoryStack;
+ }
+ /**
+ * @return Returns the fErrors.
+ */
+ protected ArrayList getErrors() {
+ return fErrors;
+ }
+ /**
+ * @return Returns the fMarkerGenerator.
+ */
+ protected IMarkerGenerator getMarkerGenerator() {
+ return fMarkerGenerator;
+ }
+ /**
+ * @return Returns the project.
+ */
+ protected IProject getProject() {
+ return project;
+ }
+
+ public IPath getWorkingDirectory() {
+ if (fDirectoryStack.size() != 0) {
+ return (IPath) fDirectoryStack.lastElement();
+ }
+ // Fallback to the Project Location
+ // FIXME: if the build did not start in the Project ?
+ return fBaseDirectory;
+ }
+
+ protected void pushDirectory(IPath dir) {
+ if (dir != null) {
+ IPath pwd = null;
+ if (fBaseDirectory.isPrefixOf(dir)) {
+ pwd = dir.removeFirstSegments(fBaseDirectory.segmentCount());
+ } else {
+ // check if it is a cygpath
+ pwd= convertCygpath(dir);
+ }
+ fDirectoryStack.addElement(pwd);
+ }
+ }
+
+ public static IPath convertCygpath(IPath path) {
+ if (path.segmentCount() > 1 && path.segment(0).equals("cygdrive")) { //$NON-NLS-1$
+ StringBuffer buf = new StringBuffer(2);
+ buf.append(Character.toUpperCase(path.segment(1).charAt(0)));
+ buf.append(':');
+ path = path.removeFirstSegments(2);
+ path = path.setDevice(buf.toString());
+ path = path.makeAbsolute();
+ }
+ return path;
+ }
+
+ protected IPath popDirectory() {
+ int i = getDirectoryLevel();
+ if (i != 0) {
+ IPath dir = (IPath) fDirectoryStack.lastElement();
+ fDirectoryStack.removeElementAt(i - 1);
+ return dir;
+ }
+ return new Path(""); //$NON-NLS-1$
+ }
+
+ protected int getDirectoryLevel() {
+ return fDirectoryStack.size();
+ }
+
+ public void changeMakeDirectory(String dir, int dirLevel, boolean enterDir) {
+ if (enterDir) {
+ /* Sometimes make screws up the output, so
+ * "leave" events can't be seen. Double-check level
+ * here.
+ */
+ for (int parseLevel = getDirectoryLevel(); dirLevel < parseLevel; parseLevel = getDirectoryLevel()) {
+ popDirectory();
+ }
+ pushDirectory(new Path(dir));
+ } else {
+ popDirectory();
+ /* Could check to see if they match */
+ }
+ }
+
+ public boolean reportProblems() {
+ boolean reset = false;
+ for (Iterator iter = fErrors.iterator(); iter.hasNext(); ) {
+ Problem problem = (Problem) iter.next();
+ if (problem.severity == IMarkerGenerator.SEVERITY_ERROR_BUILD) {
+ reset = true;
+ }
+ if (problem.file == null) {
+ fMarkerGenerator.addMarker(
+ project,
+ problem.lineNumber,
+ problem.description,
+ problem.severity,
+ problem.variableName);
+ } else {
+ fMarkerGenerator.addMarker(
+ problem.file,
+ problem.lineNumber,
+ problem.description,
+ problem.severity,
+ problem.variableName);
+ }
+ }
+ fErrors.clear();
+ return reset;
+ }
+
+ protected class Problem {
+ protected IResource file;
+ protected int lineNumber;
+ protected String description;
+ protected int severity;
+ protected String variableName;
+
+ public Problem(IResource file, int lineNumber, String desciption, int severity, String variableName) {
+ this.file = file;
+ this.lineNumber = lineNumber;
+ this.description = desciption;
+ this.severity = severity;
+ this.variableName = variableName;
+ }
+ }
+
+ /**
+ * Called by the console line parsers to generate a problem marker.
+ */
+ public void generateMarker(IResource file, int lineNumber, String desc, int severity, String varName) {
+ // No need to collect markers if marker generator is not present
+ if (fMarkerGenerator != null) {
+ Problem problem = new Problem(file, lineNumber, desc, severity, varName);
+ fErrors.add(problem);
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java
new file mode 100644
index 00000000000..2e5126a63ff
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136)
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+
+
+/**
+ * GCC per file build output parser
+ *
+ * @author vhirsl
+ */
+public class GCCPerFileBOPConsoleParser extends AbstractGCCBOPConsoleParser {
+ private final static String[] FILE_EXTENSIONS = {
+ ".c", ".cc", ".cpp", ".cxx", ".C", ".CC", ".CPP", ".CXX" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
+ };
+ private final static List FILE_EXTENSIONS_LIST = Arrays.asList(FILE_EXTENSIONS);
+
+ private String[] compilerInvocation;
+ private GCCPerFileBOPConsoleParserUtility fUtil;
+
+ /* (non-Javadoc)
+ * @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)
+ */
+ public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) {
+ fUtil = (project != null && workingDirectory != null && markerGenerator != null) ?
+ new GCCPerFileBOPConsoleParserUtility(project, workingDirectory, markerGenerator) : null;
+ super.startup(project, collector);
+
+ // check additional compiler commands from extension point manifest
+ compilerInvocation = getCompilerCommands();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility()
+ */
+ protected AbstractGCCBOPConsoleParserUtility getUtility() {
+ return fUtil;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String)
+ */
+ protected boolean processSingleLine(String line) {
+ boolean rc = false;
+ // GCC C/C++ compiler invocation
+ int compilerInvocationIndex = -1;
+ for (int cii = 0; cii < compilerInvocation.length; ++cii) {
+ compilerInvocationIndex = line.indexOf(compilerInvocation[cii]);
+ if (compilerInvocationIndex != -1)
+ break;
+ }
+ if (compilerInvocationIndex == -1)
+ return rc;
+
+ // expecting that compiler invocation is the first token in the line
+ String[] split = line.split("\\s+"); //$NON-NLS-1$
+ String command = split[0];
+ // verify that it is compiler invocation
+ int cii2 = -1;
+ for (int cii = 0; cii < compilerInvocation.length; ++cii) {
+ cii2 = command.indexOf(compilerInvocation[cii]);
+ if (cii2 != -1)
+ break;
+ }
+ if (cii2 == -1) {
+ TraceUtil.outputTrace("Error identifying compiler command", line, TraceUtil.EOL); //$NON-NLS-1$
+ return rc;
+ }
+ // find a file name
+ int extensionsIndex = -1;
+ boolean found = false;
+ String filePath = null;
+ for (int i = 1; i < split.length; ++i) {
+ int k = split[i].lastIndexOf('.');
+ if (k != -1 && (split[i].length() - k < 5)) {
+ String fileExtension = split[i].substring(k);
+ extensionsIndex = FILE_EXTENSIONS_LIST.indexOf(fileExtension);
+ if (extensionsIndex != -1) {
+ filePath = split[i];
+ found = true;
+ break;
+ }
+ }
+ }
+// for (int j = 0; j < FILE_EXTENSIONS.length; ++j) {
+// if (split[i].endsWith(FILE_EXTENSIONS[j])) {
+// filePath = split[i];
+// extensionsIndex = j;
+// found = true;
+// break;
+// }
+// }
+// if (found) break;
+ if (!found) {
+ TraceUtil.outputTrace("Error identifying file name :1", line, TraceUtil.EOL); //$NON-NLS-1$
+ return rc;
+ }
+ // sanity check
+ if (filePath.indexOf(FILE_EXTENSIONS[extensionsIndex]) == -1) {
+ TraceUtil.outputTrace("Error identifying file name :2", line, TraceUtil.EOL); //$NON-NLS-1$
+ return rc;
+ }
+ if (fUtil != null) {
+ IPath pFilePath = fUtil.getAbsolutePath(filePath);
+ String shortFileName = pFilePath.removeFileExtension().lastSegment();
+
+ // generalize occurances of the file name
+ StringBuffer genericLine = new StringBuffer();
+ for (int i = 0; i < split.length; i++) {
+ String token = split[i];
+ if (token.equals("-include") || token.equals("-imacros")) { //$NON-NLS-1$ //$NON-NLS-2$
+ ++i;
+ genericLine.append(token);
+ genericLine.append(' ');
+ }
+ else if (token.equals(filePath)) {
+ split[i] = "LONG_NAME"; //$NON-NLS-1$
+ }
+ else if (token.startsWith(shortFileName)) {
+ split[i] = token.replaceFirst(shortFileName, "SHORT_NAME"); //$NON-NLS-1$
+ }
+ genericLine.append(split[i]);
+ genericLine.append(' ');
+ }
+
+ CCommandDSC cmd = fUtil.getNewCCommandDSC(genericLine.toString(), extensionsIndex > 0);
+ IPath baseDirectory = fUtil.getBaseDirectory();
+ if (baseDirectory.isPrefixOf(pFilePath)) {
+ List cmdList = new ArrayList();
+ cmdList.add(cmd);
+ Map sc = new HashMap(1);
+ sc.put(ScannerInfoTypes.COMPILER_COMMAND, cmdList);
+
+ IPath relPath = pFilePath.removeFirstSegments(baseDirectory.segmentCount());
+ //Note: We add the scannerconfig even if the resource doesnt actually
+ //exist below this project (which may happen when reading existing
+ //build logs, because resources can be created as part of the build
+ //and may not exist at the time of analyzing the config but re-built
+ //later on.
+ //if (getProject().exists(relPath)) {
+ IFile file = getProject().getFile(relPath);
+ getCollector().contributeToScannerConfig(file, sc);
+ } else {
+ //TODO limiting to pathes below this project means not being
+ //able to work with linked resources. Linked resources could
+ //be checked through IWorkspaceRoot.findFilesForLocation().
+ TraceUtil.outputError("Build command for file outside project: "+pFilePath.toString(), line); //$NON-NLS-1$
+ }
+ // fUtil.addGenericCommandForFile2(longFileName, genericLine);
+ }
+ return rc;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java
new file mode 100644
index 00000000000..73eac867443
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Martin Oberhuber (Wind River Systems) - bug 155096
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.KVStringPair;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.SCDOptionsEnum;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * TODO Provide description
+ *
+ * @author vhirsl
+ */
+public class GCCPerFileBOPConsoleParserUtility extends AbstractGCCBOPConsoleParserUtility {
+ private Map directoryCommandListMap;
+ private List compiledFileList;
+
+ private List commandsList2;
+
+ private int workingDirsN = 0;
+ private int commandsN = 0;
+ private int filesN = 0;
+
+
+ /**
+ * @param markerGenerator
+ * @param workingDirectory
+ * @param project
+ */
+ public GCCPerFileBOPConsoleParserUtility(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) {
+ super(project, workingDirectory, markerGenerator);
+ }
+
+ /**
+ * Adds a mapping filename, generic_command
+ * @param longFileName
+ * @param genericLine
+ */
+ void addGenericCommandForFile(String longFileName, String genericCommand) {
+ // if a file name has already been added once, return
+ if (compiledFileList.contains(longFileName))
+ return;
+ compiledFileList.add(longFileName);
+
+ String workingDir = getWorkingDirectory().toString();
+ List directoryCommandList = (List) directoryCommandListMap.get(workingDir);
+ if (directoryCommandList == null) {
+ directoryCommandList = new ArrayList();
+ directoryCommandListMap.put(workingDir, directoryCommandList);
+ ++workingDirsN;
+ }
+ Map command21FileListMap = null;
+ for (Iterator i = directoryCommandList.iterator(); i.hasNext(); ) {
+ command21FileListMap = (Map) i.next();
+ List fileList = (List) command21FileListMap.get(genericCommand);
+ if (fileList != null) {
+ if (!fileList.contains(longFileName)) {
+ fileList.add(longFileName);
+ ++filesN;
+ }
+ return;
+ }
+ }
+ command21FileListMap = new HashMap(1);
+ directoryCommandList.add(command21FileListMap);
+ ++commandsN;
+ List fileList = new ArrayList();
+ command21FileListMap.put(genericCommand, fileList);
+ fileList.add(longFileName);
+ ++filesN;
+ }
+
+ /**
+ *
+ */
+ void generateReport() {
+ TraceUtil.metricsTrace("Stats for directory ", //$NON-NLS-1$
+ "Generic command: '", "' applicable for:", //$NON-NLS-1$ //$NON-NLS-2$
+ directoryCommandListMap);
+ TraceUtil.summaryTrace("Discovery summary", workingDirsN, commandsN, filesN); //$NON-NLS-1$
+ }
+
+ /**
+ * Adds a mapping command line -> file, this time without a dir
+ * @param longFileName
+ * @param genericLine
+ */
+ void addGenericCommandForFile2(String longFileName, String genericLine) {
+ // if a file name has already been added once, return
+ if (compiledFileList.contains(longFileName))
+ return;
+ compiledFileList.add(longFileName);
+
+ CCommandDSC command = getNewCCommandDSC(genericLine, false); // assume .c file type
+ int index = commandsList2.indexOf(command);
+ if (index == -1) {
+ commandsList2.add(command);
+ ++commandsN;
+ }
+ else {
+ command = (CCommandDSC) commandsList2.get(index);
+ }
+// // add a file
+// command.addFile(longFileName);
+// ++filesN;
+ }
+
+ /**
+ * @param genericLine
+ * @param cppFileType
+ * @return CCommandDSC compile command description
+ */
+ public CCommandDSC getNewCCommandDSC(String genericLine, boolean cppFileType) {
+ CCommandDSC command = new CCommandDSC(cppFileType);
+ String[] tokens = genericLine.split("\\s+"); //$NON-NLS-1$
+ command.addSCOption(new KVStringPair(SCDOptionsEnum.COMMAND.toString(), tokens[0]));
+ for (int i = 1; i < tokens.length; ++i) {
+ String token = tokens[i];
+ //Target specific options: see GccScannerInfoConsoleParser
+ if (token.startsWith("-m") || //$NON-NLS-1$
+ token.equals("-ansi") || //$NON-NLS-1$
+ token.equals("-posix") || //$NON-NLS-1$
+ token.equals("-pthread") || //$NON-NLS-1$
+ token.startsWith("-O") || //$NON-NLS-1$
+ token.equals("-fno-inline") || //$NON-NLS-1$
+ token.startsWith("-finline") || //$NON-NLS-1$
+ token.equals("-fno-exceptions") || //$NON-NLS-1$
+ token.equals("-fexceptions") || //$NON-NLS-1$
+ token.equals("-fshort-wchar") || //$NON-NLS-1$
+ token.equals("-fshort-double") || //$NON-NLS-1$
+ token.equals("-fno-signed-char") || //$NON-NLS-1$
+ token.equals("-fsigned-char") || //$NON-NLS-1$
+ token.startsWith("-fabi-version=") //$NON-NLS-1$
+ ) {
+ command.addSCOption(new KVStringPair(SCDOptionsEnum.COMMAND.toString(), token));
+ continue;
+ }
+ for (int j = SCDOptionsEnum.MIN; j <= SCDOptionsEnum.MAX; ++j) {
+ if (token.startsWith(SCDOptionsEnum.getSCDOptionsEnum(j).toString())) {
+ String option = token.substring(
+ SCDOptionsEnum.getSCDOptionsEnum(j).toString().length()).trim();
+ if (option.length() > 0) {
+ // ex. -I/dir
+ }
+ else if (SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.IDASH)) {
+ // -I- has no parameter
+ }
+ else {
+ // ex. -I /dir
+ // take a next token
+ ++i;
+ if (i < tokens.length && !tokens[i].startsWith("-")) { //$NON-NLS-1$
+ option = tokens[i];
+ }
+ else break;
+ }
+ if (option.length() > 0 && (
+ SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.INCLUDE) ||
+ SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.INCLUDE_FILE) ||
+ SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.IMACROS_FILE) ||
+ SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.IDIRAFTER) ||
+ SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.ISYSTEM))) {
+ option = (getAbsolutePath(option)).toString();
+ }
+ // add the pair
+ command.addSCOption(new KVStringPair(SCDOptionsEnum.getSCDOptionsEnum(j).toString(), option));
+ break;
+ }
+ }
+ }
+ return command;
+ }
+
+ /**
+ * @param filePath : String
+ * @return filePath : IPath - not <code>null</code>
+ */
+ IPath getAbsolutePath(String filePath) {
+ IPath pFilePath;
+ if (filePath.startsWith("/")) { //$NON-NLS-1$
+ return convertCygpath(new Path(filePath));
+ }
+ else if (filePath.startsWith("\\") || //$NON-NLS-1$
+ (!filePath.startsWith(".") && //$NON-NLS-1$
+ filePath.length() > 2 && filePath.charAt(1) == ':' &&
+ (filePath.charAt(2) == '\\' || filePath.charAt(2) == '/'))) {
+ // absolute path
+ pFilePath = new Path(filePath);
+ }
+ else {
+ // relative path
+ IPath cwd = getWorkingDirectory();
+ if (!cwd.isAbsolute()) {
+ cwd = getBaseDirectory().append(cwd);
+ }
+ pFilePath = cwd.append(filePath);
+ }
+ return pFilePath;
+ }
+
+ /**
+ *
+ */
+// void generateReport2() {
+// StringWriter buffer = new StringWriter();
+// PrintWriter writer = new PrintWriter(buffer);
+// for (Iterator i = commandsList2.iterator(); i.hasNext(); ) {
+// CCommandDSC cmd = (CCommandDSC)i.next();
+// writer.println("Stats for generic command: '" + cmd.getCommandAsString() + "' applicable for " +
+// Integer.toString(cmd.getNumberOfFiles()) + " files: ");
+// List filesList = cmd.getFilesList();
+// if (filesList != null) {
+// for (Iterator j = filesList.iterator(); j.hasNext(); ) {
+// writer.println(" " + (String)j.next());
+// }
+// }
+// }
+// writer.close();
+//
+// TraceUtil.metricsTrace(buffer.toString());
+// TraceUtil.summaryTrace("Discovery summary", workingDirsN, commandsN, filesN);
+// }
+
+ /**
+ * Returns all CCommandDSC collected so far.
+ * Currently this list is not filled, so it will always return an empty list.
+ * @return List of CCommandDSC
+ */
+ public List getCCommandDSCList() {
+ return new ArrayList(commandsList2);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileSIPConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileSIPConsoleParser.java
new file mode 100644
index 00000000000..5a07a3a8fee
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileSIPConsoleParser.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Martin Oberhuber (Wind River Systems) - bug 155096
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Console parser for generated makefile output
+ *
+ * @author vhirsl
+ */
+public class GCCPerFileSIPConsoleParser implements IScannerInfoConsoleParser {
+ private final static String INCLUDE_PREAMBLE = "#include <...>"; //$NON-NLS-1$
+ private final static String QUOTE_INCLUDE_PREAMBLE = "#include \"...\""; //$NON-NLS-1$
+ private final static String DEFINE_PREAMBLE = "#define"; //$NON-NLS-1$
+ private final static String COMMAND_ID_BEGIN = "begin generating scanner info for scd_cmd_"; //$NON-NLS-1$
+ private final static String COMMAND_ID_END = "end generating scanner info for scd_cmd_"; //$NON-NLS-1$
+
+ private final static int NO_INCLUDES = 0;
+ private final static int QUOTE_INCLUDES = 1;
+ private final static int INCLUDES = 2;
+
+ private IScannerInfoCollector fCollector = null;
+
+ private int expectingIncludes = NO_INCLUDES;
+ private List symbols;
+ private List includes;
+ private List quoteIncludes;
+ private int commandId = -1;
+
+ /* (non-Javadoc)
+ * @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)
+ */
+ public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) {
+ this.fCollector = collector;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParser#processLine(java.lang.String)
+ */
+ public boolean processLine(String line) {
+ boolean rc = false;
+ TraceUtil.outputTrace("GCCPerFileSIPConsoleParser parsing line: [", line, "]"); //$NON-NLS-1$//$NON-NLS-2$
+
+ if (line.startsWith(COMMAND_ID_BEGIN)) {
+ commandId = Integer.parseInt(line.substring(COMMAND_ID_BEGIN.length()));
+ symbols = new ArrayList();
+ includes = new ArrayList();
+ quoteIncludes = new ArrayList();
+ }
+ else if (line.startsWith(COMMAND_ID_END)) {
+ Map scannerInfo = new HashMap();
+ scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, includes);
+ scannerInfo.put(ScannerInfoTypes.QUOTE_INCLUDE_PATHS, quoteIncludes);
+ scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols);
+ fCollector.contributeToScannerConfig(new Integer(commandId), scannerInfo);
+ commandId = -1;
+ rc = true;
+ }
+ // contribution of -dD option
+ else if (line.startsWith(DEFINE_PREAMBLE)) {
+ String[] defineParts = line.split("\\s+", 3); //$NON-NLS-1$
+ if (defineParts[0].equals(DEFINE_PREAMBLE)) {
+ String symbol = null;
+ switch (defineParts.length) {
+ case 2:
+ symbol = defineParts[1];
+ break;
+ case 3:
+ symbol = defineParts[1] + "=" + defineParts[2]; //$NON-NLS-1$
+ break;
+ }
+ if (symbol != null && !symbols.contains(symbol)) {
+ symbols.add(symbol);
+ }
+ }
+ }
+ // now get all the includes
+ else if (line.startsWith(QUOTE_INCLUDE_PREAMBLE) && line.endsWith("search starts here:")) { //$NON-NLS-1$
+ expectingIncludes = QUOTE_INCLUDES;
+ }
+ else if (line.startsWith(INCLUDE_PREAMBLE) && line.endsWith("search starts here:")) { //$NON-NLS-1$
+ expectingIncludes = INCLUDES;
+ }
+ else if (line.startsWith("End of search list.")) { //$NON-NLS-1$
+ expectingIncludes = NO_INCLUDES;
+ }
+ else if (expectingIncludes == QUOTE_INCLUDES) {
+ if (!quoteIncludes.contains(line))
+ quoteIncludes.add(line);
+ }
+ else if (expectingIncludes == INCLUDES) {
+ if (!includes.contains(line))
+ includes.add(line);
+ }
+
+ return rc;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParser#shutdown()
+ */
+ public void shutdown() {
+// Map scannerInfo = new HashMap();
+// scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, includes);
+// scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols);
+// fCollector.contributeToScannerConfig(fProject, scannerInfo);
+// TraceUtil.outputTrace("Scanner info from \'specs\' file", //$NON-NLS-1$
+// "Include paths", includes, new ArrayList(), "Defined symbols", symbols); //$NON-NLS-1$ //$NON-NLS-2$);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java
new file mode 100644
index 00000000000..e111681cab3
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * GCC related utility class
+ *
+ * @author vhirsl
+ */
+public class GCCScannerConfigUtil {
+ public static final String CPP_SPECS_FILE = "specs.cpp"; //$NON-NLS-1$
+ public static final String C_SPECS_FILE = "specs.c"; //$NON-NLS-1$
+
+ public static void createSpecs() {
+ IPath path = MakeCorePlugin.getWorkingDirectory();
+ try {
+ createSpecsFile(path, CPP_SPECS_FILE);
+ createSpecsFile(path, C_SPECS_FILE);
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+ }
+
+ private static void createSpecsFile(IPath path, String fileName) throws CoreException {
+ IPath specs = path.append(fileName);
+ File specsFile = specs.toFile();
+ if (!specsFile.exists()) {
+ try {
+ FileOutputStream file = new FileOutputStream(specsFile);
+ file.write('\n');
+ file.close();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ MakeCorePlugin.getUniqueIdentifier(), -1,
+ MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java
new file mode 100644
index 00000000000..cba556e3673
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Martin Oberhuber (Wind River Systems) - bug 155096
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Parses gcc and g++ output for -I and -D parameters.
+ *
+ * @author vhirsl
+ */
+public class GCCScannerInfoConsoleParser extends AbstractGCCBOPConsoleParser {
+ private final static String SINGLE_QUOTE_STRING = "\'"; //$NON-NLS-1$
+ private final static String DOUBLE_QUOTE_STRING = "\""; //$NON-NLS-1$
+ private final static char[] matchingChars = {'`', '\'', '\"'};
+
+ private String[] compilerInvocation;
+
+ private ScannerInfoConsoleParserUtility fUtil = null;
+
+ /* (non-Javadoc)
+ * @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)
+ */
+ public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) {
+ fUtil = (project != null && workingDirectory != null && markerGenerator != null) ?
+ new ScannerInfoConsoleParserUtility(project, workingDirectory, markerGenerator) : null;
+ super.startup(project, collector);
+
+ // check additional compiler commands from extension point manifest
+ compilerInvocation = getCompilerCommands();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility()
+ */
+ protected AbstractGCCBOPConsoleParserUtility getUtility() {
+ return fUtil;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String)
+ */
+ protected boolean processSingleLine(String line) {
+ boolean rc = false;
+ // Known patterns:
+ // (a) gcc|g++ ... -Dxxx -Iyyy ...
+ List allTokens = tokenize(line);
+// ArrayList allTokens = new ArrayList(Arrays.asList(line.split("\\s+")));//$NON-NLS-1$
+ if (allTokens.size() <= 1)
+ return false;
+ Iterator I = allTokens.iterator();
+ String token = ((String) I.next()).toLowerCase();
+
+ boolean found = false;
+ for (int i = 0; i < compilerInvocation.length; i++) {
+ if (token.indexOf(compilerInvocation[i]) != -1) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ // Recognized gcc or g++ compiler invocation
+ List includes = new ArrayList();
+ List symbols = new ArrayList();
+ List targetSpecificOptions = new ArrayList();
+
+ rc = true;
+ String fileName = null;
+ // discover all -I options
+ parseLineForIncludePaths(line, includes);
+ // discover all -D options
+ parseLineForSymbolDefinitions(line, symbols);
+
+ while (I.hasNext()) {
+ token = (String) I.next();
+ if (token.startsWith("-m") || //$NON-NLS-1$
+ token.equals("-ansi") || //$NON-NLS-1$
+ token.equals("-nostdinc") || //$NON-NLS-1$
+ token.equals("-posix") || //$NON-NLS-1$
+ token.equals("-pthread") || //$NON-NLS-1$
+ token.startsWith("-O") || //$NON-NLS-1$
+ token.equals("-fno-inline") || //$NON-NLS-1$
+ token.startsWith("-finline") || //$NON-NLS-1$
+ token.equals("-fno-exceptions") || //$NON-NLS-1$
+ token.equals("-fexceptions") || //$NON-NLS-1$
+ token.equals("-fshort-wchar") || //$NON-NLS-1$
+ token.equals("-fshort-double") || //$NON-NLS-1$
+ token.equals("-fno-signed-char") || //$NON-NLS-1$
+ token.equals("-fsigned-char") || //$NON-NLS-1$
+ token.startsWith("-fabi-version=") //$NON-NLS-1$
+ ) {
+ if (!targetSpecificOptions.contains(token))
+ targetSpecificOptions.add(token);
+ }
+ else if (fileName == null) {
+ String possibleFileName = token.toLowerCase();
+ if ((possibleFileName.startsWith(DOUBLE_QUOTE_STRING) &&
+ possibleFileName.endsWith(DOUBLE_QUOTE_STRING)) ||
+ (possibleFileName.startsWith(SINGLE_QUOTE_STRING) &&
+ possibleFileName.endsWith(SINGLE_QUOTE_STRING))) {
+ possibleFileName = possibleFileName.substring(1, possibleFileName.length()-1).trim();
+ }
+ if (possibleFileName.endsWith(".c") || //$NON-NLS-1$
+ possibleFileName.endsWith(".cpp") || //$NON-NLS-1$
+ possibleFileName.endsWith(".cc") || //$NON-NLS-1$
+ possibleFileName.endsWith(".cxx") || //$NON-NLS-1$
+ possibleFileName.endsWith(".C") || //$NON-NLS-1$
+ possibleFileName.endsWith(".CPP") || //$NON-NLS-1$
+ possibleFileName.endsWith(".CC") || //$NON-NLS-1$
+ possibleFileName.endsWith(".CXX") || //$NON-NLS-1$
+ possibleFileName.endsWith(".c++")) { //$NON-NLS-1$
+
+ fileName = token;
+ }
+ }
+ }
+
+ if (fileName != null && fileName.startsWith("/cygdrive/")) { //$NON-NLS-1$
+ fileName= AbstractGCCBOPConsoleParserUtility.convertCygpath(new Path(fileName)).toOSString();
+ }
+
+ IProject project = getProject();
+ IFile file = null;
+ List translatedIncludes = includes;
+ if (includes.size() > 0) {
+ if (fileName != null) {
+ if (fUtil != null) {
+ file = fUtil.findFile(fileName);
+ if (file != null) {
+ project = file.getProject();
+ translatedIncludes = fUtil.translateRelativePaths(file, fileName, includes);
+ }
+ }
+ }
+ else {
+ final String error = MakeMessages.getString("ConsoleParser.Filename_Missing_Error_Message"); //$NON-NLS-1$
+ TraceUtil.outputError(error, line);
+ if (fUtil != null) {
+ fUtil.generateMarker(getProject(), -1, error + line, IMarkerGenerator.SEVERITY_WARNING, null);
+ }
+ }
+ if (file == null && fUtil != null) { // real world case
+ // remove include paths since there was no chance to translate them
+ translatedIncludes.clear();
+ }
+ }
+ // Contribute discovered includes and symbols to the ScannerInfoCollector
+ if (translatedIncludes.size() > 0 || symbols.size() > 0) {
+ Map scannerInfo = new HashMap();
+ scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, translatedIncludes);
+ scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols);
+ scannerInfo.put(ScannerInfoTypes.TARGET_SPECIFIC_OPTION, targetSpecificOptions);
+ getCollector().contributeToScannerConfig(project, scannerInfo);
+
+ TraceUtil.outputTrace("Discovered scanner info for file \'" + fileName + '\'', //$NON-NLS-1$
+ "Include paths", includes, translatedIncludes, "Defined symbols", symbols); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * @param line
+ * @return list of tokens
+ */
+ private List tokenize(String line) {
+ List rv = new ArrayList(2);
+ // find special characters that need to be matched: `, ' and "
+ // First Matching Chararcter
+ int prevFmc = line.length();
+ int emc = -1;
+ char matchingChar = 0;
+ for (int i = 0; i < matchingChars.length; ++i) {
+ char ch = matchingChars[i];
+ int fmc = line.indexOf(ch);
+ if (fmc > -1 && fmc < prevFmc) {
+ emc = line.indexOf(ch, fmc+1);
+ if (emc > fmc) {
+ matchingChar = ch;
+ prevFmc = fmc;
+ }
+ }
+ }
+ if (matchingChar != 0) { // found matched chars
+ String prefix = line.substring(0, prevFmc).trim();
+ rv.addAll(Arrays.asList(prefix.split("\\s+")));//$NON-NLS-1$
+
+ rv.add(line.substring(prevFmc, emc+1));
+
+ // recursion
+ rv.addAll(tokenize(line.substring(emc+1).trim()));
+ }
+ else {
+ rv.addAll(Arrays.asList(line.split("\\s+")));//$NON-NLS-1$
+ }
+ return rv;
+ }
+
+ /**
+ * @param line
+ * @param includes
+ */
+ private void parseLineForIncludePaths(String line, List includes) {
+ final String fDashI = "-I"; //$NON-NLS-1$
+ int prevIndex = 0;
+ for (int index = line.indexOf(fDashI, prevIndex); index != -1;
+ prevIndex = index+2, index = line.indexOf(fDashI, prevIndex)) {
+ String delimiter = "\\s+"; //$NON-NLS-1$
+ if (line.charAt(index-1) == '\'' || line.charAt(index-1) == '\"') {
+ // look for only one more ' or "
+ delimiter = String.valueOf(line.charAt(index-1));
+ }
+ String postfix = line.substring(index+2).trim();
+ if (postfix.charAt(0) == '-') { // empty -I
+ continue;
+ }
+ if (postfix.startsWith(SINGLE_QUOTE_STRING) || postfix.startsWith(DOUBLE_QUOTE_STRING)) {
+ delimiter = postfix.substring(0, 1);
+ }
+ String[] tokens = postfix.split(delimiter);
+ int tokIndex = (tokens.length > 1 && tokens[0].length() == 0) ? 1 : 0;
+ String iPath = tokens[tokIndex];
+ String temp = iPath;
+ // check for '\ '
+ for (++tokIndex; (temp.endsWith("\\") && tokIndex < tokens.length && //$NON-NLS-1$
+ tokens[tokIndex].length() > 0 && !tokens[tokIndex].startsWith("-")); //$NON-NLS-1$
+ ++tokIndex) {
+ int beg = postfix.indexOf(temp)+temp.length();
+ int end = postfix.indexOf(tokens[tokIndex])+tokens[tokIndex].length();
+ iPath = iPath.substring(0, iPath.length()-1) + postfix.substring(beg, end);
+ temp += postfix.substring(beg, end);
+ }
+ String nPath = iPath;
+ if (fUtil != null) {
+ nPath = fUtil.normalizePath(iPath);
+ }
+ if (!includes.contains(nPath)) {
+ includes.add(nPath);
+ }
+ }
+ }
+
+ /**
+ * @param line
+ * @param symbols
+ */
+ private void parseLineForSymbolDefinitions(String line, List symbols) {
+ final String fDashD = "-D"; //$NON-NLS-1$
+ int prevIndex = 0;
+ String delimiter = null;
+ String splitRegex = "\\s+"; //$NON-NLS-1$
+ for (int index = line.indexOf(fDashD, prevIndex); index != -1;
+ prevIndex = index+2, index = line.indexOf(fDashD, prevIndex)) {
+ int nDelimiterSymbols = 2;
+ String postfix = line.substring(index+2).trim();
+ if (postfix.charAt(0) == '-') { // empty -D
+ continue;
+ }
+ if (line.charAt(index-1) == '\'' || line.charAt(index-1) == '\"') {
+ // look for only one more ' or "
+ delimiter = String.valueOf(line.charAt(index-1));
+ nDelimiterSymbols = 1;
+ }
+ else {
+ String[] tokens = postfix.split(splitRegex, 2);
+ if (tokens.length > 0 && tokens[0].length() > 0) {
+ int sQuoteIndex = tokens[0].indexOf(SINGLE_QUOTE_STRING);
+ int dQuoteIndex = tokens[0].indexOf(DOUBLE_QUOTE_STRING);
+ if (sQuoteIndex == -1 && dQuoteIndex == -1) {
+ // simple case, no quotes
+ if (!symbols.contains(tokens[0])) {
+ symbols.add(tokens[0]);
+ }
+ continue;
+ }
+ else {
+ delimiter = (sQuoteIndex != -1 && (dQuoteIndex == -1 || sQuoteIndex < dQuoteIndex)) ? SINGLE_QUOTE_STRING : DOUBLE_QUOTE_STRING;
+ }
+ }
+ else
+ continue;
+ }
+
+ // find next matching delimiter
+ int nextDelimiterIndex = -1;
+ int prevDelimiterIndex = -1;
+ do {
+ nextDelimiterIndex = postfix.indexOf(delimiter, nextDelimiterIndex+1);
+ if (nextDelimiterIndex == 0 || (nextDelimiterIndex > 0 && postfix.charAt(nextDelimiterIndex-1) != '\\')) {
+ --nDelimiterSymbols;
+ if (nDelimiterSymbols > 0) {
+ prevDelimiterIndex = nextDelimiterIndex;
+ }
+ }
+ }
+ while (nDelimiterSymbols > 0 && nextDelimiterIndex != -1);
+ if (nDelimiterSymbols > 0)
+ continue; // non matching delimiter
+
+ // take everything up to the last delimiter
+ boolean bStartsWithDelimiter = postfix.startsWith(delimiter);
+ String symbol = postfix.substring(bStartsWithDelimiter ? 1 : 0, nextDelimiterIndex);
+ if (!bStartsWithDelimiter) {
+ // there is still a delimiter to be removed
+ if (prevDelimiterIndex != -1) {
+ symbol = symbol.substring(0, prevDelimiterIndex) + symbol.substring(prevDelimiterIndex+1);
+ }
+ }
+ // transform '\"' into '"'
+ if (delimiter.equals(DOUBLE_QUOTE_STRING)) {
+ symbol = symbol.replaceAll("\\\\\"", DOUBLE_QUOTE_STRING); //$NON-NLS-1$
+ }
+ if (!symbols.contains(symbol)) {
+ symbols.add(symbol);
+ }
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java
new file mode 100644
index 00000000000..7e378667105
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Parses output of gcc -c -v specs.c or
+ * g++ -c -v specs.cpp
+ * command
+ *
+ * @author vhirsl
+ */
+public class GCCSpecsConsoleParser implements IScannerInfoConsoleParser {
+ private final String INCLUDE = "#include"; //$NON-NLS-1$
+ private final String DEFINE = "#define"; //$NON-NLS-1$
+
+ private IProject fProject = null;
+ private IScannerInfoCollector fCollector = null;
+
+ private boolean expectingIncludes = false;
+ private List symbols = new ArrayList();
+ private List includes = new ArrayList();
+
+ /* (non-Javadoc)
+ * @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)
+ */
+ public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) {
+ this.fProject = project;
+ this.fCollector = collector;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParser#processLine(java.lang.String)
+ */
+ public boolean processLine(String line) {
+ boolean rc = false;
+ TraceUtil.outputTrace("GCCSpecsConsoleParser parsing line: [", line, "]"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // contribution of -dD option
+ if (line.startsWith(DEFINE)) {
+ String[] defineParts = line.split("\\s+", 3); //$NON-NLS-1$
+ if (defineParts[0].equals(DEFINE)) {
+ String symbol = null;
+ switch (defineParts.length) {
+ case 2:
+ symbol = defineParts[1];
+ break;
+ case 3:
+ symbol = defineParts[1] + "=" + defineParts[2]; //$NON-NLS-1$
+ break;
+ }
+ if (symbol != null && !symbols.contains(symbol)) { //$NON-NLS-1$
+ symbols.add(symbol);
+ }
+ }
+ }
+ // now get all the includes
+ else if (line.startsWith(INCLUDE) && line.endsWith("search starts here:")) { //$NON-NLS-1$
+ expectingIncludes = true;
+ }
+ else if (line.startsWith("End of search list.")) { //$NON-NLS-1$
+ expectingIncludes = false;
+ }
+ else if (expectingIncludes) {
+ if (!includes.contains(line))
+ includes.add(line);
+ }
+
+ return rc;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParser#shutdown()
+ */
+ public void shutdown() {
+ Map scannerInfo = new HashMap();
+ scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, includes);
+ scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols);
+ fCollector.contributeToScannerConfig(fProject, scannerInfo);
+ TraceUtil.outputTrace("Scanner info from \'specs\' file", //$NON-NLS-1$
+ "Include paths", includes, new ArrayList(), "Defined symbols", symbols); //$NON-NLS-1$ //$NON-NLS-2$);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java
new file mode 100644
index 00000000000..2ee24b12b77
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136)
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Implements error reporting mechanism and file/path translation mechanism
+ * Taken from ErrorParserManager and modified.
+ *
+ * @author vhirsl
+ */
+public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParserUtility {
+ /*
+ * For tracking the location of files being compiled
+ */
+ private Map fFilesInProject;
+ private List fCollectedFiles;
+ private List fNameConflicts;
+
+ public ScannerInfoConsoleParserUtility(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) {
+ super(project, workingDirectory, markerGenerator);
+
+ fFilesInProject = new HashMap();
+ fCollectedFiles = new ArrayList();
+ fNameConflicts = new ArrayList();
+
+ collectFiles(getProject(), fCollectedFiles);
+
+ for (int i = 0; i < fCollectedFiles.size(); i++) {
+ IFile curr = (IFile) fCollectedFiles.get(i);
+ Object existing = fFilesInProject.put(curr.getName(), curr);
+ if (existing != null) {
+ fNameConflicts.add(curr.getName());
+ }
+ }
+ }
+
+ /**
+ * Called by the console line parsers to find a file with a given name.
+ * @param fileName
+ * @return IFile or null
+ */
+ public IFile findFile(String fileName) {
+ IFile file = findFilePath(fileName);
+ if (file == null) {
+ // Try the project's map.
+ file = findFileName(fileName);
+ if (file != null) {
+ // If there is a conflict then try all files in the project.
+ if (isConflictingName(fileName)) {
+ file = null;
+
+ // Create a problem marker
+ final String error = MakeMessages.getString("ConsoleParser.Ambiguous_Filepath_Error_Message"); //$NON-NLS-1$
+ TraceUtil.outputError(error, fileName);
+ generateMarker(getProject(), -1, error+fileName, IMarkerGenerator.SEVERITY_WARNING, null);
+ }
+ }
+ }
+ return file;
+ }
+
+ /**
+ * @param filePath
+ * @return
+ */
+ protected IFile findFilePath(String filePath) {
+ IPath path = null;
+ IPath fp = new Path(filePath);
+ if (fp.isAbsolute()) {
+ if (getBaseDirectory().isPrefixOf(fp)) {
+ int segments = getBaseDirectory().matchingFirstSegments(fp);
+ path = fp.removeFirstSegments(segments);
+ } else {
+ path = fp;
+ }
+ } else {
+ path = getWorkingDirectory().append(filePath);
+ }
+
+ IFile file = null;
+ // The workspace may throw an IllegalArgumentException
+ // Catch it and the parser should fallback to scan the entire project.
+ try {
+ file = findFileInWorkspace(path);
+ } catch (Exception e) {
+ }
+
+ // We have to do another try, on Windows for cases like "TEST.C" vs "test.c"
+ // We use the java.io.File canonical path.
+ if (file == null || !file.exists()) {
+ File f = path.toFile();
+ try {
+ String canon = f.getCanonicalPath();
+ path = new Path(canon);
+ file = findFileInWorkspace(path);
+ } catch (IOException e1) {
+ }
+ }
+ return (file != null && file.exists()) ? file : null;
+ }
+
+ /**
+ * @param fileName
+ * @return
+ */
+ protected IFile findFileName(String fileName) {
+ IPath path = new Path(fileName);
+ return (IFile) fFilesInProject.get(path.lastSegment());
+ }
+
+ protected IFile findFileInWorkspace(IPath path) {
+ IFile file = null;
+ if (path.isAbsolute()) {
+ IWorkspaceRoot root = getProject().getWorkspace().getRoot();
+ file = root.getFileForLocation(path);
+ // It may be a link resource so we must check it also.
+ if (file == null) {
+ IFile[] files = root.findFilesForLocation(path);
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].getProject().equals(getProject())) {
+ file = files[i];
+ break;
+ }
+ }
+ }
+
+ } else {
+ file = getProject().getFile(path);
+ }
+ return file;
+ }
+
+ protected void collectFiles(IContainer parent, List result) {
+ try {
+ IResource[] resources = parent.members();
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ if (resource instanceof IFile) {
+ result.add(resource);
+ } else if (resource instanceof IContainer) {
+ collectFiles((IContainer) resource, result);
+ }
+ }
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e.getStatus());
+ }
+ }
+
+ protected boolean isConflictingName(String fileName) {
+ IPath path = new Path(fileName);
+ return fNameConflicts.contains(path.lastSegment());
+ }
+
+ public List translateRelativePaths(IFile file, String fileName, List includes) {
+ List translatedIncludes = new ArrayList(includes.size());
+ for (Iterator i = includes.iterator(); i.hasNext(); ) {
+ String include = (String) i.next();
+ IPath includePath = new Path(include);
+ if (!includePath.isAbsolute() && !includePath.isUNC()) { // do not translate UNC paths
+ // First try the current working directory
+ IPath cwd = getWorkingDirectory();
+ if (!cwd.isAbsolute()) {
+ cwd = getBaseDirectory().append(cwd);
+ }
+
+ IPath filePath = new Path(fileName);
+ if (!filePath.isAbsolute()) {
+ // check if the cwd is the right one
+ // appending fileName to cwd should yield file path
+ filePath = cwd.append(fileName);
+ }
+ if (!filePath.toString().equalsIgnoreCase(file.getLocation().toString())) {
+ // must be the cwd is wrong
+ // check if file name starts with ".."
+ if (fileName.startsWith("..")) { //$NON-NLS-1$
+ // probably multiple choices for cwd, hopeless
+ final String error = MakeMessages.getString("ConsoleParser.Working_Directory_Error_Message"); //$NON-NLS-1$
+ TraceUtil.outputError(error, fileName); //$NON-NLS-1$
+ generateMarker(file, -1, error, IMarkerGenerator.SEVERITY_WARNING, fileName);
+ break;
+ }
+ else {
+ // remove common segments at the end
+ IPath tPath = new Path(fileName);
+ if (fileName.startsWith(".")) { //$NON-NLS-1$
+ tPath = tPath.removeFirstSegments(1);
+ }
+ // get the file path from the file
+ filePath = file.getLocation();
+ IPath lastFileSegment = filePath.removeFirstSegments(filePath.segmentCount() - tPath.segmentCount());
+ if (lastFileSegment.matchingFirstSegments(tPath) == tPath.segmentCount()) {
+ cwd = filePath.removeLastSegments(tPath.segmentCount());
+ }
+ }
+ }
+
+ IPath candidatePath = cwd.append(includePath);
+ File dir = candidatePath.toFile();
+ include = candidatePath.toString();
+ if (!dir.exists()) {
+ final String error = MakeMessages.getString("ConsoleParser.Nonexistent_Include_Path_Error_Message"); //$NON-NLS-1$
+ TraceUtil.outputError(error, include);
+// generateMarker(file, -1, error+include, IMarkerGenerator.SEVERITY_WARNING, fileName);
+ }
+ }
+ // TODO VMIR for now add unresolved paths as well
+ translatedIncludes.add(include);
+ }
+ return translatedIncludes;
+ }
+
+ public String normalizePath(String path) {
+ int column = path.indexOf(':');
+ if (column > 0) {
+ char driveLetter = path.charAt(column - 1);
+ if (Character.isLowerCase(driveLetter)) {
+ StringBuffer sb = new StringBuffer();
+ if (column - 1 > 0) {
+ sb.append(path.substring(0, column-1));
+ }
+ sb.append(Character.toUpperCase(driveLetter));
+ sb.append(path.substring(column));
+ path = sb.toString();
+ }
+ }
+ if (path.indexOf('.') == -1 || path.equals(".")) { //$NON-NLS-1$
+ return (new Path(path)).toString(); // convert separators to '/'
+ }
+ // lose "./" segments since they confuse the Path normalization
+ StringBuffer buf = new StringBuffer(path);
+ int len = buf.length();
+ StringBuffer newBuf = new StringBuffer(buf.length());
+ int scp = 0; // starting copy point
+ int ssp = 0; // starting search point
+ int sdot;
+ boolean validPrefix;
+ while (ssp < len && (sdot = buf.indexOf(".", ssp)) != -1) { //$NON-NLS-1$
+ validPrefix = false;
+ int ddot = buf.indexOf("..", ssp);//$NON-NLS-1$
+ if (sdot < ddot || ddot == -1) {
+ newBuf.append(buf.substring(scp, sdot));
+ scp = sdot;
+ ssp = sdot + 1;
+ if (ssp < len) {
+ if (sdot == 0 || buf.charAt(sdot - 1) == '/' || buf.charAt(sdot - 1) == '\\') {
+ validPrefix = true;
+ }
+ char nextChar = buf.charAt(ssp);
+ if (validPrefix && nextChar == '/') {
+ ++ssp;
+ scp = ssp;
+ }
+ else if (validPrefix && nextChar == '\\') {
+ ++ssp;
+ if (ssp < len - 1 && buf.charAt(ssp) == '\\') {
+ ++ssp;
+ }
+ scp = ssp;
+ }
+ else {
+ // no path delimiter, must be '.' inside the path
+ scp = ssp - 1;
+ }
+ }
+ }
+ else if (sdot == ddot) {
+ ssp = sdot + 2;
+ }
+ }
+ newBuf.append(buf.substring(scp, len));
+
+ IPath orgPath = new Path(newBuf.toString());
+ return orgPath.toString();
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/BuildOutputReaderJob.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/BuildOutputReaderJob.java
new file mode 100644
index 00000000000..bdef3d51512
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/BuildOutputReaderJob.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.jobs;
+
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+
+/**
+ * Build output reader job
+ *
+ * @author vhirsl
+ */
+public class BuildOutputReaderJob extends Job {
+ private static final String JOB_NAME = "Build Output Reader"; //$NON-NLS-1$
+
+ private IResource resource;
+ private InfoContext context;
+ private IScannerConfigBuilderInfo2 buildInfo;
+
+ /**
+ * @param project
+ * @param buildInfo
+ */
+ public BuildOutputReaderJob(IProject project, IScannerConfigBuilderInfo2 buildInfo) {
+ this(project, new InfoContext(project), buildInfo);
+ }
+
+ public BuildOutputReaderJob(IProject project, InfoContext context, IScannerConfigBuilderInfo2 buildInfo) {
+ super(JOB_NAME);
+ this.resource = project;
+ this.context = context;
+ this.buildInfo = buildInfo;
+ setUser(true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+ IProject project = resource.getProject();
+ monitor.beginTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder"), 100); //$NON-NLS-1$
+ monitor.subTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder") + //$NON-NLS-1$
+ project.getName());
+
+ boolean rc = SCJobsUtil.readBuildOutputFile(project, buildInfo, new SubProgressMonitor(monitor, 70));
+ rc |= SCJobsUtil.getProviderScannerInfo(project, context, buildInfo, new SubProgressMonitor(monitor, 20));
+ if (rc) {
+ rc = SCJobsUtil.updateScannerConfiguration(project, context, buildInfo, new SubProgressMonitor(monitor, 10));
+ }
+
+ monitor.done();
+ return (rc == true) ? Status.OK_STATUS : Status.CANCEL_STATUS;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/SCJobsUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/SCJobsUtil.java
new file mode 100644
index 00000000000..1b9785b123d
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/jobs/SCJobsUtil.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.jobs;
+
+import java.util.List;
+
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Utility class for build and job related functionality
+ *
+ * @author vhirsl
+ */
+public class SCJobsUtil {
+ private static class RC {
+ public RC(boolean init) {
+ rc = init;
+ }
+ /**
+ * @return Returns the rc.
+ */
+ public boolean get() {
+ return rc;
+ }
+ /**
+ * @param rc The rc to set.
+ */
+ public void set(boolean rc) {
+ this.rc = rc;
+ }
+
+ public String toString() {
+ return rc ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ private boolean rc;
+ }
+ /**
+ * Call ESI providers to get scanner info
+ *
+ * @param collector
+ * @param buildInfo
+ * @param monitor
+ */
+ public static boolean getProviderScannerInfo(final IProject project,
+ final IScannerConfigBuilderInfo2 buildInfo,
+ final IProgressMonitor monitor) {
+ return getProviderScannerInfo(project, new InfoContext(project), buildInfo, monitor);
+ }
+
+ public static boolean getProviderScannerInfo(final IProject project,
+ final InfoContext context,
+ final IScannerConfigBuilderInfo2 buildInfo,
+ final IProgressMonitor monitor) {
+
+ final RC rc = new RC(false);
+ // get the collector
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(project, context, buildInfo.getSelectedProfileId());
+ final IScannerInfoCollector collector = profileInstance.getScannerInfoCollector();
+
+ List providerIds = buildInfo.getProviderIdList();
+ for (int i = 0; i < providerIds.size(); ++i) {
+ final String providerId = (String) providerIds.get(i);
+ if (buildInfo.isProviderOutputParserEnabled(providerId)) {
+ final IExternalScannerInfoProvider esiProvider = profileInstance.
+ createExternalScannerInfoProvider(providerId);
+ if (esiProvider != null) {
+ ISafeRunnable runnable = new ISafeRunnable() {
+
+ public void run() {
+ esiProvider.invokeProvider(monitor, project, providerId, buildInfo, collector);
+ rc.set(true);
+ }
+
+ public void handleException(Throwable exception) {
+ rc.set(false);
+ MakeCorePlugin.log(exception);
+ }
+
+ };
+ Platform.run(runnable);
+ }
+ }
+ }
+ return rc.get();
+ }
+
+ /**
+ * Update and persist scanner configuration
+ *
+ * @param project
+ * @param buildInfo
+ * @param monitor
+ */
+ public static boolean updateScannerConfiguration(IProject project,
+ IScannerConfigBuilderInfo2 buildInfo,
+ final IProgressMonitor monitor) {
+ return updateScannerConfiguration(project, new InfoContext(project), buildInfo, monitor);
+ }
+
+ /**
+ * Update and persist scanner configuration
+ *
+ * @param project
+ * @param buildInfo
+ * @param monitor
+ */
+ public static boolean updateScannerConfiguration(IProject project,
+ InfoContext context,
+ IScannerConfigBuilderInfo2 buildInfo,
+ final IProgressMonitor monitor) {
+ final RC rc = new RC(false);
+ // get the collector
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(project, context, buildInfo.getSelectedProfileId());
+ IScannerInfoCollector collector = profileInstance.getScannerInfoCollector();
+ if (collector instanceof IScannerInfoCollector2) {
+ final IScannerInfoCollector2 collector2 = (IScannerInfoCollector2) collector;
+ ISafeRunnable runnable = new ISafeRunnable() {
+
+ public void run() throws Exception {
+ collector2.updateScannerConfiguration(monitor);
+ rc.set(true);
+ }
+
+ public void handleException(Throwable exception) {
+ rc.set(false);
+ MakeCorePlugin.log(exception);
+ }
+
+ };
+ Platform.run(runnable);
+ }
+
+ return rc.get();
+ }
+
+ /**
+ * @param project
+ * @param buildInfo
+ * @param monitor
+ * @return
+ */
+ public static boolean readBuildOutputFile(final IProject project,
+ final IScannerConfigBuilderInfo2 buildInfo,
+ final IProgressMonitor monitor) {
+ return readBuildOutputFile(project, new InfoContext(project), buildInfo, monitor);
+ }
+
+ /**
+ * @param project
+ * @param buildInfo
+ * @param monitor
+ * @return
+ */
+ public static boolean readBuildOutputFile(final IProject project,
+ final InfoContext context,
+ final IScannerConfigBuilderInfo2 buildInfo,
+ final IProgressMonitor monitor) {
+ final RC rc = new RC(false);
+ // get the collector
+ SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance().
+ getSCProfileInstance(project, context, buildInfo.getSelectedProfileId());
+ final IScannerInfoCollector collector = profileInstance.getScannerInfoCollector();
+ final IExternalScannerInfoProvider esiProvider = profileInstance.
+ createBuildOutputProvider();
+
+ if (buildInfo.isBuildOutputFileActionEnabled()) {
+ ISafeRunnable runnable = new ISafeRunnable() {
+
+ public void run() {
+ esiProvider.invokeProvider(monitor, project, null, buildInfo, collector);
+ rc.set(true);
+ }
+
+ public void handleException(Throwable exception) {
+ rc.set(false);
+ MakeCorePlugin.log(exception);
+ }
+
+ };
+ Platform.run(runnable);
+ }
+
+ return rc.get();
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java
new file mode 100644
index 00000000000..ecc6439f43b
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * Class that represents a compiler command and related scanner configuration
+ *
+ * @author vhirsl
+ */
+public class CCommandDSC {
+ private final static String SINGLE_SPACE = " "; //$NON-NLS-1$
+ private final static String CMD_DESCRIPTION_ELEM = "commandDescription"; //$NON-NLS-1$
+ private final static String CMD_SI_ELEM = "commandScannerInfo"; //$NON-NLS-1$
+ private final static String OPTION_ELEM = "option"; //$NON-NLS-1$
+ private final static String SI_ITEM_ELEM = "siItem"; //$NON-NLS-1$
+ private final static String KEY_ATTR = "key"; //$NON-NLS-1$
+ private final static String VALUE_ATTR = "value"; //$NON-NLS-1$
+ private final static String QUOTE_INCLUDE_ATTR = "quote"; //$NON-NLS-1$
+ private final static String KIND_ATTR = "kind"; //$NON-NLS-1$
+
+ private int commandId;
+ private List compilerCommand; // members are KVStringPair objects
+ private boolean discovered;
+ private boolean cppFileType; // C or C++ file type
+
+ private List symbols;
+ private List includes;
+ private List quoteIncludes;
+
+ /**
+ * @param cppFileType2
+ */
+ public CCommandDSC(boolean cppFileType) {
+ compilerCommand = new ArrayList();
+ discovered = false;
+ this.cppFileType = cppFileType;
+
+ symbols = new ArrayList();
+ includes = new ArrayList();
+ quoteIncludes = new ArrayList();
+ }
+
+ public boolean appliesToCPPFileType() {
+ return cppFileType;
+ }
+
+ public void addSCOption(KVStringPair option) {
+ compilerCommand.add(option);
+ }
+
+ /**
+ * @return
+ */
+ public Integer getCommandIdAsInteger() {
+ return new Integer(getCommandId());
+ }
+ /**
+ * @return Returns the commandId.
+ */
+ public int getCommandId() {
+ return commandId;
+ }
+ /**
+ * @param commandId The commandId to set.
+ */
+ public void setCommandId(int commandId) {
+ this.commandId = commandId;
+ }
+
+ public String toString() {
+ String commandAsString = new String();
+ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) {
+ KVStringPair optionPair = (KVStringPair)i.next();
+ commandAsString += optionPair.getKey() + SINGLE_SPACE +
+ optionPair.getValue() + SINGLE_SPACE;
+ }
+ return commandAsString.trim();
+ }
+
+ public int getId() {
+ return commandId;
+ }
+
+ /**
+ * Returns a command where -imacros and -include options have been removed
+ * @return
+ */
+ public String getSCDRunnableCommand(boolean quoteIncludePaths) {
+ String commandAsString = new String();
+ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) {
+ KVStringPair optionPair = (KVStringPair)i.next();
+ if (optionPair.getKey().equals(SCDOptionsEnum.COMMAND.toString())) {
+ commandAsString += optionPair.getValue() + SINGLE_SPACE;
+ }
+ else {
+ // skip -include and -imacros options
+ if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE.toString()) ||
+ optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE.toString()))
+ continue;
+ if (quoteIncludePaths) {
+ if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE.toString())) {
+ commandAsString += optionPair.getKey() + SINGLE_SPACE +
+ "\"" + optionPair.getValue() + "\"" + SINGLE_SPACE; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+ else {
+ commandAsString += optionPair.getKey() + SINGLE_SPACE +
+ optionPair.getValue() + SINGLE_SPACE;
+ }
+ }
+ }
+ return commandAsString.trim();
+ }
+
+ /**
+ * @return list of strings
+ */
+ public List getImacrosFile() {
+ List imacrosFiles = new ArrayList();
+ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) {
+ KVStringPair optionPair = (KVStringPair)i.next();
+ if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE.toString())) {
+ imacrosFiles.add(optionPair.getValue());
+ }
+ }
+ return imacrosFiles;
+ }
+
+ /**
+ * @return list of strings
+ */
+ public List getIncludeFile() {
+ List includeFiles = new ArrayList();
+ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) {
+ KVStringPair optionPair = (KVStringPair)i.next();
+ if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE.toString())) {
+ includeFiles.add(optionPair.getValue());
+ }
+ }
+ return includeFiles;
+ }
+
+// public List getFilesList() {
+// return files;
+// }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object arg0) {
+ if (arg0 != null && arg0.getClass().equals(this.getClass())) {
+ CCommandDSC other = (CCommandDSC)arg0;
+ return (compilerCommand.equals(other.compilerCommand) &&
+ cppFileType == other.cppFileType);
+ }
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return compilerCommand.hashCode();
+ }
+
+ /**
+ * @return Returns the includes as strings.
+ */
+ public List getIncludes() {
+ return includes;
+ }
+ /**
+ * @param includes The includes to set.
+ */
+ public void setIncludes(List includes) {
+ this.includes = includes;
+ }
+ /**
+ * @return Returns the quote include paths as strings (for #include "...")
+ */
+ public List getQuoteIncludes() {
+ return quoteIncludes;
+ }
+ /**
+ * @param includes. Quote include paths (for #include "...")
+ */
+ public void setQuoteIncludes(List includes) {
+ quoteIncludes = includes;
+ }
+ /**
+ * @return Returns the symbols.
+ */
+ public List getSymbols() {
+ return symbols;
+ }
+ /**
+ * @param symbols The symbols to set.
+ */
+ public void setSymbols(List symbols) {
+ this.symbols = symbols;
+ }
+ /**
+ * @return Returns the discovered.
+ */
+ public boolean isDiscovered() {
+ return discovered;
+ }
+ /**
+ * @param discovered The discovered to set.
+ */
+ public void setDiscovered(boolean discovered) {
+ this.discovered = discovered;
+ }
+
+ /**
+ * @param cmdElem
+ */
+ public void serialize(Element cmdElem) {
+ Document doc = cmdElem.getOwnerDocument();
+ // serialize the command
+ Element cmdDescElem = doc.createElement(CMD_DESCRIPTION_ELEM);
+ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) {
+ Element optionElem = doc.createElement(OPTION_ELEM);
+ KVStringPair option = (KVStringPair) i.next();
+ optionElem.setAttribute(KEY_ATTR, option.getKey());
+ optionElem.setAttribute(VALUE_ATTR, option.getValue());
+ cmdDescElem.appendChild(optionElem);
+ }
+ cmdElem.appendChild(cmdDescElem);
+ // serialize includes and symbols
+ Element siElem = doc.createElement(CMD_SI_ELEM);
+ for (Iterator j = quoteIncludes.iterator(); j.hasNext(); ) {
+ Element siItem = doc.createElement(SI_ITEM_ELEM);
+ siItem.setAttribute(KIND_ATTR, "INCLUDE_PATH"); //$NON-NLS-1$
+ siItem.setAttribute(VALUE_ATTR, (String) j.next());
+ siItem.setAttribute(QUOTE_INCLUDE_ATTR, "true"); //$NON-NLS-1$
+ siElem.appendChild(siItem);
+ }
+ for (Iterator j = includes.iterator(); j.hasNext(); ) {
+ Element siItem = doc.createElement(SI_ITEM_ELEM);
+ siItem.setAttribute(KIND_ATTR, "INCLUDE_PATH"); //$NON-NLS-1$
+ siItem.setAttribute(VALUE_ATTR, (String) j.next());
+ siElem.appendChild(siItem);
+ }
+ for (Iterator j = symbols.iterator(); j.hasNext(); ) {
+ Element siItem = doc.createElement(SI_ITEM_ELEM);
+ siItem.setAttribute(KIND_ATTR, "SYMBOL_DEFINITION"); //$NON-NLS-1$
+ siItem.setAttribute(VALUE_ATTR, (String) j.next());
+ siElem.appendChild(siItem);
+ }
+ cmdElem.appendChild(siElem);
+ }
+
+ /**
+ * @param cmdElem
+ */
+ public void deserialize(Element cmdElem) {
+ // read command options
+ NodeList descList = cmdElem.getElementsByTagName(CMD_DESCRIPTION_ELEM);
+ if (descList.getLength() > 0) {
+ Element descElem = (Element) descList.item(0);
+ NodeList optionList = descElem.getElementsByTagName(OPTION_ELEM);
+ for (int i = 0; i < optionList.getLength(); ++i) {
+ Element optionElem = (Element) optionList.item(i);
+ String key = optionElem.getAttribute(KEY_ATTR);
+ String value = optionElem.getAttribute(VALUE_ATTR);
+ KVStringPair option = new KVStringPair(key, value);
+ addSCOption(option);
+ }
+ }
+ // read associated scanner info
+ NodeList siList = cmdElem.getElementsByTagName(CMD_SI_ELEM);
+ if (siList.getLength() > 0) {
+ Element siElem = (Element) siList.item(0);
+ NodeList siItemList = siElem.getElementsByTagName(SI_ITEM_ELEM);
+ for (int i = 0; i < siItemList.getLength(); ++i) {
+ Element siItemElem = (Element) siItemList.item(i);
+ String kind = siItemElem.getAttribute(KIND_ATTR);
+ String value = siItemElem.getAttribute(VALUE_ATTR);
+ String quote = siItemElem.getAttribute(QUOTE_INCLUDE_ATTR);
+ if (kind.equals("INCLUDE_PATH")) { //$NON-NLS-1$
+ if (quote.equals("true")) { //$NON-NLS-1$
+ quoteIncludes.add(value);
+ }
+ else {
+ includes.add(value);
+ }
+ }
+ else if (kind.equals("SYMBOL_DEFINITION")) { //$NON-NLS-1$
+ symbols.add(value);
+ }
+ }
+ setDiscovered(true);
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java
new file mode 100644
index 00000000000..281de5f4dac
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.core.ICExtensionReference;
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.SCMarkerGenerator;
+import org.eclipse.cdt.utils.CygPath;
+import org.eclipse.cdt.utils.ICygwinToolsFactroy;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Use binary parser's 'cygpath' command to translate cygpaths to absolute paths.
+ *
+ * @author vhirsl
+ */
+public class CygpathTranslator {
+ private static final String CYGPATH_ERROR_MESSAGE = "CygpathTranslator.NotAvailableErrorMessage"; //$NON-NLS-1$
+ private CygPath cygPath = null;
+ private boolean isAvailable = false;
+
+ public CygpathTranslator(IProject project) {
+ SCMarkerGenerator scMarkerGenerator = new SCMarkerGenerator();
+ try {
+ ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(project);
+ for (int i = 0; i < parserRef.length; i++) {
+ try {
+ IBinaryParser parser = (IBinaryParser)parserRef[i].createExtension();
+ ICygwinToolsFactroy cygwinToolFactory = (ICygwinToolsFactroy) parser.getAdapter(ICygwinToolsFactroy.class);
+ if (cygwinToolFactory != null) {
+ cygPath = cygwinToolFactory.getCygPath();
+ if (cygPath != null) {
+ isAvailable = true;
+ break;
+ }
+ }
+ } catch (ClassCastException e) {
+ }
+ }
+ // No CygPath specified in BinaryParser page or not supported.
+ // Hoping that cygpath is on the path.
+ if (cygPath == null && Platform.getOS().equals(Platform.OS_WIN32)) {
+ cygPath = new CygPath("cygpath"); //$NON-NLS-1$
+ isAvailable = true;
+ }
+ }
+ catch (CoreException e) {
+ }
+ catch (IOException e) {
+ isAvailable = false;
+ scMarkerGenerator = new SCMarkerGenerator();
+ scMarkerGenerator.addMarker(project, -1,
+ MakeMessages.getString(CYGPATH_ERROR_MESSAGE),
+ IMarkerGenerator.SEVERITY_WARNING, null);
+ }
+ if (isAvailable) {
+ // remove problem markers
+ scMarkerGenerator.removeMarker(project, -1,
+ MakeMessages.getString(CYGPATH_ERROR_MESSAGE),
+ IMarkerGenerator.SEVERITY_WARNING, null);
+ }
+ }
+
+ /**
+ * @param sumIncludes
+ * @return
+ */
+ public static List translateIncludePaths(IProject project, List sumIncludes) {
+ // first check if cygpath translation is needed at all
+ boolean translationNeeded = false;
+ if (Platform.getOS().equals(Platform.OS_WIN32)) {
+ for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) {
+ String include = (String) i.next();
+ if (include.startsWith("/")) { //$NON-NLS-1$
+ translationNeeded = true;
+ break;
+ }
+ }
+ }
+ if (!translationNeeded) {
+ return sumIncludes;
+ }
+
+ CygpathTranslator cygpath = new CygpathTranslator(project);
+ if (cygpath.cygPath == null) return sumIncludes;
+
+ List translatedIncludePaths = new ArrayList();
+ for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) {
+ String includePath = (String) i.next();
+ IPath realPath = new Path(includePath);
+ if (realPath.toFile().exists()) {
+ translatedIncludePaths.add(includePath);
+ }
+ else {
+ String translatedPath = includePath;
+ if (cygpath.isAvailable) {
+ try {
+ translatedPath = cygpath.cygPath.getFileName(includePath);
+ }
+ catch (IOException e) {
+ TraceUtil.outputError("CygpathTranslator unable to translate path: ", includePath); //$NON-NLS-1$
+ }
+ }
+ if (!translatedPath.equals(includePath)) {
+ // Check if the translated path exists
+ IPath transPath = new Path(translatedPath);
+ if (transPath.toFile().exists()) {
+ translatedIncludePaths.add(transPath.toPortableString());
+ }
+ else {
+ // TODO VMIR for now add even if it does not exist
+ translatedIncludePaths.add(translatedPath);
+ }
+ }
+ else {
+ // TODO VMIR for now add even if it does not exist
+ translatedIncludePaths.add(translatedPath);
+ }
+ }
+ }
+ cygpath.cygPath.dispose();
+ return translatedIncludePaths;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java
new file mode 100644
index 00000000000..26f45e381cf
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Key - Value (List) pair
+ *
+ * @author vhirsl
+ */
+public class KVList {
+ String key;
+ List value;
+
+ public KVList(String key) {
+ this.key = key;
+ this.value = new ArrayList();
+ }
+
+ /**
+ * List must not be <code>null</code>.
+ */
+ public KVList(String key, List value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ String getKey() {
+ return key;
+ }
+
+ List getValue() {
+ return value;
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVStringPair.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVStringPair.java
new file mode 100644
index 00000000000..4df20b5d79e
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVStringPair.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+/**
+ * Key - Value String Pair
+ *
+ * @author vhirsl
+ */
+public class KVStringPair {
+ private String key;
+ private String value;
+
+ /**
+ *
+ */
+ public KVStringPair(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object arg0) {
+ if (arg0 != null && arg0.getClass().equals(this.getClass())) {
+ KVStringPair arg = (KVStringPair) arg0;
+ return (key.equals(arg.getKey()) && value.equals(arg.getValue()));
+ }
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return 17 * key.hashCode() + value.hashCode();
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return key + " -> " + value; //$NON-NLS-1$
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/LogWriter.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/LogWriter.java
new file mode 100644
index 00000000000..74eef6af315
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/LogWriter.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * Log writer utility
+ *
+ * @author vhirsl
+ */
+public class LogWriter {
+ protected File logFile = null;
+ protected Writer log = null;
+ protected boolean newSession = true;
+
+ protected static final String SESSION = "*** SESSION";//$NON-NLS-1$
+ protected static final String ENTRY = "ENTRY";//$NON-NLS-1$
+ protected static final String SUBENTRY = "SUBENTRY";//$NON-NLS-1$
+ protected static final String MESSAGE = "MESSAGE";//$NON-NLS-1$
+ protected static final String STACK = "STACK";//$NON-NLS-1$
+
+ protected static final String LINE_SEPARATOR;
+ protected static final String TAB_STRING = "\t";//$NON-NLS-1$
+ protected static final long MAXLOG_SIZE = 10000000;
+ static {
+ String s = System.getProperty("line.separator");//$NON-NLS-1$
+ LINE_SEPARATOR = s == null ? "\n" : s;//$NON-NLS-1$
+ }
+
+ /**
+ *
+ */
+ public LogWriter(File log) {
+ this.logFile = log;
+ if(log.length() > MAXLOG_SIZE){
+ log.delete();
+ }
+ openLogFile();
+ }
+
+ protected void closeLogFile() throws IOException {
+ try {
+ if (log != null) {
+ log.flush();
+ log.close();
+ }
+ } finally {
+ log = null;
+ }
+ }
+
+ protected void openLogFile() {
+ try {
+ log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), "UTF-8"));//$NON-NLS-1$
+ if (newSession) {
+ writeHeader();
+ newSession = false;
+ }
+ } catch (IOException e) {
+ // there was a problem opening the log file so log to the console
+ //log = logForStream(System.err);
+ }
+ }
+ protected void writeHeader() throws IOException {
+ writeln();
+ write(SESSION);
+ writeSpace();
+ String date = getDate();
+ write(date);
+ writeSpace();
+ for (int i=SESSION.length()+date.length(); i<78; i++) {
+ write("-");//$NON-NLS-1$
+ }
+ writeln();
+ }
+
+ protected String getDate() {
+ try {
+ DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
+ return formatter.format(new Date());
+ } catch (Exception e) {
+ // If there were problems writing out the date, ignore and
+ // continue since that shouldn't stop us from losing the rest
+ // of the information
+ }
+ return Long.toString(System.currentTimeMillis());
+ }
+
+ /**
+ * Writes the given string to the log, followed by the line terminator string.
+ */
+ public void writeln(String s) throws IOException {
+ write(s);
+ writeln();
+ }
+ /**
+ * Shuts down the log.
+ */
+ public synchronized void shutdown() {
+ try {
+ if (logFile != null) {
+ closeLogFile();
+ logFile = null;
+ } else {
+ if (log != null) {
+ Writer old = log;
+ log = null;
+ old.flush();
+ old.close();
+ }
+ }
+ } catch (Exception e) {
+ //we've shutdown the log, so not much else we can do!
+ e.printStackTrace();
+ }
+ }
+
+ protected void write(Throwable throwable) throws IOException {
+ if (throwable == null)
+ return;
+ write(STACK);
+ writeSpace();
+ boolean isCoreException = throwable instanceof CoreException;
+ if (isCoreException)
+ writeln("1");//$NON-NLS-1$
+ else
+ writeln("0");//$NON-NLS-1$
+ throwable.printStackTrace(new PrintWriter(log));
+ if (isCoreException) {
+ CoreException e = (CoreException) throwable;
+ write(e.getStatus(), 0);
+ }
+ }
+
+ public synchronized void log(IStatus status){
+ try {
+ this.write(status, 0);
+ } catch (IOException e) {
+ }
+ }
+ protected void write(IStatus status, int depth) throws IOException {
+ if (depth == 0) {
+ write(ENTRY);
+ } else {
+ write(SUBENTRY);
+ writeSpace();
+ write(Integer.toString(depth));
+ }
+ writeSpace();
+ write(status.getPlugin());
+ writeSpace();
+ write(Integer.toString(status.getSeverity()));
+ writeSpace();
+ write(Integer.toString(status.getCode()));
+ writeSpace();
+ write(getDate());
+ writeln();
+
+ write(MESSAGE);
+ writeSpace();
+ writeln(status.getMessage());
+
+ //Took out the stack dump - too much space
+ //write(status.getException());
+
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ write(children[i], depth+1);
+ }
+ }
+ }
+
+ protected void writeln() throws IOException {
+ write(LINE_SEPARATOR);
+ }
+ protected void write(String message) throws IOException {
+ if (message != null)
+ log.write(message);
+ }
+ protected void writeSpace() throws IOException {
+ write(" ");//$NON-NLS-1$
+ }
+
+ public synchronized void flushLog(){
+ try {
+ log.flush();
+ } catch (IOException e) {}
+ }
+
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java
new file mode 100644
index 00000000000..376efa68ef3
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+/**
+ * Enumeration class for scanner configuration affecting command line options
+ *
+ * @author vhirsl
+ */
+public final class SCDOptionsEnum {
+
+ public static final SCDOptionsEnum COMMAND = new SCDOptionsEnum(0); // gcc or similar command
+ public static final int MIN = 1;
+ public static final SCDOptionsEnum DEFINE = new SCDOptionsEnum(1); // -D name
+ public static final SCDOptionsEnum UNDEFINE = new SCDOptionsEnum(2); // -U name
+ public static final SCDOptionsEnum IDASH = new SCDOptionsEnum(3); // -I-
+ public static final SCDOptionsEnum INCLUDE = new SCDOptionsEnum(4); // -I dir
+ public static final SCDOptionsEnum NOSTDINC = new SCDOptionsEnum(5); // -nostdinc
+ public static final SCDOptionsEnum NOSTDINCPP = new SCDOptionsEnum(6); // -nostdinc++
+ public static final SCDOptionsEnum INCLUDE_FILE = new SCDOptionsEnum(7); // -include file
+ public static final SCDOptionsEnum IMACROS_FILE = new SCDOptionsEnum(8); // -imacros file
+ public static final SCDOptionsEnum IDIRAFTER = new SCDOptionsEnum(9); // -idirafter dir
+ public static final SCDOptionsEnum ISYSTEM = new SCDOptionsEnum(10); // -isystem dir
+ public static final SCDOptionsEnum IPREFIX = new SCDOptionsEnum(11); // -iprefix prefix
+ public static final SCDOptionsEnum IWITHPREFIX = new SCDOptionsEnum(12); // -iwithprefix dir
+ public static final SCDOptionsEnum IWITHPREFIXBEFORE = new SCDOptionsEnum(13); // -iwithprefixbefore dir
+ public static final int MAX = 13;
+
+ private static final String[] SCDOPTION_STRING_VALS = {
+ "cc", //$NON-NLS-1$
+ "-D", //$NON-NLS-1$
+ "-U", //$NON-NLS-1$
+ "-I-", //$NON-NLS-1$
+ "-I", //$NON-NLS-1$
+ "-nostdinc", //$NON-NLS-1$
+ "-nostdinc++", //$NON-NLS-1$
+ "-include", //$NON-NLS-1$
+ "-imacros", //$NON-NLS-1$
+ "-idirafter", //$NON-NLS-1$
+ "-isystem", //$NON-NLS-1$
+ "-iprefix", //$NON-NLS-1$
+ "-iwithprefix", //$NON-NLS-1$
+ "-iwithprefixbefore" //$NON-NLS-1$
+ };
+ private static final SCDOptionsEnum SCDOPTIONS[] = {
+ COMMAND, DEFINE, UNDEFINE, IDASH, INCLUDE, NOSTDINC, NOSTDINCPP, INCLUDE_FILE, IMACROS_FILE,
+ IDIRAFTER, ISYSTEM, IPREFIX, IWITHPREFIX, IWITHPREFIXBEFORE
+ };
+
+ /**
+ *
+ */
+ private SCDOptionsEnum(int val) {
+ this._enum = val;
+ }
+
+ public int getEnumValue() {
+ return _enum;
+ }
+
+ public static SCDOptionsEnum getSCDOptionsEnum(int val) {
+ if (val >= 0 && val <= MAX) {
+ return SCDOPTIONS[val];
+ }
+ return null;
+ }
+
+ public static SCDOptionsEnum getSCDOptionsEnum(String desc) {
+ for (int i = 0; i <= MAX; ++i) {
+ if (desc.equals(SCDOPTION_STRING_VALS[i])) {
+ return SCDOPTIONS[i];
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object arg0) {
+ if (arg0 == null) return false;
+ if (arg0 == this) return true;
+ if (arg0 instanceof SCDOptionsEnum) return (_enum == ((SCDOptionsEnum)arg0)._enum);
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return _enum*17 + 11;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return SCDOPTION_STRING_VALS[_enum];
+ }
+
+ private final int _enum;
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java
new file mode 100644
index 00000000000..0066722a245
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Represents a symbol definition with possible multiple values
+ * example:
+ * LOG_LEVEL
+ * LOG_LEVEL = 2
+ * LOG_LEVEL = LOG_BASE + 1
+ * @author vhirsl
+ */
+public class SymbolEntry {
+ private static final String UNSPECIFIED_VALUE = "1"; //$NON-NLS-1$
+ private String name;
+ private Map values; // Values can be either in the active (selected) group or in the removed group
+
+// public SymbolEntry(String name) {
+// this.name = name;
+// }
+
+ public SymbolEntry(String name, String value) {
+ this(name, value, true);
+ }
+ public SymbolEntry(String name, String value, boolean active) {
+ this.name = name;
+ if (values == null) {
+ values = new LinkedHashMap(1);
+ }
+ values.put(value, Boolean.valueOf(active));
+ }
+ public SymbolEntry(SymbolEntry se) {
+ name = se.name;
+ // deep copy
+ values = new LinkedHashMap(se.values.size());
+ for (Iterator i = se.values.keySet().iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ Boolean value = (Boolean) se.values.get(key);
+ values.put(key, Boolean.valueOf(value.booleanValue()));
+ }
+ }
+
+ public boolean add(String value) {
+ return add(value, true);
+ }
+ public boolean add(String value, boolean active) {
+ boolean rc = false;
+ if (!values.containsKey(value)) {
+ values.put(value, Boolean.valueOf(active));
+ rc = true;
+ }
+ return rc;
+ }
+ public void replace(String value, boolean active) {
+ values.put(value, Boolean.valueOf(active));
+ }
+
+// private void addAll(SymbolEntry se) {
+// values.putAll(se.values);
+// }
+
+ public void remove(String value) {
+ values.remove(value);
+ }
+ public void removeAll() {
+ values = null;
+ }
+
+ public List getActive() {
+ return get(true, true, true);
+ }
+ public List getActiveRaw() {
+ return get(false, true, true);
+ }
+
+ public List getRemoved() {
+ return get(true, true, false);
+ }
+ public List getRemovedRaw() {
+ return get(false, true, false);
+ }
+
+ public List getAll() {
+ return get(true, false, true /*don't care*/);
+ }
+ public List getAllRaw() {
+ return get(false, false, true /*don't care*/);
+ }
+
+ /**
+ * Utility function to retrieve values as a set.
+ *
+ * @param format - false = raw
+ * @param subset - false = all
+ * @param active - false = removed
+ * @return List
+ */
+ private List get(boolean format, boolean subset, boolean active) {
+ List rv = new ArrayList(values.size());
+ for (Iterator i = values.keySet().iterator(); i.hasNext(); ) {
+ String val = (String) i.next();
+ if (subset && ((Boolean) values.get(val)).booleanValue() != active)
+ continue;
+ if (format) {
+ rv.add(name + "=" + (val == null ? UNSPECIFIED_VALUE : val));//$NON-NLS-1$
+ }
+ else {
+ rv.add(name + (val == null ? "" : "=" + val));//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return rv;
+ }
+ /**
+ * Returns only value part of all active entries
+ * @return List
+ */
+ public List getValuesOnly(boolean active) {
+ List rv = new ArrayList(values.size());
+ for (Iterator i = values.keySet().iterator(); i.hasNext(); ) {
+ String val = (String) i.next();
+ if (((Boolean) values.get(val)).booleanValue() == active) {
+ rv.add(val == null ? UNSPECIFIED_VALUE : val);
+ }
+ }
+ return rv;
+ }
+
+ public int numberOfValues() {
+ return values.size();
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(name);
+ buffer.append(':');
+ for (Iterator i = values.keySet().iterator(); i.hasNext(); ) {
+ String val = (String) i.next();
+ buffer.append('\t');
+ buffer.append((val == null) ? "null" : val);//$NON-NLS-1$
+ if (((Boolean) values.get(val)).booleanValue() == true) {
+ buffer.append("(active)");//$NON-NLS-1$
+ }
+ buffer.append('\n');
+ }
+ return buffer.toString();
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/TraceUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/TraceUtil.java
new file mode 100644
index 00000000000..0d04dc0c86b
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/TraceUtil.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.core.scannerconfig.util;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+
+/**
+ * Tracebility related utility functions
+ *
+ * @author vhirsl
+ */
+public class TraceUtil {
+ public static final String EOL = System.getProperty("line.separator"); //$NON-NLS-1$
+ public static boolean SCANNER_CONFIG = false;
+ private static LogWriter logger = null;
+
+ static {
+ logger = new LogWriter(MakeCorePlugin.getDefault().getStateLocation().append(".log").toFile()); //$NON-NLS-1$
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#finalize()
+ */
+ protected void finalize() throws Throwable {
+ logger.shutdown();
+ super.finalize();
+ }
+
+ public static boolean isTracing() {
+ return SCANNER_CONFIG;
+ }
+
+ public static void outputTrace(String prefix, String msg, String postfix) {
+ if (isTracing()) {
+ //System.out.println();
+ System.out.println(prefix + ' ' + msg + ' ' + postfix);
+ }
+ }
+
+ /**
+ * For traces of type:
+ * Title:
+ * Subtitle1:
+ * item1[0]
+ * item1[1]
+ * ...
+ * Subtitle2:
+ * item2[0]
+ * item2[1]
+ * ...
+ * @param title
+ * @param col1
+ * @param col2
+ */
+ public static void outputTrace(String title, String subtitle1, List item1, List item1new, String subtitle2, List item2) {
+ if (isTracing()) {
+ //System.out.println();
+ System.out.println(title);
+ final String prefix = " "; //$NON-NLS-1$
+ final String doublePrefix = " "; //$NON-NLS-1$
+ System.out.println(prefix + subtitle1 + " (" + item1.size() + "):"); //$NON-NLS-1$ //$NON-NLS-2$
+ int count = 0;
+ for (Iterator i = item1.iterator(), j = item1new.iterator(); i.hasNext(); ) {
+ System.out.println(doublePrefix + String.valueOf(++count) + "\t\'" +(String)i.next() + (j.hasNext()?"\' -> \'" + (String)j.next():"") + '\''); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ System.out.println(prefix + subtitle2 + " (" + item2.size() + "):"); //$NON-NLS-1$ //$NON-NLS-2$
+ count = 0;
+ for (Iterator i = item2.iterator(); i.hasNext(); ) {
+ System.out.println(doublePrefix + String.valueOf(++count) + "\t\'" + (String)i.next() + '\''); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * @param string
+ * @param line
+ */
+ public static void outputError(String string, String line) {
+ if (isTracing()) {
+ System.out.println();
+ System.out.println("Error: " + string + line); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @param title
+ * @param subtitlePrefix
+ * @param subtitlePostfix
+ * @param map - el grande map
+ */
+ public static void metricsTrace(String title, String subtitlePrefix, String subtitlePostfix, Map directoryCommandListMap) {
+ try {
+ logger.writeln();
+ logger.writeln(" *** NEW METRICS TRACE ***"); //$NON-NLS-1$
+ logger.writeln();
+ for (Iterator k = directoryCommandListMap.keySet().iterator(); k.hasNext(); ) {
+ String dir = (String) k.next();
+ logger.writeln(title + dir + ":"); //$NON-NLS-1$
+ List directoryCommandList = (List) directoryCommandListMap.get(dir);
+ if (directoryCommandList == null) {
+ logger.writeln(" --- empty ---" + EOL); //$NON-NLS-1$
+ return;
+ }
+ for (Iterator i = directoryCommandList.iterator(); i.hasNext(); ) {
+ Map command21FileListMap = (Map) i.next();
+ String[] commands = (String[]) command21FileListMap.keySet().toArray(new String[1]);
+ logger.writeln(" " + subtitlePrefix + commands[0] + subtitlePostfix); //$NON-NLS-1$
+ List fileList = (List) command21FileListMap.get(commands[0]);
+ for (Iterator j = fileList.iterator(); j.hasNext(); ) {
+ String fileName = (String) j.next();
+ logger.writeln(" " + fileName); //$NON-NLS-1$
+ }
+ }
+ }
+ logger.flushLog();
+ }
+ catch (IOException e) {}
+ }
+
+ /**
+ * @param title
+ * @param workingDirsN
+ * @param commandsN
+ * @param filesN
+ */
+ public static void summaryTrace(String title, int workingDirsN, int commandsN, int filesN) {
+ try {
+ logger.writeln();
+ logger.writeln(" *** METRICS SUMMARY ***"); //$NON-NLS-1$
+ logger.writeln();
+ logger.writeln(title);
+ logger.writeln(" Number of directories visited: " + Integer.toString(workingDirsN)); //$NON-NLS-1$
+ logger.writeln(" Number of generic commands: " + Integer.toString(commandsN)); //$NON-NLS-1$
+ logger.writeln(" Number of compiled files: " + Integer.toString(filesN)); //$NON-NLS-1$
+ logger.flushLog();
+ }
+ catch (IOException e) {}
+ }
+
+ /**
+ * @param trace : String
+ */
+ public static void metricsTrace(String trace) {
+ try {
+ logger.writeln();
+ logger.writeln(" *** NEW METRICS TRACE 2 ***"); //$NON-NLS-1$
+ logger.writeln();
+ logger.writeln(trace);
+ logger.flushLog();
+ }
+ catch (IOException e) {}
+ }
+
+}

Back to the top