diff options
author | Mikhail Sennikovsky | 2007-03-06 18:48:55 +0000 |
---|---|---|
committer | Mikhail Sennikovsky | 2007-03-06 18:48:55 +0000 |
commit | 6524989ba78457a202af744c22008c53ccad4e9f (patch) | |
tree | 922dfe896b75ab331dc66fecbb37a265cb302a1a /build/org.eclipse.cdt.make.core | |
parent | 99affdf6462618d31cea71ef9fc79d145f84db0f (diff) | |
download | org.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')
74 files changed, 12229 insertions, 792 deletions
diff --git a/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF index 76aac2f7355..052eb8c33d3 100644 --- a/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF @@ -6,37 +6,21 @@ Bundle-Version: 4.0.0.qualifier Bundle-Activator: org.eclipse.cdt.make.core.MakeCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin -Export-Package: org.eclipse.cdt.make.core; - uses:="org.eclipse.cdt.newmake.core, - org.osgi.framework, - org.eclipse.cdt.managedbuilder.core, - org.eclipse.core.resources, - org.eclipse.cdt.make.core.makefile, - org.eclipse.core.runtime", - org.eclipse.cdt.make.core.makefile;uses:="org.eclipse.core.resources,org.eclipse.core.runtime,org.eclipse.cdt.core", - org.eclipse.cdt.make.core.makefile.gnu;uses:="org.eclipse.cdt.make.core.makefile", - org.eclipse.cdt.make.internal.core; - uses:="org.eclipse.cdt.core.settings.model, - org.w3c.dom, - org.eclipse.cdt.managedbuilder.core, - org.eclipse.core.resources, - org.eclipse.cdt.make.core, - org.eclipse.core.runtime, - org.eclipse.cdt.core", - org.eclipse.cdt.make.internal.core.makefile;uses:="org.eclipse.cdt.make.core.makefile", - org.eclipse.cdt.make.internal.core.makefile.gnu; - uses:="org.eclipse.cdt.make.internal.core.makefile, - org.eclipse.cdt.make.core.makefile.gnu, - org.eclipse.cdt.make.internal.core.makefile.posix, - org.eclipse.cdt.core.resources, - org.eclipse.core.resources, - org.eclipse.core.runtime, - org.eclipse.cdt.make.core.makefile, - org.eclipse.cdt.core", - org.eclipse.cdt.make.internal.core.makefile.posix;uses:="org.eclipse.cdt.make.internal.core.makefile" +Export-Package: org.eclipse.cdt.make.core, + org.eclipse.cdt.make.core.makefile, + org.eclipse.cdt.make.core.makefile.gnu, + org.eclipse.cdt.make.core.scannerconfig, + org.eclipse.cdt.make.internal.core, + org.eclipse.cdt.make.internal.core.makefile, + org.eclipse.cdt.make.internal.core.makefile.gnu, + org.eclipse.cdt.make.internal.core.makefile.posix, + org.eclipse.cdt.make.internal.core.scannerconfig, + org.eclipse.cdt.make.internal.core.scannerconfig.gnu, + org.eclipse.cdt.make.internal.core.scannerconfig.jobs, + org.eclipse.cdt.make.internal.core.scannerconfig.util, + org.eclipse.cdt.make.internal.core.scannerconfig2 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", - org.eclipse.cdt.core;bundle-version="[4.0.0,5.0.0)", - org.eclipse.cdt.managedbuilder.core;visibility:=reexport + org.eclipse.cdt.core;bundle-version="[4.0.0,5.0.0)" Eclipse-LazyStart: true diff --git a/build/org.eclipse.cdt.make.core/plugin.properties b/build/org.eclipse.cdt.make.core/plugin.properties index 44b3886fea8..655cd9036b5 100644 --- a/build/org.eclipse.cdt.make.core/plugin.properties +++ b/build/org.eclipse.cdt.make.core/plugin.properties @@ -16,4 +16,16 @@ extensionTargetBuilder.name=Target Builder Extension natureMake.name=CDT Make Nature builderMake.name=CDT Makefile Builder +epScannerConfigNature.name=Scanner Configuration Nature +epScannerConfigBuilder.name=Scanner Configuration Builder +extensionExternalScannerInfoProvider.name=C/C++ External Scanner Info Provider Extension +epDefaultExternalScannerInfoProvider.name=Default External Scanner Info Provider + +extensionScannerInfoConsoleParser.name=GNU C/C++ Scanner Info Console Parser Extension +epGCCCommandLineParser.name=GNU C/C++ Scanner Info Parser +epGCCSpecsParser.name=GNU C/C++ Compiler Specs Parser + +extensionGCCPerProjectProfile.name=GNU C/C++ Scanner Info per project profile +extensionGCCPerFileProfile.name=GNU C/C++ Scanner Info per file profile + makefile=Makefile diff --git a/build/org.eclipse.cdt.make.core/plugin.xml b/build/org.eclipse.cdt.make.core/plugin.xml index 863bfbb1aae..5f58f276f4d 100644 --- a/build/org.eclipse.cdt.make.core/plugin.xml +++ b/build/org.eclipse.cdt.make.core/plugin.xml @@ -30,7 +30,7 @@ id="org.eclipse.cdt.make.core.makeBuilder"> </builder> </extension> - <!--extension + <extension id="makeBuilder" name="%builderMake.name" point="org.eclipse.core.resources.builders"> @@ -44,7 +44,7 @@ </parameter> </run> </builder> - </extension--> + </extension> <extension id="make" name="%makeproject.name" @@ -54,14 +54,14 @@ natureID="org.eclipse.cdt.make.core.makeNature"> </cproject> </extension> - <!--extension + <extension point="org.eclipse.cdt.make.core.MakeTargetBuilder"> <builder builderID="org.eclipse.cdt.make.core.makeBuilder" id="org.eclipse.cdt.make.MakeTargetBuilder"> </builder> - </extension--> - <!--extension + </extension> + <extension id="ScannerConfigNature" name="%epScannerConfigNature.name" point="org.eclipse.core.resources.natures"> @@ -87,7 +87,7 @@ class="org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder"> </run> </builder> - </extension--> + </extension> <extension id="DiscoveredScannerInfoProvider" point="org.eclipse.cdt.core.ScannerInfoProvider"> @@ -159,14 +159,5 @@ file-names="Makefile,makefile,GNUMakefile" file-extensions="mk"/> </extension> - - <extension - point="org.eclipse.cdt.make.core.MakeTargetBuilder"> - <builder - builderID="org.eclipse.cdt.managedbuilder.core.genmakebuilder" - id="org.eclipse.cdt.make.MakeTargetBuilder"> - </builder> - </extension> - </plugin> diff --git a/build/org.eclipse.cdt.make.core/schema/ScannerConfigurationDiscoveryProfile.exsd b/build/org.eclipse.cdt.make.core/schema/ScannerConfigurationDiscoveryProfile.exsd new file mode 100644 index 00000000000..b4ec5732bdb --- /dev/null +++ b/build/org.eclipse.cdt.make.core/schema/ScannerConfigurationDiscoveryProfile.exsd @@ -0,0 +1,254 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.eclipse.cdt.make.core"> +<annotation> + <appInfo> + <meta.schema plugin="org.eclipse.cdt.make.core" id="ScannerConfigurationDiscoveryProfile" name="Scanner Configuration Discovery Profile"/> + </appInfo> + <documentation> + A unified definition of a scanner configuration profile. Usually consists of <p> +- A make build output parser <p> +- A scanner info collector <p> +- An external scanner info generator <p> + - An external scanner info generator output parser <p> + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <documentation> + Definition of a profile: +- A scanner info collector +- A make build output parser +- A number of external scanner info providers + </documentation> + </annotation> + <complexType> + <sequence> + <element ref="scannerInfoCollector"/> + <element ref="buildOutputProvider" minOccurs="0" maxOccurs="1"/> + <element ref="scannerInfoProvider" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + Profile id. + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string" use="required"> + <annotation> + <documentation> + The name of the profile will be presented to the user. + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="scannerInfoCollector"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + Java class that implements IScannerInfoCollector interface. + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector"/> + </appInfo> + </annotation> + </attribute> + <attribute name="scope" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + <simpleType> + <restriction base="string"> + <enumeration value="project"> + </enumeration> + <enumeration value="file"> + </enumeration> + </restriction> + </simpleType> + </attribute> + </complexType> + </element> + + <element name="scannerInfoConsoleParser"> + <annotation> + <documentation> + Make build output or external scanner info provider output parser. + </documentation> + </annotation> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + Java class that implements IScannerInfoConsoleParser interface. + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="org.eclipse.cdt.make.core.IScannerInfoConsoleParser"/> + </appInfo> + </annotation> + </attribute> + <attribute name="compilerCommands" type="string"> + <annotation> + <documentation> + Comma separated list of compiler commands to use for detecting lines with preprocessor options. + +Example: "gcc, g++, cc, c++" + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="buildOutputProvider"> + <annotation> + <documentation> + Build output provider is make build or/and build output file. + </documentation> + </annotation> + <complexType> + <sequence> + <element ref="open" minOccurs="0" maxOccurs="1"/> + <element ref="scannerInfoConsoleParser"/> + </sequence> + </complexType> + </element> + + <element name="scannerInfoProvider"> + <annotation> + <documentation> + Either a command with arguments whose output will provide scanner information or a file that contains the scanner info. + </documentation> + </annotation> + <complexType> + <sequence> + <choice> + <element ref="run"/> + <element ref="open"/> + </choice> + <element ref="scannerInfoConsoleParser"/> + </sequence> + <attribute name="providerId" type="string" use="required"> + <annotation> + <documentation> + An id of the specific provider. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="run"> + <complexType> + <attribute name="class" type="string"> + <annotation> + <documentation> + A fully qualified name of the Java class that implements <samp>org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider2</samp> interface. +If not specified then <samp>org.eclipse.cdt.make.internal.core.scannerconfig.DefaultExternalScannerInfoProvider</samp> is the default one used. + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider"/> + </appInfo> + </annotation> + </attribute> + <attribute name="command" type="string"> + <annotation> + <documentation> + A command to run. Example: <samp>gcc</samp>. + </documentation> + </annotation> + </attribute> + <attribute name="arguments" type="string"> + <annotation> + <documentation> + Arguments for the command. Example: <samp>-E -P -v -dD</samp>. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="open"> + <complexType> + <attribute name="class" type="string"> + <annotation> + <documentation> + A fully qualified name of the Java class that implements <samp>org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoReader</samp> interface. +If not specified then <samp>org.eclipse.cdt.make.internal.core.scannerconfig.DefaultExternalScannerInfoReader</samp> is the default one used. + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="org.eclipse.cdt.make.core.scannerconfig.IESIFileReader"/> + </appInfo> + </annotation> + </attribute> + <attribute name="file" type="string"> + <annotation> + <documentation> + A file containing a make build output or scanner information in some other form. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + 3.0 + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + <samp>org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile</samp> + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + + </documentation> + </annotation> + +</schema> diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTarget.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTarget.java index 57b1b380612..41431fce6a3 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTarget.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTarget.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.make.core; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.newmake.core.IMakeCommonBuildInfo; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -27,7 +25,6 @@ public interface IMakeTarget extends IAdaptable, IMakeCommonBuildInfo { IProject getProject(); - IConfiguration getConfiguration(); /** * @deprecated */ diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetListener.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetListener.java index b31e7214737..42c754531c9 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetListener.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetListener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetManager.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetManager.java index 5a675465039..614a0095bd5 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetManager.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/IMakeTargetManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 @@ -10,24 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.make.core; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; public interface IMakeTargetManager { - /** - * @param project - * @param targetName - * @param targetBuilderID - * @return - * @throws CoreException - * - */ IMakeTarget createTarget(IProject project, String targetName, String targetBuilderID) throws CoreException; - - IMakeTarget createTarget(IConfiguration cfg, String builderId, String targetBuilderID, String name) throws CoreException; - /** * Adds target to manager. * @param target @@ -46,25 +34,10 @@ public interface IMakeTargetManager { void renameTarget(IMakeTarget target, String name) throws CoreException; boolean targetExists(IMakeTarget target); - /** - * @param container - * @return - * @throws CoreException - */ + IMakeTarget[] getTargets(IContainer container) throws CoreException; - - IMakeTarget[] getTargets(IConfiguration cfg, IContainer container) throws CoreException; - - /** - * @param container - * @param name - * @return - * @throws CoreException - */ IMakeTarget findTarget(IContainer container, String name) throws CoreException; - IMakeTarget findTarget(IConfiguration cfg, IContainer container, String name) throws CoreException; - IProject[] getTargetBuilderProjects() throws CoreException; String getBuilderID(String targetBuilderID); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java index ffd4bfef5d7..770c77b7ead 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java @@ -11,15 +11,330 @@ *******************************************************************************/ package org.eclipse.cdt.make.core; -/** - * - * @author Doug Schaefer - * - * @deprecated no longer used by the CDT but I need it temporarily. - * - */ -public class MakeBuilder { +import java.io.IOException; +import java.io.OutputStream; +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.CCorePlugin; +import org.eclipse.cdt.core.CommandLauncher; +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.resources.ACBuilder; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.cdt.internal.core.ConsoleOutputSniffer; +import org.eclipse.cdt.make.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.StreamMonitor; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceRuleFactory; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.IncrementalProjectBuilder; +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.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; + +public class MakeBuilder extends ACBuilder { public final static String BUILDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".makeBuilder"; //$NON-NLS-1$ + public MakeBuilder() { + } + + /** + * @see IncrementalProjectBuilder#build + */ + protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { + boolean bPerformBuild = true; + IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(args, MakeBuilder.BUILDER_ID); + if (!shouldBuild(kind, info)) { + return new IProject[0]; + } + if (kind == IncrementalProjectBuilder.AUTO_BUILD) { + IResourceDelta delta = getDelta(getProject()); + if (delta != null) { + IResource res = delta.getResource(); + if (res != null) { + bPerformBuild = res.getProject().equals(getProject()); + } + } else { + bPerformBuild = false; + } + } + if (bPerformBuild) { + boolean isClean = invokeMake(kind, info, monitor); + if (isClean) { + forgetLastBuiltState(); + } + } + checkCancel(monitor); + return getProject().getReferencedProjects(); + } + + + protected void clean(IProgressMonitor monitor) throws CoreException { + final IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(getProject(), BUILDER_ID); + if (shouldBuild(CLEAN_BUILD, info)) { + IResourceRuleFactory ruleFactory= ResourcesPlugin.getWorkspace().getRuleFactory(); + final ISchedulingRule rule = ruleFactory.modifyRule(getProject()); + Job backgroundJob = new Job("Standard Make Builder"){ //$NON-NLS-1$ + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + try { + ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) { + invokeMake(CLEAN_BUILD, info, monitor); + } + }, rule, IWorkspace.AVOID_UPDATE, monitor); + } catch (CoreException e) { + return e.getStatus(); + } + IStatus returnStatus = Status.OK_STATUS; + return returnStatus; + } + + + }; + + backgroundJob.setRule(rule); + backgroundJob.schedule(); + } + } + + + + protected boolean invokeMake(int kind, IMakeBuilderInfo info, IProgressMonitor monitor) { + boolean isClean = false; + IProject currProject = getProject(); + + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(MakeMessages.getString("MakeBuilder.Invoking_Make_Builder") + currProject.getName(), 100); //$NON-NLS-1$ + + try { + IPath buildCommand = info.getBuildCommand(); + if (buildCommand != null) { + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(currProject); + + OutputStream cos = console.getOutputStream(); + + // remove all markers for this project + removeAllMarkers(currProject); + + IPath workingDirectory = MakeBuilderUtil.getBuildDirectory(currProject, info); + + String[] targets = getTargets(kind, info); + if (targets.length != 0 && targets[targets.length - 1].equals(info.getCleanBuildTarget())) //$NON-NLS-1$ + isClean = true; + + String errMsg = null; + CommandLauncher launcher = new CommandLauncher(); + // Print the command for visual interaction. + launcher.showCommand(true); + + // Set the environment + HashMap envMap = new HashMap(); + if (info.appendEnvironment()) { + envMap.putAll(launcher.getEnvironment()); + } + // Add variables from build info + envMap.putAll(info.getExpandedEnvironment()); + Iterator iter = envMap.entrySet().iterator(); + List strings= new ArrayList(envMap.size()); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry) iter.next(); + StringBuffer buffer= new StringBuffer((String) entry.getKey()); + buffer.append('=').append((String) entry.getValue()); + strings.add(buffer.toString()); + } + String[] env = (String[]) strings.toArray(new String[strings.size()]); + String[] buildArguments = targets; + if (info.isDefaultBuildCmd()) { + if (!info.isStopOnError()) { + buildArguments = new String[targets.length + 1]; + buildArguments[0] = "-k"; //$NON-NLS-1$ + System.arraycopy(targets, 0, buildArguments, 1, targets.length); + } + } else { + String args = info.getBuildArguments(); + if (args != null && !args.equals("")) { //$NON-NLS-1$ + String[] newArgs = makeArray(args); + buildArguments = new String[targets.length + newArgs.length]; + System.arraycopy(newArgs, 0, buildArguments, 0, newArgs.length); + System.arraycopy(targets, 0, buildArguments, newArgs.length, targets.length); + } + } +// MakeRecon recon = new MakeRecon(buildCommand, buildArguments, env, workingDirectory, makeMonitor, cos); +// recon.invokeMakeRecon(); +// cos = recon; + QualifiedName qName = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), "progressMonitor"); //$NON-NLS-1$ + Integer last = (Integer)getProject().getSessionProperty(qName); + if (last == null) { + last = new Integer(100); + } + StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 100), cos, last.intValue()); + ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectory, this, info.getErrorParsers()); + epm.setOutputStream(streamMon); + OutputStream stdout = epm.getOutputStream(); + OutputStream stderr = epm.getOutputStream(); + // Sniff console output for scanner info + ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getMakeBuilderOutputSniffer( + stdout, stderr, getProject(), workingDirectory, null, this, null); + OutputStream consoleOut = (sniffer == null ? stdout : sniffer.getOutputStream()); + OutputStream consoleErr = (sniffer == null ? stderr : sniffer.getErrorStream()); + Process p = launcher.execute(buildCommand, buildArguments, env, workingDirectory); + if (p != null) { + try { + // Close the input of the Process explicitly. + // We will never write to it. + p.getOutputStream().close(); + } catch (IOException e) { + } + // Before launching give visual cues via the monitor + monitor.subTask(MakeMessages.getString("MakeBuilder.Invoking_Command") + launcher.getCommandLine()); //$NON-NLS-1$ + if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) + != CommandLauncher.OK) + errMsg = launcher.getErrorMessage(); + monitor.subTask(MakeMessages.getString("MakeBuilder.Updating_project")); //$NON-NLS-1$ + + try { + // Do not allow the cancel of the refresh, since the builder is external + // to Eclipse, files may have been created/modified and we will be out-of-sync. + // The caveat is for hugue projects, it may take sometimes at every build. + currProject.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + } + } else { + errMsg = launcher.getErrorMessage(); + } + getProject().setSessionProperty(qName, !monitor.isCanceled() && !isClean ? new Integer(streamMon.getWorkDone()) : null); + + if (errMsg != null) { + StringBuffer buf = new StringBuffer(buildCommand.toString() + " "); //$NON-NLS-1$ + for (int i = 0; i < buildArguments.length; i++) { + buf.append(buildArguments[i]); + buf.append(' '); + } + + String errorDesc = MakeMessages.getFormattedString("MakeBuilder.buildError", buf.toString()); //$NON-NLS-1$ + buf = new StringBuffer(errorDesc); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$ + cos.write(buf.toString().getBytes()); + cos.flush(); + } + + stdout.close(); + stderr.close(); + + monitor.subTask(MakeMessages.getString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$ + consoleOut.close(); + consoleErr.close(); + epm.reportProblems(); + cos.close(); + } + } catch (Exception e) { + CCorePlugin.log(e); + } finally { + monitor.done(); + } + return (isClean); + } + + /** + * Check whether the build has been canceled. + */ + public void checkCancel(IProgressMonitor monitor) { + if (monitor != null && monitor.isCanceled()) + throw new OperationCanceledException(); + } + + protected boolean shouldBuild(int kind, IMakeBuilderInfo info) { + switch (kind) { + case IncrementalProjectBuilder.AUTO_BUILD : + return info.isAutoBuildEnable(); + case IncrementalProjectBuilder.INCREMENTAL_BUILD : // now treated as the same! + case IncrementalProjectBuilder.FULL_BUILD : + return info.isFullBuildEnabled() | info.isIncrementalBuildEnabled() ; + case IncrementalProjectBuilder.CLEAN_BUILD : + return info.isCleanBuildEnabled(); + } + return true; + } + + protected String[] getTargets(int kind, IMakeBuilderInfo info) { + String targets = ""; //$NON-NLS-1$ + switch (kind) { + case IncrementalProjectBuilder.AUTO_BUILD : + targets = info.getAutoBuildTarget(); + break; + case IncrementalProjectBuilder.INCREMENTAL_BUILD : // now treated as the same! + case IncrementalProjectBuilder.FULL_BUILD : + targets = info.getIncrementalBuildTarget(); + break; + case IncrementalProjectBuilder.CLEAN_BUILD : + targets = info.getCleanBuildTarget(); + break; + } + return makeArray(targets); + } + + // Turn the string into an array. + String[] makeArray(String string) { + string.trim(); + char[] array = string.toCharArray(); + ArrayList aList = new ArrayList(); + StringBuffer buffer = new StringBuffer(); + boolean inComment = false; + for (int i = 0; i < array.length; i++) { + char c = array[i]; + if (array[i] == '"' || array[i] == '\'') { + if (i > 0 && array[i - 1] == '\\') { + inComment = false; + } else { + inComment = !inComment; + } + } + if (c == ' ' && !inComment) { + aList.add(buffer.toString()); + buffer = new StringBuffer(); + } else { + buffer.append(c); + } + } + if (buffer.length() > 0) + aList.add(buffer.toString()); + return (String[]) aList.toArray(new String[aList.size()]); + } + + private void removeAllMarkers(IProject currProject) throws CoreException { + IWorkspace workspace = currProject.getWorkspace(); + + // remove all markers + IMarker[] markers = currProject.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); + if (markers != null) { + workspace.deleteMarkers(markers); + } + } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilderUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilderUtil.java new file mode 100644 index 00000000000..a95a8eec695 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilderUtil.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 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 implementation + * Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136) + *******************************************************************************/ +package org.eclipse.cdt.make.core; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +public class MakeBuilderUtil { + + public static IPath getBuildDirectory(IProject project, IPath subPath, String builderID) { + IPath rootPath = getBuildDirectory(project, builderID); + return rootPath.append(subPath); + } + + public static IPath getBuildDirectory(IProject project, String builderID) { + IMakeBuilderInfo info; + try { + info = MakeCorePlugin.createBuildInfo(project, builderID); + } catch (CoreException e) { + return project.getLocation(); + } + return getBuildDirectory(project, info); + } + + public static IPath getBuildDirectory(IProject project, IMakeBuilderInfo info) { + IPath buildDirectory = info.getBuildLocation(); + if (!buildDirectory.isEmpty()) { + IResource res = project.getParent().findMember(buildDirectory); + if (res instanceof IContainer && res.exists()) { + buildDirectory = res.getLocation(); + } + } else { + buildDirectory = project.getLocation(); + } + return buildDirectory; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java index 42af4f20c14..fcf67e4387d 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java @@ -16,21 +16,34 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.eclipse.cdt.make.core.makefile.IMakefile; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager; +import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; import org.eclipse.cdt.make.internal.core.BuildInfoFactory; import org.eclipse.cdt.make.internal.core.MakeTargetManager; import org.eclipse.cdt.make.internal.core.makefile.gnu.GNUMakefile; import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefile; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathManager; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigInfoFactory; +import org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerConfigUtil; +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.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; 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.Plugin; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; @@ -44,9 +57,9 @@ public class MakeCorePlugin extends Plugin { public static final String MAKE_PROJECT_ID = MakeCorePlugin.getUniqueIdentifier() + ".make"; //$NON-NLS-1$ public static final String OLD_BUILDER_ID = "org.eclipse.cdt.core.cbuilder"; //$NON-NLS-1$ -// public static final String EXTERNAL_SI_PROVIDER_SIMPLE_ID = "ExternalScannerInfoProvider"; //$NON-NLS-1$ -// public static final String SI_CONSOLE_PARSER_SIMPLE_ID = "ScannerInfoConsoleParser"; //$NON-NLS-1$ -// public static final String DEFAULT_EXTERNAL_SI_PROVIDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".DefaultExternalScannerInfoProvider"; //$NON-NLS-1$ + public static final String EXTERNAL_SI_PROVIDER_SIMPLE_ID = "ExternalScannerInfoProvider"; //$NON-NLS-1$ + public static final String SI_CONSOLE_PARSER_SIMPLE_ID = "ScannerInfoConsoleParser"; //$NON-NLS-1$ + public static final String DEFAULT_EXTERNAL_SI_PROVIDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".DefaultExternalScannerInfoProvider"; //$NON-NLS-1$ public static final String GCC_SPECS_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCSpecsConsoleParser"; //$NON-NLS-1$ public static final String GCC_SCANNER_INFO_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCScannerInfoConsoleParser"; //$NON-NLS-1$ @@ -56,7 +69,7 @@ public class MakeCorePlugin extends Plugin { private MakeTargetManager fTargetManager; -// private DiscoveredPathManager fDiscoveryPathManager; + private DiscoveredPathManager fDiscoveryPathManager; //The shared instance. private static MakeCorePlugin plugin; @@ -100,17 +113,17 @@ public class MakeCorePlugin extends Plugin { return getDefault().getBundle().getSymbolicName(); } -// public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) { -// return BuildInfoFactory.create(prefs, builderID, useDefaults); -// } -// -// public static IMakeBuilderInfo createBuildInfo(IProject project, String builderID) throws CoreException { -// return ManagedBuilderCorePlugin.createBuilders(project, args)Info(project, builderID); -// } -// -// public static IMakeBuilderInfo createBuildInfo(Map args, String builderID) { -// return BuildInfoFactory.create(args, builderID); -// } + public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) { + return BuildInfoFactory.create(prefs, builderID, useDefaults); + } + + public static IMakeBuilderInfo createBuildInfo(IProject project, String builderID) throws CoreException { + return BuildInfoFactory.create(project, builderID); + } + + public static IMakeBuilderInfo createBuildInfo(Map args, String builderID) { + return BuildInfoFactory.create(args, builderID); + } public IMakeTargetManager getTargetManager() { if ( fTargetManager == null) { @@ -173,10 +186,10 @@ public class MakeCorePlugin extends Plugin { fTargetManager.shutdown(); fTargetManager = null; } -// if (fDiscoveryPathManager != null) { -// fDiscoveryPathManager.shutdown(); -// fDiscoveryPathManager = null; -// } + if (fDiscoveryPathManager != null) { + fDiscoveryPathManager.shutdown(); + fDiscoveryPathManager = null; + } savePluginPreferences(); } finally { super.stop(context); @@ -187,115 +200,115 @@ public class MakeCorePlugin extends Plugin { * Following methods create IScannerConfigBuilderInfo * Delegating requests to ScannerConfigInfoFactory */ -// public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( -// Preferences prefs, String builderID, boolean useDefaults) { -// return ScannerConfigInfoFactory.create(prefs, builderID, useDefaults); -// } -// -// public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( -// IProject project, String builderID) throws CoreException { -// return ScannerConfigInfoFactory.create(project, builderID); -// } -// -// public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( -// Map args, String builderID) { -// return ScannerConfigInfoFactory.create(args, builderID); -// } + public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( + Preferences prefs, String builderID, boolean useDefaults) { + return ScannerConfigInfoFactory.create(prefs, builderID, useDefaults); + } + + public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( + IProject project, String builderID) throws CoreException { + return ScannerConfigInfoFactory.create(project, builderID); + } + + public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( + Map args, String builderID) { + return ScannerConfigInfoFactory.create(args, builderID); + } public static IPath getWorkingDirectory() { return MakeCorePlugin.getDefault().getStateLocation(); } -// public IDiscoveredPathManager getDiscoveryManager() { -// if ( fDiscoveryPathManager == null) { -// fDiscoveryPathManager = new DiscoveredPathManager(); -// fDiscoveryPathManager.startup(); -// } -// return fDiscoveryPathManager; -// } + public IDiscoveredPathManager getDiscoveryManager() { + if ( fDiscoveryPathManager == null) { + fDiscoveryPathManager = new DiscoveredPathManager(); + fDiscoveryPathManager.startup(); + } + return fDiscoveryPathManager; + } + + /** + * @param id - id specifying external scanner info provider + * @return provider - new instance of an external scanner info provider + */ + public IExternalScannerInfoProvider getExternalScannerInfoProvider(String id) { + try { + IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, EXTERNAL_SI_PROVIDER_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + String tool = extensions[i].getUniqueIdentifier(); + if (tool != null && tool.equals(id)) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + IConfigurationElement[] runElement = configElements[j].getChildren("run"); //$NON-NLS-1$ + if (runElement.length > 0) { + IExternalScannerInfoProvider builder = (IExternalScannerInfoProvider) runElement[0].createExecutableExtension("class"); //$NON-NLS-1$ + return builder; + } + } + } + } + } + } + catch (CoreException e) { + log(e); + } + return null; + } -// /** -// * @param id - id specifying external scanner info provider -// * @return provider - new instance of an external scanner info provider -// */ -// public IExternalScannerInfoProvider getExternalScannerInfoProvider(String id) { -// try { -// IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, EXTERNAL_SI_PROVIDER_SIMPLE_ID); -// if (extension != null) { -// IExtension[] extensions = extension.getExtensions(); -// for (int i = 0; i < extensions.length; i++) { -// String tool = extensions[i].getUniqueIdentifier(); -// if (tool != null && tool.equals(id)) { -// IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); -// for (int j = 0; j < configElements.length; j++) { -// IConfigurationElement[] runElement = configElements[j].getChildren("run"); //$NON-NLS-1$ -// if (runElement.length > 0) { -// IExternalScannerInfoProvider builder = (IExternalScannerInfoProvider) runElement[0].createExecutableExtension("class"); //$NON-NLS-1$ -// return builder; -// } -// } -// } -// } -// } -// } -// catch (CoreException e) { -// log(e); -// } -// return null; -// } -// -// /** -// * @param commandId -// * @return String[] - array of parserIds associated with the commandId or 'all' -// */ -// public String[] getScannerInfoConsoleParserIds(String commandId) { -// String[] empty = new String[0]; -// if (commandId == null || commandId.length() == 0) { -// commandId = "all"; //$NON-NLS-1$ -// } -// IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, SI_CONSOLE_PARSER_SIMPLE_ID); -// if (extension != null) { -// IExtension[] extensions = extension.getExtensions(); -// List parserIds = new ArrayList(extensions.length); -// for (int i = 0; i < extensions.length; i++) { -// String parserId = extensions[i].getUniqueIdentifier(); -// if (parserId != null) { -// IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); -// String id = configElements[0].getAttribute("commandId");//$NON-NLS-1$ -// if (id != null && (id.equals(commandId) || id.equals("all"))) { //$NON-NLS-1$ -// parserIds.add(parserId); -// } -// } -// } -// return (String[])parserIds.toArray(empty); -// } -// return empty; -// } -// -// /** -// * @param parserId -// * @return parser - parser object identified by the parserId -// */ -// public IScannerInfoConsoleParser getScannerInfoConsoleParser(String parserId) { -// try { -// IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, SI_CONSOLE_PARSER_SIMPLE_ID); -// if (extension != null) { -// IExtension[] extensions = extension.getExtensions(); -// for (int i = 0; i < extensions.length; i++) { -// String id = extensions[i].getUniqueIdentifier(); -// if (id != null && id.equals(parserId)) { -// IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); -// IScannerInfoConsoleParser parser = (IScannerInfoConsoleParser)configElements[0].createExecutableExtension("class");//$NON-NLS-1$ -// return parser; -// } -// } -// } -// } -// catch (CoreException e) { -// log(e); -// } -// return null; -// } + /** + * @param commandId + * @return String[] - array of parserIds associated with the commandId or 'all' + */ + public String[] getScannerInfoConsoleParserIds(String commandId) { + String[] empty = new String[0]; + if (commandId == null || commandId.length() == 0) { + commandId = "all"; //$NON-NLS-1$ + } + IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, SI_CONSOLE_PARSER_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + List parserIds = new ArrayList(extensions.length); + for (int i = 0; i < extensions.length; i++) { + String parserId = extensions[i].getUniqueIdentifier(); + if (parserId != null) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + String id = configElements[0].getAttribute("commandId");//$NON-NLS-1$ + if (id != null && (id.equals(commandId) || id.equals("all"))) { //$NON-NLS-1$ + parserIds.add(parserId); + } + } + } + return (String[])parserIds.toArray(empty); + } + return empty; + } + + /** + * @param parserId + * @return parser - parser object identified by the parserId + */ + public IScannerInfoConsoleParser getScannerInfoConsoleParser(String parserId) { + try { + IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, SI_CONSOLE_PARSER_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + String id = extensions[i].getUniqueIdentifier(); + if (id != null && id.equals(parserId)) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + IScannerInfoConsoleParser parser = (IScannerInfoConsoleParser)configElements[0].createExecutableExtension("class");//$NON-NLS-1$ + return parser; + } + } + } + } + catch (CoreException e) { + log(e); + } + return null; + } /* (non-Javadoc) * @see org.eclipse.core.runtime.Plugin#startup() @@ -306,32 +319,19 @@ public class MakeCorePlugin extends Plugin { //Set debug tracing options configurePluginDebugOptions(); // Scanner config discovery setup -// GCCScannerConfigUtil.createSpecs(); + GCCScannerConfigUtil.createSpecs(); } -// private static final String SCANNER_CONFIG = MakeCorePlugin.getUniqueIdentifier() + "/debug/scdiscovery"; //$NON-NLS-1$ + private static final String SCANNER_CONFIG = MakeCorePlugin.getUniqueIdentifier() + "/debug/scdiscovery"; //$NON-NLS-1$ /** * */ private void configurePluginDebugOptions() { -// if (isDebugging()) { -// String option = Platform.getDebugOption(SCANNER_CONFIG); -// if (option != null) { -// TraceUtil.SCANNER_CONFIG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ -// } -// } - } - - public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) { - return BuildInfoFactory.create(prefs, builderID, useDefaults); - } - - public static IMakeBuilderInfo createBuildInfo(IProject project, String builderID) throws CoreException { - return BuildInfoFactory.create(project, builderID); - } - - public static IMakeBuilderInfo createBuildInfo(Map args, String builderID) { - return BuildInfoFactory.create(args, builderID); + if (isDebugging()) { + String option = Platform.getDebugOption(SCANNER_CONFIG); + if (option != null) { + TraceUtil.SCANNER_CONFIG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + } + } } - } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeProjectNature.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeProjectNature.java index fdde361be6b..0f532ac42aa 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeProjectNature.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeProjectNature.java @@ -119,48 +119,48 @@ public class MakeProjectNature implements IProjectNature { project.setDescription(description, mon); } -// public void addBuildSpec() throws CoreException { -// addToBuildSpec(getProject(), MakeBuilder.BUILDER_ID, null); -// } + public void addBuildSpec() throws CoreException { + addToBuildSpec(getProject(), MakeBuilder.BUILDER_ID, null); + } /** * @see IProjectNature#configure */ public void configure() throws CoreException { -// addBuildSpec(); -// IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(MakeCorePlugin.getDefault().getPluginPreferences(), MakeBuilder.BUILDER_ID, false); -// IMakeBuilderInfo projectInfo = MakeCorePlugin.createBuildInfo(getProject(), MakeBuilder.BUILDER_ID); -// projectInfo.setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, "")); //$NON-NLS-1$ -// projectInfo.setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make")); //$NON-NLS-1$ -// -// projectInfo.setUseDefaultBuildCmd(info.isDefaultBuildCmd()); -// projectInfo.setStopOnError(info.isStopOnError()); -// -// projectInfo.setAutoBuildEnable(info.isAutoBuildEnable()); -// projectInfo.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_AUTO, info.getBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_AUTO, "")); //$NON-NLS-1$ -// -// projectInfo.setIncrementalBuildEnable(info.isIncrementalBuildEnabled()); -// projectInfo.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_INCREMENTAL, info.getBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_INCREMENTAL, "")); //$NON-NLS-1$ -// -// projectInfo.setFullBuildEnable(info.isIncrementalBuildEnabled()); -// -// projectInfo.setCleanBuildEnable(info.isCleanBuildEnabled()); -// projectInfo.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_CLEAN, info.getBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_CLEAN, "")); //$NON-NLS-1$ -// -// projectInfo.setErrorParsers(info.getErrorParsers()); -// projectInfo.setAppendEnvironment(info.appendEnvironment()); -// projectInfo.setEnvironment(info.getEnvironment()); + addBuildSpec(); + IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(MakeCorePlugin.getDefault().getPluginPreferences(), MakeBuilder.BUILDER_ID, false); + IMakeBuilderInfo projectInfo = MakeCorePlugin.createBuildInfo(getProject(), MakeBuilder.BUILDER_ID); + projectInfo.setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, "")); //$NON-NLS-1$ + projectInfo.setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make")); //$NON-NLS-1$ + + projectInfo.setUseDefaultBuildCmd(info.isDefaultBuildCmd()); + projectInfo.setStopOnError(info.isStopOnError()); + + projectInfo.setAutoBuildEnable(info.isAutoBuildEnable()); + projectInfo.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_AUTO, info.getBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_AUTO, "")); //$NON-NLS-1$ + + projectInfo.setIncrementalBuildEnable(info.isIncrementalBuildEnabled()); + projectInfo.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_INCREMENTAL, info.getBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_INCREMENTAL, "")); //$NON-NLS-1$ + + projectInfo.setFullBuildEnable(info.isIncrementalBuildEnabled()); + + projectInfo.setCleanBuildEnable(info.isCleanBuildEnabled()); + projectInfo.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_CLEAN, info.getBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_CLEAN, "")); //$NON-NLS-1$ + + projectInfo.setErrorParsers(info.getErrorParsers()); + projectInfo.setAppendEnvironment(info.appendEnvironment()); + projectInfo.setEnvironment(info.getEnvironment()); } -// public void removeBuildSpec() throws CoreException { -// removeFromBuildSpec(getProject(), MakeBuilder.BUILDER_ID, null); -// } + public void removeBuildSpec() throws CoreException { + removeFromBuildSpec(getProject(), MakeBuilder.BUILDER_ID, null); + } /** * @see IProjectNature#deconfigure */ public void deconfigure() throws CoreException { -// removeBuildSpec(); + removeBuildSpec(); } /** diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerInfo.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerInfo.java new file mode 100644 index 00000000000..5108de96350 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerInfo.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.core; + +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.parser.IScannerInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +/** + * @deprecated + * @author DInglis + * + */ + +public class MakeScannerInfo implements IScannerInfo { + + private IProject project; + private ArrayList symbolList; + private ArrayList pathList; + boolean hasChanged = false; + + public MakeScannerInfo(IProject project) { + this.project = project; + } + + IProject getProject() { + return project; + } + + public void update() throws CoreException { + if (hasChanged) { + MakeScannerProvider.updateScannerInfo(this); + hasChanged = false; + } + } + + public synchronized void setPreprocessorSymbols(String[] symbols) { + if (!Arrays.equals(symbols, getSymbolList().toArray())) { + hasChanged = true; + // Clear out any existing symbols and add the new stuff + getSymbolList().clear(); + getSymbolList().addAll(Arrays.asList(symbols)); + } + } + + public synchronized void setIncludePaths(String[] paths) { + if (!Arrays.equals(paths, getPathList().toArray())) { + hasChanged = true; + // Clear the existing list and add the paths + getPathList().clear(); + getPathList().addAll(Arrays.asList(paths)); + } + } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() + */ + public synchronized String[] getIncludePaths() { + return (String[]) getPathList().toArray(new String[getPathList().size()]); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() + */ + public synchronized Map getDefinedSymbols() { + // Return the defined symbols for the default configuration + HashMap symbols = new HashMap(); + String[] symbolList = getPreprocessorSymbols(); + for (int i = 0; i < symbolList.length; ++i) { + String symbol = symbolList[i]; + if (symbol.length() == 0) { + continue; + } + String key = new String(); + String value = new String(); + 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(); + } + symbols.put(key, value); + } + return symbols; + } + + protected List getPathList() { + if (pathList == null) { + pathList = new ArrayList(); + } + return pathList; + } + + public synchronized String[] getPreprocessorSymbols() { + return (String[]) getSymbolList().toArray(new String[getSymbolList().size()]); + } + + protected List getSymbolList() { + if (symbolList == null) { + symbolList = new ArrayList(); + } + return symbolList; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java new file mode 100644 index 00000000000..3a759742995 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.resources.ScannerProvider; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.QualifiedName; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * @deprecated @author DInglis + * + */ +public class MakeScannerProvider extends ScannerProvider { + + // This is the id of the IScannerInfoProvider extension point entry + public static final String INTERFACE_IDENTITY = MakeCorePlugin.getUniqueIdentifier() + ".MakeScannerProvider"; //$NON-NLS-1$ + + // Name we will use to store build property with the project + private static final QualifiedName scannerInfoProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), + "makeBuildInfo"); //$NON-NLS-1$ + static final String CDESCRIPTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".makeScannerInfo"; //$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$ + + private static MakeScannerProvider defaultProvider; + + public static MakeScannerProvider getDefault() { + if (defaultProvider == null) { + defaultProvider = new MakeScannerProvider(); + } + return defaultProvider; + } + + public MakeScannerInfo getMakeScannerInfo(IProject project, boolean cacheInfo) throws CoreException { + MakeScannerInfo scannerInfo = null; + // See if there's already one associated with the resource for this + // session + scannerInfo = (MakeScannerInfo)project.getSessionProperty(scannerInfoProperty); + + // Try to load one for the project + if (scannerInfo == null) { + scannerInfo = loadScannerInfo(project); + } else { + return scannerInfo; + } + + // There is nothing persisted for the session, or saved in a file so + // create a build info object + if (scannerInfo != null && cacheInfo == true) { + project.setSessionProperty(scannerInfoProperty, scannerInfo); + } + + // migrate to new C Path Entries + if (scannerInfo != null) { + updateScannerInfo(scannerInfo); + } + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + descriptor.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID); // remove scanner provider which will fallback to default cpath + // provider. + return scannerInfo; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource) + */ + public IScannerInfo getScannerInformation(IResource resource) { + try { + getMakeScannerInfo(resource.getProject(), true); + } catch (CoreException e) { + } + return super.getScannerInformation(resource); + } + + /* + * Loads the build file and parses the nodes for build information. The information is then associated with the resource for the + * duration of the session. + */ + private MakeScannerInfo loadScannerInfo(IProject project) throws CoreException { + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + Node child = descriptor.getProjectData(CDESCRIPTOR_ID).getFirstChild(); + ArrayList includes = new ArrayList(); + ArrayList symbols = new ArrayList(); + while (child != null) { + if (child.getNodeName().equals(INCLUDE_PATH)) { + // Add the path to the property list + includes.add( ((Element)child).getAttribute(PATH)); + } else if (child.getNodeName().equals(DEFINED_SYMBOL)) { + // Add the symbol to the symbol list + symbols.add( ((Element)child).getAttribute(SYMBOL)); + } + child = child.getNextSibling(); + } + MakeScannerInfo info = new MakeScannerInfo(project); + info.setIncludePaths((String[])includes.toArray(new String[includes.size()])); + info.setPreprocessorSymbols((String[])symbols.toArray(new String[symbols.size()])); + return info; + } + + static void migrateToCPathEntries(MakeScannerInfo info) throws CoreException { + Map symbols = info.getDefinedSymbols(); + String[] includes = info.getIncludePaths(); + ICProject cProject = CoreModel.getDefault().create(info.getProject()); + IPathEntry[] entries = cProject.getRawPathEntries(); + List cPaths = new ArrayList(Arrays.asList(entries)); + + Iterator cpIter = cPaths.iterator(); + while(cpIter.hasNext()) { + int kind = ((IPathEntry)cpIter.next()).getEntryKind(); + if(kind == IPathEntry.CDT_INCLUDE || kind == IPathEntry.CDT_MACRO) { + cpIter.remove(); + } + } + for (int i = 0; i < includes.length; i++) { + IIncludeEntry include = CoreModel.newIncludeEntry(info.getProject().getFullPath(), null, new Path(includes[i]), true); + if (!cPaths.contains(include)) { + cPaths.add(include); + } + } + Iterator syms = symbols.entrySet().iterator(); + while (syms.hasNext()) { + Map.Entry entry = (Entry)syms.next(); + IMacroEntry sym = CoreModel.newMacroEntry(info.getProject().getFullPath(), (String)entry.getKey(), + (String)entry.getValue()); + if (!cPaths.contains(sym)) { + cPaths.add(sym); + } + } + cProject.setRawPathEntries((IPathEntry[])cPaths.toArray(new IPathEntry[cPaths.size()]), null); + } + + /** + * The build model manager for standard builds only caches the build information for a resource on a per-session basis. This + * method allows clients of the build model manager to programmatically remove the association between the resource and the + * information while the reource is still open or in the workspace. The Eclipse core will take care of removing it if a resource + * is closed or deleted. + * + * @param resource + */ + public static void removeScannerInfo(IResource resource) { + try { + resource.getProject().setSessionProperty(scannerInfoProperty, null); + } catch (CoreException e) { + } + } + + /** + * Persists build-specific information in the build file. Build information for standard make projects consists of preprocessor + * symbols and includes paths. Other project-related information is stored in the persistent properties of the project. + * + * @param project + */ + public static void updateScannerInfo(final MakeScannerInfo scannerInfo) throws CoreException { + ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) throws CoreException { + IProject project = scannerInfo.getProject(); + + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + + Element rootElement = descriptor.getProjectData(CDESCRIPTOR_ID); + + // Clear out all current children + // Note: Probably would be a better idea to merge in the data + Node child = rootElement.getFirstChild(); + while (child != null) { + rootElement.removeChild(child); + child = rootElement.getFirstChild(); + } + + descriptor.saveProjectData(); + migrateToCPathEntries(scannerInfo); + } + }, null); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeTargetEvent.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeTargetEvent.java index 44c05958f26..dca4dcf2a51 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeTargetEvent.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeTargetEvent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java new file mode 100644 index 00000000000..9cbeca1b47e --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +/** + * Discovered portion of scanner configuration + * @deprecated + * @author vhirsl + */ +public class DiscoveredScannerInfo implements IScannerInfo { + private IProject project; + private LinkedHashMap discoveredPaths; + private LinkedHashMap discoveredSymbols; + + private ArrayList activePaths; + private ArrayList removedPaths; + + private ArrayList activeSymbols; + private ArrayList removedSymbols; + + private org.eclipse.cdt.make.core.MakeScannerInfo userInfo; + + /** + * @param project + */ + public DiscoveredScannerInfo(IProject project) { + this.project = project; + } + + public IProject getProject() { + return project; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IScannerInfo#getDefinedSymbols() + */ + public synchronized Map getDefinedSymbols() { + Map dSymbols = ScannerConfigUtil.scSymbolEntryMap2Map(discoveredSymbols); + dSymbols.putAll(userInfo.getDefinedSymbols()); + return dSymbols; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IScannerInfo#getIncludePaths() + */ + public synchronized String[] getIncludePaths() { + String[] iPaths = new String[getUserIncludePaths().length + getActiveIncludePaths().length]; + System.arraycopy(getUserIncludePaths(), 0, iPaths, 0, getUserIncludePaths().length); + System.arraycopy(getActiveIncludePaths(), 0, iPaths, getUserIncludePaths().length, getActiveIncludePaths().length); + return iPaths; + } + + public org.eclipse.cdt.make.core.MakeScannerInfo getUserScannerInfo() { + return userInfo; + } + + public synchronized void setUserScannerInfo( org.eclipse.cdt.make.core.MakeScannerInfo info) { + userInfo = info; + } + + public LinkedHashMap getDiscoveredIncludePaths() { + if (discoveredPaths == null) { + return new LinkedHashMap(); + } + return new LinkedHashMap(discoveredPaths); + } + public synchronized void setDiscoveredIncludePaths(LinkedHashMap paths) { + discoveredPaths = new LinkedHashMap(paths); + createPathLists(); + } + + /** + * Populates active and removed include path lists + */ + private void createPathLists() { + List aPaths = getActivePathList(); + aPaths.clear(); + List rPaths = getRemovedPathList(); + rPaths.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(path); + } + else { + rPaths.add(path); + } + } + } + + public LinkedHashMap getDiscoveredSymbolDefinitions() { + if (discoveredSymbols == null) { + return new LinkedHashMap(); + } + return new LinkedHashMap(discoveredSymbols); + } + public synchronized void setDiscoveredSymbolDefinitions(LinkedHashMap symbols) { + discoveredSymbols = new LinkedHashMap(symbols); + createSymbolsLists(); + } + + /** + * Populates active and removed defined symbols sets + */ + private void createSymbolsLists() { + List aSymbols = getActiveSymbolsList(); + aSymbols.clear(); + List rSymbols = getRemovedSymbolsList(); + rSymbols.clear(); + + aSymbols.addAll(ScannerConfigUtil.scSymbolsSymbolEntryMap2List(discoveredSymbols, true)); + rSymbols.addAll(ScannerConfigUtil.scSymbolsSymbolEntryMap2List(discoveredSymbols, false)); + } + + public String[] getUserIncludePaths() { + if (userInfo == null) { + return new String[0]; + } + return userInfo.getIncludePaths(); + } + public String[] getActiveIncludePaths() { + return (String[]) getActivePathList().toArray(new String[getActivePathList().size()]); + } + public String[] getRemovedIncludePaths() { + return (String[])getRemovedPathList().toArray(new String[getRemovedPathList().size()]); + } + + public String[] getUserSymbolDefinitions() { + if (userInfo == null) { + return new String[0]; + } + return userInfo.getPreprocessorSymbols(); + } + public String[] getActiveSymbolDefinitions() { + return (String[]) getActiveSymbolsList().toArray(new String[getActiveSymbolsList().size()]); + } + public String[] getRemovedSymbolDefinitions() { + return (String[]) getRemovedSymbolsList().toArray(new String[getRemovedSymbolsList().size()]); + } + public String[] getPreprocessorSymbols() { + // user specified + active + String[] userSymbols = getUserSymbolDefinitions(); + String[] discActiveSymbols = getActiveSymbolDefinitions(); + String[] rv = new String[userSymbols.length + discActiveSymbols.length]; + System.arraycopy(userSymbols, 0, rv, 0, userSymbols.length); + System.arraycopy(discActiveSymbols, 0, rv, userSymbols.length, discActiveSymbols.length); + return rv; + } + + private List getActivePathList() { + if (activePaths == null) { + activePaths = new ArrayList(); + } + return activePaths; + } + + private List getRemovedPathList() { + if (removedPaths == null) { + removedPaths = new ArrayList(); + } + return removedPaths; + } + + private List getActiveSymbolsList() { + if (activeSymbols == null) { + activeSymbols = new ArrayList(); + } + return activeSymbols; + } + + private List getRemovedSymbolsList() { + if (removedSymbols == null) { + removedSymbols = new ArrayList(); + } + return removedSymbols; + } + + public void update() throws CoreException { + DiscoveredScannerInfoProvider.updateScannerInfo(this); + } + + /** + * @param userPaths + */ + public void setUserIncludePaths(List userPaths) { + userInfo.setIncludePaths((String[]) userPaths.toArray(new String[userPaths.size()])); + } + + /** + * @param userSymbols + */ + public void setUserDefinedSymbols(List userSymbols) { + userInfo.setPreprocessorSymbols((String[]) userSymbols.toArray(new String[userSymbols.size()])); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.java new file mode 100644 index 00000000000..24d17bf7af2 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.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.core.scannerconfig; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IContainerEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; +import org.eclipse.cdt.core.resources.ScannerProvider; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.QualifiedName; + +/** + * Provider of both user specified and discovered scanner info + * + * @deprecated @author vhirsl + */ +public class DiscoveredScannerInfoProvider extends ScannerProvider { + + // This is the id of the IScannerInfoProvider extension point entry + public static final String INTERFACE_IDENTITY = MakeCorePlugin.getUniqueIdentifier() + ".DiscoveredScannerInfoProvider"; //$NON-NLS-1$ + + // Name we will use to store build property with the project + private static final QualifiedName scannerInfoProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), + "discoveredMakeBuildInfo"); //$NON-NLS-1$ + + // Singleton + private static DiscoveredScannerInfoProvider instance; + public static DiscoveredScannerInfoProvider getDefault() { + if (instance == null) { + instance = new DiscoveredScannerInfoProvider(); + } + return instance; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource) + */ + public IScannerInfo getScannerInformation(IResource resource) { + try { + getDiscoveredScannerInfo(resource.getProject(), true); + } catch (CoreException e) { + } + return super.getScannerInformation(resource); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#subscribe(org.eclipse.core.resources.IResource, + * org.eclipse.cdt.core.parser.IScannerInfoChangeListener) + */ + public void subscribe(IResource resource, IScannerInfoChangeListener listener) { + super.subscribe(resource, listener); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#unsubscribe(org.eclipse.core.resources.IResource, + * org.eclipse.cdt.core.parser.IScannerInfoChangeListener) + */ + public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { + super.unsubscribe(resource, listener); + } + + public DiscoveredScannerInfo getDiscoveredScannerInfo(IProject project, boolean cacheInfo) throws CoreException { + DiscoveredScannerInfo scannerInfo = null; + // See if there's already one associated with the resource for this + // session + scannerInfo = (DiscoveredScannerInfo)project.getSessionProperty(scannerInfoProperty); + + if (scannerInfo == null) { + scannerInfo = new DiscoveredScannerInfo(project); + // this will convert user info + org.eclipse.cdt.make.core.MakeScannerInfo makeScannerInfo = org.eclipse.cdt.make.core.MakeScannerProvider.getDefault().getMakeScannerInfo( + project, cacheInfo); + scannerInfo.setUserScannerInfo(makeScannerInfo); + + // migrate to new C Path Entries + IContainerEntry container = CoreModel.newContainerEntry(DiscoveredPathContainer.CONTAINER_ID); + ICProject cProject = CoreModel.getDefault().create(project); + if (cProject != null) { + IPathEntry[] entries = cProject.getRawPathEntries(); + List newEntries = new ArrayList(Arrays.asList(entries)); + if (!newEntries.contains(container)) { + newEntries.add(container); + cProject.setRawPathEntries((IPathEntry[])newEntries.toArray(new IPathEntry[newEntries.size()]), null); + } + } + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + descriptor.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID); // remove scanner provider which will fallback to default + // cpath provider. + // place holder to that we don't convert again. + project.setSessionProperty(scannerInfoProperty, scannerInfo); + } + return scannerInfo; + } + + /** + * The build model manager for standard builds only caches the build information for a resource on a per-session basis. This + * method allows clients of the build model manager to programmatically remove the association between the resource and the + * information while the reource is still open or in the workspace. The Eclipse core will take care of removing it if a resource + * is closed or deleted. + * + * @param resource + */ + public static void removeScannerInfo(IResource resource) { + try { + resource.getProject().setSessionProperty(scannerInfoProperty, null); + } catch (CoreException e) { + } + } + + /** + * Persists build-specific information in the build file. Build information for standard make projects consists of preprocessor + * symbols and includes paths. Other project-related information is stored in the persistent properties of the project. + * + * @param scannerInfo + */ + static void updateScannerInfo(DiscoveredScannerInfo scannerInfo) throws CoreException { + // no longer supported! + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java new file mode 100644 index 00000000000..12cd220f35f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.w3c.dom.Element; + +public interface IDiscoveredPathManager { + + interface IDiscoveredPathInfo { + + IProject getProject(); + + /** + * Get include paths for the whole project + */ + IPath[] getIncludePaths(); + /** + * Get defined symbols for the whole project + */ + Map getSymbols(); + + IDiscoveredScannerInfoSerializable getSerializable(); + } + + interface IPerProjectDiscoveredPathInfo extends IDiscoveredPathInfo { + void setIncludeMap(LinkedHashMap map); + void setSymbolMap(LinkedHashMap map); + + LinkedHashMap getIncludeMap(); + LinkedHashMap getSymbolMap(); + } + + interface IPerFileDiscoveredPathInfo extends IDiscoveredPathInfo { + /** + * Get include paths for the specific path (file) + */ + IPath[] getIncludePaths(IPath path); + /** + * Get quote include paths (for #include "...") for the specific path (file) + */ + IPath[] getQuoteIncludePaths(IPath path); + /** + * Get defined symbols for the specific path (file) + */ + Map getSymbols(IPath path); + + /** + * Get include files (gcc option -include) for the specific path (file) + */ + IPath[] getIncludeFiles(IPath path); + /** + * Get macro files (gcc option -imacros) for the specific path (file) + */ + IPath[] getMacroFiles(IPath path); + /** + * Returns if there is any discovered scanner info for the path + */ + boolean isEmpty(IPath path); + } + + 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(); + } + + interface IDiscoveredInfoListener { + + void infoChanged(IDiscoveredPathInfo info); + void infoRemoved(IDiscoveredPathInfo info); + } + + IDiscoveredPathInfo getDiscoveredInfo(IProject project, InfoContext context) throws CoreException; + + IDiscoveredPathInfo getDiscoveredInfo(IProject project) throws CoreException; + void removeDiscoveredInfo(IProject project); + void removeDiscoveredInfo(IProject project, InfoContext context); + void updateDiscoveredInfo(InfoContext context, IDiscoveredPathInfo info, boolean updateContainer, List changedResources) throws CoreException; + void updateDiscoveredInfo(IDiscoveredPathInfo info, List changedResources) throws CoreException; + void changeDiscoveredContainer(IProject project, ScannerConfigScope profileScope, List changedResources); + + void addDiscoveredInfoListener(IDiscoveredInfoListener listener); + void removeDiscoveredInfoListener(IDiscoveredInfoListener listener); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java new file mode 100644 index 00000000000..f0cc3e16ab7 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import java.util.Properties; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * Interface for providers of C/C++ scanner info + * + * @author vhirsl + */ +public interface IExternalScannerInfoProvider { + /** + * Invokes a provider to generate scanner info. + * + * @param monitor + * @param resource project - current project being built + * @param providerId - id of the provider + * @param buildInfo - settings for ScannerConfigBuilder + * @param collector - scanner info collector for the resource (project) + */ + public boolean invokeProvider(IProgressMonitor monitor, + IResource resource, + String providerId, + IScannerConfigBuilderInfo2 buildInfo, + IScannerInfoCollector collector); + + /** + * Alternative interface to pass down the environment. + * + * @param monitor + * @param resource + * @param providerId + * @param buildInfo + * @param collector + * @param env + * @return + */ + public boolean invokeProvider(IProgressMonitor monitor, + IResource resource, + InfoContext context, + String providerId, + IScannerConfigBuilderInfo2 buildInfo, + IScannerInfoCollector collector, + Properties env); + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java new file mode 100644 index 00000000000..f063bdbb6dd --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * Settings for ScannerConfigBuilder + * + * @author vhirsl + */ +public interface IScannerConfigBuilderInfo { + boolean isAutoDiscoveryEnabled(); + void setAutoDiscoveryEnabled(boolean enabled) throws CoreException; + + String getMakeBuilderConsoleParserId(); + void setMakeBuilderConsoleParserId(String parserId) throws CoreException; + + boolean isESIProviderCommandEnabled(); + void setESIProviderCommandEnabled(boolean enabled) throws CoreException; + + boolean isDefaultESIProviderCmd(); + void setUseDefaultESIProviderCmd(boolean on) throws CoreException; + + IPath getESIProviderCommand(); + void setESIProviderCommand(IPath command) throws CoreException; + + String getESIProviderArguments(); + void setESIProviderArguments(String args) throws CoreException; + + String getESIProviderConsoleParserId(); + void setESIProviderConsoleParserId(String parserId) throws CoreException; + + boolean isMakeBuilderConsoleParserEnabled(); + void setMakeBuilderConsoleParserEnabled(boolean enabled) throws CoreException; + + boolean isSIProblemGenerationEnabled(); + void setSIProblemGenerationEnabled(boolean enabled) throws CoreException; +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo2.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo2.java new file mode 100644 index 00000000000..6069064435a --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo2.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; + +/** + * New interface to replace IScannerConfigBuildInfo + * Persisted in .cdtproject file + * + * @author vhirsl + */ +public interface IScannerConfigBuilderInfo2 { + // general SCD options + boolean isAutoDiscoveryEnabled(); + void setAutoDiscoveryEnabled(boolean enable); + + boolean isProblemReportingEnabled(); + void setProblemReportingEnabled(boolean enable); + + String getSelectedProfileId(); + void setSelectedProfileId(String profileId); + + List getProfileIdList(); + + // SCD profile - buildOutputProvider options + boolean isBuildOutputFileActionEnabled(); + void setBuildOutputFileActionEnabled(boolean enable); + + String getBuildOutputFilePath(); + void setBuildOutputFilePath(String path); + + boolean isBuildOutputParserEnabled(); + void setBuildOutputParserEnabled(boolean enable); + + // SCD profile - scanner info provider options + List getProviderIdList(); +// void addSIProvider(String providerId); +// void removeSIProvider(String providerId); + + boolean isProviderOutputParserEnabled(String providerId); + void setProviderOutputParserEnabled(String providerId, boolean enable); + + boolean isUseDefaultProviderCommand(String providerId); + void setUseDefaultProviderCommand(String providerId, boolean enable); + + String getProviderRunCommand(String providerId); + void setProviderRunCommand(String providerId, String command); + + String getProviderRunArguments(String providerId); + void setProviderRunArguments(String providerId, String arguments); + + String getProviderOpenFilePath(String providerId); + void setProviderOpenFilePath(String providerId, String filePath); + + /** + * Persist the buildInfo. + * @throws CoreException + */ + void save() throws CoreException; +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo2Set.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo2Set.java new file mode 100644 index 00000000000..db4f250eaf3 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo2Set.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007 Intel 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: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + + +public interface IScannerConfigBuilderInfo2Set { + /** + * + * @return InfoContext - to IScannerConfigBuilderInfo2 map + */ + Map getInfoMap(); + + IScannerConfigBuilderInfo2 getInfo(InfoContext context); + + IScannerConfigBuilderInfo2 removeInfo(InfoContext context) throws CoreException; + + InfoContext[] getContexts(); + + IScannerConfigBuilderInfo2 createInfo(InfoContext context, IScannerConfigBuilderInfo2 base); + + IScannerConfigBuilderInfo2 createInfo(InfoContext context, IScannerConfigBuilderInfo2 base, String profileId); + + IScannerConfigBuilderInfo2 createInfo(InfoContext context); + + IScannerConfigBuilderInfo2 createInfo(InfoContext context, String profileId); + + void save() throws CoreException; + + IProject getProject(); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector.java new file mode 100644 index 00000000000..e1a6a2c1af0 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector.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.core.scannerconfig; + +import java.util.List; +import java.util.Map; + +/** + * Interface for scanner info collector. + * Used by scanner info console parsers. + * Eclipse independent. + * + * @author vhirsl + */ +public interface IScannerInfoCollector { + /** + * Contribute to resource's scanner configuration + * + * @param resource - if used from within Eclipse it is expected that resource is a + * member of <code>org.eclipse.core.resources.IResource</code> hierarchy. + * If used outside of Eclipse then resource is expected to be a + * <code>java.io.File<code> type. + * @param scannerInfo - a map of key - list pairs, where key is the type of extra info + * i.e. target specific options or imacros commands,... + */ + public void contributeToScannerConfig(Object resource, Map scannerInfo); + + /** + * Returns specific piece of discovered scanner info for a resource + * discovered during the last collection cycle + * @param type + * @param resource + * @return + */ + public List getCollectedScannerInfo(Object resource, ScannerInfoTypes type); + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector2.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector2.java new file mode 100644 index 00000000000..539be721a22 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector2.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.core.scannerconfig; + +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * New scanner info collector interface - Eclipse dependent + * + * @author vhirsl + */ +public interface IScannerInfoCollector2 extends IScannerInfoCollector { + /** + * @param project + */ + public void setProject(IProject project); + + /** + * Relegate discovered scanner configuration to a scanner info provider + * @param monitor + * @throws CoreException + */ + public void updateScannerConfiguration(IProgressMonitor monitor) throws CoreException; + + /** + * Create and return new IDiscoveredPathInfo that can hopefully serialize + * discovered scanner config to a file + * + * @return pathInfo + * @throws CoreException + */ + public IDiscoveredPathInfo createPathInfoObject(); + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector3.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector3.java new file mode 100644 index 00000000000..b894d426e1f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollector3.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2007 Intel 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: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +public interface IScannerInfoCollector3 extends IScannerInfoCollector2 { + void setInfoContext(InfoContext context); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorCleaner.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorCleaner.java new file mode 100644 index 00000000000..5b7d92aabe3 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoCollectorCleaner.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import org.eclipse.core.resources.IResource; + +/** + * Utility functions some collectors may need + * + * @author vhirsl + */ +public interface IScannerInfoCollectorCleaner { + /** + * Delete all discovered paths for the resource + * + * @param project + */ + public void deleteAllPaths(IResource resource); + + /** + * Delete all discovered symbols for the resource + * + * @param project + */ + public void deleteAllSymbols(IResource resource); + + /** + * Delete a specific include path + * + * @param resource + * @param path + */ + public void deletePath(IResource resource, String path); + + /** + * Delete a specific symbol definition + * + * @param resource + * @param path + */ + public void deleteSymbol(IResource resource, String symbol); + + /** + * Delete all discovered scanner info for the resource + * + * @param resource + */ + public void deleteAll(IResource resource); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java new file mode 100644 index 00000000000..3c4dcffd456 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import org.eclipse.cdt.core.IConsoleParser; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; + +/** + * Parses a line of command output looking for scanner info entries. + * + * @author vhirsl + */ +public interface IScannerInfoConsoleParser extends IConsoleParser { + /** + * One time initialization of a console parser. + * + * @param project + * @param workingDirectory + * @param collector - scanner info collector + * @param markerGenerator + */ + public void startup(IProject project, IPath workingDirectory, + IScannerInfoCollector collector, IMarkerGenerator markerGenerator); + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/InfoContext.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/InfoContext.java new file mode 100644 index 00000000000..49b5143b16e --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/InfoContext.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2007 Intel 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: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +import org.eclipse.core.resources.IProject; + +public final class InfoContext { + private IProject fProject; + private String fInstanceId; + + public InfoContext(IProject project){ + this(project, null); + } + + public InfoContext(IProject project, String instanceId){ + this.fProject = project; + this.fInstanceId = instanceId != null ? instanceId : ""; //$NON-NLS-1$ + } + + public String getInstanceId(){ + return fInstanceId; + } + + public boolean equals(Object obj) { + if(obj == this) + return true; + + if(!(obj instanceof InfoContext)) + return false; + + InfoContext other = (InfoContext)obj; + if(fProject == null){ + if(other.fProject != null) + return false; + } else if(!fProject.equals(other.fProject)) + return false; + + if(!fInstanceId.equals(other.fInstanceId)) + return false; + + return true; + } + + public int hashCode() { + int code = fProject != null ? fProject.hashCode() : 0; + + code += fInstanceId.hashCode(); + + return code; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + + if(fProject != null) + buf.append(fProject.toString()); + else + buf.append("no project"); //$NON-NLS-1$ + if(fInstanceId.length() != 0){ + buf.append(" , instance: "); //$NON-NLS-1$ + buf.append(fInstanceId); + } + + return buf.toString(); + } + + /** + * a convenience method that specifies whether this is a default context, + * i.e. the one defined for the project with no extension filters + * + * @return boolean + */ + public boolean isDefaultContext(){ + if(fProject == null) + return false; + + if(fInstanceId.length() != 0) + return false; + + return true; + } + + public IProject getProject(){ + return fProject; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java new file mode 100644 index 00000000000..36d60120ce8 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import java.util.Map; + +import org.eclipse.cdt.core.resources.ACBuilder; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.scannerconfig.jobs.SCJobsUtil; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * Runs after standard make builder. + * Consolidates discovered scanner configuration and updates project's scanner configuration. + * + * @see IncrementalProjectBuilder + */ +public class ScannerConfigBuilder extends ACBuilder { + public final static String BUILDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".ScannerConfigBuilder"; //$NON-NLS-1$ + + public ScannerConfigBuilder() { + super(); + } + + /** + * @see IncrementalProjectBuilder#build + */ + protected IProject [] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { + // If auto discovery is disabled, do nothing +// boolean autodiscoveryEnabled; + boolean autodiscoveryEnabled2; + IScannerConfigBuilderInfo2 buildInfo2 = null; + try { +// IScannerConfigBuilderInfo buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(getProject(), BUILDER_ID); +// autodiscoveryEnabled = buildInfo.isAutoDiscoveryEnabled(); +// +// if (autodiscoveryEnabled) { +// monitor.beginTask("ScannerConfigBuilder.Invoking_Builder", 100); //$NON-NLS-1$ +// monitor.subTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder") + //$NON-NLS-1$ +// getProject().getName()); +// ScannerInfoCollector.getInstance().updateScannerConfiguration(getProject(), new SubProgressMonitor(monitor, 100)); +// } + + buildInfo2 = ScannerConfigProfileManager.createScannerConfigBuildInfo2(getProject()); + autodiscoveryEnabled2 = buildInfo2.isAutoDiscoveryEnabled(); + + if (autodiscoveryEnabled2) { + monitor.beginTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder"), 100); //$NON-NLS-1$ + monitor.subTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder") + //$NON-NLS-1$ + getProject().getName()); + + // get scanner info from all external providers + SCJobsUtil.getProviderScannerInfo(getProject(), buildInfo2, new SubProgressMonitor(monitor, 70)); + + // update and persist scanner configuration + SCJobsUtil.updateScannerConfiguration(getProject(), buildInfo2, new SubProgressMonitor(monitor, 30)); + } + } + catch (CoreException e) { + // builder not installed or disabled +// autodiscoveryEnabled = false; + autodiscoveryEnabled2 = false; + MakeCorePlugin.log(e); + } + + return getProject().getReferencedProjects(); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java new file mode 100644 index 00000000000..fcee6909118 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IContainerEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.runtime.CoreException; + +/** + * @see IProjectNature + */ +public class ScannerConfigNature implements IProjectNature { + + public final static String NATURE_ID = MakeCorePlugin.getUniqueIdentifier() + ".ScannerConfigNature"; //$NON-NLS-1$ + private IProject fProject; + + /** + * @see IProjectNature#configure + */ + public void configure() throws CoreException { + IProjectDescription description = getProject().getDescription(); + ICommand[] commands = description.getBuildSpec(); + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(ScannerConfigBuilder.BUILDER_ID)) { + return; + } + } + ICommand command = description.newCommand(); + command.setBuilderName(ScannerConfigBuilder.BUILDER_ID); + ICommand[] newCommands = new ICommand[commands.length + 1]; + System.arraycopy(commands, 0, newCommands, 0, commands.length); + newCommands[commands.length] = command; + description.setBuildSpec(newCommands); + getProject().setDescription(description, null); + + // set default project scanner config settings + } + + /** + * @see IProjectNature#deconfigure + */ + public void deconfigure() throws CoreException { + IProjectDescription description = getProject().getDescription(); + ICommand[] commands = description.getBuildSpec(); + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(ScannerConfigBuilder.BUILDER_ID)) { + ICommand[] newCommands = new ICommand[commands.length - 1]; + System.arraycopy(commands, 0, newCommands, 0, i); + System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1); + description.setBuildSpec(newCommands); + break; + } + } + getProject().setDescription(description, null); + } + + /** + * @see IProjectNature#getProject + */ + public IProject getProject() { + return fProject; + } + + /** + * @see IProjectNature#setProject + */ + public void setProject(IProject project) { + fProject = project; + } + + public static void addScannerConfigNature(IProject project) throws CoreException { + IProjectDescription description = project.getDescription(); + if (description.hasNature(NATURE_ID)) + return; + String[] ids = description.getNatureIds(); + String[] newIds = new String[ids.length + 1]; + System.arraycopy(ids, 0, newIds, 0, ids.length); + newIds[ids.length] = NATURE_ID; + description.setNatureIds(newIds); + project.setDescription(description, null); + + } + + public static void removeScannerConfigNature(IProject project) throws CoreException { + IProjectDescription description = project.getDescription(); + if (!description.hasNature(NATURE_ID)) + return; + String[] ids = description.getNatureIds(); + for (int i = 0; i < ids.length; ++i) { + if (ids[i].equals(NATURE_ID)) { + String[] newIds = new String[ids.length - 1]; + System.arraycopy(ids, 0, newIds, 0, i); + System.arraycopy(ids, i + 1, newIds, i, ids.length - i - 1); + description.setNatureIds(newIds); + project.setDescription(description, null); + } + } + + } + + /** + * Returns build command as stored in .project file + * + * @param description + * @param builderID + * @return ICommand + */ + public static ICommand getBuildSpec(IProjectDescription description, String builderID) { + ICommand[] commands = description.getBuildSpec(); + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(builderID)) { + return commands[i]; + } + } + return null; + } + + /** + * Stores a build command in .project file + * + * @param description + * @param newCommand + * @return IProjecDescription + */ + public static IProjectDescription setBuildSpec(IProjectDescription description, ICommand newCommand) { + ICommand[] oldCommands = description.getBuildSpec(); + ICommand oldCommand = getBuildSpec(description, newCommand.getBuilderName()); + ICommand[] newCommands; + + if (oldCommand == null) { + // Add the build spec at the end + newCommands = new ICommand[oldCommands.length + 1]; + System.arraycopy(oldCommands, 0, newCommands, 0, oldCommands.length); + newCommands[oldCommands.length] = newCommand; + } + else { + for (int i = 0; i < oldCommands.length; i++) { + if (oldCommands[i] == oldCommand) { + oldCommands[i] = newCommand; + break; + } + } + newCommands = oldCommands; + } + + // Commit the spec change into the project + description.setBuildSpec(newCommands); + return description; + } + + /** + * @param project + */ + public static void initializeDiscoveryOptions(IProject project) { + try { + IScannerConfigBuilderInfo2 scPrefInfo = ScannerConfigProfileManager.createScannerConfigBuildInfo2( + MakeCorePlugin.getDefault().getPluginPreferences(), false); + String selectedProfile = scPrefInfo.getSelectedProfileId(); + IScannerConfigBuilderInfo2 scProjInfo = ScannerConfigProfileManager.createScannerConfigBuildInfo2( + project, selectedProfile); + + scProjInfo.setAutoDiscoveryEnabled(scPrefInfo.isAutoDiscoveryEnabled()); + scProjInfo.setProblemReportingEnabled(scPrefInfo.isProblemReportingEnabled()); + + scProjInfo.setBuildOutputParserEnabled(scPrefInfo.isBuildOutputParserEnabled()); + scProjInfo.setBuildOutputFileActionEnabled(scPrefInfo.isBuildOutputFileActionEnabled()); + scProjInfo.setBuildOutputFilePath(scPrefInfo.getBuildOutputFilePath()); + + ScannerConfigProfile profile = ScannerConfigProfileManager.getInstance().getSCProfileConfiguration(selectedProfile); + List providerIdList = scPrefInfo.getProviderIdList(); + for (Iterator i = providerIdList.iterator(); i.hasNext();) { + String providerId = (String) i.next(); + + scProjInfo.setProviderOutputParserEnabled(providerId, scPrefInfo.isProviderOutputParserEnabled(providerId)); + if (profile.getScannerInfoProviderElement(providerId).getProviderKind().equals( + ScannerConfigProfile.ScannerInfoProvider.RUN)) { + scProjInfo.setProviderRunCommand(providerId, scPrefInfo.getProviderRunCommand(providerId)); + scProjInfo.setProviderRunArguments(providerId, scPrefInfo.getProviderRunArguments(providerId)); + } + else { + scProjInfo.setProviderOpenFilePath(providerId, scPrefInfo.getProviderOpenFilePath(providerId)); + } + } + scProjInfo.save(); + + // the last step is to add discovered paths container + ICProject cProject = CoreModel.getDefault().create(project); + IPathEntry[] rawPathEntries = CoreModel.getRawPathEntries(cProject); + boolean found = false; + for (int i = 0; i < rawPathEntries.length; i++) { + if (rawPathEntries[i].getEntryKind() == IPathEntry.CDT_CONTAINER) { + IContainerEntry container = (IContainerEntry) rawPathEntries[i]; + if (container.getPath().equals(DiscoveredPathContainer.CONTAINER_ID)) { + found = true; + break; + } + } + } + if (!found) { + IPathEntry[] newRawPathEntries = new IPathEntry[rawPathEntries.length + 1]; + System.arraycopy(rawPathEntries, 0, newRawPathEntries, 0, rawPathEntries.length); + newRawPathEntries[rawPathEntries.length] = CoreModel.newContainerEntry(DiscoveredPathContainer.CONTAINER_ID); + CoreModel.setRawPathEntries(cProject, newRawPathEntries, null); + } +// if (profile.getProfileScope().equals(ScannerConfigScope.PROJECT_SCOPE)) { +// CoreModel.setPathEntryContainer(new ICProject[]{cProject}, +// new DiscoveredPathContainer(project), null); +// } +// else { // file scope +// CoreModel.setPathEntryContainer(new ICProject[]{cProject}, +// new PerFileDiscoveredPathContainer(project), null); +// } + } + catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigScope.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigScope.java new file mode 100644 index 00000000000..e77d94d617d --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigScope.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 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.core.scannerconfig; + +/** + * Profile scope enum + * + * @author vhirsl + */ +public class ScannerConfigScope { + public static final ScannerConfigScope PROJECT_SCOPE = new ScannerConfigScope("project"); //$NON-NLS-1$ + public static final ScannerConfigScope FILE_SCOPE = new ScannerConfigScope("file"); //$NON-NLS-1$ + + public String toString() { + return scope; + } + + private String scope; + private ScannerConfigScope(String scope) { + this.scope = scope; + } + /* (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 ScannerConfigScope) return scope.equals(((ScannerConfigScope)arg0).scope); + return false; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return scope.hashCode(); + } +}
\ No newline at end of file diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerInfoTypes.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerInfoTypes.java new file mode 100644 index 00000000000..de3732ec1ec --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerInfoTypes.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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.core.scannerconfig; + +/** + * Typesafe enum pattern + * + * @author vhirsl + */ +public class ScannerInfoTypes { + public static final ScannerInfoTypes COMPILER_COMMAND = new ScannerInfoTypes(1); // CCommandDSC + public static final ScannerInfoTypes UNDISCOVERED_COMPILER_COMMAND = new ScannerInfoTypes(2); // CCommandDSC whose SI has not been resolved + public static final ScannerInfoTypes INCLUDE_PATHS = new ScannerInfoTypes(10); + public static final ScannerInfoTypes QUOTE_INCLUDE_PATHS = new ScannerInfoTypes(11); + public static final ScannerInfoTypes SYMBOL_DEFINITIONS = new ScannerInfoTypes(12); + public static final ScannerInfoTypes TARGET_SPECIFIC_OPTION = new ScannerInfoTypes(13) ; + public static final ScannerInfoTypes COMPILER_VERSION_INFO = new ScannerInfoTypes(14); + + private final int _enum; + + private ScannerInfoTypes(int val) { + _enum = val; + } + public final int toInt() { + return _enum; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java index 04361a0ebc8..689478e3ecc 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 @@ -11,15 +11,14 @@ *******************************************************************************/ package org.eclipse.cdt.make.internal.core; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map; -import org.eclipse.cdt.core.settings.model.ICStorageElement; +import org.eclipse.cdt.make.core.IMakeBuilderInfo; +import org.eclipse.cdt.make.core.IMakeCommonBuildInfo; import org.eclipse.cdt.make.core.IMakeTarget; -import org.eclipse.cdt.managedbuilder.core.IBuilder; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.core.Builder; -import org.eclipse.cdt.managedbuilder.internal.core.BuilderFactory; +import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; @@ -30,154 +29,38 @@ 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.Path; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.osgi.service.environment.Constants; public class MakeTarget extends PlatformObject implements IMakeTarget { -// private final static int USE_PROJECT_ENV_SETTING = 3; + private final static int USE_PROJECT_ENV_SETTING = 3; private final MakeTargetManager manager; private final IProject project; -// private final IConfiguration configuration; - private IBuilder builder; - private String name; -// private boolean isDefaultBuildCmd; -// private boolean isStopOnError; - private boolean runAllBuidlers = true; + private boolean isDefaultBuildCmd; + private boolean isStopOnError; + boolean runAllBuidlers = true; private String targetBuilderID; private IContainer container; -// private int appendEnvironment = USE_PROJECT_ENV_SETTING; -// private boolean appendProjectEnvironment = true; -// private Map buildEnvironment = new HashMap(); -// private Map targetAttributes = new HashMap(); - - private static final String TARGET_ATTR_ID = "targetID"; //$NON-NLS-1$ - private static final String TARGET_ATTR_PATH = "path"; //$NON-NLS-1$ - private static final String TARGET_ATTR_NAME = "name"; //$NON-NLS-1$ - private static final String TARGET_STOP_ON_ERROR = "stopOnError"; //$NON-NLS-1$ - private static final String TARGET_USE_DEFAULT_CMD = "useDefaultCommand"; //$NON-NLS-1$ - private static final String TARGET_ARGUMENTS = "buildArguments"; //$NON-NLS-1$ - private static final String TARGET_COMMAND = "buildCommand"; //$NON-NLS-1$ - private static final String BAD_TARGET = "buidlTarget"; //$NON-NLS-1$ - private static final String TARGET = "buildTarget"; //$NON-NLS-1$ - - MakeTarget(MakeTarget target, IConfiguration cfg) { - manager = target.manager; - project = target.project; - - builder = ManagedBuildManager.createCustomBuilder(cfg, target.builder); - - name = target.name; - runAllBuidlers = target.runAllBuidlers; - targetBuilderID = target.targetBuilderID; - container = target.container; - } - - MakeTarget(MakeTargetManager manager, IConfiguration cfg, ICStorageElement el) throws CoreException { - this.manager = manager; - this.project = cfg.getOwner().getProject(); - ICStorageElement children[] = el.getChildren(); - IBuilder builder = null; - - String path = el.getAttribute(TARGET_ATTR_PATH); - if (path != null && !path.equals("")) { //$NON-NLS-1$ - container = project.getFolder(path); - } else { - container = project; - } - - - for(int i = 0; i < children.length; i++){ - ICStorageElement child = children[i]; - if(IBuilder.BUILDER_ELEMENT_NAME.equals(child.getName())){ - builder = new Builder(cfg.getToolChain(), child, null); - } - } - - if(builder == null){ - builder = ManagedBuildManager.createCustomBuilder(cfg, cfg.getBuilder()); - } - - this.builder = builder; - - targetBuilderID = el.getAttribute(TARGET_ATTR_ID); - name = el.getAttribute(TARGET_ATTR_NAME); - - for(int i = 0; i < children.length; i++){ - ICStorageElement child = children[i]; - String name = child.getName(); - if(TARGET_STOP_ON_ERROR.equals(name)){ - String value = child.getValue(); - if(value != null){ - builder.setStopOnError(Boolean.valueOf(value).booleanValue()); - } - } else if (TARGET_USE_DEFAULT_CMD.equals(name)){ - String value = child.getValue(); - if(value != null){ - builder.setUseDefaultBuildCmd(Boolean.valueOf(value).booleanValue()); - } - } else if (TARGET_COMMAND.equals(name)){ - String value = child.getValue(); - if(value != null){ - builder.setCommand(value); - } - } else if (TARGET_ARGUMENTS.equals(name)){ - String value = child.getValue(); - if(value != null){ - builder.setArguments(value); - } - } else if (BAD_TARGET.equals(name)){ - String value = child.getValue(); - if(value != null){ - builder.setBuildAttribute(IMakeTarget.BUILD_TARGET, value); - } - } else if (TARGET.equals(name)){ - String value = child.getValue(); - if(value != null){ - builder.setBuildAttribute(IMakeTarget.BUILD_TARGET, value); - } - } - } - } - - void serialize(ICStorageElement el){ - - if(container != null){ - el.setAttribute(TARGET_ATTR_PATH, container.getProjectRelativePath().toString()); - } - - if(targetBuilderID != null) - el.setAttribute(TARGET_ATTR_ID, targetBuilderID); - - if(name != null) - el.setAttribute(TARGET_ATTR_NAME, name); + private int appendEnvironment = USE_PROJECT_ENV_SETTING; + private boolean appendProjectEnvironment = true; + private Map buildEnvironment = new HashMap(); + private Map targetAttributes = new HashMap(); - ICStorageElement builderEl = el.createChild(IBuilder.BUILDER_ELEMENT_NAME); - ((Builder)builder).serialize(builderEl, false); - } - - MakeTarget(MakeTargetManager manager, IConfiguration cfg, String builderId, String targetBuilderID, String name) throws CoreException { + MakeTarget(MakeTargetManager manager, IProject project, String targetBuilderID, String name) throws CoreException { this.manager = manager; -// this.configuration = cfg; - this.project = cfg.getOwner().getProject(); + this.project = project; this.targetBuilderID = targetBuilderID; this.name = name; - - if(builderId != null){ - builder = ManagedBuildManager.createCustomBuilder(cfg, builderId); - } /*else if (targetBuilderID != null){ - builder = ManagedBuildManager.createBuilderForEclipseBuilder(cfg, manager.getBuilderID(targetBuilderID)); - } */else { - builder = ManagedBuildManager.createCustomBuilder(cfg, cfg.getBuilder()); - } - -// IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(project, manager.getBuilderID(targetBuilderID)); -// setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make")); //$NON-NLS-1$ -// setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, "")); //$NON-NLS-1$ -// isDefaultBuildCmd = info.isDefaultBuildCmd(); -// isStopOnError = info.isStopOnError(); - manager.updateTarget(this); - + IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(project, manager.getBuilderID(targetBuilderID)); + setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make")); //$NON-NLS-1$ + setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, info.getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, "")); //$NON-NLS-1$ + isDefaultBuildCmd = info.isDefaultBuildCmd(); + isStopOnError = info.isStopOnError(); } public IProject getProject() { @@ -192,9 +75,9 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { this.name = name; } -// Map getAttributeMap() { -// return targetAttributes; -// } + Map getAttributeMap() { + return targetAttributes; + } public String getName() { return name; @@ -205,26 +88,25 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } public boolean isStopOnError() { - return builder.isStopOnError(); + return isStopOnError; } public void setStopOnError(boolean stopOnError) throws CoreException { - builder.setStopOnError(stopOnError); + isStopOnError = stopOnError; manager.updateTarget(this); } public boolean isDefaultBuildCmd() { - return builder.isDefaultBuildCmd(); + return isDefaultBuildCmd; } public void setUseDefaultBuildCmd(boolean useDefault) throws CoreException { - builder.setUseDefaultBuildCmd(useDefault); + isDefaultBuildCmd = useDefault; manager.updateTarget(this); } public IPath getBuildCommand() { - return builder.getBuildCommand(); -/* if (isDefaultBuildCmd()) { + if (isDefaultBuildCmd()) { IMakeBuilderInfo info; try { info = MakeCorePlugin.createBuildInfo(getProject(), manager.getBuilderID(targetBuilderID)); @@ -238,43 +120,36 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } catch (CoreException e) { } return new Path(result); -*/ } public void setBuildCommand(IPath command) throws CoreException { - builder.setBuildCommand(command); -// setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, command.toString()); + setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, command.toString()); } public String getBuildArguments() { - return builder.getBuildArguments(); -// String result = getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, ""); //$NON-NLS-1$ -// try { -// result = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(result, false); -// } catch (CoreException e) { -// } -// return result; + String result = getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, ""); //$NON-NLS-1$ + try { + result = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(result, false); + } catch (CoreException e) { + } + return result; } public void setBuildArguments(String arguments) throws CoreException { - builder.setBuildArguments(arguments); -// setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, arguments); + setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, arguments); } public void setBuildTarget(String target) throws CoreException { -// setBuildAttribute(IMakeTarget.BUILD_TARGET, target); - builder.setIncrementalBuildTarget(target); + setBuildAttribute(IMakeTarget.BUILD_TARGET, target); } public String getBuildTarget() { -/* String result = getBuildAttribute(IMakeTarget.BUILD_TARGET, ""); //$NON-NLS-1$ + String result = getBuildAttribute(IMakeTarget.BUILD_TARGET, ""); //$NON-NLS-1$ try { result = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(result, false); } catch (CoreException e) { } return result; -*/ - return builder.getIncrementalBuildTarget(); } public void setRunAllBuilders(boolean runAllBuilders) throws CoreException { @@ -287,23 +162,13 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } public void setBuildAttribute(String name, String value) throws CoreException { - if(BUILD_TARGET.equals(name)) - setBuildTarget(value); - else - builder.setBuildAttribute(name, value); + targetAttributes.put(name, value); manager.updateTarget(this); } public String getBuildAttribute(String name, String defaultValue) { - String value = null; - if(BUILD_TARGET.equals(name)){ - value = getBuildTarget(); - } else { - value = builder.getBuildAttribute(name, defaultValue); - } - if(value == null) - value = defaultValue; - return value; + String value = (String)targetAttributes.get(name); + return value != null ? value : defaultValue; } public IPath getBuildLocation() { @@ -315,16 +180,21 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } public String[] getErrorParsers() { - return builder.getErrorParsers(); + IMakeBuilderInfo projectInfo; + try { + projectInfo = MakeCorePlugin.createBuildInfo(getProject(), manager.getBuilderID(targetBuilderID)); + return projectInfo.getErrorParsers(); + } catch (CoreException e) { + } + return new String[0]; } public void setErrorParsers(String[] parsers) throws CoreException { - builder.setErrorParsers(parsers); + throw new UnsupportedOperationException(); } public Map getExpandedEnvironment() throws CoreException { - return builder.getExpandedEnvironment(); -/* Map env = null; + Map env = null; if (appendProjectEnvironment()) { IMakeBuilderInfo projectInfo; projectInfo = MakeCorePlugin.createBuildInfo(getProject(), manager.getBuilderID(targetBuilderID)); @@ -353,44 +223,35 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { envMap.put(key, translated); } return envMap; -*/ } public boolean appendProjectEnvironment() { - return builder.appendEnvironment(); -// return appendProjectEnvironment; + return appendProjectEnvironment; } public void setAppendProjectEnvironment(boolean append) { - try { - builder.setAppendEnvironment(append); - } catch (CoreException e) { - e.printStackTrace(); - } -// appendProjectEnvironment = append; + appendProjectEnvironment = append; } public Map getEnvironment() { - return builder.getEnvironment(); + return buildEnvironment; } public void setEnvironment(Map env) throws CoreException { - builder.setEnvironment(env); + buildEnvironment = new HashMap(env); manager.updateTarget(this); } - public void setAppendEnvironment(boolean append) throws CoreException { - builder.setAppendEnvironment(append); -// appendEnvironment = append ? 1 : 0; + public void setAppendEnvironment(boolean append) throws CoreException { + appendEnvironment = append ? 1 : 0; manager.updateTarget(this); } public boolean appendEnvironment() { - return builder.appendEnvironment(); -// return appendEnvironment == USE_PROJECT_ENV_SETTING ? getProjectEnvSetting(): appendEnvironment == 1; + return appendEnvironment == USE_PROJECT_ENV_SETTING ? getProjectEnvSetting(): appendEnvironment == 1; } -/* private boolean getProjectEnvSetting() { + private boolean getProjectEnvSetting() { IMakeBuilderInfo projectInfo; try { projectInfo = MakeCorePlugin.createBuildInfo(getProject(), manager.getBuilderID(targetBuilderID)); @@ -399,7 +260,6 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } return false; } -*/ public IContainer getContainer() { return container; @@ -418,33 +278,10 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { public int hashCode() { return container.hashCode() * 17 + name != null ? name.hashCode(): 0; } - - public IConfiguration getConfiguration(){ - return builder.getParent().getParent(); - } -/* public IConfiguration getConfiguration() throws CoreException{ - IConfiguration builderCfg = builder.getParent().getParent(); - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - IConfiguration cfg = info.getManagedProject().getConfiguration(builderCfg.getId()); - if(cfg == null){ - cfg = info.getDefaultConfiguration(); - } - - if(cfg != null){ - if(builderCfg != cfg){ - ((Builder)builder).setParent(cfg.getToolChain()); - } - return cfg; - } - throw new CoreException(new Status( - IStatus.ERROR, - ManagedBuilderCorePlugin.getUniqueIdentifier(), - "builder configuration was removed")); - } -*/ + public void build(IProgressMonitor monitor) throws CoreException { final String builderID = manager.getBuilderID(targetBuilderID); -/* final HashMap infoMap = new HashMap(); + final HashMap infoMap = new HashMap(); IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(infoMap, builderID); info.setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make")); //$NON-NLS-1$ @@ -460,14 +297,6 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } IMakeBuilderInfo projectInfo = MakeCorePlugin.createBuildInfo(getProject(), builderID); info.setErrorParsers(projectInfo.getErrorParsers()); -*/ - - - IConfiguration cfg = builder.getParent().getParent(); - final Map infoMap = BuilderFactory.createBuildArgs( - new IConfiguration[]{cfg}, - builder); - IWorkspaceRunnable op = new IWorkspaceRunnable() { /* @@ -508,46 +337,4 @@ public class MakeTarget extends PlatformObject implements IMakeTarget { } return super.getAdapter(adapter); } - - public boolean isManagedBuildOn() { - return builder.isManagedBuildOn(); - } - - public void setManagedBuildOn(boolean on) throws CoreException { - builder.setManagedBuildOn(on); - } - - public boolean supportsBuild(boolean managed) { - return builder.supportsBuild(managed); - } - - public void setConfiguration(IConfiguration cfg){ - if(getConfiguration() == cfg) - return; - builder = ManagedBuildManager.createCustomBuilder(cfg, builder); - } - - public int getParallelizationNum() { - return builder.getParallelizationNum(); - } - - public void setParallelizationNum(int num) throws CoreException { - builder.setParallelizationNum(num); - } - - public boolean supportsParallelBuild() { - return builder.supportsParallelBuild(); - } - - public boolean supportsStopOnError(boolean on) { - return builder.supportsStopOnError(on); - } - - public boolean isParallelBuildOn() { - return builder.isParallelBuildOn(); - } - - public void setParallelBuildOn(boolean on) throws CoreException { - builder.setParallelBuildOn(on); - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetManager.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetManager.java index 74741cba978..1ed60d2f148 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetManager.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 @@ -17,18 +17,11 @@ import java.util.Map; import java.util.Vector; import java.util.Map.Entry; -import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; -import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.make.core.IMakeTarget; import org.eclipse.cdt.make.core.IMakeTargetListener; import org.eclipse.cdt.make.core.IMakeTargetManager; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.MakeTargetEvent; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; @@ -47,7 +40,6 @@ import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; public class MakeTargetManager implements IMakeTargetManager, IResourceChangeListener { @@ -56,23 +48,15 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis private static String TARGETS_EXT = "targets"; //$NON-NLS-1$ private ListenerList listeners = new ListenerList(); -// Map projectMap = new HashMap(); + Map projectMap = new HashMap(); private HashMap builderMap; protected Vector fProjects = new Vector(); - private final static QualifiedName projectTargetsQualifiedName = new QualifiedName( - ManagedBuilderCorePlugin.getUniqueIdentifier(), - "targetMapQualifiedName"); //$NON-NLS-1$ public MakeTargetManager() { } public IMakeTarget createTarget(IProject project, String name, String targetBuilderID) throws CoreException { - IConfiguration cfg = getConfiguration(project); - return createTarget(cfg, null, targetBuilderID, name); - } - - public IMakeTarget createTarget(IConfiguration cfg, String builderId, String targetBuilderID, String name) throws CoreException { - return new MakeTarget(this, cfg, builderId, targetBuilderID, name); + return new MakeTarget(this, project, targetBuilderID, name); } public void addTarget(IMakeTarget target) throws CoreException { @@ -81,17 +65,12 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis public void addTarget(IContainer container, IMakeTarget target) throws CoreException { if (container instanceof IWorkspaceRoot) { - throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.getUniqueIdentifier(), -1, MakeMessages.getString("MakeTargetManager.add_to_workspace_root"), null)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeMessages.getString("MakeTargetManager.add_to_workspace_root"), null)); //$NON-NLS-1$ + } + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(target.getProject()); + if (projectTargets == null) { + projectTargets = readTargets(target.getProject()); } - -// ICConfigurationDescription cfgDescription = getDescription(target); -// if(cfgDescription == null){ -// throw new CoreException(new Status(IStatus.ERROR, -// ManagedBuilderCorePlugin.getUniqueIdentifier(), -// "target refers inexistent configuration")); -// } - - ProjectTargets projectTargets = getProjectTargets(target); ((MakeTarget) target).setContainer(container == null ? target.getProject() : container); projectTargets.add((MakeTarget) target); try { @@ -103,67 +82,19 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis notifyListeners(new MakeTargetEvent(this, MakeTargetEvent.TARGET_ADD, target)); } - private ProjectTargets getProjectTargets(IMakeTarget target) throws CoreException{ - return getProjectTargets(target, true); - } - - private ProjectTargets getProjectTargets(IMakeTarget target, boolean load) throws CoreException{ - return getProjectTargets(target.getConfiguration(), load); - } - - private ProjectTargets getProjectTargets(IConfiguration cfg) throws CoreException{ - return getProjectTargets(cfg, true); - } - - private ProjectTargets getProjectTargets(IConfiguration cfg, boolean load) throws CoreException{ - ICConfigurationDescription cfgDes = ManagedBuildManager.getDescriptionForConfiguration(cfg); - if(cfgDes == null){ - throw new CoreException(new Status(IStatus.ERROR, - ManagedBuilderCorePlugin.getUniqueIdentifier(), - "target refers inexistent configuration")); - } - - ICProjectDescription des = cfgDes.getProjectDescription(); - - ProjectTargets targets = (ProjectTargets)des.getSessionProperty(projectTargetsQualifiedName);//getLoaddedProjectTargets(des); - if(targets == null || targets.getProjectDescription() != des){ - if(load){ - if(targets == null) - targets = readTargets(cfg); - else - targets = new ProjectTargets(targets, des, cfg); - des.setSessionProperty(projectTargetsQualifiedName, targets); - } else { - targets = null; - } - } - return targets; - } - -// private ProjectTargets getLoaddedProjectTargets(ICConfigurationDescription des){ -// return (ProjectTargets)des.getSessionProperty(projectTargetsQualifiedName); -// } - -// private void setLoaddedProjectTargets(ICConfigurationDescription des, ProjectTargets targets){ -// des.setSessionProperty(projectTargetsQualifiedName, targets); -// } - public boolean targetExists(IMakeTarget target) { - try { - ProjectTargets projectTargets = getProjectTargets(target); - return projectTargets.contains((MakeTarget) target); - } catch (CoreException e) { + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(target.getProject()); + if (projectTargets == null) { + projectTargets = readTargets(target.getProject()); } - return false; + return projectTargets.contains((MakeTarget) target); } -// private ICConfigurationDescription getDescription(IMakeTarget target){ -// IConfiguration cfg = target.getConfiguration(); -// return ManagedBuildManager.getDescriptionForConfiguration(cfg); -// } - public void removeTarget(IMakeTarget target) throws CoreException { - ProjectTargets projectTargets = getProjectTargets(target); + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(target.getProject()); + if (projectTargets == null) { + projectTargets = readTargets(target.getProject()); + } if (projectTargets.remove((MakeTarget) target)) { try { writeTargets(projectTargets); @@ -176,7 +107,10 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis } public void renameTarget(IMakeTarget target, String name) throws CoreException { - ProjectTargets projectTargets = getProjectTargets(target); + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(target.getProject()); + if (projectTargets == null) { + projectTargets = readTargets(target.getProject()); + } if (!projectTargets.contains((MakeTarget)target)) { throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeMessages.getString("MakeTargetManager.target_exists"), null)); //$NON-NLS-1$ } @@ -185,42 +119,19 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis } public IMakeTarget[] getTargets(IContainer container) throws CoreException { - IConfiguration cfg = getConfiguration(container); - return getTargets(cfg, container); - } - - private IConfiguration getConfiguration(IResource rc){ - IProject project = rc.getProject(); - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - return info.getDefaultConfiguration(); - } - - public IMakeTarget[] getTargets(IConfiguration cfg, IContainer container) - throws CoreException { - ProjectTargets targets = getProjectTargets(cfg); - return setConfiguration(cfg, targets.get(container)); - } - - private IMakeTarget[] setConfiguration(IConfiguration cfg, IMakeTarget targets[]){ - for(int i = 0; i < targets.length; i++){ - ((MakeTarget)targets[i]).setConfiguration(cfg); + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(container.getProject()); + if (projectTargets == null) { + projectTargets = readTargets(container.getProject()); } - return targets; + return projectTargets.get(container); } public IMakeTarget findTarget(IContainer container, String name) throws CoreException { - IConfiguration cfg = getConfiguration(container); - return findTarget(cfg, container, name); - } - - public IMakeTarget findTarget(IConfiguration cfg, IContainer container, - String name) throws CoreException { - ProjectTargets targets = getProjectTargets(cfg); - IMakeTarget target = targets.findTarget(container, name); - if(target != null){ - ((MakeTarget)target).setConfiguration(cfg); + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(container.getProject()); + if (projectTargets == null) { + projectTargets = readTargets(container.getProject()); } - return target; + return projectTargets.findTarget(container, name); } public IProject[] getTargetBuilderProjects() { @@ -319,7 +230,7 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis if (0 != (flags & IResourceDelta.DESCRIPTION)) { if (fProjects.contains(project) && !hasTargetBuilder(project)) { fProjects.remove(project); - // projectMap.remove(project); + projectMap.remove(project); notifyListeners(new MakeTargetEvent(MakeTargetManager.this, MakeTargetEvent.PROJECT_REMOVED, project)); } else if (!fProjects.contains(project) && hasTargetBuilder(project)) { fProjects.add(project); @@ -329,7 +240,7 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis if (0 != (flags & IResourceDelta.OPEN)) { if (!project.isOpen() && fProjects.contains(project)) { fProjects.remove(project); -// projectMap.remove(project); + projectMap.remove(project); notifyListeners(new MakeTargetEvent(MakeTargetManager.this, MakeTargetEvent.PROJECT_REMOVED, project)); } else if (project.isOpen() && hasTargetBuilder(project) && !fProjects.contains(project)) { fProjects.add(project); @@ -345,7 +256,7 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis protected void updateTarget(MakeTarget target) throws CoreException { if (target.getContainer() != null ) { // target has not been added to manager. - ProjectTargets projectTargets = getProjectTargets(target, false); + ProjectTargets projectTargets = (ProjectTargets)projectMap.get(target.getProject()); if (projectTargets == null || !projectTargets.contains(target)) { return; // target has not been added to manager. } @@ -356,38 +267,28 @@ public class MakeTargetManager implements IMakeTargetManager, IResourceChangeLis protected void writeTargets(ProjectTargets projectTargets) throws CoreException { projectTargets.saveTargets(); - CoreModel.getDefault().setProjectDescription(projectTargets.getProject(), projectTargets.getProjectDescription()); } - protected ProjectTargets readTargets(IConfiguration cfg) throws CoreException { - ICConfigurationDescription cfgDes = ManagedBuildManager.getDescriptionForConfiguration(cfg); - if(cfgDes == null){ - throw new CoreException(new Status(IStatus.ERROR, - ManagedBuilderCorePlugin.getUniqueIdentifier(), - "target refers inexistent configuration")); - } - - ICProjectDescription des = cfgDes.getProjectDescription(); - - ProjectTargets projectTargets = new ProjectTargets(this, des, cfg); -// projectMap.put(project, projectTargets); + protected ProjectTargets readTargets(IProject project) { + ProjectTargets projectTargets = new ProjectTargets(this, project); + projectMap.put(project, projectTargets); return projectTargets; } protected void deleteTargets(IProject project) { //Historical: We clean up after all other parts. IPath targetFilePath = - ManagedBuilderCorePlugin.getDefault().getStateLocation().append(project.getName()).addFileExtension(TARGETS_EXT); + MakeCorePlugin.getDefault().getStateLocation().append(project.getName()).addFileExtension(TARGETS_EXT); File targetFile = targetFilePath.toFile(); if (targetFile.exists()) { targetFile.delete(); } -// projectMap.remove(project); + projectMap.remove(project); } protected void initializeBuilders() { builderMap = new HashMap(); - IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(MakeCorePlugin.getUniqueIdentifier(), MakeTargetManager.TARGET_BUILD_EXT); + IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(MakeCorePlugin.PLUGIN_ID, MakeTargetManager.TARGET_BUILD_EXT); IExtension[] ext = point.getExtensions(); for (int i = 0; i < ext.length; i++) { IConfigurationElement[] element = ext[i].getConfigurationElements(); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/PreferenceInitializer.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/PreferenceInitializer.java new file mode 100644 index 00000000000..937bbeab521 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/PreferenceInitializer.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.make.core.IMakeCommonBuildInfo; +import org.eclipse.cdt.make.core.IMakeBuilderInfo; +import org.eclipse.cdt.make.core.MakeBuilder; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; + + +public class PreferenceInitializer extends AbstractPreferenceInitializer { + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences() + */ + public void initializeDefaultPreferences() { + IMakeBuilderInfo info = MakeCorePlugin.createBuildInfo(MakeCorePlugin.getDefault().getPluginPreferences(), MakeBuilder.BUILDER_ID, true); + try { + info.setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make"); //$NON-NLS-1$ + info.setBuildAttribute(IMakeCommonBuildInfo.BUILD_LOCATION, ""); //$NON-NLS-1$ + info.setStopOnError(false); + info.setUseDefaultBuildCmd(true); + info.setAutoBuildEnable(false); + info.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_AUTO, "all"); //$NON-NLS-1$ + info.setIncrementalBuildEnable(true); + info.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_INCREMENTAL, "all"); //$NON-NLS-1$ + info.setFullBuildEnable(true); + info.setCleanBuildEnable(true); + info.setBuildAttribute(IMakeBuilderInfo.BUILD_TARGET_CLEAN, "clean"); //$NON-NLS-1$ + info.setAppendEnvironment(true); + info.setErrorParsers(CCorePlugin.getDefault().getAllErrorParsersIDs()); + } catch (CoreException e) { + } + MakeCorePlugin.getDefault().getPluginPreferences().setDefault(CCorePlugin.PREF_BINARY_PARSER, CCorePlugin.PLUGIN_ID + ".ELF"); //$NON-NLS-1$ + + // default plugin preferences for scanner configuration discovery + IScannerConfigBuilderInfo scInfo = MakeCorePlugin.createScannerConfigBuildInfo(MakeCorePlugin.getDefault().getPluginPreferences(), ScannerConfigBuilder.BUILDER_ID, true); + try { + scInfo.setAutoDiscoveryEnabled(true); + scInfo.setMakeBuilderConsoleParserEnabled(true); + scInfo.setESIProviderCommandEnabled(true); + scInfo.setUseDefaultESIProviderCmd(true); + scInfo.setESIProviderCommand(new Path("gcc")); //$NON-NLS-1$ + scInfo.setESIProviderArguments("-E -P -v -dD ${plugin_state_location}/${specs_file}"); //$NON-NLS-1$ + scInfo.setESIProviderConsoleParserId(MakeCorePlugin.GCC_SPECS_CONSOLE_PARSER_ID); + scInfo.setMakeBuilderConsoleParserId(MakeCorePlugin.GCC_SCANNER_INFO_CONSOLE_PARSER_ID); + scInfo.setSIProblemGenerationEnabled(true); + } catch (CoreException e) { + } + + // default plugin preferences for new scanner configuration discovery + IScannerConfigBuilderInfo2 scInfo2 = ScannerConfigProfileManager. + createScannerConfigBuildInfo2(MakeCorePlugin.getDefault().getPluginPreferences(), + ScannerConfigProfileManager.NULL_PROFILE_ID, true); + scInfo2.setAutoDiscoveryEnabled(true); + scInfo2.setProblemReportingEnabled(true); + scInfo2.setSelectedProfileId(ScannerConfigProfileManager.DEFAULT_SI_PROFILE_ID); + scInfo2.setBuildOutputFileActionEnabled(false); + scInfo2.setBuildOutputFilePath(""); //$NON-NLS-1$ + scInfo2.setBuildOutputParserEnabled(true); + String providerId = "specsFile"; //$NON-NLS-1$ + scInfo2.setProviderOpenFilePath(providerId, "");//$NON-NLS-1$ + scInfo2.setProviderRunCommand(providerId, "gcc"); //$NON-NLS-1$ + scInfo2.setProviderRunArguments(providerId, "-E -P -v -dD ${plugin_state_location}/${specs_file}");//$NON-NLS-1$ + scInfo2.setProviderOutputParserEnabled(providerId, true); + scInfo2.setProblemReportingEnabled(true); + try { + scInfo2.save(); + } + catch (CoreException e) { + } + + // Store default for makefile + MakeCorePlugin.getDefault().getPluginPreferences().setDefault(MakeCorePlugin.MAKEFILE_STYLE, "GNU"); //$NON-NLS-1$ + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/ProjectTargets.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/ProjectTargets.java index f3a73b05308..bd8054d611e 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/ProjectTargets.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/ProjectTargets.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 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 @@ -14,6 +14,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -21,16 +22,19 @@ import java.util.List; import java.util.Map; 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.model.CoreModel; -import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; -import org.eclipse.cdt.core.settings.model.ICProjectDescription; -import org.eclipse.cdt.core.settings.model.ICStorageElement; -import org.eclipse.cdt.core.settings.model.util.XmlStorageElement; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.make.core.IMakeCommonBuildInfo; import org.eclipse.cdt.make.core.IMakeTarget; import org.eclipse.cdt.make.core.MakeCorePlugin; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -39,6 +43,7 @@ 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.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -49,81 +54,49 @@ public class ProjectTargets { private static final String BUILD_TARGET_ELEMENT = "buildTargets"; //$NON-NLS-1$ private static final String TARGET_ELEMENT = "target"; //$NON-NLS-1$ - - private static final String TARGETS_STORAGE_ID = "build.Targets"; //$NON-NLS-1$ + private static final String TARGET_ATTR_ID = "targetID"; //$NON-NLS-1$ + private static final String TARGET_ATTR_PATH = "path"; //$NON-NLS-1$ + private static final String TARGET_ATTR_NAME = "name"; //$NON-NLS-1$ + private static final String TARGET_STOP_ON_ERROR = "stopOnError"; //$NON-NLS-1$ + private static final String TARGET_USE_DEFAULT_CMD = "useDefaultCommand"; //$NON-NLS-1$ + private static final String TARGET_ARGUMENTS = "buildArguments"; //$NON-NLS-1$ + private static final String TARGET_COMMAND = "buildCommand"; //$NON-NLS-1$ + private static final String BAD_TARGET = "buidlTarget"; //$NON-NLS-1$ + private static final String TARGET = "buildTarget"; //$NON-NLS-1$ private HashMap targetMap = new HashMap(); -// private IConfiguration configuraion; - private ICProjectDescription projDes; -// private IProject project; - - public ProjectTargets(ProjectTargets targets, ICProjectDescription des, IConfiguration cfg) { - projDes = des; - for(Iterator iter = targets.targetMap.entrySet().iterator(); iter.hasNext();){ - Map.Entry entry = (Map.Entry)iter.next(); - IContainer cr = (IContainer)entry.getKey(); - List list = (List)entry.getValue(); - - List targetsList = new ArrayList(list.size()); - targetMap.put(cr, targetsList); - for(int i = 0; i < list.size(); i++){ - MakeTarget target = (MakeTarget)list.get(i); - MakeTarget cloneTarget = new MakeTarget(target, cfg); - targetsList.add(cloneTarget); - } - } - } - public ProjectTargets(MakeTargetManager manager, ICProjectDescription projDes, IConfiguration cfg) { + private IProject project; + + public ProjectTargets(MakeTargetManager manager, IProject project) { boolean writeTargets = false; File targetFile = null; -// this.project = project; - this.projDes = projDes; - IProject project = projDes.getProject(); - -// ICConfigurationDescription des = ManagedBuildManager.getDescriptionForConfiguration(cfg); - ICStorageElement el = null; - - try { - ICStorageElement rootEl = getStorageElement(projDes, false); - - if(rootEl != null){ - ICStorageElement children[] = rootEl.getChildren(); - for(int i = 0; i < children.length; i++){ - if(BUILD_TARGET_ELEMENT.equals(children[i].getName())){ - el = children[i]; - break; - } - } - } - } catch (CoreException e1) { - } -// Document document = translateCDTProjectToDocument(); + this.project = project; + + Document document = translateCDTProjectToDocument(); //Historical ... fall back to the workspace and look in previous // location - if (el == null) { - IPath targetFilePath = ManagedBuilderCorePlugin.getDefault().getStateLocation().append(project.getName()).addFileExtension( + if (document == null || !document.hasChildNodes()) { + IPath targetFilePath = MakeCorePlugin.getDefault().getStateLocation().append(project.getName()).addFileExtension( TARGETS_EXT); targetFile = targetFilePath.toFile(); try { InputStream input = new FileInputStream(targetFile); - Document document = translateInputStreamToDocument(input); - Element element = document.getDocumentElement(); - el = new XmlStorageElement(element); + document = translateInputStreamToDocument(input); writeTargets = true; // update cdtproject } catch (FileNotFoundException ex) { /* Ignore */ } } - if (el != null) { - extractMakeTargetsFromDocument(el, manager, cfg); + if (document != null) { + extractMakeTargetsFromDocument(document, manager); if (writeTargets) { try { - saveTargets(); -// translateDocumentToCDTProject(doc); + Document doc = getAsXML(); + translateDocumentToCDTProject(doc); } catch (Exception e) { targetFile = null; } @@ -133,11 +106,7 @@ public class ProjectTargets { } } } - -/* public IConfiguration getConfiguration(){ - return configuraion; - } -*/ + protected String getString(Node target, String tagName) { Node node = searchNode(target, tagName); return node != null ? (node.getFirstChild() == null ? null : node.getFirstChild().getNodeValue()) : null; @@ -208,39 +177,111 @@ public class ProjectTargets { } public IProject getProject() { - return projDes.getProject(); + return project; } - protected void storeTargets(ICStorageElement element) throws CoreException { + protected Document getAsXML() throws CoreException { + Document doc; + try { + doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException ex) { + //This should never happen. + throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, + "Error creating new XML storage document", ex)); //$NON-NLS-1$ + } + Element targetsRootElement = doc.createElement(BUILD_TARGET_ELEMENT); + doc.appendChild(targetsRootElement); Iterator container = targetMap.entrySet().iterator(); while (container.hasNext()) { List targets = (List) ((Map.Entry) container.next()).getValue(); for (int i = 0; i < targets.size(); i++) { MakeTarget target = (MakeTarget) targets.get(i); - ICStorageElement child = element.createChild(TARGET_ELEMENT); - target.serialize(child); + targetsRootElement.appendChild(createTargetElement(doc, target)); } } + return doc; + } + + private Node createTargetElement(Document doc, MakeTarget target) { + Element targetElem = doc.createElement(TARGET_ELEMENT); + targetElem.setAttribute(TARGET_ATTR_NAME, target.getName()); + targetElem.setAttribute(TARGET_ATTR_ID, target.getTargetBuilderID()); + targetElem.setAttribute(TARGET_ATTR_PATH, target.getContainer().getProjectRelativePath().toString()); + Element elem = doc.createElement(TARGET_COMMAND); + targetElem.appendChild(elem); + elem.appendChild(doc.createTextNode(target.getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make"))); //$NON-NLS-1$ + + String targetAttr = target.getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, null); + if ( targetAttr != null) { + elem = doc.createElement(TARGET_ARGUMENTS); + elem.appendChild(doc.createTextNode(targetAttr)); + targetElem.appendChild(elem); + } + + targetAttr = target.getBuildAttribute(IMakeTarget.BUILD_TARGET, null); + if (targetAttr != null) { + elem = doc.createElement(TARGET); + elem.appendChild(doc.createTextNode(targetAttr)); + targetElem.appendChild(elem); + } + + elem = doc.createElement(TARGET_STOP_ON_ERROR); + elem.appendChild(doc.createTextNode(new Boolean(target.isStopOnError()).toString())); + targetElem.appendChild(elem); + + elem = doc.createElement(TARGET_USE_DEFAULT_CMD); + elem.appendChild(doc.createTextNode(new Boolean(target.isDefaultBuildCmd()).toString())); + targetElem.appendChild(elem); + return targetElem; } public void saveTargets() throws CoreException { - ICProjectDescription des = projDes.isReadOnly() ? - CoreModel.getDefault().getProjectDescription(projDes.getProject()) - : - projDes; - - ICStorageElement rootEl = getStorageElement(des, true); - rootEl.clear(); - ICStorageElement el = rootEl.createChild(BUILD_TARGET_ELEMENT); - storeTargets(el); - - CoreModel.getDefault().setProjectDescription(des.getProject(), des); + Document doc = getAsXML(); + //Historical method would save the output to the stream specified + //translateDocumentToOutputStream(doc, output); + translateDocumentToCDTProject(doc); } - private ICStorageElement getStorageElement(ICProjectDescription des, boolean create) throws CoreException{ -// return create || des.containsStorage(TARGETS_STORAGE_ID) ? -// des.getStorage(TARGETS_STORAGE_ID) : null; - return des.getStorage(TARGETS_STORAGE_ID, create); + protected void saveTargets(Document doc, OutputStream output) throws TransformerException { + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer; + transformer = factory.newTransformer(); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + + DOMSource source = new DOMSource(doc); + StreamResult outputTarget = new StreamResult(output); + transformer.transform(source, outputTarget); + } + /** + * This output method saves the information into the .cdtproject metadata file. + * + * @param doc + * @throws CoreException + */ + protected void translateDocumentToCDTProject(Document doc) throws CoreException { + ICDescriptor descriptor; + descriptor = CCorePlugin.getDefault().getCProjectDescription(getProject(), true); + + Element rootElement = descriptor.getProjectData(MAKE_TARGET_KEY); + + //Nuke the children since we are going to write out new ones + NodeList kids = rootElement.getChildNodes(); + for (int i = 0; i < kids.getLength(); i++) { + rootElement.removeChild(kids.item(i)); + i--; + } + + //Extract the root of our temporary document + Node node = doc.getFirstChild(); + if (node.hasChildNodes()) { + //Create a copy which is a part of the new document + Node appendNode = rootElement.getOwnerDocument().importNode(node, true); + //Put the copy into the document in the appropriate location + rootElement.appendChild(appendNode); + } + //Save the results + descriptor.saveProjectData(); } /** @@ -249,7 +290,7 @@ public class ProjectTargets { * @param input * @return */ -/* protected Document translateCDTProjectToDocument() { + protected Document translateCDTProjectToDocument() { Document document = null; Element rootElement = null; try { @@ -273,7 +314,7 @@ public class ProjectTargets { } return document; } -*/ + /** * This method parses the input stream for the XML document describing the build targets. * @@ -295,38 +336,55 @@ public class ProjectTargets { * * @param document */ - protected void extractMakeTargetsFromDocument(ICStorageElement el, MakeTargetManager manager, IConfiguration cfg) { -// Node node = document.getFirstChild(); -// if (node != null && node.getNodeName().equals(BUILD_TARGET_ELEMENT)) { - ICStorageElement list[] = el.getChildren(); - ICConfigurationDescription cfgDes = projDes.getActiveConfiguration(); -/* IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgDes); - if(cfg == null){ - ICConfigurationDescription dess[] = projDes.getConfigurations(); - for(int i = 0; i < dess.length; i++){ - cfg = ManagedBuildManager.getConfigurationForDescription(dess[i]); - if(cfg != null) - break; - } - } -*/ - if(cfg != null){ - for (int i = 0; i < list.length; i++) { - ICStorageElement node = list[i]; - if (node.getName().equals(TARGET_ELEMENT)) { - try { - MakeTarget target = new MakeTarget(manager, cfg, node); - add(target); - } catch (CoreException e) { - ManagedBuilderCorePlugin.log(e); + protected void extractMakeTargetsFromDocument(Document document, MakeTargetManager manager) { + Node node = document.getFirstChild(); + if (node != null && node.getNodeName().equals(BUILD_TARGET_ELEMENT)) { + NodeList list = node.getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + node = list.item(i); + if (node.getNodeName().equals(TARGET_ELEMENT)) { + IContainer container = null; + NamedNodeMap attr = node.getAttributes(); + String path = attr.getNamedItem(TARGET_ATTR_PATH).getNodeValue(); + if (path != null && !path.equals("")) { //$NON-NLS-1$ + container = project.getFolder(path); + } else { + container = project; + } + try { + MakeTarget target = new MakeTarget(manager, project, attr.getNamedItem(TARGET_ATTR_ID).getNodeValue(), + attr.getNamedItem(TARGET_ATTR_NAME).getNodeValue()); + target.setContainer(container); + String option = getString(node, TARGET_STOP_ON_ERROR); + if (option != null) { + target.setStopOnError(Boolean.valueOf(option).booleanValue()); + } + option = getString(node, TARGET_USE_DEFAULT_CMD); + if (option != null) { + target.setUseDefaultBuildCmd(Boolean.valueOf(option).booleanValue()); + } + option = getString(node, TARGET_COMMAND); + if (option != null) { + target.setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, option); } + option = getString(node, TARGET_ARGUMENTS); + if (option != null) { + target.setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, option); + } + option = getString(node, BAD_TARGET); + if (option != null) { + target.setBuildAttribute(IMakeTarget.BUILD_TARGET, option); + } + option = getString(node, TARGET); + if (option != null) { + target.setBuildAttribute(IMakeTarget.BUILD_TARGET, option); + } + add(target); + } catch (CoreException e) { + MakeCorePlugin.log(e); } } } -// } - } - - public ICProjectDescription getProjectDescription(){ - return projDes; + } } } 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) {} + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java new file mode 100644 index 00000000000..18b319ad1b3 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Properties; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CommandLauncher; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.cdt.internal.core.ConsoleOutputSniffer; +import org.eclipse.cdt.make.core.MakeBuilder; +import org.eclipse.cdt.make.core.MakeBuilderUtil; +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.InfoContext; +import org.eclipse.cdt.make.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.StreamMonitor; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * New default external scanner info provider of type 'run' + * + * @author vhirsl + */ +public class DefaultRunSIProvider implements IExternalScannerInfoProvider { + private static final String EXTERNAL_SI_PROVIDER_ERROR = "ExternalScannerInfoProvider.Provider_Error"; //$NON-NLS-1$ + private static final String EXTERNAL_SI_PROVIDER_CONSOLE_ID = MakeCorePlugin.getUniqueIdentifier() + ".ExternalScannerInfoProviderConsole"; //$NON-NLS-1$ + private static final String LANG_ENV_VAR = "LANG"; //$NON-NLS-1$ + + protected IResource resource; + protected String providerId; + protected IScannerConfigBuilderInfo2 buildInfo; + protected IScannerInfoCollector collector; + // To be initialized by a subclass + protected IPath fWorkingDirectory; + protected IPath fCompileCommand; + protected String[] fCompileArguments; + + private SCMarkerGenerator markerGenerator = new SCMarkerGenerator(); + + public boolean invokeProvider(IProgressMonitor monitor, IResource resource, + String providerId, IScannerConfigBuilderInfo2 buildInfo, + IScannerInfoCollector collector) { + return invokeProvider(monitor, resource, new InfoContext(resource.getProject()), providerId, buildInfo, collector, null); + } + + public boolean invokeProvider(IProgressMonitor monitor, + IResource resource, + InfoContext context, + String providerId, + IScannerConfigBuilderInfo2 buildInfo, + IScannerInfoCollector collector, + Properties env) { + // initialize fields + this.resource = resource; + this.providerId = providerId; + this.buildInfo = buildInfo; + this.collector = collector; + + IProject currentProject = resource.getProject(); + // call a subclass to initialize protected fields + if (!initialize()) { + return false; + } + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs"), 100); //$NON-NLS-1$ + + try { + IConsole console = CCorePlugin.getDefault().getConsole(EXTERNAL_SI_PROVIDER_CONSOLE_ID); + console.start(currentProject); + OutputStream cos = console.getOutputStream(); + + // Before launching give visual cues via the monitor + monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs")); //$NON-NLS-1$ + + String errMsg = null; + CommandLauncher launcher = new CommandLauncher(); + // Print the command for visual interaction. + launcher.showCommand(true); + + // add additional arguments + // subclass can change default behavior + String[] compileArguments = prepareArguments( + buildInfo.isUseDefaultProviderCommand(providerId)); + + String ca = coligate(compileArguments); + + monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Invoking_Command") //$NON-NLS-1$ + + fCompileCommand.toString() + ca); + cos = new StreamMonitor(new SubProgressMonitor(monitor, 70), cos, 100); + + ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer( + cos, cos, currentProject, context, providerId, buildInfo, collector, markerGenerator); + OutputStream consoleOut = (sniffer == null ? cos : sniffer.getOutputStream()); + OutputStream consoleErr = (sniffer == null ? cos : sniffer.getErrorStream()); + TraceUtil.outputTrace("Default provider is executing command:", fCompileCommand.toString() + ca, ""); //$NON-NLS-1$ //$NON-NLS-2$ + Process p = launcher.execute(fCompileCommand, compileArguments, setEnvironment(launcher, env), fWorkingDirectory); + if (p != null) { + try { + // Close the input of the Process explicitely. + // We will never write to it. + p.getOutputStream().close(); + } catch (IOException e) { + } + if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != CommandLauncher.OK) { + errMsg = launcher.getErrorMessage(); + } + monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Parsing_Output")); //$NON-NLS-1$ + } + else { + errMsg = launcher.getErrorMessage(); + } + + if (errMsg != null) { + String errorDesc = MakeMessages.getFormattedString(EXTERNAL_SI_PROVIDER_ERROR, + fCompileCommand.toString() + ca); + markerGenerator.addMarker(currentProject, -1, errorDesc, IMarkerGenerator.SEVERITY_WARNING, null); + } + + monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Creating_Markers")); //$NON-NLS-1$ + consoleOut.close(); + consoleErr.close(); + cos.close(); + } + catch (Exception e) { + CCorePlugin.log(e); + } + finally { + monitor.done(); + } + return true; + } + + + + /** + * Initialization of protected fields. + * Subclasses are most likely to override default implementation. + * + * @param currentProject + * @return boolean + */ + protected boolean initialize() { + + IProject currProject = resource.getProject(); + //fWorkingDirectory = resource.getProject().getLocation(); + fWorkingDirectory = MakeBuilderUtil.getBuildDirectory(currProject, MakeBuilder.BUILDER_ID); + fCompileCommand = new Path(buildInfo.getProviderRunCommand(providerId)); + fCompileArguments = ScannerConfigUtil.tokenizeStringWithQuotes(buildInfo.getProviderRunArguments(providerId), "\"");//$NON-NLS-1$ + return (fCompileCommand != null); + } + + /** + * Add additional arguments. For example: tso - target specific options + * Base class implementation returns compileArguments. + * Subclasses are most likely to override default implementation. + * + * @param isDefaultCommand + * @param collector + * @return + */ + protected String[] prepareArguments(boolean isDefaultCommand) { + return fCompileArguments; + } + + /** + * @param array + * @return + */ + private String coligate(String[] array) { + StringBuffer sb = new StringBuffer(128); + for (int i = 0; i < array.length; ++i) { + sb.append(' '); + sb.append(array[i]); + } + String ca = sb.toString(); + return ca; + } + + /** + * @param launcher + * @return + */ + protected String[] setEnvironment(CommandLauncher launcher, Properties initialEnv) { + // Set the environmennt, some scripts may need the CWD var to be set. + Properties props = initialEnv != null ? initialEnv : launcher.getEnvironment(); + props.put("CWD", fWorkingDirectory.toOSString()); //$NON-NLS-1$ + props.put("PWD", fWorkingDirectory.toOSString()); //$NON-NLS-1$ + // On POSIX (Linux, UNIX) systems reset LANG variable to English with UTF-8 encoding + // since GNU compilers can handle only UTF-8 characters. English language is chosen + // beacuse GNU compilers inconsistently handle different locales when generating + // output of the 'gcc -v' command. Include paths with locale characters will be + // handled properly regardless of the language as long as the encoding is set to UTF-8. + if (props.containsKey(LANG_ENV_VAR)) { + props.put(LANG_ENV_VAR, "en_US.UTF-8"); //$NON-NLS-1$ + } + String[] env = null; + ArrayList envList = new ArrayList(); + Enumeration names = props.propertyNames(); + if (names != null) { + while (names.hasMoreElements()) { + String key = (String) names.nextElement(); + envList.add(key + "=" + props.getProperty(key)); //$NON-NLS-1$ + } + env = (String[]) envList.toArray(new String[envList.size()]); + } + return env; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultSIFileReader.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultSIFileReader.java new file mode 100644 index 00000000000..068a03dac3e --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultSIFileReader.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.Properties; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.cdt.internal.core.ConsoleOutputSniffer; +import org.eclipse.cdt.make.core.MakeBuilder; +import org.eclipse.cdt.make.core.MakeBuilderUtil; +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.InfoContext; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory; +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; + +/** + * New default external scanner info provider of type 'open' + * + * @author vhirsl + */ +public class DefaultSIFileReader implements IExternalScannerInfoProvider { + private static final String EXTERNAL_SI_PROVIDER_CONSOLE_ID = MakeCorePlugin.getUniqueIdentifier() + ".ExternalScannerInfoProviderConsole"; //$NON-NLS-1$ + + private long fileSize = 0; + + private SCMarkerGenerator markerGenerator = new SCMarkerGenerator(); + + public boolean invokeProvider(IProgressMonitor monitor, IResource resource, + String providerId, IScannerConfigBuilderInfo2 buildInfo, + IScannerInfoCollector collector) { + return invokeProvider(monitor, resource, new InfoContext(resource.getProject()), providerId, buildInfo, collector, null); + } + + public boolean invokeProvider(IProgressMonitor monitor, + IResource resource, + InfoContext context, + String providerId, + IScannerConfigBuilderInfo2 buildInfo, + IScannerInfoCollector collector, + Properties env) { + boolean rc = false; + IProject project = resource.getProject(); + // input + BufferedReader reader = getStreamReader(buildInfo.getBuildOutputFilePath()); + if (reader == null) + return rc; + // output + IConsole console = CCorePlugin.getDefault().getConsole(EXTERNAL_SI_PROVIDER_CONSOLE_ID); + console.start(project); + OutputStream ostream; + try { + ostream = console.getOutputStream(); + } + catch (CoreException e) { + ostream = null; + } + + // get build location + IPath buildDirectory = MakeBuilderUtil.getBuildDirectory(project, MakeBuilder.BUILDER_ID); + + ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory. + getMakeBuilderOutputSniffer(ostream, null, project, context, buildDirectory, buildInfo, markerGenerator, collector); + if (sniffer != null) { + ostream = (sniffer == null ? null : sniffer.getOutputStream()); + } + + rc = readFileToOutputStream(monitor, reader, ostream); + + return rc; + } + + /** + * @param inputFileName + * @return + */ + private BufferedReader getStreamReader(String inputFileName) { + BufferedReader reader = null; + try { + fileSize = new File(inputFileName).length(); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFileName))); + } catch (FileNotFoundException e) { + MakeCorePlugin.log(e); + } + return reader; + } + + /** + * Precondition: Neither input nor output are null + * @param monitor + * @return + */ + private boolean readFileToOutputStream(IProgressMonitor monitor, BufferedReader reader, OutputStream ostream) { + final String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$ + monitor.beginTask("Reading build output ...", (int)((fileSize == 0) ? 10000 : fileSize)); //$NON-NLS-1$ + // check if build output file exists + String line; + try { + while ((line = reader.readLine()) != null) { + if (monitor.isCanceled()) { + return false; + } + + line += lineSeparator; + byte[] bytes = line.getBytes(); + ostream.write(bytes); + monitor.worked(bytes.length); + } + } catch (IOException e) { + MakeCorePlugin.log(e); + } finally { + try { + ostream.flush(); + } catch (IOException e) { + MakeCorePlugin.log(e); + } + try { + ostream.close(); + } catch (IOException e) { + MakeCorePlugin.log(e); + } + } + monitor.done(); + return true; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/GCCSpecsRunSIProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/GCCSpecsRunSIProvider.java new file mode 100644 index 00000000000..7b9a837fef2 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/GCCSpecsRunSIProvider.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.util.List; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerConfigUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +/** + * Runs a command to retrieve compiler intrinsic scanner info from 'specs' file. + * + * @author vhirsl + */ +public class GCCSpecsRunSIProvider extends DefaultRunSIProvider { + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.DefaultRunSIProvider#initialize() + */ + protected boolean initialize() { + boolean rc = super.initialize(); + + if (rc) { + String targetFile = "dummy"; //$NON-NLS-1$ + IProject project = resource.getProject(); + try { + if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { + targetFile = GCCScannerConfigUtil.CPP_SPECS_FILE; + } + else if (project.hasNature(CProjectNature.C_NATURE_ID)) { + targetFile = GCCScannerConfigUtil.C_SPECS_FILE; + } + // replace string variables in compile arguments + // TODO Vmir - use string variable replacement + for (int i = 0; i < fCompileArguments.length; ++i) { + fCompileArguments[i] = fCompileArguments[i].replaceAll("\\$\\{plugin_state_location\\}", //$NON-NLS-1$ + MakeCorePlugin.getWorkingDirectory().toString()); + fCompileArguments[i] = fCompileArguments[i].replaceAll("\\$\\{specs_file\\}", targetFile); //$NON-NLS-1$ + } + } catch (CoreException e) { + //TODO VMIR better error handling + MakeCorePlugin.log(e.getStatus()); + rc = false; + } + } + return rc; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.DefaultRunSIProvider#prepareArguments(boolean) + */ + protected String[] prepareArguments(boolean isDefaultCommand) { + List tso = collector.getCollectedScannerInfo(resource.getProject(), ScannerInfoTypes.TARGET_SPECIFIC_OPTION); + if (tso == null || tso.size() == 0) { + return fCompileArguments; + } + + String[] rv = null; + // commandArguments may have multiple arguments; tokenizing + int nTokens = 0; + if (fCompileArguments != null && fCompileArguments.length > 0) { + nTokens = fCompileArguments.length; + rv = new String[nTokens + tso.size()]; + System.arraycopy(fCompileArguments, 0, rv, 0, nTokens); + } + else { + rv = new String[tso.size()]; + } + for (int i = 0; i < tso.size(); ++i) { + rv[nTokens + i] = (String) tso.get(i); + } + return rv; + } + +} 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 new file mode 100644 index 00000000000..db952383cc6 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java @@ -0,0 +1,821 @@ +/******************************************************************************* + * 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 + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +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; +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 java.util.Map.Entry; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector3; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner; +import org.eclipse.cdt.make.core.scannerconfig.InfoContext; +import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredScannerInfoSerializable; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo; +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.ScannerConfigUtil; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator; +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.eclipse.core.runtime.Path; +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 IScannerInfoCollector3, IScannerInfoCollectorCleaner { + private static final int INCLUDE_PATH = 1; + private static final int QUOTE_INCLUDE_PATH = 2; + private static final int INCLUDE_FILE = 3; + private static final int MACROS_FILE = 4; + + public class ScannerInfoData implements IDiscoveredScannerInfoSerializable { + 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 + + public ScannerInfoData() { + commandIdCommandMap = new LinkedHashMap(); // [commandId, command] + fileToCommandIdMap = new HashMap(); // [file, commandId] + commandIdToFilesMap = new HashMap(); // [commandId, set of files] + } + + /* (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); + collectorElem.appendChild(cmdElem); + cmdElem.setAttribute(ID_ATTR, commandId.toString()); + cmdElem.setAttribute(FILE_TYPE_ATTR, command.appliesToCPPFileType() ? "c++" : "c"); //$NON-NLS-1$ //$NON-NLS-2$ + // write command and scanner info + command.serialize(cmdElem); + // write files command applies to + Element filesElem = doc.createElement(APPLIES_TO_ATTR); + 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); + IFile file = (IFile) j.next(); + IPath path = file.getProjectRelativePath(); + fileElem.setAttribute(PATH_ATTR, path.toString()); + 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)) { + Element cmdElem = (Element) child; + boolean cppFileType = cmdElem.getAttribute(FILE_TYPE_ATTR).equals("c++"); //$NON-NLS-1$ + 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); + } + applyFileDeltas(); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#getCollectorId() + */ + public String getCollectorId() { + return COLLECTOR_ID; + } + + } + + private static class ProjectScannerInfo { + IPath[] includePaths; + IPath[] quoteIncludePaths; + IPath[] includeFiles; + IPath[] macrosFiles; + Map definedSymbols; + public boolean isEmpty() { + return (includePaths.length == 0 && + quoteIncludePaths.length == 0 && + includeFiles.length == 0 && + macrosFiles.length == 0 && + definedSymbols.size() == 0); + } + } + + 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$ + + IProject project; + InfoContext context; + + private ScannerInfoData sid; // scanner info data + private ProjectScannerInfo psi = null; // sum of all scanner info + +// private List siChangedForFileList; // list of files for which scanner info has changed + private Map siChangedForFileMap; // (file, comandId) map for deltas + private List siChangedForCommandIdList; // list of command ids for which scanner info has changed + + private SortedSet freeCommandIdPool; // sorted set of free command ids + private int commandIdCounter = 0; + + /** + * + */ + public PerFileSICollector() { + sid = new ScannerInfoData(); + +// siChangedForFileList = new ArrayList(); + siChangedForFileMap = new HashMap(); + siChangedForCommandIdList = new ArrayList(); + + freeCommandIdPool = new TreeSet(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#setProject(org.eclipse.core.resources.IProject) + */ + public void setProject(IProject project) { + setInfoContext(new InfoContext(project)); + } + + public void setInfoContext(InfoContext context) { + this.project = context.getProject(); + this.context = context; + + try { + // deserialize from SI store + DiscoveredScannerInfoStore.getInstance().loadDiscoveredScannerInfoFromState(project, context, sid); + } + catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#contributeToScannerConfig(java.lang.Object, java.util.Map) + */ + public synchronized void contributeToScannerConfig(Object resource, Map scannerInfo) { + // check the resource + String errorMessage = null; + if (resource == null) { + errorMessage = "resource is null";//$NON-NLS-1$ + } + else if (resource instanceof Integer) { + addScannerInfo(((Integer)resource), scannerInfo); + return; + } + else if (!(resource instanceof IFile)) { + errorMessage = "resource is not an IFile";//$NON-NLS-1$ + } + else if (((IFile) resource).getProject() == null) { + errorMessage = "project is null";//$NON-NLS-1$ + } + else if (((IFile) resource).getProject() != project) { + errorMessage = "wrong project";//$NON-NLS-1$ + } + if (errorMessage != null) { + TraceUtil.outputError("PerFileSICollector.contributeToScannerConfig : ", errorMessage); //$NON-NLS-1$ + return; + } + IFile file = (IFile) resource; + + for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext(); ) { + ScannerInfoTypes type = (ScannerInfoTypes) i.next(); + if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { + 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)); + } + } + } + + /** + * @param commandId + * @param scannerInfo + */ + private void addScannerInfo(Integer commandId, Map scannerInfo) { + CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(commandId); + if (cmd != null) { + List siItem = (List) scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS); + cmd.setSymbols(siItem); + siItem = (List) scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS); + cmd.setIncludes(CygpathTranslator.translateIncludePaths(project, siItem)); + siItem = (List) scannerInfo.get(ScannerInfoTypes.QUOTE_INCLUDE_PATHS); + cmd.setQuoteIncludes(siItem); + + cmd.setDiscovered(true); + } + } + + /** + * @param file + * @param object + */ + void addCompilerCommand(IFile file, CCommandDSC cmd) { + List existingCommands = new ArrayList(sid.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); + sid.commandIdCommandMap.put(cmd.getCommandIdAsInteger(), cmd); + } + + generateFileDelta(file, cmd); + } + + /** + * @param file + * @param cmd + */ + private void generateFileDelta(IFile file, CCommandDSC cmd) { + Integer commandId = cmd.getCommandIdAsInteger(); + Integer oldCommandId = (Integer) sid.fileToCommandIdMap.get(file); + + if (oldCommandId != null && oldCommandId.equals(commandId)) { + // already exists; remove form delta + siChangedForFileMap.remove(file); + } + else { + // new (file, commandId) pair + siChangedForFileMap.put(file, commandId); + } + } + + /** + * @param file + * @param cmd + */ + void applyFileDeltas() { + for (Iterator i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) { + IFile file = (IFile) i.next(); + Integer commandId = (Integer) siChangedForFileMap.get(file); + if (commandId != null) { + + // update sid.commandIdToFilesMap + Set fileSet = (Set) sid.commandIdToFilesMap.get(commandId); + if (fileSet == null) { + fileSet = new HashSet(); + sid.commandIdToFilesMap.put(commandId, fileSet); + } + if (fileSet.add(file)) { + // update fileToCommandIdsMap + boolean change = true; + Integer oldCommandId = (Integer) sid.fileToCommandIdMap.get(file); + if (oldCommandId != null) { + if (oldCommandId.equals(commandId)) { + change = false; + } + else { + Set oldFileSet = (Set) sid.commandIdToFilesMap.get(oldCommandId); + oldFileSet.remove(file); + } + } + if (change) { + sid.fileToCommandIdMap.put(file, commandId); + // TODO generate change event for this resource +// IPath path = file.getFullPath(); +// if (!siChangedForFileList.contains(path)) { +// siChangedForFileList.add(path); +// } + } + } + } + } + generateProjectScannerInfo(); + } + + private void generateProjectScannerInfo() { + psi = new ProjectScannerInfo(); + psi.includePaths = getAllIncludePaths(INCLUDE_PATH); + psi.quoteIncludePaths = getAllIncludePaths(QUOTE_INCLUDE_PATH); + psi.includeFiles = getAllIncludePaths(INCLUDE_FILE); + psi.macrosFiles = getAllIncludePaths(MACROS_FILE); + psi.definedSymbols = getAllSymbols(); + } + + private void removeUnusedCommands() { + for (Iterator i = sid.commandIdToFilesMap.entrySet().iterator(); i.hasNext(); ) { + Entry entry = (Entry) i.next(); + Integer cmdId = (Integer) entry.getKey(); + Set fileSet = (Set) entry.getValue(); + if (fileSet.isEmpty()) { + // return cmdId to the free command id pool + freeCommandIdPool.add(cmdId); + } + } + for (Iterator i = freeCommandIdPool.iterator(); i.hasNext(); ) { + Integer cmdId = (Integer) i.next(); + // the command does not have any files associated; remove + sid.commandIdCommandMap.remove(cmdId); + sid.commandIdToFilesMap.remove(cmdId); + } + while (!freeCommandIdPool.isEmpty()) { + Integer last = (Integer) freeCommandIdPool.last(); + if (last.intValue() == commandIdCounter) { + freeCommandIdPool.remove(last); + --commandIdCounter; + } + else break; + } + } + + /** + * @param type + * @param object + */ + private void addScannerInfo(ScannerInfoTypes type, List delta) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#updateScannerConfiguration(org.eclipse.core.runtime.IProgressMonitor) + */ + public void updateScannerConfiguration(IProgressMonitor monitor) throws CoreException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(MakeMessages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$ +// removeUnusedCommands(); + monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$ + if (scannerInfoChanged()) { + applyFileDeltas(); + removeUnusedCommands(); + monitor.worked(50); + monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + project.getName()); //$NON-NLS-1$ + try { + // update scanner configuration +// MakeCorePlugin.getDefault().getDiscoveryManager(). +// updateDiscoveredInfo(createPathInfoObject(), siChangedForFileList); + IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project, context); + if (!(pathInfo instanceof IPerFileDiscoveredPathInfo)) { + pathInfo = createPathInfoObject(); + } + MakeCorePlugin.getDefault().getDiscoveryManager(). + updateDiscoveredInfo(context, pathInfo, context.isDefaultContext(), new ArrayList(siChangedForFileMap.keySet())); + monitor.worked(50); + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + } +// siChangedForFileList.clear(); + siChangedForFileMap.clear(); + siChangedForCommandIdList.clear(); + + monitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#createPathInfoObject() + */ + public IDiscoveredPathInfo createPathInfoObject() { + return new PerFileDiscoveredPathInfo(); + } + + private boolean scannerInfoChanged() { +// return !siChangedForFileList.isEmpty(); + return !siChangedForFileMap.isEmpty(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#getCollectedScannerInfo(java.lang.Object, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes) + */ + public List getCollectedScannerInfo(Object resource, ScannerInfoTypes type) { + List rv = new ArrayList(); + // check the resource + String errorMessage = null; + if (resource == null) { + errorMessage = "resource is null";//$NON-NLS-1$ + } + else if (!(resource instanceof IResource)) { + errorMessage = "resource is not an IResource";//$NON-NLS-1$ + } + else if (((IResource) resource).getProject() == null) { + errorMessage = "project is null";//$NON-NLS-1$ + } + else if (((IResource) resource).getProject() != project) { + errorMessage = "wrong project";//$NON-NLS-1$ + } + + if (errorMessage != null) { + TraceUtil.outputError("PerProjectSICollector.getCollectedScannerInfo : ", errorMessage); //$NON-NLS-1$ + } + else if (project.equals(((IResource)resource).getProject())) { + if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { + for (Iterator i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) { + Integer cmdId = (Integer) i.next(); + Set fileSet = (Set) sid.commandIdToFilesMap.get(cmdId); + if (!fileSet.isEmpty()) { + rv.add(sid.commandIdCommandMap.get(cmdId)); + } + } + } + else if (type.equals(ScannerInfoTypes.UNDISCOVERED_COMPILER_COMMAND)) { +// if (!siChangedForFileList.isEmpty()) { + if (scannerInfoChanged()) { + if (siChangedForCommandIdList.isEmpty()) { +// for (Iterator i = siChangedForFileList.iterator(); i.hasNext(); ) { + for (Iterator i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) { +// IPath path = (IPath) i.next(); + IFile file = (IFile) i.next(); + Integer cmdId = (Integer) siChangedForFileMap.get(file); + if (cmdId != null) { + if (!siChangedForCommandIdList.contains(cmdId)) { + siChangedForCommandIdList.add(cmdId); + } + } + } + } + Collections.sort(siChangedForCommandIdList); + for (Iterator i = siChangedForCommandIdList.iterator(); i.hasNext(); ) { + Integer cmdId = (Integer) i.next(); + CCommandDSC command = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); + rv.add(command); + } + } + } + } + return rv; + } + + /* (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 + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner#deleteAll(org.eclipse.core.resources.IResource) + */ + public void deleteAll(IResource resource) { + if (resource.equals(project)) { +// siChangedForFileList = new ArrayList(); + siChangedForFileMap.clear(); + Set changedFiles = sid.fileToCommandIdMap.keySet(); + for (Iterator i = changedFiles.iterator(); i.hasNext(); ) { + IFile file = (IFile) i.next(); +// IPath path = file.getFullPath(); +// siChangedForFileList.add(path); + siChangedForFileMap.put(file, null); + } + + sid = new ScannerInfoData(); + psi = null; + + commandIdCounter = 0; + freeCommandIdPool.clear(); + } + } + + /** + * Per file DPI object + * + * @author vhirsl + */ + public class PerFileDiscoveredPathInfo implements IPerFileDiscoveredPathInfo { + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getProject() + */ + public IProject getProject() { + return project; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths() + */ + public IPath[] getIncludePaths() { +// return new IPath[0]; + return getAllIncludePaths(INCLUDE_PATH); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols() + */ + public Map getSymbols() { +// return new HashMap(); + return getAllSymbols(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths(org.eclipse.core.runtime.IPath) + */ + public IPath[] getIncludePaths(IPath path) { + // get the command + CCommandDSC cmd = getCommand(path); + if (cmd != null && cmd.isDiscovered()) { + return stringListToPathArray(cmd.getIncludes()); + } + // use project scope scanner info + if (psi == null) { + generateProjectScannerInfo(); + } + return psi.includePaths; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getQuoteIncludePaths(org.eclipse.core.runtime.IPath) + */ + public IPath[] getQuoteIncludePaths(IPath path) { + // get the command + CCommandDSC cmd = getCommand(path); + if (cmd != null && cmd.isDiscovered()) { + return stringListToPathArray(cmd.getQuoteIncludes()); + } + // use project scope scanner info + if (psi == null) { + generateProjectScannerInfo(); + } + return psi.quoteIncludePaths; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols(org.eclipse.core.runtime.IPath) + */ + public Map getSymbols(IPath path) { + // get the command + CCommandDSC cmd = getCommand(path); + if (cmd != null && cmd.isDiscovered()) { + List symbols = cmd.getSymbols(); + Map definedSymbols = new HashMap(symbols.size()); + for (Iterator i = symbols.iterator(); i.hasNext(); ) { + String symbol = (String) i.next(); + String key = ScannerConfigUtil.getSymbolKey(symbol); + String value = ScannerConfigUtil.getSymbolValue(symbol); + definedSymbols.put(key, value); + } + return definedSymbols; + } + // use project scope scanner info + if (psi == null) { + generateProjectScannerInfo(); + } + return psi.definedSymbols; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludeFiles(org.eclipse.core.runtime.IPath) + */ + public IPath[] getIncludeFiles(IPath path) { + // get the command + CCommandDSC cmd = getCommand(path); + if (cmd != null) { + return stringListToPathArray(cmd.getIncludeFile()); + } + // use project scope scanner info + if (psi == null) { + generateProjectScannerInfo(); + } + return psi.includeFiles; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getMacroFiles(org.eclipse.core.runtime.IPath) + */ + public IPath[] getMacroFiles(IPath path) { + // get the command + CCommandDSC cmd = getCommand(path); + if (cmd != null) { + return stringListToPathArray(cmd.getImacrosFile()); + } + // use project scope scanner info + if (psi == null) { + generateProjectScannerInfo(); + } + return psi.macrosFiles; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getSerializable() + */ + public IDiscoveredScannerInfoSerializable getSerializable() { + return sid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#isEmpty(org.eclipse.core.runtime.IPath) + */ + public boolean isEmpty(IPath path) { + boolean rc = true; + IResource resource = project.getWorkspace().getRoot().findMember(path); + if (resource != null) { + if (resource instanceof IFile) { + rc = (getCommand((IFile)resource) == null); + } + else if (resource instanceof IProject) { + rc = (psi == null || psi.isEmpty()); + } + } + return rc; + } + + } + + /** + * @param path + * @return + */ + private CCommandDSC getCommand(IPath path) { + try { + IFile file = project.getWorkspace().getRoot().getFile(path); + return getCommand(file); + } + catch (Exception e) { + return null; + } + } + + private CCommandDSC getCommand(IFile file) { + CCommandDSC cmd = null; + if (file != null) { + Integer cmdId = (Integer) sid.fileToCommandIdMap.get(file); + if (cmdId != null) { + // get the command + cmd = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); + } + } + return cmd; + } + + /** + * @param type can be one of the following: + * <li><code>INCLUDE_PATH</code> + * <li><code>QUOTE_INCLUDE_PATH</code> + * <li><code>INCLUDE_FILE</code> + * <li><code>MACROS_FILE</code> + * + * @return list of IPath(s). + */ + private IPath[] getAllIncludePaths(int type) { + List allIncludes = new ArrayList(); + for (Iterator i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) { + Integer cmdId = (Integer) i.next(); + CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); + if (cmd.isDiscovered()) { + List discovered = null; + switch (type) { + case INCLUDE_PATH: + discovered = cmd.getIncludes(); + break; + case QUOTE_INCLUDE_PATH: + discovered = cmd.getQuoteIncludes(); + break; + case INCLUDE_FILE: + discovered = cmd.getIncludeFile(); + break; + case MACROS_FILE: + discovered = cmd.getImacrosFile(); + break; + } + for (Iterator j = discovered.iterator(); j.hasNext(); ) { + String include = (String) j.next(); + if (!allIncludes.contains(include)) { + allIncludes.add(include); + } + } + } + } + return stringListToPathArray(allIncludes); + } + + /** + * @param discovered + * @param allIncludes + * @return + */ + private IPath[] stringListToPathArray(List discovered) { + List allIncludes = new ArrayList(discovered.size()); + for (Iterator j = discovered.iterator(); j.hasNext(); ) { + String include = (String) j.next(); + if (!allIncludes.contains(include)) { + allIncludes.add(new Path(include)); + } + } + return (IPath[])allIncludes.toArray(new IPath[allIncludes.size()]); + } + + /** + * @return + */ + private Map getAllSymbols() { + Map symbols = new HashMap(); + for (Iterator i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) { + Integer cmdId = (Integer) i.next(); + CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); + if (cmd.isDiscovered()) { + List discovered = cmd.getSymbols(); + for (Iterator j = discovered.iterator(); j.hasNext(); ) { + String symbol = (String) j.next(); + String key = ScannerConfigUtil.getSymbolKey(symbol); + String value = ScannerConfigUtil.getSymbolValue(symbol); + symbols.put(key, value); + } + } + } + return symbols; + } + +} 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 new file mode 100644 index 00000000000..3ee43cf7cc7 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerProjectSICollector.java @@ -0,0 +1,533 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IPathEntry; +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.IScannerInfoCollector3; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner; +import org.eclipse.cdt.make.core.scannerconfig.InfoContext; +import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo; +import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerProjectDiscoveredPathInfo; +import org.eclipse.cdt.make.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathInfo; +import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.w3c.dom.Element; + +/** + * New per project scanner info collector + * + * @since 3.0 + * @author vhirsl + */ +public class PerProjectSICollector implements IScannerInfoCollector3, IScannerInfoCollectorCleaner { + public static final String COLLECTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".PerProjectSICollector"; //$NON-NLS-1$ + + private IProject project; + private InfoContext context; + + private Map discoveredSI; +// private List discoveredIncludes; +// private List discoveredSymbols; +// private List discoveredTSO; // target specific options + // cumulative values + private List sumDiscoveredIncludes; + private Map sumDiscoveredSymbols; + private boolean scPersisted = false; + + public PerProjectSICollector() { + discoveredSI = new HashMap(); +// discoveredIncludes = new ArrayList(); +// discoveredSymbols = new ArrayList(); +// discoveredTSO = new ArrayList(); +// + sumDiscoveredIncludes = new ArrayList(); + sumDiscoveredSymbols = new LinkedHashMap(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#setProject(org.eclipse.core.resources.IProject) + */ + public void setProject(IProject project) { + this.project = project; + this.context = new InfoContext(project); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#contributeToScannerConfig(java.lang.Object, java.util.Map) + */ + public synchronized void contributeToScannerConfig(Object resource, Map scannerInfo) { + // check the resource + String errorMessage = null; + if (resource == null) { + errorMessage = "resource is null";//$NON-NLS-1$ + } + else if (!(resource instanceof IResource)) { + errorMessage = "resource is not an IResource";//$NON-NLS-1$ + } + else if (((IResource) resource).getProject() == null) { + errorMessage = "project is null";//$NON-NLS-1$ + } + else if (((IResource) resource).getProject() != project) { + errorMessage = "wrong project";//$NON-NLS-1$ + } + if (errorMessage != null) { + TraceUtil.outputError("PerProjectSICollector.contributeToScannerConfig : ", errorMessage); //$NON-NLS-1$ + return; + } + + if (scPersisted) { + // delete discovered scanner config + discoveredSI.clear(); + // new collection cycle + scPersisted = false; + } + try { + if (/*project.hasNature(MakeProjectNature.NATURE_ID) && */// limits to StandardMake projects + (project.hasNature(CProjectNature.C_NATURE_ID) || + project.hasNature(CCProjectNature.CC_NATURE_ID))) { + + for (Iterator I = scannerInfo.keySet().iterator(); I.hasNext(); ) { + ScannerInfoTypes siType = (ScannerInfoTypes) I.next(); + List delta = (List) scannerInfo.get(siType); + + List discovered = (List) discoveredSI.get(siType); + if (discovered == null) { + discovered = new ArrayList(delta); + discoveredSI.put(siType, discovered); + } + else { + if (siType.equals(ScannerInfoTypes.INCLUDE_PATHS)) { + contribute(discovered, delta, true); + } + else { + contribute(discovered, delta, false); + } + } + } + } + } + catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + + /** + * @param discovered symbols | includes | targetSpecificOptions + * @param delta symbols | includes | targetSpecificOptions + * @param ordered - to preserve order or append at the end + * @return true if there is a change in discovered symbols | includes | targetSpecificOptions + */ + private boolean contribute(List discovered, List delta, boolean ordered) { + if (delta == null || delta.isEmpty()) + return false; + return addItemsWithOrder(discovered, delta, ordered); + } + + /** + * Adds new items to the already accumulated ones preserving order + * + * @param sumIncludes - previously accumulated items + * @param includes - items to be added + * @param ordered - to preserve order or append at the end + * @return boolean - true if added + */ + private boolean addItemsWithOrder(List sumIncludes, List includes, boolean ordered) { + boolean addedIncludes = false; + int prev = sumIncludes.size() - 1; // index of previously added/found contribution in already discovered list + for (Iterator i = includes.iterator(); i.hasNext(); ) { + String item = (String) i.next(); + if (!sumIncludes.contains(item)) { + sumIncludes.add(prev + 1, item); + addedIncludes = true; + } + prev = ordered ? sumIncludes.indexOf(item) : sumIncludes.size() - 1; + } + return addedIncludes; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#updateScannerConfiguration(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IProgressMonitor) + */ + public synchronized void updateScannerConfiguration(IProgressMonitor monitor) throws CoreException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project, context); + if (pathInfo instanceof IPerProjectDiscoveredPathInfo) { + IPerProjectDiscoveredPathInfo projectPathInfo = (IPerProjectDiscoveredPathInfo) pathInfo; + + monitor.beginTask(MakeMessages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$ + if (pathInfo != null) { + monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$ + if (scannerConfigNeedsUpdate(projectPathInfo)) { + monitor.worked(50); + monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + project.getName()); //$NON-NLS-1$ + try { + // update scanner configuration + List resourceDelta = new ArrayList(1); + resourceDelta.add(project); + MakeCorePlugin.getDefault().getDiscoveryManager().updateDiscoveredInfo(context, pathInfo, context.isDefaultContext(), resourceDelta); + monitor.worked(50); + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + } + monitor.done(); + scPersisted = true; + } + } + + /** + * Compare discovered include paths and symbol definitions with the ones from scanInfo. + * + * @param scanInfo + * @return + */ + private boolean scannerConfigNeedsUpdate(IPerProjectDiscoveredPathInfo discPathInfo) { + boolean addedIncludes = includePathsNeedUpdate(discPathInfo); + boolean addedSymbols = definedSymbolsNeedUpdate(discPathInfo); + + return (addedIncludes | addedSymbols); + } + + /** + * Compare include paths with already discovered. + * + * @param discPathInfo + * @param includes + * @return + */ + private boolean includePathsNeedUpdate(IPerProjectDiscoveredPathInfo discPathInfo) { + boolean addedIncludes = false; + List discoveredIncludes = (List) discoveredSI.get(ScannerInfoTypes.INCLUDE_PATHS); + if (discoveredIncludes != null) { + // Step 1. Add discovered scanner config to the existing discovered scanner config + // add the includes from the latest discovery +// if (sumDiscoveredIncludes == null) { +// sumDiscoveredIncludes = new ArrayList(discoveredIncludes); +// addedIncludes = true; +// } +// else { +// addedIncludes = addItemsWithOrder(sumDiscoveredIncludes, discoveredIncludes, true); +// } +// instead + addedIncludes = addItemsWithOrder(sumDiscoveredIncludes, discoveredIncludes, true); + + // try to translate cygpaths to absolute paths + List finalSumIncludes = CygpathTranslator.translateIncludePaths(project, sumDiscoveredIncludes); + + // Step 2. Get project's scanner config + LinkedHashMap persistedIncludes = discPathInfo.getIncludeMap(); + + // Step 3. Merge scanner config from steps 1 and 2 + // order is important, use list to preserve it + ArrayList persistedKeyList = new ArrayList(persistedIncludes.keySet()); + addedIncludes = addItemsWithOrder(persistedKeyList, finalSumIncludes, true); + + LinkedHashMap newPersistedIncludes; + if (addedIncludes) { + newPersistedIncludes = new LinkedHashMap(persistedKeyList.size()); + for (Iterator i = persistedKeyList.iterator(); i.hasNext(); ) { + String include = (String) i.next(); + if (persistedIncludes.containsKey(include)) { + newPersistedIncludes.put(include, persistedIncludes.get(include)); + } + else { + newPersistedIncludes.put(include, + ((new Path(include)).toFile().exists()) ? Boolean.FALSE : Boolean.TRUE); + } + } + } + else { + newPersistedIncludes = persistedIncludes; + } + + // Step 4. Set resulting scanner config + discPathInfo.setIncludeMap(newPersistedIncludes); + } + return addedIncludes; + } + + /* + * translated to raw map + */ + private Map translateDiscoveredIncludes(List list){ + int baseSize = list.size(); + LinkedHashMap map = new LinkedHashMap(baseSize); + List translated = CygpathTranslator.translateIncludePaths(project, list); + if(baseSize == translated.size()){ + for(int i = 0; i < baseSize; i++){ + map.put(translated.get(i), list.get(i)); + } + } else { + List tmpList = new ArrayList(1); + for(int i = 0; i < baseSize; i++){ + String basePath = (String)list.get(i); + tmpList.add(0, basePath); + List tr = CygpathTranslator.translateIncludePaths(project, tmpList); + if(tr.size() != 0){ + String translatedPath = (String)tr.get(0); + map.put(translatedPath, basePath); + } + } + } + return map; + } + + /** + * Compare symbol definitions with already discovered. + * + * @param discPathInfo + * @param symbols + * @return + */ + private boolean definedSymbolsNeedUpdate(IPerProjectDiscoveredPathInfo discPathInfo) { + boolean addedSymbols = false; + List discoveredSymbols = (List) discoveredSI.get(ScannerInfoTypes.SYMBOL_DEFINITIONS); + if (discoveredSymbols != null) { + // Step 1. Add discovered scanner config to the existing discovered scanner config + // add the symbols from the latest discovery +// if (sumDiscoveredSymbols == null) { +// sumDiscoveredSymbols = new LinkedHashMap(); +// } + addedSymbols = ScannerConfigUtil.scAddSymbolsList2SymbolEntryMap(sumDiscoveredSymbols, discoveredSymbols, false); + + // Step 2. Get project's scanner config + LinkedHashMap persistedSymbols = discPathInfo.getSymbolMap(); + + // Step 3. Merge scanner config from steps 1 and 2 + LinkedHashMap candidateSymbols = new LinkedHashMap(persistedSymbols); + addedSymbols |= ScannerConfigUtil.scAddSymbolEntryMap2SymbolEntryMap(candidateSymbols, sumDiscoveredSymbols); + + // Step 4. Set resulting scanner config + discPathInfo.setSymbolMap(candidateSymbols); + } + return addedSymbols; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#getCollectedScannerInfo(java.lang.Object, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes) + */ + public List getCollectedScannerInfo(Object resource, ScannerInfoTypes type) { + List rv = null; + // check the resource + String errorMessage = null; + if (resource == null) { + errorMessage = "resource is null";//$NON-NLS-1$ + } + else if (!(resource instanceof IResource)) { + errorMessage = "resource is not an IResource";//$NON-NLS-1$ + } + else if (((IResource) resource).getProject() == null) { + errorMessage = "project is null";//$NON-NLS-1$ + } + else if (((IResource) resource).getProject() != project) { + errorMessage = "wrong project";//$NON-NLS-1$ + } + + if (errorMessage != null) { + TraceUtil.outputError("PerProjectSICollector.getCollectedScannerInfo : ", errorMessage); //$NON-NLS-1$ + } + else if (project.equals(((IResource)resource).getProject())) { + rv = (List) discoveredSI.get(type); + } + return rv; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#getDefinedSymbols() + */ + public Map getDefinedSymbols() { + Map definedSymbols = ScannerConfigUtil.scSymbolEntryMap2Map(sumDiscoveredSymbols); + return definedSymbols; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#getIncludePaths() + */ + public List getIncludePaths() { + 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) + */ + public void deleteAllPaths(IResource resource) { + IProject project = resource.getProject(); + if (project != null && project.equals(this.project)) { + sumDiscoveredIncludes.clear(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorUtil#deleteAllSymbols(org.eclipse.core.resources.IResource) + */ + public void deleteAllSymbols(IResource resource) { + IProject project = resource.getProject(); + if (project != null && project.equals(this.project)) { + sumDiscoveredSymbols.clear(); + } + } + + /* (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) { + IProject project = resource.getProject(); + if (project != null && project.equals(this.project)) { + sumDiscoveredIncludes.remove(path); + } + } + + /* (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) { + IProject project = resource.getProject(); + if (project != null && project.equals(this.project)) { + // remove it from the Map of SymbolEntries + ScannerConfigUtil.removeSymbolEntryValue(symbol, sumDiscoveredSymbols); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner#deleteAll(org.eclipse.core.resources.IResource) + */ + public void deleteAll(IResource resource) { + deleteAllPaths(resource); + deleteAllSymbols(resource); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#createPathInfoObject() + */ + public IDiscoveredPathInfo createPathInfoObject() { + DiscoveredPathInfo pathInfo = new DiscoveredPathInfo(project); + try { + DiscoveredScannerInfoStore.getInstance().loadDiscoveredScannerInfoFromState(project, context, pathInfo); + } + catch (CoreException e) { + MakeCorePlugin.log(e); + } + return pathInfo; + } + + /** + * Static method to return compiler built-in scanner info. + * Preconditions: resource has to be contained by a project that has following natures: + * C nature, CC nature (for C++ projects), Make nature and ScannerConfig nature + * + * @param project + * @throws CModelException + */ + public static void calculateCompilerBuiltins(final IProject project) throws CModelException { + createDiscoveredPathContainer(project, new NullProgressMonitor()); + String scdProfileId = ScannerConfigProfileManager.PER_PROJECT_PROFILE_ID; + SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance(). + getSCProfileInstance(project, scdProfileId); + final IScannerConfigBuilderInfo2 buildInfo = ScannerConfigProfileManager. + createScannerConfigBuildInfo2(MakeCorePlugin.getDefault().getPluginPreferences(), + scdProfileId, true); + final IScannerInfoCollector collector = profileInstance.getScannerInfoCollector(); + if (collector instanceof IScannerInfoCollectorCleaner) { + ((IScannerInfoCollectorCleaner) collector).deleteAll(project); + } + final IExternalScannerInfoProvider esiProvider = profileInstance.createExternalScannerInfoProvider("specsFile");//$NON-NLS-1$ + + // Set the arguments for the provider + + ISafeRunnable runnable = new ISafeRunnable() { + public void run() throws CoreException { + IProgressMonitor monitor = new NullProgressMonitor(); + esiProvider.invokeProvider(monitor, project, "specsFile", buildInfo, collector);//$NON-NLS-1$ + if (collector instanceof IScannerInfoCollector2) { + IScannerInfoCollector2 collector2 = (IScannerInfoCollector2) collector; + collector2.updateScannerConfiguration(monitor); + } + } + + public void handleException(Throwable exception) { + if (exception instanceof OperationCanceledException) { + throw (OperationCanceledException) exception; + } + } + }; + Platform.run(runnable); + } + + private static void createDiscoveredPathContainer(IProject project, IProgressMonitor monitor) throws CModelException { + IPathEntry container = CoreModel.newContainerEntry(DiscoveredPathContainer.CONTAINER_ID); + ICProject cProject = CoreModel.getDefault().create(project); + if (cProject != null) { + IPathEntry[] entries = cProject.getRawPathEntries(); + List newEntries = new ArrayList(Arrays.asList(entries)); + if (!newEntries.contains(container)) { + newEntries.add(container); + cProject.setRawPathEntries((IPathEntry[])newEntries.toArray(new IPathEntry[newEntries.size()]), monitor); + } + } + // create a new discovered scanner config store + MakeCorePlugin.getDefault().getDiscoveryManager().removeDiscoveredInfo(project); + } + + public void setInfoContext(InfoContext context) { + this.context = context; + this.project = context.getProject(); + } + +} 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 new file mode 100644 index 00000000000..0950319ae33 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.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.scannerconfig2; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2; +import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; + + +/** + * A 'provider' that will generate a special makefile to generate scanner config + * + * @author vhirsl + */ +public class SCDMakefileGenerator extends DefaultRunSIProvider { + private static final String ENDL = System.getProperty("line.separator"); //$NON-NLS-1$ + private static final String DENDL = ENDL+ENDL; + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.DefaultRunSIProvider#initialize() + */ + protected boolean initialize() { + boolean rc = super.initialize(); + + if (rc) { + fWorkingDirectory = MakeCorePlugin.getWorkingDirectory(); + // replace string variables in compile arguments + // TODO Vmir - use string variable replacement + for (int i = 0; i < fCompileArguments.length; ++i) { + fCompileArguments[i] = fCompileArguments[i].replaceAll("\\$\\{project_name\\}", //$NON-NLS-1$ + resource.getProject().getName()); + } + rc = generateMakefile(resource.getProject().getName()); + } + return rc; + } + + /** + * @param name + * @return + */ + private boolean generateMakefile(String projectName) { + boolean rc = false; + if (collector instanceof IScannerInfoCollector2) { + IScannerInfoCollector2 collector2 = (IScannerInfoCollector2) collector; + List commands = collector2.getCollectedScannerInfo( + resource.getProject(), ScannerInfoTypes.UNDISCOVERED_COMPILER_COMMAND); + if (commands != null && commands.size() > 0) { + + StringBuffer buffer = new StringBuffer(); + buffer.append("# This is a generated file. Please do not edit."); //$NON-NLS-1$ + buffer.append(DENDL); + buffer.append(".PHONY: all"); //$NON-NLS-1$ + buffer.append(DENDL); + buffer.append("COMMANDS := "); //$NON-NLS-1$ + for (Iterator i = commands.iterator(); i.hasNext(); ) { + CCommandDSC cmd = (CCommandDSC) i.next(); + buffer.append("\t\\"+ENDL+"\t scd_cmd_"); //$NON-NLS-1$ //$NON-NLS-2$ + buffer.append(cmd.getCommandId()); + } + buffer.append(DENDL); + buffer.append("all: $(COMMANDS)"); //$NON-NLS-1$ + buffer.append(DENDL); + for (Iterator i = commands.iterator(); i.hasNext(); ) { + CCommandDSC cmd = (CCommandDSC) i.next(); + buffer.append("scd_cmd_"); //$NON-NLS-1$ + buffer.append(cmd.getCommandId()); + 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.getSCDRunnableCommand(true)); // quoteIncludePaths + buffer.append(" -E -P -v -dD "); //$NON-NLS-1$ + 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); + } + + File makefile = new File(fWorkingDirectory.toFile(), projectName+"_scd.mk"); //$NON-NLS-1$ + try { + PrintStream ps = new PrintStream(new FileOutputStream(makefile)); + ps.println(buffer.toString()); + ps.close(); + rc = true; + } + catch (FileNotFoundException e) { + MakeCorePlugin.log(e); + } + } + } + + return rc; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCMarkerGenerator.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCMarkerGenerator.java new file mode 100644 index 00000000000..4badaee97e5 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCMarkerGenerator.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.core.ProblemMarkerInfo; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; + +/** + * Scanner config discovery related marker generator + * + * @author vhirsl + */ +public class SCMarkerGenerator implements IMarkerGenerator { + + /** + * + */ + public SCMarkerGenerator() { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IMarkerGenerator#addMarker(org.eclipse.core.resources.IResource, int, java.lang.String, int, java.lang.String) + */ + public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) { + ProblemMarkerInfo info = new ProblemMarkerInfo(file, lineNumber, errorDesc, severity, errorVar); + addMarker(info); + } + + + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IMarkerGenerator#addMarker(org.eclipse.cdt.core.ProblemMarkerInfo) + */ + public void addMarker(ProblemMarkerInfo problemMarkerInfo) { + try { + IMarker[] cur = problemMarkerInfo.file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE); + /* + * Try to find matching markers and don't put in duplicates + */ + if ((cur != null) && (cur.length > 0)) { + for (int i = 0; i < cur.length; i++) { + int line = ((Integer) cur[i].getAttribute(IMarker.LOCATION)).intValue(); + int sev = ((Integer) cur[i].getAttribute(IMarker.SEVERITY)).intValue(); + String mesg = (String) cur[i].getAttribute(IMarker.MESSAGE); + if (line == problemMarkerInfo.lineNumber && sev == mapMarkerSeverity(problemMarkerInfo.severity) && mesg.equals(problemMarkerInfo.description)) { + return; + } + } + } + + IMarker marker = problemMarkerInfo.file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.LOCATION, problemMarkerInfo.lineNumber); + marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description); + marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity)); + marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber); + marker.setAttribute(IMarker.CHAR_START, -1); + marker.setAttribute(IMarker.CHAR_END, -1); + if (problemMarkerInfo.variableName != null) { + marker.setAttribute(ICModelMarker.C_MODEL_MARKER_VARIABLE, problemMarkerInfo.variableName); + } + if (problemMarkerInfo.externalPath != null) { + marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, problemMarkerInfo.externalPath.toOSString()); + } + } + catch (CoreException e) { + CCorePlugin.log(e.getStatus()); + } + + } + + public void removeMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) { + IWorkspace workspace = file.getWorkspace(); + // remove specific marker + try { + IMarker[] markers = file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE); + if (markers != null) { + List exactMarkers = new ArrayList(); + for (int i = 0; i < markers.length; i++) { + IMarker marker = markers[i]; + int location = ((Integer) marker.getAttribute(IMarker.LOCATION)).intValue(); + String error = (String) marker.getAttribute(IMarker.MESSAGE); + int sev = ((Integer) marker.getAttribute(IMarker.SEVERITY)).intValue(); + if (location == lineNumber && + errorDesc.equals(error) && + sev == severity) { + exactMarkers.add(marker); + } + } + if (exactMarkers.size() > 0) { + workspace.deleteMarkers((IMarker[]) exactMarkers.toArray(new IMarker[exactMarkers.size()])); + } + } + } + catch (CoreException e) { + CCorePlugin.log(e.getStatus()); + } + } + + int mapMarkerSeverity(int severity) { + switch (severity) { + case SEVERITY_ERROR_BUILD : + case SEVERITY_ERROR_RESOURCE : + return IMarker.SEVERITY_ERROR; + case SEVERITY_INFO : + return IMarker.SEVERITY_INFO; + case SEVERITY_WARNING : + return IMarker.SEVERITY_WARNING; + } + return IMarker.SEVERITY_ERROR; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCProfileInstance.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCProfileInstance.java new file mode 100644 index 00000000000..c1e0ac2aa5e --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCProfileInstance.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 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.scannerconfig2; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; +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.internal.core.scannerconfig2.ScannerConfigProfile.Action; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile.BuildOutputProvider; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile.ScannerInfoCollector; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile.ScannerInfoConsoleParser; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile.ScannerInfoProvider; +import org.eclipse.core.resources.IProject; + +/** + * Instantiated scanner config profile + * + * @author vhirsl + */ +public class SCProfileInstance { + private IProject project; + private ScannerConfigProfile profile; + private IScannerInfoCollector collector; + private InfoContext context; + /** + * + */ + public SCProfileInstance(IProject project, ScannerConfigProfile profile) { + this(project, new InfoContext(project), profile); + } + + public SCProfileInstance(IProject project, InfoContext context, ScannerConfigProfile profile) { + this.project = project; + this.profile = profile; + this.context = context; + } + + /** + * + */ + private void instantiateCollector() { + // create collector object + collector = createScannerInfoCollector(); + if (collector != null) { + // call collector.setProject(project) if class supports it + Class clazz = collector.getClass(); + try { +// Method setProjectMethod = clazz.getMethod("setProject", new Class[] {IProject.class});//$NON-NLS-1$ +// setProjectMethod.invoke(collector, new Object[] {project}); + Object[] args = null; + Method setMethod = null; + if(context != null){ + try { + setMethod = clazz.getMethod("setInfoContext", new Class[] {InfoContext.class});//$NON-NLS-1$ + args = new Object[]{context}; + } catch(NoSuchMethodException e) { + } + } + + if(setMethod == null){ + try { + setMethod = clazz.getMethod("setProject", new Class[] {IProject.class});//$NON-NLS-1$ + args = new Object[]{project}; + } catch(NoSuchMethodException e) { + } + } + if(setMethod != null) + setMethod.invoke(collector, args); + + } catch (SecurityException e) { + MakeCorePlugin.log(e); +// } catch (NoSuchMethodException e) { + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + MakeCorePlugin.log(e.getCause()); + } + } + // all other objects are created on request + } + + /** + * @return + */ + public ScannerConfigProfile getProfile() { + return profile; + } + + /** + * @return a single scannerInfoCollector object + */ + public IScannerInfoCollector getScannerInfoCollector() { + if (collector == null) { + instantiateCollector(); + } + return collector; + } + + public IScannerInfoCollector createScannerInfoCollector() { + ScannerInfoCollector collector = profile.getScannerInfoCollectorElement(); + if (collector != null) { + return (IScannerInfoCollector) collector.createScannerInfoCollector(); + } + return null; + } + + /** + * @return Creates new buildOutputProvider user object. + */ + public IExternalScannerInfoProvider createBuildOutputProvider() { + BuildOutputProvider bop = profile.getBuildOutputProviderElement(); + if (bop != null) { + Action action = bop.getAction(); + if (action != null) { + return (IExternalScannerInfoProvider) action.createExternalScannerInfoProvider(); + } + } + return null; + } + /** + * @return Creates new buildOutputParser user object. + */ + public IScannerInfoConsoleParser createBuildOutputParser() { + BuildOutputProvider bop = profile.getBuildOutputProviderElement(); + if (bop != null) { + ScannerInfoConsoleParser parserElement = bop.getScannerInfoConsoleParser(); + if (parserElement != null) { + return (IScannerInfoConsoleParser) parserElement.createScannerInfoConsoleParser(); + } + } + return null; + } + /** + * @return Creates new externalSIProvider user object. + */ + public IExternalScannerInfoProvider createExternalScannerInfoProvider(String providerId) { + ScannerInfoProvider provider = profile.getScannerInfoProviderElement(providerId); + if (provider != null) { + return (IExternalScannerInfoProvider) provider.getAction().createExternalScannerInfoProvider(); + } + return null; + } + /** + * @return Creates new esiProviderOutputParser user object. + */ + public IScannerInfoConsoleParser createExternalScannerInfoParser(String providerId) { + ScannerInfoProvider provider = profile.getScannerInfoProviderElement(providerId); + if (provider != null) { + return (IScannerInfoConsoleParser) provider.getScannerInfoConsoleParser().createScannerInfoConsoleParser(); + } + return null; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigInfoFactory2.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigInfoFactory2.java new file mode 100644 index 00000000000..a7a9a21d56b --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigInfoFactory2.java @@ -0,0 +1,1168 @@ +/******************************************************************************* + * 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.scannerconfig2; + +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 org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2Set; +import org.eclipse.cdt.make.core.scannerconfig.InfoContext; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile.ScannerInfoProvider; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.core.runtime.Status; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * New ScannerConfigInfoFactory + * + * @author vhirsl + */ +public class ScannerConfigInfoFactory2 { + // build properties + private static final String SCANNER_CONFIG = "scannerConfiguration"; //$NON-NLS-1$ + private static final String SC_AUTODISCOVERY = "autodiscovery"; //$NON-NLS-1$ + private static final String ENABLED = "enabled"; //$NON-NLS-1$ + private static final String SELECTED_PROFILE_ID = "selectedProfileId"; //$NON-NLS-1$ + private static final String PROBLEM_REPORTING_ENABLED = "problemReportingEnabled"; //$NON-NLS-1$ + private static final String PROFILE = "profile"; //$NON-NLS-1$ + private static final String ID = "id"; //$NON-NLS-1$ + private static final String BUILD_OUTPUT_PROVIDER = "buildOutputProvider"; //$NON-NLS-1$ + private static final String OPEN_ACTION = "openAction"; //$NON-NLS-1$ + private static final String FILE_PATH = "filePath"; //$NON-NLS-1$ + private static final String PARSER = "parser"; //$NON-NLS-1$ + private static final String SCANNER_INFO_PROVIDER = "scannerInfoProvider"; //$NON-NLS-1$ + private static final String RUN_ACTION = "runAction"; //$NON-NLS-1$ + private static final String USE_DEFAULT = "useDefault"; //$NON-NLS-1$ + private static final String COMMAND = "command"; //$NON-NLS-1$ + private static final String ARGUMENTS = "arguments"; //$NON-NLS-1$ + // preferences + private static final String DOT = ".";//$NON-NLS-1$ + private static final String SCD = "SCD.";//$NON-NLS-1$ + private static final String SCANNER_CONFIG_AUTODISCOVERY_ENABLED = "SCD.enabled";//$NON-NLS-1$ + private static final String SCANNER_CONFIG_SELECTED_PROFILE_ID = "SCD.selectedProfileId";//$NON-NLS-1$ + private static final String SCANNER_CONFIG_PROBLEM_REPORTING_ENABLED = "SCD.problemReportingEnabled"; //$NON-NLS-1$ +// following require prefix: profileId + private static final String BUILD_OUTPUT_OPEN_ACTION_ENABLED = ".BOP.open.enabled";//$NON-NLS-1$ + private static final String BUILD_OUTPUT_OPEN_ACTION_FILE_PATH = ".BOP.open.path";//$NON-NLS-1$ + private static final String BUILD_OUTPUT_PARSER_ENABLED = ".BOP.parser.enabled";//$NON-NLS-1$ + // following require prefix: profileId + "." + SCANNER_INFO_PROVIDER + "." + providerId + private static final String SI_PROVIDER_RUN_ACTION_USE_DEFAULT = ".run.useDefault";//$NON-NLS-1$ + private static final String SI_PROVIDER_RUN_ACTION_COMMAND = ".run.command";//$NON-NLS-1$ + private static final String SI_PROVIDER_RUN_ACTION_ARGUMENTS = ".run.arguments";//$NON-NLS-1$ + private static final String SI_PROVIDER_OPEN_ACTION_FILE_PATH = ".open.path";//$NON-NLS-1$ + private static final String SI_PROVIDER_PARSER_ENABLED = ".parser.enabled";//$NON-NLS-1$ + + private static final String ELEMENT_CS_INFO = "scannerConfigBuildInfo";//$NON-NLS-1$ + private static final String ATTRIBUTE_CS_INFO_INSTANCE_ID = "instanceId";//$NON-NLS-1$ + + private static class ScannerConfigInfoSet implements IScannerConfigBuilderInfo2Set { + private HashMap fMap = new HashMap(); + private IProject fProject; + private boolean fIsDirty; + + ScannerConfigInfoSet(IProject project, String profileId){ + this.fProject = project; + load(profileId); + } + + private void load(String profileId) { + ICDescriptor descriptor; + try { + descriptor = CCorePlugin.getDefault().getCProjectDescription(fProject, false); + Element rootEl = descriptor != null ? descriptor.getProjectData(SCANNER_CONFIG) : null; + InfoContext defaultContext = new InfoContext(fProject); + if(rootEl == null || !rootEl.hasChildNodes()){ + BuildProperty prop = new BuildProperty(this, fProject, defaultContext, (Store)create(MakeCorePlugin.getDefault().getPluginPreferences(), profileId, false), profileId); + fMap.put(defaultContext, prop); + prop.isDirty = true; + } else { + BuildProperty prop = new BuildProperty(this, fProject,defaultContext, profileId, rootEl); + fMap.put(defaultContext, prop); + + for (Node sc = rootEl.getFirstChild(); + sc != null; sc = sc.getNextSibling()) { + if (sc.getNodeName().equals(ELEMENT_CS_INFO)) { + Element el = (Element)sc; + String instanceId = el.getAttribute(ATTRIBUTE_CS_INFO_INSTANCE_ID); + if(instanceId.length() != 0){ + InfoContext c = new InfoContext(fProject, instanceId); + BuildProperty p = new BuildProperty(this, fProject, c, profileId, el); + fMap.put(c, p); + } + } + } + } + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + + public IScannerConfigBuilderInfo2 createInfo(InfoContext context, + IScannerConfigBuilderInfo2 base, String profileId){ + fIsDirty = true; + BuildProperty prop = new BuildProperty(this, fProject, context, (Store)base, profileId); + fMap.put(context, prop); + return prop; + } + + public IScannerConfigBuilderInfo2 createInfo(InfoContext context, + IScannerConfigBuilderInfo2 base){ + fIsDirty = true; + return createInfo(context, base, ScannerConfigProfileManager.NULL_PROFILE_ID); + } + + public InfoContext[] getContexts() { + return (InfoContext[])fMap.keySet().toArray(new InfoContext[fMap.size()]); + } + + public IScannerConfigBuilderInfo2 getInfo(InfoContext context) { + return (IScannerConfigBuilderInfo2)fMap.get(context); + } + + public Map getInfoMap() { + return Collections.unmodifiableMap(fMap); + } + + public IScannerConfigBuilderInfo2 removeInfo(InfoContext context) throws CoreException { + checkRemoveInfo(context); + fIsDirty = true; + return (IScannerConfigBuilderInfo2)fMap.remove(context); + } + + private void checkRemoveInfo(InfoContext context) throws CoreException{ + if(context.isDefaultContext()) + throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, "can not remove the default info")); + } + + public void save() throws CoreException { + if (isDirty()) { + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(fProject, true); + Element sc = descriptor.getProjectData(SCANNER_CONFIG); + + Document doc = sc.getOwnerDocument(); + + // Clear out all current children + Node child = sc.getFirstChild(); + while (child != null) { + sc.removeChild(child); + child = sc.getFirstChild(); + } + + BuildProperty prop = (BuildProperty)fMap.get(new InfoContext(fProject)); + prop.store(sc); + + for(Iterator iter = fMap.entrySet().iterator(); iter.hasNext();){ + Map.Entry entry = (Map.Entry)iter.next(); + + InfoContext context = (InfoContext)entry.getKey(); + if(context.isDefaultContext()) + continue; + + String instanceId = context.getInstanceId(); + if(instanceId.length() == 0) + continue; + + BuildProperty p = (BuildProperty)entry.getValue(); + if(p == prop) + continue; + + Element el = doc.createElement(ELEMENT_CS_INFO); + el.setAttribute(ATTRIBUTE_CS_INFO_INSTANCE_ID, instanceId); + p.store(el); + sc.appendChild(el); + } + + fIsDirty = false; + } + } + + public boolean isDirty(){ + if(fIsDirty) + return true; + for(Iterator iter = fMap.values().iterator(); iter.hasNext();){ + BuildProperty prop = (BuildProperty)iter.next(); + if(prop.isDirty) + return true; + } + + return false; + } + + public IProject getProject() { + return fProject; + } + + public IScannerConfigBuilderInfo2 createInfo(InfoContext context) { + fIsDirty = true; + return createInfo(context, ScannerConfigProfileManager.NULL_PROFILE_ID); + } + + public IScannerConfigBuilderInfo2 createInfo(InfoContext context, + String profileId) { + fIsDirty = true; + IScannerConfigBuilderInfo2 base = getInfo(new InfoContext(fProject)); + return createInfo(context, base, profileId); + } + } + + private static abstract class Store implements IScannerConfigBuilderInfo2 { + protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ + protected boolean isDirty; // derived + + protected boolean autoDiscoveryEnabled; + protected boolean problemReportingEnabled; + protected String selectedProfile = EMPTY_STRING; + protected Map profileOptionsMap; // (profileId, options) + static class ProfileOptions { + protected boolean buildOutputFileActionEnabled; + protected String buildOutputFilePath = EMPTY_STRING; + protected boolean buildOutputParserEnabled; + protected Map providerOptionsMap; // {providerId, options} + static class ProviderOptions { + protected String providerKind; // derived + protected boolean providerOutputParserEnabled; + protected boolean providerRunUseDefault; + protected String providerRunCommand = EMPTY_STRING; + protected String providerRunArguments = EMPTY_STRING; + protected String providerOpenFilePath = EMPTY_STRING; + + ProviderOptions(){ + } + + ProviderOptions(ProviderOptions base){ + this.providerKind = base.providerKind; + this.providerOutputParserEnabled = base.providerOutputParserEnabled; + this.providerRunUseDefault = base.providerRunUseDefault; + this.providerRunCommand = base.providerRunCommand; + this.providerRunArguments = base.providerRunArguments; + this.providerOpenFilePath = base.providerOpenFilePath; + } + + } + + ProfileOptions(){ + } + + ProfileOptions(ProfileOptions base){ + this.buildOutputFileActionEnabled = base.buildOutputFileActionEnabled; + this.buildOutputFilePath = base.buildOutputFilePath; + this.buildOutputParserEnabled = base.buildOutputParserEnabled; + this.providerOptionsMap = new LinkedHashMap(base.providerOptionsMap); + for(Iterator iter = this.providerOptionsMap.entrySet().iterator(); iter.hasNext();){ + Map.Entry entry = (Map.Entry)iter.next(); + ProviderOptions basePo = (ProviderOptions)entry.getValue(); + entry.setValue(new ProviderOptions(basePo)); + } + } + + } + + protected Store() { + isDirty = false; + } + + protected Store(Store base, String profileId){ + this.autoDiscoveryEnabled = base.autoDiscoveryEnabled; + this.problemReportingEnabled = base.problemReportingEnabled; + this.selectedProfile = ScannerConfigProfileManager.NULL_PROFILE_ID.equals(profileId) ? base.selectedProfile : profileId; + this.profileOptionsMap = new LinkedHashMap(base.profileOptionsMap); + for(Iterator iter = this.profileOptionsMap.entrySet().iterator(); iter.hasNext();){ + Map.Entry entry = (Map.Entry)iter.next(); + ProfileOptions basePo = (ProfileOptions)entry.getValue(); + entry.setValue(new ProfileOptions(basePo)); + } + + isDirty = true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#isAutoDiscoveryEnabled() + */ + public boolean isAutoDiscoveryEnabled() { + return autoDiscoveryEnabled; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setAutoDiscoveryEnabled(boolean) + */ + public void setAutoDiscoveryEnabled(boolean enable) { + autoDiscoveryEnabled = setDirty(autoDiscoveryEnabled, enable); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#isSIProblemGenerationEnabled() + */ + public boolean isProblemReportingEnabled() { + return problemReportingEnabled; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setSIProblemGenerationEnabled(boolean) + */ + public void setProblemReportingEnabled(boolean enable) { + problemReportingEnabled = setDirty(problemReportingEnabled, enable); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getSelectedProfileId() + */ + public String getSelectedProfileId() { + return selectedProfile; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setSelectedProfileId(java.lang.String) + */ + public void setSelectedProfileId(String profileId) { + selectedProfile = setDirty(selectedProfile, profileId); +// if (isDirty) { +// try { +// load(); +// isDirty = false; +// } catch (CoreException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getProfileIdList() + */ + public List getProfileIdList() { + return new ArrayList(profileOptionsMap.keySet()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#isBuildOutputFileActionEnabled() + */ + public boolean isBuildOutputFileActionEnabled() { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + return (po != null) ? po.buildOutputFileActionEnabled : false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setBuildOutputFileActionEnabled(boolean) + */ + public void setBuildOutputFileActionEnabled(boolean enable) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + po.buildOutputFileActionEnabled = setDirty(po.buildOutputFileActionEnabled, enable); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getBuildOutputFilePath() + */ + public String getBuildOutputFilePath() { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + return (po != null) ? po.buildOutputFilePath : EMPTY_STRING; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setBuildOutputFilePath(java.lang.String) + */ + public void setBuildOutputFilePath(String path) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + po.buildOutputFilePath = setDirty(po.buildOutputFilePath, path); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#isBuildOutputParserEnabled() + */ + public boolean isBuildOutputParserEnabled() { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + return (po != null) ? po.buildOutputParserEnabled : true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setBuildOutputParserEnabled(boolean) + */ + public void setBuildOutputParserEnabled(boolean enable) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + po.buildOutputParserEnabled = setDirty(po.buildOutputParserEnabled, enable); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getSIProviderIdList() + */ + public List getProviderIdList() { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + return (po != null) ? new ArrayList(po.providerOptionsMap.keySet()) : new ArrayList(0); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#addSIProvider(java.lang.String) + */ +// public void addSIProvider(String providerId) { +// providerOptionsMap.put(providerId, new ProviderOptions()); +// } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#removeSIProvider(java.lang.String) + */ +// public void removeSIProvider(String providerId) { +// providerOptionsMap.put(providerId, null); +// } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#isSIProviderOutputParserEnabled(java.lang.String) + */ + public boolean isProviderOutputParserEnabled(String providerId) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + return (ppo == null) ? false : ppo.providerOutputParserEnabled; + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setSIProviderOutputParserEnabled(java.lang.String, boolean) + */ + public void setProviderOutputParserEnabled(String providerId, boolean enable) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + if (ppo != null) { + ppo.providerOutputParserEnabled = setDirty(ppo.providerOutputParserEnabled, enable); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#isUseDefaultProviderCommand(java.lang.String) + */ + public boolean isUseDefaultProviderCommand(String providerId) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + return (ppo == null) ? false : ppo.providerRunUseDefault; + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setUseDefaultProviderCommand(java.lang.String, boolean) + */ + public void setUseDefaultProviderCommand(String providerId, boolean enable) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + if (ppo != null) { + ppo.providerRunUseDefault = setDirty(ppo.providerRunUseDefault, enable); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getProviderRunCommand(java.lang.String) + */ + public String getProviderRunCommand(String providerId) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + return (ppo == null) ? null : ppo.providerRunCommand; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setProviderRunCommand(java.lang.String, java.lang.String) + */ + public void setProviderRunCommand(String providerId, String command) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + if (ppo != null) { + ppo.providerRunCommand = setDirty(ppo.providerRunCommand, command); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getProviderRunArguments(java.lang.String) + */ + public String getProviderRunArguments(String providerId) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + return (ppo == null) ? null : ppo.providerRunArguments; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setProviderRunArguments(java.lang.String, java.lang.String) + */ + public void setProviderRunArguments(String providerId, String arguments) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + if (ppo != null) { + ppo.providerRunArguments = setDirty(ppo.providerRunArguments, arguments); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#getProviderOpenFilePath(java.lang.String) + */ + public String getProviderOpenFilePath(String providerId) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + return (ppo == null) ? null : ppo.providerOpenFilePath; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#setProviderOpenFilePath(java.lang.String, java.lang.String) + */ + public void setProviderOpenFilePath(String providerId, String filePath) { + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(selectedProfile); + if (po != null) { + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + if (ppo != null) { + ppo.providerOpenFilePath = setDirty(ppo.providerOpenFilePath, filePath); + } + } + } + + private boolean setDirty(boolean l, boolean r) { + isDirty = isDirty || (l != r); + return r; + } + private String setDirty(String l, String r) { + isDirty = isDirty || !l.equals(r); + return r; + } + +// protected abstract void load(); +// public abstract void store(); + + /** + * Populate buildInfo based on profile configuration + */ + protected void loadFromProfileConfiguration(ProfileOptions po, String profileId) { + ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). + getSCProfileConfiguration(profileId); + List providerIds = configuredProfile.getSIProviderIds(); + + po.buildOutputParserEnabled = false; + po.buildOutputFileActionEnabled = false; + po.buildOutputFilePath = EMPTY_STRING; + if (configuredProfile.getBuildOutputProviderElement() != null) { + po.buildOutputParserEnabled = true; + if (configuredProfile.getBuildOutputProviderElement().getAction() != null) { + po.buildOutputFileActionEnabled = true; + String buildOutputFilePath = configuredProfile.getBuildOutputProviderElement(). + getAction().getAttribute("file");//$NON-NLS-1$ + po.buildOutputFilePath = (buildOutputFilePath != null) ? buildOutputFilePath : EMPTY_STRING; + } + } + po.providerOptionsMap = new LinkedHashMap(providerIds.size()); + for (int i = 0; i < providerIds.size(); ++i) { + ProfileOptions.ProviderOptions ppo = new ProfileOptions.ProviderOptions(); + String providerId = (String) providerIds.get(i); + po.providerOptionsMap.put(providerId, ppo); + + ppo.providerOutputParserEnabled = (configuredProfile.getScannerInfoProviderElement(providerId) == null) ? false : true; + ppo.providerKind = configuredProfile.getScannerInfoProviderElement(providerId).getProviderKind(); + String attrValue; + if (ppo.providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.RUN)) { + attrValue = configuredProfile.getScannerInfoProviderElement(providerId). + getAction().getAttribute(COMMAND); + ppo.providerRunCommand = (attrValue != null) ? attrValue : EMPTY_STRING; + attrValue = configuredProfile.getScannerInfoProviderElement(providerId). + getAction().getAttribute(ARGUMENTS); + ppo.providerRunArguments = (attrValue != null) ? attrValue : EMPTY_STRING; + + ppo.providerRunUseDefault = true; + } + else if (ppo.providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.OPEN)) { + attrValue = configuredProfile.getScannerInfoProviderElement(providerId). + getAction().getAttribute("file");//$NON-NLS-1$ + ppo.providerOpenFilePath = (attrValue != null) ? attrValue : EMPTY_STRING; + } + } + } + + } + + /** + * Build properties stored in .cdtproject file + * + * @author vhirsl + */ + private static class BuildProperty extends Store { + private IProject project; + private InfoContext context; + private String profileId; + private ScannerConfigInfoSet container; + + BuildProperty(ScannerConfigInfoSet container, IProject project, InfoContext context, String profileId, Element element) { + super(); + this.project = project; + this.context = context; + this.profileId = profileId; + this.container = container; + load(element); + } + + BuildProperty(ScannerConfigInfoSet container, IProject project, InfoContext context, Store base, String profileId) { + super(base, profileId); + this.project = project; + this.context = context; + this.container = container; + if(!profileId.equals(ScannerConfigProfileManager.NULL_PROFILE_ID)){ + this.profileId = profileId; + } else if(base instanceof BuildProperty){ + BuildProperty prop = (BuildProperty)base; + this.profileId = prop.profileId; + } else { + Preference pref = (Preference)base; + this.profileId = pref.profileId; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigInfoFactory2.Store#load() + */ + protected void load(Element element) { +// ICDescriptor descriptor; + List profileIds = ScannerConfigProfileManager.getInstance().getProfileIds(context); + List loadedProfiles = new ArrayList(); +// try { +// descriptor = CCorePlugin.getDefault().getCProjectDescription(project, false); + for (Node sc = element.getFirstChild(); + sc != null; sc = sc.getNextSibling()) { + if (sc.getNodeName().equals(SC_AUTODISCOVERY)) { + autoDiscoveryEnabled = Boolean.valueOf( + ((Element)sc).getAttribute(ENABLED)).booleanValue(); + selectedProfile = (profileId == ScannerConfigProfileManager.NULL_PROFILE_ID) + ? ((Element)sc).getAttribute(SELECTED_PROFILE_ID) + : profileId; + problemReportingEnabled = Boolean.valueOf( + ((Element)sc).getAttribute(PROBLEM_REPORTING_ENABLED)).booleanValue(); + } + else if (sc.getNodeName().equals(PROFILE)) { + if (profileIds.contains(((Element)sc).getAttribute(ID))) { + load(sc); + loadedProfiles.add(((Element)sc).getAttribute(ID)); + } + } + } + if (loadedProfiles.size() < 1) { + // No ScannerConfigDiscovery entry, try old project location - .project + if (migrateScannerConfigBuildInfo(ScannerConfigProfileManager.PER_PROJECT_PROFILE_ID)) { + loadedProfiles.add(ScannerConfigProfileManager.PER_PROJECT_PROFILE_ID); + } + else { + // disable autodiscovery + autoDiscoveryEnabled = false; + } + } + if (loadedProfiles.size() < profileIds.size()) { + // initialize remaining profiles with default values + for (Iterator i = profileIds.iterator(); i.hasNext(); ) { + String profileId = (String) i.next(); + if (!loadedProfiles.contains(profileId)) { + loadDefaults(profileId); + loadedProfiles.add(profileId); + } + } +// // store migrated data +// isDirty = true; +// store(); +// save(); + } +// } catch (CoreException e) { +// MakeCorePlugin.log(e); +// } + } + + /** + * Load profile defaults + * @param profileId + */ + private void loadDefaults(String profileId) { + ProfileOptions po = new ProfileOptions(); + po.buildOutputFileActionEnabled = false; + po.buildOutputParserEnabled = true; + + ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). + getSCProfileConfiguration(profileId); + + po.providerOptionsMap = new LinkedHashMap(); + for (Iterator i = configuredProfile.getSIProviderIds().iterator(); i.hasNext(); ) { + String providerId = (String) i.next(); + ProfileOptions.ProviderOptions ppo = new ProfileOptions.ProviderOptions(); + ScannerInfoProvider configuredProvider = configuredProfile. + getScannerInfoProviderElement(providerId); + ppo.providerKind = configuredProvider.getProviderKind(); + ppo.providerOutputParserEnabled = false; + if (ppo.providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.RUN)) { + ppo.providerRunUseDefault = true; + ppo.providerRunCommand = configuredProvider.getAction().getAttribute(COMMAND); + ppo.providerRunArguments = configuredProvider.getAction().getAttribute(ARGUMENTS); + } + else if (ppo.providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.OPEN)) { + ppo.providerOpenFilePath = configuredProvider.getAction().getAttribute("file");//$NON-NLS-1$ + } + + po.providerOptionsMap.put(providerId, ppo); + } + + if (profileOptionsMap == null) { + profileOptionsMap = new LinkedHashMap(); + } + profileOptionsMap.put(profileId, po); + } + + /** + * @param profileId + */ + private boolean migrateScannerConfigBuildInfo(String profileId) { + boolean rc = true; + try { + IScannerConfigBuilderInfo oldInfo = MakeCorePlugin. + createScannerConfigBuildInfo(project, ScannerConfigBuilder.BUILDER_ID); + autoDiscoveryEnabled = oldInfo.isAutoDiscoveryEnabled(); + problemReportingEnabled = oldInfo.isSIProblemGenerationEnabled(); + // effectively a PerProject profile + selectedProfile = profileId; + + ProfileOptions po = new ProfileOptions(); + po.buildOutputFileActionEnabled = false; + po.buildOutputParserEnabled = oldInfo.isMakeBuilderConsoleParserEnabled(); + + ProfileOptions.ProviderOptions ppo = new ProfileOptions.ProviderOptions(); + ppo.providerKind = ScannerConfigProfile.ScannerInfoProvider.RUN; + ppo.providerOutputParserEnabled = oldInfo.isESIProviderCommandEnabled(); + ppo.providerRunUseDefault = oldInfo.isDefaultESIProviderCmd(); + ppo.providerRunCommand = oldInfo.getESIProviderCommand().toString(); + ppo.providerRunArguments = oldInfo.getESIProviderArguments(); + + ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). + getSCProfileConfiguration(selectedProfile); + // get the one and only provider id + String providerId = (String) configuredProfile.getSIProviderIds().get(0); + po.providerOptionsMap = new LinkedHashMap(1); + po.providerOptionsMap.put(providerId, ppo); + + profileOptionsMap = new LinkedHashMap(1); + profileOptionsMap.put(profileId, po); + + // store migrated data + isDirty = true; + save(); + } + catch (CoreException e) { + MakeCorePlugin.log(e); + rc = false; + } + return rc; + } + + /** + * @param profile + */ + private void load(Node profile) { + if (profileOptionsMap == null) { + profileOptionsMap = new LinkedHashMap(1); + } + ProfileOptions po = new ProfileOptions(); + String profileId = ((Element)profile).getAttribute(ID); + profileOptionsMap.put(profileId, po); + // get the list of providers from the profile configuration + ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). + getSCProfileConfiguration(profileId); + List providerIds = configuredProfile.getSIProviderIds(); + int providerCounter = 0; + po.providerOptionsMap = new LinkedHashMap(providerIds.size()); + + for (Node child = profile.getFirstChild(); + child != null; + child = child.getNextSibling()) { + // buildOutputProvider element + if (BUILD_OUTPUT_PROVIDER.equals(child.getNodeName())) { + for (Node grandchild = child.getFirstChild(); + grandchild != null; + grandchild = grandchild.getNextSibling()) { + + if (OPEN_ACTION.equals(grandchild.getNodeName())) { + po.buildOutputFileActionEnabled = Boolean.valueOf( + ((Element)grandchild).getAttribute(ENABLED)).booleanValue(); + po.buildOutputFilePath = ((Element)grandchild).getAttribute(FILE_PATH); + } + else if (PARSER.equals(grandchild.getNodeName())) { + po.buildOutputParserEnabled = Boolean.valueOf( + ((Element)grandchild).getAttribute(ENABLED)).booleanValue(); + } + } + } + else if (SCANNER_INFO_PROVIDER.equals(child.getNodeName())) { + String providerId = ((Element)child).getAttribute(ID); + if (providerIds.get(providerCounter).equals(providerId)) { + // new provider + ProfileOptions.ProviderOptions ppo = new ProfileOptions.ProviderOptions(); + po.providerOptionsMap.put(providerId, ppo); + ppo.providerKind = configuredProfile.getScannerInfoProviderElement( + providerId).getProviderKind(); + + for (Node grandchild = child.getFirstChild(); + grandchild != null; + grandchild = grandchild.getNextSibling()) { + // action + if (RUN_ACTION.equals(grandchild.getNodeName())) { + ppo.providerRunUseDefault = Boolean.valueOf( + ((Element)grandchild).getAttribute(USE_DEFAULT)).booleanValue(); + ppo.providerRunCommand = ((Element)grandchild).getAttribute(COMMAND); + ppo.providerRunArguments = ((Element)grandchild).getAttribute(ARGUMENTS); + } + else if (OPEN_ACTION.equals(grandchild.getNodeName())) { + ppo.providerOpenFilePath = ((Element)grandchild).getAttribute(FILE_PATH); + } + // parser + else if (PARSER.equals(grandchild.getNodeName())) { + ppo.providerOutputParserEnabled = Boolean.valueOf( + ((Element)grandchild).getAttribute(ENABLED)).booleanValue(); + } + } + ++providerCounter; + } + else { + // mismatch - error + // TODO Vmir define error + } + } + } + } + + private void store(Element sc)/* throws CoreException */{ +// if (isDirty || force) { +// ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project, true); +// Element sc = descriptor.getProjectData(SCANNER_CONFIG); + Document doc = sc.getOwnerDocument(); + + // Clear out all current children + Node child = sc.getFirstChild(); + while (child != null) { + sc.removeChild(child); + child = sc.getFirstChild(); + } + + Element autod = doc.createElement(SC_AUTODISCOVERY); + sc.appendChild(autod); + autod.setAttribute(ENABLED, Boolean.toString(autoDiscoveryEnabled)); + autod.setAttribute(SELECTED_PROFILE_ID, selectedProfile); + autod.setAttribute(PROBLEM_REPORTING_ENABLED, Boolean.toString(problemReportingEnabled)); + + for (Iterator i = profileOptionsMap.keySet().iterator(); i.hasNext();) { + String profileId = (String) i.next(); + Element profile = doc.createElement(PROFILE); + profile.setAttribute(ID, profileId); + store(profile, (ProfileOptions) profileOptionsMap.get(profileId)); + sc.appendChild(profile); + } + + isDirty = false; +// return true; +// } +// return false; + } + + /** + * @param profile element + * @param profile options + */ + private void store(Element profile, ProfileOptions po) { + Element child, grandchild; + Document doc = profile.getOwnerDocument(); + // buildOutputProvider element + child = doc.createElement(BUILD_OUTPUT_PROVIDER); + grandchild = doc.createElement(OPEN_ACTION); + grandchild.setAttribute(ENABLED, Boolean.toString(po.buildOutputFileActionEnabled)); + grandchild.setAttribute(FILE_PATH, po.buildOutputFilePath); + child.appendChild(grandchild); + grandchild = doc.createElement(PARSER); + grandchild.setAttribute(ENABLED, Boolean.toString(po.buildOutputParserEnabled)); + child.appendChild(grandchild); + profile.appendChild(child); + // scannerInfoProvider elements + // get the list of providers from the profile configuration +// ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). +// getSCProfileConfiguration(selectedProfile); +// List providerIds = configuredProfile.getSIProviderIds(); + List providerIds = new ArrayList(po.providerOptionsMap.keySet()); + for (int i = 0; i < providerIds.size(); ++i) { + String providerId = (String) providerIds.get(i); + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) po.providerOptionsMap.get(providerId); + + if (ppo != null) { + child = doc.createElement(SCANNER_INFO_PROVIDER); + child.setAttribute(ID, providerId); + + // action +// String providerKind = configuredProfile.getScannerInfoProviderElement( +// providerId).getProviderKind(); + String providerKind = ppo.providerKind; + + if (providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.RUN)) { + grandchild = doc.createElement(RUN_ACTION); + grandchild.setAttribute(USE_DEFAULT, Boolean.toString(ppo.providerRunUseDefault)); + grandchild.setAttribute(COMMAND, ppo.providerRunCommand); + grandchild.setAttribute(ARGUMENTS, ppo.providerRunArguments); + } + else if (providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.OPEN)) { + grandchild = doc.createElement(OPEN_ACTION); + grandchild.setAttribute(FILE_PATH, ppo.providerOpenFilePath); + } + child.appendChild(grandchild); + // parser + grandchild = doc.createElement(PARSER); + grandchild.setAttribute(ENABLED, Boolean.toString(ppo.providerOutputParserEnabled)); + child.appendChild(grandchild); + profile.appendChild(child); + } + else { + // missing provider options - error + // TODO Vmir define error + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#save() + */ + public synchronized void save() throws CoreException { + if(isDirty){ + container.save(); + isDirty = false; + } +// if (store()) { +// ICDescriptorOperation op = new ICDescriptorOperation() { +// +// public void execute(ICDescriptor descriptor, IProgressMonitor monitor) throws CoreException { +// descriptor.saveProjectData(); +// } +// +// }; +// CCorePlugin.getDefault().getCDescriptorManager(). +// runDescriptorOperation(project, op, null); +// } + } + + } + + /** + * Preferences + * + * @author vhirsl + */ + private static class Preference extends Store { + private Preferences prefs; + private String profileId; + private boolean useDefaults; + + /** + * @param prefs + * @param profileId + * @param useDefaults + */ + public Preference(Preferences prefs, String profileId, boolean useDefaults) { + super(); + this.prefs = prefs; + this.profileId = profileId; + this.useDefaults = useDefaults; + load(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigInfoFactory2.Store#load() + */ + protected void load() { + autoDiscoveryEnabled = getBoolean(SCANNER_CONFIG_AUTODISCOVERY_ENABLED); + selectedProfile = (ScannerConfigProfileManager.NULL_PROFILE_ID.equals(profileId)) ? + getString(SCANNER_CONFIG_SELECTED_PROFILE_ID) : + profileId; + problemReportingEnabled = getBoolean(SCANNER_CONFIG_PROBLEM_REPORTING_ENABLED); + if (ScannerConfigProfileManager.NULL_PROFILE_ID.equals(selectedProfile) && !useDefaults) { + // get the default value + selectedProfile = prefs.getDefaultString(SCANNER_CONFIG_SELECTED_PROFILE_ID); + } + List profileIds = ScannerConfigProfileManager.getInstance().getProfileIds(); + profileOptionsMap = new LinkedHashMap(profileIds.size()); + for (Iterator I = profileIds.iterator(); I.hasNext(); ) { + String profileId = (String) I.next(); + ProfileOptions po = new ProfileOptions(); + profileOptionsMap.put(profileId, po); + + boolean profileStored = getBoolean(SCD + profileId + DOT + ENABLED); + if (!profileStored && !useDefaults) { + loadFromProfileConfiguration(po, profileId); + continue; + } + + po.buildOutputFileActionEnabled = getBoolean(SCD + profileId + BUILD_OUTPUT_OPEN_ACTION_ENABLED); + po.buildOutputFilePath = getString(SCD + profileId + BUILD_OUTPUT_OPEN_ACTION_FILE_PATH); + po.buildOutputParserEnabled = getBoolean(SCD + profileId + BUILD_OUTPUT_PARSER_ENABLED); + + ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). + getSCProfileConfiguration(profileId); + List providerIds = configuredProfile.getSIProviderIds(); + po.providerOptionsMap = new LinkedHashMap(providerIds.size()); + for (int i = 0; i < providerIds.size(); ++i) { + String providerId = (String) providerIds.get(i); + ProfileOptions.ProviderOptions ppo = new ProfileOptions.ProviderOptions(); + po.providerOptionsMap.put(providerId, ppo); + ppo.providerKind = configuredProfile.getScannerInfoProviderElement( + providerId).getProviderKind(); + + ppo.providerOutputParserEnabled = getBoolean(SCD + profileId + DOT + + providerId + SI_PROVIDER_PARSER_ENABLED); + if (ppo.providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.RUN)) { + ppo.providerRunUseDefault = getBoolean(SCD + profileId + DOT + providerId + + SI_PROVIDER_RUN_ACTION_USE_DEFAULT); + ppo.providerRunCommand = getString(SCD + profileId + DOT + providerId + + SI_PROVIDER_RUN_ACTION_COMMAND); + ppo.providerRunArguments = getString(SCD + profileId + DOT + providerId + + SI_PROVIDER_RUN_ACTION_ARGUMENTS); + } + else if (ppo.providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.OPEN)) { + ppo.providerOpenFilePath = getString(SCD + profileId + DOT + providerId + + SI_PROVIDER_OPEN_ACTION_FILE_PATH); + } + } + } + } + + private void store() { + if (isDirty) { + set(SCANNER_CONFIG_AUTODISCOVERY_ENABLED, autoDiscoveryEnabled); + set(SCANNER_CONFIG_SELECTED_PROFILE_ID, selectedProfile); + set(SCANNER_CONFIG_PROBLEM_REPORTING_ENABLED, problemReportingEnabled); + + List profileIds = new ArrayList(profileOptionsMap.keySet()); + for (Iterator I = profileIds.iterator(); I.hasNext(); ) { + String profileId = (String) I.next(); + ProfileOptions po = (ProfileOptions) profileOptionsMap.get(profileId); + + set(SCD + profileId + DOT + ENABLED, !useDefaults); + set(SCD + profileId + BUILD_OUTPUT_OPEN_ACTION_ENABLED, po.buildOutputFileActionEnabled); + set(SCD + profileId + BUILD_OUTPUT_OPEN_ACTION_FILE_PATH, po.buildOutputFilePath); + set(SCD + profileId + BUILD_OUTPUT_PARSER_ENABLED, po.buildOutputParserEnabled); + + ScannerConfigProfile configuredProfile = ScannerConfigProfileManager.getInstance(). + getSCProfileConfiguration(profileId); + List providerIds = configuredProfile.getSIProviderIds(); + for (int i = 0; i < providerIds.size(); ++i) { + String providerId = (String) providerIds.get(i); + ProfileOptions.ProviderOptions ppo = (ProfileOptions.ProviderOptions) + po.providerOptionsMap.get(providerId); + + set(SCD + profileId + DOT + providerId + SI_PROVIDER_PARSER_ENABLED, + ppo.providerOutputParserEnabled); +// String providerKind = configuredProfile.getScannerInfoProviderElement( +// providerId).getProviderKind(); + String providerKind = ppo.providerKind; + + if (providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.RUN)) { + set(SCD + profileId + DOT + providerId + SI_PROVIDER_RUN_ACTION_USE_DEFAULT, + ppo.providerRunUseDefault); + set(SCD + profileId + DOT + providerId + SI_PROVIDER_RUN_ACTION_COMMAND, + ppo.providerRunCommand); + set(SCD + profileId + DOT + providerId + SI_PROVIDER_RUN_ACTION_ARGUMENTS, + ppo.providerRunArguments); + } + else if (providerKind.equals(ScannerConfigProfile.ScannerInfoProvider.OPEN)) { + set(SCD + profileId + DOT + providerId + SI_PROVIDER_OPEN_ACTION_FILE_PATH, + ppo.providerOpenFilePath); + } + } + } + + isDirty = false; + } + } + + private boolean getBoolean(String name) { + if (useDefaults) { + return prefs.getDefaultBoolean(name); + } + return prefs.getBoolean(name); + } + private void set(String name, boolean value) { + if (useDefaults) { + prefs.setDefault(name, value); + } + else { + prefs.setValue(name, value); + } + } + + private String getString(String name) { + if (useDefaults) { + return prefs.getDefaultString(name); + } + return prefs.getString(name); + } + private void set(String name, String value) { + if (useDefaults) { + prefs.setDefault(name, value); + } + else { + prefs.setValue(name, value); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2#save() + */ + public void save() throws CoreException { + store(); + } + + } + + public static IScannerConfigBuilderInfo2 create(IProject project, String profileId) throws CoreException { + IScannerConfigBuilderInfo2Set container = createInfoSet(project, profileId); + return container.getInfo(new InfoContext(project)); + } + + public static IScannerConfigBuilderInfo2 create(Preferences prefs, String profileId, boolean useDefaults) { + return new ScannerConfigInfoFactory2.Preference(prefs, profileId, useDefaults); + } + + public static IScannerConfigBuilderInfo2Set createInfoSet(IProject project, String profileId){ + return new ScannerConfigInfoFactory2.ScannerConfigInfoSet(project, profileId); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigProfile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigProfile.java new file mode 100644 index 00000000000..cee6b1ebad1 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigProfile.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.InfoContext; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigScope; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; + + +/** + * SCD Profile extension point object model + * + * @author vhirsl + */ +public class ScannerConfigProfile { + /** + * scannerInfoCollector element + * + * @author vhirsl + */ + public class ScannerInfoCollector { + private IConfigurationElement configElem; + + public ScannerInfoCollector(IConfigurationElement configElem) { + this.configElem = configElem; + } + public Object createScannerInfoCollector() { + try { + return configElem.createExecutableExtension("class"); //$NON-NLS-1$ + } catch (CoreException e) { + MakeCorePlugin.log(e); + return null; + } + } + public String getScope() { + return configElem.getAttribute("scope"); //$NON-NLS-1$ + } + } + /** + * scannerInfoConsoleParser element + * + * @author vhirsl + */ + public final class ScannerInfoConsoleParser { + private IConfigurationElement configElem; + + /** + * @param scannerInfoConsoleParser + */ + public ScannerInfoConsoleParser(IConfigurationElement configElem) { + this.configElem = configElem; + } + public Object createScannerInfoConsoleParser() { + try { + return configElem.createExecutableExtension("class"); //$NON-NLS-1$ + } catch (CoreException e) { + MakeCorePlugin.log(e); + return null; + } + } + public String getCompilerCommands() { + return configElem.getAttribute("compilerCommands"); //$NON-NLS-1$ + } + } + /** + * tag interface, a placeholder for either run or open element + * + * @author vhirsl + */ + protected abstract class Action { + protected IConfigurationElement configElem; + + protected Action(IConfigurationElement configElem) { + this.configElem = configElem; + } + + public Object createExternalScannerInfoProvider() { + if (configElem.getAttribute("class") != null) { //$NON-NLS-1$ + try { + return configElem.createExecutableExtension("class"); //$NON-NLS-1$ + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + return null; + } + + public String getAttribute(String name) { + return configElem.getAttribute(name); + } + } + /** + * run element + * + * @author vhirsl + */ + public final class Run extends Action { + /** + * @param run + */ + public Run(IConfigurationElement run) { + super(run); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager.IAction#getNewExternalScannerInfoProvider() + */ + public Object createExternalScannerInfoProvider() { + Object provider = super.createExternalScannerInfoProvider(); + if (provider == null) { + // use the default one + provider = new DefaultRunSIProvider(); + } + return provider; + } + } + /** + * open element + * + * @author vhirsl + */ + public final class Open extends Action { + /** + * @param open + */ + public Open(IConfigurationElement open) { + super(open); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager.IAction#getNewExternalScannerInfoProvider() + */ + public Object createExternalScannerInfoProvider() { + Object provider = super.createExternalScannerInfoProvider(); + if (provider == null) { + // use the default one + provider = new DefaultSIFileReader(); + } + return provider; + } + } + /** + * buildOutputProvider element + * + * @author vhirsl + */ + public final class BuildOutputProvider { + private Open openFileAction; + private ScannerInfoConsoleParser scannerInfoConsoleParser; + + public BuildOutputProvider(IConfigurationElement provider) { + IConfigurationElement[] actions = provider.getChildren("open"); //$NON-NLS-1$ + // take the first one + if (actions.length > 0) { + this.openFileAction = new ScannerConfigProfile.Open(actions[0]); + } + IConfigurationElement[] parsers = provider.getChildren("scannerInfoConsoleParser"); //$NON-NLS-1$ + // take the first one + this.scannerInfoConsoleParser = new ScannerConfigProfile.ScannerInfoConsoleParser(parsers[0]); + } + + public Action getAction() { + return openFileAction; + } + public ScannerInfoConsoleParser getScannerInfoConsoleParser() { + return scannerInfoConsoleParser; + } + } + /** + * scannerInfoProvider element + * + * @author vhirsl + */ + public final class ScannerInfoProvider { + public static final String RUN = "run";//$NON-NLS-1$ + public static final String OPEN = "open";//$NON-NLS-1$ + + private String providerId; + private String providerKind; // derived attribute + private Action action; + private ScannerInfoConsoleParser scannerInfoConsoleParser; + + public ScannerInfoProvider(IConfigurationElement provider) { + providerId = provider.getAttribute("providerId"); //$NON-NLS-1$ + IConfigurationElement[] actions = provider.getChildren(); + providerKind = actions[0].getName(); + if (providerKind.equals(RUN)) { + this.action = new ScannerConfigProfile.Run(actions[0]); + } + else if (providerKind.equals(OPEN)) { //$NON-NLS-1$ + this.action = new ScannerConfigProfile.Open(actions[0]); + } + else { + // TODO Vmir generate an error + } + IConfigurationElement[] parsers = provider.getChildren("scannerInfoConsoleParser"); //$NON-NLS-1$ + // take the first one + scannerInfoConsoleParser = new ScannerConfigProfile.ScannerInfoConsoleParser(parsers[0]); + } + + public String getProviderId() { + return providerId; + } + public String getProviderKind() { + return providerKind; + } + public Action getAction() { + return action; + } + public ScannerInfoConsoleParser getScannerInfoConsoleParser() { + return scannerInfoConsoleParser; + } + } + + // ScannerConfigProfile members + private final String id; + + private ScannerInfoCollector scannerInfoCollector; + private BuildOutputProvider buildOutputProvider; + private Map scannerInfoProviders = new LinkedHashMap(); + + private Boolean supportsContext; + + /** + * @param profileId + */ + public ScannerConfigProfile(String profileId) { + id = profileId; + load(); + } + /** + * loads the profile from the manifest file. + */ + private void load() { + IExtensionPoint extension = Platform.getExtensionRegistry(). + getExtensionPoint(MakeCorePlugin.PLUGIN_ID, ScannerConfigProfileManager.SI_PROFILE_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + for (int i = 0; i < extensions.length; ++i) { + String rProfileId = extensions[i].getUniqueIdentifier(); + if (rProfileId != null && rProfileId.equals(getId())) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + for (int j = 0; j < configElements.length; ++j) { + String name = configElements[j].getName(); + if (scannerInfoCollector == null && + name.equals("scannerInfoCollector")) { //$NON-NLS-1$ + scannerInfoCollector = new ScannerConfigProfile.ScannerInfoCollector(configElements[j]); + } + else if (name.equals("buildOutputProvider")) { //$NON-NLS-1$ + buildOutputProvider = new ScannerConfigProfile.BuildOutputProvider(configElements[j]); + } + else if (name.equals("scannerInfoProvider")) { //$NON-NLS-1$ + String providerId = configElements[j].getAttribute("providerId"); //$NON-NLS-1$ + if (providerId != null && scannerInfoProviders.get(providerId) == null) { + scannerInfoProviders.put(providerId, + new ScannerConfigProfile.ScannerInfoProvider(configElements[j])); + } + } + } + break; + } + } + } + } + /** + * @return Returns the id. + */ + public String getId() { + return id; + } + + // access to model objects + /** + * @return Returns the list of providerIds + */ + public List getSIProviderIds() { + return new ArrayList(scannerInfoProviders.keySet()); + } + /** + * @return Returns the buildOutputProvider. + */ + public BuildOutputProvider getBuildOutputProviderElement() { + return buildOutputProvider; + } + /** + * @return Returns the scannerInfoCollector. + */ + public ScannerInfoCollector getScannerInfoCollectorElement() { + return scannerInfoCollector; + } + + public ScannerConfigScope getProfileScope() { + ScannerConfigScope scope = null; + if (scannerInfoCollector != null) { + if (scannerInfoCollector.getScope().equals(ScannerConfigScope.PROJECT_SCOPE.toString())) { + scope = ScannerConfigScope.PROJECT_SCOPE; + } + else if (scannerInfoCollector.getScope().equals(ScannerConfigScope.FILE_SCOPE.toString())) { + scope = ScannerConfigScope.FILE_SCOPE; + } + } + return scope; + } + + /** + * @return Returns the scannerInfoProviders. + */ + public ScannerInfoProvider getScannerInfoProviderElement(String providerId) { + return (ScannerInfoProvider) scannerInfoProviders.get(providerId); + } + + public boolean supportsContext(){ + if(supportsContext == null){ + ScannerInfoCollector cr = getScannerInfoCollectorElement(); + if(cr != null){ + Object o = cr.createScannerInfoCollector(); + if(o != null){ + Class clazz = o.getClass(); + try { + clazz.getMethod("setInfoContext", new Class[] {InfoContext.class}); //$NON-NLS-1$ + supportsContext = Boolean.TRUE; + } catch (SecurityException e) { + } catch (NoSuchMethodException e) { + } + } + } + + if(supportsContext == null) + supportsContext = Boolean.FALSE; + } + return supportsContext.booleanValue(); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigProfileManager.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigProfileManager.java new file mode 100644 index 00000000000..3332cf09eab --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/ScannerConfigProfileManager.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * 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.scannerconfig2; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.InfoContext; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Preferences; + +/** + * Manages profiles per project + * + * @author vhirsl + */ +public class ScannerConfigProfileManager { + public static final String SI_PROFILE_SIMPLE_ID = "ScannerConfigurationDiscoveryProfile"; //$NON-NLS-1$ + public static final String PER_PROJECT_PROFILE_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCStandardMakePerProjectProfile"; //$NON-NLS-1$ + public static final String DEFAULT_SI_PROFILE_ID = PER_PROJECT_PROFILE_ID; + public static final String NULL_PROFILE_ID = "";//$NON-NLS-1$ + + private Map projectToProfileInstanceMap; + private List profileIds; + private List contextAwareProfileIds; + + /** + * Singleton pattern + */ + private ScannerConfigProfileManager() { + projectToProfileInstanceMap = new HashMap(); + } + private static ScannerConfigProfileManager instance = null; + + public static ScannerConfigProfileManager getInstance() { + if (instance == null) { + instance = new ScannerConfigProfileManager(); + } + return instance; + } + + private String getProfileId(IProject project, InfoContext context) { + String profileId; + try { + IScannerConfigBuilderInfo2Set container = createScannerConfigBuildInfo2Set(project); + IScannerConfigBuilderInfo2 buildInfo = container.getInfo(context); + profileId = buildInfo.getSelectedProfileId(); + } catch (CoreException e) { + MakeCorePlugin.log(e); + profileId = DEFAULT_SI_PROFILE_ID; + } + return profileId; + } + + /** + * For projects that do not have profile id specified in .project file. + * For example managed projects. + * @param project + * @param profile + */ + public void addProfile(IProject project, ScannerConfigProfile profile) { + addProfile(project, new InfoContext(project), profile); + } + + public void addProfile(IProject project, InfoContext context, ScannerConfigProfile profile) { + getProfileMap(project, true).put(context, profile); + } + + private Map getProfileMap(IProject project, boolean create){ + Map map = (Map)projectToProfileInstanceMap.get(project); + if(map == null && create){ + map = new HashMap(); + projectToProfileInstanceMap.put(project, map); + } + return map; + } + + /** + * @param project + * @param profileId - if null, get the one associated with the project + * @return Returns the scannerConfigProfile instance for a project. + */ + public SCProfileInstance getSCProfileInstance(IProject project, String profileId) { + return getSCProfileInstance(project, new InfoContext(project), profileId); + } + + public SCProfileInstance getSCProfileInstance(IProject project, InfoContext context, String profileId) { + + // if not specified read from .project file + if (profileId == NULL_PROFILE_ID) { + profileId = getProfileId(project, context); + } + // is the project's profile already loaded? + Map map = getProfileMap(project, true); + SCProfileInstance profileInstance = (SCProfileInstance) map.get(context); + if (profileInstance == null || !profileInstance.getProfile().getId().equals(profileId)) { + profileInstance = new SCProfileInstance(project, context, getSCProfileConfiguration(profileId)); + map.put(context, profileInstance); + } + return profileInstance; + } + + /** + * @param profileId + * @return + */ + public SCProfileInstance getSCProfileInstance(String profileId) { + SCProfileInstance profileInstance = null; + if (profileId != NULL_PROFILE_ID) { + profileInstance = new SCProfileInstance(null, getSCProfileConfiguration(profileId)); + } + return profileInstance; + } + + /** + * @param profileId - if null, get the default one + * @return Returns the scannerConfigProfile for a project. + */ + public ScannerConfigProfile getSCProfileConfiguration(String profileId) { + profileId = (profileId == NULL_PROFILE_ID) ? getDefaultSIProfileId() : profileId; + return new ScannerConfigProfile(profileId); + } + + /** + * @return + */ + public List getProfileIds() { + if (profileIds == null) { + profileIds = new ArrayList(); + IExtensionPoint extension = Platform.getExtensionRegistry(). + getExtensionPoint(MakeCorePlugin.PLUGIN_ID, ScannerConfigProfileManager.SI_PROFILE_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + for (int i = 0; i < extensions.length; ++i) { + String rProfileId = extensions[i].getUniqueIdentifier(); + profileIds.add(rProfileId); + } + } + } + return profileIds; + } + + /** + * returns the list od profile IDs supported for this context + * @param context + * @return + */ + public List getProfileIds(InfoContext context){ + if(context.isDefaultContext() || context.getProject() == null) + return getProfileIds(); + + if(contextAwareProfileIds == null){ + contextAwareProfileIds = new ArrayList(); + List all = getProfileIds(); + + for(int i = 0; i < all.size(); i++){ + String id = (String)all.get(i); + ScannerConfigProfile profile = getSCProfileConfiguration(id); + if(profile.supportsContext()) + contextAwareProfileIds.add(id); + } + } + + return contextAwareProfileIds; + } + + /** + * @return default profile id + */ + public static String getDefaultSIProfileId() { + return DEFAULT_SI_PROFILE_ID; + } + + /** + * Set selectedProfile to profileId + * @param project + * @param profileId + * @return + * @throws CoreException + */ + public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(IProject project, String profileId) throws CoreException { + return ScannerConfigInfoFactory2.create(project, profileId); + } + + /** + * Use stored selectedProfile + * @param project + * @return + * @throws CoreException + */ + public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(IProject project) throws CoreException { + return ScannerConfigInfoFactory2.create(project, ScannerConfigProfileManager.NULL_PROFILE_ID); + } + + public static IScannerConfigBuilderInfo2Set createScannerConfigBuildInfo2Set(IProject project) throws CoreException { + return ScannerConfigInfoFactory2.createInfoSet(project, ScannerConfigProfileManager.NULL_PROFILE_ID); + } + + public static IScannerConfigBuilderInfo2Set createScannerConfigBuildInfo2Set(IProject project, String profileId) throws CoreException { + return ScannerConfigInfoFactory2.createInfoSet(project, profileId); + } + + /** + * Set selectedProfile to profileId + * @param prefs + * @param profileId + * @param useDefaults + * @return + */ + public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(Preferences prefs, String profileId, boolean useDefaults) { + return ScannerConfigInfoFactory2.create(prefs, profileId, useDefaults); + } + + /** + * Use stored selectedProfile + * @param prefs + * @param useDefaults + * @return + */ + public static IScannerConfigBuilderInfo2 createScannerConfigBuildInfo2(Preferences prefs, boolean useDefaults) { + return ScannerConfigInfoFactory2.create(prefs, ScannerConfigProfileManager.NULL_PROFILE_ID, useDefaults); + } + +} |