From 0b009bab2540ef5401dce54e1c8249a5f5a1ac02 Mon Sep 17 00:00:00 2001 From: Vladimir Hirsl Date: Mon, 14 Feb 2005 22:21:47 +0000 Subject: [PATCH] Per file scanner configuration discovery profile. Added per file collector persistency and updated per project collector's persistency. --- ...java => IScannerInfoCollectorCleaner.java} | 4 +- .../internal/core/MakeMessages.properties | 1 + .../scannerconfig/DiscoveredPathInfo.java | 96 ++++++- .../DiscoveredPathInitializer.java | 2 +- .../scannerconfig/DiscoveredPathManager.java | 200 ++----------- .../DiscoveredScannerInfoStore.java | 266 ++++++++++++++++++ .../core/scannerconfig/ScannerConfigUtil.java | 13 +- .../gnu/GCCPerFileBOPConsoleParser.java | 7 +- .../core/scannerconfig/util/CCommandDSC.java | 99 ++++++- .../scannerconfig/util/SCDOptionsEnum.java | 13 +- .../scannerconfig2/PerFileSICollector.java | 242 +++++++++++++--- .../scannerconfig2/PerProjectSICollector.java | 21 +- .../scannerconfig2/SCDMakefileGenerator.java | 4 +- .../dialogs/DiscoveredPathContainerPage.java | 6 +- .../ui/dialogs/DiscoveryOptionsBlock.java | 6 + 15 files changed, 720 insertions(+), 260 deletions(-) rename build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/{IScannerInfoCollectorUtil.java => IScannerInfoCollectorCleaner.java} (93%) create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredScannerInfoStore.java diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorCleaner.java similarity index 93% rename from build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorUtil.java rename to build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorCleaner.java index 087abd13b9c..7373366a436 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorUtil.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorCleaner.java @@ -13,11 +13,11 @@ package org.eclipse.cdt.make.core.scannerconfig; import org.eclipse.core.resources.IResource; /** - * TODO Provide description + * Utility functions some collectors may need * * @author vhirsl */ -public interface IScannerInfoCollectorUtil { +public interface IScannerInfoCollectorCleaner { /** * Delete all discovered paths for a resource * diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeMessages.properties b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeMessages.properties index 4e65960f6c7..c2ed9295cbe 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeMessages.properties +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeMessages.properties @@ -40,6 +40,7 @@ ScannerInfoCollector.Processing=Processing discovered scanner configuration ... ScannerInfoCollector.Updating=Updating Scanner Configuration for project DiscoveredPathManager.File_Error_Message=Error accessing scanner config file for project +DiscoveredPathManager.Info_Not_Serializable=Error persisting discovered scanner config GCCScannerConfigUtil.Error_Message=Error creating specs file 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 index ef3037409cf..4984c139f8e 100644 --- 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 @@ -16,12 +16,24 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable; +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 IDiscoveredPathInfo { +public class DiscoveredPathInfo implements IDiscoveredPathInfo, 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; @@ -31,6 +43,8 @@ public class DiscoveredPathInfo implements IDiscoveredPathInfo { public DiscoveredPathInfo(IProject project) { this.project = project; + discoveredPaths = new LinkedHashMap(); + discoveredSymbols = new LinkedHashMap(); } public IProject getProject() { @@ -53,9 +67,6 @@ public class DiscoveredPathInfo implements IDiscoveredPathInfo { } public LinkedHashMap getIncludeMap() { - if (discoveredPaths == null) { - return new LinkedHashMap(); - } return new LinkedHashMap(discoveredPaths); } @@ -81,9 +92,6 @@ public class DiscoveredPathInfo implements IDiscoveredPathInfo { } public LinkedHashMap getSymbolMap() { - if (discoveredSymbols == null) { - return new LinkedHashMap(); - } return new LinkedHashMap(discoveredSymbols); } @@ -115,4 +123,78 @@ public class DiscoveredPathInfo implements IDiscoveredPathInfo { } 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; + } + } 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 index c2e263afc42..cc07436708f 100644 --- 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 @@ -18,7 +18,7 @@ import org.eclipse.core.runtime.IPath; public class DiscoveredPathInitializer extends PathEntryContainerInitializer { public void initialize(IPath containerPath, ICProject project) throws CoreException { - CoreModel.getDefault().setPathEntryContainer(new ICProject[]{project}, new DiscoveredPathContainer(project.getProject()), null); + CoreModel.setPathEntryContainer(new ICProject[]{project}, new DiscoveredPathContainer(project.getProject()), null); } } 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 index 803f06dbcd7..5ca497c751e 100644 --- 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 @@ -8,35 +8,19 @@ ******************************************************************************/ package org.eclipse.cdt.make.internal.core.scannerconfig; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; 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.core.CCorePlugin; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager; import org.eclipse.cdt.make.internal.core.MakeMessages; -import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; @@ -44,25 +28,13 @@ import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceChangeListener { - private static final String CDESCRIPTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".discoveredScannerInfo"; //$NON-NLS-1$ - 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$ - private Map fDiscoveredMap = new HashMap(); private List listeners = Collections.synchronizedList(new ArrayList()); @@ -70,6 +42,7 @@ public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceC private static final int INFO_REMOVED = 2; public DiscoveredPathManager() { + } public void startup() { @@ -111,12 +84,8 @@ public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceC } private DiscoveredPathInfo loadPathInfo(IProject project) throws CoreException { - LinkedHashMap includes = new LinkedHashMap(); - LinkedHashMap symbols = new LinkedHashMap(); - loadDiscoveredScannerInfoFromState(project, includes, symbols); DiscoveredPathInfo info = new DiscoveredPathInfo(project); - info.setIncludeMap(includes); - info.setSymbolMap(symbols); + DiscoveredScannerInfoStore.getInstance().loadDiscoveredScannerInfoFromState(project, info); return info; } @@ -130,156 +99,20 @@ public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceC public void updateDiscoveredInfo(IDiscoveredPathInfo info) throws CoreException { if (fDiscoveredMap.get(info.getProject()) != null) { - saveDiscoveredScannerInfoToState((DiscoveredPathInfo)info); - fireUpdate(INFO_CHANGED, info); - ICProject cProject = CoreModel.getDefault().create(info.getProject()); - if (cProject != null) { - CoreModel.getDefault().setPathEntryContainer(new ICProject[]{cProject}, - new DiscoveredPathContainer(info.getProject()), null); - } - } - } - - private void loadDiscoveredScannerInfoFromState(IProject project, LinkedHashMap includes, LinkedHashMap symbols) - throws CoreException { - // Save the document - IPath path = ScannerConfigUtil.getDiscoveredScannerConfigStore(project, false); - if (path.toFile().exists()) { - try { - FileInputStream file = new FileInputStream(path.toFile()); - DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document document = parser.parse(file); - Node rootElement = document.getFirstChild(); - if (rootElement.getNodeName().equals("scannerInfo")) { //$NON-NLS-1$ - Node child = rootElement.getFirstChild(); - loadDiscoveredScannerInfo(includes, symbols, child); - } - } catch (IOException 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$ - } - } - } - - /** - * @param includes - * @param symbols - * @param child - */ - private void loadDiscoveredScannerInfo(LinkedHashMap includes, LinkedHashMap symbols, Node child) { - 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(); - } - } - - /** - * @param scannerInfo - * @param rootElement - * @param doc - */ - private static void saveDiscoveredScannerInfo(DiscoveredPathInfo info, Element rootElement, Document doc) { - // Save the build info - if (info != null) { - // Serialize the include paths - Map discoveredIncludes = info.getIncludeMap(); - Iterator iter = discoveredIncludes.keySet().iterator(); - while (iter.hasNext()) { - Element pathElement = doc.createElement(INCLUDE_PATH); - String include = (String)iter.next(); - pathElement.setAttribute(PATH, include); - Boolean removed = (Boolean)discoveredIncludes.get(include); - if (removed != null && removed.booleanValue() == true) { - pathElement.setAttribute(REMOVED, "true"); //$NON-NLS-1$ - } - rootElement.appendChild(pathElement); - } - // Now do the same for the symbols - Map discoveredSymbols = info.getSymbolMap(); - iter = discoveredSymbols.keySet().iterator(); - while (iter.hasNext()) { - String symbol = (String)iter.next(); - SymbolEntry se = (SymbolEntry)discoveredSymbols.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); - rootElement.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$ - rootElement.appendChild(symbolElement); + if (info instanceof IDiscoveredScannerInfoSerializable) { + IDiscoveredScannerInfoSerializable serializable = (IDiscoveredScannerInfoSerializable) info; + DiscoveredScannerInfoStore.getInstance().saveDiscoveredScannerInfoToState(info.getProject(), serializable); + fireUpdate(INFO_CHANGED, info); + ICProject cProject = CoreModel.getDefault().create(info.getProject()); + if (cProject != null) { + CoreModel.setPathEntryContainer(new ICProject[]{cProject}, + new DiscoveredPathContainer(info.getProject()), null); } } - } - } - - private static void saveDiscoveredScannerInfoToState(DiscoveredPathInfo info) throws CoreException { - // Create document - try { - DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document doc = builder.newDocument(); - Element rootElement = doc.createElement("scannerInfo"); //$NON-NLS-1$ - rootElement.setAttribute("id", CDESCRIPTOR_ID); //$NON-NLS-1$ - doc.appendChild(rootElement); - - saveDiscoveredScannerInfo(info, rootElement, doc); - - // 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(doc); - StreamResult result = new StreamResult(stream); - transformer.transform(source, result); - - // Save the document - try { - IPath path = ScannerConfigUtil.getDiscoveredScannerConfigStore(info.getProject(), false); - 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$ + else { + throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, + MakeMessages.getString("DiscoveredPathManager.Info_Not_Serializable"), null)); //$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$ - } 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$ } } @@ -289,13 +122,13 @@ public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceC 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 : @@ -319,4 +152,5 @@ public class DiscoveredPathManager implements IDiscoveredPathManager, IResourceC listeners.remove(listener); } + } \ No newline at end of file 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..e32652e19bd --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredScannerInfoStore.java @@ -0,0 +1,266 @@ +/*********************************************************************** + * Copyright (c) 2004 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.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.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.scannerconfig2.PerProjectSICollector; +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; +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 { + public interface IDiscoveredScannerInfoSerializable { + /** + * Serialize discovered scanner info to an XML element + * + * @param root + */ + public void serialize(Element root); + + /** + * Deserialize discovered scanner info from an XML element + * + * @param root + */ + public void deserialize(Element root); + + /** + * @return an id of the collector + */ + public String getCollectorId(); + } + + + 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 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 { + // Get the document + Document document = getDocument(project); + if (document != null) { + NodeList rootList = document.getElementsByTagName(SI_ELEM); + if (rootList.getLength() > 0) { + Element rootElem = (Element) rootList.item(0); + // 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; + } + } + } + } + } + } + + private Document getDocument(IProject project) throws CoreException { + // Get the document + Document document = null; + document = (Document) fDocumentMap.get(project); + if (document == null) { + try { + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + IPath path = ScannerConfigUtil.getDiscoveredScannerConfigStore(project, false); + 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 + * @throws CoreException + */ + private void upgradeDocument(Document document, IProject project) throws CoreException { + 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); + } + + /** + * @param scannerInfo + * @param rootElement + * @param doc + * @throws CoreException + */ + private void saveDiscoveredScannerInfo(IDiscoveredScannerInfoSerializable serializable, Document doc) throws CoreException { + NodeList rootList = doc.getElementsByTagName(SI_ELEM); + if (rootList.getLength() > 0) { + Element rootElem = (Element) rootList.item(0); + // 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 { + Document document = getDocument(project); + // Create document + try { + saveDiscoveredScannerInfo(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 = ScannerConfigUtil.getDiscoveredScannerConfigStore(project, false); + 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$ + } + } + +} 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 index 752ac579acd..76e4d688f65 100644 --- 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 @@ -17,7 +17,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.Set; import org.eclipse.cdt.make.core.MakeCorePlugin; @@ -36,10 +35,10 @@ import org.eclipse.core.runtime.QualifiedName; * @author vhirsl */ public final class ScannerConfigUtil { - private static Random sRandom = new Random(); - private static final QualifiedName discoveredScannerConfigFileNameProperty = new + private static final QualifiedName dscFileNameProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), "discoveredScannerConfigFileName"); //$NON-NLS-1$ - /** + + /** * Adds all new discovered symbols/values to the existing ones. * * @param sumSymbols - a map of [String, Map] where Map is a SymbolEntry @@ -303,7 +302,7 @@ public final class ScannerConfigUtil { String fileName = project.getName() + ".sc"; //$NON-NLS-1$ String storedFileName = null; try { - storedFileName = project.getPersistentProperty(discoveredScannerConfigFileNameProperty); + storedFileName = project.getPersistentProperty(dscFileNameProperty); } catch (CoreException e) { MakeCorePlugin.log(e.getStatus()); } @@ -312,7 +311,7 @@ public final class ScannerConfigUtil { movePluginStateFile(storedFileName, fileName); } try { - project.setPersistentProperty(discoveredScannerConfigFileNameProperty, fileName); + project.setPersistentProperty(dscFileNameProperty, fileName); } catch (CoreException e) { MakeCorePlugin.log(e.getStatus()); } @@ -382,7 +381,7 @@ public final class ScannerConfigUtil { String scNewFileName = newProject.getName() + ".sc"; //$NON-NLS-1$ movePluginStateFile(scOldFileName, scNewFileName); try { - newProject.setPersistentProperty(discoveredScannerConfigFileNameProperty, scNewFileName); + newProject.setPersistentProperty(dscFileNameProperty, scNewFileName); } catch (CoreException e) { MakeCorePlugin.log(e); 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 index 9fa2175452c..ebd690fb91c 100644 --- 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 @@ -133,8 +133,11 @@ public class GCCPerFileBOPConsoleParser extends AbstractGCCBOPConsoleParser { cmdList.add(cmd); Map sc = new HashMap(1); sc.put(ScannerInfoTypes.COMPILER_COMMAND, cmdList); - IFile file = getProject().getFile(pFilePath); - getCollector().contributeToScannerConfig(file, sc); + if (getProject().getLocation().isPrefixOf(pFilePath)) { + IPath relPath = pFilePath.removeFirstSegments(getProject().getLocation().segmentCount()); + IFile file = getProject().getFile(relPath); + getCollector().contributeToScannerConfig(file, sc); + } // fUtil.addGenericCommandForFile2(longFileName, genericLine); } return rc; 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 index a4c667089c6..5e39343d6c0 100644 --- 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 @@ -14,6 +14,10 @@ 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 * @@ -22,11 +26,9 @@ import java.util.List; public class CCommandDSC { private final static String SINGLE_SPACE = " "; //$NON-NLS-1$ - private static int ids = 0; private int commandId; private List compilerCommand; // members are KVPair objects private boolean discovered; -// private List files; // list of files this command applies to private boolean cppFileType; // C or C++ file type private List symbols; @@ -40,11 +42,13 @@ public class CCommandDSC { discovered = false; // files = null; this.cppFileType = cppFileType; - commandId = ++ids; + + symbols = new ArrayList(); + includes = new ArrayList(); } - public boolean appliesToCFileType() { - return !cppFileType; + public boolean appliesToCPPFileType() { + return cppFileType; } public void addSCOption(KVPair option) { @@ -109,11 +113,16 @@ public class CCommandDSC { String commandAsString = new String(); for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { KVPair optionPair = (KVPair)i.next(); - if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE) || - optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE)) - continue; - commandAsString += optionPair.getKey().toString() + SINGLE_SPACE + - optionPair.getValue() + SINGLE_SPACE; + if (optionPair.getKey().equals(SCDOptionsEnum.COMMAND)) { + commandAsString += optionPair.getValue() + SINGLE_SPACE; + } + else { +// if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE) || +// optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE)) +// continue; + commandAsString += optionPair.getKey().toString() + SINGLE_SPACE + + optionPair.getValue() + SINGLE_SPACE; + } } return commandAsString.trim(); } @@ -198,4 +207,74 @@ public class CCommandDSC { 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("commandDescription"); //$NON-NLS-1$ + for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + Element optionElem = doc.createElement("option"); //$NON-NLS-1$ + KVPair option = (KVPair) i.next(); + optionElem.setAttribute("key", option.getKey().toString()); //$NON-NLS-1$ + optionElem.setAttribute("value", option.getValue()); //$NON-NLS-1$ + cmdDescElem.appendChild(optionElem); + } + cmdElem.appendChild(cmdDescElem); + // serialize includes and symbols + Element siElem = doc.createElement("commandScannerInfo"); //$NON-NLS-1$ + for (Iterator j = includes.iterator(); j.hasNext(); ) { + Element siItem = doc.createElement("siItem"); //$NON-NLS-1$ + siItem.setAttribute("kind", "INCLUDE_PATH"); //$NON-NLS-1$ //$NON-NLS-2$ + siItem.setAttribute("value", (String) j.next()); //$NON-NLS-1$ + siElem.appendChild(siItem); + } + for (Iterator j = symbols.iterator(); j.hasNext(); ) { + Element siItem = doc.createElement("siItem"); //$NON-NLS-1$ + siItem.setAttribute("kind", "SYMBOL_DEFINITION"); //$NON-NLS-1$ //$NON-NLS-2$ + siItem.setAttribute("value", (String) j.next()); //$NON-NLS-1$ + siElem.appendChild(siItem); + } + cmdElem.appendChild(siElem); + } + + /** + * @param cmdElem + */ + public void deserialize(Element cmdElem) { + // read command options + NodeList descList = cmdElem.getElementsByTagName("commandDescription"); + if (descList.getLength() > 0) { + Element descElem = (Element) descList.item(0); + NodeList optionList = descElem.getElementsByTagName("option"); + for (int i = 0; i < optionList.getLength(); ++i) { + Element optionElem = (Element) optionList.item(i); + String key = optionElem.getAttribute("key"); + SCDOptionsEnum eKey = SCDOptionsEnum.getSCDOptionsEnum(key); + String value = optionElem.getAttribute("value"); + KVPair option = new KVPair(eKey, value); + addSCOption(option); + } + } + // read associated scanner info + NodeList siList = cmdElem.getElementsByTagName("commandScannerInfo"); + if (siList.getLength() > 0) { + Element siElem = (Element) siList.item(0); + NodeList siItemList = siElem.getElementsByTagName("siItem"); + for (int i = 0; i < siItemList.getLength(); ++i) { + Element siItemElem = (Element) siItemList.item(i); + String kind = siItemElem.getAttribute("kind"); + String value = siItemElem.getAttribute("value"); + if (kind.equals("INCLUDE_PATH")) { + includes.add(value); + } + else if (kind.equals("SYMBOL_DEFINITION")) { + symbols.add(value); + } + } + setDiscovered(true); + } + } } 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 index 0554a52cfc6..559345eaae6 100644 --- 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 @@ -35,7 +35,7 @@ public final class SCDOptionsEnum { public static final int MAX = 13; private static final String[] SCDOPTION_STRING_VALS = { - "", "-D", "-U", "-I", "-I-", "-nostdinc", "-nostdinc++", "-include", "-imacros", + "cc", "-D", "-U", "-I", "-I-", "-nostdinc", "-nostdinc++", "-include", "-imacros", "-idirafter", "-isystem", "-iprefix", "-iwithprefix", "-iwithprefixbefore" }; private static final SCDOptionsEnum SCDOPTIONS[] = { @@ -46,7 +46,7 @@ public final class SCDOptionsEnum { /** * */ - public SCDOptionsEnum(int val) { + private SCDOptionsEnum(int val) { this._enum = val; } @@ -61,6 +61,15 @@ public final class SCDOptionsEnum { 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) */ diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java index 065d1288469..89667ea7fd9 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.make.internal.core.scannerconfig2; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -18,37 +19,63 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner; import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; +import org.eclipse.cdt.make.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable; 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.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * Per file scanner info collector * * @author vhirsl */ -public class PerFileSICollector implements IScannerInfoCollector2 { - private IProject project; +public class PerFileSICollector implements IScannerInfoCollector2, IScannerInfoCollectorCleaner, + IDiscoveredScannerInfoSerializable { + public static final String COLLECTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".PerFileSICollector"; //$NON-NLS-1$ + private static final String CC_ELEM = "compilerCommand"; //$NON-NLS-1$ + private static final String ID_ATTR = "id"; //$NON-NLS-1$ + private static final String FILE_TYPE_ATTR = "fileType"; //$NON-NLS-1$ + private static final String APPLIES_TO_ATTR = "appliesToFiles"; //$NON-NLS-1$ + private static final String FILE_ELEM = "file"; //$NON-NLS-1$ + private static final String PATH_ATTR = "path"; //$NON-NLS-1$ + + private IProject project; - private Map commandIdToFilesMap; // command id and list of files it applies to - private Map fileToCommandIdsMap; // maps each file to the list of corresponding command ids + private Map commandIdToFilesMap; // command id and set of files it applies to + private Map fileToCommandIdMap; // maps each file to the corresponding command id private Map commandIdCommandMap; // map of all commands + private SortedSet freeCommandIdPool; // sorted set of free command ids private int commandIdCounter = 0; /** * */ public PerFileSICollector() { - commandIdToFilesMap = new HashMap(); // [commandId, List of files] - fileToCommandIdsMap = new HashMap(); // [file, List of commands] - commandIdCommandMap = new LinkedHashMap(); // [commandId, command] + commandIdCommandMap = new LinkedHashMap(); // [commandId, command] + fileToCommandIdMap = new HashMap(); // [file, commandId] + commandIdToFilesMap = new HashMap(); // [commandId, set of files] + + freeCommandIdPool = new TreeSet(); } /* (non-Javadoc) @@ -56,6 +83,13 @@ public class PerFileSICollector implements IScannerInfoCollector2 { */ public void setProject(IProject project) { this.project = project; + + try { + IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project); + } + catch (CoreException e) { + MakeCorePlugin.log(e); + } } /* (non-Javadoc) @@ -89,7 +123,10 @@ public class PerFileSICollector implements IScannerInfoCollector2 { for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext(); ) { ScannerInfoTypes type = (ScannerInfoTypes) i.next(); if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { - addCompilerCommands(file, (List) scannerInfo.get(type)); + List commands = (List) scannerInfo.get(type); + for (Iterator j = commands.iterator(); j.hasNext(); ) { + addCompilerCommand(file, (CCommandDSC) j.next()); + } } else { addScannerInfo(type, (List) scannerInfo.get(type)); @@ -116,38 +153,50 @@ public class PerFileSICollector implements IScannerInfoCollector2 { * @param file * @param object */ - private void addCompilerCommands(IFile file, List commandList) { - if (commandList != null) { - List existingCommands = new ArrayList(commandIdCommandMap.values()); - for (Iterator i = commandList.iterator(); i.hasNext(); ) { - CCommandDSC cmd = (CCommandDSC) i.next(); - int index = existingCommands.indexOf(cmd); - if (index != -1) { - cmd = (CCommandDSC) existingCommands.get(index); - } - else { - cmd.setCommandId(++commandIdCounter); - commandIdCommandMap.put(cmd.getCommandIdAsInteger(), cmd); - } - Integer commandId = cmd.getCommandIdAsInteger(); - // update commandIdToFilesMap - Set fileSet = (Set) commandIdToFilesMap.get(commandId); - if (fileSet == null) { - fileSet = new HashSet(); - commandIdToFilesMap.put(commandId, fileSet); - } - fileSet.add(file); - // update fileToCommandIdsMap - List commandIds = (List) fileToCommandIdsMap.get(file); - if (commandIds == null) { - commandIds = new ArrayList(); - fileToCommandIdsMap.put(file, commandIds); - } - if (!commandIds.contains(commandId)) { - commandIds.add(commandId); + private void addCompilerCommand(IFile file, CCommandDSC cmd) { + List existingCommands = new ArrayList(commandIdCommandMap.values()); + int index = existingCommands.indexOf(cmd); + if (index != -1) { + cmd = (CCommandDSC) existingCommands.get(index); + } + else { + int commandId = -1; + if (!freeCommandIdPool.isEmpty()) { + Integer freeCommandId = (Integer) freeCommandIdPool.first(); + freeCommandIdPool.remove(freeCommandId); + commandId = freeCommandId.intValue(); + } + else { + commandId = ++commandIdCounter; + } + cmd.setCommandId(commandId); + commandIdCommandMap.put(cmd.getCommandIdAsInteger(), cmd); + } + Integer commandId = cmd.getCommandIdAsInteger(); + // update commandIdToFilesMap + Set fileSet = (Set) commandIdToFilesMap.get(commandId); + if (fileSet == null) { + fileSet = new HashSet(); + commandIdToFilesMap.put(commandId, fileSet); + } + fileSet.add(file); + // update fileToCommandIdsMap + boolean change = true; + Integer oldCommandId = (Integer) fileToCommandIdMap.get(file); + if (oldCommandId != null) { + if (oldCommandId.equals(commandId)) { + change = false; + } + else { + commandIdToFilesMap.remove(file); + if (((Set)(commandIdToFilesMap.get(oldCommandId))).isEmpty()) { + // old command does not apply to any files any more; remove + commandIdCommandMap.remove(oldCommandId); + freeCommandIdPool.add(oldCommandId); } } } + fileToCommandIdMap.put(file, commandId); } /** @@ -163,8 +212,22 @@ public class PerFileSICollector implements IScannerInfoCollector2 { * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#updateScannerConfiguration(org.eclipse.core.runtime.IProgressMonitor) */ public void updateScannerConfiguration(IProgressMonitor monitor) throws CoreException { - // TODO Auto-generated method stub - + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(MakeMessages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$ + monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$ + DiscoveredScannerInfoStore.getInstance().loadDiscoveredScannerInfoFromState(project, this); + monitor.worked(50); + monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + project.getName()); //$NON-NLS-1$ + try { + // update scanner configuration + DiscoveredScannerInfoStore.getInstance().saveDiscoveredScannerInfoToState(project, this); + monitor.worked(50); + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + monitor.done(); } /* (non-Javadoc) @@ -198,4 +261,105 @@ public class PerFileSICollector implements IScannerInfoCollector2 { return rv; } + /* (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(); + + List commandIds = new ArrayList(commandIdCommandMap.keySet()); + Collections.sort(commandIds); + for (Iterator i = commandIds.iterator(); i.hasNext(); ) { + Integer commandId = (Integer) i.next(); + CCommandDSC command = (CCommandDSC) commandIdCommandMap.get(commandId); + + Element cmdElem = doc.createElement(CC_ELEM); //$NON-NLS-1$ + collectorElem.appendChild(cmdElem); + cmdElem.setAttribute(ID_ATTR, commandId.toString()); //$NON-NLS-1$ + cmdElem.setAttribute(FILE_TYPE_ATTR, command.appliesToCPPFileType() ? "c++" : "c"); + // write command and scanner info + command.serialize(cmdElem); + // write files command applies to + Element filesElem = doc.createElement(APPLIES_TO_ATTR); //$NON-NLS-1$ + cmdElem.appendChild(filesElem); + Set files = (Set) commandIdToFilesMap.get(commandId); + if (files != null) { + for (Iterator j = files.iterator(); j.hasNext(); ) { + Element fileElem = doc.createElement(FILE_ELEM); //$NON-NLS-1$ + IFile file = (IFile) j.next(); + IPath path = file.getProjectRelativePath(); + fileElem.setAttribute(PATH_ATTR, path.toString()); //$NON-NLS-1$ + filesElem.appendChild(fileElem); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#deserialize(org.w3c.dom.Element) + */ + public void deserialize(Element collectorElem) { + for (Node child = collectorElem.getFirstChild(); child != null; child = child.getNextSibling()) { + if (child.getNodeName().equals(CC_ELEM)) { //$NON-NLS-1$ + Element cmdElem = (Element) child; + boolean cppFileType = cmdElem.getAttribute(FILE_TYPE_ATTR).equals("c++"); + CCommandDSC command = new CCommandDSC(cppFileType); + command.setCommandId(Integer.parseInt(cmdElem.getAttribute(ID_ATTR))); + // deserialize command + command.deserialize(cmdElem); + // get set of files the command applies to + NodeList appliesList = cmdElem.getElementsByTagName(APPLIES_TO_ATTR); + if (appliesList.getLength() > 0) { + Element appliesElem = (Element) appliesList.item(0); + NodeList fileList = appliesElem.getElementsByTagName(FILE_ELEM); + for (int i = 0; i < fileList.getLength(); ++i) { + Element fileElem = (Element) fileList.item(i); + String fileName = fileElem.getAttribute(PATH_ATTR); + IFile file = project.getFile(fileName); + addCompilerCommand(file, command); + } + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#getCollectorId() + */ + public String getCollectorId() { + return COLLECTOR_ID; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deleteAllPaths(org.eclipse.core.resources.IResource) + */ + public void deleteAllPaths(IResource resource) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deleteAllSymbols(org.eclipse.core.resources.IResource) + */ + public void deleteAllSymbols(IResource resource) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deletePath(org.eclipse.core.resources.IResource, java.lang.String) + */ + public void deletePath(IResource resource, String path) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deleteSymbol(org.eclipse.core.resources.IResource, java.lang.String) + */ + public void deleteSymbol(IResource resource, String symbol) { + // TODO Auto-generated method stub + + } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerProjectSICollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerProjectSICollector.java index 9b1dc746608..e7c8ed731ab 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerProjectSICollector.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerProjectSICollector.java @@ -22,7 +22,7 @@ import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.MakeProjectNature; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner; import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; import org.eclipse.cdt.make.internal.core.MakeMessages; @@ -37,6 +37,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.w3c.dom.Element; /** * New per project scanner info collector @@ -44,7 +45,9 @@ import org.eclipse.core.runtime.Platform; * @since 3.0 * @author vhirsl */ -public class PerProjectSICollector implements IScannerInfoCollector2, IScannerInfoCollectorUtil { +public class PerProjectSICollector implements IScannerInfoCollector2, IScannerInfoCollectorCleaner { + public static final String COLLECTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".PerProjectSICollector"; //$NON-NLS-1$ + private IProject project; private Map discoveredSI; @@ -382,6 +385,20 @@ public class PerProjectSICollector implements IScannerInfoCollector2, IScannerIn return sumDiscoveredIncludes; } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#serialize(org.w3c.dom.Element) + */ + public void serialize(Element root) { + // not supported in PerProject collector + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deserialize(org.w3c.dom.Element) + */ + public void deserialize(Element root) { + // not supported in PerProject collector + } + /* (non-Javadoc) * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deleteAllPaths(org.eclipse.core.resources.IResource) */ diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java index 6c999fe6142..c9742d99ff8 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java @@ -84,9 +84,9 @@ public class SCDMakefileGenerator extends DefaultRunSIProvider { buffer.append(':'); buffer.append(ENDL); buffer.append("\t@echo begin generating scanner info for $@"+ENDL+"\t"); //$NON-NLS-1$ //$NON-NLS-2$ - buffer.append(cmd); + buffer.append(cmd.getSCDRunnableCommand()); buffer.append(" -E -P -v -dD "); //$NON-NLS-1$ - buffer.append(cmd.appliesToCFileType() ? "specs.c" : "specs.cpp"); //$NON-NLS-1$ //$NON-NLS-2$ + buffer.append(cmd.appliesToCPPFileType() ? "specs.cpp" : "specs.c"); //$NON-NLS-1$ //$NON-NLS-2$ buffer.append(ENDL); buffer.append("\t@echo end generating scanner info for $@"); //$NON-NLS-1$ buffer.append(DENDL); diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java index 94fbf2dcae3..4ee54ae160c 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java @@ -31,7 +31,7 @@ import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil; import org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner; import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer; import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; @@ -563,8 +563,8 @@ public class DiscoveredPathContainerPage extends WizardPage implements IPathEntr SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance(). getSCProfileInstance(project, ScannerConfigProfileManager.NULL_PROFILE_ID); // use selected profile for the project IScannerInfoCollector collector = profileInstance.getScannerInfoCollector(); - if (collector instanceof IScannerInfoCollectorUtil) { - IScannerInfoCollectorUtil collectorUtil = (IScannerInfoCollectorUtil) collector; + if (collector instanceof IScannerInfoCollectorCleaner) { + IScannerInfoCollectorCleaner collectorUtil = (IScannerInfoCollectorCleaner) collector; List newSelection = new ArrayList(); List selElements = fDiscoveredContainerList.getSelectedElements(); for (int i = 0; i < selElements.size(); ++i) { diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java index a2cf95ba7e9..f3aa19d07ce 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java @@ -312,7 +312,13 @@ public class DiscoveryOptionsBlock extends AbstractDiscoveryOptionsBlock { if (buildInfo != null) { buildInfo.setAutoDiscoveryEnabled(scEnabledButton.getSelection()); String profileName = profileComboBox.getItem(profileComboBox.getSelectionIndex()); + String oldProfileId = buildInfo.getSelectedProfileId(); buildInfo.setSelectedProfileId(getDiscoveryProfileId(profileName)); + String newProfileId = buildInfo.getSelectedProfileId(); + if (!oldProfileId.equals(newProfileId) && getProject() != null) { + // invalidate scanner config store and reload +// MakeCorePlugin.getDefault().getDiscoveryManager().removeDiscoveredInfo(getProject()); + } buildInfo.setProblemReportingEnabled(scProblemReportingEnabledButton.getSelection()); } }