diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml index 3e8cb09b74c..4a2d6a5be88 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml @@ -1,6123 +1,6123 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java index b8193aee547..508703ababc 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java @@ -1,67 +1,67 @@ -/******************************************************************************* - * 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.managedbuilder.tests.suite; - -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests20; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests_SharedToolOptions; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildEnvironmentTests; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildMacrosTests; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildDependencyCalculatorTests; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildTCSupportedTest; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedCommandLineGeneratorTest; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedProject21MakefileTests; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedProject30MakefileTests; -import org.eclipse.cdt.managedbuilder.core.tests.ManagedProjectUpdateTests; -import org.eclipse.cdt.managedbuilder.core.tests.MultiVersionSupportTests; -import org.eclipse.cdt.managedbuilder.core.tests.OptionEnablementTests; -import org.eclipse.cdt.managedbuilder.core.tests.ResourceBuildCoreTests; - -/** - * - */ -public class AllManagedBuildTests { - public static void main(String[] args) { - CCorePlugin.getDefault().getCoreModel().getIndexManager().reset(); - junit.textui.TestRunner.run(AllManagedBuildTests.suite()); - } - public static Test suite() { - // May/2005 Turning off all indexing for now because the "original" indexer causes hangs... - CCorePlugin.getDefault().getPluginPreferences().setValue(CCorePlugin.PREF_INDEXER, CCorePlugin.NULL_INDEXER_UNIQUE_ID); - // We could enable this later... - //CCorePlugin.getDefault().getPluginPreferences().setValue(CCorePlugin.PREF_INDEXER, "org.eclipse.cdt.core.domsourceindexer"); - - TestSuite suite = new TestSuite( - "Test for org.eclipse.cdt.managedbuild.core.tests"); - //$JUnit-BEGIN$ -// TODO uncoment this - suite.addTest(ManagedBuildCoreTests20.suite()); - suite.addTest(ManagedBuildCoreTests.suite()); - suite.addTest(ManagedProjectUpdateTests.suite()); - suite.addTest(ManagedCommandLineGeneratorTest.suite()); - suite.addTest(ResourceBuildCoreTests.suite()); - suite.addTest(ManagedProject21MakefileTests.suite()); - suite.addTest(ManagedProject30MakefileTests.suite()); - suite.addTest(ManagedBuildCoreTests_SharedToolOptions.suite()); - suite.addTest(ManagedBuildEnvironmentTests.suite()); - suite.addTest(ManagedBuildMacrosTests.suite()); - suite.addTest(ManagedBuildTCSupportedTest.suite()); - suite.addTest(MultiVersionSupportTests.suite()); - suite.addTest(OptionEnablementTests.suite()); - suite.addTest(ManagedBuildDependencyCalculatorTests.suite()); - //$JUnit-END$ - return suite; - } -} +/******************************************************************************* + * 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.managedbuilder.tests.suite; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests20; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests_SharedToolOptions; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildEnvironmentTests; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildMacrosTests; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildDependencyCalculatorTests; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildTCSupportedTest; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedCommandLineGeneratorTest; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedProject21MakefileTests; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedProject30MakefileTests; +import org.eclipse.cdt.managedbuilder.core.tests.ManagedProjectUpdateTests; +import org.eclipse.cdt.managedbuilder.core.tests.MultiVersionSupportTests; +import org.eclipse.cdt.managedbuilder.core.tests.OptionEnablementTests; +import org.eclipse.cdt.managedbuilder.core.tests.ResourceBuildCoreTests; + +/** + * + */ +public class AllManagedBuildTests { + public static void main(String[] args) { + CCorePlugin.getDefault().getCoreModel().getIndexManager().reset(); + junit.textui.TestRunner.run(AllManagedBuildTests.suite()); + } + public static Test suite() { + // May/2005 Turning off all indexing for now because the "original" indexer causes hangs... + CCorePlugin.getDefault().getPluginPreferences().setValue(CCorePlugin.PREF_INDEXER, CCorePlugin.NULL_INDEXER_UNIQUE_ID); + // We could enable this later... + //CCorePlugin.getDefault().getPluginPreferences().setValue(CCorePlugin.PREF_INDEXER, "org.eclipse.cdt.core.domsourceindexer"); + + TestSuite suite = new TestSuite( + "Test for org.eclipse.cdt.managedbuild.core.tests"); + //$JUnit-BEGIN$ +// TODO uncoment this + suite.addTest(ManagedBuildCoreTests20.suite()); + suite.addTest(ManagedBuildCoreTests.suite()); + suite.addTest(ManagedProjectUpdateTests.suite()); + suite.addTest(ManagedCommandLineGeneratorTest.suite()); + suite.addTest(ResourceBuildCoreTests.suite()); + suite.addTest(ManagedProject21MakefileTests.suite()); + suite.addTest(ManagedProject30MakefileTests.suite()); + suite.addTest(ManagedBuildCoreTests_SharedToolOptions.suite()); + suite.addTest(ManagedBuildEnvironmentTests.suite()); + suite.addTest(ManagedBuildMacrosTests.suite()); + suite.addTest(ManagedBuildTCSupportedTest.suite()); + suite.addTest(MultiVersionSupportTests.suite()); + suite.addTest(OptionEnablementTests.suite()); + suite.addTest(ManagedBuildDependencyCalculatorTests.suite()); + //$JUnit-END$ + return suite; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyCalculatorTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyCalculatorTests.java index 9dca2b35ef4..dc022112e4d 100755 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyCalculatorTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyCalculatorTests.java @@ -1,240 +1,240 @@ -/******************************************************************************* - * Copyright (c) 2006 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 - *******************************************************************************/ - -/********************************************************************** - * These tests are for the default dependency calculators - **********************************************************************/ - -package org.eclipse.cdt.managedbuilder.core.tests; - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.projectconverter.UpdateManagedProjectManager; -import org.eclipse.cdt.managedbuilder.testplugin.CTestPlugin; -import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.ui.dialogs.IOverwriteQuery; - -public class ManagedBuildDependencyCalculatorTests extends TestCase { - - public ManagedBuildDependencyCalculatorTests(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(ManagedBuildDependencyCalculatorTests.class.getName()); - - suite.addTest(new ManagedBuildDependencyCalculatorTests("test1DepCalc2")); - suite.addTest(new ManagedBuildDependencyCalculatorTests("test1DepCalc3")); - suite.addTest(new ManagedBuildDependencyCalculatorTests("test1DepCalcPreBuild")); - return suite; - } - - private IProject[] createProject(String projName, IPath location, String projectTypeId, boolean containsZip){ - ArrayList projectList = null; - if (containsZip) { - File testDir = CTestPlugin.getFileInPlugin(new Path("resources/depCalcProjects/" + projName)); - if(testDir == null) { - fail("Test project directory " + projName + " is missing."); - return null; - } - - File projectZips[] = testDir.listFiles(new FileFilter(){ - public boolean accept(File pathname){ - if(pathname.isDirectory()) - return false; - return true; - } - }); - - projectList = new ArrayList(projectZips.length); - for(int i = 0; i < projectZips.length; i++){ - try{ - String projectName = projectZips[i].getName(); - if(!projectName.endsWith(".zip")) - continue; - - projectName = projectName.substring(0,projectName.length()-".zip".length()); - if(projectName.length() == 0) - continue; - IProject project = ManagedBuildTestHelper.createProject(projectName, projectZips[i], location, projectTypeId); - if(project != null) - projectList.add(project); - } - catch(Exception e){ - } - } - if(projectList.size() == 0) { - fail("No projects found in test project directory " + testDir.getName() + ". The .zip file may be missing or corrupt."); - return null; - } - } else { - try{ - IProject project = ManagedBuildTestHelper.createProject(projName, null, location, projectTypeId); - if(project != null) - projectList = new ArrayList(1); - projectList.add(project); - } catch(Exception e){} - } - - return (IProject[])projectList.toArray(new IProject[projectList.size()]); - } - - private IProject[] createProjects(String projName, IPath location, String projectTypeId, boolean containsZip) { - - // In case the projects need to be updated... - IOverwriteQuery queryALL = new IOverwriteQuery(){ - public String queryOverwrite(String file) { - return ALL; - }}; - IOverwriteQuery queryNOALL = new IOverwriteQuery(){ - public String queryOverwrite(String file) { - return NO_ALL; - }}; - - UpdateManagedProjectManager.setBackupFileOverwriteQuery(queryALL); - UpdateManagedProjectManager.setUpdateProjectQuery(queryALL); - - IProject projects[] = createProject(projName, location, projectTypeId, containsZip); - return projects; - } - - private void buildProjectsWorker(IProject projects[], IPath[] files, boolean compareBenchmark) { - if(projects == null || projects.length == 0) - return; - - boolean succeeded = true; - for (int i = 0; i < projects.length; i++){ - IProject curProject = projects[i]; - - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(curProject); - - //check whether the managed build info is converted - boolean isCompatible = UpdateManagedProjectManager.isCompatibleProject(info); - assertTrue(isCompatible); - - if (isCompatible){ - // Build the project in order to generate the makefiles - try{ - curProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD,null); - } - catch(CoreException e){ - fail(e.getStatus().getMessage()); - } - catch(OperationCanceledException e){ - fail("the project \"" + curProject.getName() + "\" build was cancelled, exception message: " + e.getMessage()); - } - - //compare the generated makefiles to their benchmarks - if (files != null && files.length > 0) { - if (i == 0) { - String configName = info.getDefaultConfiguration().getName(); - IPath buildDir = Path.fromOSString(configName); - if (compareBenchmark) - succeeded = ManagedBuildTestHelper.compareBenchmarks(curProject, buildDir, files); - else - succeeded = ManagedBuildTestHelper.verifyFilesDoNotExist(curProject, buildDir, files); - } - } - } - } - - if (succeeded) { // Otherwise leave the projects around for comparison - for (int i = 0; i < projects.length; i++) - ManagedBuildTestHelper.removeProject(projects[i].getName()); - } - } - - // Build projects and compare benchmarks - private void buildProjects(IProject projects[], IPath[] files) { - buildProjectsWorker(projects, files, true); - } - - - /* (non-Javadoc) - * test for dependency calculation as a side-effect of compilation - */ - public void test1DepCalc2(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk"), - // This file is different using Cygwin vs GCC - //Path.fromOSString("main.d"), - Path.fromOSString("Sources/subdir.mk"), - Path.fromOSString("Sources/func1.d"), - Path.fromOSString("Sources/func2.d"), - Path.fromOSString("Sources/func4.d"), - Path.fromOSString("Sources/sub sources/func 3.d"), - Path.fromOSString("Sources/sub sources/subdir.mk")}; - IProject[] projects = createProjects("test1DepCalc2", null, null, true); - buildProjects(projects, makefiles); - } - - - /* (non-Javadoc) - * test for dependency calculation using Echo, a 2nd conmpilation step, and post-processing - */ - public void test1DepCalc3(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk"), - // This file is different using Cygwin vs GCC - //Path.fromOSString("main.d"), - Path.fromOSString("Sources/subdir.mk"), - Path.fromOSString("Sources/func1.d"), - Path.fromOSString("Sources/func2.d"), - Path.fromOSString("Sources/func4.d"), - Path.fromOSString("Sources/sub sources/func 3.d"), - Path.fromOSString("Sources/sub sources/subdir.mk")}; - IProject[] projects = createProjects("test1DepCalc3", null, null, true); - buildProjects(projects, makefiles); - } - - - /* (non-Javadoc) - * test for dependency calculation that uses a separate, pre-build, step to generate dependency files - */ - public void test1DepCalcPreBuild(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk"), - // This file is different using Cygwin vs GCC - //Path.fromOSString("main.d"), - Path.fromOSString("Sources/subdir.mk"), - Path.fromOSString("Sources/func1.d"), - Path.fromOSString("Sources/func2.d"), - Path.fromOSString("Sources/func4.d"), - Path.fromOSString("Sources/sub sources/func 3.d"), - Path.fromOSString("Sources/sub sources/subdir.mk")}; - IProject[] projects = createProjects("test1DepCalcPreBuild", null, null, true); - buildProjects(projects, makefiles); - } - +/******************************************************************************* + * Copyright (c) 2006 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 + *******************************************************************************/ + +/********************************************************************** + * These tests are for the default dependency calculators + **********************************************************************/ + +package org.eclipse.cdt.managedbuilder.core.tests; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.projectconverter.UpdateManagedProjectManager; +import org.eclipse.cdt.managedbuilder.testplugin.CTestPlugin; +import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.ui.dialogs.IOverwriteQuery; + +public class ManagedBuildDependencyCalculatorTests extends TestCase { + + public ManagedBuildDependencyCalculatorTests(String name) { + super(name); + } + + public static Test suite() { + TestSuite suite = new TestSuite(ManagedBuildDependencyCalculatorTests.class.getName()); + + suite.addTest(new ManagedBuildDependencyCalculatorTests("test1DepCalc2")); + suite.addTest(new ManagedBuildDependencyCalculatorTests("test1DepCalc3")); + suite.addTest(new ManagedBuildDependencyCalculatorTests("test1DepCalcPreBuild")); + return suite; + } + + private IProject[] createProject(String projName, IPath location, String projectTypeId, boolean containsZip){ + ArrayList projectList = null; + if (containsZip) { + File testDir = CTestPlugin.getFileInPlugin(new Path("resources/depCalcProjects/" + projName)); + if(testDir == null) { + fail("Test project directory " + projName + " is missing."); + return null; + } + + File projectZips[] = testDir.listFiles(new FileFilter(){ + public boolean accept(File pathname){ + if(pathname.isDirectory()) + return false; + return true; + } + }); + + projectList = new ArrayList(projectZips.length); + for(int i = 0; i < projectZips.length; i++){ + try{ + String projectName = projectZips[i].getName(); + if(!projectName.endsWith(".zip")) + continue; + + projectName = projectName.substring(0,projectName.length()-".zip".length()); + if(projectName.length() == 0) + continue; + IProject project = ManagedBuildTestHelper.createProject(projectName, projectZips[i], location, projectTypeId); + if(project != null) + projectList.add(project); + } + catch(Exception e){ + } + } + if(projectList.size() == 0) { + fail("No projects found in test project directory " + testDir.getName() + ". The .zip file may be missing or corrupt."); + return null; + } + } else { + try{ + IProject project = ManagedBuildTestHelper.createProject(projName, null, location, projectTypeId); + if(project != null) + projectList = new ArrayList(1); + projectList.add(project); + } catch(Exception e){} + } + + return (IProject[])projectList.toArray(new IProject[projectList.size()]); + } + + private IProject[] createProjects(String projName, IPath location, String projectTypeId, boolean containsZip) { + + // In case the projects need to be updated... + IOverwriteQuery queryALL = new IOverwriteQuery(){ + public String queryOverwrite(String file) { + return ALL; + }}; + IOverwriteQuery queryNOALL = new IOverwriteQuery(){ + public String queryOverwrite(String file) { + return NO_ALL; + }}; + + UpdateManagedProjectManager.setBackupFileOverwriteQuery(queryALL); + UpdateManagedProjectManager.setUpdateProjectQuery(queryALL); + + IProject projects[] = createProject(projName, location, projectTypeId, containsZip); + return projects; + } + + private void buildProjectsWorker(IProject projects[], IPath[] files, boolean compareBenchmark) { + if(projects == null || projects.length == 0) + return; + + boolean succeeded = true; + for (int i = 0; i < projects.length; i++){ + IProject curProject = projects[i]; + + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(curProject); + + //check whether the managed build info is converted + boolean isCompatible = UpdateManagedProjectManager.isCompatibleProject(info); + assertTrue(isCompatible); + + if (isCompatible){ + // Build the project in order to generate the makefiles + try{ + curProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD,null); + } + catch(CoreException e){ + fail(e.getStatus().getMessage()); + } + catch(OperationCanceledException e){ + fail("the project \"" + curProject.getName() + "\" build was cancelled, exception message: " + e.getMessage()); + } + + //compare the generated makefiles to their benchmarks + if (files != null && files.length > 0) { + if (i == 0) { + String configName = info.getDefaultConfiguration().getName(); + IPath buildDir = Path.fromOSString(configName); + if (compareBenchmark) + succeeded = ManagedBuildTestHelper.compareBenchmarks(curProject, buildDir, files); + else + succeeded = ManagedBuildTestHelper.verifyFilesDoNotExist(curProject, buildDir, files); + } + } + } + } + + if (succeeded) { // Otherwise leave the projects around for comparison + for (int i = 0; i < projects.length; i++) + ManagedBuildTestHelper.removeProject(projects[i].getName()); + } + } + + // Build projects and compare benchmarks + private void buildProjects(IProject projects[], IPath[] files) { + buildProjectsWorker(projects, files, true); + } + + + /* (non-Javadoc) + * test for dependency calculation as a side-effect of compilation + */ + public void test1DepCalc2(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk"), + // This file is different using Cygwin vs GCC + //Path.fromOSString("main.d"), + Path.fromOSString("Sources/subdir.mk"), + Path.fromOSString("Sources/func1.d"), + Path.fromOSString("Sources/func2.d"), + Path.fromOSString("Sources/func4.d"), + Path.fromOSString("Sources/sub sources/func 3.d"), + Path.fromOSString("Sources/sub sources/subdir.mk")}; + IProject[] projects = createProjects("test1DepCalc2", null, null, true); + buildProjects(projects, makefiles); + } + + + /* (non-Javadoc) + * test for dependency calculation using Echo, a 2nd conmpilation step, and post-processing + */ + public void test1DepCalc3(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk"), + // This file is different using Cygwin vs GCC + //Path.fromOSString("main.d"), + Path.fromOSString("Sources/subdir.mk"), + Path.fromOSString("Sources/func1.d"), + Path.fromOSString("Sources/func2.d"), + Path.fromOSString("Sources/func4.d"), + Path.fromOSString("Sources/sub sources/func 3.d"), + Path.fromOSString("Sources/sub sources/subdir.mk")}; + IProject[] projects = createProjects("test1DepCalc3", null, null, true); + buildProjects(projects, makefiles); + } + + + /* (non-Javadoc) + * test for dependency calculation that uses a separate, pre-build, step to generate dependency files + */ + public void test1DepCalcPreBuild(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk"), + // This file is different using Cygwin vs GCC + //Path.fromOSString("main.d"), + Path.fromOSString("Sources/subdir.mk"), + Path.fromOSString("Sources/func1.d"), + Path.fromOSString("Sources/func2.d"), + Path.fromOSString("Sources/func4.d"), + Path.fromOSString("Sources/sub sources/func 3.d"), + Path.fromOSString("Sources/sub sources/subdir.mk")}; + IProject[] projects = createProjects("test1DepCalcPreBuild", null, null, true); + buildProjects(projects, makefiles); + } + } \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java index 76a39889f96..216635fe185 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java @@ -1,624 +1,624 @@ -/******************************************************************************* - * Copyright (c) 2005 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 - *******************************************************************************/ - -/********************************************************************** - * These tests are for a 3.0 style tool integration. - **********************************************************************/ - -package org.eclipse.cdt.managedbuilder.core.tests; - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; -import java.util.Iterator; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.internal.core.Tool; -import org.eclipse.cdt.managedbuilder.internal.core.ToolChain; -import org.eclipse.cdt.managedbuilder.projectconverter.UpdateManagedProjectManager; -import org.eclipse.cdt.managedbuilder.testplugin.CTestPlugin; -import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; -import org.eclipse.core.resources.*; -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.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.ui.dialogs.IOverwriteQuery; - -public class ManagedProject30MakefileTests extends TestCase { - public static final String MBS_TEMP_DIR = "MBSTemp"; - - static boolean pathVariableCreated = false; - - public ManagedProject30MakefileTests(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(ManagedProject30MakefileTests.class.getName()); - - suite.addTest(new ManagedProject30MakefileTests("test30SingleFileExe")); - suite.addTest(new ManagedProject30MakefileTests("test30TwoFileSO")); - suite.addTest(new ManagedProject30MakefileTests("test30MultiResConfig")); - suite.addTest(new ManagedProject30MakefileTests("test30LinkedLib")); - // TODO: testLinkedFolder fails intermittently saying that it cannot find - // the makefiles to compare. This appears to be a test set issue, - // rather than an MBS functionality issue - //suite.addTest(new ManagedProject30MakefileTests("test30LinkedFolder")); - suite.addTest(new ManagedProject30MakefileTests("test30CopyandDeploy")); - suite.addTest(new ManagedProject30MakefileTests("test30DeleteFile")); - suite.addTest(new ManagedProject30MakefileTests("test30NoFilesToBuild")); - suite.addTest(new ManagedProject30MakefileTests("testFileWithNoExtension")); - suite.addTest(new ManagedProject30MakefileTests("testPreAndPostProcessBuildSteps")); - suite.addTest(new ManagedProject30MakefileTests("testResourceCustomBuildStep")); - suite.addTest(new ManagedProject30MakefileTests("test30_1")); - suite.addTest(new ManagedProject30MakefileTests("test30_2")); - suite.addTest(new ManagedProject30MakefileTests("testTopTC")); - suite.addTest(new ManagedProject30MakefileTests("CDTFortranTest1")); - suite.addTest(new ManagedProject30MakefileTests("CDTFortranTest2")); - suite.addTest(new ManagedProject30MakefileTests("TestATO")); - suite.addTest(new ManagedProject30MakefileTests("testMacroSupportInBuildDefinitions")); - suite.addTest(new ManagedProject30MakefileTests("testSpaces")); - return suite; - } - - private IProject[] createProject(String projName, IPath location, String projectTypeId, boolean containsZip){ - ArrayList projectList = null; - if (containsZip) { - File testDir = CTestPlugin.getFileInPlugin(new Path("resources/test30Projects/" + projName)); - if(testDir == null) { - fail("Test project directory " + projName + " is missing."); - return null; - } - - File projectZips[] = testDir.listFiles(new FileFilter(){ - public boolean accept(File pathname){ - if(pathname.isDirectory()) - return false; - return true; - } - }); - - projectList = new ArrayList(projectZips.length); - for(int i = 0; i < projectZips.length; i++){ - try{ - String projectName = projectZips[i].getName(); - if(!projectName.endsWith(".zip")) - continue; - - projectName = projectName.substring(0,projectName.length()-".zip".length()); - if(projectName.length() == 0) - continue; - IProject project = ManagedBuildTestHelper.createProject(projectName, projectZips[i], location, projectTypeId); - if(project != null) - projectList.add(project); - } - catch(Exception e){ - } - } - if(projectList.size() == 0) { - fail("No projects found in test project directory " + testDir.getName() + ". The .zip file may be missing or corrupt."); - return null; - } - } else { - try{ - IProject project = ManagedBuildTestHelper.createProject(projName, null, location, projectTypeId); - if(project != null) - projectList = new ArrayList(1); - projectList.add(project); - } catch(Exception e){} - } - - return (IProject[])projectList.toArray(new IProject[projectList.size()]); - } - - private IProject[] createProjects(String projName, IPath location, String projectTypeId, boolean containsZip) { - - // In case the projects need to be updated... - IOverwriteQuery queryALL = new IOverwriteQuery(){ - public String queryOverwrite(String file) { - return ALL; - }}; - IOverwriteQuery queryNOALL = new IOverwriteQuery(){ - public String queryOverwrite(String file) { - return NO_ALL; - }}; - - UpdateManagedProjectManager.setBackupFileOverwriteQuery(queryALL); - UpdateManagedProjectManager.setUpdateProjectQuery(queryALL); - - IProject projects[] = createProject(projName, location, projectTypeId, containsZip); - return projects; - } - - private void buildProjectsWorker(IProject projects[], IPath[] files, boolean compareBenchmark) { - if(projects == null || projects.length == 0) - return; - - boolean succeeded = true; - for (int i = 0; i < projects.length; i++){ - IProject curProject = projects[i]; - - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(curProject); - - //check whether the managed build info is converted - boolean isCompatible = UpdateManagedProjectManager.isCompatibleProject(info); - assertTrue(isCompatible); - - if (isCompatible){ - // Build the project in order to generate the makefiles - try{ - curProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD,null); - } - catch(CoreException e){ - fail(e.getStatus().getMessage()); - } - catch(OperationCanceledException e){ - fail("the project \"" + curProject.getName() + "\" build was cancelled, exception message: " + e.getMessage()); - } - - //compare the generated makefiles to their benchmarks - if (files != null && files.length > 0) { - if (i == 0) { - String configName = info.getDefaultConfiguration().getName(); - IPath buildDir = Path.fromOSString(configName); - if (compareBenchmark) - succeeded = ManagedBuildTestHelper.compareBenchmarks(curProject, buildDir, files); - else - succeeded = ManagedBuildTestHelper.verifyFilesDoNotExist(curProject, buildDir, files); - } - } - } - } - - if (succeeded) { // Otherwise leave the projects around for comparison - for (int i = 0; i < projects.length; i++) - ManagedBuildTestHelper.removeProject(projects[i].getName()); - } - } - - // Build projects and compare benchmarks - private void buildProjects(IProject projects[], IPath[] files) { - buildProjectsWorker(projects, files, true); - } - - // Build projects but don't compare benchmarks because there should be not build files generated - private void buildDegenerativeProjects(IProject projects[], IPath[] files) { - buildProjectsWorker(projects, files, false); - } - - private void createPathVariable(IPath tmpDir) { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - workspace = ResourcesPlugin.getWorkspace(); - IPathVariableManager pathMan = workspace.getPathVariableManager(); - String name = MBS_TEMP_DIR; - try { - if (pathMan.validateName(name).isOK() && pathMan.validateValue(tmpDir).isOK()) { - pathMan.setValue(name, tmpDir); - assertTrue(pathMan.isDefined(name)); - } else { - fail("could not create the path variable " + name); - } - } catch (Exception e) {fail("could not create the path variable " + name);} - } - - private void createFileLink(IProject project, IPath tmpDir, String linkName, String fileName) { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - String name = MBS_TEMP_DIR; - if (!pathVariableCreated) { - createPathVariable(tmpDir); - pathVariableCreated = true; - } - - try { - // Now we can create a linked resource relative to the defined path variable: - IFile linkF1 = project.getFile(linkName); - IPath location = new Path("MBSTemp/" + fileName); - if (workspace.validateLinkLocation(linkF1, location).isOK()) { - linkF1.createLink(location, IResource.NONE, null); - } else { - fail("could not create the link to " + name); - } - } catch (Exception e) {fail("could not create the link to " + name);} - } - - /* (non-Javadoc) - * tests 3.0 style tool integration for a single file executable - */ - public void test30SingleFileExe(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk")}; - IProject[] projects = createProjects("singleFileExe", null, null, true); - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 style tool integration for a two file SO - */ - public void test30TwoFileSO(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk")}; - IProject[] projects = createProjects("twoFileSO", null, null, true); - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 style tool integration for multiple source files & a resource configuration - */ - public void test30MultiResConfig(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("main.d"), - Path.fromOSString("source1/subdir.mk"), - Path.fromOSString("source1/Class1.d"), - Path.fromOSString("source2/subdir.mk"), - Path.fromOSString("source2/Class2.d"), - Path.fromOSString("source2/source21/Class21.d"), - Path.fromOSString("source2/source21/subdir.mk")}; - IProject[] projects = createProjects("multiResConfig", null, null, true); - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 style tool integration for linked files - */ - public void test30LinkedLib(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - //Path.fromOSString("subdir.mk") // Can't compare this yet since it contains absolute paths! - Path.fromOSString("sources.mk")}; - IPath[] linkedFiles = { - Path.fromOSString("f1.c"), - Path.fromOSString("f2.c"), - Path.fromOSString("test_ar.h")}; - File srcDirFile = CTestPlugin.getFileInPlugin(new Path("resources/test30Projects/linkedLib/")); - IPath srcDir = Path.fromOSString(srcDirFile.toString()); - IPath tmpSubDir = Path.fromOSString("CDTMBSTest"); - IPath tmpDir = ManagedBuildTestHelper.copyFilesToTempDir(srcDir, tmpSubDir, linkedFiles); - try { - IProject[] projects = createProjects("linkedLib", null, "cdt.managedbuild.target.gnu30.lib", true); - // There should be only one project. Add our linked files to it. - IProject project = projects[0]; - createFileLink(project, tmpDir, "f1.c", "f1.c"); - createFileLink(project, tmpDir, "f2link.c", "f2.c"); - createFileLink(project, tmpDir, "test_ar.h", "test_ar.h"); - // Build the project - buildProjects(projects, makefiles); - } finally {ManagedBuildTestHelper.deleteTempDir(tmpSubDir, linkedFiles);} - } - - /* (non-Javadoc) - * tests 3.0 style tool integration for a linked folder - */ - public void test30LinkedFolder(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("sources.mk")}; - IPath[] linkedFiles = { - Path.fromOSString("f1.c"), - Path.fromOSString("f2.c"), - Path.fromOSString("test_ar.h"), - Path.fromOSString("Benchmarks/makefile"), - Path.fromOSString("Benchmarks/objects.mk"), - Path.fromOSString("Benchmarks/subdir.mk"), - Path.fromOSString("Benchmarks/sources.mk")}; - File srcDirFile = CTestPlugin.getFileInPlugin(new Path("resources/test30Projects/linkedFolder/")); - IPath srcDir = Path.fromOSString(srcDirFile.toString()); - IPath tmpSubDir = Path.fromOSString("CDTMBSTest"); - IPath tmpDir = ManagedBuildTestHelper.copyFilesToTempDir(srcDir, tmpSubDir, linkedFiles); - if (!pathVariableCreated) { - createPathVariable(tmpDir); - pathVariableCreated = true; - } - try { - IPath location = Path.fromOSString(MBS_TEMP_DIR); - IProject[] projects = createProjects("linkedFolder", location, "cdt.managedbuild.target.gnu30.lib", false); - // Build the project - buildProjects(projects, makefiles); - } finally {ManagedBuildTestHelper.deleteTempDir(tmpSubDir, linkedFiles);} - } - - /* (non-Javadoc) - * tests 3.0 style tool integration with pre and post process steps added to typical compile & link - */ - public void test30CopyandDeploy(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("main.d"), - Path.fromOSString("Functions/subdir.mk"), - Path.fromOSString("Functions/Func1.d")}; - IProject[] projects = createProjects("copyandDeploy", null, null, true); - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 style tool integration in the context of deleting a file, to see if the proper behavior - * occurs in the managedbuild system - */ - public void test30DeleteFile(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("sources.mk")}; - - IProject[] projects = createProjects("deleteFile", null, null, true); - final IWorkspace workspace = ResourcesPlugin.getWorkspace(); - ArrayList resourceList = new ArrayList(1); - IProject project = projects[0]; - IFile projfile = project.getFile("filetobedeleted.cxx"); - resourceList.add(projfile); - final IResource[] fileResource = (IResource[])resourceList.toArray(new IResource[resourceList.size()]); - IWorkspaceRunnable runnable = new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - workspace.delete(fileResource, false, null); - } - }; - try { - NullProgressMonitor monitor = new NullProgressMonitor(); - workspace.run(runnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor); - } catch (Exception e) { - fail("could not delete file in project " + project.getName()); - } - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 managed build system with a project which has only a single source file that is marked as - * "excluded from build" to see that this degenerative case is handled gracefully - */ - public void test30NoFilesToBuild(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("sources.mk")}; - - IProject[] projects = createProjects("noFilesToBuild", null, null, true); - IProject project = projects[0]; - IFile projfile = project.getFile("filetobeexcluded.cxx"); - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - IConfiguration config = info.getDefaultConfiguration(); - IResourceConfiguration rconfig = config.createResourceConfiguration(projfile); - rconfig.setExclude(true); - buildDegenerativeProjects(projects, makefiles); - } - - /** - * (non-Javadoc) - * tests 3.0 managed build system with a project which has a file with no file extesnion - */ - public void testFileWithNoExtension() - { - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk")}; - IProject[] projects = createProjects("testFileWithNoExtension", null, null, true); - buildProjects(projects, makefiles); - } - - - /* (non-Javadoc) - * tests 3.0 style tool integration: create pre-build and post-build steps and verify that - * the proper commands are generated in the makefile which is created by the managedbuild system - */ - public void testPreAndPostProcessBuildSteps(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("sources.mk")}; - - IProject[] projects = createProjects("preAndPostBuildSteps", null, null, true); - IProject project = projects[0]; - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - IConfiguration config = info.getDefaultConfiguration(); - IFile projfile = project.getFile("main.cxx"); - config.setPreannouncebuildStep("Pre-announce Build Step"); - config.setPrebuildStep("echo 'executing Pre-Build Step' "); - config.setPostannouncebuildStep("Post-announce Build Step"); - config.setPostbuildStep("echo 'executing Post-Build Step' "); - buildProjects(projects, makefiles); - } - - - /* (non-Javadoc) - * tests 3.0 style tool integration: create resource custom build step and verify that - * the proper commands are generated in the makefile which is created by the managedbuild system - */ - public void testResourceCustomBuildStep(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("subdir.mk"), - Path.fromOSString("sources.mk")}; - ITool rcbsTool; - IInputType rcbsToolInputType; - IAdditionalInput rcbsToolInputTypeAdditionalInput; - IOutputType rcbsToolOutputType; - - IProject[] projects = createProjects("rcbsBasicTest", null, null, true); - IProject project = projects[0]; - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - IConfiguration config = info.getDefaultConfiguration(); - IFile projfile = project.getFile("rcbsBasicTest.c"); - IResourceConfiguration rconfig = config.createResourceConfiguration(projfile); - rcbsTool = rconfig.createTool(null,"rcbsBasicTestTool","rcbs Basic Test Tool",false); - rcbsToolInputType = rcbsTool.createInputType(null,"rcbsToolInputTypeId","rcbsToolInputTypeName",false); - rcbsToolInputTypeAdditionalInput = rcbsToolInputType.createAdditionalInput(""); - rcbsToolInputTypeAdditionalInput.setKind(IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY); - rcbsToolOutputType = rcbsTool.createOutputType(null,"rcbsToolOutputTypeId","rcbsToolOutputTypeName",false); - rcbsToolOutputType.setOutputNames("rcbsBasicTest.o"); - rcbsTool.setCustomBuildStep(true); - rcbsTool.setToolCommand("gcc -g -c ../rcbsBasicTest.c -o ./rcbsBasicTest.o"); - rcbsTool.setAnnouncement("Now executing custom build step for rcbsBasicTest debug config"); - rconfig.setRcbsApplicability(IResourceConfiguration.KIND_APPLY_RCBS_TOOL_AS_OVERRIDE); - buildProjects(projects, makefiles); - } - - - /* (non-Javadoc) - * tests 3.0 style tool integration with pre and post process steps added to typical compile & link - */ - public void test30_1(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk")}; - IProject[] projects = createProjects("test30_1", null, null, true); - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 style tool integration with multiple input types use Eclipse content types - */ - public void test30_2(){ - IPath[] makefiles = { - Path.fromOSString("makefile"), - Path.fromOSString("objects.mk"), - Path.fromOSString("sources.mk"), - Path.fromOSString("subdir.mk")}; - IProject[] projects = createProjects("test30_2", null, null, true); - buildProjects(projects, makefiles); - } - - /* (non-Javadoc) - * tests 3.0 top-level tool-chain definition - */ - public void testTopTC(){ - IProject[] projects = createProjects("TopTC", null, "TopTC.target.exe", false); - // There should be only one project. - assertNotNull(projects); - assertEquals(1, projects.length); - IProject project = projects[0]; - // Verify a number of other attributes - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - assertNotNull(info); - IManagedProject managedProj = info.getManagedProject(); - assertNotNull(managedProj); - IConfiguration[] configs = managedProj.getConfigurations(); - assertNotNull(configs); - assertEquals(2, configs.length); - // Make sure that each configuration has a tool-chain with all 5 tools - for (int i=0; i 0) { + if (i == 0) { + String configName = info.getDefaultConfiguration().getName(); + IPath buildDir = Path.fromOSString(configName); + if (compareBenchmark) + succeeded = ManagedBuildTestHelper.compareBenchmarks(curProject, buildDir, files); + else + succeeded = ManagedBuildTestHelper.verifyFilesDoNotExist(curProject, buildDir, files); + } + } + } + } + + if (succeeded) { // Otherwise leave the projects around for comparison + for (int i = 0; i < projects.length; i++) + ManagedBuildTestHelper.removeProject(projects[i].getName()); + } + } + + // Build projects and compare benchmarks + private void buildProjects(IProject projects[], IPath[] files) { + buildProjectsWorker(projects, files, true); + } + + // Build projects but don't compare benchmarks because there should be not build files generated + private void buildDegenerativeProjects(IProject projects[], IPath[] files) { + buildProjectsWorker(projects, files, false); + } + + private void createPathVariable(IPath tmpDir) { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace = ResourcesPlugin.getWorkspace(); + IPathVariableManager pathMan = workspace.getPathVariableManager(); + String name = MBS_TEMP_DIR; + try { + if (pathMan.validateName(name).isOK() && pathMan.validateValue(tmpDir).isOK()) { + pathMan.setValue(name, tmpDir); + assertTrue(pathMan.isDefined(name)); + } else { + fail("could not create the path variable " + name); + } + } catch (Exception e) {fail("could not create the path variable " + name);} + } + + private void createFileLink(IProject project, IPath tmpDir, String linkName, String fileName) { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + String name = MBS_TEMP_DIR; + if (!pathVariableCreated) { + createPathVariable(tmpDir); + pathVariableCreated = true; + } + + try { + // Now we can create a linked resource relative to the defined path variable: + IFile linkF1 = project.getFile(linkName); + IPath location = new Path("MBSTemp/" + fileName); + if (workspace.validateLinkLocation(linkF1, location).isOK()) { + linkF1.createLink(location, IResource.NONE, null); + } else { + fail("could not create the link to " + name); + } + } catch (Exception e) {fail("could not create the link to " + name);} + } + + /* (non-Javadoc) + * tests 3.0 style tool integration for a single file executable + */ + public void test30SingleFileExe(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk")}; + IProject[] projects = createProjects("singleFileExe", null, null, true); + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 style tool integration for a two file SO + */ + public void test30TwoFileSO(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk")}; + IProject[] projects = createProjects("twoFileSO", null, null, true); + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 style tool integration for multiple source files & a resource configuration + */ + public void test30MultiResConfig(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("main.d"), + Path.fromOSString("source1/subdir.mk"), + Path.fromOSString("source1/Class1.d"), + Path.fromOSString("source2/subdir.mk"), + Path.fromOSString("source2/Class2.d"), + Path.fromOSString("source2/source21/Class21.d"), + Path.fromOSString("source2/source21/subdir.mk")}; + IProject[] projects = createProjects("multiResConfig", null, null, true); + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 style tool integration for linked files + */ + public void test30LinkedLib(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + //Path.fromOSString("subdir.mk") // Can't compare this yet since it contains absolute paths! + Path.fromOSString("sources.mk")}; + IPath[] linkedFiles = { + Path.fromOSString("f1.c"), + Path.fromOSString("f2.c"), + Path.fromOSString("test_ar.h")}; + File srcDirFile = CTestPlugin.getFileInPlugin(new Path("resources/test30Projects/linkedLib/")); + IPath srcDir = Path.fromOSString(srcDirFile.toString()); + IPath tmpSubDir = Path.fromOSString("CDTMBSTest"); + IPath tmpDir = ManagedBuildTestHelper.copyFilesToTempDir(srcDir, tmpSubDir, linkedFiles); + try { + IProject[] projects = createProjects("linkedLib", null, "cdt.managedbuild.target.gnu30.lib", true); + // There should be only one project. Add our linked files to it. + IProject project = projects[0]; + createFileLink(project, tmpDir, "f1.c", "f1.c"); + createFileLink(project, tmpDir, "f2link.c", "f2.c"); + createFileLink(project, tmpDir, "test_ar.h", "test_ar.h"); + // Build the project + buildProjects(projects, makefiles); + } finally {ManagedBuildTestHelper.deleteTempDir(tmpSubDir, linkedFiles);} + } + + /* (non-Javadoc) + * tests 3.0 style tool integration for a linked folder + */ + public void test30LinkedFolder(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("sources.mk")}; + IPath[] linkedFiles = { + Path.fromOSString("f1.c"), + Path.fromOSString("f2.c"), + Path.fromOSString("test_ar.h"), + Path.fromOSString("Benchmarks/makefile"), + Path.fromOSString("Benchmarks/objects.mk"), + Path.fromOSString("Benchmarks/subdir.mk"), + Path.fromOSString("Benchmarks/sources.mk")}; + File srcDirFile = CTestPlugin.getFileInPlugin(new Path("resources/test30Projects/linkedFolder/")); + IPath srcDir = Path.fromOSString(srcDirFile.toString()); + IPath tmpSubDir = Path.fromOSString("CDTMBSTest"); + IPath tmpDir = ManagedBuildTestHelper.copyFilesToTempDir(srcDir, tmpSubDir, linkedFiles); + if (!pathVariableCreated) { + createPathVariable(tmpDir); + pathVariableCreated = true; + } + try { + IPath location = Path.fromOSString(MBS_TEMP_DIR); + IProject[] projects = createProjects("linkedFolder", location, "cdt.managedbuild.target.gnu30.lib", false); + // Build the project + buildProjects(projects, makefiles); + } finally {ManagedBuildTestHelper.deleteTempDir(tmpSubDir, linkedFiles);} + } + + /* (non-Javadoc) + * tests 3.0 style tool integration with pre and post process steps added to typical compile & link + */ + public void test30CopyandDeploy(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("main.d"), + Path.fromOSString("Functions/subdir.mk"), + Path.fromOSString("Functions/Func1.d")}; + IProject[] projects = createProjects("copyandDeploy", null, null, true); + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 style tool integration in the context of deleting a file, to see if the proper behavior + * occurs in the managedbuild system + */ + public void test30DeleteFile(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("sources.mk")}; + + IProject[] projects = createProjects("deleteFile", null, null, true); + final IWorkspace workspace = ResourcesPlugin.getWorkspace(); + ArrayList resourceList = new ArrayList(1); + IProject project = projects[0]; + IFile projfile = project.getFile("filetobedeleted.cxx"); + resourceList.add(projfile); + final IResource[] fileResource = (IResource[])resourceList.toArray(new IResource[resourceList.size()]); + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + workspace.delete(fileResource, false, null); + } + }; + try { + NullProgressMonitor monitor = new NullProgressMonitor(); + workspace.run(runnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor); + } catch (Exception e) { + fail("could not delete file in project " + project.getName()); + } + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 managed build system with a project which has only a single source file that is marked as + * "excluded from build" to see that this degenerative case is handled gracefully + */ + public void test30NoFilesToBuild(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("sources.mk")}; + + IProject[] projects = createProjects("noFilesToBuild", null, null, true); + IProject project = projects[0]; + IFile projfile = project.getFile("filetobeexcluded.cxx"); + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + IConfiguration config = info.getDefaultConfiguration(); + IResourceConfiguration rconfig = config.createResourceConfiguration(projfile); + rconfig.setExclude(true); + buildDegenerativeProjects(projects, makefiles); + } + + /** + * (non-Javadoc) + * tests 3.0 managed build system with a project which has a file with no file extesnion + */ + public void testFileWithNoExtension() + { + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk")}; + IProject[] projects = createProjects("testFileWithNoExtension", null, null, true); + buildProjects(projects, makefiles); + } + + + /* (non-Javadoc) + * tests 3.0 style tool integration: create pre-build and post-build steps and verify that + * the proper commands are generated in the makefile which is created by the managedbuild system + */ + public void testPreAndPostProcessBuildSteps(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("sources.mk")}; + + IProject[] projects = createProjects("preAndPostBuildSteps", null, null, true); + IProject project = projects[0]; + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + IConfiguration config = info.getDefaultConfiguration(); + IFile projfile = project.getFile("main.cxx"); + config.setPreannouncebuildStep("Pre-announce Build Step"); + config.setPrebuildStep("echo 'executing Pre-Build Step' "); + config.setPostannouncebuildStep("Post-announce Build Step"); + config.setPostbuildStep("echo 'executing Post-Build Step' "); + buildProjects(projects, makefiles); + } + + + /* (non-Javadoc) + * tests 3.0 style tool integration: create resource custom build step and verify that + * the proper commands are generated in the makefile which is created by the managedbuild system + */ + public void testResourceCustomBuildStep(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("subdir.mk"), + Path.fromOSString("sources.mk")}; + ITool rcbsTool; + IInputType rcbsToolInputType; + IAdditionalInput rcbsToolInputTypeAdditionalInput; + IOutputType rcbsToolOutputType; + + IProject[] projects = createProjects("rcbsBasicTest", null, null, true); + IProject project = projects[0]; + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + IConfiguration config = info.getDefaultConfiguration(); + IFile projfile = project.getFile("rcbsBasicTest.c"); + IResourceConfiguration rconfig = config.createResourceConfiguration(projfile); + rcbsTool = rconfig.createTool(null,"rcbsBasicTestTool","rcbs Basic Test Tool",false); + rcbsToolInputType = rcbsTool.createInputType(null,"rcbsToolInputTypeId","rcbsToolInputTypeName",false); + rcbsToolInputTypeAdditionalInput = rcbsToolInputType.createAdditionalInput(""); + rcbsToolInputTypeAdditionalInput.setKind(IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY); + rcbsToolOutputType = rcbsTool.createOutputType(null,"rcbsToolOutputTypeId","rcbsToolOutputTypeName",false); + rcbsToolOutputType.setOutputNames("rcbsBasicTest.o"); + rcbsTool.setCustomBuildStep(true); + rcbsTool.setToolCommand("gcc -g -c ../rcbsBasicTest.c -o ./rcbsBasicTest.o"); + rcbsTool.setAnnouncement("Now executing custom build step for rcbsBasicTest debug config"); + rconfig.setRcbsApplicability(IResourceConfiguration.KIND_APPLY_RCBS_TOOL_AS_OVERRIDE); + buildProjects(projects, makefiles); + } + + + /* (non-Javadoc) + * tests 3.0 style tool integration with pre and post process steps added to typical compile & link + */ + public void test30_1(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk")}; + IProject[] projects = createProjects("test30_1", null, null, true); + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 style tool integration with multiple input types use Eclipse content types + */ + public void test30_2(){ + IPath[] makefiles = { + Path.fromOSString("makefile"), + Path.fromOSString("objects.mk"), + Path.fromOSString("sources.mk"), + Path.fromOSString("subdir.mk")}; + IProject[] projects = createProjects("test30_2", null, null, true); + buildProjects(projects, makefiles); + } + + /* (non-Javadoc) + * tests 3.0 top-level tool-chain definition + */ + public void testTopTC(){ + IProject[] projects = createProjects("TopTC", null, "TopTC.target.exe", false); + // There should be only one project. + assertNotNull(projects); + assertEquals(1, projects.length); + IProject project = projects[0]; + // Verify a number of other attributes + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + assertNotNull(info); + IManagedProject managedProj = info.getManagedProject(); + assertNotNull(managedProj); + IConfiguration[] configs = managedProj.getConfigurations(); + assertNotNull(configs); + assertEquals(2, configs.length); + // Make sure that each configuration has a tool-chain with all 5 tools + for (int i=0; iProjectType the configuration will be added to. - * @param element The element from the manifest that contains the configuration information. - * @param managedBuildRevision - */ - public Configuration(ProjectType projectType, IManagedConfigElement element, String managedBuildRevision) { - this.projectType = projectType; - isExtensionConfig = true; - - // setup for resolving - resolved = false; - - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionConfiguration(this); - - // Hook me up to the ProjectType - if (projectType != null) { - projectType.addConfiguration(this); - } - - // Load the children - IManagedConfigElement[] configElements = element.getChildren(); - for (int l = 0; l < configElements.length; ++l) { - IManagedConfigElement configElement = configElements[l]; - if (configElement.getName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { - toolChain = new ToolChain(this, configElement, managedBuildRevision); - }else if (configElement.getName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { - ResourceConfiguration resConfig = new ResourceConfiguration(this, configElement, managedBuildRevision); - addResourceConfiguration(resConfig); - } - } - } - - /** - * Create a new extension configuration based on one already defined. - * - * @param projectType The ProjectType the configuration will be added to. - * @param parentConfig The IConfiguration that is the parent configuration of this configuration - * @param id A unique ID for the new configuration. - */ - public Configuration(ProjectType projectType, IConfiguration parentConfig, String id) { - setId(id); - this.projectType = projectType; - isExtensionConfig = true; - - // setup for resolving - resolved = false; - - if (parentConfig != null) { - name = parentConfig.getName(); - // If this contructor is called to clone an existing - // configuration, the parent of the parent should be stored. - // As of 2.1, there is still one single level of inheritence to - // worry about - parent = parentConfig.getParent() == null ? parentConfig : parentConfig.getParent(); - } - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionConfiguration(this); - - // Hook me up to the ProjectType - if (projectType != null) { - projectType.addConfiguration(this); - // set managedBuildRevision - setManagedBuildRevision(projectType.getManagedBuildRevision()); - } - } - - /** - * Create a new extension configuration and fill in the attributes and childen later. - * - * @param projectType The ProjectType the configuration will be added to. - * @param parentConfig The IConfiguration that is the parent configuration of this configuration - * @param id A unique ID for the new configuration. - * @param name A name for the new configuration. - */ - public Configuration(ProjectType projectType, IConfiguration parentConfig, String id, String name) { - setId(id); - setName(name); - this.projectType = projectType; - parent = parentConfig; - isExtensionConfig = true; - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionConfiguration(this); - - // Hook me up to the ProjectType - if (projectType != null) { - projectType.addConfiguration(this); - setManagedBuildRevision(projectType.getManagedBuildRevision()); - } - } - - /** - * Create a Configuration based on the specification stored in the - * project file (.cdtbuild). - * - * @param managedProject The ManagedProject the configuration will be added to. - * @param element The XML element that contains the configuration settings. - * - */ - public Configuration(ManagedProject managedProject, Element element, String managedBuildRevision) { - this.managedProject = managedProject; - isExtensionConfig = false; - - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromProject(element); - - // Hook me up - managedProject.addConfiguration(this); - - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { - toolChain = new ToolChain(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { - ResourceConfiguration resConfig = new ResourceConfiguration(this, (Element)configElement, managedBuildRevision); - addResourceConfiguration(resConfig); - } - } - } - - /** - * Create a new project, non-extension, configuration based on one already defined. - * - * @param managedProject The ManagedProject the configuration will be added to. - * @param cloneConfig The IConfiguration to copy the settings from. - * @param id A unique ID for the new configuration. - * @param cloneChildren If true, the configuration's tools are cloned - */ - public Configuration(ManagedProject managedProject, Configuration cloneConfig, String id, boolean cloneChildren, boolean temporary) { - setId(id); - setName(cloneConfig.getName()); - this.description = cloneConfig.getDescription(); - this.managedProject = managedProject; - isExtensionConfig = false; - this.isTemporary = temporary; - - // set managedBuildRevision - setManagedBuildRevision(cloneConfig.getManagedBuildRevision()); - - // If this contructor is called to clone an existing - // configuration, the parent of the cloning config should be stored. - parent = cloneConfig.getParent() == null ? cloneConfig : cloneConfig.getParent(); - - // Copy the remaining attributes - projectType = cloneConfig.projectType; - if (cloneConfig.artifactName != null) { - artifactName = new String(cloneConfig.artifactName); - } - if (cloneConfig.cleanCommand != null) { - cleanCommand = new String(cloneConfig.cleanCommand); - } - if (cloneConfig.artifactExtension != null) { - artifactExtension = new String(cloneConfig.artifactExtension); - } - if (cloneConfig.errorParserIds != null) { - errorParserIds = new String(cloneConfig.errorParserIds); - } - if (cloneConfig.prebuildStep != null) { - prebuildStep = new String(cloneConfig.prebuildStep); - } - if (cloneConfig.postbuildStep != null) { - postbuildStep = new String(cloneConfig.postbuildStep); - } - if (cloneConfig.preannouncebuildStep != null) { - preannouncebuildStep = new String(cloneConfig.preannouncebuildStep); - } - if (cloneConfig.postannouncebuildStep != null) { - postannouncebuildStep = new String(cloneConfig.postannouncebuildStep); - } - - // Clone the configuration's children - // Tool Chain - String subId; - String subName; - if (cloneConfig.parent != null) { - subId = ManagedBuildManager.calculateChildId( - cloneConfig.parent.getToolChain().getId(), - null); - subName = cloneConfig.parent.getToolChain().getName(); - - } else { - subId = ManagedBuildManager.calculateChildId( - cloneConfig.getToolChain().getId(), - null); - subName = cloneConfig.getToolChain().getName(); - } - - if (cloneChildren) { - toolChain = new ToolChain(this, subId, subName, (ToolChain)cloneConfig.getToolChain()); - - //copy expand build macros setting - BuildMacroProvider macroProvider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); - macroProvider.expandMacrosInBuildfile(this, - macroProvider.areMacrosExpandedInBuildfile(cloneConfig)); - - //copy user-defined build macros - UserDefinedMacroSupplier userMacros = BuildMacroProvider.fUserDefinedMacroSupplier; - userMacros.setMacros( - userMacros.getMacros(BuildMacroProvider.CONTEXT_CONFIGURATION,cloneConfig), - BuildMacroProvider.CONTEXT_CONFIGURATION, - this); - - //copy user-defined environment - UserDefinedEnvironmentSupplier userEnv = EnvironmentVariableProvider.fUserSupplier; - userEnv.setVariables( - userEnv.getVariables(cloneConfig), this); - - } else { - // Add a tool-chain element that specifies as its superClass the - // tool-chain that is the child of the configuration. - ToolChain superChain = (ToolChain)cloneConfig.getToolChain(); - subId = ManagedBuildManager.calculateChildId( - superChain.getId(), - null); - IToolChain newChain = createToolChain(superChain, subId, superChain.getName(), false); - - // For each option/option category child of the tool-chain that is - // the child of the selected configuration element, create an option/ - // option category child of the cloned configuration's tool-chain element - // that specifies the original tool element as its superClass. - newChain.createOptions(superChain); - - // For each tool element child of the tool-chain that is the child of - // the selected configuration element, create a tool element child of - // the cloned configuration's tool-chain element that specifies the - // original tool element as its superClass. - ITool[] tools = superChain.getTools(); - for (int i=0; iProjectType the configuration will be added to. + * @param element The element from the manifest that contains the configuration information. + * @param managedBuildRevision + */ + public Configuration(ProjectType projectType, IManagedConfigElement element, String managedBuildRevision) { + this.projectType = projectType; + isExtensionConfig = true; + + // setup for resolving + resolved = false; + + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionConfiguration(this); + + // Hook me up to the ProjectType + if (projectType != null) { + projectType.addConfiguration(this); + } + + // Load the children + IManagedConfigElement[] configElements = element.getChildren(); + for (int l = 0; l < configElements.length; ++l) { + IManagedConfigElement configElement = configElements[l]; + if (configElement.getName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { + toolChain = new ToolChain(this, configElement, managedBuildRevision); + }else if (configElement.getName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { + ResourceConfiguration resConfig = new ResourceConfiguration(this, configElement, managedBuildRevision); + addResourceConfiguration(resConfig); + } + } + } + + /** + * Create a new extension configuration based on one already defined. + * + * @param projectType The ProjectType the configuration will be added to. + * @param parentConfig The IConfiguration that is the parent configuration of this configuration + * @param id A unique ID for the new configuration. + */ + public Configuration(ProjectType projectType, IConfiguration parentConfig, String id) { + setId(id); + this.projectType = projectType; + isExtensionConfig = true; + + // setup for resolving + resolved = false; + + if (parentConfig != null) { + name = parentConfig.getName(); + // If this contructor is called to clone an existing + // configuration, the parent of the parent should be stored. + // As of 2.1, there is still one single level of inheritence to + // worry about + parent = parentConfig.getParent() == null ? parentConfig : parentConfig.getParent(); + } + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionConfiguration(this); + + // Hook me up to the ProjectType + if (projectType != null) { + projectType.addConfiguration(this); + // set managedBuildRevision + setManagedBuildRevision(projectType.getManagedBuildRevision()); + } + } + + /** + * Create a new extension configuration and fill in the attributes and childen later. + * + * @param projectType The ProjectType the configuration will be added to. + * @param parentConfig The IConfiguration that is the parent configuration of this configuration + * @param id A unique ID for the new configuration. + * @param name A name for the new configuration. + */ + public Configuration(ProjectType projectType, IConfiguration parentConfig, String id, String name) { + setId(id); + setName(name); + this.projectType = projectType; + parent = parentConfig; + isExtensionConfig = true; + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionConfiguration(this); + + // Hook me up to the ProjectType + if (projectType != null) { + projectType.addConfiguration(this); + setManagedBuildRevision(projectType.getManagedBuildRevision()); + } + } + + /** + * Create a Configuration based on the specification stored in the + * project file (.cdtbuild). + * + * @param managedProject The ManagedProject the configuration will be added to. + * @param element The XML element that contains the configuration settings. + * + */ + public Configuration(ManagedProject managedProject, Element element, String managedBuildRevision) { + this.managedProject = managedProject; + isExtensionConfig = false; + + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromProject(element); + + // Hook me up + managedProject.addConfiguration(this); + + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { + toolChain = new ToolChain(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { + ResourceConfiguration resConfig = new ResourceConfiguration(this, (Element)configElement, managedBuildRevision); + addResourceConfiguration(resConfig); + } + } + } + + /** + * Create a new project, non-extension, configuration based on one already defined. + * + * @param managedProject The ManagedProject the configuration will be added to. + * @param cloneConfig The IConfiguration to copy the settings from. + * @param id A unique ID for the new configuration. + * @param cloneChildren If true, the configuration's tools are cloned + */ + public Configuration(ManagedProject managedProject, Configuration cloneConfig, String id, boolean cloneChildren, boolean temporary) { + setId(id); + setName(cloneConfig.getName()); + this.description = cloneConfig.getDescription(); + this.managedProject = managedProject; + isExtensionConfig = false; + this.isTemporary = temporary; + + // set managedBuildRevision + setManagedBuildRevision(cloneConfig.getManagedBuildRevision()); + + // If this contructor is called to clone an existing + // configuration, the parent of the cloning config should be stored. + parent = cloneConfig.getParent() == null ? cloneConfig : cloneConfig.getParent(); + + // Copy the remaining attributes + projectType = cloneConfig.projectType; + if (cloneConfig.artifactName != null) { + artifactName = new String(cloneConfig.artifactName); + } + if (cloneConfig.cleanCommand != null) { + cleanCommand = new String(cloneConfig.cleanCommand); + } + if (cloneConfig.artifactExtension != null) { + artifactExtension = new String(cloneConfig.artifactExtension); + } + if (cloneConfig.errorParserIds != null) { + errorParserIds = new String(cloneConfig.errorParserIds); + } + if (cloneConfig.prebuildStep != null) { + prebuildStep = new String(cloneConfig.prebuildStep); + } + if (cloneConfig.postbuildStep != null) { + postbuildStep = new String(cloneConfig.postbuildStep); + } + if (cloneConfig.preannouncebuildStep != null) { + preannouncebuildStep = new String(cloneConfig.preannouncebuildStep); + } + if (cloneConfig.postannouncebuildStep != null) { + postannouncebuildStep = new String(cloneConfig.postannouncebuildStep); + } + + // Clone the configuration's children + // Tool Chain + String subId; + String subName; + if (cloneConfig.parent != null) { + subId = ManagedBuildManager.calculateChildId( + cloneConfig.parent.getToolChain().getId(), + null); + subName = cloneConfig.parent.getToolChain().getName(); + + } else { + subId = ManagedBuildManager.calculateChildId( + cloneConfig.getToolChain().getId(), + null); + subName = cloneConfig.getToolChain().getName(); + } + + if (cloneChildren) { + toolChain = new ToolChain(this, subId, subName, (ToolChain)cloneConfig.getToolChain()); + + //copy expand build macros setting + BuildMacroProvider macroProvider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + macroProvider.expandMacrosInBuildfile(this, + macroProvider.areMacrosExpandedInBuildfile(cloneConfig)); + + //copy user-defined build macros + UserDefinedMacroSupplier userMacros = BuildMacroProvider.fUserDefinedMacroSupplier; + userMacros.setMacros( + userMacros.getMacros(BuildMacroProvider.CONTEXT_CONFIGURATION,cloneConfig), + BuildMacroProvider.CONTEXT_CONFIGURATION, + this); + + //copy user-defined environment + UserDefinedEnvironmentSupplier userEnv = EnvironmentVariableProvider.fUserSupplier; + userEnv.setVariables( + userEnv.getVariables(cloneConfig), this); + + } else { + // Add a tool-chain element that specifies as its superClass the + // tool-chain that is the child of the configuration. + ToolChain superChain = (ToolChain)cloneConfig.getToolChain(); + subId = ManagedBuildManager.calculateChildId( + superChain.getId(), + null); + IToolChain newChain = createToolChain(superChain, subId, superChain.getName(), false); + + // For each option/option category child of the tool-chain that is + // the child of the selected configuration element, create an option/ + // option category child of the cloned configuration's tool-chain element + // that specifies the original tool element as its superClass. + newChain.createOptions(superChain); + + // For each tool element child of the tool-chain that is the child of + // the selected configuration element, create a tool element child of + // the cloned configuration's tool-chain element that specifies the + // original tool element as its superClass. + ITool[] tools = superChain.getTools(); + for (int i=0; i 0) - name = resolved; - } catch (BuildMacroException e){ - } - - if (ext.length() > 0) { - buildGoalName = buildInfo.getOutputPrefix(ext) + name + IManagedBuilderMakefileGenerator.DOT + ext; - } else { - buildGoalName = name; - } - reservedNames = Arrays.asList(new String[]{".cdtbuild", ".cdtproject", ".project"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - /** - * @param changedResource - * @return - */ - private boolean isGeneratedResource(IResource resource) { - // Is this a generated directory ... - IPath path = resource.getProjectRelativePath(); - String[] configNames = buildInfo.getConfigurationNames(); - for (int i = 0; i < configNames.length; i++) { - String name = configNames[i]; - IPath root = new Path(name); - // It is if it is a root of the resource pathname - if (root.isPrefixOf(path)) return true; - } - return false; - } - - /** - * @param resource - * @return - */ - private boolean isProjectFile(IResource resource) { - return reservedNames.contains(resource.getName()); - } - - public boolean shouldBuildIncr() { - return incrBuildNeeded; - } - - public boolean shouldBuildFull() { - return fullBuildNeeded; - } - - public boolean visit(IResourceDelta delta) throws CoreException { - IResource resource = delta.getResource(); - // If the project has changed, then a build is needed and we can stop - if (resource != null && resource.getProject() == getProject()) { - IResourceDelta[] kids = delta.getAffectedChildren(); - for (int index = kids.length - 1; index >= 0; --index) { - IResource changedResource = kids[index].getResource(); - if (changedResource instanceof IFolder) { - return true; - } else { - String name = changedResource.getName(); - if ((!name.equals(buildGoalName) && - // TODO: Also need to check for secondary outputs - (changedResource.isDerived() || - (isProjectFile(changedResource)) || - (isGeneratedResource(changedResource))))) { - // The resource that changed has attributes which make it uninteresting, - // so don't do anything - ; - } - else { - // TODO: Should we do extra checks here to determine if a build is really needed, - // or do you just do exclusion checks like above? - // We could check for: - // o The build goal name - // o A secondary output - // o An input file to a tool: - // o Has an extension of a source file used by a tool - // o Has an extension of a header file used by a tool - // o Has the name of an input file specified in an InputType via: - // o An Option - // o An AdditionalInput - // - //if (resourceName.equals(buildGoalName) || - // (buildInfo.buildsFileType(ext) || buildInfo.isHeaderFile(ext))) { - - // We need to do an incremental build, at least - incrBuildNeeded = true; - if (kids[index].getKind() == IResourceDelta.REMOVED) { - // If a meaningful resource was removed, then force a full build - // This is required because an incremental build will trigger make to - // do nothing for a missing source, since the state after the file - // removal is uptodate, as far as make is concerned - // A full build will clean, and ultimately trigger a relink without - // the object generated from the deleted source, which is what we want - fullBuildNeeded = true; - // There is no point in checking anything else since we have - // decided to do a full build anyway - break; - } - - //} - } - } - } - return false; - } - return true; - } - } - - // String constants - private static final String BUILD_ERROR = "ManagedMakeBuilder.message.error"; //$NON-NLS-1$ - private static final String BUILD_FINISHED = "ManagedMakeBuilder.message.finished"; //$NON-NLS-1$ - private static final String CONSOLE_HEADER = "ManagedMakeBuilder.message.console.header"; //$NON-NLS-1$ - private static final String ERROR_HEADER = "GeneratedmakefileBuilder error ["; //$NON-NLS-1$ - private static final String MAKE = "ManagedMakeBuilder.message.make"; //$NON-NLS-1$ - private static final String MARKERS = "ManagedMakeBuilder.message.creating.markers"; //$NON-NLS-1$ - private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ - private static final String NOTHING_BUILT = "ManagedMakeBuilder.message.no.build"; //$NON-NLS-1$ - private static final String REFRESH = "ManagedMakeBuilder.message.updating"; //$NON-NLS-1$ - private static final String REFRESH_ERROR = BUILD_ERROR + ".refresh"; //$NON-NLS-1$ - private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$ - private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$ - private static final String TYPE_CLEAN = "ManagedMakeBuilder.type.clean"; //$NON-NLS-1$ - private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$ - private static final String WARNING_UNSUPPORTED_CONFIGURATION = "ManagedMakeBuilder.warning.unsupported.configuration"; //$NON-NLS-1$ - public static boolean VERBOSE = false; - - // Local variables - protected Vector generationProblems; - protected IProject[] referencedProjects; - protected List resourcesToBuild; - public static void outputTrace(String resourceName, String message) { - if (VERBOSE) { - System.out.println(TRACE_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); - } - } - - public static void outputError(String resourceName, String message) { - if (VERBOSE) { - System.err.println(ERROR_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); - } - } - - /** - * Zero-argument constructor needed to fulfill the contract of an - * incremental builder. - */ - public GeneratedMakefileBuilder() { - } - - /** - * @param epm - */ - private void addBuilderMarkers(ErrorParserManager epm) { - IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); - Iterator iter = getGenerationProblems().iterator(); - while (iter.hasNext()) { - IStatus stat = (IStatus)iter.next(); - IResource location = root.findMember(stat.getMessage()); - if (stat.getCode() == IManagedBuilderMakefileGenerator.SPACES_IN_PATH) { - epm.generateMarker(location, -1, ManagedMakeMessages.getResourceString("MakefileGenerator.error.spaces"), IMarkerGenerator.SEVERITY_WARNING, null); //$NON-NLS-1$ - } - } - } - - /* (non-javadoc) - * Emits a message to the console indicating that there were no source files to build - * @param buildType - * @param status - * @param configName - */ - private void emitNoSourceMessage(int buildType, IStatus status, String configName) throws CoreException { - try { - StringBuffer buf = new StringBuffer(); - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(getProject()); - ConsoleOutputStream consoleOutStream = console.getOutputStream(); - // Report a successful clean - String[] consoleHeader = new String[3]; - if (buildType == FULL_BUILD || buildType == INCREMENTAL_BUILD) { - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); - } else { - consoleHeader[0] = new String(); - outputError(getProject().getName(), "The given build type is not supported in this context"); //$NON-NLS-1$ - } - consoleHeader[1] = configName; - consoleHeader[2] = getProject().getName(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(status.getMessage()); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - consoleOutStream.close(); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } catch (IOException io) { // Ignore console failures... - } - } - - /** - * - * This method has been created so that subclasses can override how the builder obtains its - * build info. The default implementation retrieves the info from the build manager. - * - * @return An IManagedBuildInfo object representing the build info. - */ - protected IManagedBuildInfo getBuildInfo() { - return ManagedBuildManager.getBuildInfo(getProject()); - } - - /* (non-Javadoc) - * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) - */ - protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { - // We should always tell the build system what projects we reference - referencedProjects = getProject().getReferencedProjects(); - - // Get the build information - IManagedBuildInfo info = getBuildInfo(); - if (info == null) { - outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ - return referencedProjects; - } - if (!info.isValid()) { - outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ - return referencedProjects; - } - - // Create a makefile generator for the build - IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); - generator.initialize(getProject(), info, monitor); - - // So let's figure out why we got called - if (kind == FULL_BUILD || info.needsRebuild()) { - outputTrace(getProject().getName(), "Full build needed/requested"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } - else if (kind == AUTO_BUILD && info.needsRebuild()) { - outputTrace(getProject().getName(), "Autobuild requested, full build needed"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } - else { - // Create a delta visitor to make sure we should be rebuilding - ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(info); - IResourceDelta delta = getDelta(getProject()); - if (delta == null) { - outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } - else { - delta.accept(visitor); - if (visitor.shouldBuildFull()) { - outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } else if (visitor.shouldBuildIncr()) { - outputTrace(getProject().getName(), "Incremental build requested"); //$NON-NLS-1$ - incrementalBuild(delta, info, generator, monitor); - } - else if (referencedProjects != null) { - // Also check to see is any of the dependent projects changed - for (int i=0; iOperationCanceledException. - * - * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() - */ - public void checkCancel(IProgressMonitor monitor) { - if (monitor != null && monitor.isCanceled()) { - outputTrace(getProject().getName(), "Build cancelled"); //$NON-NLS-1$ - forgetLastBuiltState(); - throw new OperationCanceledException(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.IncrementalProjectBuilder#clean(org.eclipse.core.runtime.IProgressMonitor) - */ - protected void clean(IProgressMonitor monitor) throws CoreException { - referencedProjects = getProject().getReferencedProjects(); - outputTrace(getProject().getName(), "Clean build requested"); //$NON-NLS-1$ - IManagedBuildInfo info = getBuildInfo(); - if (info == null) { - outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ - return; - } - if (!info.isValid()) { - outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ - return; - } - IPath buildDirPath = getProject().getLocation().append(info.getConfigurationName()); - IWorkspace workspace = CCorePlugin.getWorkspace(); - IContainer buildDir = workspace.getRoot().getContainerForLocation(buildDirPath); - if (buildDir == null || !buildDir.isAccessible()){ - outputError(buildDir.getName(), "Could not delete the build directory"); //$NON-NLS-1$ - return; - } - String status; - try { - // try the brute force approach first - status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.deleting.output", buildDir.getName()); //$NON-NLS-1$ - monitor.subTask(status); - workspace.delete(new IResource[]{buildDir}, true, monitor); - StringBuffer buf = new StringBuffer(); - // write to the console - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(getProject()); - ConsoleOutputStream consoleOutStream = console.getOutputStream(); - String[] consoleHeader = new String[3]; - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); - consoleHeader[1] = info.getConfigurationName(); - consoleHeader[2] = getProject().getName(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - buf = new StringBuffer(); - // Report a successful clean - String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); - buf.append(successMsg); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - consoleOutStream.close(); - } catch (CoreException e) { - // Create a makefile generator for the build - status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.build.clean", buildDir.getName()); //$NON-NLS-1$ - monitor.subTask(status); - IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); - generator.initialize(getProject(), info, monitor); - cleanBuild(info, generator, monitor); - } catch (IOException io) {} // Ignore console failures... - } - - /* (non-Javadoc) - * @param info - * @param generator - * @param monitor - */ - protected void cleanBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { - // Make sure that there is a top level directory and a set of makefiles - IPath buildDir = generator.getBuildWorkingDir(); - if (buildDir == null) { - buildDir = new Path(info.getConfigurationName()); - } - IPath makefilePath = getProject().getLocation().append(buildDir.append(generator.getMakefileName())); - IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); - IFile makefile = root.getFileForLocation(makefilePath); - - if (buildDir != null && makefile != null && makefile.isAccessible()) { - // invoke make with the clean argument - String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - checkCancel(monitor); - invokeMake(CLEAN_BUILD, buildDir, info, generator, monitor); - } - } - - /* (non-Javadoc) - * @param info - * @param generator - * @param monitor - */ - protected void fullBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { - // Always need one of these bad boys - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - - checkCancel(monitor); - //If the previous builder invocation was cancelled, generated files might be corrupted - //in case one or more of the generated makefiles (e.g. dep files) are corrupted, - //the builder invocation might fail because of the possible syntax errors, so e.g. "make clean" will not work - //we need to explicitly clean the generated directories - clean(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN)); - - // Regenerate the makefiles for this project - checkCancel(monitor); - String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.rebuild.makefiles", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - //generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); - generator.initialize(getProject(), info, monitor); - MultiStatus result = generator.regenerateMakefiles(); - if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { - IStatus[] kids = result.getChildren(); - for (int index = 0; index < kids.length; ++index) { - // One possibility is that there is nothing to build - IStatus status = kids[index]; - if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { - // Inform the user, via the console, that there is nothing to build - // either because there are no buildable sources files or all potentially - // buildable files have been excluded from build - try { - emitNoSourceMessage(FULL_BUILD, status, info.getConfigurationName()); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } - // Dude, we're done - return; - } else { - // Stick this in the list of stuff to warn the user about - getGenerationProblems().add(status); - } - } - } - - // Now call make - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - IPath topBuildDir = generator.getBuildWorkingDir(); - if (topBuildDir != null) { - invokeMake(FULL_BUILD, topBuildDir, info, generator, monitor); - } else { - statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - return; - } - - // Now regenerate the dependencies - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.regen.deps", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - try { - generator.regenerateDependencies(false); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } - - // Build finished message - statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - } - - /* (non-Javadoc) - * - * @return - */ - private Vector getGenerationProblems() { - if (generationProblems == null) { - generationProblems = new Vector(); - } - return generationProblems; - } - - /* (non-javadoc) - * Answers an array of strings with the proper make targets - * for a build with no custom prebuild/postbuild steps - * - * @param fullBuild - * @return - */ - protected String[] getMakeTargets(int buildType) { - List args = new ArrayList(); - switch (buildType) { - case CLEAN_BUILD: - args.add("clean"); //$NON-NLS-1$ - break; - case FULL_BUILD: - case INCREMENTAL_BUILD: - args.add("all"); //$NON-NLS-1$ - break; - } - return (String[])args.toArray(new String[args.size()]); - } - - /** - * @return - */ - protected List getResourcesToBuild() { - if (resourcesToBuild == null) { - resourcesToBuild = new ArrayList(); - } - return resourcesToBuild; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.resources.ACBuilder#getWorkingDirectory() - */ - public IPath getWorkingDirectory() { - return getProject().getLocation(); - } - - /* (non-Javadoc) - * @param delta - * @param info - * @param monitor - * @throws CoreException - */ - protected void incrementalBuild(IResourceDelta delta, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { - // Need to report status to the user - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - - // Ask the makefile generator to generate any makefiles needed to build delta - checkCancel(monitor); - String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.update.makefiles", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - MultiStatus result = generator.generateMakefiles(delta); - if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { - IStatus[] kids = result.getChildren(); - for (int index = 0; index < kids.length; ++index) { - // One possibility is that there is nothing to build - IStatus status = kids[index]; - if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { - // Inform the user, via the console, that there is nothing to build - // either because there are no buildable sources files or all potentially - // buildable files have been excluded from build - try { - emitNoSourceMessage(INCREMENTAL_BUILD, status, info.getConfigurationName()); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } - // Dude, we're done - return; - } else { - // Stick this in the list of stuff to warn the user about - getGenerationProblems().add(status); - } - } - } - - // Run the build - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - IPath buildDir = generator.getBuildWorkingDir(); - if (buildDir != null) { - invokeMake(INCREMENTAL_BUILD, buildDir, info, generator, monitor); - } else { - statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - return; - } - - // Generate the dependencies for all changes - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.updating.deps", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - try { - generator.generateDependencies(); - } catch (CoreException e) { - throw e; - } - - // Build finished message - statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); -} - - /* (non-Javadoc) - * @param buildType - * @param buildDir - * @param info - * @param generator - * @param monitor - */ - protected void invokeMake(int buildType, IPath buildDir, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { - // Get the project and make sure there's a monitor to cancel the build - IProject currentProject = getProject(); - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - - try { - // Figure out the working directory for the build and make sure there is a makefile there - IPath workingDirectory = getWorkingDirectory().append(buildDir); - IWorkspace workspace = currentProject.getWorkspace(); - if (workspace == null) { - return; - } - IWorkspaceRoot root = workspace.getRoot(); - if (root == null) { - return; - } - IPath makefile = workingDirectory.append(generator.getMakefileName()); - if (root.getFileForLocation(makefile) == null) { - return; - } - - // Flag to the user that make is about to be called - String makeCmd = info.getBuildCommand(); - //try to resolve the build macros in the builder command - try{ - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - makeCmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - if((resolved = resolved.trim()).length() > 0) - makeCmd = resolved; - } catch (BuildMacroException e){ - } - - IPath makeCommand = new Path(makeCmd); - if (makeCommand != null) { - String[] msgs = new String[2]; - msgs[0] = makeCommand.toString(); - msgs[1] = currentProject.getName(); - monitor.subTask(ManagedMakeMessages.getFormattedString(MAKE, msgs)); - - // Get a build console for the project - StringBuffer buf = new StringBuffer(); - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(currentProject); - ConsoleOutputStream consoleOutStream = console.getOutputStream(); - String[] consoleHeader = new String[3]; - switch (buildType) { - case FULL_BUILD: - case INCREMENTAL_BUILD: - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); - break; - case CLEAN_BUILD: - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); - break; - } - - consoleHeader[1] = info.getConfigurationName(); - consoleHeader[2] = currentProject.getName(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - - IConfiguration cfg = info.getDefaultConfiguration(); - if(!cfg.isSupported()){ - buf.append(ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()})); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - } - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - - // Remove all markers for this project - removeAllMarkers(currentProject); - - // Get a launcher for the make command - String errMsg = null; - CommandLauncher launcher = new CommandLauncher(); - launcher.showCommand(true); - - // Set the environmennt - IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true,true); - String[] env = null; - ArrayList envList = new ArrayList(); - if (variables != null) { - for(int i = 0; i < variables.length; i++){ - envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$ - } - env = (String[]) envList.toArray(new String[envList.size()]); - } - - // Hook up an error parser manager - String[] errorParsers = info.getDefaultConfiguration().getErrorParserList(); - ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectory, this, errorParsers); - epm.setOutputStream(consoleOutStream); - // This variable is necessary to ensure that the EPM stream stay open - // until we explicitly close it. See bug#123302. - OutputStream epmOutputStream = epm.getOutputStream(); - - // Get the arguments to be passed to make from build model - ArrayList makeArgs = new ArrayList(); - String arg = info.getBuildArguments(); - if (arg.length() > 0) { - String[] args = arg.split("\\s"); //$NON-NLS-1$ - for (int i = 0; i < args.length; ++i) { - makeArgs.add(args[i]); - } - } - - String[] makeTargets; - String prebuildStep = info.getPrebuildStep(); - //try to resolve the build macros in the prebuildStep - try{ - prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - prebuildStep, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - cfg); - } catch (BuildMacroException e){ - } - boolean prebuildStepPresent = (prebuildStep.length() > 0); - Process proc = null; - boolean isuptodate = false; - - if (prebuildStepPresent) { - ArrayList premakeArgs = (ArrayList) makeArgs.clone(); - String[] premakeTargets; - switch (buildType) { - case INCREMENTAL_BUILD: { - // For an incremental build with a prebuild step: - // Check the status of the main build with "make -q main-build" - // If up to date: - // then: don't invoke the prebuild step, which should be run only if - // something needs to be built in the main build - // else: invoke the prebuild step and the main build step - premakeArgs.add("-q"); //$NON-NLS-1$ - premakeArgs.add("main-build"); //$NON-NLS-1$ - premakeTargets = (String[]) premakeArgs.toArray(new String[premakeArgs.size()]); - proc = launcher.execute(makeCommand, premakeTargets, env, workingDirectory); - if (proc != null) { - try { - // Close the input of the process since we will never write to it - proc.getOutputStream().close(); - } catch (IOException e) { - } - if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), - new SubProgressMonitor(monitor, - IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { - errMsg = launcher.getErrorMessage(); - } - } else { - errMsg = launcher.getErrorMessage(); - } - - if ((errMsg != null && errMsg.length() > 0) || proc == null) { - // Can't tell if the build is needed, so assume it is, and let any errors be triggered - // when the "real" build is invoked below - makeArgs.add("pre-build"); //$NON-NLS-1$ - makeArgs.add("main-build"); //$NON-NLS-1$ - } else { - // The "make -q" command launch was successful - if (proc.exitValue() == 0) { - // If the status value returned from "make -q" is 0, then the build state is up-to-date - isuptodate = true; - // Report that the build was up to date, and thus nothing needs to be built - String uptodateMsg = ManagedMakeMessages - .getFormattedString(NOTHING_BUILT, currentProject.getName()); - buf = new StringBuffer(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - buf.append(uptodateMsg); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - // Write message on the console - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - epmOutputStream.close(); - consoleOutStream.close(); - } else { - // The status value was other than 0, so press on with the build process - makeArgs.add("pre-build"); //$NON-NLS-1$ - makeArgs.add("main-build"); //$NON-NLS-1$ - } - } - break; - } - case FULL_BUILD: { - makeArgs.add("clean"); //$NON-NLS-1$ - makeArgs.add("pre-build"); //$NON-NLS-1$ - makeArgs.add("main-build"); //$NON-NLS-1$ - break; - } - case CLEAN_BUILD: { - makeArgs.add("clean"); //$NON-NLS-1$ - break; - } - } - - } else { - // No prebuild step - // - makeArgs.addAll(Arrays.asList(getMakeTargets(buildType))); - } - - makeTargets = (String[]) makeArgs.toArray(new String[makeArgs.size()]); - - // Launch make - main invocation - if (!isuptodate) { - proc = launcher.execute(makeCommand, makeTargets, env, - workingDirectory); - if (proc != null) { - try { - // Close the input of the process since we will never write to it - proc.getOutputStream().close(); - } catch (IOException e) { - } - - if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), - new SubProgressMonitor(monitor, - IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { - errMsg = launcher.getErrorMessage(); - } - - // Force a resync of the projects without allowing the user to cancel. - // This is probably unkind, but short of this there is no way to insure - // the UI is up-to-date with the build results - monitor.subTask(ManagedMakeMessages - .getResourceString(REFRESH)); - try { - currentProject.refreshLocal( - IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - monitor.subTask(ManagedMakeMessages - .getResourceString(REFRESH_ERROR)); - } - } else { - errMsg = launcher.getErrorMessage(); - } - - // Report either the success or failure of our mission - buf = new StringBuffer(); - if (errMsg != null && errMsg.length() > 0) { - String errorDesc = ManagedMakeMessages - .getResourceString(BUILD_ERROR); - buf.append(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$ - } else { - // Report a successful build - String successMsg = ManagedMakeMessages - .getFormattedString(BUILD_FINISHED, - currentProject.getName()); - buf.append(successMsg); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - } - - // Write message on the console - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - epmOutputStream.close(); - - // Generate any error markers that the build has discovered - monitor.subTask(ManagedMakeMessages - .getResourceString(MARKERS)); - addBuilderMarkers(epm); - epm.reportProblems(); - consoleOutStream.close(); - } - } - } catch (Exception e) { - forgetLastBuiltState(); - } finally { - getGenerationProblems().clear(); - } - } - - /* (non-Javadoc) - * Removes the IMarkers for the project specified in the argument if the - * project exists, and is open. - * - * @param project - */ - private void removeAllMarkers(IProject project) { - if (project == null || !project.isAccessible()) return; - - // Clear out the problem markers - IWorkspace workspace = project.getWorkspace(); - IMarker[] markers; - try { - markers = project.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - } catch (CoreException e) { - // Handled just about every case in the sanity check - return; - } - if (markers != null) { - try { - workspace.deleteMarkers(markers); - } catch (CoreException e) { - // The only situation that might cause this is some sort of resource change event - return; - } - } - } -} +/******************************************************************************* + * Copyright (c) 2002, 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 Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CommandLauncher; +import org.eclipse.cdt.core.ConsoleOutputStream; +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.IMarkerGenerator; +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.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +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.IResourceDeltaVisitor; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +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.MultiStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * This is the incremental builder associated with a managed build project. It dynamically + * decides the makefile generator it wants to use for a specific target. + * + * @since 1.2 + */ +public class GeneratedMakefileBuilder extends ACBuilder { + + /** + * @since 1.2 + */ + public class ResourceDeltaVisitor implements IResourceDeltaVisitor { + private String buildGoalName; + private IManagedBuildInfo buildInfo; + private boolean incrBuildNeeded = false; + private boolean fullBuildNeeded = false; + private List reservedNames; + + /** + * + */ + public ResourceDeltaVisitor(IManagedBuildInfo info) { + buildInfo = info; + String ext = buildInfo.getBuildArtifactExtension(); + //try to resolve build macros in the build artifact extension + try{ + ext = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + ext, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + String name = buildInfo.getBuildArtifactName(); + //try to resolve build macros in the build artifact name + try{ + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + name, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + name = resolved; + } catch (BuildMacroException e){ + } + + if (ext.length() > 0) { + buildGoalName = buildInfo.getOutputPrefix(ext) + name + IManagedBuilderMakefileGenerator.DOT + ext; + } else { + buildGoalName = name; + } + reservedNames = Arrays.asList(new String[]{".cdtbuild", ".cdtproject", ".project"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * @param changedResource + * @return + */ + private boolean isGeneratedResource(IResource resource) { + // Is this a generated directory ... + IPath path = resource.getProjectRelativePath(); + String[] configNames = buildInfo.getConfigurationNames(); + for (int i = 0; i < configNames.length; i++) { + String name = configNames[i]; + IPath root = new Path(name); + // It is if it is a root of the resource pathname + if (root.isPrefixOf(path)) return true; + } + return false; + } + + /** + * @param resource + * @return + */ + private boolean isProjectFile(IResource resource) { + return reservedNames.contains(resource.getName()); + } + + public boolean shouldBuildIncr() { + return incrBuildNeeded; + } + + public boolean shouldBuildFull() { + return fullBuildNeeded; + } + + public boolean visit(IResourceDelta delta) throws CoreException { + IResource resource = delta.getResource(); + // If the project has changed, then a build is needed and we can stop + if (resource != null && resource.getProject() == getProject()) { + IResourceDelta[] kids = delta.getAffectedChildren(); + for (int index = kids.length - 1; index >= 0; --index) { + IResource changedResource = kids[index].getResource(); + if (changedResource instanceof IFolder) { + return true; + } else { + String name = changedResource.getName(); + if ((!name.equals(buildGoalName) && + // TODO: Also need to check for secondary outputs + (changedResource.isDerived() || + (isProjectFile(changedResource)) || + (isGeneratedResource(changedResource))))) { + // The resource that changed has attributes which make it uninteresting, + // so don't do anything + ; + } + else { + // TODO: Should we do extra checks here to determine if a build is really needed, + // or do you just do exclusion checks like above? + // We could check for: + // o The build goal name + // o A secondary output + // o An input file to a tool: + // o Has an extension of a source file used by a tool + // o Has an extension of a header file used by a tool + // o Has the name of an input file specified in an InputType via: + // o An Option + // o An AdditionalInput + // + //if (resourceName.equals(buildGoalName) || + // (buildInfo.buildsFileType(ext) || buildInfo.isHeaderFile(ext))) { + + // We need to do an incremental build, at least + incrBuildNeeded = true; + if (kids[index].getKind() == IResourceDelta.REMOVED) { + // If a meaningful resource was removed, then force a full build + // This is required because an incremental build will trigger make to + // do nothing for a missing source, since the state after the file + // removal is uptodate, as far as make is concerned + // A full build will clean, and ultimately trigger a relink without + // the object generated from the deleted source, which is what we want + fullBuildNeeded = true; + // There is no point in checking anything else since we have + // decided to do a full build anyway + break; + } + + //} + } + } + } + return false; + } + return true; + } + } + + // String constants + private static final String BUILD_ERROR = "ManagedMakeBuilder.message.error"; //$NON-NLS-1$ + private static final String BUILD_FINISHED = "ManagedMakeBuilder.message.finished"; //$NON-NLS-1$ + private static final String CONSOLE_HEADER = "ManagedMakeBuilder.message.console.header"; //$NON-NLS-1$ + private static final String ERROR_HEADER = "GeneratedmakefileBuilder error ["; //$NON-NLS-1$ + private static final String MAKE = "ManagedMakeBuilder.message.make"; //$NON-NLS-1$ + private static final String MARKERS = "ManagedMakeBuilder.message.creating.markers"; //$NON-NLS-1$ + private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ + private static final String NOTHING_BUILT = "ManagedMakeBuilder.message.no.build"; //$NON-NLS-1$ + private static final String REFRESH = "ManagedMakeBuilder.message.updating"; //$NON-NLS-1$ + private static final String REFRESH_ERROR = BUILD_ERROR + ".refresh"; //$NON-NLS-1$ + private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$ + private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$ + private static final String TYPE_CLEAN = "ManagedMakeBuilder.type.clean"; //$NON-NLS-1$ + private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$ + private static final String WARNING_UNSUPPORTED_CONFIGURATION = "ManagedMakeBuilder.warning.unsupported.configuration"; //$NON-NLS-1$ + public static boolean VERBOSE = false; + + // Local variables + protected Vector generationProblems; + protected IProject[] referencedProjects; + protected List resourcesToBuild; + public static void outputTrace(String resourceName, String message) { + if (VERBOSE) { + System.out.println(TRACE_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); + } + } + + public static void outputError(String resourceName, String message) { + if (VERBOSE) { + System.err.println(ERROR_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); + } + } + + /** + * Zero-argument constructor needed to fulfill the contract of an + * incremental builder. + */ + public GeneratedMakefileBuilder() { + } + + /** + * @param epm + */ + private void addBuilderMarkers(ErrorParserManager epm) { + IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); + Iterator iter = getGenerationProblems().iterator(); + while (iter.hasNext()) { + IStatus stat = (IStatus)iter.next(); + IResource location = root.findMember(stat.getMessage()); + if (stat.getCode() == IManagedBuilderMakefileGenerator.SPACES_IN_PATH) { + epm.generateMarker(location, -1, ManagedMakeMessages.getResourceString("MakefileGenerator.error.spaces"), IMarkerGenerator.SEVERITY_WARNING, null); //$NON-NLS-1$ + } + } + } + + /* (non-javadoc) + * Emits a message to the console indicating that there were no source files to build + * @param buildType + * @param status + * @param configName + */ + private void emitNoSourceMessage(int buildType, IStatus status, String configName) throws CoreException { + try { + StringBuffer buf = new StringBuffer(); + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(getProject()); + ConsoleOutputStream consoleOutStream = console.getOutputStream(); + // Report a successful clean + String[] consoleHeader = new String[3]; + if (buildType == FULL_BUILD || buildType == INCREMENTAL_BUILD) { + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); + } else { + consoleHeader[0] = new String(); + outputError(getProject().getName(), "The given build type is not supported in this context"); //$NON-NLS-1$ + } + consoleHeader[1] = configName; + consoleHeader[2] = getProject().getName(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(status.getMessage()); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + consoleOutStream.close(); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } catch (IOException io) { // Ignore console failures... + } + } + + /** + * + * This method has been created so that subclasses can override how the builder obtains its + * build info. The default implementation retrieves the info from the build manager. + * + * @return An IManagedBuildInfo object representing the build info. + */ + protected IManagedBuildInfo getBuildInfo() { + return ManagedBuildManager.getBuildInfo(getProject()); + } + + /* (non-Javadoc) + * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) + */ + protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { + // We should always tell the build system what projects we reference + referencedProjects = getProject().getReferencedProjects(); + + // Get the build information + IManagedBuildInfo info = getBuildInfo(); + if (info == null) { + outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ + return referencedProjects; + } + if (!info.isValid()) { + outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ + return referencedProjects; + } + + // Create a makefile generator for the build + IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize(getProject(), info, monitor); + + // So let's figure out why we got called + if (kind == FULL_BUILD || info.needsRebuild()) { + outputTrace(getProject().getName(), "Full build needed/requested"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } + else if (kind == AUTO_BUILD && info.needsRebuild()) { + outputTrace(getProject().getName(), "Autobuild requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } + else { + // Create a delta visitor to make sure we should be rebuilding + ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(info); + IResourceDelta delta = getDelta(getProject()); + if (delta == null) { + outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } + else { + delta.accept(visitor); + if (visitor.shouldBuildFull()) { + outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } else if (visitor.shouldBuildIncr()) { + outputTrace(getProject().getName(), "Incremental build requested"); //$NON-NLS-1$ + incrementalBuild(delta, info, generator, monitor); + } + else if (referencedProjects != null) { + // Also check to see is any of the dependent projects changed + for (int i=0; iOperationCanceledException. + * + * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() + */ + public void checkCancel(IProgressMonitor monitor) { + if (monitor != null && monitor.isCanceled()) { + outputTrace(getProject().getName(), "Build cancelled"); //$NON-NLS-1$ + forgetLastBuiltState(); + throw new OperationCanceledException(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.IncrementalProjectBuilder#clean(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void clean(IProgressMonitor monitor) throws CoreException { + referencedProjects = getProject().getReferencedProjects(); + outputTrace(getProject().getName(), "Clean build requested"); //$NON-NLS-1$ + IManagedBuildInfo info = getBuildInfo(); + if (info == null) { + outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ + return; + } + if (!info.isValid()) { + outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ + return; + } + IPath buildDirPath = getProject().getLocation().append(info.getConfigurationName()); + IWorkspace workspace = CCorePlugin.getWorkspace(); + IContainer buildDir = workspace.getRoot().getContainerForLocation(buildDirPath); + if (buildDir == null || !buildDir.isAccessible()){ + outputError(buildDir.getName(), "Could not delete the build directory"); //$NON-NLS-1$ + return; + } + String status; + try { + // try the brute force approach first + status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.deleting.output", buildDir.getName()); //$NON-NLS-1$ + monitor.subTask(status); + workspace.delete(new IResource[]{buildDir}, true, monitor); + StringBuffer buf = new StringBuffer(); + // write to the console + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(getProject()); + ConsoleOutputStream consoleOutStream = console.getOutputStream(); + String[] consoleHeader = new String[3]; + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); + consoleHeader[1] = info.getConfigurationName(); + consoleHeader[2] = getProject().getName(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + buf = new StringBuffer(); + // Report a successful clean + String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); + buf.append(successMsg); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + consoleOutStream.close(); + } catch (CoreException e) { + // Create a makefile generator for the build + status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.build.clean", buildDir.getName()); //$NON-NLS-1$ + monitor.subTask(status); + IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize(getProject(), info, monitor); + cleanBuild(info, generator, monitor); + } catch (IOException io) {} // Ignore console failures... + } + + /* (non-Javadoc) + * @param info + * @param generator + * @param monitor + */ + protected void cleanBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { + // Make sure that there is a top level directory and a set of makefiles + IPath buildDir = generator.getBuildWorkingDir(); + if (buildDir == null) { + buildDir = new Path(info.getConfigurationName()); + } + IPath makefilePath = getProject().getLocation().append(buildDir.append(generator.getMakefileName())); + IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); + IFile makefile = root.getFileForLocation(makefilePath); + + if (buildDir != null && makefile != null && makefile.isAccessible()) { + // invoke make with the clean argument + String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + checkCancel(monitor); + invokeMake(CLEAN_BUILD, buildDir, info, generator, monitor); + } + } + + /* (non-Javadoc) + * @param info + * @param generator + * @param monitor + */ + protected void fullBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { + // Always need one of these bad boys + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + checkCancel(monitor); + //If the previous builder invocation was cancelled, generated files might be corrupted + //in case one or more of the generated makefiles (e.g. dep files) are corrupted, + //the builder invocation might fail because of the possible syntax errors, so e.g. "make clean" will not work + //we need to explicitly clean the generated directories + clean(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN)); + + // Regenerate the makefiles for this project + checkCancel(monitor); + String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.rebuild.makefiles", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + //generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize(getProject(), info, monitor); + MultiStatus result = generator.regenerateMakefiles(); + if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { + IStatus[] kids = result.getChildren(); + for (int index = 0; index < kids.length; ++index) { + // One possibility is that there is nothing to build + IStatus status = kids[index]; + if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { + // Inform the user, via the console, that there is nothing to build + // either because there are no buildable sources files or all potentially + // buildable files have been excluded from build + try { + emitNoSourceMessage(FULL_BUILD, status, info.getConfigurationName()); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } + // Dude, we're done + return; + } else { + // Stick this in the list of stuff to warn the user about + getGenerationProblems().add(status); + } + } + } + + // Now call make + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + IPath topBuildDir = generator.getBuildWorkingDir(); + if (topBuildDir != null) { + invokeMake(FULL_BUILD, topBuildDir, info, generator, monitor); + } else { + statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + return; + } + + // Now regenerate the dependencies + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.regen.deps", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + try { + generator.regenerateDependencies(false); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } + + // Build finished message + statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + } + + /* (non-Javadoc) + * + * @return + */ + private Vector getGenerationProblems() { + if (generationProblems == null) { + generationProblems = new Vector(); + } + return generationProblems; + } + + /* (non-javadoc) + * Answers an array of strings with the proper make targets + * for a build with no custom prebuild/postbuild steps + * + * @param fullBuild + * @return + */ + protected String[] getMakeTargets(int buildType) { + List args = new ArrayList(); + switch (buildType) { + case CLEAN_BUILD: + args.add("clean"); //$NON-NLS-1$ + break; + case FULL_BUILD: + case INCREMENTAL_BUILD: + args.add("all"); //$NON-NLS-1$ + break; + } + return (String[])args.toArray(new String[args.size()]); + } + + /** + * @return + */ + protected List getResourcesToBuild() { + if (resourcesToBuild == null) { + resourcesToBuild = new ArrayList(); + } + return resourcesToBuild; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.resources.ACBuilder#getWorkingDirectory() + */ + public IPath getWorkingDirectory() { + return getProject().getLocation(); + } + + /* (non-Javadoc) + * @param delta + * @param info + * @param monitor + * @throws CoreException + */ + protected void incrementalBuild(IResourceDelta delta, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { + // Need to report status to the user + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + // Ask the makefile generator to generate any makefiles needed to build delta + checkCancel(monitor); + String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.update.makefiles", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + MultiStatus result = generator.generateMakefiles(delta); + if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { + IStatus[] kids = result.getChildren(); + for (int index = 0; index < kids.length; ++index) { + // One possibility is that there is nothing to build + IStatus status = kids[index]; + if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { + // Inform the user, via the console, that there is nothing to build + // either because there are no buildable sources files or all potentially + // buildable files have been excluded from build + try { + emitNoSourceMessage(INCREMENTAL_BUILD, status, info.getConfigurationName()); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } + // Dude, we're done + return; + } else { + // Stick this in the list of stuff to warn the user about + getGenerationProblems().add(status); + } + } + } + + // Run the build + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + IPath buildDir = generator.getBuildWorkingDir(); + if (buildDir != null) { + invokeMake(INCREMENTAL_BUILD, buildDir, info, generator, monitor); + } else { + statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + return; + } + + // Generate the dependencies for all changes + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.updating.deps", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + try { + generator.generateDependencies(); + } catch (CoreException e) { + throw e; + } + + // Build finished message + statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); +} + + /* (non-Javadoc) + * @param buildType + * @param buildDir + * @param info + * @param generator + * @param monitor + */ + protected void invokeMake(int buildType, IPath buildDir, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { + // Get the project and make sure there's a monitor to cancel the build + IProject currentProject = getProject(); + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + try { + // Figure out the working directory for the build and make sure there is a makefile there + IPath workingDirectory = getWorkingDirectory().append(buildDir); + IWorkspace workspace = currentProject.getWorkspace(); + if (workspace == null) { + return; + } + IWorkspaceRoot root = workspace.getRoot(); + if (root == null) { + return; + } + IPath makefile = workingDirectory.append(generator.getMakefileName()); + if (root.getFileForLocation(makefile) == null) { + return; + } + + // Flag to the user that make is about to be called + String makeCmd = info.getBuildCommand(); + //try to resolve the build macros in the builder command + try{ + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + makeCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + makeCmd = resolved; + } catch (BuildMacroException e){ + } + + IPath makeCommand = new Path(makeCmd); + if (makeCommand != null) { + String[] msgs = new String[2]; + msgs[0] = makeCommand.toString(); + msgs[1] = currentProject.getName(); + monitor.subTask(ManagedMakeMessages.getFormattedString(MAKE, msgs)); + + // Get a build console for the project + StringBuffer buf = new StringBuffer(); + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(currentProject); + ConsoleOutputStream consoleOutStream = console.getOutputStream(); + String[] consoleHeader = new String[3]; + switch (buildType) { + case FULL_BUILD: + case INCREMENTAL_BUILD: + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); + break; + case CLEAN_BUILD: + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); + break; + } + + consoleHeader[1] = info.getConfigurationName(); + consoleHeader[2] = currentProject.getName(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + + IConfiguration cfg = info.getDefaultConfiguration(); + if(!cfg.isSupported()){ + buf.append(ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()})); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + } + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + + // Remove all markers for this project + removeAllMarkers(currentProject); + + // Get a launcher for the make command + String errMsg = null; + CommandLauncher launcher = new CommandLauncher(); + launcher.showCommand(true); + + // Set the environmennt + IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true,true); + String[] env = null; + ArrayList envList = new ArrayList(); + if (variables != null) { + for(int i = 0; i < variables.length; i++){ + envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$ + } + env = (String[]) envList.toArray(new String[envList.size()]); + } + + // Hook up an error parser manager + String[] errorParsers = info.getDefaultConfiguration().getErrorParserList(); + ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectory, this, errorParsers); + epm.setOutputStream(consoleOutStream); + // This variable is necessary to ensure that the EPM stream stay open + // until we explicitly close it. See bug#123302. + OutputStream epmOutputStream = epm.getOutputStream(); + + // Get the arguments to be passed to make from build model + ArrayList makeArgs = new ArrayList(); + String arg = info.getBuildArguments(); + if (arg.length() > 0) { + String[] args = arg.split("\\s"); //$NON-NLS-1$ + for (int i = 0; i < args.length; ++i) { + makeArgs.add(args[i]); + } + } + + String[] makeTargets; + String prebuildStep = info.getPrebuildStep(); + //try to resolve the build macros in the prebuildStep + try{ + prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + prebuildStep, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + cfg); + } catch (BuildMacroException e){ + } + boolean prebuildStepPresent = (prebuildStep.length() > 0); + Process proc = null; + boolean isuptodate = false; + + if (prebuildStepPresent) { + ArrayList premakeArgs = (ArrayList) makeArgs.clone(); + String[] premakeTargets; + switch (buildType) { + case INCREMENTAL_BUILD: { + // For an incremental build with a prebuild step: + // Check the status of the main build with "make -q main-build" + // If up to date: + // then: don't invoke the prebuild step, which should be run only if + // something needs to be built in the main build + // else: invoke the prebuild step and the main build step + premakeArgs.add("-q"); //$NON-NLS-1$ + premakeArgs.add("main-build"); //$NON-NLS-1$ + premakeTargets = (String[]) premakeArgs.toArray(new String[premakeArgs.size()]); + proc = launcher.execute(makeCommand, premakeTargets, env, workingDirectory); + if (proc != null) { + try { + // Close the input of the process since we will never write to it + proc.getOutputStream().close(); + } catch (IOException e) { + } + if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), + new SubProgressMonitor(monitor, + IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { + errMsg = launcher.getErrorMessage(); + } + } else { + errMsg = launcher.getErrorMessage(); + } + + if ((errMsg != null && errMsg.length() > 0) || proc == null) { + // Can't tell if the build is needed, so assume it is, and let any errors be triggered + // when the "real" build is invoked below + makeArgs.add("pre-build"); //$NON-NLS-1$ + makeArgs.add("main-build"); //$NON-NLS-1$ + } else { + // The "make -q" command launch was successful + if (proc.exitValue() == 0) { + // If the status value returned from "make -q" is 0, then the build state is up-to-date + isuptodate = true; + // Report that the build was up to date, and thus nothing needs to be built + String uptodateMsg = ManagedMakeMessages + .getFormattedString(NOTHING_BUILT, currentProject.getName()); + buf = new StringBuffer(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + buf.append(uptodateMsg); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + // Write message on the console + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + epmOutputStream.close(); + consoleOutStream.close(); + } else { + // The status value was other than 0, so press on with the build process + makeArgs.add("pre-build"); //$NON-NLS-1$ + makeArgs.add("main-build"); //$NON-NLS-1$ + } + } + break; + } + case FULL_BUILD: { + makeArgs.add("clean"); //$NON-NLS-1$ + makeArgs.add("pre-build"); //$NON-NLS-1$ + makeArgs.add("main-build"); //$NON-NLS-1$ + break; + } + case CLEAN_BUILD: { + makeArgs.add("clean"); //$NON-NLS-1$ + break; + } + } + + } else { + // No prebuild step + // + makeArgs.addAll(Arrays.asList(getMakeTargets(buildType))); + } + + makeTargets = (String[]) makeArgs.toArray(new String[makeArgs.size()]); + + // Launch make - main invocation + if (!isuptodate) { + proc = launcher.execute(makeCommand, makeTargets, env, + workingDirectory); + if (proc != null) { + try { + // Close the input of the process since we will never write to it + proc.getOutputStream().close(); + } catch (IOException e) { + } + + if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), + new SubProgressMonitor(monitor, + IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { + errMsg = launcher.getErrorMessage(); + } + + // Force a resync of the projects without allowing the user to cancel. + // This is probably unkind, but short of this there is no way to insure + // the UI is up-to-date with the build results + monitor.subTask(ManagedMakeMessages + .getResourceString(REFRESH)); + try { + currentProject.refreshLocal( + IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + monitor.subTask(ManagedMakeMessages + .getResourceString(REFRESH_ERROR)); + } + } else { + errMsg = launcher.getErrorMessage(); + } + + // Report either the success or failure of our mission + buf = new StringBuffer(); + if (errMsg != null && errMsg.length() > 0) { + String errorDesc = ManagedMakeMessages + .getResourceString(BUILD_ERROR); + buf.append(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$ + } else { + // Report a successful build + String successMsg = ManagedMakeMessages + .getFormattedString(BUILD_FINISHED, + currentProject.getName()); + buf.append(successMsg); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + } + + // Write message on the console + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + epmOutputStream.close(); + + // Generate any error markers that the build has discovered + monitor.subTask(ManagedMakeMessages + .getResourceString(MARKERS)); + addBuilderMarkers(epm); + epm.reportProblems(); + consoleOutStream.close(); + } + } + } catch (Exception e) { + forgetLastBuiltState(); + } finally { + getGenerationProblems().clear(); + } + } + + /* (non-Javadoc) + * Removes the IMarkers for the project specified in the argument if the + * project exists, and is open. + * + * @param project + */ + private void removeAllMarkers(IProject project) { + if (project == null || !project.isAccessible()) return; + + // Clear out the problem markers + IWorkspace workspace = project.getWorkspace(); + IMarker[] markers; + try { + markers = project.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + // Handled just about every case in the sanity check + return; + } + if (markers != null) { + try { + workspace.deleteMarkers(markers); + } catch (CoreException e) { + // The only situation that might cause this is some sort of resource change event + return; + } + } + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java index a8792781bbc..08dcc9189b0 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java @@ -1,568 +1,568 @@ -/******************************************************************************* - * Copyright (c) 2005 Symbian Ltd 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: - * Symbian Ltd - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -/** - * Implements the functionality that is needed to hold options and option - * categories. In CDT 3.0, the functionality has been moved from ITool and - * Tool to this class. - * - * This class is intended to be used as base class for all MBS grammar - * elements that can hold Options and Option Categories. These are currently - * Tool and ToolChain. - * - * Note that the member superClass must be shared with the - * derived class. This requires to wrap this member by access functions - * in the derived class or frequent casts, because the type of superClass - * in HoldsOptions must be IHoldOptions. Further - * note that the member resolved must inherit the value of its - * derived class. This achieved through the constructor. - * - * @since 3.0 - */ -public class HoldsOptions extends BuildObject implements IHoldsOptions { - - private static final IOptionCategory[] EMPTY_CATEGORIES = new IOptionCategory[0]; - - // Members that are to be shared with the derived class - protected IHoldsOptions superClass; - // Members that must have the same values on creation as the derived class - private boolean resolved; - // Parent and children - private Vector categoryIds; - private Map categoryMap; - private List childOptionCategories; - private Vector optionList; - private Map optionMap; - // Miscellaneous - private boolean isDirty = false; - - /* - * C O N S T R U C T O R S - */ - - private HoldsOptions() { - // prevent accidental construction of class without setting up - // resolved - } - - protected HoldsOptions(boolean resolved) { - this.resolved = resolved; - } - - /** - * Copies children of HoldsOptions. Helper function for - * derived constructors. - * - * @param source The children of the source will be cloned and added - * to the class itself. - */ - protected void copyChildren(HoldsOptions source) { - - // Note: This function ignores OptionCategories since they should not be - // found on an non-extension tools - if (source.optionList != null) { - Iterator iter = source.getOptionList().listIterator(); - while (iter.hasNext()) { - Option option = (Option) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (option.getSuperClass() != null) { - subId = option.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = option.getSuperClass().getName(); - } else { - subId = option.getId() + "." + nnn; //$NON-NLS-1$ - subName = option.getName(); - } - Option newOption = new Option(this, subId, subName, option); - addOption(newOption); - } - } - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /** - * Load child element from XML element if it is of the correct type - * - * @param element which is loaded as child only iff it is of the correct type - * @return true when a child has been loaded, false otherwise - */ - protected boolean loadChild(Node element) { - if (element.getNodeName().equals(ITool.OPTION)) { - Option option = new Option(this, (Element)element); - addOption(option); - return true; - } else if (element.getNodeName().equals(ITool.OPTION_CAT)) { - new OptionCategory(this, (Element)element); - return true; - } - return false; - } - - /** - * Load child element from configuration element if it is of the correct type - * - * @param element which is loaded as child only iff it is of the correct type - * @return true when a child has been loaded, false otherwise - */ - protected boolean loadChild(IManagedConfigElement element) { - if (element.getName().equals(ITool.OPTION)) { - Option option = new Option(this, element); - addOption(option); - return true; - } else if (element.getName().equals(ITool.OPTION_CAT)) { - new OptionCategory(this, element); - return true; - } - return false; - } - - /** - * Persist the tool to the project file. Intended to be called by derived - * class only, thus do not handle exceptions. - * - * @param doc - * @param element - * @throws BuildException - */ - protected void serialize(Document doc, Element element) throws BuildException { - - Iterator iter; - - if (childOptionCategories != null) { - iter = childOptionCategories.listIterator(); - while (iter.hasNext()) { - OptionCategory optCat = (OptionCategory)iter.next(); - Element optCatElement = doc.createElement(OPTION); - element.appendChild(optCatElement); - optCat.serialize(doc, optCatElement); - } - } - - List optionElements = getOptionList(); - iter = optionElements.listIterator(); - while (iter.hasNext()) { - Option option = (Option) iter.next(); - Element optionElement = doc.createElement(OPTION); - element.appendChild(optionElement); - option.serialize(doc, optionElement); - } -} - - /* - * M E T H O D S M O V E D F R O M I T O O L I N 3 . 0 - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOption(IOption, String, String, boolean) - */ - public IOption createOption(IOption superClass, String Id, String name, boolean isExtensionElement) { - Option option = new Option(this, superClass, Id, name, isExtensionElement); - addOption(option); - if(!isExtensionElement) - setDirty(true); - return option; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOptions(IHoldsOptions) - */ - public void createOptions(IHoldsOptions superClass) { - Iterator iter = ((HoldsOptions)superClass).getOptionList().listIterator(); - while (iter.hasNext()) { - Option optionChild = (Option) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId = optionChild.getId() + "." + nnn; //$NON-NLS-1$ - createOption(optionChild, subId, optionChild.getName(), false); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#removeOption(IOption) - */ - public void removeOption(IOption option) { - getOptionList().remove(option); - getOptionMap().remove(option.getId()); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptions() - */ - public IOption[] getOptions() { - IOption[] options = null; - // Merge our options with our superclass' options. - if (superClass != null) { - options = superClass.getOptions(); - } - // Our options take precedence. - Vector ourOpts = getOptionList(); - if (options != null) { - for (int i = 0; i < ourOpts.size(); i++) { - int j = options.length; - IOption ourOpt = (IOption)ourOpts.get(i); - if (ourOpt.getSuperClass() != null) { - String matchId = ourOpt.getSuperClass().getId(); - search: - for (j = 0; j < options.length; j++) { - IOption superHolderOption = options[j]; - if (((Option)superHolderOption).wasOptRef()) { - superHolderOption = superHolderOption.getSuperClass(); - } - while (superHolderOption != null) { - if (matchId.equals(superHolderOption.getId())) { - options[j] = ourOpt; - break search; - } - superHolderOption = superHolderOption.getSuperClass(); - } - } - } - // No Match? Add it. - if (j == options.length) { - IOption[] newOptions = new IOption[options.length + 1]; - for (int k = 0; k < options.length; k++) { - newOptions[k] = options[k]; - } - newOptions[j] = ourOpt; - options = newOptions; - } - } - } else { - options = (IOption[])ourOpts.toArray(new IOption[ourOpts.size()]); - } - // Check for any invalid options. - int numInvalidOptions = 0; - int i; - for (i=0; i < options.length; i++) { - if (options[i].isValid() == false) { - numInvalidOptions++; - } - } - // Take invalid options out of the array, if there are any - if (numInvalidOptions > 0) { - int j = 0; - IOption[] newOptions = new IOption[options.length - numInvalidOptions]; - for (i=0; i < options.length; i++) { - if (options[i].isValid() == true) { - newOptions[j] = options[i]; - j++; - } - } - options = newOptions; - } - return options; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOption(java.lang.String) - */ - public IOption getOption(String id) { - return getOptionById(id); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptionById(java.lang.String) - */ - public IOption getOptionById(String id) { - IOption opt = (IOption)getOptionMap().get(id); - if (opt == null) { - if (superClass != null) { - return superClass.getOptionById(id); - } - } - if (opt == null) return null; - return opt.isValid() ? opt : null; - } - - /* (non-Javadoc) - * org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptionBySuperClassId(java.lang.String) - */ - public IOption getOptionBySuperClassId(String optionId) { - if (optionId == null) return null; - - // Look for an option with this ID, or an option with a superclass with this id - IOption[] options = getOptions(); - for (int i = 0; i < options.length; i++) { - IOption targetOption = options[i]; - IOption option = targetOption; - do { - if (optionId.equals(option.getId())) { - return targetOption.isValid() ? targetOption : null; - } - option = option.getSuperClass(); - } while (option != null); - } - - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getChildCategories() - */ - public IOptionCategory[] getChildCategories() { - IOptionCategory[] superCats = EMPTY_CATEGORIES; - IOptionCategory[] ourCats = EMPTY_CATEGORIES; - // Merge our option categories with our superclass' option categories. - // Note that these are two disjoint sets of categories because - // categories do not use derivation AND object Id's are unique. Thus - // they are merely sequentially added. - if (superClass != null) { - superCats = superClass.getChildCategories(); - } - if ( childOptionCategories != null ) { - ourCats = (IOptionCategory[])childOptionCategories.toArray(new IOptionCategory[childOptionCategories.size()]); - } - // Add the two arrays together; - if (superCats.length > 0 || ourCats.length > 0) { - IOptionCategory[] allCats = new IOptionCategory[superCats.length + ourCats.length]; - int j; - for (j=0; j < superCats.length; j++) - allCats[j] = superCats[j]; - for (j=0; j < ourCats.length; j++) - allCats[j+superCats.length] = ourCats[j]; - return allCats; - } - // Nothing found, return EMPTY_CATEGORIES - return EMPTY_CATEGORIES; - } - - /* - * M E T H O D S M O V E D F R O M T O O L I N 3 . 0 - */ - - /* (non-Javadoc) - * Memory-safe way to access the vector of category IDs - */ - private Vector getCategoryIds() { - if (categoryIds == null) { - categoryIds = new Vector(); - } - return categoryIds; - } - - /** - * @param category - */ - public void addChildCategory(IOptionCategory category) { - if (childOptionCategories == null) - childOptionCategories = new ArrayList(); - childOptionCategories.add(category); - } - - /** - * @param option - */ - public void addOption(Option option) { - getOptionList().add(option); - getOptionMap().put(option.getId(), option); - } - /* (non-Javadoc) - * Memeory-safe way to access the map of category IDs to categories - */ - private Map getCategoryMap() { - if (categoryMap == null) { - categoryMap = new HashMap(); - } - return categoryMap; - } - - /* (non-Javadoc) - * Memory-safe way to access the list of options - */ - private Vector getOptionList() { - if (optionList == null) { - optionList = new Vector(); - } - return optionList; - } - - /* (non-Javadoc) - * Memory-safe way to access the list of IDs to options - */ - private Map getOptionMap() { - if (optionMap == null) { - optionMap = new HashMap(); - } - return optionMap; - } - - /* (non-Javadoc) - * org.eclipse.cdt.managedbuilder.core.IHoldsOptions#addOptionCategory() - */ - public void addOptionCategory(IOptionCategory category) { - // To preserve the order of the categories, record the ids in the order they are read - getCategoryIds().add(category.getId()); - // Map the categories by ID for resolution later - getCategoryMap().put(category.getId(), category); - } - - /* (non-Javadoc) - * org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptionCategory() - */ - public IOptionCategory getOptionCategory(String id) { - IOptionCategory cat = (IOptionCategory)getCategoryMap().get(id); - if (cat == null && superClass != null) { - // Look up the holders superclasses to find the category - return superClass.getOptionCategory(id); - } - return cat; - } - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * Implements isDirty() for children of HoldsOptions. Intended to be - * called by derived class. - */ - protected boolean isDirty() { - // If I need saving, just say yes - if (isDirty) return true; - - // Otherwise see if any options need saving - List optionElements = getOptionList(); - Iterator iter = optionElements.listIterator(); - while (iter.hasNext()) { - Option option = (Option) iter.next(); - if (option.isDirty()) return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * Implements setDirty() for children of HoldsOptions. Intended to be - * called by derived class. - */ - protected void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to the children - if (!isDirty) { - List optionElements = getOptionList(); - Iterator iter = optionElements.listIterator(); - while (iter.hasNext()) { - Option option = (Option) iter.next(); - if(!option.isExtensionElement()) - option.setDirty(false); - } - } - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references. Intended to be - * called by derived class. - */ - protected void resolveReferences() { - if (!resolved) { - resolved = true; - // Call resolveReferences on our children - Iterator optionIter = getOptionList().iterator(); - while (optionIter.hasNext()) { - Option current = (Option)optionIter.next(); - current.resolveReferences(); - } - // Somewhat wasteful, but use the vector to retrieve the categories in proper order - Iterator catIter = getCategoryIds().iterator(); - while (catIter.hasNext()) { - String id = (String)catIter.next(); - IOptionCategory current = (IOptionCategory)getCategoryMap().get(id); - if (current instanceof Tool) { - ((Tool)current).resolveReferences(); - } else if (current instanceof ToolChain) { - ((ToolChain)current).resolveReferences(); - } else if (current instanceof OptionCategory) { - ((OptionCategory)current).resolveReferences(); - } - } - } - } - - public IOption getOptionToSet(IOption option, boolean adjustExtension) throws BuildException{ - IOption setOption = null; - if(option.getOptionHolder() != this) - option = getOptionBySuperClassId(option.getId()); - - if(adjustExtension){ - for(; option != null && !option.isExtensionElement(); option=option.getSuperClass()){} - - if(option != null){ - IHoldsOptions holder = option.getOptionHolder(); - if(holder == this) - setOption = option; - else { - IOption newSuperClass = option; - if (((Option)option).wasOptRef()) { - newSuperClass = option.getSuperClass(); - } - // Create a new extension Option element - String subId; - String version = ManagedBuildManager.getVersionFromIdAndVersion(newSuperClass.getId()); - String baseId = ManagedBuildManager.getIdFromIdAndVersion(newSuperClass.getId()); - if ( version != null) { - subId = baseId + ".adjusted." + new Integer(ManagedBuildManager.getRandomNumber()) + "_" + version; //$NON-NLS-1$ //$NON-NLS-2$ - } else { - subId = baseId + ".adjusted." + new Integer(ManagedBuildManager.getRandomNumber()); //$NON-NLS-1$ - } - setOption = createOption(newSuperClass, subId, null, true); - ((Option)setOption).setAdjusted(true); - setOption.setValueType(option.getValueType()); - } - } - } else { - if(option.getOptionHolder() == this && !option.isExtensionElement()){ - setOption = option; - } else { - IOption newSuperClass = option; - for(; - newSuperClass != null && !newSuperClass.isExtensionElement(); - newSuperClass = newSuperClass.getSuperClass()){} - - if (((Option)newSuperClass).wasOptRef()) { - newSuperClass = newSuperClass.getSuperClass(); - } - - if(((Option)newSuperClass).isAdjustedExtension()){ - newSuperClass = newSuperClass.getSuperClass(); - } - // Create an Option element for the managed build project file (.CDTBUILD) - String subId; - subId = ManagedBuildManager.calculateChildId(newSuperClass.getId(), null); - setOption = createOption(newSuperClass, subId, null, false); - setOption.setValueType(option.getValueType()); - } - } - return setOption; - } -} +/******************************************************************************* + * Copyright (c) 2005 Symbian Ltd 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: + * Symbian Ltd - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionCategory; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Implements the functionality that is needed to hold options and option + * categories. In CDT 3.0, the functionality has been moved from ITool and + * Tool to this class. + * + * This class is intended to be used as base class for all MBS grammar + * elements that can hold Options and Option Categories. These are currently + * Tool and ToolChain. + * + * Note that the member superClass must be shared with the + * derived class. This requires to wrap this member by access functions + * in the derived class or frequent casts, because the type of superClass + * in HoldsOptions must be IHoldOptions. Further + * note that the member resolved must inherit the value of its + * derived class. This achieved through the constructor. + * + * @since 3.0 + */ +public class HoldsOptions extends BuildObject implements IHoldsOptions { + + private static final IOptionCategory[] EMPTY_CATEGORIES = new IOptionCategory[0]; + + // Members that are to be shared with the derived class + protected IHoldsOptions superClass; + // Members that must have the same values on creation as the derived class + private boolean resolved; + // Parent and children + private Vector categoryIds; + private Map categoryMap; + private List childOptionCategories; + private Vector optionList; + private Map optionMap; + // Miscellaneous + private boolean isDirty = false; + + /* + * C O N S T R U C T O R S + */ + + private HoldsOptions() { + // prevent accidental construction of class without setting up + // resolved + } + + protected HoldsOptions(boolean resolved) { + this.resolved = resolved; + } + + /** + * Copies children of HoldsOptions. Helper function for + * derived constructors. + * + * @param source The children of the source will be cloned and added + * to the class itself. + */ + protected void copyChildren(HoldsOptions source) { + + // Note: This function ignores OptionCategories since they should not be + // found on an non-extension tools + if (source.optionList != null) { + Iterator iter = source.getOptionList().listIterator(); + while (iter.hasNext()) { + Option option = (Option) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (option.getSuperClass() != null) { + subId = option.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = option.getSuperClass().getName(); + } else { + subId = option.getId() + "." + nnn; //$NON-NLS-1$ + subName = option.getName(); + } + Option newOption = new Option(this, subId, subName, option); + addOption(newOption); + } + } + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /** + * Load child element from XML element if it is of the correct type + * + * @param element which is loaded as child only iff it is of the correct type + * @return true when a child has been loaded, false otherwise + */ + protected boolean loadChild(Node element) { + if (element.getNodeName().equals(ITool.OPTION)) { + Option option = new Option(this, (Element)element); + addOption(option); + return true; + } else if (element.getNodeName().equals(ITool.OPTION_CAT)) { + new OptionCategory(this, (Element)element); + return true; + } + return false; + } + + /** + * Load child element from configuration element if it is of the correct type + * + * @param element which is loaded as child only iff it is of the correct type + * @return true when a child has been loaded, false otherwise + */ + protected boolean loadChild(IManagedConfigElement element) { + if (element.getName().equals(ITool.OPTION)) { + Option option = new Option(this, element); + addOption(option); + return true; + } else if (element.getName().equals(ITool.OPTION_CAT)) { + new OptionCategory(this, element); + return true; + } + return false; + } + + /** + * Persist the tool to the project file. Intended to be called by derived + * class only, thus do not handle exceptions. + * + * @param doc + * @param element + * @throws BuildException + */ + protected void serialize(Document doc, Element element) throws BuildException { + + Iterator iter; + + if (childOptionCategories != null) { + iter = childOptionCategories.listIterator(); + while (iter.hasNext()) { + OptionCategory optCat = (OptionCategory)iter.next(); + Element optCatElement = doc.createElement(OPTION); + element.appendChild(optCatElement); + optCat.serialize(doc, optCatElement); + } + } + + List optionElements = getOptionList(); + iter = optionElements.listIterator(); + while (iter.hasNext()) { + Option option = (Option) iter.next(); + Element optionElement = doc.createElement(OPTION); + element.appendChild(optionElement); + option.serialize(doc, optionElement); + } +} + + /* + * M E T H O D S M O V E D F R O M I T O O L I N 3 . 0 + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOption(IOption, String, String, boolean) + */ + public IOption createOption(IOption superClass, String Id, String name, boolean isExtensionElement) { + Option option = new Option(this, superClass, Id, name, isExtensionElement); + addOption(option); + if(!isExtensionElement) + setDirty(true); + return option; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOptions(IHoldsOptions) + */ + public void createOptions(IHoldsOptions superClass) { + Iterator iter = ((HoldsOptions)superClass).getOptionList().listIterator(); + while (iter.hasNext()) { + Option optionChild = (Option) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId = optionChild.getId() + "." + nnn; //$NON-NLS-1$ + createOption(optionChild, subId, optionChild.getName(), false); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#removeOption(IOption) + */ + public void removeOption(IOption option) { + getOptionList().remove(option); + getOptionMap().remove(option.getId()); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptions() + */ + public IOption[] getOptions() { + IOption[] options = null; + // Merge our options with our superclass' options. + if (superClass != null) { + options = superClass.getOptions(); + } + // Our options take precedence. + Vector ourOpts = getOptionList(); + if (options != null) { + for (int i = 0; i < ourOpts.size(); i++) { + int j = options.length; + IOption ourOpt = (IOption)ourOpts.get(i); + if (ourOpt.getSuperClass() != null) { + String matchId = ourOpt.getSuperClass().getId(); + search: + for (j = 0; j < options.length; j++) { + IOption superHolderOption = options[j]; + if (((Option)superHolderOption).wasOptRef()) { + superHolderOption = superHolderOption.getSuperClass(); + } + while (superHolderOption != null) { + if (matchId.equals(superHolderOption.getId())) { + options[j] = ourOpt; + break search; + } + superHolderOption = superHolderOption.getSuperClass(); + } + } + } + // No Match? Add it. + if (j == options.length) { + IOption[] newOptions = new IOption[options.length + 1]; + for (int k = 0; k < options.length; k++) { + newOptions[k] = options[k]; + } + newOptions[j] = ourOpt; + options = newOptions; + } + } + } else { + options = (IOption[])ourOpts.toArray(new IOption[ourOpts.size()]); + } + // Check for any invalid options. + int numInvalidOptions = 0; + int i; + for (i=0; i < options.length; i++) { + if (options[i].isValid() == false) { + numInvalidOptions++; + } + } + // Take invalid options out of the array, if there are any + if (numInvalidOptions > 0) { + int j = 0; + IOption[] newOptions = new IOption[options.length - numInvalidOptions]; + for (i=0; i < options.length; i++) { + if (options[i].isValid() == true) { + newOptions[j] = options[i]; + j++; + } + } + options = newOptions; + } + return options; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOption(java.lang.String) + */ + public IOption getOption(String id) { + return getOptionById(id); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptionById(java.lang.String) + */ + public IOption getOptionById(String id) { + IOption opt = (IOption)getOptionMap().get(id); + if (opt == null) { + if (superClass != null) { + return superClass.getOptionById(id); + } + } + if (opt == null) return null; + return opt.isValid() ? opt : null; + } + + /* (non-Javadoc) + * org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptionBySuperClassId(java.lang.String) + */ + public IOption getOptionBySuperClassId(String optionId) { + if (optionId == null) return null; + + // Look for an option with this ID, or an option with a superclass with this id + IOption[] options = getOptions(); + for (int i = 0; i < options.length; i++) { + IOption targetOption = options[i]; + IOption option = targetOption; + do { + if (optionId.equals(option.getId())) { + return targetOption.isValid() ? targetOption : null; + } + option = option.getSuperClass(); + } while (option != null); + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getChildCategories() + */ + public IOptionCategory[] getChildCategories() { + IOptionCategory[] superCats = EMPTY_CATEGORIES; + IOptionCategory[] ourCats = EMPTY_CATEGORIES; + // Merge our option categories with our superclass' option categories. + // Note that these are two disjoint sets of categories because + // categories do not use derivation AND object Id's are unique. Thus + // they are merely sequentially added. + if (superClass != null) { + superCats = superClass.getChildCategories(); + } + if ( childOptionCategories != null ) { + ourCats = (IOptionCategory[])childOptionCategories.toArray(new IOptionCategory[childOptionCategories.size()]); + } + // Add the two arrays together; + if (superCats.length > 0 || ourCats.length > 0) { + IOptionCategory[] allCats = new IOptionCategory[superCats.length + ourCats.length]; + int j; + for (j=0; j < superCats.length; j++) + allCats[j] = superCats[j]; + for (j=0; j < ourCats.length; j++) + allCats[j+superCats.length] = ourCats[j]; + return allCats; + } + // Nothing found, return EMPTY_CATEGORIES + return EMPTY_CATEGORIES; + } + + /* + * M E T H O D S M O V E D F R O M T O O L I N 3 . 0 + */ + + /* (non-Javadoc) + * Memory-safe way to access the vector of category IDs + */ + private Vector getCategoryIds() { + if (categoryIds == null) { + categoryIds = new Vector(); + } + return categoryIds; + } + + /** + * @param category + */ + public void addChildCategory(IOptionCategory category) { + if (childOptionCategories == null) + childOptionCategories = new ArrayList(); + childOptionCategories.add(category); + } + + /** + * @param option + */ + public void addOption(Option option) { + getOptionList().add(option); + getOptionMap().put(option.getId(), option); + } + /* (non-Javadoc) + * Memeory-safe way to access the map of category IDs to categories + */ + private Map getCategoryMap() { + if (categoryMap == null) { + categoryMap = new HashMap(); + } + return categoryMap; + } + + /* (non-Javadoc) + * Memory-safe way to access the list of options + */ + private Vector getOptionList() { + if (optionList == null) { + optionList = new Vector(); + } + return optionList; + } + + /* (non-Javadoc) + * Memory-safe way to access the list of IDs to options + */ + private Map getOptionMap() { + if (optionMap == null) { + optionMap = new HashMap(); + } + return optionMap; + } + + /* (non-Javadoc) + * org.eclipse.cdt.managedbuilder.core.IHoldsOptions#addOptionCategory() + */ + public void addOptionCategory(IOptionCategory category) { + // To preserve the order of the categories, record the ids in the order they are read + getCategoryIds().add(category.getId()); + // Map the categories by ID for resolution later + getCategoryMap().put(category.getId(), category); + } + + /* (non-Javadoc) + * org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOptionCategory() + */ + public IOptionCategory getOptionCategory(String id) { + IOptionCategory cat = (IOptionCategory)getCategoryMap().get(id); + if (cat == null && superClass != null) { + // Look up the holders superclasses to find the category + return superClass.getOptionCategory(id); + } + return cat; + } + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * Implements isDirty() for children of HoldsOptions. Intended to be + * called by derived class. + */ + protected boolean isDirty() { + // If I need saving, just say yes + if (isDirty) return true; + + // Otherwise see if any options need saving + List optionElements = getOptionList(); + Iterator iter = optionElements.listIterator(); + while (iter.hasNext()) { + Option option = (Option) iter.next(); + if (option.isDirty()) return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * Implements setDirty() for children of HoldsOptions. Intended to be + * called by derived class. + */ + protected void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to the children + if (!isDirty) { + List optionElements = getOptionList(); + Iterator iter = optionElements.listIterator(); + while (iter.hasNext()) { + Option option = (Option) iter.next(); + if(!option.isExtensionElement()) + option.setDirty(false); + } + } + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references. Intended to be + * called by derived class. + */ + protected void resolveReferences() { + if (!resolved) { + resolved = true; + // Call resolveReferences on our children + Iterator optionIter = getOptionList().iterator(); + while (optionIter.hasNext()) { + Option current = (Option)optionIter.next(); + current.resolveReferences(); + } + // Somewhat wasteful, but use the vector to retrieve the categories in proper order + Iterator catIter = getCategoryIds().iterator(); + while (catIter.hasNext()) { + String id = (String)catIter.next(); + IOptionCategory current = (IOptionCategory)getCategoryMap().get(id); + if (current instanceof Tool) { + ((Tool)current).resolveReferences(); + } else if (current instanceof ToolChain) { + ((ToolChain)current).resolveReferences(); + } else if (current instanceof OptionCategory) { + ((OptionCategory)current).resolveReferences(); + } + } + } + } + + public IOption getOptionToSet(IOption option, boolean adjustExtension) throws BuildException{ + IOption setOption = null; + if(option.getOptionHolder() != this) + option = getOptionBySuperClassId(option.getId()); + + if(adjustExtension){ + for(; option != null && !option.isExtensionElement(); option=option.getSuperClass()){} + + if(option != null){ + IHoldsOptions holder = option.getOptionHolder(); + if(holder == this) + setOption = option; + else { + IOption newSuperClass = option; + if (((Option)option).wasOptRef()) { + newSuperClass = option.getSuperClass(); + } + // Create a new extension Option element + String subId; + String version = ManagedBuildManager.getVersionFromIdAndVersion(newSuperClass.getId()); + String baseId = ManagedBuildManager.getIdFromIdAndVersion(newSuperClass.getId()); + if ( version != null) { + subId = baseId + ".adjusted." + new Integer(ManagedBuildManager.getRandomNumber()) + "_" + version; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + subId = baseId + ".adjusted." + new Integer(ManagedBuildManager.getRandomNumber()); //$NON-NLS-1$ + } + setOption = createOption(newSuperClass, subId, null, true); + ((Option)setOption).setAdjusted(true); + setOption.setValueType(option.getValueType()); + } + } + } else { + if(option.getOptionHolder() == this && !option.isExtensionElement()){ + setOption = option; + } else { + IOption newSuperClass = option; + for(; + newSuperClass != null && !newSuperClass.isExtensionElement(); + newSuperClass = newSuperClass.getSuperClass()){} + + if (((Option)newSuperClass).wasOptRef()) { + newSuperClass = newSuperClass.getSuperClass(); + } + + if(((Option)newSuperClass).isAdjustedExtension()){ + newSuperClass = newSuperClass.getSuperClass(); + } + // Create an Option element for the managed build project file (.CDTBUILD) + String subId; + subId = ManagedBuildManager.calculateChildId(newSuperClass.getId(), null); + setOption = createOption(newSuperClass, subId, null, false); + setOption.setValueType(option.getValueType()); + } + } + return setOption; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java index 6380d298951..f828fa58e4a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java @@ -1,1221 +1,1221 @@ -/******************************************************************************* - * Copyright (c) 2005, 2006 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.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.eclipse.core.runtime.content.*; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IInputOrder; -import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class InputType extends BuildObject implements IInputType { - - private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ - private static final String EMPTY_STRING = new String(); - - // Superclass - private IInputType superClass; - private String superClassId; - // Parent and children - private ITool parent; - private Vector inputOrderList; - private Vector additionalInputList; - // Managed Build model attributes - private String sourceContentTypeId; - private IContentType sourceContentType; - private List inputExtensions; - private String dependencyContentTypeId; - private IContentType dependencyContentType; - private List dependencyExtensions; - private String optionId; - private String assignToOptionId; - private String buildVariable; - private Boolean multipleOfType; - private Boolean primaryInput; - private IConfigurationElement dependencyGeneratorElement = null; - private IManagedDependencyGeneratorType dependencyGenerator = null; - // Miscellaneous - private boolean isExtensionInputType = false; - private boolean isDirty = false; - private boolean resolved = true; - - /* - * C O N S T R U C T O R S - */ - - /** - * This constructor is called to create an InputType defined by an extension point in - * a plugin manifest file, or returned by a dynamic element provider - * - * @param parent The ITool parent of this InputType - * @param element The InputType definition from the manifest file or a dynamic element - * provider - */ - public InputType(ITool parent, IManagedConfigElement element) { - this.parent = parent; - isExtensionInputType = true; - - // setup for resolving - resolved = false; - - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionInputType(this); - - // Load Children - IManagedConfigElement[] iElements = element.getChildren(); - for (int l = 0; l < iElements.length; ++l) { - IManagedConfigElement iElement = iElements[l]; - if (iElement.getName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { - InputOrder inputOrder = new InputOrder(this, iElement); - getInputOrderList().add(inputOrder); - } else if (iElement.getName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { - AdditionalInput addlInput = new AdditionalInput(this, iElement); - getAdditionalInputList().add(addlInput); - } - } - } - - /** - * This constructor is called to create an InputType whose attributes and children will be - * added by separate calls. - * - * @param Tool The parent of the an InputType - * @param InputType The superClass, if any - * @param String The id for the new InputType - * @param String The name for the new InputType - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public InputType(Tool parent, IInputType superClass, String Id, String name, boolean isExtensionElement) { - this.parent = parent; - this.superClass = superClass; - if (this.superClass != null) { - superClassId = this.superClass.getId(); - } - setId(Id); - setName(name); - - isExtensionInputType = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionInputType(this); - } else { - setDirty(true); - } - } - - /** - * Create an InputType based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The ITool the InputType will be added to. - * @param element The XML element that contains the InputType settings. - * - */ - public InputType(ITool parent, Element element) { - this.parent = parent; - isExtensionInputType = false; - - // Initialize from the XML attributes - loadFromProject(element); - - // Load children - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { - InputOrder inputOrder = new InputOrder(this, (Element)configElement); - getInputOrderList().add(inputOrder); - } else if (configElement.getNodeName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { - AdditionalInput addlInput = new AdditionalInput(this, (Element)configElement); - getAdditionalInputList().add(addlInput); - } - } - } - - /** - * Create an InputType based upon an existing InputType. - * - * @param parent The ITool the InputType will be added to. - * @param Id The identifier of the new InputType - * @param name The name of the new InputType - * @param inputType The existing InputType to clone. - */ - public InputType(ITool parent, String Id, String name, InputType inputType) { - this.parent = parent; - superClass = inputType.superClass; - if (superClass != null) { - if (inputType.superClassId != null) { - superClassId = new String(inputType.superClassId); - } - } - setId(Id); - setName(name); - - isExtensionInputType = false; - - // Copy the remaining attributes - - if (inputType.sourceContentTypeId != null) { - sourceContentTypeId = new String(inputType.sourceContentTypeId); - } - sourceContentType = inputType.sourceContentType; - if (inputType.inputExtensions != null) { - inputExtensions = new ArrayList(inputType.inputExtensions); - } - if (inputType.dependencyContentTypeId != null) { - dependencyContentTypeId = new String(inputType.dependencyContentTypeId); - } - dependencyContentType = inputType.dependencyContentType; - if (inputType.dependencyExtensions != null) { - dependencyExtensions = new ArrayList(inputType.dependencyExtensions); - } - if (inputType.optionId != null) { - optionId = new String(inputType.optionId); - } - if (inputType.assignToOptionId != null) { - assignToOptionId = new String(inputType.assignToOptionId); - } - if (inputType.buildVariable != null) { - buildVariable = new String(inputType.buildVariable); - } - if (inputType.multipleOfType != null) { - multipleOfType = new Boolean(inputType.multipleOfType.booleanValue()); - } - if (inputType.primaryInput != null) { - primaryInput = new Boolean(inputType.primaryInput.booleanValue()); - } - dependencyGeneratorElement = inputType.dependencyGeneratorElement; - dependencyGenerator = inputType.dependencyGenerator; - - // Clone the children - if (inputType.inputOrderList != null) { - Iterator iter = inputType.getInputOrderList().listIterator(); - while (iter.hasNext()) { - InputOrder inputOrder = (InputOrder) iter.next(); - InputOrder newInputOrder = new InputOrder(this, inputOrder); - getInputOrderList().add(newInputOrder); - } - } - if (inputType.additionalInputList != null) { - Iterator iter = inputType.getAdditionalInputList().listIterator(); - while (iter.hasNext()) { - AdditionalInput additionalInput = (AdditionalInput) iter.next(); - AdditionalInput newAdditionalInput = new AdditionalInput(this, additionalInput); - getAdditionalInputList().add(newAdditionalInput); - } - } - - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Loads the InputType information from the ManagedConfigElement specified in the - * argument. - * - * @param element Contains the InputType information - */ - protected void loadFromManifest(IManagedConfigElement element) { - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // Get the name - setName(element.getAttribute(IBuildObject.NAME)); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // sourceContentType - sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); - - // Get the supported input file extensions - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - - // dependencyContentType - dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); - - // Get the dependency (header file) extensions - String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getDependencyExtensionsList().add(tokenizer.nextElement()); - } - } - - // option - optionId = element.getAttribute(IInputType.OPTION); - - // assignToOption - assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); - - // multipleOfType - String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); - if (isMOT != null){ - multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ - } - - // primaryInput - String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); - if (isPI != null){ - primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ - } - - // buildVariable - buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); - - // Store the configuration element IFF there is a dependency generator defined - String depGenerator = element.getAttribute(ITool.DEP_CALC_ID); - if (depGenerator != null && element instanceof DefaultManagedConfigElement) { - dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - } - - /* (non-Javadoc) - * Initialize the InputType information from the XML element - * specified in the argument - * - * @param element An XML element containing the InputType information - */ - protected boolean loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - superClass = ManagedBuildManager.getExtensionInputType(superClassId); - if (superClass == null) { - // TODO: Report error - } - } - - // sourceContentType - IContentTypeManager manager = Platform.getContentTypeManager(); - if (element.hasAttribute(IInputType.SOURCE_CONTENT_TYPE)) { - sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); - if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { - sourceContentType = manager.getContentType(sourceContentTypeId); - } - } - - // sources - if (element.hasAttribute(IInputType.SOURCES)) { - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // dependencyContentType - if (element.hasAttribute(IInputType.DEPENDENCY_CONTENT_TYPE)) { - dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); - if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { - dependencyContentType = manager.getContentType(dependencyContentTypeId); - } - } - - // dependencyExtensions - // Get the dependency (header file) extensions - if (element.hasAttribute(IInputType.DEPENDENCY_EXTENSIONS)) { - String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getDependencyExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // option - if (element.hasAttribute(IInputType.OPTION)) { - optionId = element.getAttribute(IInputType.OPTION); - } - - // assignToOption - if (element.hasAttribute(IInputType.ASSIGN_TO_OPTION)) { - assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); - } - - // multipleOfType - if (element.hasAttribute(IInputType.MULTIPLE_OF_TYPE)) { - String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); - if (isMOT != null){ - multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ - } - } - - // primaryInput - if (element.hasAttribute(IInputType.PRIMARY_INPUT)) { - String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); - if (isPI != null){ - primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ - } - } - - // buildVariable - if (element.hasAttribute(IInputType.BUILD_VARIABLE)) { - buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); - } - - // Note: dependency generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (element.hasAttribute(ITool.DEP_CALC_ID)) { - // TODO: Issue warning? - } - - return true; - } - - /** - * Persist the InputType to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - if (superClass != null) - element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); - - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - // sourceContentType - if (sourceContentTypeId != null) { - element.setAttribute(IInputType.SOURCE_CONTENT_TYPE, sourceContentTypeId); - } - - // input file extensions - if (getInputExtensionsList().size() > 0) { - String inputs; - List list = getInputExtensionsList(); - Iterator iter = list.listIterator(); - inputs = (String)iter.next(); - while (iter.hasNext()) { - inputs += DEFAULT_SEPARATOR; - inputs += iter.next(); - } - element.setAttribute(IInputType.SOURCES, inputs); - } - - // dependencyContentType - if (dependencyContentTypeId != null) { - element.setAttribute(IInputType.DEPENDENCY_CONTENT_TYPE, dependencyContentTypeId); - } - - // dependency (header file) extensions - if (getDependencyExtensionsList().size() > 0) { - String headers; - List list = getDependencyExtensionsList(); - Iterator iter = list.listIterator(); - headers = (String)iter.next(); - while (iter.hasNext()) { - headers += DEFAULT_SEPARATOR; - headers += iter.next(); - } - element.setAttribute(IInputType.DEPENDENCY_EXTENSIONS, headers); - } - - if (optionId != null) { - element.setAttribute(IInputType.OPTION, optionId); - } - - if (assignToOptionId != null) { - element.setAttribute(IInputType.ASSIGN_TO_OPTION, assignToOptionId); - } - - if (multipleOfType != null) { - element.setAttribute(IInputType.MULTIPLE_OF_TYPE, multipleOfType.toString()); - } - - if (primaryInput != null) { - element.setAttribute(IInputType.PRIMARY_INPUT, primaryInput.toString()); - } - - if (buildVariable != null) { - element.setAttribute(IInputType.BUILD_VARIABLE, buildVariable); - } - - // Note: dependency generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (dependencyGeneratorElement != null) { - // TODO: issue warning? - } - - // Serialize my children - List childElements = getInputOrderList(); - Iterator iter = childElements.listIterator(); - while (iter.hasNext()) { - InputOrder io = (InputOrder) iter.next(); - Element ioElement = doc.createElement(InputOrder.INPUT_ORDER_ELEMENT_NAME); - element.appendChild(ioElement); - io.serialize(doc, ioElement); - } - childElements = getAdditionalInputList(); - iter = childElements.listIterator(); - while (iter.hasNext()) { - AdditionalInput ai = (AdditionalInput) iter.next(); - Element aiElement = doc.createElement(AdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME); - element.appendChild(aiElement); - ai.serialize(doc, aiElement); - } - - // I am clean now - isDirty = false; - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getParent() - */ - public ITool getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#createInputOrder() - */ - public IInputOrder createInputOrder(String path) { - InputOrder inputOrder = new InputOrder(this, false); - inputOrder.setPath(path); - getInputOrderList().add(inputOrder); - setDirty(true); - return inputOrder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrders() - */ - public IInputOrder[] getInputOrders() { - IInputOrder[] orders; - Vector ours = getInputOrderList(); - orders = (IInputOrder[])ours.toArray(new IInputOrder[ours.size()]); - return orders; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrder() - */ - public IInputOrder getInputOrder(String path) { - // TODO Convert both paths to absolute? - List orders = getInputOrderList(); - Iterator iter = orders.listIterator(); - while (iter.hasNext()) { - InputOrder io = (InputOrder) iter.next(); - if (path.compareToIgnoreCase(io.getPath()) != 0) { - return io; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() - */ - public void removeInputOrder(String path) { - IInputOrder order = getInputOrder(path); - if (order != null) removeInputOrder(order); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() - */ - public void removeInputOrder(IInputOrder element) { - getInputOrderList().remove(element); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#createAdditionalInput() - */ - public IAdditionalInput createAdditionalInput(String paths) { - AdditionalInput addlInput = new AdditionalInput(this, false); - addlInput.setPaths(paths); - getAdditionalInputList().add(addlInput); - setDirty(true); - return addlInput; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInputs() - */ - public IAdditionalInput[] getAdditionalInputs() { - IAdditionalInput[] inputs; - Vector ours = getAdditionalInputList(); - inputs = (IAdditionalInput[])ours.toArray(new IAdditionalInput[ours.size()]); - return inputs; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInput() - */ - public IAdditionalInput getAdditionalInput(String paths) { - // TODO Convert both paths to absolute? - // Must match all strings - String[] inputTokens = paths.split(";"); //$NON-NLS-1$ - List inputs = getInputOrderList(); - Iterator iter = inputs.listIterator(); - while (iter.hasNext()) { - AdditionalInput ai = (AdditionalInput) iter.next(); - boolean match = false; - String[] tokens = ai.getPaths(); - if (tokens.length == inputTokens.length) { - match = true; - for (int i = 0; i < tokens.length; i++) { - if (tokens[i].compareToIgnoreCase(inputTokens[i]) != 0) { - match = false; - break; - } - } - } - if (match) return ai; - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() - */ - public void removeAdditionalInput(String path) { - IAdditionalInput input = getAdditionalInput(path); - if (input != null) removeAdditionalInput(input); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() - */ - public void removeAdditionalInput(IAdditionalInput element) { - getAdditionalInputList().remove(element); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalDependencies() - */ - public IPath[] getAdditionalDependencies() { - List deps = new ArrayList(); - Iterator typeIter = getAdditionalInputList().iterator(); - while (typeIter.hasNext()) { - AdditionalInput current = (AdditionalInput)typeIter.next(); - int kind = current.getKind(); - if (kind == IAdditionalInput.KIND_ADDITIONAL_DEPENDENCY || - kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { - String[] paths = current.getPaths(); - if (paths != null) { - for (int i = 0; i < paths.length; i++) { - if (paths[i].length() > 0) { - deps.add(Path.fromOSString(paths[i])); - } - } - } - } - } - return (IPath[])deps.toArray(new IPath[deps.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalResources() - */ - public IPath[] getAdditionalResources() { - List ins = new ArrayList(); - Iterator typeIter = getAdditionalInputList().iterator(); - while (typeIter.hasNext()) { - AdditionalInput current = (AdditionalInput)typeIter.next(); - int kind = current.getKind(); - if (kind == IAdditionalInput.KIND_ADDITIONAL_INPUT || - kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { - String[] paths = current.getPaths(); - if (paths != null) { - for (int i = 0; i < paths.length; i++) { - if (paths[i].length() > 0) { - ins.add(Path.fromOSString(paths[i])); - } - } - } - } - } - return (IPath[])ins.toArray(new IPath[ins.size()]); - } - - /* (non-Javadoc) - * Memory-safe way to access the list of input orders - */ - private Vector getInputOrderList() { - if (inputOrderList == null) { - inputOrderList = new Vector(); - } - return inputOrderList; - } - - /* (non-Javadoc) - * Memory-safe way to access the list of input orders - */ - private Vector getAdditionalInputList() { - if (additionalInputList == null) { - additionalInputList = new Vector(); - } - return additionalInputList; - } - - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IInputType#getSuperClass() - */ - public IInputType getSuperClass() { - return superClass; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getName() - */ - public String getName() { - return (name == null && superClass != null) ? superClass.getName() : name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getBuildVariable() - */ - public String getBuildVariable() { - if (buildVariable == null) { - // If I have a superClass, ask it - if (superClass != null) { - return superClass.getBuildVariable(); - } else { - return EMPTY_STRING; - } - } - return buildVariable; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#setBuildVariable() - */ - public void setBuildVariable(String variableName) { - if (variableName == null && buildVariable == null) return; - if (buildVariable == null || variableName == null || !(variableName.equals(buildVariable))) { - buildVariable = variableName; - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyContentType() - */ - public IContentType getDependencyContentType() { - if (dependencyContentType == null) { - if (superClass != null) { - return superClass.getDependencyContentType(); - } else { - return null; - } - } - return dependencyContentType; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyContentType() - */ - public void setDependencyContentType(IContentType type) { - if (dependencyContentType != type) { - dependencyContentType = type; - if (dependencyContentType != null) { - dependencyContentTypeId = dependencyContentType.getId(); - } else { - dependencyContentTypeId = null; - } - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensionsAttribute() - */ - public String[] getDependencyExtensionsAttribute() { - if (dependencyExtensions == null || dependencyExtensions.size() == 0) { - // If I have a superClass, ask it - if (superClass != null) { - return superClass.getDependencyExtensionsAttribute(); - } else { - if (dependencyExtensions == null) { - dependencyExtensions = new ArrayList(); - } - } - } - return (String[])dependencyExtensions.toArray(new String[dependencyExtensions.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyExtensionsAttribute() - */ - public void setDependencyExtensionsAttribute(String extensions) { - getDependencyExtensionsList().clear(); - if (extensions != null) { - StringTokenizer tokenizer = new StringTokenizer(extensions, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getDependencyExtensionsList().add(tokenizer.nextElement()); - } - } - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensions() - */ - public String[] getDependencyExtensions(ITool tool) { - // Use content type if specified and registered with Eclipse - IContentType type = getDependencyContentType(); - if (type != null) { - String[] exts = ((Tool)tool).getContentTypeFileSpecs(type); - // TODO: This is a temporary hack until we decide how to specify the langauge (C vs. C++) - // of a .h file. If the content type is the CDT-defined C/C++ content type, then - // add "h" to the list if it is not already there. - if (type.getId().compareTo("org.eclipse.cdt.core.cxxHeader") == 0) { // $NON-NLS-1$ - boolean h_found = false; - for (int i=0; i 0) { - superClass = ManagedBuildManager.getExtensionInputType(superClassId); - if (superClass == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "inputType", //$NON-NLS-1$ - getId()); - } - } - - // Resolve content types - IContentTypeManager manager = Platform.getContentTypeManager(); - if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { - sourceContentType = manager.getContentType(sourceContentTypeId); - } - if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { - dependencyContentType = manager.getContentType(dependencyContentTypeId); - } - - // Call resolveReferences on our children - Iterator typeIter = getInputOrderList().iterator(); - while (typeIter.hasNext()) { - InputOrder current = (InputOrder)typeIter.next(); - current.resolveReferences(); - } - typeIter = getAdditionalInputList().iterator(); - while (typeIter.hasNext()) { - AdditionalInput current = (AdditionalInput)typeIter.next(); - current.resolveReferences(); - } - } - } - - /** - * @return Returns the managedBuildRevision. - */ - public String getManagedBuildRevision() { - if ( managedBuildRevision == null) { - if ( getParent() != null) { - return getParent().getManagedBuildRevision(); - } - } - return managedBuildRevision; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if ( version == null) { - if ( getParent() != null) { - return getParent().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } -} +/******************************************************************************* + * Copyright (c) 2005, 2006 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.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.core.runtime.content.*; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IInputOrder; +import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class InputType extends BuildObject implements IInputType { + + private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ + private static final String EMPTY_STRING = new String(); + + // Superclass + private IInputType superClass; + private String superClassId; + // Parent and children + private ITool parent; + private Vector inputOrderList; + private Vector additionalInputList; + // Managed Build model attributes + private String sourceContentTypeId; + private IContentType sourceContentType; + private List inputExtensions; + private String dependencyContentTypeId; + private IContentType dependencyContentType; + private List dependencyExtensions; + private String optionId; + private String assignToOptionId; + private String buildVariable; + private Boolean multipleOfType; + private Boolean primaryInput; + private IConfigurationElement dependencyGeneratorElement = null; + private IManagedDependencyGeneratorType dependencyGenerator = null; + // Miscellaneous + private boolean isExtensionInputType = false; + private boolean isDirty = false; + private boolean resolved = true; + + /* + * C O N S T R U C T O R S + */ + + /** + * This constructor is called to create an InputType defined by an extension point in + * a plugin manifest file, or returned by a dynamic element provider + * + * @param parent The ITool parent of this InputType + * @param element The InputType definition from the manifest file or a dynamic element + * provider + */ + public InputType(ITool parent, IManagedConfigElement element) { + this.parent = parent; + isExtensionInputType = true; + + // setup for resolving + resolved = false; + + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionInputType(this); + + // Load Children + IManagedConfigElement[] iElements = element.getChildren(); + for (int l = 0; l < iElements.length; ++l) { + IManagedConfigElement iElement = iElements[l]; + if (iElement.getName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { + InputOrder inputOrder = new InputOrder(this, iElement); + getInputOrderList().add(inputOrder); + } else if (iElement.getName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { + AdditionalInput addlInput = new AdditionalInput(this, iElement); + getAdditionalInputList().add(addlInput); + } + } + } + + /** + * This constructor is called to create an InputType whose attributes and children will be + * added by separate calls. + * + * @param Tool The parent of the an InputType + * @param InputType The superClass, if any + * @param String The id for the new InputType + * @param String The name for the new InputType + * @param boolean Indicates whether this is an extension element or a managed project element + */ + public InputType(Tool parent, IInputType superClass, String Id, String name, boolean isExtensionElement) { + this.parent = parent; + this.superClass = superClass; + if (this.superClass != null) { + superClassId = this.superClass.getId(); + } + setId(Id); + setName(name); + + isExtensionInputType = isExtensionElement; + if (isExtensionElement) { + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionInputType(this); + } else { + setDirty(true); + } + } + + /** + * Create an InputType based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The ITool the InputType will be added to. + * @param element The XML element that contains the InputType settings. + * + */ + public InputType(ITool parent, Element element) { + this.parent = parent; + isExtensionInputType = false; + + // Initialize from the XML attributes + loadFromProject(element); + + // Load children + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { + InputOrder inputOrder = new InputOrder(this, (Element)configElement); + getInputOrderList().add(inputOrder); + } else if (configElement.getNodeName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { + AdditionalInput addlInput = new AdditionalInput(this, (Element)configElement); + getAdditionalInputList().add(addlInput); + } + } + } + + /** + * Create an InputType based upon an existing InputType. + * + * @param parent The ITool the InputType will be added to. + * @param Id The identifier of the new InputType + * @param name The name of the new InputType + * @param inputType The existing InputType to clone. + */ + public InputType(ITool parent, String Id, String name, InputType inputType) { + this.parent = parent; + superClass = inputType.superClass; + if (superClass != null) { + if (inputType.superClassId != null) { + superClassId = new String(inputType.superClassId); + } + } + setId(Id); + setName(name); + + isExtensionInputType = false; + + // Copy the remaining attributes + + if (inputType.sourceContentTypeId != null) { + sourceContentTypeId = new String(inputType.sourceContentTypeId); + } + sourceContentType = inputType.sourceContentType; + if (inputType.inputExtensions != null) { + inputExtensions = new ArrayList(inputType.inputExtensions); + } + if (inputType.dependencyContentTypeId != null) { + dependencyContentTypeId = new String(inputType.dependencyContentTypeId); + } + dependencyContentType = inputType.dependencyContentType; + if (inputType.dependencyExtensions != null) { + dependencyExtensions = new ArrayList(inputType.dependencyExtensions); + } + if (inputType.optionId != null) { + optionId = new String(inputType.optionId); + } + if (inputType.assignToOptionId != null) { + assignToOptionId = new String(inputType.assignToOptionId); + } + if (inputType.buildVariable != null) { + buildVariable = new String(inputType.buildVariable); + } + if (inputType.multipleOfType != null) { + multipleOfType = new Boolean(inputType.multipleOfType.booleanValue()); + } + if (inputType.primaryInput != null) { + primaryInput = new Boolean(inputType.primaryInput.booleanValue()); + } + dependencyGeneratorElement = inputType.dependencyGeneratorElement; + dependencyGenerator = inputType.dependencyGenerator; + + // Clone the children + if (inputType.inputOrderList != null) { + Iterator iter = inputType.getInputOrderList().listIterator(); + while (iter.hasNext()) { + InputOrder inputOrder = (InputOrder) iter.next(); + InputOrder newInputOrder = new InputOrder(this, inputOrder); + getInputOrderList().add(newInputOrder); + } + } + if (inputType.additionalInputList != null) { + Iterator iter = inputType.getAdditionalInputList().listIterator(); + while (iter.hasNext()) { + AdditionalInput additionalInput = (AdditionalInput) iter.next(); + AdditionalInput newAdditionalInput = new AdditionalInput(this, additionalInput); + getAdditionalInputList().add(newAdditionalInput); + } + } + + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Loads the InputType information from the ManagedConfigElement specified in the + * argument. + * + * @param element Contains the InputType information + */ + protected void loadFromManifest(IManagedConfigElement element) { + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // Get the name + setName(element.getAttribute(IBuildObject.NAME)); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // sourceContentType + sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); + + // Get the supported input file extensions + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + + // dependencyContentType + dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); + + // Get the dependency (header file) extensions + String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getDependencyExtensionsList().add(tokenizer.nextElement()); + } + } + + // option + optionId = element.getAttribute(IInputType.OPTION); + + // assignToOption + assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); + + // multipleOfType + String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); + if (isMOT != null){ + multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ + } + + // primaryInput + String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); + if (isPI != null){ + primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ + } + + // buildVariable + buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); + + // Store the configuration element IFF there is a dependency generator defined + String depGenerator = element.getAttribute(ITool.DEP_CALC_ID); + if (depGenerator != null && element instanceof DefaultManagedConfigElement) { + dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + } + + /* (non-Javadoc) + * Initialize the InputType information from the XML element + * specified in the argument + * + * @param element An XML element containing the InputType information + */ + protected boolean loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + superClass = ManagedBuildManager.getExtensionInputType(superClassId); + if (superClass == null) { + // TODO: Report error + } + } + + // sourceContentType + IContentTypeManager manager = Platform.getContentTypeManager(); + if (element.hasAttribute(IInputType.SOURCE_CONTENT_TYPE)) { + sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); + if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { + sourceContentType = manager.getContentType(sourceContentTypeId); + } + } + + // sources + if (element.hasAttribute(IInputType.SOURCES)) { + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // dependencyContentType + if (element.hasAttribute(IInputType.DEPENDENCY_CONTENT_TYPE)) { + dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); + if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { + dependencyContentType = manager.getContentType(dependencyContentTypeId); + } + } + + // dependencyExtensions + // Get the dependency (header file) extensions + if (element.hasAttribute(IInputType.DEPENDENCY_EXTENSIONS)) { + String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getDependencyExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // option + if (element.hasAttribute(IInputType.OPTION)) { + optionId = element.getAttribute(IInputType.OPTION); + } + + // assignToOption + if (element.hasAttribute(IInputType.ASSIGN_TO_OPTION)) { + assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); + } + + // multipleOfType + if (element.hasAttribute(IInputType.MULTIPLE_OF_TYPE)) { + String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); + if (isMOT != null){ + multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ + } + } + + // primaryInput + if (element.hasAttribute(IInputType.PRIMARY_INPUT)) { + String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); + if (isPI != null){ + primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ + } + } + + // buildVariable + if (element.hasAttribute(IInputType.BUILD_VARIABLE)) { + buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); + } + + // Note: dependency generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (element.hasAttribute(ITool.DEP_CALC_ID)) { + // TODO: Issue warning? + } + + return true; + } + + /** + * Persist the InputType to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + if (superClass != null) + element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + // sourceContentType + if (sourceContentTypeId != null) { + element.setAttribute(IInputType.SOURCE_CONTENT_TYPE, sourceContentTypeId); + } + + // input file extensions + if (getInputExtensionsList().size() > 0) { + String inputs; + List list = getInputExtensionsList(); + Iterator iter = list.listIterator(); + inputs = (String)iter.next(); + while (iter.hasNext()) { + inputs += DEFAULT_SEPARATOR; + inputs += iter.next(); + } + element.setAttribute(IInputType.SOURCES, inputs); + } + + // dependencyContentType + if (dependencyContentTypeId != null) { + element.setAttribute(IInputType.DEPENDENCY_CONTENT_TYPE, dependencyContentTypeId); + } + + // dependency (header file) extensions + if (getDependencyExtensionsList().size() > 0) { + String headers; + List list = getDependencyExtensionsList(); + Iterator iter = list.listIterator(); + headers = (String)iter.next(); + while (iter.hasNext()) { + headers += DEFAULT_SEPARATOR; + headers += iter.next(); + } + element.setAttribute(IInputType.DEPENDENCY_EXTENSIONS, headers); + } + + if (optionId != null) { + element.setAttribute(IInputType.OPTION, optionId); + } + + if (assignToOptionId != null) { + element.setAttribute(IInputType.ASSIGN_TO_OPTION, assignToOptionId); + } + + if (multipleOfType != null) { + element.setAttribute(IInputType.MULTIPLE_OF_TYPE, multipleOfType.toString()); + } + + if (primaryInput != null) { + element.setAttribute(IInputType.PRIMARY_INPUT, primaryInput.toString()); + } + + if (buildVariable != null) { + element.setAttribute(IInputType.BUILD_VARIABLE, buildVariable); + } + + // Note: dependency generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (dependencyGeneratorElement != null) { + // TODO: issue warning? + } + + // Serialize my children + List childElements = getInputOrderList(); + Iterator iter = childElements.listIterator(); + while (iter.hasNext()) { + InputOrder io = (InputOrder) iter.next(); + Element ioElement = doc.createElement(InputOrder.INPUT_ORDER_ELEMENT_NAME); + element.appendChild(ioElement); + io.serialize(doc, ioElement); + } + childElements = getAdditionalInputList(); + iter = childElements.listIterator(); + while (iter.hasNext()) { + AdditionalInput ai = (AdditionalInput) iter.next(); + Element aiElement = doc.createElement(AdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME); + element.appendChild(aiElement); + ai.serialize(doc, aiElement); + } + + // I am clean now + isDirty = false; + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getParent() + */ + public ITool getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#createInputOrder() + */ + public IInputOrder createInputOrder(String path) { + InputOrder inputOrder = new InputOrder(this, false); + inputOrder.setPath(path); + getInputOrderList().add(inputOrder); + setDirty(true); + return inputOrder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrders() + */ + public IInputOrder[] getInputOrders() { + IInputOrder[] orders; + Vector ours = getInputOrderList(); + orders = (IInputOrder[])ours.toArray(new IInputOrder[ours.size()]); + return orders; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrder() + */ + public IInputOrder getInputOrder(String path) { + // TODO Convert both paths to absolute? + List orders = getInputOrderList(); + Iterator iter = orders.listIterator(); + while (iter.hasNext()) { + InputOrder io = (InputOrder) iter.next(); + if (path.compareToIgnoreCase(io.getPath()) != 0) { + return io; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() + */ + public void removeInputOrder(String path) { + IInputOrder order = getInputOrder(path); + if (order != null) removeInputOrder(order); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() + */ + public void removeInputOrder(IInputOrder element) { + getInputOrderList().remove(element); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#createAdditionalInput() + */ + public IAdditionalInput createAdditionalInput(String paths) { + AdditionalInput addlInput = new AdditionalInput(this, false); + addlInput.setPaths(paths); + getAdditionalInputList().add(addlInput); + setDirty(true); + return addlInput; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInputs() + */ + public IAdditionalInput[] getAdditionalInputs() { + IAdditionalInput[] inputs; + Vector ours = getAdditionalInputList(); + inputs = (IAdditionalInput[])ours.toArray(new IAdditionalInput[ours.size()]); + return inputs; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInput() + */ + public IAdditionalInput getAdditionalInput(String paths) { + // TODO Convert both paths to absolute? + // Must match all strings + String[] inputTokens = paths.split(";"); //$NON-NLS-1$ + List inputs = getInputOrderList(); + Iterator iter = inputs.listIterator(); + while (iter.hasNext()) { + AdditionalInput ai = (AdditionalInput) iter.next(); + boolean match = false; + String[] tokens = ai.getPaths(); + if (tokens.length == inputTokens.length) { + match = true; + for (int i = 0; i < tokens.length; i++) { + if (tokens[i].compareToIgnoreCase(inputTokens[i]) != 0) { + match = false; + break; + } + } + } + if (match) return ai; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() + */ + public void removeAdditionalInput(String path) { + IAdditionalInput input = getAdditionalInput(path); + if (input != null) removeAdditionalInput(input); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() + */ + public void removeAdditionalInput(IAdditionalInput element) { + getAdditionalInputList().remove(element); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalDependencies() + */ + public IPath[] getAdditionalDependencies() { + List deps = new ArrayList(); + Iterator typeIter = getAdditionalInputList().iterator(); + while (typeIter.hasNext()) { + AdditionalInput current = (AdditionalInput)typeIter.next(); + int kind = current.getKind(); + if (kind == IAdditionalInput.KIND_ADDITIONAL_DEPENDENCY || + kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { + String[] paths = current.getPaths(); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + if (paths[i].length() > 0) { + deps.add(Path.fromOSString(paths[i])); + } + } + } + } + } + return (IPath[])deps.toArray(new IPath[deps.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalResources() + */ + public IPath[] getAdditionalResources() { + List ins = new ArrayList(); + Iterator typeIter = getAdditionalInputList().iterator(); + while (typeIter.hasNext()) { + AdditionalInput current = (AdditionalInput)typeIter.next(); + int kind = current.getKind(); + if (kind == IAdditionalInput.KIND_ADDITIONAL_INPUT || + kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { + String[] paths = current.getPaths(); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + if (paths[i].length() > 0) { + ins.add(Path.fromOSString(paths[i])); + } + } + } + } + } + return (IPath[])ins.toArray(new IPath[ins.size()]); + } + + /* (non-Javadoc) + * Memory-safe way to access the list of input orders + */ + private Vector getInputOrderList() { + if (inputOrderList == null) { + inputOrderList = new Vector(); + } + return inputOrderList; + } + + /* (non-Javadoc) + * Memory-safe way to access the list of input orders + */ + private Vector getAdditionalInputList() { + if (additionalInputList == null) { + additionalInputList = new Vector(); + } + return additionalInputList; + } + + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IInputType#getSuperClass() + */ + public IInputType getSuperClass() { + return superClass; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getName() + */ + public String getName() { + return (name == null && superClass != null) ? superClass.getName() : name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getBuildVariable() + */ + public String getBuildVariable() { + if (buildVariable == null) { + // If I have a superClass, ask it + if (superClass != null) { + return superClass.getBuildVariable(); + } else { + return EMPTY_STRING; + } + } + return buildVariable; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#setBuildVariable() + */ + public void setBuildVariable(String variableName) { + if (variableName == null && buildVariable == null) return; + if (buildVariable == null || variableName == null || !(variableName.equals(buildVariable))) { + buildVariable = variableName; + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyContentType() + */ + public IContentType getDependencyContentType() { + if (dependencyContentType == null) { + if (superClass != null) { + return superClass.getDependencyContentType(); + } else { + return null; + } + } + return dependencyContentType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyContentType() + */ + public void setDependencyContentType(IContentType type) { + if (dependencyContentType != type) { + dependencyContentType = type; + if (dependencyContentType != null) { + dependencyContentTypeId = dependencyContentType.getId(); + } else { + dependencyContentTypeId = null; + } + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensionsAttribute() + */ + public String[] getDependencyExtensionsAttribute() { + if (dependencyExtensions == null || dependencyExtensions.size() == 0) { + // If I have a superClass, ask it + if (superClass != null) { + return superClass.getDependencyExtensionsAttribute(); + } else { + if (dependencyExtensions == null) { + dependencyExtensions = new ArrayList(); + } + } + } + return (String[])dependencyExtensions.toArray(new String[dependencyExtensions.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyExtensionsAttribute() + */ + public void setDependencyExtensionsAttribute(String extensions) { + getDependencyExtensionsList().clear(); + if (extensions != null) { + StringTokenizer tokenizer = new StringTokenizer(extensions, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getDependencyExtensionsList().add(tokenizer.nextElement()); + } + } + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensions() + */ + public String[] getDependencyExtensions(ITool tool) { + // Use content type if specified and registered with Eclipse + IContentType type = getDependencyContentType(); + if (type != null) { + String[] exts = ((Tool)tool).getContentTypeFileSpecs(type); + // TODO: This is a temporary hack until we decide how to specify the langauge (C vs. C++) + // of a .h file. If the content type is the CDT-defined C/C++ content type, then + // add "h" to the list if it is not already there. + if (type.getId().compareTo("org.eclipse.cdt.core.cxxHeader") == 0) { // $NON-NLS-1$ + boolean h_found = false; + for (int i=0; i 0) { + superClass = ManagedBuildManager.getExtensionInputType(superClassId); + if (superClass == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "inputType", //$NON-NLS-1$ + getId()); + } + } + + // Resolve content types + IContentTypeManager manager = Platform.getContentTypeManager(); + if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { + sourceContentType = manager.getContentType(sourceContentTypeId); + } + if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { + dependencyContentType = manager.getContentType(dependencyContentTypeId); + } + + // Call resolveReferences on our children + Iterator typeIter = getInputOrderList().iterator(); + while (typeIter.hasNext()) { + InputOrder current = (InputOrder)typeIter.next(); + current.resolveReferences(); + } + typeIter = getAdditionalInputList().iterator(); + while (typeIter.hasNext()) { + AdditionalInput current = (AdditionalInput)typeIter.next(); + current.resolveReferences(); + } + } + } + + /** + * @return Returns the managedBuildRevision. + */ + public String getManagedBuildRevision() { + if ( managedBuildRevision == null) { + if ( getParent() != null) { + return getParent().getManagedBuildRevision(); + } + } + return managedBuildRevision; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if ( version == null) { + if ( getParent() != null) { + return getParent().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java index 0917f79dcdc..5c21fe68dd5 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java @@ -1,1448 +1,1448 @@ -/******************************************************************************* - * Copyright (c) 2002, 2006 IBM Software 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 Rational Software - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -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 java.util.Vector; - -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.IContainerEntry; -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.model.IPathEntryContainer; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IBuilder; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITarget; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; -import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; -import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; -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.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.QualifiedName; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * - * @since 1.2 - */ -public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { - // The path container used for all managed projects - public static final IContainerEntry containerEntry = CoreModel.newContainerEntry(new Path("org.eclipse.cdt.managedbuilder.MANAGED_CONTAINER")); //$NON-NLS-1$ - private static final QualifiedName defaultConfigProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_CONFIGURATION); - //private static final QualifiedName defaultTargetProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_TARGET); - public static final String MAJOR_SEPERATOR = ";"; //$NON-NLS-1$ - public static final String MINOR_SEPERATOR = "::"; //$NON-NLS-1$ - private static final String EMPTY_STRING = new String(); - - private IManagedProject managedProject; - private ICProject cProject; - private IConfiguration defaultConfig; - private String defaultConfigId; - private boolean isDirty; - private boolean isValid = false; - private IResource owner; - private boolean rebuildNeeded; - private String version; - private IConfiguration selectedConfig; - - private List targetList; - private Map targetMap; - - private boolean isReadOnly = false; - private boolean bIsContainerInited = false; - - - /** - * Basic contructor used when the project is brand new. - * - * @param owner - */ - public ManagedBuildInfo(IResource owner) { - this.owner = owner; - cProject = CoreModel.getDefault().create(owner.getProject()); - - // Does not need a save but should be rebuilt - isDirty = false; - rebuildNeeded = true; - - // Get the default configs - IProject project = owner.getProject(); - defaultConfigId = null; - try { - defaultConfigId = project.getPersistentProperty(defaultConfigProperty); - } catch (CoreException e) { - // Hitting this error just means the default config is not set - return; - } - } - - /** - * Reads the build information from the project file and creates the - * internal representation of the build settings for the project. - * - * @param owner - * @param element - * @param managedBuildRevision - */ - public ManagedBuildInfo(IResource owner, Element element, String managedBuildRevision) { - this(owner); - - // Recreate the managed build project element and its children - NodeList projNodes = element.getElementsByTagName(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); - // TODO: There should only be 1? - for (int projIndex = projNodes.getLength() - 1; projIndex >= 0; --projIndex) { - ManagedProject proj = new ManagedProject(this, (Element)projNodes.item(projIndex), managedBuildRevision); - if (!proj.resolveReferences()) - proj.setValid(false); - } - - // Switch the rebuild off since this is an existing project - rebuildNeeded = false; - - version = managedBuildRevision; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setManagedProject(IManagedProject) - */ - public void setManagedProject(IManagedProject managedProject) { - this.managedProject = managedProject; - //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getManagedProject() - */ - public IManagedProject getManagedProject() { - return managedProject; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#buildsFileType(java.lang.String) - */ - public boolean buildsFileType(String srcExt) { - // Check to see if there is a rule to build a file with this extension - IConfiguration config = getDefaultConfiguration(); - ITool[] tools = config.getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool != null && tool.buildsFileType(srcExt)) { - return true; - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getBuildArtifactExtension() - */ - public String getBuildArtifactExtension() { - String ext = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - ext = config.getArtifactExtension(); - } - return ext; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getBuildArtifactName() - */ - public String getBuildArtifactName() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getArtifactName(); - } - return name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getCleanCommand() - */ - public String getCleanCommand() { - // Get from the model - String command = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - command = config.getCleanCommand(); - } - return command; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationName() - */ - public String getConfigurationName() { - // Return the human-readable name of the default configuration - IConfiguration config = getDefaultConfiguration(); - return config == null ? new String() : config.getName(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationNames() - */ - public String[] getConfigurationNames() { - ArrayList configNames = new ArrayList(); - IConfiguration[] configs = managedProject.getConfigurations(); - for (int i = 0; i < configs.length; i++) { - IConfiguration configuration = configs[i]; - configNames.add(configuration.getName()); - } - configNames.trimToSize(); - return (String[])configNames.toArray(new String[configNames.size()]); - } - - public ICProject getCProject() { - return cProject; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getDefaultConfiguration() - */ - public IConfiguration getDefaultConfiguration() { - // Get the default config associated with the project - if (defaultConfig == null) { - if (managedProject != null) { - if (defaultConfigId != null) { - defaultConfig = managedProject.getConfiguration(defaultConfigId); - } - if (defaultConfig == null) { - IConfiguration[] configs = managedProject.getConfigurations(); - for (int i = 0; i < configs.length; i++){ - if (configs[i].isSupported()){ - defaultConfig = configs[i]; - defaultConfigId = defaultConfig.getId(); - break; - } - } - if (defaultConfig == null && configs.length > 0) { - defaultConfig = configs[0]; - defaultConfigId = defaultConfig.getId(); - } - } - } - } - return defaultConfig; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getDefinedSymbols() - */ - public Map getDefinedSymbols() { - // Return the defined symbols for the default configuration - HashMap symbols = getMacroPathEntries(); - return symbols; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getDependencyGenerator(java.lang.String) - */ - public IManagedDependencyGeneratorType getDependencyGenerator(String sourceExtension) { - // Find the tool and ask the Managed Build Manager for its dep generator - try { - if (getDefaultConfiguration() != null) { - ITool[] tools = getDefaultConfiguration().getFilteredTools(); - for (int index = 0; index < tools.length; ++index) { - if(tools[index].buildsFileType(sourceExtension)) { - return tools[index].getDependencyGeneratorForExtension(sourceExtension); - } - } - } - } catch (NullPointerException e) { - return null; - } - - return null; - } - - /* (non-Javadoc) - * Helper method to extract a list of valid tools that are filtered by the - * project nature. - * - * @return - */ - private ITool[] getFilteredTools() { - // Get all the tools for the current config filtered by the project nature - IConfiguration config = getDefaultConfiguration(); - return config.getFilteredTools(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForSource(java.lang.String) - */ - public String getFlagsForSource(String extension) { - return getToolFlagsForSource(extension,null,null); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForSource(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation){ - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool != null && tool.buildsFileType(extension)) { - try { - return tool.getToolCommandFlagsString(inputLocation,outputLocation); - } catch (BuildException e) { - return null; - } - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForConfiguration(java.lang.String) - */ - public String getFlagsForConfiguration(String extension) { - return getToolFlagsForConfiguration(extension, null, null); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForConfiguration(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation){ - // Treat null extensions as an empty string - String ext = extension == null ? new String() : extension; - - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - try { - return tool.getToolCommandFlagsString(inputLocation,outputLocation); - } catch (BuildException e) { - return null; - } - } - } - return null; - } - - private ArrayList getIncludePathEntries() { - // Extract the resolved paths from the project (if any) - ArrayList paths = new ArrayList(); - if (cProject != null) { - try { - IPathEntry[] entries = cProject.getResolvedPathEntries(); - for (int index = 0; index < entries.length; ++index) { - int kind = entries[index].getEntryKind(); - if (kind == IPathEntry.CDT_INCLUDE) { - IIncludeEntry include = (IIncludeEntry) entries[index]; - if (include.isSystemInclude()) { - IPath entryPath = include.getFullIncludePath(); - paths.add(entryPath.toString()); - } - } - } - } catch (CModelException e) { - // Just return an empty array - paths.clear(); - return paths; - } - } - return paths; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() - */ - public String[] getIncludePaths() { - // Return the include paths for the default configuration - ArrayList paths = getIncludePathEntries(); - return (String[])paths.toArray(new String[paths.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getLibsForConfiguration(java.lang.String) - */ - public String[] getLibsForConfiguration(String extension) { - Vector libs = new Vector(); - ITool tool = getDefaultConfiguration().getTargetTool(); - if(tool == null) - tool = getToolFromOutputExtension(extension); - - if(tool != null){ - IOption[] opts = tool.getOptions(); - // Look for the lib option type - for (int i = 0; i < opts.length; i++) { - IOption option = opts[i]; - try { - if (option.getValueType() == IOption.LIBRARIES) { - - // check to see if the option has an applicability calculator - IOptionApplicability applicabilitytCalculator = option.getApplicabilityCalculator(); - - if (applicabilitytCalculator == null - || applicabilitytCalculator.isOptionUsedInCommandLine(getDefaultConfiguration(), tool, option)) { - String command = option.getCommand(); - String[] allLibs = option.getLibraries(); - for (int j = 0; j < allLibs.length; j++) - { - try { - String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( - allLibs[j], - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_OPTION, - new OptionContextData(option, tool)); - if(resolved != null && resolved.length > 0){ - for(int k = 0; k < resolved.length; k++){ - String string = resolved[k]; - if(string.length() > 0) - libs.add(command + string); - } - } - } catch (BuildMacroException e) { - // TODO: report error - continue; - } - - } - } - } - } catch (BuildException e) { - // TODO: report error - continue; - } - } - } - return (String[])libs.toArray(new String[libs.size()]); - } - - private HashMap getMacroPathEntries() { - HashMap macros = new HashMap(); - if (cProject != null) { - try { - IPathEntry[] entries = cProject.getResolvedPathEntries(); - for (int index = 0; index < entries.length; ++index) { - if (entries[index].getEntryKind() == IPathEntry.CDT_MACRO) { - IMacroEntry macro = (IMacroEntry) entries[index]; - macros.put(macro.getMacroName(), macro.getMacroValue()); - } - } - } catch (CModelException e) { - // return an empty map - macros.clear(); - return macros; - } - - } - return macros; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeArguments() - */ - public String getBuildArguments() { - if (getDefaultConfiguration() != null) { - IToolChain toolChain = getDefaultConfiguration().getToolChain(); - IBuilder builder = toolChain.getBuilder(); - if (builder != null) { - return builder.getArguments(); - } - } - return new String("-k"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeCommand() - */ - public String getBuildCommand() { - if (getDefaultConfiguration() != null) { - IToolChain toolChain = getDefaultConfiguration().getToolChain(); - IBuilder builder = toolChain.getBuilder(); - if (builder != null) { - return builder.getCommand(); - } - } - return new String("make"); //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPrebuildStep() - */ - public String getPrebuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPrebuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostbuildStep() - */ - public String getPostbuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPostbuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPreannouncebuildStep() - */ - public String getPreannouncebuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPreannouncebuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostannouncebuildStep() - */ - public String getPostannouncebuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPostannouncebuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputExtension(java.lang.String) - */ - public String getOutputExtension(String resourceExtension) { - String outputExtension = null; - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - outputExtension = tool.getOutputExtension(resourceExtension); - if (outputExtension != null) { - return outputExtension; - } - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputFlag() - */ - public String getOutputFlag(String outputExt) { - // Treat null extension as an empty string - String ext = outputExt == null ? new String() : outputExt; - - // Get all the tools for the current config - String flags = new String(); - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - // It's OK - if (tool.producesFileType(ext)) { - flags = tool.getOutputFlag(); - } - } - return flags; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputPrefix(java.lang.String) - */ - public String getOutputPrefix(String outputExtension) { - // Treat null extensions as empty string - String ext = outputExtension == null ? new String() : outputExtension; - - // Get all the tools for the current config - String flags = new String(); - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - flags = tool.getOutputPrefix(); - } - } - return flags; - } - - /** - * @return - */ - public IResource getOwner() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForSource(java.lang.String) - */ - public String getToolForSource(String sourceExtension) { - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.buildsFileType(sourceExtension)) { - return tool.getToolCommand(); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForConfiguration(java.lang.String) - */ - public String getToolForConfiguration(String extension) { - // Treat a null argument as an empty string - String ext = extension == null ? new String() : extension; - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - return tool.getToolCommand(); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromInputExtension(java.lang.String) - */ - public ITool getToolFromInputExtension(String sourceExtension) { - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.buildsFileType(sourceExtension)) { - return tool; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromOutputExtension(java.lang.String) - */ - public ITool getToolFromOutputExtension(String extension) { - // Treat a null argument as an empty string - String ext = extension == null ? new String() : extension; - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - return tool; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[]) - */ - public IManagedCommandLineInfo generateCommandLineInfo( - String sourceExtension, String[] flags, String outputFlag, - String outputPrefix, String outputName, String[] inputResources) { - return generateToolCommandLineInfo( sourceExtension, flags, - outputFlag, outputPrefix, outputName, inputResources, null, null ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateToolCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, - String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ){ - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.buildsFileType(sourceExtension)) { - String cmd = tool.getToolCommand(); - //try to resolve the build macros in the tool command - try{ - String resolvedCommand = null; - - if ((inputLocation != null && inputLocation.toString().indexOf(" ") != -1) || //$NON-NLS-1$ - (outputLocation != null && outputLocation.toString().indexOf(" ") != -1) ) //$NON-NLS-1$ - { - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider().resolveValue( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputLocation, - outputLocation, null, - tool)); - } - - else { - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputLocation, - outputLocation, null, - tool)); - } - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - return gen.generateCommandLineInfo( tool, cmd, - flags, outputFlag, outputPrefix, outputName, inputResources, - tool.getCommandLinePattern() ); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getUserObjectsForConfiguration(java.lang.String) - */ - public String[] getUserObjectsForConfiguration(String extension) { - Vector objs = new Vector(); - ITool tool = getDefaultConfiguration().getTargetTool(); - if(tool == null) - tool = getToolFromOutputExtension(extension); - - if(tool != null){ - IOption[] opts = tool.getOptions(); - // Look for the user object option type - for (int i = 0; i < opts.length; i++) { - IOption option = opts[i]; - try { - if (option.getValueType() == IOption.OBJECTS) { - String unresolved[] = option.getUserObjects(); - if(unresolved != null && unresolved.length > 0){ - for(int k = 0; k < unresolved.length; k++){ - try { - String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( - unresolved[k], - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_OPTION, - new OptionContextData(option, tool)); - if(resolved != null && resolved.length > 0) - objs.addAll(Arrays.asList(resolved)); - } catch (BuildMacroException e) { - // TODO: report error - continue; - } - } - } - } - } catch (BuildException e) { - // TODO: report error - continue; - } - } - } - return (String[])objs.toArray(new String[objs.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getVersion() - */ - public String getVersion() { - return version; - } - - /* (non-Javadoc) - * - */ - public void initializePathEntries() { - if (!isValid()) return; - try { - IPathEntryContainer container = new ManagedBuildCPathEntryContainer(getOwner().getProject()); - CoreModel.setPathEntryContainer(new ICProject[]{cProject}, container, new NullProgressMonitor()); - } catch (CModelException e) { - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isDirty() - */ - public boolean isDirty() { - // If the info has been flagged dirty, answer true - if (isDirty) { - return true; - } - - // Check if the project is dirty - if (managedProject != null) { - return managedProject.isDirty(); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isValid() - */ - public boolean isValid() { - // If the info has been flagged as valid, answer true - return isValid; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isReadOnly() - */ - public boolean isReadOnly(){ - return isReadOnly; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isHeaderFile(java.lang.String) - */ - public boolean isHeaderFile(String ext) { - // Check to see if there is a rule to build a file with this extension - IConfiguration config = getDefaultConfiguration(); - return config.isHeaderFile(ext); - } - - /** - * - * @return boolean - */ - public boolean isContainerInited() { - return bIsContainerInited; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#needsRebuild() - */ - public boolean needsRebuild() { - if (rebuildNeeded) return true; - - if (getDefaultConfiguration() != null) { - return getDefaultConfiguration().needsRebuild(); - } - return false; - } - - /* (non-Javadoc) - * - */ - private void persistDefaultConfiguration() { - // Persist the default configuration - IProject project = owner.getProject(); - try { - if(defaultConfigId != null) - project.setPersistentProperty(defaultConfigProperty, defaultConfigId.toString().trim()); - } catch (CoreException e) { - // Too bad - } - } - - /** - * Write the contents of the build model to the persistent store - * specified in the argument. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - // Write out the managed build project - - if(managedProject != null){ - Element projElement = doc.createElement(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); - element.appendChild(projElement); - managedProject.serialize(doc, projElement); - } - else{ - Iterator iter = getTargets().listIterator(); - while (iter.hasNext()) { - // Get the target - Target targ = (Target)iter.next(); - // Create an XML element to hold the target settings - Element targetElement = doc.createElement(ITarget.TARGET_ELEMENT_NAME); - element.appendChild(targetElement); - targ.serialize(doc, targetElement); - } -// persistDefaultTarget(); - } - - - // Remember the default configuration - persistDefaultConfiguration(); - - // I'm clean now - setDirty(false); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setDefaultConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public void setDefaultConfiguration(IConfiguration configuration) { - // TODO: This is probably wrong. I'll bet we don't handle the case where all configs are deleted... - // But, at least, our UI does not allow the last config to be deleted. - // Sanity - if (configuration == null) return; - - if (!configuration.equals(getDefaultConfiguration())) { - // Save it - defaultConfig = configuration; - defaultConfigId = configuration.getId(); - // TODO: is this appropriate? - persistDefaultConfiguration(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDefaultConfiguration(java.lang.String) - */ - public boolean setDefaultConfiguration(String configName) { - if (configName != null) { - // Look for the configuration with the same name as the argument - IConfiguration[] configs = managedProject.getConfigurations(); - for (int index = configs.length - 1; index >= 0; --index) { - IConfiguration config = configs[index]; - if (configName.equalsIgnoreCase(config.getName())) { - setDefaultConfiguration(config); - return true; - } - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - // Reset the dirty status here - this.isDirty = isDirty; - // and in the managed project - if (managedProject != null) { - managedProject.setDirty(isDirty); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setValid(boolean) - */ - public void setValid(boolean isValid) { - // Reset the valid status - this.isValid = isValid; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setReadOnly(boolean) - */ - public void setReadOnly(boolean readOnly){ - if(!readOnly && isReadOnly) - setDirty(true); - isReadOnly = readOnly; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean) - */ - public void setRebuildState(boolean rebuild) { - // Reset the status here - rebuildNeeded = rebuild; - // TODO: Is the appropriate? Should the rebuild state be stored in the project file? - // and in the managed project - if (getDefaultConfiguration() != null) { - getDefaultConfiguration().setRebuildState(rebuild); - } - } - - /** - * @param version - */ - public void setVersion(String version) { - if (version != null && !version.equals(this.version)) { - this.version = version; - //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state - } - updateRevision(version); - } - - /** - * @param boolean - */ - public void setContainerInited(boolean bInited) { - bIsContainerInited = bInited; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - // Just print out the name of the project - return "Managed build information for " + owner.getName(); //$NON-NLS-1$ - } - - /** - * Sets the owner of the receiver to be the IResource specified - * in the argument. - * - * @param resource - */ - public void updateOwner(IResource resource) { - // Check to see if the owner is the same as the argument - if (resource != null) { - if (!owner.equals(resource)) { - owner = resource; - // Do the same for the managed project - managedProject.updateOwner(resource); - // And finally update the cModelElement - cProject = CoreModel.getDefault().create(owner.getProject()); - - // Save everything - setDirty(true); - setRebuildState(true); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getSelectedConfiguration() - */ - public IConfiguration getSelectedConfiguration() { - return selectedConfig; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setSelectedConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public void setSelectedConfiguration(IConfiguration config) { - selectedConfig = config; - } - - /* - * Note: "Target" routines are only currently applicable when loading a CDT 2.0 - * or earlier managed build project file (.cdtbuild) - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#addTarget(org.eclipse.cdt.core.build.managed.ITarget) - */ - public void addTarget(ITarget target) { - getTargetMap().put(target.getId(), target); - getTargets().add(target); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#removeTarget(java.lang.String) - */ - public void removeTarget(String id) { - getTargets().remove(getTarget(id)); - getTargetMap().remove(id); - setDirty(true); - - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTarget(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public ITarget getTarget(String id) { - return (ITarget) getTargetMap().get(id); - } - - /* (non-Javadoc) - * Safe accessor. - * - * @return Returns the map of IDs to ITargets. - */ - private Map getTargetMap() { - if (targetMap == null) { - targetMap = new HashMap(); - } - return targetMap; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTargets(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public List getTargets() { - if (targetList == null) { - targetList = new ArrayList(); - } - return targetList; - } - - /** - * - * @return - */ - private String getCWD() { - String cwd = ""; //$NON-NLS-1$ - IBuildEnvironmentVariable cwdvar = ManagedBuildManager.getEnvironmentVariableProvider().getVariable("CWD", getDefaultConfiguration(), false, true); //$NON-NLS-1$ - if (cwdvar != null) { cwd = cwdvar.getValue().replace('\\','/'); } //$NON-NLS-1$ //$NON-NLS-2$ - return cwd; - } - - /** - */ - private List processPath(List list, String path, int context, Object obj) { - final String EMPTY = ""; //$NON-NLS-1$ - if (path != null) { - if (context != 0) { - try { - String paths[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValue(path, EMPTY, " ", context, obj); //$NON-NLS-1$ - if (paths != null) { - for(int i = 0; i < paths.length; i++){ - list.add(checkPath(paths[i])); - } - } - } catch (BuildMacroException e) { - } - } else { - list.add(checkPath(path)); - } - } - return list; - } - - private String checkPath(String p){ - final String QUOTE = "\""; //$NON-NLS-1$ - final String EMPTY = ""; //$NON-NLS-1$ - - if(p == null) - return EMPTY; - - if (p.length()> 1 && p.startsWith(QUOTE) && p.endsWith(QUOTE)) { - p = p.substring(1, p.length()-1); - } - - if ( ".".equals(p) ) { //$NON-NLS-1$ - String cwd = getCWD(); - if (cwd.length()>0) { p = cwd; } - } - if (!(new Path(p)).isAbsolute()) { - String cwd = getCWD(); - if (cwd.length()>0) { p = cwd + "/" + p; } //$NON-NLS-1$ - } - return p; - - } - - /** - * Obtain all possible Managed build values - * @return - */ - public IPathEntry[] getManagedBuildValues() { - List entries = new ArrayList(); - int i=0; - IPathEntry[] a = getManagedBuildValues(IPathEntry.CDT_INCLUDE); - if (a != null) { for (i=0; i 0) { - List list = new ArrayList(); - for (int k=0; k 1) ? tokens[1].trim() : new String(); - // Make sure the current entries do not contain a duplicate - boolean add = true; - Iterator entryIter = entries.listIterator(); - while (entryIter.hasNext()) { - IPathEntry entry = (IPathEntry) entryIter.next(); - if (entry.getEntryKind() == IPathEntry.CDT_MACRO) { - if (((IMacroEntry)entry).getMacroName().equals(key) && - ((IMacroEntry)entry).getMacroValue().equals(value)) { - add = false; - break; - } - } - } - if (add) { entries.add(CoreModel.newMacroEntry(resPath, key, value)); } - } - return entries; - } - - public void updateRevision(String revision){ - if(managedProject != null) - ((ManagedProject)managedProject).updateManagedBuildRevision(revision); - } - -} +/******************************************************************************* + * Copyright (c) 2002, 2006 IBM Software 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 Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +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 java.util.Vector; + +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.IContainerEntry; +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.model.IPathEntryContainer; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITarget; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; +import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +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.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.QualifiedName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * + * @since 1.2 + */ +public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { + // The path container used for all managed projects + public static final IContainerEntry containerEntry = CoreModel.newContainerEntry(new Path("org.eclipse.cdt.managedbuilder.MANAGED_CONTAINER")); //$NON-NLS-1$ + private static final QualifiedName defaultConfigProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_CONFIGURATION); + //private static final QualifiedName defaultTargetProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_TARGET); + public static final String MAJOR_SEPERATOR = ";"; //$NON-NLS-1$ + public static final String MINOR_SEPERATOR = "::"; //$NON-NLS-1$ + private static final String EMPTY_STRING = new String(); + + private IManagedProject managedProject; + private ICProject cProject; + private IConfiguration defaultConfig; + private String defaultConfigId; + private boolean isDirty; + private boolean isValid = false; + private IResource owner; + private boolean rebuildNeeded; + private String version; + private IConfiguration selectedConfig; + + private List targetList; + private Map targetMap; + + private boolean isReadOnly = false; + private boolean bIsContainerInited = false; + + + /** + * Basic contructor used when the project is brand new. + * + * @param owner + */ + public ManagedBuildInfo(IResource owner) { + this.owner = owner; + cProject = CoreModel.getDefault().create(owner.getProject()); + + // Does not need a save but should be rebuilt + isDirty = false; + rebuildNeeded = true; + + // Get the default configs + IProject project = owner.getProject(); + defaultConfigId = null; + try { + defaultConfigId = project.getPersistentProperty(defaultConfigProperty); + } catch (CoreException e) { + // Hitting this error just means the default config is not set + return; + } + } + + /** + * Reads the build information from the project file and creates the + * internal representation of the build settings for the project. + * + * @param owner + * @param element + * @param managedBuildRevision + */ + public ManagedBuildInfo(IResource owner, Element element, String managedBuildRevision) { + this(owner); + + // Recreate the managed build project element and its children + NodeList projNodes = element.getElementsByTagName(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); + // TODO: There should only be 1? + for (int projIndex = projNodes.getLength() - 1; projIndex >= 0; --projIndex) { + ManagedProject proj = new ManagedProject(this, (Element)projNodes.item(projIndex), managedBuildRevision); + if (!proj.resolveReferences()) + proj.setValid(false); + } + + // Switch the rebuild off since this is an existing project + rebuildNeeded = false; + + version = managedBuildRevision; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setManagedProject(IManagedProject) + */ + public void setManagedProject(IManagedProject managedProject) { + this.managedProject = managedProject; + //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getManagedProject() + */ + public IManagedProject getManagedProject() { + return managedProject; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#buildsFileType(java.lang.String) + */ + public boolean buildsFileType(String srcExt) { + // Check to see if there is a rule to build a file with this extension + IConfiguration config = getDefaultConfiguration(); + ITool[] tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool != null && tool.buildsFileType(srcExt)) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getBuildArtifactExtension() + */ + public String getBuildArtifactExtension() { + String ext = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + ext = config.getArtifactExtension(); + } + return ext; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getBuildArtifactName() + */ + public String getBuildArtifactName() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getArtifactName(); + } + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getCleanCommand() + */ + public String getCleanCommand() { + // Get from the model + String command = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + command = config.getCleanCommand(); + } + return command; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationName() + */ + public String getConfigurationName() { + // Return the human-readable name of the default configuration + IConfiguration config = getDefaultConfiguration(); + return config == null ? new String() : config.getName(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationNames() + */ + public String[] getConfigurationNames() { + ArrayList configNames = new ArrayList(); + IConfiguration[] configs = managedProject.getConfigurations(); + for (int i = 0; i < configs.length; i++) { + IConfiguration configuration = configs[i]; + configNames.add(configuration.getName()); + } + configNames.trimToSize(); + return (String[])configNames.toArray(new String[configNames.size()]); + } + + public ICProject getCProject() { + return cProject; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getDefaultConfiguration() + */ + public IConfiguration getDefaultConfiguration() { + // Get the default config associated with the project + if (defaultConfig == null) { + if (managedProject != null) { + if (defaultConfigId != null) { + defaultConfig = managedProject.getConfiguration(defaultConfigId); + } + if (defaultConfig == null) { + IConfiguration[] configs = managedProject.getConfigurations(); + for (int i = 0; i < configs.length; i++){ + if (configs[i].isSupported()){ + defaultConfig = configs[i]; + defaultConfigId = defaultConfig.getId(); + break; + } + } + if (defaultConfig == null && configs.length > 0) { + defaultConfig = configs[0]; + defaultConfigId = defaultConfig.getId(); + } + } + } + } + return defaultConfig; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getDefinedSymbols() + */ + public Map getDefinedSymbols() { + // Return the defined symbols for the default configuration + HashMap symbols = getMacroPathEntries(); + return symbols; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getDependencyGenerator(java.lang.String) + */ + public IManagedDependencyGeneratorType getDependencyGenerator(String sourceExtension) { + // Find the tool and ask the Managed Build Manager for its dep generator + try { + if (getDefaultConfiguration() != null) { + ITool[] tools = getDefaultConfiguration().getFilteredTools(); + for (int index = 0; index < tools.length; ++index) { + if(tools[index].buildsFileType(sourceExtension)) { + return tools[index].getDependencyGeneratorForExtension(sourceExtension); + } + } + } + } catch (NullPointerException e) { + return null; + } + + return null; + } + + /* (non-Javadoc) + * Helper method to extract a list of valid tools that are filtered by the + * project nature. + * + * @return + */ + private ITool[] getFilteredTools() { + // Get all the tools for the current config filtered by the project nature + IConfiguration config = getDefaultConfiguration(); + return config.getFilteredTools(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForSource(java.lang.String) + */ + public String getFlagsForSource(String extension) { + return getToolFlagsForSource(extension,null,null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForSource(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation){ + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool != null && tool.buildsFileType(extension)) { + try { + return tool.getToolCommandFlagsString(inputLocation,outputLocation); + } catch (BuildException e) { + return null; + } + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForConfiguration(java.lang.String) + */ + public String getFlagsForConfiguration(String extension) { + return getToolFlagsForConfiguration(extension, null, null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForConfiguration(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation){ + // Treat null extensions as an empty string + String ext = extension == null ? new String() : extension; + + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + try { + return tool.getToolCommandFlagsString(inputLocation,outputLocation); + } catch (BuildException e) { + return null; + } + } + } + return null; + } + + private ArrayList getIncludePathEntries() { + // Extract the resolved paths from the project (if any) + ArrayList paths = new ArrayList(); + if (cProject != null) { + try { + IPathEntry[] entries = cProject.getResolvedPathEntries(); + for (int index = 0; index < entries.length; ++index) { + int kind = entries[index].getEntryKind(); + if (kind == IPathEntry.CDT_INCLUDE) { + IIncludeEntry include = (IIncludeEntry) entries[index]; + if (include.isSystemInclude()) { + IPath entryPath = include.getFullIncludePath(); + paths.add(entryPath.toString()); + } + } + } + } catch (CModelException e) { + // Just return an empty array + paths.clear(); + return paths; + } + } + return paths; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() + */ + public String[] getIncludePaths() { + // Return the include paths for the default configuration + ArrayList paths = getIncludePathEntries(); + return (String[])paths.toArray(new String[paths.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getLibsForConfiguration(java.lang.String) + */ + public String[] getLibsForConfiguration(String extension) { + Vector libs = new Vector(); + ITool tool = getDefaultConfiguration().getTargetTool(); + if(tool == null) + tool = getToolFromOutputExtension(extension); + + if(tool != null){ + IOption[] opts = tool.getOptions(); + // Look for the lib option type + for (int i = 0; i < opts.length; i++) { + IOption option = opts[i]; + try { + if (option.getValueType() == IOption.LIBRARIES) { + + // check to see if the option has an applicability calculator + IOptionApplicability applicabilitytCalculator = option.getApplicabilityCalculator(); + + if (applicabilitytCalculator == null + || applicabilitytCalculator.isOptionUsedInCommandLine(getDefaultConfiguration(), tool, option)) { + String command = option.getCommand(); + String[] allLibs = option.getLibraries(); + for (int j = 0; j < allLibs.length; j++) + { + try { + String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( + allLibs[j], + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_OPTION, + new OptionContextData(option, tool)); + if(resolved != null && resolved.length > 0){ + for(int k = 0; k < resolved.length; k++){ + String string = resolved[k]; + if(string.length() > 0) + libs.add(command + string); + } + } + } catch (BuildMacroException e) { + // TODO: report error + continue; + } + + } + } + } + } catch (BuildException e) { + // TODO: report error + continue; + } + } + } + return (String[])libs.toArray(new String[libs.size()]); + } + + private HashMap getMacroPathEntries() { + HashMap macros = new HashMap(); + if (cProject != null) { + try { + IPathEntry[] entries = cProject.getResolvedPathEntries(); + for (int index = 0; index < entries.length; ++index) { + if (entries[index].getEntryKind() == IPathEntry.CDT_MACRO) { + IMacroEntry macro = (IMacroEntry) entries[index]; + macros.put(macro.getMacroName(), macro.getMacroValue()); + } + } + } catch (CModelException e) { + // return an empty map + macros.clear(); + return macros; + } + + } + return macros; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeArguments() + */ + public String getBuildArguments() { + if (getDefaultConfiguration() != null) { + IToolChain toolChain = getDefaultConfiguration().getToolChain(); + IBuilder builder = toolChain.getBuilder(); + if (builder != null) { + return builder.getArguments(); + } + } + return new String("-k"); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeCommand() + */ + public String getBuildCommand() { + if (getDefaultConfiguration() != null) { + IToolChain toolChain = getDefaultConfiguration().getToolChain(); + IBuilder builder = toolChain.getBuilder(); + if (builder != null) { + return builder.getCommand(); + } + } + return new String("make"); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPrebuildStep() + */ + public String getPrebuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPrebuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostbuildStep() + */ + public String getPostbuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPostbuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPreannouncebuildStep() + */ + public String getPreannouncebuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPreannouncebuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostannouncebuildStep() + */ + public String getPostannouncebuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPostannouncebuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputExtension(java.lang.String) + */ + public String getOutputExtension(String resourceExtension) { + String outputExtension = null; + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + outputExtension = tool.getOutputExtension(resourceExtension); + if (outputExtension != null) { + return outputExtension; + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputFlag() + */ + public String getOutputFlag(String outputExt) { + // Treat null extension as an empty string + String ext = outputExt == null ? new String() : outputExt; + + // Get all the tools for the current config + String flags = new String(); + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + // It's OK + if (tool.producesFileType(ext)) { + flags = tool.getOutputFlag(); + } + } + return flags; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputPrefix(java.lang.String) + */ + public String getOutputPrefix(String outputExtension) { + // Treat null extensions as empty string + String ext = outputExtension == null ? new String() : outputExtension; + + // Get all the tools for the current config + String flags = new String(); + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + flags = tool.getOutputPrefix(); + } + } + return flags; + } + + /** + * @return + */ + public IResource getOwner() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForSource(java.lang.String) + */ + public String getToolForSource(String sourceExtension) { + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.buildsFileType(sourceExtension)) { + return tool.getToolCommand(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForConfiguration(java.lang.String) + */ + public String getToolForConfiguration(String extension) { + // Treat a null argument as an empty string + String ext = extension == null ? new String() : extension; + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + return tool.getToolCommand(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromInputExtension(java.lang.String) + */ + public ITool getToolFromInputExtension(String sourceExtension) { + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.buildsFileType(sourceExtension)) { + return tool; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromOutputExtension(java.lang.String) + */ + public ITool getToolFromOutputExtension(String extension) { + // Treat a null argument as an empty string + String ext = extension == null ? new String() : extension; + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + return tool; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[]) + */ + public IManagedCommandLineInfo generateCommandLineInfo( + String sourceExtension, String[] flags, String outputFlag, + String outputPrefix, String outputName, String[] inputResources) { + return generateToolCommandLineInfo( sourceExtension, flags, + outputFlag, outputPrefix, outputName, inputResources, null, null ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateToolCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, + String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ){ + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.buildsFileType(sourceExtension)) { + String cmd = tool.getToolCommand(); + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = null; + + if ((inputLocation != null && inputLocation.toString().indexOf(" ") != -1) || //$NON-NLS-1$ + (outputLocation != null && outputLocation.toString().indexOf(" ") != -1) ) //$NON-NLS-1$ + { + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider().resolveValue( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputLocation, + outputLocation, null, + tool)); + } + + else { + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputLocation, + outputLocation, null, + tool)); + } + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); + return gen.generateCommandLineInfo( tool, cmd, + flags, outputFlag, outputPrefix, outputName, inputResources, + tool.getCommandLinePattern() ); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getUserObjectsForConfiguration(java.lang.String) + */ + public String[] getUserObjectsForConfiguration(String extension) { + Vector objs = new Vector(); + ITool tool = getDefaultConfiguration().getTargetTool(); + if(tool == null) + tool = getToolFromOutputExtension(extension); + + if(tool != null){ + IOption[] opts = tool.getOptions(); + // Look for the user object option type + for (int i = 0; i < opts.length; i++) { + IOption option = opts[i]; + try { + if (option.getValueType() == IOption.OBJECTS) { + String unresolved[] = option.getUserObjects(); + if(unresolved != null && unresolved.length > 0){ + for(int k = 0; k < unresolved.length; k++){ + try { + String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( + unresolved[k], + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_OPTION, + new OptionContextData(option, tool)); + if(resolved != null && resolved.length > 0) + objs.addAll(Arrays.asList(resolved)); + } catch (BuildMacroException e) { + // TODO: report error + continue; + } + } + } + } + } catch (BuildException e) { + // TODO: report error + continue; + } + } + } + return (String[])objs.toArray(new String[objs.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getVersion() + */ + public String getVersion() { + return version; + } + + /* (non-Javadoc) + * + */ + public void initializePathEntries() { + if (!isValid()) return; + try { + IPathEntryContainer container = new ManagedBuildCPathEntryContainer(getOwner().getProject()); + CoreModel.setPathEntryContainer(new ICProject[]{cProject}, container, new NullProgressMonitor()); + } catch (CModelException e) { + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isDirty() + */ + public boolean isDirty() { + // If the info has been flagged dirty, answer true + if (isDirty) { + return true; + } + + // Check if the project is dirty + if (managedProject != null) { + return managedProject.isDirty(); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isValid() + */ + public boolean isValid() { + // If the info has been flagged as valid, answer true + return isValid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isReadOnly() + */ + public boolean isReadOnly(){ + return isReadOnly; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isHeaderFile(java.lang.String) + */ + public boolean isHeaderFile(String ext) { + // Check to see if there is a rule to build a file with this extension + IConfiguration config = getDefaultConfiguration(); + return config.isHeaderFile(ext); + } + + /** + * + * @return boolean + */ + public boolean isContainerInited() { + return bIsContainerInited; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#needsRebuild() + */ + public boolean needsRebuild() { + if (rebuildNeeded) return true; + + if (getDefaultConfiguration() != null) { + return getDefaultConfiguration().needsRebuild(); + } + return false; + } + + /* (non-Javadoc) + * + */ + private void persistDefaultConfiguration() { + // Persist the default configuration + IProject project = owner.getProject(); + try { + if(defaultConfigId != null) + project.setPersistentProperty(defaultConfigProperty, defaultConfigId.toString().trim()); + } catch (CoreException e) { + // Too bad + } + } + + /** + * Write the contents of the build model to the persistent store + * specified in the argument. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + // Write out the managed build project + + if(managedProject != null){ + Element projElement = doc.createElement(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); + element.appendChild(projElement); + managedProject.serialize(doc, projElement); + } + else{ + Iterator iter = getTargets().listIterator(); + while (iter.hasNext()) { + // Get the target + Target targ = (Target)iter.next(); + // Create an XML element to hold the target settings + Element targetElement = doc.createElement(ITarget.TARGET_ELEMENT_NAME); + element.appendChild(targetElement); + targ.serialize(doc, targetElement); + } +// persistDefaultTarget(); + } + + + // Remember the default configuration + persistDefaultConfiguration(); + + // I'm clean now + setDirty(false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setDefaultConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public void setDefaultConfiguration(IConfiguration configuration) { + // TODO: This is probably wrong. I'll bet we don't handle the case where all configs are deleted... + // But, at least, our UI does not allow the last config to be deleted. + // Sanity + if (configuration == null) return; + + if (!configuration.equals(getDefaultConfiguration())) { + // Save it + defaultConfig = configuration; + defaultConfigId = configuration.getId(); + // TODO: is this appropriate? + persistDefaultConfiguration(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDefaultConfiguration(java.lang.String) + */ + public boolean setDefaultConfiguration(String configName) { + if (configName != null) { + // Look for the configuration with the same name as the argument + IConfiguration[] configs = managedProject.getConfigurations(); + for (int index = configs.length - 1; index >= 0; --index) { + IConfiguration config = configs[index]; + if (configName.equalsIgnoreCase(config.getName())) { + setDefaultConfiguration(config); + return true; + } + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + // Reset the dirty status here + this.isDirty = isDirty; + // and in the managed project + if (managedProject != null) { + managedProject.setDirty(isDirty); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setValid(boolean) + */ + public void setValid(boolean isValid) { + // Reset the valid status + this.isValid = isValid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setReadOnly(boolean) + */ + public void setReadOnly(boolean readOnly){ + if(!readOnly && isReadOnly) + setDirty(true); + isReadOnly = readOnly; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean) + */ + public void setRebuildState(boolean rebuild) { + // Reset the status here + rebuildNeeded = rebuild; + // TODO: Is the appropriate? Should the rebuild state be stored in the project file? + // and in the managed project + if (getDefaultConfiguration() != null) { + getDefaultConfiguration().setRebuildState(rebuild); + } + } + + /** + * @param version + */ + public void setVersion(String version) { + if (version != null && !version.equals(this.version)) { + this.version = version; + //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state + } + updateRevision(version); + } + + /** + * @param boolean + */ + public void setContainerInited(boolean bInited) { + bIsContainerInited = bInited; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + // Just print out the name of the project + return "Managed build information for " + owner.getName(); //$NON-NLS-1$ + } + + /** + * Sets the owner of the receiver to be the IResource specified + * in the argument. + * + * @param resource + */ + public void updateOwner(IResource resource) { + // Check to see if the owner is the same as the argument + if (resource != null) { + if (!owner.equals(resource)) { + owner = resource; + // Do the same for the managed project + managedProject.updateOwner(resource); + // And finally update the cModelElement + cProject = CoreModel.getDefault().create(owner.getProject()); + + // Save everything + setDirty(true); + setRebuildState(true); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getSelectedConfiguration() + */ + public IConfiguration getSelectedConfiguration() { + return selectedConfig; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setSelectedConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public void setSelectedConfiguration(IConfiguration config) { + selectedConfig = config; + } + + /* + * Note: "Target" routines are only currently applicable when loading a CDT 2.0 + * or earlier managed build project file (.cdtbuild) + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#addTarget(org.eclipse.cdt.core.build.managed.ITarget) + */ + public void addTarget(ITarget target) { + getTargetMap().put(target.getId(), target); + getTargets().add(target); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#removeTarget(java.lang.String) + */ + public void removeTarget(String id) { + getTargets().remove(getTarget(id)); + getTargetMap().remove(id); + setDirty(true); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTarget(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public ITarget getTarget(String id) { + return (ITarget) getTargetMap().get(id); + } + + /* (non-Javadoc) + * Safe accessor. + * + * @return Returns the map of IDs to ITargets. + */ + private Map getTargetMap() { + if (targetMap == null) { + targetMap = new HashMap(); + } + return targetMap; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTargets(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public List getTargets() { + if (targetList == null) { + targetList = new ArrayList(); + } + return targetList; + } + + /** + * + * @return + */ + private String getCWD() { + String cwd = ""; //$NON-NLS-1$ + IBuildEnvironmentVariable cwdvar = ManagedBuildManager.getEnvironmentVariableProvider().getVariable("CWD", getDefaultConfiguration(), false, true); //$NON-NLS-1$ + if (cwdvar != null) { cwd = cwdvar.getValue().replace('\\','/'); } //$NON-NLS-1$ //$NON-NLS-2$ + return cwd; + } + + /** + */ + private List processPath(List list, String path, int context, Object obj) { + final String EMPTY = ""; //$NON-NLS-1$ + if (path != null) { + if (context != 0) { + try { + String paths[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValue(path, EMPTY, " ", context, obj); //$NON-NLS-1$ + if (paths != null) { + for(int i = 0; i < paths.length; i++){ + list.add(checkPath(paths[i])); + } + } + } catch (BuildMacroException e) { + } + } else { + list.add(checkPath(path)); + } + } + return list; + } + + private String checkPath(String p){ + final String QUOTE = "\""; //$NON-NLS-1$ + final String EMPTY = ""; //$NON-NLS-1$ + + if(p == null) + return EMPTY; + + if (p.length()> 1 && p.startsWith(QUOTE) && p.endsWith(QUOTE)) { + p = p.substring(1, p.length()-1); + } + + if ( ".".equals(p) ) { //$NON-NLS-1$ + String cwd = getCWD(); + if (cwd.length()>0) { p = cwd; } + } + if (!(new Path(p)).isAbsolute()) { + String cwd = getCWD(); + if (cwd.length()>0) { p = cwd + "/" + p; } //$NON-NLS-1$ + } + return p; + + } + + /** + * Obtain all possible Managed build values + * @return + */ + public IPathEntry[] getManagedBuildValues() { + List entries = new ArrayList(); + int i=0; + IPathEntry[] a = getManagedBuildValues(IPathEntry.CDT_INCLUDE); + if (a != null) { for (i=0; i 0) { + List list = new ArrayList(); + for (int k=0; k 1) ? tokens[1].trim() : new String(); + // Make sure the current entries do not contain a duplicate + boolean add = true; + Iterator entryIter = entries.listIterator(); + while (entryIter.hasNext()) { + IPathEntry entry = (IPathEntry) entryIter.next(); + if (entry.getEntryKind() == IPathEntry.CDT_MACRO) { + if (((IMacroEntry)entry).getMacroName().equals(key) && + ((IMacroEntry)entry).getMacroValue().equals(value)) { + add = false; + break; + } + } + } + if (add) { entries.add(CoreModel.newMacroEntry(resPath, key, value)); } + } + return entries; + } + + public void updateRevision(String revision){ + if(managedProject != null) + ((ManagedProject)managedProject).updateManagedBuildRevision(revision); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java index 1d3d52488e2..bc276ea0783 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java @@ -1,535 +1,535 @@ -/******************************************************************************* - * Copyright (c) 2004, 2005 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.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; -import org.eclipse.cdt.managedbuilder.internal.envvar.StorableEnvironment; -import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -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.IProgressMonitor; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class ManagedProject extends BuildObject implements IManagedProject { - - private static final String EMPTY_STRING = new String(); - private static final IConfiguration[] emptyConfigs = new IConfiguration[0]; - - // Parent and children - private IProjectType projectType; - private String projectTypeId; - private IResource owner; - private List configList; // Configurations of this project type - private Map configMap; - // Miscellaneous - private boolean isDirty = false; - private boolean isValid = true; - private boolean resolved = true; - //holds the user-defined macros - private StorableMacros userDefinedMacros; - //holds user-defined environment - private StorableEnvironment userDefinedEnvironment; - /* - * C O N S T R U C T O R S - */ - - /* (non-Javadoc) - * Sets the Eclipse project that owns the Managed Project - * - * @param owner - */ - protected ManagedProject(IResource owner) { - this.owner = owner; - } - - /** - * Create a project instance from the project-type specified in the argument, - * that is owned by the specified Eclipse project. - * - * @param owner the Eclipse project that owns the Managed Project - * @param projectType - */ - public ManagedProject(IResource owner, IProjectType projectType) { - // Make the owner of the ProjectType the project resource - this(owner); - - // Copy the parent's identity - this.projectType = projectType; - int id = ManagedBuildManager.getRandomNumber(); - setId(owner.getName() + "." + projectType.getId() + "." + id); //$NON-NLS-1$ //$NON-NLS-2$ - setName(projectType.getName()); - - setManagedBuildRevision(projectType.getManagedBuildRevision()); - - // Hook me up - IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(owner); - buildInfo.setManagedProject(this); - setDirty(true); - } - - /** - * Create the project instance from project file. - * - * @param buildInfo - * @param element - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public ManagedProject(ManagedBuildInfo buildInfo, Element element, String managedBuildRevision) { - this(buildInfo.getOwner()); - - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - if (loadFromProject(element)) { - - // check for migration support. - boolean isSupportAvailable = projectType.checkForMigrationSupport(); - if (isSupportAvailable == false) { - setValid(false); - } - - // Load children - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) { - Configuration config = new Configuration(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { - //load user-defined macros - userDefinedMacros = new StorableMacros((Element)configElement); - } - - } - } else { - setValid(false); - } - - // hook me up - buildInfo.setManagedProject(this); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Initialize the project information from the XML element - * specified in the argument - * - * @param element An XML element containing the project information - */ - protected boolean loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // projectType - projectTypeId = element.getAttribute(PROJECTTYPE); - if (projectTypeId != null && projectTypeId.length() > 0) { - projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); - if (projectType == null) { - return false; - } - } - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#serialize() - */ - public void serialize(Document doc, Element element) { - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - if (projectType != null) { - element.setAttribute(PROJECTTYPE, projectType.getId()); - } - - // Serialize my children - List configElements = getConfigurationList(); - Iterator iter = configElements.listIterator(); - while (iter.hasNext()) { - Configuration config = (Configuration) iter.next(); - Element configElement = doc.createElement(IConfiguration.CONFIGURATION_ELEMENT_NAME); - element.appendChild(configElement); - config.serialize(doc, configElement); - } - - //serialize user-defined macros - if(userDefinedMacros != null){ - Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); - element.appendChild(macrosElement); - userDefinedMacros.serialize(doc,macrosElement); - } - - if(userDefinedEnvironment != null){ - EnvironmentVariableProvider.fUserSupplier.storeEnvironment(this,true); - } - - // I am clean now - isDirty = false; - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getOwner() - */ - public IResource getOwner() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#updateOwner(org.eclipse.core.resources.IResource) - */ - public void updateOwner(IResource resource) { - if (!resource.equals(owner)) { - // Set the owner correctly - owner = resource; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getProjectType() - */ - public IProjectType getProjectType() { - return projectType; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public IConfiguration createConfiguration(IConfiguration parent, String id) { - Configuration config = new Configuration(this, (Configuration)parent, id, false, false); - ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); - return (IConfiguration)config; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfigurationClone(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public IConfiguration createConfigurationClone(IConfiguration parent, String id) { - Configuration config = new Configuration(this, (Configuration)parent, id, true, false); - // Inform all options in the configuration and all its resource configurations - ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); - return (IConfiguration)config; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedProject#getConfiguration() - */ - public IConfiguration getConfiguration(String id) { - return (IConfiguration)getConfigurationMap().get(id); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getConfigurations() - */ - public IConfiguration[] getConfigurations() { - IConfiguration[] configs = new IConfiguration[getConfigurationList().size()]; - Iterator iter = getConfigurationList().listIterator(); - int i = 0; - while (iter.hasNext()) { - Configuration config = (Configuration)iter.next(); - configs[i++] = (IConfiguration)config; - } - return configs; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#removeConfiguration(java.lang.String) - */ - public void removeConfiguration(String id) { - final String removeId = id; - - //handle the case of temporary configuration - if(getConfigurationMap().get(id) == null) - return; - - IWorkspaceRunnable remover = new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - // Remove the specified configuration from the list and map - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - IConfiguration config = (IConfiguration)iter.next(); - if (config.getId().equals(removeId)) { - // TODO: For now we clean the entire project. This may be overkill, but - // it avoids a problem with leaving the configuration output directory - // around and having the outputs try to be used by the makefile generator code. - IResource proj = config.getOwner(); - IManagedBuildInfo info = null; - if (proj instanceof IProject) { - info = ManagedBuildManager.getBuildInfo(proj); - } - IConfiguration currentConfig = null; - boolean isCurrent = true; - if (info != null) { - currentConfig = info.getDefaultConfiguration(); - if (!currentConfig.getId().equals(removeId)) { - info.setDefaultConfiguration(config); - isCurrent = false; - } - } - ((IProject)proj).build(IncrementalProjectBuilder.CLEAN_BUILD, monitor); - - ManagedBuildManager.performValueHandlerEvent(config, - IManagedOptionValueHandler.EVENT_CLOSE); - getConfigurationList().remove(config); - getConfigurationMap().remove(removeId); - - if (info != null) { - if (!isCurrent) { - info.setDefaultConfiguration(currentConfig); - } else { - // If the current default config is the one being removed, reset the default config - String[] configs = info.getConfigurationNames(); - if (configs.length > 0) { - info.setDefaultConfiguration(configs[0]); - } - } - } - break; - } - } - } - }; - try { - ResourcesPlugin.getWorkspace().run( remover, null ); - } - catch( CoreException e ) {} - setDirty(true); - } - - /* (non-Javadoc) - * Adds the Configuration to the Configuration list and map - * - * @param Tool - */ - public void addConfiguration(Configuration configuration) { - if(!configuration.isTemporary()){ - getConfigurationList().add(configuration); - getConfigurationMap().put(configuration.getId(), configuration); - } - } - - /* (non-Javadoc) - * Safe accessor for the list of configurations. - * - * @return List containing the configurations - */ - private List getConfigurationList() { - if (configList == null) { - configList = new ArrayList(); - } - return configList; - } - - /* (non-Javadoc) - * Safe accessor for the map of configuration ids to configurations - * - * @return - */ - public Map getConfigurationMap() { - if (configMap == null) { - configMap = new HashMap(); - } - return configMap; - } - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#(getDefaultArtifactName) - */ - public String getDefaultArtifactName(){ - String name = new String(); - // Check for spaces - String[] tokens = getOwner().getName().split("\\s"); //$NON-NLS-1$ - for (int index = 0; index < tokens.length; ++index) { - name += tokens[index]; - } - return name; - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references - */ - public boolean resolveReferences() { - if (!resolved) { - resolved = true; - // Resolve project-type - if (projectTypeId != null && projectTypeId.length() > 0) { - projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); - if (projectType == null) { - return false; - } - } - - // call resolve references on any children - Iterator configIter = getConfigurationList().iterator(); - while (configIter.hasNext()) { - Configuration current = (Configuration)configIter.next(); - current.resolveReferences(); - } - } - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isDirty() - */ - public boolean isDirty() { - // If I need saving, just say yes - if (isDirty) return true; - - //check whether the project - specific macros are dirty - if(userDefinedMacros != null && userDefinedMacros.isDirty()) - return true; - - //check whether the project - specific environment is dirty - if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) - return true; - - - // Otherwise see if any configurations need saving - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - Configuration current = (Configuration) iter.next(); - if (current.isDirty()) return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to the children - if (!isDirty) { - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - Configuration current = (Configuration) iter.next(); - current.setDirty(false); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isValid() - */ - public boolean isValid() { - // TODO: In the future, children could also have a "valid" state that should be checked - return isValid; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setValid(boolean) - */ - public void setValid(boolean isValid) { - // TODO: In the future, children could also have a "valid" state... - this.isValid = isValid; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if (version == null) { - if ( getProjectType() != null) { - return getProjectType().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } - - /* - * this method is called by the UserDefinedMacroSupplier to obtain user-defined - * macros available for this managed project - */ - public StorableMacros getUserDefinedMacros(){ - if(userDefinedMacros == null) - userDefinedMacros = new StorableMacros(); - return userDefinedMacros; - } - - public StorableEnvironment getUserDefinedEnvironmet(){ - return userDefinedEnvironment; - } - - public void setUserDefinedEnvironmet(StorableEnvironment env){ - userDefinedEnvironment = env; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) - */ - public void updateManagedBuildRevision(String revision){ - super.updateManagedBuildRevision(revision); - for(Iterator iter = getConfigurationList().iterator(); iter.hasNext();){ - Configuration cfg = (Configuration)iter.next(); - cfg.updateManagedBuildRevision(revision); - } - } - - public void setProjectType(IProjectType projectType) { - if ( this.projectType != projectType ) { - this.projectType = projectType; - if ( this.projectType == null) { - projectTypeId = null; - } else { - projectTypeId = this.projectType.getId(); - } - } - } -} +/******************************************************************************* + * Copyright (c) 2004, 2005 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.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.StorableEnvironment; +import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +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.IProgressMonitor; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class ManagedProject extends BuildObject implements IManagedProject { + + private static final String EMPTY_STRING = new String(); + private static final IConfiguration[] emptyConfigs = new IConfiguration[0]; + + // Parent and children + private IProjectType projectType; + private String projectTypeId; + private IResource owner; + private List configList; // Configurations of this project type + private Map configMap; + // Miscellaneous + private boolean isDirty = false; + private boolean isValid = true; + private boolean resolved = true; + //holds the user-defined macros + private StorableMacros userDefinedMacros; + //holds user-defined environment + private StorableEnvironment userDefinedEnvironment; + /* + * C O N S T R U C T O R S + */ + + /* (non-Javadoc) + * Sets the Eclipse project that owns the Managed Project + * + * @param owner + */ + protected ManagedProject(IResource owner) { + this.owner = owner; + } + + /** + * Create a project instance from the project-type specified in the argument, + * that is owned by the specified Eclipse project. + * + * @param owner the Eclipse project that owns the Managed Project + * @param projectType + */ + public ManagedProject(IResource owner, IProjectType projectType) { + // Make the owner of the ProjectType the project resource + this(owner); + + // Copy the parent's identity + this.projectType = projectType; + int id = ManagedBuildManager.getRandomNumber(); + setId(owner.getName() + "." + projectType.getId() + "." + id); //$NON-NLS-1$ //$NON-NLS-2$ + setName(projectType.getName()); + + setManagedBuildRevision(projectType.getManagedBuildRevision()); + + // Hook me up + IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(owner); + buildInfo.setManagedProject(this); + setDirty(true); + } + + /** + * Create the project instance from project file. + * + * @param buildInfo + * @param element + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public ManagedProject(ManagedBuildInfo buildInfo, Element element, String managedBuildRevision) { + this(buildInfo.getOwner()); + + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + if (loadFromProject(element)) { + + // check for migration support. + boolean isSupportAvailable = projectType.checkForMigrationSupport(); + if (isSupportAvailable == false) { + setValid(false); + } + + // Load children + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) { + Configuration config = new Configuration(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { + //load user-defined macros + userDefinedMacros = new StorableMacros((Element)configElement); + } + + } + } else { + setValid(false); + } + + // hook me up + buildInfo.setManagedProject(this); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Initialize the project information from the XML element + * specified in the argument + * + * @param element An XML element containing the project information + */ + protected boolean loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // projectType + projectTypeId = element.getAttribute(PROJECTTYPE); + if (projectTypeId != null && projectTypeId.length() > 0) { + projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); + if (projectType == null) { + return false; + } + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#serialize() + */ + public void serialize(Document doc, Element element) { + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + if (projectType != null) { + element.setAttribute(PROJECTTYPE, projectType.getId()); + } + + // Serialize my children + List configElements = getConfigurationList(); + Iterator iter = configElements.listIterator(); + while (iter.hasNext()) { + Configuration config = (Configuration) iter.next(); + Element configElement = doc.createElement(IConfiguration.CONFIGURATION_ELEMENT_NAME); + element.appendChild(configElement); + config.serialize(doc, configElement); + } + + //serialize user-defined macros + if(userDefinedMacros != null){ + Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); + element.appendChild(macrosElement); + userDefinedMacros.serialize(doc,macrosElement); + } + + if(userDefinedEnvironment != null){ + EnvironmentVariableProvider.fUserSupplier.storeEnvironment(this,true); + } + + // I am clean now + isDirty = false; + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getOwner() + */ + public IResource getOwner() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#updateOwner(org.eclipse.core.resources.IResource) + */ + public void updateOwner(IResource resource) { + if (!resource.equals(owner)) { + // Set the owner correctly + owner = resource; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getProjectType() + */ + public IProjectType getProjectType() { + return projectType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public IConfiguration createConfiguration(IConfiguration parent, String id) { + Configuration config = new Configuration(this, (Configuration)parent, id, false, false); + ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); + return (IConfiguration)config; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfigurationClone(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public IConfiguration createConfigurationClone(IConfiguration parent, String id) { + Configuration config = new Configuration(this, (Configuration)parent, id, true, false); + // Inform all options in the configuration and all its resource configurations + ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); + return (IConfiguration)config; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedProject#getConfiguration() + */ + public IConfiguration getConfiguration(String id) { + return (IConfiguration)getConfigurationMap().get(id); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getConfigurations() + */ + public IConfiguration[] getConfigurations() { + IConfiguration[] configs = new IConfiguration[getConfigurationList().size()]; + Iterator iter = getConfigurationList().listIterator(); + int i = 0; + while (iter.hasNext()) { + Configuration config = (Configuration)iter.next(); + configs[i++] = (IConfiguration)config; + } + return configs; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#removeConfiguration(java.lang.String) + */ + public void removeConfiguration(String id) { + final String removeId = id; + + //handle the case of temporary configuration + if(getConfigurationMap().get(id) == null) + return; + + IWorkspaceRunnable remover = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + // Remove the specified configuration from the list and map + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + IConfiguration config = (IConfiguration)iter.next(); + if (config.getId().equals(removeId)) { + // TODO: For now we clean the entire project. This may be overkill, but + // it avoids a problem with leaving the configuration output directory + // around and having the outputs try to be used by the makefile generator code. + IResource proj = config.getOwner(); + IManagedBuildInfo info = null; + if (proj instanceof IProject) { + info = ManagedBuildManager.getBuildInfo(proj); + } + IConfiguration currentConfig = null; + boolean isCurrent = true; + if (info != null) { + currentConfig = info.getDefaultConfiguration(); + if (!currentConfig.getId().equals(removeId)) { + info.setDefaultConfiguration(config); + isCurrent = false; + } + } + ((IProject)proj).build(IncrementalProjectBuilder.CLEAN_BUILD, monitor); + + ManagedBuildManager.performValueHandlerEvent(config, + IManagedOptionValueHandler.EVENT_CLOSE); + getConfigurationList().remove(config); + getConfigurationMap().remove(removeId); + + if (info != null) { + if (!isCurrent) { + info.setDefaultConfiguration(currentConfig); + } else { + // If the current default config is the one being removed, reset the default config + String[] configs = info.getConfigurationNames(); + if (configs.length > 0) { + info.setDefaultConfiguration(configs[0]); + } + } + } + break; + } + } + } + }; + try { + ResourcesPlugin.getWorkspace().run( remover, null ); + } + catch( CoreException e ) {} + setDirty(true); + } + + /* (non-Javadoc) + * Adds the Configuration to the Configuration list and map + * + * @param Tool + */ + public void addConfiguration(Configuration configuration) { + if(!configuration.isTemporary()){ + getConfigurationList().add(configuration); + getConfigurationMap().put(configuration.getId(), configuration); + } + } + + /* (non-Javadoc) + * Safe accessor for the list of configurations. + * + * @return List containing the configurations + */ + private List getConfigurationList() { + if (configList == null) { + configList = new ArrayList(); + } + return configList; + } + + /* (non-Javadoc) + * Safe accessor for the map of configuration ids to configurations + * + * @return + */ + public Map getConfigurationMap() { + if (configMap == null) { + configMap = new HashMap(); + } + return configMap; + } + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#(getDefaultArtifactName) + */ + public String getDefaultArtifactName(){ + String name = new String(); + // Check for spaces + String[] tokens = getOwner().getName().split("\\s"); //$NON-NLS-1$ + for (int index = 0; index < tokens.length; ++index) { + name += tokens[index]; + } + return name; + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references + */ + public boolean resolveReferences() { + if (!resolved) { + resolved = true; + // Resolve project-type + if (projectTypeId != null && projectTypeId.length() > 0) { + projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); + if (projectType == null) { + return false; + } + } + + // call resolve references on any children + Iterator configIter = getConfigurationList().iterator(); + while (configIter.hasNext()) { + Configuration current = (Configuration)configIter.next(); + current.resolveReferences(); + } + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isDirty() + */ + public boolean isDirty() { + // If I need saving, just say yes + if (isDirty) return true; + + //check whether the project - specific macros are dirty + if(userDefinedMacros != null && userDefinedMacros.isDirty()) + return true; + + //check whether the project - specific environment is dirty + if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) + return true; + + + // Otherwise see if any configurations need saving + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + Configuration current = (Configuration) iter.next(); + if (current.isDirty()) return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to the children + if (!isDirty) { + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + Configuration current = (Configuration) iter.next(); + current.setDirty(false); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isValid() + */ + public boolean isValid() { + // TODO: In the future, children could also have a "valid" state that should be checked + return isValid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setValid(boolean) + */ + public void setValid(boolean isValid) { + // TODO: In the future, children could also have a "valid" state... + this.isValid = isValid; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if (version == null) { + if ( getProjectType() != null) { + return getProjectType().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } + + /* + * this method is called by the UserDefinedMacroSupplier to obtain user-defined + * macros available for this managed project + */ + public StorableMacros getUserDefinedMacros(){ + if(userDefinedMacros == null) + userDefinedMacros = new StorableMacros(); + return userDefinedMacros; + } + + public StorableEnvironment getUserDefinedEnvironmet(){ + return userDefinedEnvironment; + } + + public void setUserDefinedEnvironmet(StorableEnvironment env){ + userDefinedEnvironment = env; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) + */ + public void updateManagedBuildRevision(String revision){ + super.updateManagedBuildRevision(revision); + for(Iterator iter = getConfigurationList().iterator(); iter.hasNext();){ + Configuration cfg = (Configuration)iter.next(); + cfg.updateManagedBuildRevision(revision); + } + } + + public void setProjectType(IProjectType projectType) { + if ( this.projectType != projectType ) { + this.projectType = projectType; + if ( this.projectType == null) { + projectTypeId = null; + } else { + projectTypeId = this.projectType.getId(); + } + } + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java index b64fb0af337..73b2e2e5679 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java @@ -1,1867 +1,1867 @@ -/******************************************************************************* - * Copyright (c) 2003, 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 - * ARM Ltd. - basic tooltip support - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class Option extends BuildObject implements IOption { - // Static default return values - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - - // Superclass - private IOption superClass; - private String superClassId; - // Parent and children - private IHoldsOptions holder; - // Managed Build model attributes - private String unusedChildren; - private Integer browseType; - private List builtIns; - private IOptionCategory category; - private String categoryId; - private String command; - private String commandFalse; - private String tip; - private List enumList; - private Map enumCommands; - private Map enumNames; - private Object value; - private Object defaultValue; - private Integer valueType; - private Boolean isAbstract; - private Integer resourceFilter; - private IConfigurationElement valueHandlerElement = null; - private IManagedOptionValueHandler valueHandler = null; - private String valueHandlerExtraArgument; - private IConfigurationElement applicabilityCalculatorElement = null; - private IOptionApplicability applicabilityCalculator = null; - private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null; - // Miscellaneous - private boolean isExtensionOption = false; - private boolean isDirty = false; - private boolean resolved = true; - private boolean verified = false; - private boolean isValid = true; /** False for options which are invalid. getOption() - * routines will ignore invalid options. */ - private boolean wasOptRef = false; /** True for options which are created because of an - * MBS 2.0 model OptionReference element - */ - private boolean isUdjusted = false; - - /* - * C O N S T R U C T O R S - */ - - /** - * This constructor is called to create an option defined by an extension point in - * a plugin manifest file, or returned by a dynamic element provider - * - * @param parent The IHoldsOptions parent of this option, or null if - * defined at the top level - * @param element The option definition from the manifest file or a dynamic element - * provider - */ - public Option(IHoldsOptions parent, IManagedConfigElement element) { - this.holder = parent; - isExtensionOption = true; - - // setup for resolving - resolved = false; - - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionOption(this); - } - - /** - * This constructor is called to create an Option whose attributes and children will be - * added by separate calls. - * - * @param IHoldsOptions The parent of the option, if any - * @param Option The superClass, if any - * @param String The id for the new option - * @param String The name for the new option - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public Option(IHoldsOptions parent, IOption superClass, String Id, String name, boolean isExtensionElement) { - this.holder = parent; - this.superClass = superClass; - if (this.superClass != null) { - superClassId = this.superClass.getId(); - } - setId(Id); - setName(name); - isExtensionOption = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionOption(this); - } else { - setDirty(true); - } - } - - /** - * Create an Option based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The IHoldsOptions the option will be added to. - * @param element The XML element that contains the option settings. - */ - public Option(IHoldsOptions parent, Element element) { - this.holder = parent; - isExtensionOption = false; - - // Initialize from the XML attributes - loadFromProject(element); - } - - /** - * Create an Option based upon an existing option. - * - * @param parent The IHoldsOptions the option will be added to. - * @param Id New ID for the option. - * @param name New name for the option. - * @param option The existing option to clone, except for the above fields. - */ - public Option(IHoldsOptions parent, String Id, String name, Option option){ - this.holder = parent; - superClass = option.superClass; - if (superClass != null) { - superClassId = option.superClass.getId(); - } - setId(Id); - setName(name); - isExtensionOption = false; - - // Copy the remaining attributes - if (option.unusedChildren != null) { - unusedChildren = new String(option.unusedChildren); - } - if (option.isAbstract != null) { - isAbstract = new Boolean(option.isAbstract.booleanValue()); - } - if (option.command != null) { - command = new String(option.command); - } - if (option.commandFalse != null) { - commandFalse = new String(option.commandFalse); - } - if (option.tip != null) { - tip = new String(option.tip); - } - if (option.categoryId != null) { - categoryId = new String(option.categoryId); - } - if (option.builtIns != null) { - builtIns = new ArrayList(option.builtIns); - } - if (option.browseType != null) { - browseType = new Integer(option.browseType.intValue()); - } - if (option.resourceFilter != null) { - resourceFilter = new Integer(option.resourceFilter.intValue()); - } - if (option.enumList != null) { - enumList = new ArrayList(option.enumList); - enumCommands = new HashMap(option.enumCommands); - enumNames = new HashMap(option.enumNames); - } - - if (option.valueType != null) { - valueType = new Integer(option.valueType.intValue()); - } - Integer vType = null; - try { - vType = new Integer(option.getValueType()); - if (vType != null) { - switch (vType.intValue()) { - case BOOLEAN: - if (option.value != null) { - value = new Boolean(((Boolean)option.value).booleanValue()); - } - if (option.defaultValue != null) { - defaultValue = new Boolean(((Boolean)option.defaultValue).booleanValue()); - } - break; - case STRING: - case ENUMERATED: - if (option.value != null) { - value = new String((String)option.value); - } - if (option.defaultValue != null) { - defaultValue = new String((String)option.defaultValue); - } - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - if (option.value != null) { - value = new ArrayList((ArrayList)option.value); - } - if (option.defaultValue != null) { - defaultValue = new ArrayList((ArrayList)option.defaultValue); - } - break; - } - } - } catch (BuildException be) { - // TODO: should we ignore this?? - } - - category = option.category; - applicabilityCalculatorElement = option.applicabilityCalculatorElement; - applicabilityCalculator = option.applicabilityCalculator; - - booleanExpressionCalculator = option.booleanExpressionCalculator; - - if (option.valueHandlerElement != null) { - valueHandlerElement = option.valueHandlerElement; - valueHandler = option.valueHandler; - } - if (option.valueHandlerExtraArgument != null) { - valueHandlerExtraArgument = new String(option.valueHandlerExtraArgument); - } - - if(!isExtensionElement()) - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Loads the option information from the ManagedConfigElement specified in the - * argument. - * - * @param element Contains the option information - */ - protected void loadFromManifest(IManagedConfigElement element) { - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // Get the name - setName(element.getAttribute(IBuildObject.NAME)); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // Get the unused children, if any - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - - // isAbstract - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - - // Get the command defined for the option - command = element.getAttribute(COMMAND); - - // Get the command defined for a Boolean option when the value is False - commandFalse = element.getAttribute(COMMAND_FALSE); - - // Get the tooltip for the option - tip = element.getAttribute(TOOL_TIP); - - // Options hold different types of values - String valueTypeStr = element.getAttribute(VALUE_TYPE); - if (valueTypeStr != null) { - valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); - } - - // Note: The value and defaultValue attributes are loaded in the resolveReferences routine. - // This is because we need to have the value-type, and this may be defined in a - // superClass that is not yet loaded. - - // Determine if there needs to be a browse button - String browseTypeStr = element.getAttribute(BROWSE_TYPE); - if (browseTypeStr == null) { - // Set to null, to indicate no browse type specification - // This will allow any superclasses to be searched for the - // browse type specification, and thus inherited, if found, - // which they should be - browseType = null; - } else if (browseTypeStr.equals(NONE)) { - browseType = new Integer(BROWSE_NONE); - } else if (browseTypeStr.equals(FILE)) { - browseType = new Integer(BROWSE_FILE); - } else if (browseTypeStr.equals(DIR)) { - browseType = new Integer(BROWSE_DIR); - } - - categoryId = element.getAttribute(CATEGORY); - - // Get the resourceFilter attribute - String resFilterStr = element.getAttribute(RESOURCE_FILTER); - if (resFilterStr == null) { - // Set to null, to indicate no resource filter specification - // This will allow any superclasses to be searched for the - // resource filter specification, and thus inherited, if found, - // which they should be - resourceFilter = null; - } else if (resFilterStr.equals(ALL)) { - resourceFilter = new Integer(FILTER_ALL); - } else if (resFilterStr.equals(FILE)) { - resourceFilter = new Integer(FILTER_FILE); - } else if (resFilterStr.equals(PROJECT)) { - resourceFilter = new Integer(FILTER_PROJECT); - } - - //get enablements - IManagedConfigElement enablements[] = element.getChildren(OptionEnablementExpression.NAME); - if(enablements.length > 0) - booleanExpressionCalculator = new BooleanExpressionApplicabilityCalculator(enablements); - - // get the applicability calculator, if any - String applicabilityCalculatorStr = element.getAttribute(APPLICABILITY_CALCULATOR); - if (applicabilityCalculatorStr != null && element instanceof DefaultManagedConfigElement) { - applicabilityCalculatorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } else { - applicabilityCalculator = booleanExpressionCalculator; - } - - // valueHandler - // Store the configuration element IFF there is a value handler defined - String valueHandler = element.getAttribute(VALUE_HANDLER); - if (valueHandler != null && element instanceof DefaultManagedConfigElement) { - valueHandlerElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - // valueHandlerExtraArgument - valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); - } - - /* (non-Javadoc) - * Initialize the option information from the XML element - * specified in the argument - * - * @param element An XML element containing the option information - */ - protected void loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - superClass = ManagedBuildManager.getExtensionOption(superClassId); - if (superClass == null) { - // TODO: Report error - } - } - - // Get the unused children, if any - if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - } - - // isAbstract - if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - } - - // Get the command defined for the option - if (element.hasAttribute(COMMAND)) { - command = element.getAttribute(COMMAND); - } - - // Get the command defined for a Boolean option when the value is False - if (element.hasAttribute(COMMAND_FALSE)) { - commandFalse = element.getAttribute(COMMAND_FALSE); - } - - // Get the tooltip for the option - if (element.hasAttribute(TOOL_TIP)) { - tip = element.getAttribute(TOOL_TIP); - } - - // Options hold different types of values - if (element.hasAttribute(VALUE_TYPE)) { - String valueTypeStr = element.getAttribute(VALUE_TYPE); - valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); - } - - // Now get the actual value based upon value-type - try { - int valType = getValueType(); - switch (valType) { - case BOOLEAN: - // Convert the string to a boolean - if (element.hasAttribute(VALUE)) { - value = new Boolean(element.getAttribute(VALUE)); - } - if (element.hasAttribute(DEFAULT_VALUE)) { - defaultValue = new Boolean(element.getAttribute(DEFAULT_VALUE)); - } - break; - case STRING: - // Just get the value out of the option directly - if (element.hasAttribute(VALUE)) { - value = element.getAttribute(VALUE); - } - if (element.hasAttribute(DEFAULT_VALUE)) { - defaultValue = element.getAttribute(DEFAULT_VALUE); - } - break; - case ENUMERATED: - if (element.hasAttribute(VALUE)) { - value = element.getAttribute(VALUE); - } - if (element.hasAttribute(DEFAULT_VALUE)) { - defaultValue = element.getAttribute(DEFAULT_VALUE); - } - - // Do we have enumeratedOptionValue children? If so, load them - // to define the valid values and the default value. - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configNode = configElements.item(i); - if (configNode.getNodeName().equals(ENUM_VALUE)) { - Element configElement = (Element)configNode; - String optId = configElement.getAttribute(ID); - if (i == 0) { - enumList = new ArrayList(); - if (defaultValue == null) { - defaultValue = optId; // Default value to be overridden is default is specified - } - } - enumList.add(optId); - if (configElement.hasAttribute(COMMAND)) { - getEnumCommandMap().put(optId, configElement.getAttribute(COMMAND)); - } else { - getEnumCommandMap().put(optId, EMPTY_STRING); - } - getEnumNameMap().put(optId, configElement.getAttribute(NAME)); - if (configElement.hasAttribute(IS_DEFAULT)) { - Boolean isDefault = new Boolean(configElement.getAttribute(IS_DEFAULT)); - if (isDefault.booleanValue()) { - defaultValue = optId; - } - } - } - } - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - // Note: These string-list options do not load either the "value" or - // "defaultValue" attributes. Instead, the ListOptionValue children - // are loaded in the value field. - List valueList = null; - configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - if (i == 0) { - valueList = new ArrayList(); - builtIns = new ArrayList(); - } - Node configNode = configElements.item(i); - if (configNode.getNodeName().equals(LIST_VALUE)) { - Element valueElement = (Element)configNode; - Boolean isBuiltIn; - if (valueElement.hasAttribute(IS_DEFAULT)) { - isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); - } else { - isBuiltIn = new Boolean(false); - } - if (isBuiltIn.booleanValue()) { - builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - else { - valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - } - } - value = valueList; - break; - default : - break; - } - } catch (BuildException e) { - // TODO: report error - } - - // Determine if there needs to be a browse button - if (element.hasAttribute(BROWSE_TYPE)) { - String browseTypeStr = element.getAttribute(BROWSE_TYPE); - - if (browseTypeStr == null) { - // Set to null, to indicate no browse type specification - // This will allow any superclasses to be searched for the - // browse type specification, and thus inherited, if found, - // which they should be - browseType = null; - } else if (browseTypeStr.equals(NONE)) { - browseType = new Integer(BROWSE_NONE); - } else if (browseTypeStr.equals(FILE)) { - browseType = new Integer(BROWSE_FILE); - } else if (browseTypeStr.equals(DIR)) { - browseType = new Integer(BROWSE_DIR); - } - } - - if (element.hasAttribute(CATEGORY)) { - categoryId = element.getAttribute(CATEGORY); - if (categoryId != null) { - category = holder.getOptionCategory(categoryId); - } - } - - // Get the resourceFilter attribute - if (element.hasAttribute(RESOURCE_FILTER)) { - String resFilterStr = element.getAttribute(RESOURCE_FILTER); - if (resFilterStr == null) { - // Set to null, to indicate no resource filter specification - // This will allow any superclasses to be searched for the - // resource filter specification, and thus inherited, if found, - // which they should be - resourceFilter = null; - } else if (resFilterStr.equals(ALL)) { - resourceFilter = new Integer(FILTER_ALL); - } else if (resFilterStr.equals(FILE)) { - resourceFilter = new Integer(FILTER_FILE); - } else if (resFilterStr.equals(PROJECT)) { - resourceFilter = new Integer(FILTER_PROJECT); - } - } - - // Note: valueHandlerElement and VALUE_HANDLER are not restored, - // as they are not saved. See note in serialize(). - - // valueHandlerExtraArgument - if (element.hasAttribute(VALUE_HANDLER_EXTRA_ARGUMENT)) { - valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); - } - } - - private int ValueTypeStrToInt(String valueTypeStr) { - if (valueTypeStr == null) return -1; - if (valueTypeStr.equals(TYPE_STRING)) - return STRING; - else if (valueTypeStr.equals(TYPE_STR_LIST)) - return STRING_LIST; - else if (valueTypeStr.equals(TYPE_BOOL)) - return BOOLEAN; - else if (valueTypeStr.equals(TYPE_ENUM)) - return ENUMERATED; - else if (valueTypeStr.equals(TYPE_INC_PATH)) - return INCLUDE_PATH; - else if (valueTypeStr.equals(TYPE_LIB)) - return LIBRARIES; - else if (valueTypeStr.equals(TYPE_USER_OBJS)) - return OBJECTS; - else if (valueTypeStr.equals(TYPE_DEFINED_SYMBOLS)) - return PREPROCESSOR_SYMBOLS; - else { - // TODO: This was the CDT 2.0 default - should we keep it? - return PREPROCESSOR_SYMBOLS; - } - } - - /** - * Persist the option to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) throws BuildException { - if (superClass != null) - element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); - - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - if (unusedChildren != null) { - element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); - } - - if (isAbstract != null) { - element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); - } - - if (command != null) { - element.setAttribute(COMMAND, command); - } - - if (commandFalse != null) { - element.setAttribute(COMMAND_FALSE, commandFalse); - } - - if (tip != null) { - element.setAttribute(TOOL_TIP, tip); - } - - /* - * Note: We store value & value-type as a pair, so we know what type of value we are - * dealing with when we read it back in. - * This is also true of defaultValue. - */ - boolean storeValueType = false; - - // value - if (value != null) { - storeValueType = true; - switch (getValueType()) { - case BOOLEAN: - element.setAttribute(VALUE, ((Boolean)value).toString()); - break; - case STRING: - case ENUMERATED: - element.setAttribute(VALUE, (String)value); - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - if (value != null) { - ArrayList stringList = (ArrayList)value; - ListIterator iter = stringList.listIterator(); - while (iter.hasNext()) { - Element valueElement = doc.createElement(LIST_VALUE); - valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); - valueElement.setAttribute(LIST_ITEM_BUILTIN, "false"); //$NON-NLS-1$ - element.appendChild(valueElement); - } - } - // Serialize the built-ins that have been overridden - if (builtIns != null) { - ListIterator iter = builtIns.listIterator(); - while (iter.hasNext()) { - Element valueElement = doc.createElement(LIST_VALUE); - valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); - valueElement.setAttribute(LIST_ITEM_BUILTIN, "true"); //$NON-NLS-1$ - element.appendChild(valueElement); - } - } - break; - } - } - - // defaultValue - if (defaultValue != null) { - storeValueType = true; - switch (getValueType()) { - case BOOLEAN: - element.setAttribute(DEFAULT_VALUE, ((Boolean)defaultValue).toString()); - break; - case STRING: - case ENUMERATED: - element.setAttribute(DEFAULT_VALUE, (String)defaultValue); - break; - default: - break; - } - } - - if (storeValueType) { - String str; - switch (getValueType()) { - case BOOLEAN: - str = TYPE_BOOL; - break; - case STRING: - str = TYPE_STRING; - break; - case ENUMERATED: - str = TYPE_ENUM; - break; - case STRING_LIST: - str = TYPE_STR_LIST; - break; - case INCLUDE_PATH: - str = TYPE_INC_PATH; - break; - case LIBRARIES: - str = TYPE_LIB; - break; - case OBJECTS: - str = TYPE_USER_OBJS; - break; - case PREPROCESSOR_SYMBOLS: - str = TYPE_DEFINED_SYMBOLS; - break; - default: - // TODO; is this a problem... - str = EMPTY_STRING; - break; - } - element.setAttribute(VALUE_TYPE, str); - } - - // browse type - if (browseType != null) { - String str; - switch (getBrowseType()) { - case BROWSE_NONE: - str = NONE; - break; - case BROWSE_FILE: - str = FILE; - break; - case BROWSE_DIR: - str = DIR; - break; - default: - str = EMPTY_STRING; - break; - } - element.setAttribute(BROWSE_TYPE, str); - } - - if (categoryId != null) { - element.setAttribute(CATEGORY, categoryId); - } - - // resource filter - if (resourceFilter != null) { - String str; - switch (getResourceFilter()) { - case FILTER_ALL: - str = ALL; - break; - case FILTER_FILE: - str = FILE; - break; - case FILTER_PROJECT: - str = PROJECT; - break; - default: - str = EMPTY_STRING; - break; - } - element.setAttribute(RESOURCE_FILTER, str); - } - - // Note: applicability calculator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (applicabilityCalculatorElement != null) { - // TODO: issue warning? - } - - // Note: a value handler cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (valueHandlerElement != null) { - // TODO: Issue warning? Stuck with behavior of this elsewhere in - // CDT, e.g. the implementation of Tool - } - if (valueHandlerExtraArgument != null) { - element.setAttribute(VALUE_HANDLER_EXTRA_ARGUMENT, valueHandlerExtraArgument); - } - - // I am clean now - isDirty = false; - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getParent() - */ - public IBuildObject getParent() { - return holder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getOptionHolder() - */ - public IHoldsOptions getOptionHolder() { - // Do not take superclasses into account - return holder; - } - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getSuperClass() - */ - public IOption getSuperClass() { - return superClass; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getName() - */ - public String getName() { - return (name == null && superClass != null) ? superClass.getName() : name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicableValues() - */ - public String[] getApplicableValues() { - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getApplicableValues(); - } else { - return EMPTY_STRING_ARRAY; - } - } - // Get all of the enumerated names from the option - if (enumList.size() == 0) { - return EMPTY_STRING_ARRAY; - } else { - // Return the elements in the order they are specified in the manifest - String[] enumNames = new String[enumList.size()]; - for (int index = 0; index < enumList.size(); ++ index) { - enumNames[index] = (String) getEnumNameMap().get(enumList.get(index)); - } - return enumNames; - } - } - - public boolean getBooleanValue() { - return ((Boolean)getValue()).booleanValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getBrowseType() - */ - public int getBrowseType() { - if (browseType == null) { - if (superClass != null) { - return superClass.getBrowseType(); - } else { - return BROWSE_NONE; - } - } - return browseType.intValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getResourceFilter() - */ - public int getResourceFilter() { - if (resourceFilter == null) { - if (superClass != null) { - return superClass.getResourceFilter(); - } else { - return FILTER_ALL; - } - } - return resourceFilter.intValue(); - } - - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculatorElement() - */ - public IConfigurationElement getApplicabilityCalculatorElement() { -/* if (applicabilityCalculatorElement == null) { - if (superClass != null) { - return ((Option)superClass).getApplicabilityCalculatorElement(); - } - } -*/ - return applicabilityCalculatorElement; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculator() - */ - public IOptionApplicability getApplicabilityCalculator() { - if (applicabilityCalculator == null) { - if (applicabilityCalculatorElement != null) { - try { - if (applicabilityCalculatorElement.getAttribute(APPLICABILITY_CALCULATOR) != null) - applicabilityCalculator = (IOptionApplicability) applicabilityCalculatorElement - .createExecutableExtension(APPLICABILITY_CALCULATOR); - } catch (CoreException e) { - } - } - else if(superClass != null) - applicabilityCalculator = superClass.getApplicabilityCalculator(); - } - - return applicabilityCalculator; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getBuiltIns() - */ - public String[] getBuiltIns() { - // Return the list of built-ins as an array - if (builtIns == null) { - if (superClass != null) { - return superClass.getBuiltIns(); - } else { - return EMPTY_STRING_ARRAY; - } - } - return (String[])builtIns.toArray(new String[builtIns.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getCategory() - */ - public IOptionCategory getCategory() { - if (category == null) { - if (superClass != null) { - return superClass.getCategory(); - } else { - if (getOptionHolder() instanceof ITool) { - return ((ITool)getOptionHolder()).getTopOptionCategory(); - } else { - return null; - } - } - } - return category; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommand() - */ - public String getCommand() { - if (command == null) { - if (superClass != null) { - return superClass.getCommand(); - } else { - return EMPTY_STRING; - } - } - return command; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommandFalse() - */ - public String getCommandFalse() { - if (commandFalse == null) { - if (superClass != null) { - return superClass.getCommandFalse(); - } else { - return EMPTY_STRING; - } - } - return commandFalse; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getToolTip() - */ - public String getToolTip() { - if (tip == null) { - if (superClass != null) { - return superClass.getToolTip(); - } else { - return EMPTY_STRING; - } - } - return tip; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefinedSymbols() - */ - public String[] getDefinedSymbols() throws BuildException { - if (getValueType() != PREPROCESSOR_SYMBOLS) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String) - */ - public String getEnumCommand(String id) throws BuildException { - // Sanity - if (id == null) return EMPTY_STRING; - - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getEnumCommand(id); - } else { - return EMPTY_STRING; - } - } - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - - // First check for the command in ID->command map - String cmd = (String) getEnumCommandMap().get(id); - if (cmd == null) { - // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable - // name of the enumeration. Search for the ID that maps to the name and use that to find the - // command. - ListIterator iter = enumList.listIterator(); - while (iter.hasNext()) { - String realID = (String) iter.next(); - String name = (String) getEnumNameMap().get(realID); - if (id.equals(name)) { - cmd = (String) getEnumCommandMap().get(realID); - break; - } - } - } - return cmd == null ? EMPTY_STRING : cmd; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumName(java.lang.String) - */ - public String getEnumName(String id) throws BuildException { - // Sanity - if (id == null) return EMPTY_STRING; - - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getEnumName(id); - } else { - return EMPTY_STRING; - } - } - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - - // First check for the command in ID->name map - String name = (String) getEnumNameMap().get(id); - if (name == null) { - // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable - // name of the enumeration. - name = id; - } - return name; - } - - /* (non-Javadoc) - * A memory-safe accessor to the map of enumerated option value IDs to the commands - * that a tool understands. - * - * @return a Map of enumerated option value IDs to actual commands that are passed - * to a tool on the command line. - */ - private Map getEnumCommandMap() { - if (enumCommands == null) { - enumCommands = new HashMap(); - } - return enumCommands; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumeratedId(java.lang.String) - */ - public String getEnumeratedId(String name) throws BuildException { - if (name == null) return null; - - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getEnumeratedId(name); - } else { - return EMPTY_STRING; - } - } - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - - Set idSet = getEnumNameMap().keySet(); - Iterator iter = idSet.iterator(); - while (iter.hasNext()) { - String id = (String) iter.next(); - String enumName = (String) getEnumNameMap().get(id); - if (name.equals(enumName)) { - return id; - } - } - return null; - } - - /* (non-Javadoc) - * - * @return a Map of enumerated option value IDs to the selection displayed to the user. - */ - private Map getEnumNameMap() { - if (enumNames == null) { - enumNames = new HashMap(); - } - return enumNames; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getIncludePaths() - */ - public String[] getIncludePaths() throws BuildException { - if (getValueType() != INCLUDE_PATH) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getLibraries() - */ - public String[] getLibraries() throws BuildException { - if (getValueType() != LIBRARIES) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefaultEnumValue() - */ - public String getSelectedEnum() throws BuildException { - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - return getStringValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringListValue() - */ - public String[] getStringListValue() throws BuildException { - if (getValueType() != STRING_LIST) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringValue() - */ - public String getStringValue() throws BuildException { - if (getValueType() != STRING && getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - return getValue() == null ? EMPTY_STRING : (String)getValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getUserObjects() - */ - public String[] getUserObjects() throws BuildException { - if (getValueType() != OBJECTS) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - // This is the right puppy, so return its list value - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueType() - */ - public int getValueType() throws BuildException { - if (valueType == null) { - if (superClass != null) { - return superClass.getValueType(); - } else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$; - } - } - return valueType.intValue(); - } - - /* (non-Javadoc) - * Gets the value, applying appropriate defaults if necessary. - */ - public Object getValue() { - /* - * In order to determine the current value of an option, perform the following steps until a value is found: - * 1. Examine the value attribute of the option. - * 2. Examine the value attribute of the option’s superClass recursively. - * 3. Examine the dynamicDefaultValue attribute of the option and invoke it if specified. (not yet implemented) - * 4. Examine the defaultValue attribute of the option. - * 5. Examine the dynamicDefaultValue attribute of the option’s superClass and invoke it if specified. (not yet implemented) - * 6. Examine the defaultValue attribute of the option’s superClass. - * 7. Go to step 5 recursively until no more super classes. - * 8. Use the default value for the option type. - */ - - Object val = getRawValue(); - if (val == null) { - val = getDefaultValue(); - if (val == null) { - int valType; - try { - valType = getValueType(); - } catch (BuildException e) { - return EMPTY_STRING; - } - switch (valType) { - case BOOLEAN: - val = new Boolean(false); - break; - case STRING: - val = EMPTY_STRING; - break; - case ENUMERATED: - // TODO: Can we default to the first enumerated id? - val = EMPTY_STRING; - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - val = new ArrayList(); - break; - default: - val = EMPTY_STRING; - break; - } - } - } - return val; - } - - /* (non-Javadoc) - * Gets the raw value, applying appropriate defauls if necessary. - */ - public Object getRawValue() { - if (value == null) { - if (superClass != null) { - Option mySuperClass = (Option)superClass; - return mySuperClass.getRawValue(); - } - } - return value; - } - - /* (non-Javadoc) - * Gets the raw default value. - */ - public Object getDefaultValue() { - // Note: string-list options do not have a default value - if (defaultValue == null) { - if (superClass != null) { - return superClass.getDefaultValue(); - } - } - return defaultValue; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) - */ - public void setDefaultValue(Object v) { - defaultValue = v; - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setCategory(org.eclipse.cdt.managedbuilder.core.IOptionCategory) - */ - public void setCategory(IOptionCategory category) { - if (this.category != category) { - this.category = category; - if (category != null) { - categoryId = category.getId(); - } else { - categoryId = null; - } - if(!isExtensionElement()) - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommand(String) - */ - public void setCommand(String cmd) { - if (cmd == null && command == null) return; - if (cmd == null || command == null || !cmd.equals(command)) { - command = cmd; - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommandFalse(String) - */ - public void setCommandFalse(String cmd) { - if (cmd == null && commandFalse == null) return; - if (cmd == null || commandFalse == null || !cmd.equals(commandFalse)) { - commandFalse = cmd; - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setToolTip(String) - */ - public void setToolTip(String tooltip) { - if (tooltip == null && tip == null) return; - if (tooltip == null || tip == null || !tooltip.equals(tip)) { - tip = tooltip; - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setResourceFilter(int) - */ - public void setResourceFilter(int filter) { - if (resourceFilter == null || !(filter == resourceFilter.intValue())) { - resourceFilter = new Integer(filter); - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setBrowseType(int) - */ - public void setBrowseType(int type) { - if (browseType == null || !(type == browseType.intValue())) { - browseType = new Integer(type); - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(boolean) - */ - public void setValue(boolean value) throws BuildException { - if (/*!isExtensionElement() && */getValueType() == BOOLEAN){ - this.value = new Boolean(value); - } else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - if(!isExtensionElement()) - setDirty(true); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String) - */ - public void setValue(String value) throws BuildException { - // Note that we can still set the human-readable value here - if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED)) { - this.value = value; - } else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - if(!isExtensionElement()) - setDirty(true); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String []) - */ - public void setValue(String [] value) throws BuildException { - if (/*!isExtensionElement() && */ - (getValueType() == STRING_LIST - || getValueType() == INCLUDE_PATH - || getValueType() == PREPROCESSOR_SYMBOLS - || getValueType() == LIBRARIES - || getValueType() == OBJECTS)) { - // Just replace what the option reference is holding onto - if(value == null) - this.value = null; - else - this.value = new ArrayList(Arrays.asList(value)); - } - else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) - */ - public void setValue(Object v) { - value = v; - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueType() - */ - public void setValueType(int type) { - // TODO: Verify that this is a valid type - if (valueType == null || valueType.intValue() != type) { - valueType = new Integer(type); - if(!isExtensionElement()) - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerElement() - */ - public IConfigurationElement getValueHandlerElement() { - if (valueHandlerElement == null) { - if (superClass != null) { - return ((Option)superClass).getValueHandlerElement(); - } - } - return valueHandlerElement; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerElement(IConfigurationElement) - */ - public void setValueHandlerElement(IConfigurationElement element) { - valueHandlerElement = element; - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandler() - */ - public IManagedOptionValueHandler getValueHandler() { - if (valueHandler != null) { - return valueHandler; - } - IConfigurationElement element = getValueHandlerElement(); - if (element != null) { - try { - if (element.getAttribute(VALUE_HANDLER) != null) { - valueHandler = (IManagedOptionValueHandler) element.createExecutableExtension(VALUE_HANDLER); - return valueHandler; - } - } catch (CoreException e) { - ManagedBuildManager.OptionValueHandlerError(element.getAttribute(VALUE_HANDLER), getId()); - // Assign the default handler to avoid further error messages - valueHandler = ManagedOptionValueHandler.getManagedOptionValueHandler(); - return valueHandler; - } - } - // If no handler is provided, then use the default handler - return ManagedOptionValueHandler.getManagedOptionValueHandler(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerExtraArgument()) - */ - public String getValueHandlerExtraArgument() { - if (valueHandlerExtraArgument == null) { - if (superClass != null) { - return superClass.getValueHandlerExtraArgument(); - } else { - return EMPTY_STRING; - } - } - return valueHandlerExtraArgument; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerExtraArgument(String)) - */ - public void setValueHandlerExtraArgument(String extraArgument) { - if (extraArgument == null && valueHandlerExtraArgument == null) return; - if (extraArgument == null || - valueHandlerExtraArgument == null || - !extraArgument.equals(valueHandlerExtraArgument)) { - valueHandlerExtraArgument = extraArgument; - if(!isExtensionElement()) - isDirty = true; - } - } - - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#isExtensionElement() - */ - public boolean isExtensionElement() { - return isExtensionOption; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#overridesOnlyValue() - * Deprecated since 3.0.1 - */ - public boolean overridesOnlyValue() { - if (superClass != null && - unusedChildren == null && - browseType == null && - (builtIns == null || builtIns.size() == 0) && - category == null && - categoryId == null && - command == null && - commandFalse == null && - tip == null && - enumList == null && - enumCommands == null && - enumNames == null && - defaultValue == null) { - return true; - } else { - return false; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#isDirty() - */ - public boolean isDirty() { - // This shouldn't be called for an extension option - if (isExtensionOption) return false; - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - } - - public void resolveReferences() { - - if (!resolved) { - resolved = true; - // Resolve superClass - if (superClassId != null && superClassId.length() > 0) { - superClass = ManagedBuildManager.getExtensionOption(superClassId); - if (superClass == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "option", //$NON-NLS-1$ - getId()); - } else { - // All of our superclasses must be resolved in order to call - // getValueType below. - ((Option)superClass).resolveReferences(); - } - } - if (categoryId != null) { - category = holder.getOptionCategory(categoryId); - if (category == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "category", //$NON-NLS-1$ - categoryId, - "option", //$NON-NLS-1$ - getId()); - } - } - // Process the value and default value attributes. This is delayed until now - // because we may not know the valueType until after we have resolved the superClass above - // Now get the actual value - try { - IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); - switch (getValueType()) { - case BOOLEAN: - // Convert the string to a boolean - String val = element.getAttribute(VALUE); - if (val != null) { - value = new Boolean(val); - } - val = element.getAttribute(DEFAULT_VALUE); - if (val != null) { - defaultValue = new Boolean(val); - } - break; - case STRING: - // Just get the value out of the option directly - value = element.getAttribute(VALUE); - defaultValue = element.getAttribute(DEFAULT_VALUE); - break; - case ENUMERATED: - value = element.getAttribute(VALUE); - defaultValue = element.getAttribute(DEFAULT_VALUE); - - // Do we have enumeratedOptionValue children? If so, load them - // to define the valid values and the default value. - IManagedConfigElement[] enumElements = element.getChildren(ENUM_VALUE); - for (int i = 0; i < enumElements.length; ++i) { - String optId = enumElements[i].getAttribute(ID); - if (i == 0) { - enumList = new ArrayList(); - if (defaultValue == null) { - defaultValue = optId; // Default value to be overridden if default is specified - } - } - enumList.add(optId); - getEnumCommandMap().put(optId, enumElements[i].getAttribute(COMMAND)); - getEnumNameMap().put(optId, enumElements[i].getAttribute(NAME)); - Boolean isDefault = new Boolean(enumElements[i].getAttribute(IS_DEFAULT)); - if (isDefault.booleanValue()) { - defaultValue = optId; - } - } - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - // Note: These string-list options do not load either the "value" or - // "defaultValue" attributes. Instead, the ListOptionValue children - // are loaded in the value field. - List valueList = null; - IManagedConfigElement[] valueElements = element.getChildren(LIST_VALUE); - for (int i = 0; i < valueElements.length; ++i) { - if (i == 0) { - valueList = new ArrayList(); - builtIns = new ArrayList(); - } - IManagedConfigElement valueElement = valueElements[i]; - Boolean isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); - if (isBuiltIn.booleanValue()) { - builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - else { - valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - } - value = valueList; - break; - default : - break; - } - } catch (BuildException e) { - // TODO: report error - } - } - } - - /** - * @return Returns the managedBuildRevision. - */ - public String getManagedBuildRevision() { - if ( managedBuildRevision == null) { - if ( getParent() != null) { - return getParent().getManagedBuildRevision(); - } - } - return managedBuildRevision; - } - - /* (non-Javadoc) - * For now implement this method just as a utility to make code - * within the Option class cleaner. - * TODO: In future we may want to move this to IOption - */ - protected boolean isAbstract() { - if (isAbstract != null) { - return isAbstract.booleanValue(); - } else { - return false; // Note: no inheritance from superClass - } - } - - /** - * Verifies whether the option is valid and handles - * any errors for the option. The following errors - * can occur: - * (a) Options that are children of a ToolChain must - * ALWAYS have a category - * (b) Options that are children of a ToolChain must - * NEVER have a resourceFilter of "file". - * If an error occurs, the option is set to being invalid. - * - * @pre All references have been resolved. - */ - private void verify() { - if (verified) return; - verified = true; - // Ignore elements that are superclasses - if ( getOptionHolder() instanceof IToolChain && isAbstract() == false ) { - // Check for error (a) - if (getCategory() == null) { - ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_CATEGORY, getId()); - // Object becomes invalid - isValid = false; - } - // Check for error (b). Not specifying an attribute is OK. - // Do not use getResourceFilter as it does not allow - // differentiating between "all" and no attribute specified. - if ( resourceFilter != null ) - { - switch (getResourceFilter()) { - case Option.FILTER_FILE: - // TODO: Cannot differentiate between "all" and attribute not - // specified. Thus do not produce an error. We can argue that "all" - // means all valid resource configurations. - ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_FILTER, getId()); - // Object becomes invalid - isValid = false; - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#isValid() - */ - public boolean isValid() { - // We use a lazy scheme to check whether the option is valid. - // Note that by default an option is valid. verify() is only called if - // the option has been resolved. This gets us around having to deal with - // ordering problems during a resolve, or introducing another global - // stage to verify the configuration after a resolve. - // The trade-off is that errors in the MBS grammar may not be - // detected on load, but only when a particular grammar element - // is used, say in the GUI. - if (verified == false && resolved == true) { - verify(); - } - return isValid; - } - - /** - * @return Returns true if this Option was created from an MBS 2.0 model - * OptionReference element. - */ - public boolean wasOptRef() { - return wasOptRef; - } - - public void setWasOptRef(boolean was) { - wasOptRef = was; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if ( version == null) { - if ( getParent() != null) { - return getParent().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } - - public BooleanExpressionApplicabilityCalculator getBooleanExpressionCalculator(){ - return booleanExpressionCalculator; - } - - public boolean isAdjustedExtension(){ - return isUdjusted; - } - - public void setAdjusted(boolean adjusted) { - isUdjusted = adjusted; - } - - public void setSuperClass(IOption superClass) { - if ( this.superClass != superClass ) { - this.superClass = superClass; - if ( this.superClass == null) { - superClassId = null; - } else { - superClassId = this.superClass.getId(); - } - - if(!isExtensionElement()) - setDirty(true); - } - } - -} +/******************************************************************************* + * Copyright (c) 2003, 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 + * ARM Ltd. - basic tooltip support + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; +import org.eclipse.cdt.managedbuilder.core.IOptionCategory; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class Option extends BuildObject implements IOption { + // Static default return values + private static final String EMPTY_STRING = new String(); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + // Superclass + private IOption superClass; + private String superClassId; + // Parent and children + private IHoldsOptions holder; + // Managed Build model attributes + private String unusedChildren; + private Integer browseType; + private List builtIns; + private IOptionCategory category; + private String categoryId; + private String command; + private String commandFalse; + private String tip; + private List enumList; + private Map enumCommands; + private Map enumNames; + private Object value; + private Object defaultValue; + private Integer valueType; + private Boolean isAbstract; + private Integer resourceFilter; + private IConfigurationElement valueHandlerElement = null; + private IManagedOptionValueHandler valueHandler = null; + private String valueHandlerExtraArgument; + private IConfigurationElement applicabilityCalculatorElement = null; + private IOptionApplicability applicabilityCalculator = null; + private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null; + // Miscellaneous + private boolean isExtensionOption = false; + private boolean isDirty = false; + private boolean resolved = true; + private boolean verified = false; + private boolean isValid = true; /** False for options which are invalid. getOption() + * routines will ignore invalid options. */ + private boolean wasOptRef = false; /** True for options which are created because of an + * MBS 2.0 model OptionReference element + */ + private boolean isUdjusted = false; + + /* + * C O N S T R U C T O R S + */ + + /** + * This constructor is called to create an option defined by an extension point in + * a plugin manifest file, or returned by a dynamic element provider + * + * @param parent The IHoldsOptions parent of this option, or null if + * defined at the top level + * @param element The option definition from the manifest file or a dynamic element + * provider + */ + public Option(IHoldsOptions parent, IManagedConfigElement element) { + this.holder = parent; + isExtensionOption = true; + + // setup for resolving + resolved = false; + + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionOption(this); + } + + /** + * This constructor is called to create an Option whose attributes and children will be + * added by separate calls. + * + * @param IHoldsOptions The parent of the option, if any + * @param Option The superClass, if any + * @param String The id for the new option + * @param String The name for the new option + * @param boolean Indicates whether this is an extension element or a managed project element + */ + public Option(IHoldsOptions parent, IOption superClass, String Id, String name, boolean isExtensionElement) { + this.holder = parent; + this.superClass = superClass; + if (this.superClass != null) { + superClassId = this.superClass.getId(); + } + setId(Id); + setName(name); + isExtensionOption = isExtensionElement; + if (isExtensionElement) { + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionOption(this); + } else { + setDirty(true); + } + } + + /** + * Create an Option based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The IHoldsOptions the option will be added to. + * @param element The XML element that contains the option settings. + */ + public Option(IHoldsOptions parent, Element element) { + this.holder = parent; + isExtensionOption = false; + + // Initialize from the XML attributes + loadFromProject(element); + } + + /** + * Create an Option based upon an existing option. + * + * @param parent The IHoldsOptions the option will be added to. + * @param Id New ID for the option. + * @param name New name for the option. + * @param option The existing option to clone, except for the above fields. + */ + public Option(IHoldsOptions parent, String Id, String name, Option option){ + this.holder = parent; + superClass = option.superClass; + if (superClass != null) { + superClassId = option.superClass.getId(); + } + setId(Id); + setName(name); + isExtensionOption = false; + + // Copy the remaining attributes + if (option.unusedChildren != null) { + unusedChildren = new String(option.unusedChildren); + } + if (option.isAbstract != null) { + isAbstract = new Boolean(option.isAbstract.booleanValue()); + } + if (option.command != null) { + command = new String(option.command); + } + if (option.commandFalse != null) { + commandFalse = new String(option.commandFalse); + } + if (option.tip != null) { + tip = new String(option.tip); + } + if (option.categoryId != null) { + categoryId = new String(option.categoryId); + } + if (option.builtIns != null) { + builtIns = new ArrayList(option.builtIns); + } + if (option.browseType != null) { + browseType = new Integer(option.browseType.intValue()); + } + if (option.resourceFilter != null) { + resourceFilter = new Integer(option.resourceFilter.intValue()); + } + if (option.enumList != null) { + enumList = new ArrayList(option.enumList); + enumCommands = new HashMap(option.enumCommands); + enumNames = new HashMap(option.enumNames); + } + + if (option.valueType != null) { + valueType = new Integer(option.valueType.intValue()); + } + Integer vType = null; + try { + vType = new Integer(option.getValueType()); + if (vType != null) { + switch (vType.intValue()) { + case BOOLEAN: + if (option.value != null) { + value = new Boolean(((Boolean)option.value).booleanValue()); + } + if (option.defaultValue != null) { + defaultValue = new Boolean(((Boolean)option.defaultValue).booleanValue()); + } + break; + case STRING: + case ENUMERATED: + if (option.value != null) { + value = new String((String)option.value); + } + if (option.defaultValue != null) { + defaultValue = new String((String)option.defaultValue); + } + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + if (option.value != null) { + value = new ArrayList((ArrayList)option.value); + } + if (option.defaultValue != null) { + defaultValue = new ArrayList((ArrayList)option.defaultValue); + } + break; + } + } + } catch (BuildException be) { + // TODO: should we ignore this?? + } + + category = option.category; + applicabilityCalculatorElement = option.applicabilityCalculatorElement; + applicabilityCalculator = option.applicabilityCalculator; + + booleanExpressionCalculator = option.booleanExpressionCalculator; + + if (option.valueHandlerElement != null) { + valueHandlerElement = option.valueHandlerElement; + valueHandler = option.valueHandler; + } + if (option.valueHandlerExtraArgument != null) { + valueHandlerExtraArgument = new String(option.valueHandlerExtraArgument); + } + + if(!isExtensionElement()) + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Loads the option information from the ManagedConfigElement specified in the + * argument. + * + * @param element Contains the option information + */ + protected void loadFromManifest(IManagedConfigElement element) { + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // Get the name + setName(element.getAttribute(IBuildObject.NAME)); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // Get the unused children, if any + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + + // isAbstract + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + + // Get the command defined for the option + command = element.getAttribute(COMMAND); + + // Get the command defined for a Boolean option when the value is False + commandFalse = element.getAttribute(COMMAND_FALSE); + + // Get the tooltip for the option + tip = element.getAttribute(TOOL_TIP); + + // Options hold different types of values + String valueTypeStr = element.getAttribute(VALUE_TYPE); + if (valueTypeStr != null) { + valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); + } + + // Note: The value and defaultValue attributes are loaded in the resolveReferences routine. + // This is because we need to have the value-type, and this may be defined in a + // superClass that is not yet loaded. + + // Determine if there needs to be a browse button + String browseTypeStr = element.getAttribute(BROWSE_TYPE); + if (browseTypeStr == null) { + // Set to null, to indicate no browse type specification + // This will allow any superclasses to be searched for the + // browse type specification, and thus inherited, if found, + // which they should be + browseType = null; + } else if (browseTypeStr.equals(NONE)) { + browseType = new Integer(BROWSE_NONE); + } else if (browseTypeStr.equals(FILE)) { + browseType = new Integer(BROWSE_FILE); + } else if (browseTypeStr.equals(DIR)) { + browseType = new Integer(BROWSE_DIR); + } + + categoryId = element.getAttribute(CATEGORY); + + // Get the resourceFilter attribute + String resFilterStr = element.getAttribute(RESOURCE_FILTER); + if (resFilterStr == null) { + // Set to null, to indicate no resource filter specification + // This will allow any superclasses to be searched for the + // resource filter specification, and thus inherited, if found, + // which they should be + resourceFilter = null; + } else if (resFilterStr.equals(ALL)) { + resourceFilter = new Integer(FILTER_ALL); + } else if (resFilterStr.equals(FILE)) { + resourceFilter = new Integer(FILTER_FILE); + } else if (resFilterStr.equals(PROJECT)) { + resourceFilter = new Integer(FILTER_PROJECT); + } + + //get enablements + IManagedConfigElement enablements[] = element.getChildren(OptionEnablementExpression.NAME); + if(enablements.length > 0) + booleanExpressionCalculator = new BooleanExpressionApplicabilityCalculator(enablements); + + // get the applicability calculator, if any + String applicabilityCalculatorStr = element.getAttribute(APPLICABILITY_CALCULATOR); + if (applicabilityCalculatorStr != null && element instanceof DefaultManagedConfigElement) { + applicabilityCalculatorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } else { + applicabilityCalculator = booleanExpressionCalculator; + } + + // valueHandler + // Store the configuration element IFF there is a value handler defined + String valueHandler = element.getAttribute(VALUE_HANDLER); + if (valueHandler != null && element instanceof DefaultManagedConfigElement) { + valueHandlerElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + // valueHandlerExtraArgument + valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); + } + + /* (non-Javadoc) + * Initialize the option information from the XML element + * specified in the argument + * + * @param element An XML element containing the option information + */ + protected void loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + superClass = ManagedBuildManager.getExtensionOption(superClassId); + if (superClass == null) { + // TODO: Report error + } + } + + // Get the unused children, if any + if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + } + + // isAbstract + if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + } + + // Get the command defined for the option + if (element.hasAttribute(COMMAND)) { + command = element.getAttribute(COMMAND); + } + + // Get the command defined for a Boolean option when the value is False + if (element.hasAttribute(COMMAND_FALSE)) { + commandFalse = element.getAttribute(COMMAND_FALSE); + } + + // Get the tooltip for the option + if (element.hasAttribute(TOOL_TIP)) { + tip = element.getAttribute(TOOL_TIP); + } + + // Options hold different types of values + if (element.hasAttribute(VALUE_TYPE)) { + String valueTypeStr = element.getAttribute(VALUE_TYPE); + valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); + } + + // Now get the actual value based upon value-type + try { + int valType = getValueType(); + switch (valType) { + case BOOLEAN: + // Convert the string to a boolean + if (element.hasAttribute(VALUE)) { + value = new Boolean(element.getAttribute(VALUE)); + } + if (element.hasAttribute(DEFAULT_VALUE)) { + defaultValue = new Boolean(element.getAttribute(DEFAULT_VALUE)); + } + break; + case STRING: + // Just get the value out of the option directly + if (element.hasAttribute(VALUE)) { + value = element.getAttribute(VALUE); + } + if (element.hasAttribute(DEFAULT_VALUE)) { + defaultValue = element.getAttribute(DEFAULT_VALUE); + } + break; + case ENUMERATED: + if (element.hasAttribute(VALUE)) { + value = element.getAttribute(VALUE); + } + if (element.hasAttribute(DEFAULT_VALUE)) { + defaultValue = element.getAttribute(DEFAULT_VALUE); + } + + // Do we have enumeratedOptionValue children? If so, load them + // to define the valid values and the default value. + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configNode = configElements.item(i); + if (configNode.getNodeName().equals(ENUM_VALUE)) { + Element configElement = (Element)configNode; + String optId = configElement.getAttribute(ID); + if (i == 0) { + enumList = new ArrayList(); + if (defaultValue == null) { + defaultValue = optId; // Default value to be overridden is default is specified + } + } + enumList.add(optId); + if (configElement.hasAttribute(COMMAND)) { + getEnumCommandMap().put(optId, configElement.getAttribute(COMMAND)); + } else { + getEnumCommandMap().put(optId, EMPTY_STRING); + } + getEnumNameMap().put(optId, configElement.getAttribute(NAME)); + if (configElement.hasAttribute(IS_DEFAULT)) { + Boolean isDefault = new Boolean(configElement.getAttribute(IS_DEFAULT)); + if (isDefault.booleanValue()) { + defaultValue = optId; + } + } + } + } + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + // Note: These string-list options do not load either the "value" or + // "defaultValue" attributes. Instead, the ListOptionValue children + // are loaded in the value field. + List valueList = null; + configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + if (i == 0) { + valueList = new ArrayList(); + builtIns = new ArrayList(); + } + Node configNode = configElements.item(i); + if (configNode.getNodeName().equals(LIST_VALUE)) { + Element valueElement = (Element)configNode; + Boolean isBuiltIn; + if (valueElement.hasAttribute(IS_DEFAULT)) { + isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); + } else { + isBuiltIn = new Boolean(false); + } + if (isBuiltIn.booleanValue()) { + builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + else { + valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + } + } + value = valueList; + break; + default : + break; + } + } catch (BuildException e) { + // TODO: report error + } + + // Determine if there needs to be a browse button + if (element.hasAttribute(BROWSE_TYPE)) { + String browseTypeStr = element.getAttribute(BROWSE_TYPE); + + if (browseTypeStr == null) { + // Set to null, to indicate no browse type specification + // This will allow any superclasses to be searched for the + // browse type specification, and thus inherited, if found, + // which they should be + browseType = null; + } else if (browseTypeStr.equals(NONE)) { + browseType = new Integer(BROWSE_NONE); + } else if (browseTypeStr.equals(FILE)) { + browseType = new Integer(BROWSE_FILE); + } else if (browseTypeStr.equals(DIR)) { + browseType = new Integer(BROWSE_DIR); + } + } + + if (element.hasAttribute(CATEGORY)) { + categoryId = element.getAttribute(CATEGORY); + if (categoryId != null) { + category = holder.getOptionCategory(categoryId); + } + } + + // Get the resourceFilter attribute + if (element.hasAttribute(RESOURCE_FILTER)) { + String resFilterStr = element.getAttribute(RESOURCE_FILTER); + if (resFilterStr == null) { + // Set to null, to indicate no resource filter specification + // This will allow any superclasses to be searched for the + // resource filter specification, and thus inherited, if found, + // which they should be + resourceFilter = null; + } else if (resFilterStr.equals(ALL)) { + resourceFilter = new Integer(FILTER_ALL); + } else if (resFilterStr.equals(FILE)) { + resourceFilter = new Integer(FILTER_FILE); + } else if (resFilterStr.equals(PROJECT)) { + resourceFilter = new Integer(FILTER_PROJECT); + } + } + + // Note: valueHandlerElement and VALUE_HANDLER are not restored, + // as they are not saved. See note in serialize(). + + // valueHandlerExtraArgument + if (element.hasAttribute(VALUE_HANDLER_EXTRA_ARGUMENT)) { + valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); + } + } + + private int ValueTypeStrToInt(String valueTypeStr) { + if (valueTypeStr == null) return -1; + if (valueTypeStr.equals(TYPE_STRING)) + return STRING; + else if (valueTypeStr.equals(TYPE_STR_LIST)) + return STRING_LIST; + else if (valueTypeStr.equals(TYPE_BOOL)) + return BOOLEAN; + else if (valueTypeStr.equals(TYPE_ENUM)) + return ENUMERATED; + else if (valueTypeStr.equals(TYPE_INC_PATH)) + return INCLUDE_PATH; + else if (valueTypeStr.equals(TYPE_LIB)) + return LIBRARIES; + else if (valueTypeStr.equals(TYPE_USER_OBJS)) + return OBJECTS; + else if (valueTypeStr.equals(TYPE_DEFINED_SYMBOLS)) + return PREPROCESSOR_SYMBOLS; + else { + // TODO: This was the CDT 2.0 default - should we keep it? + return PREPROCESSOR_SYMBOLS; + } + } + + /** + * Persist the option to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) throws BuildException { + if (superClass != null) + element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + if (command != null) { + element.setAttribute(COMMAND, command); + } + + if (commandFalse != null) { + element.setAttribute(COMMAND_FALSE, commandFalse); + } + + if (tip != null) { + element.setAttribute(TOOL_TIP, tip); + } + + /* + * Note: We store value & value-type as a pair, so we know what type of value we are + * dealing with when we read it back in. + * This is also true of defaultValue. + */ + boolean storeValueType = false; + + // value + if (value != null) { + storeValueType = true; + switch (getValueType()) { + case BOOLEAN: + element.setAttribute(VALUE, ((Boolean)value).toString()); + break; + case STRING: + case ENUMERATED: + element.setAttribute(VALUE, (String)value); + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + if (value != null) { + ArrayList stringList = (ArrayList)value; + ListIterator iter = stringList.listIterator(); + while (iter.hasNext()) { + Element valueElement = doc.createElement(LIST_VALUE); + valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); + valueElement.setAttribute(LIST_ITEM_BUILTIN, "false"); //$NON-NLS-1$ + element.appendChild(valueElement); + } + } + // Serialize the built-ins that have been overridden + if (builtIns != null) { + ListIterator iter = builtIns.listIterator(); + while (iter.hasNext()) { + Element valueElement = doc.createElement(LIST_VALUE); + valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); + valueElement.setAttribute(LIST_ITEM_BUILTIN, "true"); //$NON-NLS-1$ + element.appendChild(valueElement); + } + } + break; + } + } + + // defaultValue + if (defaultValue != null) { + storeValueType = true; + switch (getValueType()) { + case BOOLEAN: + element.setAttribute(DEFAULT_VALUE, ((Boolean)defaultValue).toString()); + break; + case STRING: + case ENUMERATED: + element.setAttribute(DEFAULT_VALUE, (String)defaultValue); + break; + default: + break; + } + } + + if (storeValueType) { + String str; + switch (getValueType()) { + case BOOLEAN: + str = TYPE_BOOL; + break; + case STRING: + str = TYPE_STRING; + break; + case ENUMERATED: + str = TYPE_ENUM; + break; + case STRING_LIST: + str = TYPE_STR_LIST; + break; + case INCLUDE_PATH: + str = TYPE_INC_PATH; + break; + case LIBRARIES: + str = TYPE_LIB; + break; + case OBJECTS: + str = TYPE_USER_OBJS; + break; + case PREPROCESSOR_SYMBOLS: + str = TYPE_DEFINED_SYMBOLS; + break; + default: + // TODO; is this a problem... + str = EMPTY_STRING; + break; + } + element.setAttribute(VALUE_TYPE, str); + } + + // browse type + if (browseType != null) { + String str; + switch (getBrowseType()) { + case BROWSE_NONE: + str = NONE; + break; + case BROWSE_FILE: + str = FILE; + break; + case BROWSE_DIR: + str = DIR; + break; + default: + str = EMPTY_STRING; + break; + } + element.setAttribute(BROWSE_TYPE, str); + } + + if (categoryId != null) { + element.setAttribute(CATEGORY, categoryId); + } + + // resource filter + if (resourceFilter != null) { + String str; + switch (getResourceFilter()) { + case FILTER_ALL: + str = ALL; + break; + case FILTER_FILE: + str = FILE; + break; + case FILTER_PROJECT: + str = PROJECT; + break; + default: + str = EMPTY_STRING; + break; + } + element.setAttribute(RESOURCE_FILTER, str); + } + + // Note: applicability calculator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (applicabilityCalculatorElement != null) { + // TODO: issue warning? + } + + // Note: a value handler cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (valueHandlerElement != null) { + // TODO: Issue warning? Stuck with behavior of this elsewhere in + // CDT, e.g. the implementation of Tool + } + if (valueHandlerExtraArgument != null) { + element.setAttribute(VALUE_HANDLER_EXTRA_ARGUMENT, valueHandlerExtraArgument); + } + + // I am clean now + isDirty = false; + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getParent() + */ + public IBuildObject getParent() { + return holder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getOptionHolder() + */ + public IHoldsOptions getOptionHolder() { + // Do not take superclasses into account + return holder; + } + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getSuperClass() + */ + public IOption getSuperClass() { + return superClass; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getName() + */ + public String getName() { + return (name == null && superClass != null) ? superClass.getName() : name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicableValues() + */ + public String[] getApplicableValues() { + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getApplicableValues(); + } else { + return EMPTY_STRING_ARRAY; + } + } + // Get all of the enumerated names from the option + if (enumList.size() == 0) { + return EMPTY_STRING_ARRAY; + } else { + // Return the elements in the order they are specified in the manifest + String[] enumNames = new String[enumList.size()]; + for (int index = 0; index < enumList.size(); ++ index) { + enumNames[index] = (String) getEnumNameMap().get(enumList.get(index)); + } + return enumNames; + } + } + + public boolean getBooleanValue() { + return ((Boolean)getValue()).booleanValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getBrowseType() + */ + public int getBrowseType() { + if (browseType == null) { + if (superClass != null) { + return superClass.getBrowseType(); + } else { + return BROWSE_NONE; + } + } + return browseType.intValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getResourceFilter() + */ + public int getResourceFilter() { + if (resourceFilter == null) { + if (superClass != null) { + return superClass.getResourceFilter(); + } else { + return FILTER_ALL; + } + } + return resourceFilter.intValue(); + } + + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculatorElement() + */ + public IConfigurationElement getApplicabilityCalculatorElement() { +/* if (applicabilityCalculatorElement == null) { + if (superClass != null) { + return ((Option)superClass).getApplicabilityCalculatorElement(); + } + } +*/ + return applicabilityCalculatorElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculator() + */ + public IOptionApplicability getApplicabilityCalculator() { + if (applicabilityCalculator == null) { + if (applicabilityCalculatorElement != null) { + try { + if (applicabilityCalculatorElement.getAttribute(APPLICABILITY_CALCULATOR) != null) + applicabilityCalculator = (IOptionApplicability) applicabilityCalculatorElement + .createExecutableExtension(APPLICABILITY_CALCULATOR); + } catch (CoreException e) { + } + } + else if(superClass != null) + applicabilityCalculator = superClass.getApplicabilityCalculator(); + } + + return applicabilityCalculator; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getBuiltIns() + */ + public String[] getBuiltIns() { + // Return the list of built-ins as an array + if (builtIns == null) { + if (superClass != null) { + return superClass.getBuiltIns(); + } else { + return EMPTY_STRING_ARRAY; + } + } + return (String[])builtIns.toArray(new String[builtIns.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCategory() + */ + public IOptionCategory getCategory() { + if (category == null) { + if (superClass != null) { + return superClass.getCategory(); + } else { + if (getOptionHolder() instanceof ITool) { + return ((ITool)getOptionHolder()).getTopOptionCategory(); + } else { + return null; + } + } + } + return category; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommand() + */ + public String getCommand() { + if (command == null) { + if (superClass != null) { + return superClass.getCommand(); + } else { + return EMPTY_STRING; + } + } + return command; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommandFalse() + */ + public String getCommandFalse() { + if (commandFalse == null) { + if (superClass != null) { + return superClass.getCommandFalse(); + } else { + return EMPTY_STRING; + } + } + return commandFalse; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getToolTip() + */ + public String getToolTip() { + if (tip == null) { + if (superClass != null) { + return superClass.getToolTip(); + } else { + return EMPTY_STRING; + } + } + return tip; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefinedSymbols() + */ + public String[] getDefinedSymbols() throws BuildException { + if (getValueType() != PREPROCESSOR_SYMBOLS) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String) + */ + public String getEnumCommand(String id) throws BuildException { + // Sanity + if (id == null) return EMPTY_STRING; + + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getEnumCommand(id); + } else { + return EMPTY_STRING; + } + } + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + // First check for the command in ID->command map + String cmd = (String) getEnumCommandMap().get(id); + if (cmd == null) { + // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable + // name of the enumeration. Search for the ID that maps to the name and use that to find the + // command. + ListIterator iter = enumList.listIterator(); + while (iter.hasNext()) { + String realID = (String) iter.next(); + String name = (String) getEnumNameMap().get(realID); + if (id.equals(name)) { + cmd = (String) getEnumCommandMap().get(realID); + break; + } + } + } + return cmd == null ? EMPTY_STRING : cmd; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumName(java.lang.String) + */ + public String getEnumName(String id) throws BuildException { + // Sanity + if (id == null) return EMPTY_STRING; + + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getEnumName(id); + } else { + return EMPTY_STRING; + } + } + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + // First check for the command in ID->name map + String name = (String) getEnumNameMap().get(id); + if (name == null) { + // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable + // name of the enumeration. + name = id; + } + return name; + } + + /* (non-Javadoc) + * A memory-safe accessor to the map of enumerated option value IDs to the commands + * that a tool understands. + * + * @return a Map of enumerated option value IDs to actual commands that are passed + * to a tool on the command line. + */ + private Map getEnumCommandMap() { + if (enumCommands == null) { + enumCommands = new HashMap(); + } + return enumCommands; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumeratedId(java.lang.String) + */ + public String getEnumeratedId(String name) throws BuildException { + if (name == null) return null; + + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getEnumeratedId(name); + } else { + return EMPTY_STRING; + } + } + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + Set idSet = getEnumNameMap().keySet(); + Iterator iter = idSet.iterator(); + while (iter.hasNext()) { + String id = (String) iter.next(); + String enumName = (String) getEnumNameMap().get(id); + if (name.equals(enumName)) { + return id; + } + } + return null; + } + + /* (non-Javadoc) + * + * @return a Map of enumerated option value IDs to the selection displayed to the user. + */ + private Map getEnumNameMap() { + if (enumNames == null) { + enumNames = new HashMap(); + } + return enumNames; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getIncludePaths() + */ + public String[] getIncludePaths() throws BuildException { + if (getValueType() != INCLUDE_PATH) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getLibraries() + */ + public String[] getLibraries() throws BuildException { + if (getValueType() != LIBRARIES) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefaultEnumValue() + */ + public String getSelectedEnum() throws BuildException { + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + return getStringValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringListValue() + */ + public String[] getStringListValue() throws BuildException { + if (getValueType() != STRING_LIST) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringValue() + */ + public String getStringValue() throws BuildException { + if (getValueType() != STRING && getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + return getValue() == null ? EMPTY_STRING : (String)getValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getUserObjects() + */ + public String[] getUserObjects() throws BuildException { + if (getValueType() != OBJECTS) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + // This is the right puppy, so return its list value + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueType() + */ + public int getValueType() throws BuildException { + if (valueType == null) { + if (superClass != null) { + return superClass.getValueType(); + } else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$; + } + } + return valueType.intValue(); + } + + /* (non-Javadoc) + * Gets the value, applying appropriate defaults if necessary. + */ + public Object getValue() { + /* + * In order to determine the current value of an option, perform the following steps until a value is found: + * 1. Examine the value attribute of the option. + * 2. Examine the value attribute of the option�s superClass recursively. + * 3. Examine the dynamicDefaultValue attribute of the option and invoke it if specified. (not yet implemented) + * 4. Examine the defaultValue attribute of the option. + * 5. Examine the dynamicDefaultValue attribute of the option�s superClass and invoke it if specified. (not yet implemented) + * 6. Examine the defaultValue attribute of the option�s superClass. + * 7. Go to step 5 recursively until no more super classes. + * 8. Use the default value for the option type. + */ + + Object val = getRawValue(); + if (val == null) { + val = getDefaultValue(); + if (val == null) { + int valType; + try { + valType = getValueType(); + } catch (BuildException e) { + return EMPTY_STRING; + } + switch (valType) { + case BOOLEAN: + val = new Boolean(false); + break; + case STRING: + val = EMPTY_STRING; + break; + case ENUMERATED: + // TODO: Can we default to the first enumerated id? + val = EMPTY_STRING; + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + val = new ArrayList(); + break; + default: + val = EMPTY_STRING; + break; + } + } + } + return val; + } + + /* (non-Javadoc) + * Gets the raw value, applying appropriate defauls if necessary. + */ + public Object getRawValue() { + if (value == null) { + if (superClass != null) { + Option mySuperClass = (Option)superClass; + return mySuperClass.getRawValue(); + } + } + return value; + } + + /* (non-Javadoc) + * Gets the raw default value. + */ + public Object getDefaultValue() { + // Note: string-list options do not have a default value + if (defaultValue == null) { + if (superClass != null) { + return superClass.getDefaultValue(); + } + } + return defaultValue; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) + */ + public void setDefaultValue(Object v) { + defaultValue = v; + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setCategory(org.eclipse.cdt.managedbuilder.core.IOptionCategory) + */ + public void setCategory(IOptionCategory category) { + if (this.category != category) { + this.category = category; + if (category != null) { + categoryId = category.getId(); + } else { + categoryId = null; + } + if(!isExtensionElement()) + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommand(String) + */ + public void setCommand(String cmd) { + if (cmd == null && command == null) return; + if (cmd == null || command == null || !cmd.equals(command)) { + command = cmd; + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommandFalse(String) + */ + public void setCommandFalse(String cmd) { + if (cmd == null && commandFalse == null) return; + if (cmd == null || commandFalse == null || !cmd.equals(commandFalse)) { + commandFalse = cmd; + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setToolTip(String) + */ + public void setToolTip(String tooltip) { + if (tooltip == null && tip == null) return; + if (tooltip == null || tip == null || !tooltip.equals(tip)) { + tip = tooltip; + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setResourceFilter(int) + */ + public void setResourceFilter(int filter) { + if (resourceFilter == null || !(filter == resourceFilter.intValue())) { + resourceFilter = new Integer(filter); + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setBrowseType(int) + */ + public void setBrowseType(int type) { + if (browseType == null || !(type == browseType.intValue())) { + browseType = new Integer(type); + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(boolean) + */ + public void setValue(boolean value) throws BuildException { + if (/*!isExtensionElement() && */getValueType() == BOOLEAN){ + this.value = new Boolean(value); + } else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + if(!isExtensionElement()) + setDirty(true); + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String) + */ + public void setValue(String value) throws BuildException { + // Note that we can still set the human-readable value here + if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED)) { + this.value = value; + } else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + if(!isExtensionElement()) + setDirty(true); + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String []) + */ + public void setValue(String [] value) throws BuildException { + if (/*!isExtensionElement() && */ + (getValueType() == STRING_LIST + || getValueType() == INCLUDE_PATH + || getValueType() == PREPROCESSOR_SYMBOLS + || getValueType() == LIBRARIES + || getValueType() == OBJECTS)) { + // Just replace what the option reference is holding onto + if(value == null) + this.value = null; + else + this.value = new ArrayList(Arrays.asList(value)); + } + else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) + */ + public void setValue(Object v) { + value = v; + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueType() + */ + public void setValueType(int type) { + // TODO: Verify that this is a valid type + if (valueType == null || valueType.intValue() != type) { + valueType = new Integer(type); + if(!isExtensionElement()) + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerElement() + */ + public IConfigurationElement getValueHandlerElement() { + if (valueHandlerElement == null) { + if (superClass != null) { + return ((Option)superClass).getValueHandlerElement(); + } + } + return valueHandlerElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerElement(IConfigurationElement) + */ + public void setValueHandlerElement(IConfigurationElement element) { + valueHandlerElement = element; + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandler() + */ + public IManagedOptionValueHandler getValueHandler() { + if (valueHandler != null) { + return valueHandler; + } + IConfigurationElement element = getValueHandlerElement(); + if (element != null) { + try { + if (element.getAttribute(VALUE_HANDLER) != null) { + valueHandler = (IManagedOptionValueHandler) element.createExecutableExtension(VALUE_HANDLER); + return valueHandler; + } + } catch (CoreException e) { + ManagedBuildManager.OptionValueHandlerError(element.getAttribute(VALUE_HANDLER), getId()); + // Assign the default handler to avoid further error messages + valueHandler = ManagedOptionValueHandler.getManagedOptionValueHandler(); + return valueHandler; + } + } + // If no handler is provided, then use the default handler + return ManagedOptionValueHandler.getManagedOptionValueHandler(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerExtraArgument()) + */ + public String getValueHandlerExtraArgument() { + if (valueHandlerExtraArgument == null) { + if (superClass != null) { + return superClass.getValueHandlerExtraArgument(); + } else { + return EMPTY_STRING; + } + } + return valueHandlerExtraArgument; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerExtraArgument(String)) + */ + public void setValueHandlerExtraArgument(String extraArgument) { + if (extraArgument == null && valueHandlerExtraArgument == null) return; + if (extraArgument == null || + valueHandlerExtraArgument == null || + !extraArgument.equals(valueHandlerExtraArgument)) { + valueHandlerExtraArgument = extraArgument; + if(!isExtensionElement()) + isDirty = true; + } + } + + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#isExtensionElement() + */ + public boolean isExtensionElement() { + return isExtensionOption; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#overridesOnlyValue() + * Deprecated since 3.0.1 + */ + public boolean overridesOnlyValue() { + if (superClass != null && + unusedChildren == null && + browseType == null && + (builtIns == null || builtIns.size() == 0) && + category == null && + categoryId == null && + command == null && + commandFalse == null && + tip == null && + enumList == null && + enumCommands == null && + enumNames == null && + defaultValue == null) { + return true; + } else { + return false; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#isDirty() + */ + public boolean isDirty() { + // This shouldn't be called for an extension option + if (isExtensionOption) return false; + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + } + + public void resolveReferences() { + + if (!resolved) { + resolved = true; + // Resolve superClass + if (superClassId != null && superClassId.length() > 0) { + superClass = ManagedBuildManager.getExtensionOption(superClassId); + if (superClass == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "option", //$NON-NLS-1$ + getId()); + } else { + // All of our superclasses must be resolved in order to call + // getValueType below. + ((Option)superClass).resolveReferences(); + } + } + if (categoryId != null) { + category = holder.getOptionCategory(categoryId); + if (category == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "category", //$NON-NLS-1$ + categoryId, + "option", //$NON-NLS-1$ + getId()); + } + } + // Process the value and default value attributes. This is delayed until now + // because we may not know the valueType until after we have resolved the superClass above + // Now get the actual value + try { + IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); + switch (getValueType()) { + case BOOLEAN: + // Convert the string to a boolean + String val = element.getAttribute(VALUE); + if (val != null) { + value = new Boolean(val); + } + val = element.getAttribute(DEFAULT_VALUE); + if (val != null) { + defaultValue = new Boolean(val); + } + break; + case STRING: + // Just get the value out of the option directly + value = element.getAttribute(VALUE); + defaultValue = element.getAttribute(DEFAULT_VALUE); + break; + case ENUMERATED: + value = element.getAttribute(VALUE); + defaultValue = element.getAttribute(DEFAULT_VALUE); + + // Do we have enumeratedOptionValue children? If so, load them + // to define the valid values and the default value. + IManagedConfigElement[] enumElements = element.getChildren(ENUM_VALUE); + for (int i = 0; i < enumElements.length; ++i) { + String optId = enumElements[i].getAttribute(ID); + if (i == 0) { + enumList = new ArrayList(); + if (defaultValue == null) { + defaultValue = optId; // Default value to be overridden if default is specified + } + } + enumList.add(optId); + getEnumCommandMap().put(optId, enumElements[i].getAttribute(COMMAND)); + getEnumNameMap().put(optId, enumElements[i].getAttribute(NAME)); + Boolean isDefault = new Boolean(enumElements[i].getAttribute(IS_DEFAULT)); + if (isDefault.booleanValue()) { + defaultValue = optId; + } + } + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + // Note: These string-list options do not load either the "value" or + // "defaultValue" attributes. Instead, the ListOptionValue children + // are loaded in the value field. + List valueList = null; + IManagedConfigElement[] valueElements = element.getChildren(LIST_VALUE); + for (int i = 0; i < valueElements.length; ++i) { + if (i == 0) { + valueList = new ArrayList(); + builtIns = new ArrayList(); + } + IManagedConfigElement valueElement = valueElements[i]; + Boolean isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); + if (isBuiltIn.booleanValue()) { + builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + else { + valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + } + value = valueList; + break; + default : + break; + } + } catch (BuildException e) { + // TODO: report error + } + } + } + + /** + * @return Returns the managedBuildRevision. + */ + public String getManagedBuildRevision() { + if ( managedBuildRevision == null) { + if ( getParent() != null) { + return getParent().getManagedBuildRevision(); + } + } + return managedBuildRevision; + } + + /* (non-Javadoc) + * For now implement this method just as a utility to make code + * within the Option class cleaner. + * TODO: In future we may want to move this to IOption + */ + protected boolean isAbstract() { + if (isAbstract != null) { + return isAbstract.booleanValue(); + } else { + return false; // Note: no inheritance from superClass + } + } + + /** + * Verifies whether the option is valid and handles + * any errors for the option. The following errors + * can occur: + * (a) Options that are children of a ToolChain must + * ALWAYS have a category + * (b) Options that are children of a ToolChain must + * NEVER have a resourceFilter of "file". + * If an error occurs, the option is set to being invalid. + * + * @pre All references have been resolved. + */ + private void verify() { + if (verified) return; + verified = true; + // Ignore elements that are superclasses + if ( getOptionHolder() instanceof IToolChain && isAbstract() == false ) { + // Check for error (a) + if (getCategory() == null) { + ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_CATEGORY, getId()); + // Object becomes invalid + isValid = false; + } + // Check for error (b). Not specifying an attribute is OK. + // Do not use getResourceFilter as it does not allow + // differentiating between "all" and no attribute specified. + if ( resourceFilter != null ) + { + switch (getResourceFilter()) { + case Option.FILTER_FILE: + // TODO: Cannot differentiate between "all" and attribute not + // specified. Thus do not produce an error. We can argue that "all" + // means all valid resource configurations. + ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_FILTER, getId()); + // Object becomes invalid + isValid = false; + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#isValid() + */ + public boolean isValid() { + // We use a lazy scheme to check whether the option is valid. + // Note that by default an option is valid. verify() is only called if + // the option has been resolved. This gets us around having to deal with + // ordering problems during a resolve, or introducing another global + // stage to verify the configuration after a resolve. + // The trade-off is that errors in the MBS grammar may not be + // detected on load, but only when a particular grammar element + // is used, say in the GUI. + if (verified == false && resolved == true) { + verify(); + } + return isValid; + } + + /** + * @return Returns true if this Option was created from an MBS 2.0 model + * OptionReference element. + */ + public boolean wasOptRef() { + return wasOptRef; + } + + public void setWasOptRef(boolean was) { + wasOptRef = was; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if ( version == null) { + if ( getParent() != null) { + return getParent().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } + + public BooleanExpressionApplicabilityCalculator getBooleanExpressionCalculator(){ + return booleanExpressionCalculator; + } + + public boolean isAdjustedExtension(){ + return isUdjusted; + } + + public void setAdjusted(boolean adjusted) { + isUdjusted = adjusted; + } + + public void setSuperClass(IOption superClass) { + if ( this.superClass != superClass ) { + this.superClass = superClass; + if ( this.superClass == null) { + superClassId = null; + } else { + superClassId = this.superClass.getId(); + } + + if(!isExtensionElement()) + setDirty(true); + } + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties index f3fc0fc7815..03173c51c76 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties @@ -1,111 +1,111 @@ -############################################################################### -# Copyright (c) 2002, 2006 Rational Software 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 Rational Software - Initial API and implementation -############################################################################### - -# Generated makefile builder messages -ManagedMakeBuilder.message.starting = Starting the build for project {0} -ManagedMakeBuilder.message.rebuild.makefiles = Regenerating makefiles for project {0} -ManagedMakeBuilder.message.update.makefiles = Updating makefiles for project {0} -ManagedMakeBuilder.message.incremental = Updating makefiles for project {0} -ManagedMakeBuilder.message.updating = Updating project files... -ManagedMakeBuilder.message.make = Calling {0} for project {1} -ManagedMakeBuilder.message.regen.deps = Regenerating dependency files for {0} -ManagedMakeBuilder.message.updating.deps = Updating dependency files for {0} -ManagedMakeBuilder.message.creating.markers = Generating markers... -ManagedMakeBuilder.message.console.header = **** {0} of configuration {1} for project {2} **** -ManagedMakeBuilder.message.no.build = Nothing to build for {0} -ManagedMakeBuilder.message.error = Build error -ManagedMakeBuilder.message.error.refresh = Error refreshing project -ManagedMakeBuilder.message.finished = Build complete for project {0} -ManagedMakeBuilder.message.clean.deleting.output=Removing build artifacts from {0} -ManagedMakeBuilder.message.clean.build.clean=Trying a make clean in {0} -ManagedMakeBuilder.type.clean = Clean-only build -ManagedMakeBuider.type.incremental = Build -ManagedMakeBuilder.warning.unsupported.configuration=**** WARNING: The "{0}" Configuration may not build ****\n**** because it uses the "{1}" ****\n**** tool-chain that is unsupported on this system. ****\n\n**** Attempting to build... **** - -# Option exception messages -Option.error.bad_value_type=Bad value for type - -# Managed build manager exception messages -ManagedBuildManager.error.owner_not_null=addTarget: owner not null -ManagedBuildManager.error.null_owner=addTarget: null owner -ManagedBuildManager.error.owner_not_project=addTarget: owner not project -ManagedBuildManager.error.manifest_load_failed_title=Managed Build System Version Error -ManagedBuildManager.error.manifest.version.error=The version number defined in the plugin manifest file\n{0}\nis greater than the version of the Managed Build System.\nThe definitions in the manifest file will not be loaded. -ManagedBuildManager.error.manifest.header=Managed Build system manifest file error: -ManagedBuildManager.error.manifest.resolving=Unable to resolve the {0} identifier {1} in the {2} {3}. -ManagedBuildManager.error.manifest.duplicate=Duplicate identifier {1} for element type {0}. -ManagedBuildManager.error.manifest.icon=Could not load icon "{0}". -ManagedBuildManager.error.manifest.option.category=Option {0} uses a null category that is invalid in its context. The option was ignored. -ManagedBuildManager.error.manifest.option.filter=Option {0} uses an unsupported resourceFilter attribute value. The option was ignored. -ManagedBuildManager.error.manifest.option.valuehandler=Could not load value handler {0} in option {1}. -ManagedBuildManager.error.open_failed_title=Managed Make Project File Error -ManagedBuildManager.error.open_failed=The Managed Make project file could not be read because of the following error:\n\n{0}\n\nManaged Make functionality will not be available for this project. -ManagedBuildManager.error.write_failed_title=Managed Make Project File Write Error -ManagedBuildManager.error.write_failed=The Managed Make project file could not be written because of the following error:\n\n{0}\n -ManagedBuildManager.error.read_only=File {0} is read-only. -ManagedBuildManager.error.project.version.error=The version number of the project {0} is greater than the Managed Build System version number. -ManagedBuildManager.error.id.nomatch=Error loading Managed Make project information for project {0}. The tool definitions used to create the project are not available. -ManagedBuildManager.error.project.file.missing=The Managed Make project file for project {0} is missing. -# Makefile Generator Messages -MakefileGenerator.message.start.file=Building file: -MakefileGenerator.message.finish.file=Finished building: -MakefileGenerator.message.start.build=Building target: -MakefileGenerator.message.finish.build=Finished building target: -MakefileGenerator.message.start.dependency=Regenerating dependency file: -MakefileGenerator.message.no.target=No tool found that can build the extension specified with the build arrtifact name -MakefileGenerator.message.adding.source.folder=Adding folder {0} to sources -MakefileGenerator.message.gen.source.makefile=Generating makefile for source folder {0} -MakefileGenerator.message.calc.delta=Calculating the delta for project {0} -MakefileGenerator.message.finding.sources=Finding source files in project {0} -MakefileGenerator.comment.module.list = Every subdirectory with source files must be described here -MakefileGenerator.comment.module.variables = Add inputs and outputs from these tool invocations to the build variables -MakefileGenerator.comment.source.list = All of the sources participating in the build are defined here -MakefileGenerator.comment.build.rule = Each subdirectory must supply rules for building sources it contributes -MakefileGenerator.comment.build.toprules = Tool invocations -MakefileGenerator.comment.build.alltarget = All Target -MakefileGenerator.comment.build.mainbuildtarget = Main-build Target -MakefileGenerator.comment.build.toptargets = Other Targets -MakefileGenerator.comment.module.make.includes = Include the makefiles for each source subdirectory -MakefileGenerator.comment.module.dep.includes = Include automatically-generated dependency list: -MakefileGenerator.comment.autodeps=Automatically-generated dependency list: -MakefileGenerator.comment.header=Automatically-generated file. Do not edit! -MakefileGenerator.error.spaces=Cannot generate makefile for folder with spaces in name -MakefileGenerator.warning.no.source=Nothing to build for project {0} -MakefileGenerator.error.no.nameprovider=A nameProvider or outputNames must be specified with multipleType == true - -ManagedBuildInfo.message.job.init = Initializing path container for {0} -ManagedBuildInfo.message.init.ok = Initializing path container succeeded for {0} - -# Default GNU Makefile Generator messages -GnuMakefileGenerator.message.postproc.dep.file=Verifying contents of dependency file {0} - -# Tool strings -Tool.default.announcement=Invoking: -#Environment loader messages -StorableEnvironmentLoader.storeOutputStream.wrong.arguments=Wrong arguments - -#User Defined Macro Supplier -UserDefinedMacroSupplier.storeOutputStream.wrong.arguments=Failed to persist macros: Wrong arguments - -# BuildMacroStatus messages -BuildMacroStatus.status.macro.undefined=Macro {0} is undefined -BuildMacroStatus.status.reference.eachother=Macros {0} and {1} reference each other -BuildMacroStatus.status.reference.incorrect=Macro {0} reference is incorrect -BuildMacroStatus.status.macro.not.string=Macro {0} is not of String type -BuildMacroStatus.status.macro.not.stringlist=Macro {0} is not of String-list type -BuildMacroStatus.status.error=Error occured -BuildMacroStatus.value.undefined= - -#ResourceChangeHandler messages -ResourceChangeHandler.buildInfoSerializationJob=Build Info Serialization - -#ManagedBuilderCorePlugin messages +############################################################################### +# Copyright (c) 2002, 2006 Rational Software 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 Rational Software - Initial API and implementation +############################################################################### + +# Generated makefile builder messages +ManagedMakeBuilder.message.starting = Starting the build for project {0} +ManagedMakeBuilder.message.rebuild.makefiles = Regenerating makefiles for project {0} +ManagedMakeBuilder.message.update.makefiles = Updating makefiles for project {0} +ManagedMakeBuilder.message.incremental = Updating makefiles for project {0} +ManagedMakeBuilder.message.updating = Updating project files... +ManagedMakeBuilder.message.make = Calling {0} for project {1} +ManagedMakeBuilder.message.regen.deps = Regenerating dependency files for {0} +ManagedMakeBuilder.message.updating.deps = Updating dependency files for {0} +ManagedMakeBuilder.message.creating.markers = Generating markers... +ManagedMakeBuilder.message.console.header = **** {0} of configuration {1} for project {2} **** +ManagedMakeBuilder.message.no.build = Nothing to build for {0} +ManagedMakeBuilder.message.error = Build error +ManagedMakeBuilder.message.error.refresh = Error refreshing project +ManagedMakeBuilder.message.finished = Build complete for project {0} +ManagedMakeBuilder.message.clean.deleting.output=Removing build artifacts from {0} +ManagedMakeBuilder.message.clean.build.clean=Trying a make clean in {0} +ManagedMakeBuilder.type.clean = Clean-only build +ManagedMakeBuider.type.incremental = Build +ManagedMakeBuilder.warning.unsupported.configuration=**** WARNING: The "{0}" Configuration may not build ****\n**** because it uses the "{1}" ****\n**** tool-chain that is unsupported on this system. ****\n\n**** Attempting to build... **** + +# Option exception messages +Option.error.bad_value_type=Bad value for type + +# Managed build manager exception messages +ManagedBuildManager.error.owner_not_null=addTarget: owner not null +ManagedBuildManager.error.null_owner=addTarget: null owner +ManagedBuildManager.error.owner_not_project=addTarget: owner not project +ManagedBuildManager.error.manifest_load_failed_title=Managed Build System Version Error +ManagedBuildManager.error.manifest.version.error=The version number defined in the plugin manifest file\n{0}\nis greater than the version of the Managed Build System.\nThe definitions in the manifest file will not be loaded. +ManagedBuildManager.error.manifest.header=Managed Build system manifest file error: +ManagedBuildManager.error.manifest.resolving=Unable to resolve the {0} identifier {1} in the {2} {3}. +ManagedBuildManager.error.manifest.duplicate=Duplicate identifier {1} for element type {0}. +ManagedBuildManager.error.manifest.icon=Could not load icon "{0}". +ManagedBuildManager.error.manifest.option.category=Option {0} uses a null category that is invalid in its context. The option was ignored. +ManagedBuildManager.error.manifest.option.filter=Option {0} uses an unsupported resourceFilter attribute value. The option was ignored. +ManagedBuildManager.error.manifest.option.valuehandler=Could not load value handler {0} in option {1}. +ManagedBuildManager.error.open_failed_title=Managed Make Project File Error +ManagedBuildManager.error.open_failed=The Managed Make project file could not be read because of the following error:\n\n{0}\n\nManaged Make functionality will not be available for this project. +ManagedBuildManager.error.write_failed_title=Managed Make Project File Write Error +ManagedBuildManager.error.write_failed=The Managed Make project file could not be written because of the following error:\n\n{0}\n +ManagedBuildManager.error.read_only=File {0} is read-only. +ManagedBuildManager.error.project.version.error=The version number of the project {0} is greater than the Managed Build System version number. +ManagedBuildManager.error.id.nomatch=Error loading Managed Make project information for project {0}. The tool definitions used to create the project are not available. +ManagedBuildManager.error.project.file.missing=The Managed Make project file for project {0} is missing. +# Makefile Generator Messages +MakefileGenerator.message.start.file=Building file: +MakefileGenerator.message.finish.file=Finished building: +MakefileGenerator.message.start.build=Building target: +MakefileGenerator.message.finish.build=Finished building target: +MakefileGenerator.message.start.dependency=Regenerating dependency file: +MakefileGenerator.message.no.target=No tool found that can build the extension specified with the build arrtifact name +MakefileGenerator.message.adding.source.folder=Adding folder {0} to sources +MakefileGenerator.message.gen.source.makefile=Generating makefile for source folder {0} +MakefileGenerator.message.calc.delta=Calculating the delta for project {0} +MakefileGenerator.message.finding.sources=Finding source files in project {0} +MakefileGenerator.comment.module.list = Every subdirectory with source files must be described here +MakefileGenerator.comment.module.variables = Add inputs and outputs from these tool invocations to the build variables +MakefileGenerator.comment.source.list = All of the sources participating in the build are defined here +MakefileGenerator.comment.build.rule = Each subdirectory must supply rules for building sources it contributes +MakefileGenerator.comment.build.toprules = Tool invocations +MakefileGenerator.comment.build.alltarget = All Target +MakefileGenerator.comment.build.mainbuildtarget = Main-build Target +MakefileGenerator.comment.build.toptargets = Other Targets +MakefileGenerator.comment.module.make.includes = Include the makefiles for each source subdirectory +MakefileGenerator.comment.module.dep.includes = Include automatically-generated dependency list: +MakefileGenerator.comment.autodeps=Automatically-generated dependency list: +MakefileGenerator.comment.header=Automatically-generated file. Do not edit! +MakefileGenerator.error.spaces=Cannot generate makefile for folder with spaces in name +MakefileGenerator.warning.no.source=Nothing to build for project {0} +MakefileGenerator.error.no.nameprovider=A nameProvider or outputNames must be specified with multipleType == true + +ManagedBuildInfo.message.job.init = Initializing path container for {0} +ManagedBuildInfo.message.init.ok = Initializing path container succeeded for {0} + +# Default GNU Makefile Generator messages +GnuMakefileGenerator.message.postproc.dep.file=Verifying contents of dependency file {0} + +# Tool strings +Tool.default.announcement=Invoking: +#Environment loader messages +StorableEnvironmentLoader.storeOutputStream.wrong.arguments=Wrong arguments + +#User Defined Macro Supplier +UserDefinedMacroSupplier.storeOutputStream.wrong.arguments=Failed to persist macros: Wrong arguments + +# BuildMacroStatus messages +BuildMacroStatus.status.macro.undefined=Macro {0} is undefined +BuildMacroStatus.status.reference.eachother=Macros {0} and {1} reference each other +BuildMacroStatus.status.reference.incorrect=Macro {0} reference is incorrect +BuildMacroStatus.status.macro.not.string=Macro {0} is not of String type +BuildMacroStatus.status.macro.not.stringlist=Macro {0} is not of String-list type +BuildMacroStatus.status.error=Error occured +BuildMacroStatus.value.undefined= + +#ResourceChangeHandler messages +ResourceChangeHandler.buildInfoSerializationJob=Build Info Serialization + +#ManagedBuilderCorePlugin messages ManagedBuilderCorePlugin.resourceChangeHandlingInitializationJob=Initializing Resource Change Handling \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java index 136104c5753..a9749482531 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java @@ -1,458 +1,458 @@ -/******************************************************************************* - * Copyright (c) 2005 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.managedbuilder.internal.core; - -import java.util.HashMap; -import java.util.HashSet; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -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.IResourceDelta; -import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.resources.IResourceRuleFactory; -import org.eclipse.core.resources.ISaveContext; -import org.eclipse.core.resources.ISaveParticipant; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -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.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.MultiRule; - -public class ResourceChangeHandler implements IResourceChangeListener, ISaveParticipant { - - private class ResourceConfigurationChecker implements IResourceDeltaVisitor{ - private IResourceDelta fRootDelta; - private HashMap fBuildFileGeneratorMap = new HashMap(); - private HashSet fValidatedFilesSet = new HashSet(); - private HashSet fModifiedProjects = new HashSet(); - - public ResourceConfigurationChecker(IResourceDelta rootDelta){ - fRootDelta = rootDelta; - } - - public IProject[] getModifiedProjects(){ - return (IProject[])fModifiedProjects.toArray(new IProject[fModifiedProjects.size()]); - } - - public boolean visit(IResourceDelta delta) throws CoreException { - IResource dResource = delta.getResource(); - int rcType = dResource.getType(); - - if(rcType == IResource.PROJECT || rcType == IResource.FOLDER){ - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IProject project = null; - IResource rcToCheck = null; - switch (delta.getKind()) { - case IResourceDelta.REMOVED : - if ((delta.getFlags() & IResourceDelta.MOVED_TO) == 0 && rcType == IResource.PROJECT) { - sendClose((IProject)dResource); - break; - } - case IResourceDelta.CHANGED : - if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) { - IPath path = delta.getMovedToPath(); - if(path != null){ - project = root.findMember(path.segment(0)).getProject(); - if(project != null && rcType == IResource.FOLDER) - rcToCheck = root.getFolder(substituteProject(dResource.getFullPath(),project.getName())); - } - break; - } - default: - project = dResource.getProject(); - if(rcType == IResource.FOLDER) - rcToCheck = dResource; - break; - } - - if(project != null) { - IManagedBuilderMakefileGenerator makeGen = getInitializedGenerator(project); - if(makeGen != null){ - if(rcToCheck == null || !makeGen.isGeneratedResource(rcToCheck)) - return true; - } - } - return false; - } else if (rcType == IResource.FILE && !dResource.isDerived()) { - int flags = delta.getFlags(); - switch (delta.getKind()) { - case IResourceDelta.REMOVED : - if ((flags & IResourceDelta.MOVED_TO) == 0) { - handleDeleteFile(dResource.getFullPath()); - break; - } - case IResourceDelta.ADDED : - case IResourceDelta.CHANGED : - if ((flags & IResourceDelta.MOVED_TO) != 0) { - IPath path = delta.getMovedToPath(); - if (path != null) { - handleRenamedFile( - dResource.getFullPath(), - path); - } - } else if ((flags & IResourceDelta.MOVED_FROM) != 0) { - IPath path = delta.getMovedFromPath(); - if (path != null) { - handleRenamedFile( - path, - dResource.getFullPath()); - } - } - break; - - default: - break; - } - return false; - } - return true; // visit the children - } - - private IPath substituteProject(IPath path, String projectName){ - return new Path(projectName).makeAbsolute().append(path.removeFirstSegments(1)); - } - - private void handleRenamedFile(IPath fromPath, IPath toPath){ - if(!fValidatedFilesSet.add(fromPath)) - return; - - IProject fromProject = findModifiedProject(fromPath.segment(0)); - if(fromProject == null) - return; - IManagedBuilderMakefileGenerator fromMakeGen = getInitializedGenerator(fromProject); - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - if(fromMakeGen == null || fromMakeGen.isGeneratedResource(root.getFile(substituteProject(fromPath,fromProject.getName())))) - return; - - IManagedBuildInfo fromInfo = fromProject != null ? - ManagedBuildManager.getBuildInfo(fromProject) : - null; - - IProject toProject = root.findMember(toPath.uptoSegment(1)).getProject(); - IManagedBuildInfo toInfo = toProject != null ? - ManagedBuildManager.getBuildInfo(toProject) : - null; - IManagedBuilderMakefileGenerator toMakeGen = toProject != null ? - getInitializedGenerator(toProject) : - null; - if(toMakeGen != null && toMakeGen.isGeneratedResource(root.getFile(toPath))) - toInfo = null; - - if(fromInfo == toInfo){ - //the resource was moved whithing the project scope - if(updateResourceConfigurations(fromInfo,fromPath,toPath) && toProject != null) - fModifiedProjects.add(toProject); - } else { - if(fromInfo != null && toInfo != null){ - //TODO: this is the case when the resource - //is moved from one managed project to another - //should we handle this? - //e.g. add resource configurations to the destination project? - } - if(fromInfo != null && removeResourceConfigurations(fromInfo,fromPath) && fromProject != null) - fModifiedProjects.add(fromProject); - } - } - - private void handleDeleteFile(IPath path){ - IProject project = findModifiedProject(path.segment(0)); - if(project != null){ - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - if(info != null - && removeResourceConfigurations(info,path)) - fModifiedProjects.add(project); - } - } - - //finds the project geven the initial project name - //That is: - // if the project of a given name was renamed returns the renamed project - // if the project of a given name was removed returns null - // if the project of a given name was neither renamed or removed - // returns the project of that name or null if the project does not exist - // - private IProject findModifiedProject(final String oldProjectName){ - IResourceDelta projectDelta = fRootDelta.findMember(new Path(oldProjectName)); - boolean replaced = false; - if(projectDelta != null) { - switch(projectDelta.getKind()){ - case IResourceDelta.REMOVED : - if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) == 0) { - return null; - } - case IResourceDelta.CHANGED : - if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { - IPath path = projectDelta.getMovedToPath(); - if(path != null) - return ResourcesPlugin.getWorkspace().getRoot().findMember(path).getProject(); - } - break; - } - } - - final IProject project[] = new IProject[1]; - try { - fRootDelta.accept(new IResourceDeltaVisitor() { - public boolean visit(IResourceDelta delta) throws CoreException { - IResource dResource = delta.getResource(); - int rcType = dResource.getType(); - if(rcType == IResource.ROOT) { - return true; - } else if(rcType == IResource.PROJECT){ - switch(delta.getKind()){ - case IResourceDelta.ADDED : - case IResourceDelta.CHANGED : - if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) { - IPath path = delta.getMovedFromPath(); - if (path != null && path.segment(0).equals(oldProjectName)) { - project[0] = dResource.getProject(); - } - } - break; - default: - break; - } - } - return false; - } - }); - } catch (CoreException e) { - } - - if(project[0] == null && !replaced) - project[0] = ResourcesPlugin.getWorkspace().getRoot().findMember(oldProjectName).getProject(); - return project[0]; - } - - private IManagedBuilderMakefileGenerator getInitializedGenerator(IProject project){ - IManagedBuilderMakefileGenerator makeGen = (IManagedBuilderMakefileGenerator)fBuildFileGeneratorMap.get(project); - if (makeGen == null) { - try { - if (project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)) { - // Determine if we can access the build info before actually trying - // If not, don't try, to avoid putting up a dialog box warning the user - if (!ManagedBuildManager.canGetBuildInfo(project)) return null; - - IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project); - if (buildInfo != null){ - IConfiguration defaultCfg = buildInfo.getDefaultConfiguration(); - if (defaultCfg != null) { - makeGen = ManagedBuildManager.getBuildfileGenerator(defaultCfg); - makeGen.initialize(project,buildInfo,new NullProgressMonitor()); - fBuildFileGeneratorMap.put(project,makeGen); - } - } - } - } catch (CoreException e){ - return null; - } - } - return makeGen; - } - } - - public void sendClose(IProject project){ - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project,false); - if(info != null){ - IManagedProject managedProj = info.getManagedProject(); - if (managedProj != null) { - IConfiguration cfgs[] = managedProj.getConfigurations(); - - for(int i = 0; i < cfgs.length; i++) - ManagedBuildManager.performValueHandlerEvent(cfgs[i], IManagedOptionValueHandler.EVENT_CLOSE, true); - } - } - } - - /* - * I R e s o u r c e C h a n g e L i s t e n e r - */ - - /* (non-Javadoc) - * - * Handle the renaming and deletion of project resources - * This is necessary in order to update ResourceConfigurations and AdditionalInputs - * - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public void resourceChanged(IResourceChangeEvent event) { - if (event.getSource() instanceof IWorkspace) { - - switch (event.getType()) { - case IResourceChangeEvent.PRE_CLOSE: - IResource proj = event.getResource(); - if(proj instanceof IProject) - sendClose((IProject)proj); - break; - case IResourceChangeEvent.POST_CHANGE : - case IResourceChangeEvent.POST_BUILD : - case IResourceChangeEvent.PRE_DELETE : - IResourceDelta resDelta = event.getDelta(); - if (resDelta == null) { - break; - } - try { - ResourceConfigurationChecker rcChecker = new ResourceConfigurationChecker(resDelta); - resDelta.accept(rcChecker); - - //saving info for the modified projects - initInfoSerialization(rcChecker.getModifiedProjects()); - - } catch (CoreException e) { - CCorePlugin.log(e); - } - break; - default : - break; - } - } - } - - private void initInfoSerialization(final IProject projects[]){ - if(projects.length == 0) - return; - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IResourceRuleFactory ruleFactory = workspace.getRuleFactory(); - ISchedulingRule buildInfoSaveRule; - if(projects.length == 1){ - buildInfoSaveRule = ruleFactory.modifyRule(projects[0]); - } else { - ISchedulingRule rules[] = new ISchedulingRule[projects.length]; - for(int i = 0; i < rules.length; i++) - rules[i] = ruleFactory.modifyRule(projects[i]); - buildInfoSaveRule = MultiRule.combine(rules); - } - - Job savingJob = new Job(ManagedMakeMessages.getResourceString("ResourceChangeHandler.buildInfoSerializationJob")){ //$NON-NLS-1$ - protected IStatus run(IProgressMonitor monitor) { - for(int i = 0; i < projects.length; i++){ - ManagedBuildManager.saveBuildInfo(projects[i],true); - } - return new Status( - IStatus.OK, - ManagedBuilderCorePlugin.getUniqueIdentifier(), - IStatus.OK, - new String(), - null); - } - }; - savingJob.setRule(buildInfoSaveRule); - - savingJob.schedule(); - } - - private boolean updateResourceConfigurations(IManagedBuildInfo info, IPath oldPath, IPath newPath){ - boolean changed = false; - if(!oldPath.equals(newPath)){ - IManagedProject mngProj = info.getManagedProject(); - if(mngProj != null){ - IConfiguration configs[] = mngProj.getConfigurations(); - if(configs != null && configs.length > 0){ - for(int i = 0; i < configs.length; i++){ - if(updateResourceConfiguration(configs[i],oldPath,newPath)) - changed = true; - } - } - } - } - return changed; - } - - private boolean removeResourceConfigurations(IManagedBuildInfo info, IPath path){ - boolean changed = false; - IManagedProject mngProj = info.getManagedProject(); - if(mngProj != null){ - IConfiguration configs[] = mngProj.getConfigurations(); - if(configs != null && configs.length > 0){ - for(int i = 0; i < configs.length; i++){ - if(removeResourceConfiguration(configs[i],path)) - changed = true; - } - } - } - return changed; - } - - private boolean updateResourceConfiguration(IConfiguration config, IPath oldPath, IPath newPath){ - IResourceConfiguration rcCfg = config.getResourceConfiguration(oldPath.toString()); - if(rcCfg != null && !oldPath.equals(newPath)){ - config.removeResourceConfiguration(rcCfg); - rcCfg.setResourcePath(newPath.toString()); - ((Configuration)config).addResourceConfiguration((ResourceConfiguration)rcCfg); - config.setRebuildState(true); - return true; - } - return false; - } - - private boolean removeResourceConfiguration(IConfiguration config, IPath path){ - IResourceConfiguration rcCfg = config.getResourceConfiguration(path.toString()); - if(rcCfg != null){ - config.removeResourceConfiguration(rcCfg); - config.setRebuildState(true); - return true; - } - return false; - } - - /* - * I S a v e P a r t i c i p a n t - */ - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext) - */ - public void saving(ISaveContext context) throws CoreException { - // No state to be saved by the plug-in, but request a - // resource delta to be used on next activation. - context.needDelta(); - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext) - */ - public void doneSaving(ISaveContext context) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext) - */ - public void prepareToSave(ISaveContext context) throws CoreException { - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext) - */ - public void rollback(ISaveContext context) { - } - -} +/******************************************************************************* + * Copyright (c) 2005 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.managedbuilder.internal.core; + +import java.util.HashMap; +import java.util.HashSet; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +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.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.IResourceRuleFactory; +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.ISaveParticipant; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +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.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.MultiRule; + +public class ResourceChangeHandler implements IResourceChangeListener, ISaveParticipant { + + private class ResourceConfigurationChecker implements IResourceDeltaVisitor{ + private IResourceDelta fRootDelta; + private HashMap fBuildFileGeneratorMap = new HashMap(); + private HashSet fValidatedFilesSet = new HashSet(); + private HashSet fModifiedProjects = new HashSet(); + + public ResourceConfigurationChecker(IResourceDelta rootDelta){ + fRootDelta = rootDelta; + } + + public IProject[] getModifiedProjects(){ + return (IProject[])fModifiedProjects.toArray(new IProject[fModifiedProjects.size()]); + } + + public boolean visit(IResourceDelta delta) throws CoreException { + IResource dResource = delta.getResource(); + int rcType = dResource.getType(); + + if(rcType == IResource.PROJECT || rcType == IResource.FOLDER){ + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject project = null; + IResource rcToCheck = null; + switch (delta.getKind()) { + case IResourceDelta.REMOVED : + if ((delta.getFlags() & IResourceDelta.MOVED_TO) == 0 && rcType == IResource.PROJECT) { + sendClose((IProject)dResource); + break; + } + case IResourceDelta.CHANGED : + if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) { + IPath path = delta.getMovedToPath(); + if(path != null){ + project = root.findMember(path.segment(0)).getProject(); + if(project != null && rcType == IResource.FOLDER) + rcToCheck = root.getFolder(substituteProject(dResource.getFullPath(),project.getName())); + } + break; + } + default: + project = dResource.getProject(); + if(rcType == IResource.FOLDER) + rcToCheck = dResource; + break; + } + + if(project != null) { + IManagedBuilderMakefileGenerator makeGen = getInitializedGenerator(project); + if(makeGen != null){ + if(rcToCheck == null || !makeGen.isGeneratedResource(rcToCheck)) + return true; + } + } + return false; + } else if (rcType == IResource.FILE && !dResource.isDerived()) { + int flags = delta.getFlags(); + switch (delta.getKind()) { + case IResourceDelta.REMOVED : + if ((flags & IResourceDelta.MOVED_TO) == 0) { + handleDeleteFile(dResource.getFullPath()); + break; + } + case IResourceDelta.ADDED : + case IResourceDelta.CHANGED : + if ((flags & IResourceDelta.MOVED_TO) != 0) { + IPath path = delta.getMovedToPath(); + if (path != null) { + handleRenamedFile( + dResource.getFullPath(), + path); + } + } else if ((flags & IResourceDelta.MOVED_FROM) != 0) { + IPath path = delta.getMovedFromPath(); + if (path != null) { + handleRenamedFile( + path, + dResource.getFullPath()); + } + } + break; + + default: + break; + } + return false; + } + return true; // visit the children + } + + private IPath substituteProject(IPath path, String projectName){ + return new Path(projectName).makeAbsolute().append(path.removeFirstSegments(1)); + } + + private void handleRenamedFile(IPath fromPath, IPath toPath){ + if(!fValidatedFilesSet.add(fromPath)) + return; + + IProject fromProject = findModifiedProject(fromPath.segment(0)); + if(fromProject == null) + return; + IManagedBuilderMakefileGenerator fromMakeGen = getInitializedGenerator(fromProject); + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + if(fromMakeGen == null || fromMakeGen.isGeneratedResource(root.getFile(substituteProject(fromPath,fromProject.getName())))) + return; + + IManagedBuildInfo fromInfo = fromProject != null ? + ManagedBuildManager.getBuildInfo(fromProject) : + null; + + IProject toProject = root.findMember(toPath.uptoSegment(1)).getProject(); + IManagedBuildInfo toInfo = toProject != null ? + ManagedBuildManager.getBuildInfo(toProject) : + null; + IManagedBuilderMakefileGenerator toMakeGen = toProject != null ? + getInitializedGenerator(toProject) : + null; + if(toMakeGen != null && toMakeGen.isGeneratedResource(root.getFile(toPath))) + toInfo = null; + + if(fromInfo == toInfo){ + //the resource was moved whithing the project scope + if(updateResourceConfigurations(fromInfo,fromPath,toPath) && toProject != null) + fModifiedProjects.add(toProject); + } else { + if(fromInfo != null && toInfo != null){ + //TODO: this is the case when the resource + //is moved from one managed project to another + //should we handle this? + //e.g. add resource configurations to the destination project? + } + if(fromInfo != null && removeResourceConfigurations(fromInfo,fromPath) && fromProject != null) + fModifiedProjects.add(fromProject); + } + } + + private void handleDeleteFile(IPath path){ + IProject project = findModifiedProject(path.segment(0)); + if(project != null){ + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + if(info != null + && removeResourceConfigurations(info,path)) + fModifiedProjects.add(project); + } + } + + //finds the project geven the initial project name + //That is: + // if the project of a given name was renamed returns the renamed project + // if the project of a given name was removed returns null + // if the project of a given name was neither renamed or removed + // returns the project of that name or null if the project does not exist + // + private IProject findModifiedProject(final String oldProjectName){ + IResourceDelta projectDelta = fRootDelta.findMember(new Path(oldProjectName)); + boolean replaced = false; + if(projectDelta != null) { + switch(projectDelta.getKind()){ + case IResourceDelta.REMOVED : + if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) == 0) { + return null; + } + case IResourceDelta.CHANGED : + if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { + IPath path = projectDelta.getMovedToPath(); + if(path != null) + return ResourcesPlugin.getWorkspace().getRoot().findMember(path).getProject(); + } + break; + } + } + + final IProject project[] = new IProject[1]; + try { + fRootDelta.accept(new IResourceDeltaVisitor() { + public boolean visit(IResourceDelta delta) throws CoreException { + IResource dResource = delta.getResource(); + int rcType = dResource.getType(); + if(rcType == IResource.ROOT) { + return true; + } else if(rcType == IResource.PROJECT){ + switch(delta.getKind()){ + case IResourceDelta.ADDED : + case IResourceDelta.CHANGED : + if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) { + IPath path = delta.getMovedFromPath(); + if (path != null && path.segment(0).equals(oldProjectName)) { + project[0] = dResource.getProject(); + } + } + break; + default: + break; + } + } + return false; + } + }); + } catch (CoreException e) { + } + + if(project[0] == null && !replaced) + project[0] = ResourcesPlugin.getWorkspace().getRoot().findMember(oldProjectName).getProject(); + return project[0]; + } + + private IManagedBuilderMakefileGenerator getInitializedGenerator(IProject project){ + IManagedBuilderMakefileGenerator makeGen = (IManagedBuilderMakefileGenerator)fBuildFileGeneratorMap.get(project); + if (makeGen == null) { + try { + if (project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)) { + // Determine if we can access the build info before actually trying + // If not, don't try, to avoid putting up a dialog box warning the user + if (!ManagedBuildManager.canGetBuildInfo(project)) return null; + + IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project); + if (buildInfo != null){ + IConfiguration defaultCfg = buildInfo.getDefaultConfiguration(); + if (defaultCfg != null) { + makeGen = ManagedBuildManager.getBuildfileGenerator(defaultCfg); + makeGen.initialize(project,buildInfo,new NullProgressMonitor()); + fBuildFileGeneratorMap.put(project,makeGen); + } + } + } + } catch (CoreException e){ + return null; + } + } + return makeGen; + } + } + + public void sendClose(IProject project){ + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project,false); + if(info != null){ + IManagedProject managedProj = info.getManagedProject(); + if (managedProj != null) { + IConfiguration cfgs[] = managedProj.getConfigurations(); + + for(int i = 0; i < cfgs.length; i++) + ManagedBuildManager.performValueHandlerEvent(cfgs[i], IManagedOptionValueHandler.EVENT_CLOSE, true); + } + } + } + + /* + * I R e s o u r c e C h a n g e L i s t e n e r + */ + + /* (non-Javadoc) + * + * Handle the renaming and deletion of project resources + * This is necessary in order to update ResourceConfigurations and AdditionalInputs + * + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent event) { + if (event.getSource() instanceof IWorkspace) { + + switch (event.getType()) { + case IResourceChangeEvent.PRE_CLOSE: + IResource proj = event.getResource(); + if(proj instanceof IProject) + sendClose((IProject)proj); + break; + case IResourceChangeEvent.POST_CHANGE : + case IResourceChangeEvent.POST_BUILD : + case IResourceChangeEvent.PRE_DELETE : + IResourceDelta resDelta = event.getDelta(); + if (resDelta == null) { + break; + } + try { + ResourceConfigurationChecker rcChecker = new ResourceConfigurationChecker(resDelta); + resDelta.accept(rcChecker); + + //saving info for the modified projects + initInfoSerialization(rcChecker.getModifiedProjects()); + + } catch (CoreException e) { + CCorePlugin.log(e); + } + break; + default : + break; + } + } + } + + private void initInfoSerialization(final IProject projects[]){ + if(projects.length == 0) + return; + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IResourceRuleFactory ruleFactory = workspace.getRuleFactory(); + ISchedulingRule buildInfoSaveRule; + if(projects.length == 1){ + buildInfoSaveRule = ruleFactory.modifyRule(projects[0]); + } else { + ISchedulingRule rules[] = new ISchedulingRule[projects.length]; + for(int i = 0; i < rules.length; i++) + rules[i] = ruleFactory.modifyRule(projects[i]); + buildInfoSaveRule = MultiRule.combine(rules); + } + + Job savingJob = new Job(ManagedMakeMessages.getResourceString("ResourceChangeHandler.buildInfoSerializationJob")){ //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + for(int i = 0; i < projects.length; i++){ + ManagedBuildManager.saveBuildInfo(projects[i],true); + } + return new Status( + IStatus.OK, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + IStatus.OK, + new String(), + null); + } + }; + savingJob.setRule(buildInfoSaveRule); + + savingJob.schedule(); + } + + private boolean updateResourceConfigurations(IManagedBuildInfo info, IPath oldPath, IPath newPath){ + boolean changed = false; + if(!oldPath.equals(newPath)){ + IManagedProject mngProj = info.getManagedProject(); + if(mngProj != null){ + IConfiguration configs[] = mngProj.getConfigurations(); + if(configs != null && configs.length > 0){ + for(int i = 0; i < configs.length; i++){ + if(updateResourceConfiguration(configs[i],oldPath,newPath)) + changed = true; + } + } + } + } + return changed; + } + + private boolean removeResourceConfigurations(IManagedBuildInfo info, IPath path){ + boolean changed = false; + IManagedProject mngProj = info.getManagedProject(); + if(mngProj != null){ + IConfiguration configs[] = mngProj.getConfigurations(); + if(configs != null && configs.length > 0){ + for(int i = 0; i < configs.length; i++){ + if(removeResourceConfiguration(configs[i],path)) + changed = true; + } + } + } + return changed; + } + + private boolean updateResourceConfiguration(IConfiguration config, IPath oldPath, IPath newPath){ + IResourceConfiguration rcCfg = config.getResourceConfiguration(oldPath.toString()); + if(rcCfg != null && !oldPath.equals(newPath)){ + config.removeResourceConfiguration(rcCfg); + rcCfg.setResourcePath(newPath.toString()); + ((Configuration)config).addResourceConfiguration((ResourceConfiguration)rcCfg); + config.setRebuildState(true); + return true; + } + return false; + } + + private boolean removeResourceConfiguration(IConfiguration config, IPath path){ + IResourceConfiguration rcCfg = config.getResourceConfiguration(path.toString()); + if(rcCfg != null){ + config.removeResourceConfiguration(rcCfg); + config.setRebuildState(true); + return true; + } + return false; + } + + /* + * I S a v e P a r t i c i p a n t + */ + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext) + */ + public void saving(ISaveContext context) throws CoreException { + // No state to be saved by the plug-in, but request a + // resource delta to be used on next activation. + context.needDelta(); + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext) + */ + public void doneSaving(ISaveContext context) { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext) + */ + public void prepareToSave(ISaveContext context) throws CoreException { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext) + */ + public void rollback(ISaveContext context) { + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java index d2b9737e946..3df55d55276 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java @@ -1,1180 +1,1180 @@ -/******************************************************************************* - * Copyright (c) 2003, 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.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.managedbuilder.core.IBuilder; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IConfigurationV2; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.ITarget; -import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.IToolReference; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -public class Target extends BuildObject implements ITarget { - private static final String EMPTY_STRING = new String(); - private static final IConfigurationV2[] emptyConfigs = new IConfigurationV2[0]; - private String artifactName; - private String binaryParserId; - private String cleanCommand; - private List configList; - private Map configMap; - private String defaultExtension; - private Map depCalculatorsMap; - private String errorParserIds; - private String extension; - private boolean isAbstract = false; - private boolean isDirty = false; - private boolean isTest = false; - private String makeArguments; - private String makeCommand; - private IResource owner; - private ITarget parent; - private boolean resolved = true; - private List targetArchList; - private List targetOSList; - private List toolList; - private Map toolMap; - private List toolReferences; - private ProjectType createdProjectType; - private String scannerInfoCollectorId; - - /** - * This constructor is called to create a target defined by an extension point in - * a plugin manifest file. - * - * @param element - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Target(IManagedConfigElement element, String managedBuildRevision) { - // setup for resolving - ManagedBuildManager.putConfigElement(this, element); - resolved = false; - - // id - setId(element.getAttribute(ID)); - - // managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - // hook me up - ManagedBuildManager.addExtensionTarget(this); - - // Get the target name - setName(element.getAttribute(NAME)); - - // Get the name of the build artifact associated with target (usually - // in the plugin specification). - artifactName = element.getAttribute(ARTIFACT_NAME); - - // Get the ID of the binary parser - binaryParserId = element.getAttribute(BINARY_PARSER); - - // Get the semicolon separated list of IDs of the error parsers - errorParserIds = element.getAttribute(ERROR_PARSERS); - - // Get the default extension - defaultExtension = element.getAttribute(DEFAULT_EXTENSION); - - // isAbstract - isAbstract = ("true".equals(element.getAttribute(IS_ABSTRACT))); //$NON-NLS-1$ - - // Is this a test target - isTest = ("true".equals(element.getAttribute(IS_TEST))); //$NON-NLS-1$ - - // Get the clean command - cleanCommand = element.getAttribute(CLEAN_COMMAND); - - // Get the make command - makeCommand = element.getAttribute(MAKE_COMMAND); - - // Get the make arguments - makeArguments = element.getAttribute(MAKE_ARGS); - - // Get scannerInfoCollectorId - scannerInfoCollectorId = element.getAttribute(SCANNER_INFO_COLLECTOR_ID); - - // Get the comma-separated list of valid OS - String os = element.getAttribute(OS_LIST); - if (os != null) { - targetOSList = new ArrayList(); - String[] osTokens = os.split(","); //$NON-NLS-1$ - for (int i = 0; i < osTokens.length; ++i) { - targetOSList.add(osTokens[i].trim()); - } - } - - // Get the comma-separated list of valid Architectures - String arch = element.getAttribute(ARCH_LIST); - if (arch != null) { - targetArchList = new ArrayList(); - String[] archTokens = arch.split(","); //$NON-NLS-1$ - for (int j = 0; j < archTokens.length; ++j) { - targetArchList.add(archTokens[j].trim()); - } - } - - // Load any tool references we might have - IManagedConfigElement[] toolRefs = element.getChildren(IConfigurationV2.TOOLREF_ELEMENT_NAME); - for (int k = 0; k < toolRefs.length; ++k) { - new ToolReference(this, toolRefs[k]); - } - // Then load any tools defined for the target - IManagedConfigElement[] tools = element.getChildren(ITool.TOOL_ELEMENT_NAME); - for (int m = 0; m < tools.length; ++m) { - ITool newTool = new Tool(this, tools[m], managedBuildRevision); - // Add this tool to the target, as this is not done in the constructor - this.addTool(newTool); - } - // Then load the configurations which may have tool references - IManagedConfigElement[] configs = element.getChildren(IConfigurationV2.CONFIGURATION_ELEMENT_NAME); - for (int n = 0; n < configs.length; ++n) { - new ConfigurationV2(this, configs[n]); - } - } - - /* (non-Javadoc) - * Set the resource that owns the target. - * - * @param owner - */ - protected Target(IResource owner) { - this.owner = owner; - } - - /** - * Create a copy of the target specified in the argument, - * that is owned by the owned by the specified resource. - * - * @param owner - * @param parent - */ - public Target(IResource owner, ITarget parent) { - // Make the owner of the target the project resource - this(owner); - - // Copy the parent's identity - this.parent = parent; - int id = ManagedBuildManager.getRandomNumber(); - setId(owner.getName() + "." + parent.getId() + "." + id); //$NON-NLS-1$ //$NON-NLS-2$ - setName(parent.getName()); - - setManagedBuildRevision(parent.getManagedBuildRevision()); - - setArtifactName(parent.getArtifactName()); - this.binaryParserId = parent.getBinaryParserId(); - this.errorParserIds = parent.getErrorParserIds(); - this.defaultExtension = parent.getArtifactExtension(); - this.isTest = parent.isTestTarget(); - this.cleanCommand = parent.getCleanCommand(); - this.scannerInfoCollectorId = ((Target)parent).scannerInfoCollectorId; - - // Hook me up - IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(owner); - buildInfo.addTarget(this); - } - - /** - * Create target from project file. - * - * @param buildInfo - * @param element - */ - public Target(ManagedBuildInfo buildInfo, Element element) { - this(buildInfo.getOwner()); - - // id - setId(element.getAttribute(ID)); - - // hook me up - buildInfo.addTarget(this); - - // name - setName(element.getAttribute(NAME)); - - // Get the name of the build artifact associated with target (should - // contain what the user entered in the UI). - artifactName = element.getAttribute(ARTIFACT_NAME); - - // Get the overridden extension - if (element.hasAttribute(EXTENSION)) { - extension = element.getAttribute(EXTENSION); - } - - // parent - String parentId = element.getAttribute(PARENT); - if (parentId != null) - parent = ManagedBuildManager.getTarget(null, parentId); - - // isAbstract - if ("true".equals(element.getAttribute(IS_ABSTRACT))) //$NON-NLS-1$ - isAbstract = true; - - // Is this a test target - isTest = ("true".equals(element.getAttribute(IS_TEST))); //$NON-NLS-1$ - - // Get the clean command - if (element.hasAttribute(CLEAN_COMMAND)) { - cleanCommand = element.getAttribute(CLEAN_COMMAND); - } - - // Get the semicolon separated list of IDs of the error parsers - if (element.hasAttribute(ERROR_PARSERS)) { - errorParserIds = element.getAttribute(ERROR_PARSERS); - } - - // Get the make command and arguments - if (element.hasAttribute(MAKE_COMMAND)) { - makeCommand = element.getAttribute(MAKE_COMMAND); - } - if(element.hasAttribute(MAKE_ARGS)) { - makeArguments = element.getAttribute(MAKE_ARGS); - } - - Node child = element.getFirstChild(); - while (child != null) { - if (child.getNodeName().equals(IConfigurationV2.CONFIGURATION_ELEMENT_NAME)) { - new ConfigurationV2(this, (Element)child); - } - child = child.getNextSibling(); - } - } - - /** - * @param configuration - */ - public void addConfiguration(IConfigurationV2 configuration) { - getConfigurationList().add(configuration); - getConfigurationMap().put(configuration.getId(), configuration); - } - - /** - * Adds a tool specification to the receiver. This tool is defined - * only for the receiver, and cannot be shared by other targets. - * - * @param tool - */ - public void addTool(ITool tool) { - getToolList().add(tool); - getToolMap().put(tool.getId(), tool); - } - - /** - * Adds a tool reference to the receiver. - * - * @param toolRef - */ - public void addToolReference(ToolReference toolRef) { - getLocalToolReferences().add(toolRef); - } - - - /* (non-Javadoc) - * Tail-recursion method that creates a lits of tools and tool reference - * walking the receiver's parent hierarchy. - * - * @param toolArray - */ - private void addToolsToArray(Vector toolArray) { - if (parent != null) { - ((Target)parent).addToolsToArray(toolArray); - } - - // Add the tools from out own list - toolArray.addAll(getToolList()); - - // Add local tool references - toolArray.addAll(getLocalToolReferences()); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#createConfiguration(org.eclipse.cdt.core.build.managed.IConfigurationV2) - */ - public IConfigurationV2 createConfiguration(IConfigurationV2 parent, String id) { - isDirty = true; - return new ConfigurationV2(this, parent, id); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#createConfiguration() - */ - public IConfigurationV2 createConfiguration(String id) { - return new ConfigurationV2(this, id); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getArtifactExtension() - */ - public String getArtifactExtension() { - // Has the user changed the extension for this target - if (extension != null) { - return extension; - } - // If not, then go through the default extension lookup - if (defaultExtension == null) { - // Ask my parent first - if (parent != null) { - return parent.getArtifactExtension(); - } else { - return EMPTY_STRING; - } - } else { - return defaultExtension; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#getArtifactName() - */ - public String getArtifactName() { - if (artifactName == null) { - // If I have a parent, ask it - if (parent != null) { - return parent.getArtifactName(); - } else { - // I'm it and this is not good! - return EMPTY_STRING; - } - } else { - return artifactName; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getBinaryParserId() - */ - public String getBinaryParserId() { - if (binaryParserId == null) { - // If I have a parent, ask it - if (parent != null) { - return parent.getBinaryParserId(); - } else { - // I'm it and this is not good! - return EMPTY_STRING; - } - } - return binaryParserId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#getCleanCommand() - */ - public String getCleanCommand() { - // Return the command used to remove files - if (cleanCommand == null) { - if (parent != null) { - return parent.getCleanCommand(); - } else { - // User forgot to specify it. Guess based on OS. - if (Platform.getOS().equals(Platform.OS_WIN32)) { - return new String("del"); //$NON-NLS-1$ - } else { - return new String("rm"); //$NON-NLS-1$ - } - } - } else { - // This was spec'd in the manifest - return cleanCommand; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#getConfiguration() - */ - public IConfigurationV2 getConfiguration(String id) { - return (IConfigurationV2)getConfigurationMap().get(id); - } - - /* (non-Javadoc) - * Safe accessor for the list of configurations. - * - * @return List containing the configurations - */ - private List getConfigurationList() { - if (configList == null) { - configList = new ArrayList(); - } - return configList; - } - - /* (non-Javadoc) - * Safe accessor for the map of configuration ids to configurations - * - * @return - */ - private Map getConfigurationMap() { - if (configMap == null) { - configMap = new HashMap(); - } - return configMap; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getConfigurations() - */ - public IConfigurationV2[] getConfigurations() { - return (IConfigurationV2[])getConfigurationList().toArray(new IConfigurationV2[getConfigurationList().size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getDefaultExtension() - */ - public String getDefaultExtension() { - return defaultExtension == null ? EMPTY_STRING : defaultExtension; - } - - private Map getDepCalcMap() { - if (depCalculatorsMap == null) { - depCalculatorsMap = new HashMap(); - } - return depCalculatorsMap; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getErrorParserIds() - */ - public String getErrorParserIds() { - if (errorParserIds == null) { - // If I have a parent, ask it - if (parent != null) { - return parent.getErrorParserIds(); - } - } - return errorParserIds; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getErrorParserList() - */ - public String[] getErrorParserList() { - String parserIDs = getErrorParserIds(); - String[] errorParsers = null; - if (parserIDs != null) { - // Check for an empty string - if (parserIDs.length() == 0) { - errorParsers = new String[0]; - } else { - StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ - List list = new ArrayList(tok.countTokens()); - while (tok.hasMoreElements()) { - list.add(tok.nextToken()); - } - String[] strArr = {""}; //$NON-NLS-1$ - errorParsers = (String[]) list.toArray(strArr); - } - } else { - // If no error parsers are specified by the target, the default is - // all error parsers - errorParsers = CCorePlugin.getDefault().getAllErrorParsersIDs(); - } - return errorParsers; - } - - /* (non-javadoc) - * A safe accesor method. It answers the tool reference list in the - * receiver. - * - * @return List - */ - protected List getLocalToolReferences() { - if (toolReferences == null) { - toolReferences = new ArrayList(); - } - return toolReferences; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getMakeArguments() - */ - public String getMakeArguments() { - if (makeArguments == null) { - // See if it is defined in my parent - if (parent != null) { - return parent.getMakeArguments(); - } else { - // No parent and no user setting - return new String(""); //$NON-NLS-1$ - } - } - return makeArguments; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#getMakeCommand() - */ - public String getMakeCommand() { - // Return the name of the make utility - if (makeCommand == null) { - // If I have a parent, ask it - if (parent != null) { - return parent.getMakeCommand(); - } else { - // The user has forgotten to specify a command in the plugin manifest - return new String("make"); //$NON-NLS-1$ - } - } else { - return makeCommand; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getName() - */ - public String getName() { - // If I am unnamed, see if I can inherit one from my parent - if (name == null) { - if (parent != null) { - return parent.getName(); - } else { - return new String(""); //$NON-NLS-1$ - } - } else { - return name; - } - } - - /* (non-javadoc) - * - * @param tool - * @return List - */ - protected List getOptionReferences(ITool tool) { - List references = new ArrayList(); - - // Get all the option references I add for this tool - ToolReference toolRef = getToolReference(tool); - if (toolRef != null) { - references.addAll(toolRef.getOptionReferenceList()); - } - - // See if there is anything that my parents add that I don't - if (parent != null) { - List temp = ((Target)parent).getOptionReferences(tool); - Iterator iter = temp.listIterator(); - while (iter.hasNext()) { - OptionReference ref = (OptionReference) iter.next(); - if (!references.contains(ref)) { - references.add(ref); - } - } - } - - return references; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getOwner() - */ - public IResource getOwner() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getParent() - */ - public ITarget getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTargetArchList() - */ - public String[] getTargetArchList() { - if (targetArchList == null) { - // Ask parent for its list - if (parent != null) { - return parent.getTargetArchList(); - } else { - // I have no parent and no defined list - return new String[] {"all"}; //$NON-NLS-1$ - } - } - return (String[]) targetArchList.toArray(new String[targetArchList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTargetOSList() - */ - public String[] getTargetOSList() { - if (targetOSList == null) { - // Ask parent for its list - if (parent != null) { - return parent.getTargetOSList(); - } else { - // I have no parent and no defined filter list - return new String[] {"all"}; //$NON-NLS-1$ - } - } - return (String[]) targetOSList.toArray(new String[targetOSList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTool(java.lang.String) - */ - public ITool getTool(String id) { - ITool result = null; - - // See if receiver has it in list - result = (ITool) getToolMap().get(id); - - // If not, check if parent has it - if (result == null && parent != null) { - result = ((Target)parent).getTool(id); - } - - // If not defined in parents, check if defined at all - if (result == null) { - result = ManagedBuildManager.getExtensionTool(id); - } - - return result; - } - - /* (non-Javadoc) - * A safe accessor method for the list of tools maintained by the - * target - * - */ - private List getToolList() { - if (toolList == null) { - toolList = new ArrayList(); - } - return toolList; - } - - /* (non-Javadoc) - * A safe accessor for the tool map - * - */ - private Map getToolMap() { - if (toolMap == null) { - toolMap = new HashMap(); - } - return toolMap; - } - - /* (non-Javadoc) - * Returns the reference for a given tool or null if one is not - * found. - * - * @param tool - * @return ToolReference - */ - private ToolReference getToolReference(ITool tool) { - // See if the receiver has a reference to the tool - ToolReference ref = null; - if (tool == null) return ref; - Iterator iter = getLocalToolReferences().listIterator(); - while (iter.hasNext()) { - ToolReference temp = (ToolReference)iter.next(); - if (temp.references(tool)) { - ref = temp; - break; - } - } - return ref; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTools() - */ - public ITool[] getTools() { - Vector toolArray = new Vector(); - addToolsToArray(toolArray); - return (ITool[]) toolArray.toArray(new ITool[toolArray.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#hasMakeCommandOverride() - */ - public boolean hasOverridenMakeCommand() { - // We answer true if the make command or the flags are different - return ((makeCommand != null && !makeCommand.equals(parent.getMakeCommand())) - || (makeArguments != null && !makeArguments.equals(parent.getMakeArguments()))); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#isAbstract() - */ - public boolean isAbstract() { - return isAbstract; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#isDirty() - */ - public boolean isDirty() { - // If I need saving, just say yes - if (isDirty) { - return true; - } - - // Iterate over the configurations and ask them if they need saving - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - if (((IConfigurationV2)iter.next()).isDirty()) { - return true; - } - } - - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#isTestTarget() - */ - public boolean isTestTarget() { - return isTest; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#needsRebuild() - */ - public boolean needsRebuild(){ - // Iterate over the configurations and ask them if they need saving - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - if (((IConfigurationV2)iter.next()).needsRebuild()) { - return true; - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#removeConfiguration(java.lang.String) - */ - public void removeConfiguration(String id) { - // Remove the specified configuration from the list and map - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - IConfigurationV2 config = (IConfigurationV2)iter.next(); - if (config.getId().equals(id)) { - getConfigurationList().remove(config); - getConfigurationMap().remove(id); - isDirty = true; - break; - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#resetMakeCommand() - */ - public void resetMakeCommand() { - // Flag target as dirty if the reset actually changes something - if (makeCommand != null) { - setDirty(true); - } - makeCommand = null; - makeArguments = null; - } - - /** - * - */ - public void resolveReferences() { - if (!resolved) { - resolved = true; - IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); - // parent - String parentId = element.getAttribute(PARENT); - if (parentId != null) { - parent = ManagedBuildManager.getTarget(null, parentId); - // should resolve before calling methods on it - ((Target)parent).resolveReferences(); - // copy over the parents configs - IConfigurationV2[] parentConfigs = parent.getConfigurations(); - for (int i = 0; i < parentConfigs.length; ++i) - addConfiguration(parentConfigs[i]); - } - - // call resolve references on any children - Iterator toolIter = getToolList().iterator(); - while (toolIter.hasNext()) { - Tool current = (Tool)toolIter.next(); - current.resolveReferences(); - } - Iterator refIter = getLocalToolReferences().iterator(); - while (refIter.hasNext()) { - ToolReference current = (ToolReference)refIter.next(); - current.resolveReferences(); - } - Iterator configIter = getConfigurationList().iterator(); - while (configIter.hasNext()) { - ConfigurationV2 current = (ConfigurationV2)configIter.next(); - current.resolveReferences(); - } - } - } - - /** - * Persist receiver to project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - element.setAttribute(ID, getId()); - element.setAttribute(NAME, getName()); - if (parent != null) - element.setAttribute(PARENT, parent.getId()); - element.setAttribute(IS_ABSTRACT, isAbstract ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ - element.setAttribute(ARTIFACT_NAME, getArtifactName()); - if (extension != null) { - element.setAttribute(EXTENSION, extension); - } - element.setAttribute(IS_TEST, isTest ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ - - if (makeCommand != null) { - element.setAttribute(MAKE_COMMAND, makeCommand); - } else { - // Make sure we use the default - } - - if (makeArguments != null) { - element.setAttribute(MAKE_ARGS, makeArguments); - } - if (errorParserIds != null) { - element.setAttribute(ERROR_PARSERS, errorParserIds); - } - - // Serialize the configuration settings - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - ConfigurationV2 config = (ConfigurationV2) iter.next(); - Element configElement = doc.createElement(IConfigurationV2.CONFIGURATION_ELEMENT_NAME); - element.appendChild(configElement); - config.serialize(doc, configElement); - } - - // I am clean now - isDirty = false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#setArtifactExtension(java.lang.String) - */ - public void setArtifactExtension(String extension) { - if (extension != null) { - this.extension = extension; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITarget#setArtifactName(java.lang.String) - */ - public void setArtifactName(String name) { - if (name != null) { - artifactName = name; - setRebuildState(true); - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - // Override the dirty flag here - this.isDirty = isDirty; - // and in the configurations - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - IConfigurationV2 config = (IConfigurationV2)iter.next(); - config.setDirty(isDirty); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#setErrorParserIds() - */ - public void setErrorParserIds(String ids) { - if (ids == null) return; - String currentIds = getErrorParserIds(); - if (currentIds == null || !(currentIds.equals(ids))) { - errorParserIds = ids; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#setMakeArguments(java.lang.String) - */ - public void setMakeArguments(String makeArgs) { - if (makeArgs != null && !getMakeArguments().equals(makeArgs)) { - makeArguments = makeArgs; - setRebuildState(true); - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#setMakeCommand(java.lang.String) - */ - public void setMakeCommand(String command) { - if (command != null && !getMakeCommand().equals(command)) { - makeCommand = command; - setRebuildState(true); - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#setRebuildState(boolean) - */ - public void setRebuildState(boolean rebuild) { - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - ((IConfigurationV2)iter.next()).setRebuildState(rebuild); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#updateOwner(org.eclipse.core.resources.IResource) - */ - public void updateOwner(IResource resource) { - if (!resource.equals(owner)) { - // Set the owner correctly - owner = resource; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#convertToProjectType() - */ - public void convertToProjectType(String managedBuildRevision) { - // Create a ProjectType + Configuration + Toolchain + Builder + TargetPlatform - // from the Target - - // The "parent" needs to have been converted already. - // Do it now if necessary. - ProjectType parentProj = null; - if (parent != null) { - parentProj = parent.getCreatedProjectType(); - if (parentProj == null) { - parent.convertToProjectType(managedBuildRevision); - parentProj = parent.getCreatedProjectType(); - } - } - ProjectType projectType = new ProjectType(parentProj, getId(), getName(), managedBuildRevision); - createdProjectType = projectType; - // Set the project type attributes - projectType.setIsAbstract(isAbstract); - projectType.setIsTest(isTest); - // Add children - // Add configurations (Configuration -> ToolChain -> Builder -> TargetPlatform) - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - IConfigurationV2 configV2 = (IConfigurationV2)iter.next(); - if (configV2.getCreatedConfig() != null) continue; - // The new config's superClass needs to be the - // Configuration created from the ConfigurationV2 parent... - IConfiguration configSuperClass = null; - IConfigurationV2 parentV2 = configV2.getParent(); - if (parentV2 != null) { - configSuperClass = parentV2.getCreatedConfig(); - } - String id = configV2.getId(); - String name = configV2.getName(); - IConfiguration config = projectType.createConfiguration(configSuperClass, id, name); - configV2.setCreatedConfig(config); - // Set the configuration attributes - config.setArtifactName(getArtifactName()); - config.setArtifactExtension(getArtifactExtension()); - config.setCleanCommand(getCleanCommand()); - config.setErrorParserIds(getErrorParserIds()); - // Create the Tool-chain - String subId; - String subName; - subId = id + ".toolchain"; //$NON-NLS-1$ - subName = name + ".toolchain"; //$NON-NLS-1$ - IToolChain toolChain = config.createToolChain(null, subId, subName, true); - // Set the tool chain attributes - toolChain.setIsAbstract(isAbstract); - toolChain.setOSList(getTargetOSList()); - toolChain.setArchList(getTargetArchList()); - // In target element had a scannerInfoCollector element here which - // is now replaced with scanner config discovery profile id. - // Using the default per project profile for managed make - if(scannerInfoCollectorId != null && scannerInfoCollectorId.equals("org.eclipse.cdt.managedbuilder.internal.scannerconfig.DefaultGCCScannerInfoCollector")) //$NON-NLS-1$ - toolChain.setScannerConfigDiscoveryProfileId(ManagedBuildCPathEntryContainer.MM_PP_DISCOVERY_PROFILE_ID); - // Create the Builder - subId = id + ".builder"; //$NON-NLS-1$ - subName = name + ".builder"; //$NON-NLS-1$ - IBuilder builder = toolChain.createBuilder(null, subId, subName, true); - // Set the builder attributes - builder.setIsAbstract(isAbstract); - builder.setCommand(getMakeCommand()); - builder.setArguments(getMakeArguments()); - IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); - if (element instanceof DefaultManagedConfigElement) { - ((Builder)builder).setBuildFileGeneratorElement(((DefaultManagedConfigElement)element).getConfigurationElement()); - } - // Create the TargetPlatform - subId = id + ".targetplatform"; //$NON-NLS-1$ - subName = name + ".targetplatform"; //$NON-NLS-1$ - ITargetPlatform targetPlatform = toolChain.createTargetPlatform(null, subId, subName, true); - // Set the target platform attributes - targetPlatform.setIsAbstract(isAbstract); - targetPlatform.setOSList(getTargetOSList()); - targetPlatform.setArchList(getTargetArchList()); - targetPlatform.setBinaryParserList(new String[]{getBinaryParserId()}); // Older projects will always have only one binary parser set. - - // Handle ConfigurationV2 children (ToolReference) - // The tools references fetched here are strictly local to the configuration, - // so additional work is required to fetch the tool references from the target - IToolReference[] configToolRefs = configV2.getToolReferences(); - // Add the "local" tool references (they are direct children of the target and - // its parent targets) - Vector targetToolRefs = new Vector(); - addTargetToolReferences(targetToolRefs); - IToolReference[] toolRefs; - if (targetToolRefs.size() > 0) { - toolRefs = new IToolReference[targetToolRefs.size() + configToolRefs.length]; - int i; - for (i = 0; i < configToolRefs.length; ++i) { - toolRefs[i] = configToolRefs[i]; - } - Iterator localToolRefIter = targetToolRefs.iterator(); - while (localToolRefIter.hasNext()) { - toolRefs[i++] = (IToolReference)localToolRefIter.next(); - } - } else { - toolRefs = configToolRefs; - } - for (int i = 0; i < toolRefs.length; ++i) { - IToolReference toolRef = toolRefs[i]; - subId = id + "." + toolRef.getId(); //$NON-NLS-1$ - // The ToolReference's Tool becomes the newTool's SuperClass - ITool newTool = toolChain.createTool(toolRef.getTool(), subId, toolRef.getName(), true); - // Set the tool attributes - newTool.setToolCommand(toolRef.getRawToolCommand()); - newTool.setOutputPrefix(toolRef.getRawOutputPrefix()); - newTool.setOutputFlag(toolRef.getRawOutputFlag()); - newTool.setOutputsAttribute(toolRef.getRawOutputExtensions()); - // Handle ToolReference children (OptionReference) - Iterator optRefIter = toolRef.getOptionReferenceList().listIterator(); - while (optRefIter.hasNext()) { - OptionReference optRef = (OptionReference)optRefIter.next(); - subId = id + "." + optRef.getId(); //$NON-NLS-1$ - IOption newOption = newTool.createOption(optRef.getOption(), subId, optRef.getName(), true); - // Set the option attributes - newOption.setValue(optRef.getValue()); - newOption.setValueType(optRef.getValueType()); - ((Option)newOption).setWasOptRef(true); - } - } - - // Process the tools in the configuration, adding them to the toolchain - // Tools for a configuration are stored in the enclosing target, so getting - // the tools for the configuration ultimately gets them from the enclosing target - ITool[] configTools = configV2.getTools(); - for (int i = 0; i < configTools.length; ++i) { - ITool tool = configTools[i]; - // If tool references encountered, they have already been processed, above, - // so ignore them now - if (!(tool instanceof ToolReference)) { - // See if the toolchain already has a tool with a SuperClass that has an id - // equal to the tool that we are considering adding to the toolchain; if so, - // don't add it - // This case arises when we have added a tool to the toolchain because - // we processed a ToolReference (above) that references this tool - // The original tool referenced in the ToolReference becomes the SuperClass - // of the tool that is created because of the ToolReference - boolean found = false; - ITool[] tools = toolChain.getTools(); - ITool currentTool; - ITool supercurrentTool; - for (int j = 0; j < tools.length; ++j) { - currentTool = tools[j]; - supercurrentTool = currentTool.getSuperClass(); - if (supercurrentTool != null) { - if (supercurrentTool.getId() == tool.getId()) { - found = true; - // If this tool was already added to the toolchain because of a - // ToolReference, then we disconnent this redundant - // tool from the target by setting the parent to null - ((Tool)tool).setToolParent(null); - break; - } - } - } - - if (!found) - // This tool is not in the toolchain yet, so add it to the toolchain - ((ToolChain)toolChain).addTool((Tool)tool); - - } - } - // Normalize the outputextensions list by adding an empty string for each tool - // which did not have an explicit output file extension specified - ((ToolChain)toolChain).normalizeOutputExtensions(); - } - } - - /* - * A target element may contain toolReference elements. These get applied to all of the configurations - * of the target. The method adds the list of this target's local tool references to the passed in vector. - */ - public void addTargetToolReferences(Vector toolRefs) { - toolRefs.addAll(getLocalToolReferences()); - if (parent != null) { - Target targetParent = (Target)parent; - targetParent.addTargetToolReferences(toolRefs); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITarget#getCreatedProjectType() - */ - public ProjectType getCreatedProjectType() { - return createdProjectType; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if ( version == null) { - if ( getParent() != null) { - return getParent().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } - -} +/******************************************************************************* + * Copyright (c) 2003, 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.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IConfigurationV2; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.ITarget; +import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.IToolReference; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +public class Target extends BuildObject implements ITarget { + private static final String EMPTY_STRING = new String(); + private static final IConfigurationV2[] emptyConfigs = new IConfigurationV2[0]; + private String artifactName; + private String binaryParserId; + private String cleanCommand; + private List configList; + private Map configMap; + private String defaultExtension; + private Map depCalculatorsMap; + private String errorParserIds; + private String extension; + private boolean isAbstract = false; + private boolean isDirty = false; + private boolean isTest = false; + private String makeArguments; + private String makeCommand; + private IResource owner; + private ITarget parent; + private boolean resolved = true; + private List targetArchList; + private List targetOSList; + private List toolList; + private Map toolMap; + private List toolReferences; + private ProjectType createdProjectType; + private String scannerInfoCollectorId; + + /** + * This constructor is called to create a target defined by an extension point in + * a plugin manifest file. + * + * @param element + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public Target(IManagedConfigElement element, String managedBuildRevision) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + + // id + setId(element.getAttribute(ID)); + + // managedBuildRevision + setManagedBuildRevision(managedBuildRevision); + + // hook me up + ManagedBuildManager.addExtensionTarget(this); + + // Get the target name + setName(element.getAttribute(NAME)); + + // Get the name of the build artifact associated with target (usually + // in the plugin specification). + artifactName = element.getAttribute(ARTIFACT_NAME); + + // Get the ID of the binary parser + binaryParserId = element.getAttribute(BINARY_PARSER); + + // Get the semicolon separated list of IDs of the error parsers + errorParserIds = element.getAttribute(ERROR_PARSERS); + + // Get the default extension + defaultExtension = element.getAttribute(DEFAULT_EXTENSION); + + // isAbstract + isAbstract = ("true".equals(element.getAttribute(IS_ABSTRACT))); //$NON-NLS-1$ + + // Is this a test target + isTest = ("true".equals(element.getAttribute(IS_TEST))); //$NON-NLS-1$ + + // Get the clean command + cleanCommand = element.getAttribute(CLEAN_COMMAND); + + // Get the make command + makeCommand = element.getAttribute(MAKE_COMMAND); + + // Get the make arguments + makeArguments = element.getAttribute(MAKE_ARGS); + + // Get scannerInfoCollectorId + scannerInfoCollectorId = element.getAttribute(SCANNER_INFO_COLLECTOR_ID); + + // Get the comma-separated list of valid OS + String os = element.getAttribute(OS_LIST); + if (os != null) { + targetOSList = new ArrayList(); + String[] osTokens = os.split(","); //$NON-NLS-1$ + for (int i = 0; i < osTokens.length; ++i) { + targetOSList.add(osTokens[i].trim()); + } + } + + // Get the comma-separated list of valid Architectures + String arch = element.getAttribute(ARCH_LIST); + if (arch != null) { + targetArchList = new ArrayList(); + String[] archTokens = arch.split(","); //$NON-NLS-1$ + for (int j = 0; j < archTokens.length; ++j) { + targetArchList.add(archTokens[j].trim()); + } + } + + // Load any tool references we might have + IManagedConfigElement[] toolRefs = element.getChildren(IConfigurationV2.TOOLREF_ELEMENT_NAME); + for (int k = 0; k < toolRefs.length; ++k) { + new ToolReference(this, toolRefs[k]); + } + // Then load any tools defined for the target + IManagedConfigElement[] tools = element.getChildren(ITool.TOOL_ELEMENT_NAME); + for (int m = 0; m < tools.length; ++m) { + ITool newTool = new Tool(this, tools[m], managedBuildRevision); + // Add this tool to the target, as this is not done in the constructor + this.addTool(newTool); + } + // Then load the configurations which may have tool references + IManagedConfigElement[] configs = element.getChildren(IConfigurationV2.CONFIGURATION_ELEMENT_NAME); + for (int n = 0; n < configs.length; ++n) { + new ConfigurationV2(this, configs[n]); + } + } + + /* (non-Javadoc) + * Set the resource that owns the target. + * + * @param owner + */ + protected Target(IResource owner) { + this.owner = owner; + } + + /** + * Create a copy of the target specified in the argument, + * that is owned by the owned by the specified resource. + * + * @param owner + * @param parent + */ + public Target(IResource owner, ITarget parent) { + // Make the owner of the target the project resource + this(owner); + + // Copy the parent's identity + this.parent = parent; + int id = ManagedBuildManager.getRandomNumber(); + setId(owner.getName() + "." + parent.getId() + "." + id); //$NON-NLS-1$ //$NON-NLS-2$ + setName(parent.getName()); + + setManagedBuildRevision(parent.getManagedBuildRevision()); + + setArtifactName(parent.getArtifactName()); + this.binaryParserId = parent.getBinaryParserId(); + this.errorParserIds = parent.getErrorParserIds(); + this.defaultExtension = parent.getArtifactExtension(); + this.isTest = parent.isTestTarget(); + this.cleanCommand = parent.getCleanCommand(); + this.scannerInfoCollectorId = ((Target)parent).scannerInfoCollectorId; + + // Hook me up + IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(owner); + buildInfo.addTarget(this); + } + + /** + * Create target from project file. + * + * @param buildInfo + * @param element + */ + public Target(ManagedBuildInfo buildInfo, Element element) { + this(buildInfo.getOwner()); + + // id + setId(element.getAttribute(ID)); + + // hook me up + buildInfo.addTarget(this); + + // name + setName(element.getAttribute(NAME)); + + // Get the name of the build artifact associated with target (should + // contain what the user entered in the UI). + artifactName = element.getAttribute(ARTIFACT_NAME); + + // Get the overridden extension + if (element.hasAttribute(EXTENSION)) { + extension = element.getAttribute(EXTENSION); + } + + // parent + String parentId = element.getAttribute(PARENT); + if (parentId != null) + parent = ManagedBuildManager.getTarget(null, parentId); + + // isAbstract + if ("true".equals(element.getAttribute(IS_ABSTRACT))) //$NON-NLS-1$ + isAbstract = true; + + // Is this a test target + isTest = ("true".equals(element.getAttribute(IS_TEST))); //$NON-NLS-1$ + + // Get the clean command + if (element.hasAttribute(CLEAN_COMMAND)) { + cleanCommand = element.getAttribute(CLEAN_COMMAND); + } + + // Get the semicolon separated list of IDs of the error parsers + if (element.hasAttribute(ERROR_PARSERS)) { + errorParserIds = element.getAttribute(ERROR_PARSERS); + } + + // Get the make command and arguments + if (element.hasAttribute(MAKE_COMMAND)) { + makeCommand = element.getAttribute(MAKE_COMMAND); + } + if(element.hasAttribute(MAKE_ARGS)) { + makeArguments = element.getAttribute(MAKE_ARGS); + } + + Node child = element.getFirstChild(); + while (child != null) { + if (child.getNodeName().equals(IConfigurationV2.CONFIGURATION_ELEMENT_NAME)) { + new ConfigurationV2(this, (Element)child); + } + child = child.getNextSibling(); + } + } + + /** + * @param configuration + */ + public void addConfiguration(IConfigurationV2 configuration) { + getConfigurationList().add(configuration); + getConfigurationMap().put(configuration.getId(), configuration); + } + + /** + * Adds a tool specification to the receiver. This tool is defined + * only for the receiver, and cannot be shared by other targets. + * + * @param tool + */ + public void addTool(ITool tool) { + getToolList().add(tool); + getToolMap().put(tool.getId(), tool); + } + + /** + * Adds a tool reference to the receiver. + * + * @param toolRef + */ + public void addToolReference(ToolReference toolRef) { + getLocalToolReferences().add(toolRef); + } + + + /* (non-Javadoc) + * Tail-recursion method that creates a lits of tools and tool reference + * walking the receiver's parent hierarchy. + * + * @param toolArray + */ + private void addToolsToArray(Vector toolArray) { + if (parent != null) { + ((Target)parent).addToolsToArray(toolArray); + } + + // Add the tools from out own list + toolArray.addAll(getToolList()); + + // Add local tool references + toolArray.addAll(getLocalToolReferences()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#createConfiguration(org.eclipse.cdt.core.build.managed.IConfigurationV2) + */ + public IConfigurationV2 createConfiguration(IConfigurationV2 parent, String id) { + isDirty = true; + return new ConfigurationV2(this, parent, id); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#createConfiguration() + */ + public IConfigurationV2 createConfiguration(String id) { + return new ConfigurationV2(this, id); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getArtifactExtension() + */ + public String getArtifactExtension() { + // Has the user changed the extension for this target + if (extension != null) { + return extension; + } + // If not, then go through the default extension lookup + if (defaultExtension == null) { + // Ask my parent first + if (parent != null) { + return parent.getArtifactExtension(); + } else { + return EMPTY_STRING; + } + } else { + return defaultExtension; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#getArtifactName() + */ + public String getArtifactName() { + if (artifactName == null) { + // If I have a parent, ask it + if (parent != null) { + return parent.getArtifactName(); + } else { + // I'm it and this is not good! + return EMPTY_STRING; + } + } else { + return artifactName; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getBinaryParserId() + */ + public String getBinaryParserId() { + if (binaryParserId == null) { + // If I have a parent, ask it + if (parent != null) { + return parent.getBinaryParserId(); + } else { + // I'm it and this is not good! + return EMPTY_STRING; + } + } + return binaryParserId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#getCleanCommand() + */ + public String getCleanCommand() { + // Return the command used to remove files + if (cleanCommand == null) { + if (parent != null) { + return parent.getCleanCommand(); + } else { + // User forgot to specify it. Guess based on OS. + if (Platform.getOS().equals(Platform.OS_WIN32)) { + return new String("del"); //$NON-NLS-1$ + } else { + return new String("rm"); //$NON-NLS-1$ + } + } + } else { + // This was spec'd in the manifest + return cleanCommand; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#getConfiguration() + */ + public IConfigurationV2 getConfiguration(String id) { + return (IConfigurationV2)getConfigurationMap().get(id); + } + + /* (non-Javadoc) + * Safe accessor for the list of configurations. + * + * @return List containing the configurations + */ + private List getConfigurationList() { + if (configList == null) { + configList = new ArrayList(); + } + return configList; + } + + /* (non-Javadoc) + * Safe accessor for the map of configuration ids to configurations + * + * @return + */ + private Map getConfigurationMap() { + if (configMap == null) { + configMap = new HashMap(); + } + return configMap; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getConfigurations() + */ + public IConfigurationV2[] getConfigurations() { + return (IConfigurationV2[])getConfigurationList().toArray(new IConfigurationV2[getConfigurationList().size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getDefaultExtension() + */ + public String getDefaultExtension() { + return defaultExtension == null ? EMPTY_STRING : defaultExtension; + } + + private Map getDepCalcMap() { + if (depCalculatorsMap == null) { + depCalculatorsMap = new HashMap(); + } + return depCalculatorsMap; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getErrorParserIds() + */ + public String getErrorParserIds() { + if (errorParserIds == null) { + // If I have a parent, ask it + if (parent != null) { + return parent.getErrorParserIds(); + } + } + return errorParserIds; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getErrorParserList() + */ + public String[] getErrorParserList() { + String parserIDs = getErrorParserIds(); + String[] errorParsers = null; + if (parserIDs != null) { + // Check for an empty string + if (parserIDs.length() == 0) { + errorParsers = new String[0]; + } else { + StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ + List list = new ArrayList(tok.countTokens()); + while (tok.hasMoreElements()) { + list.add(tok.nextToken()); + } + String[] strArr = {""}; //$NON-NLS-1$ + errorParsers = (String[]) list.toArray(strArr); + } + } else { + // If no error parsers are specified by the target, the default is + // all error parsers + errorParsers = CCorePlugin.getDefault().getAllErrorParsersIDs(); + } + return errorParsers; + } + + /* (non-javadoc) + * A safe accesor method. It answers the tool reference list in the + * receiver. + * + * @return List + */ + protected List getLocalToolReferences() { + if (toolReferences == null) { + toolReferences = new ArrayList(); + } + return toolReferences; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getMakeArguments() + */ + public String getMakeArguments() { + if (makeArguments == null) { + // See if it is defined in my parent + if (parent != null) { + return parent.getMakeArguments(); + } else { + // No parent and no user setting + return new String(""); //$NON-NLS-1$ + } + } + return makeArguments; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#getMakeCommand() + */ + public String getMakeCommand() { + // Return the name of the make utility + if (makeCommand == null) { + // If I have a parent, ask it + if (parent != null) { + return parent.getMakeCommand(); + } else { + // The user has forgotten to specify a command in the plugin manifest + return new String("make"); //$NON-NLS-1$ + } + } else { + return makeCommand; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getName() + */ + public String getName() { + // If I am unnamed, see if I can inherit one from my parent + if (name == null) { + if (parent != null) { + return parent.getName(); + } else { + return new String(""); //$NON-NLS-1$ + } + } else { + return name; + } + } + + /* (non-javadoc) + * + * @param tool + * @return List + */ + protected List getOptionReferences(ITool tool) { + List references = new ArrayList(); + + // Get all the option references I add for this tool + ToolReference toolRef = getToolReference(tool); + if (toolRef != null) { + references.addAll(toolRef.getOptionReferenceList()); + } + + // See if there is anything that my parents add that I don't + if (parent != null) { + List temp = ((Target)parent).getOptionReferences(tool); + Iterator iter = temp.listIterator(); + while (iter.hasNext()) { + OptionReference ref = (OptionReference) iter.next(); + if (!references.contains(ref)) { + references.add(ref); + } + } + } + + return references; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getOwner() + */ + public IResource getOwner() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getParent() + */ + public ITarget getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTargetArchList() + */ + public String[] getTargetArchList() { + if (targetArchList == null) { + // Ask parent for its list + if (parent != null) { + return parent.getTargetArchList(); + } else { + // I have no parent and no defined list + return new String[] {"all"}; //$NON-NLS-1$ + } + } + return (String[]) targetArchList.toArray(new String[targetArchList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTargetOSList() + */ + public String[] getTargetOSList() { + if (targetOSList == null) { + // Ask parent for its list + if (parent != null) { + return parent.getTargetOSList(); + } else { + // I have no parent and no defined filter list + return new String[] {"all"}; //$NON-NLS-1$ + } + } + return (String[]) targetOSList.toArray(new String[targetOSList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTool(java.lang.String) + */ + public ITool getTool(String id) { + ITool result = null; + + // See if receiver has it in list + result = (ITool) getToolMap().get(id); + + // If not, check if parent has it + if (result == null && parent != null) { + result = ((Target)parent).getTool(id); + } + + // If not defined in parents, check if defined at all + if (result == null) { + result = ManagedBuildManager.getExtensionTool(id); + } + + return result; + } + + /* (non-Javadoc) + * A safe accessor method for the list of tools maintained by the + * target + * + */ + private List getToolList() { + if (toolList == null) { + toolList = new ArrayList(); + } + return toolList; + } + + /* (non-Javadoc) + * A safe accessor for the tool map + * + */ + private Map getToolMap() { + if (toolMap == null) { + toolMap = new HashMap(); + } + return toolMap; + } + + /* (non-Javadoc) + * Returns the reference for a given tool or null if one is not + * found. + * + * @param tool + * @return ToolReference + */ + private ToolReference getToolReference(ITool tool) { + // See if the receiver has a reference to the tool + ToolReference ref = null; + if (tool == null) return ref; + Iterator iter = getLocalToolReferences().listIterator(); + while (iter.hasNext()) { + ToolReference temp = (ToolReference)iter.next(); + if (temp.references(tool)) { + ref = temp; + break; + } + } + return ref; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getTools() + */ + public ITool[] getTools() { + Vector toolArray = new Vector(); + addToolsToArray(toolArray); + return (ITool[]) toolArray.toArray(new ITool[toolArray.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#hasMakeCommandOverride() + */ + public boolean hasOverridenMakeCommand() { + // We answer true if the make command or the flags are different + return ((makeCommand != null && !makeCommand.equals(parent.getMakeCommand())) + || (makeArguments != null && !makeArguments.equals(parent.getMakeArguments()))); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#isAbstract() + */ + public boolean isAbstract() { + return isAbstract; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#isDirty() + */ + public boolean isDirty() { + // If I need saving, just say yes + if (isDirty) { + return true; + } + + // Iterate over the configurations and ask them if they need saving + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + if (((IConfigurationV2)iter.next()).isDirty()) { + return true; + } + } + + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#isTestTarget() + */ + public boolean isTestTarget() { + return isTest; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#needsRebuild() + */ + public boolean needsRebuild(){ + // Iterate over the configurations and ask them if they need saving + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + if (((IConfigurationV2)iter.next()).needsRebuild()) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#removeConfiguration(java.lang.String) + */ + public void removeConfiguration(String id) { + // Remove the specified configuration from the list and map + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + IConfigurationV2 config = (IConfigurationV2)iter.next(); + if (config.getId().equals(id)) { + getConfigurationList().remove(config); + getConfigurationMap().remove(id); + isDirty = true; + break; + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#resetMakeCommand() + */ + public void resetMakeCommand() { + // Flag target as dirty if the reset actually changes something + if (makeCommand != null) { + setDirty(true); + } + makeCommand = null; + makeArguments = null; + } + + /** + * + */ + public void resolveReferences() { + if (!resolved) { + resolved = true; + IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); + // parent + String parentId = element.getAttribute(PARENT); + if (parentId != null) { + parent = ManagedBuildManager.getTarget(null, parentId); + // should resolve before calling methods on it + ((Target)parent).resolveReferences(); + // copy over the parents configs + IConfigurationV2[] parentConfigs = parent.getConfigurations(); + for (int i = 0; i < parentConfigs.length; ++i) + addConfiguration(parentConfigs[i]); + } + + // call resolve references on any children + Iterator toolIter = getToolList().iterator(); + while (toolIter.hasNext()) { + Tool current = (Tool)toolIter.next(); + current.resolveReferences(); + } + Iterator refIter = getLocalToolReferences().iterator(); + while (refIter.hasNext()) { + ToolReference current = (ToolReference)refIter.next(); + current.resolveReferences(); + } + Iterator configIter = getConfigurationList().iterator(); + while (configIter.hasNext()) { + ConfigurationV2 current = (ConfigurationV2)configIter.next(); + current.resolveReferences(); + } + } + } + + /** + * Persist receiver to project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + element.setAttribute(ID, getId()); + element.setAttribute(NAME, getName()); + if (parent != null) + element.setAttribute(PARENT, parent.getId()); + element.setAttribute(IS_ABSTRACT, isAbstract ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ + element.setAttribute(ARTIFACT_NAME, getArtifactName()); + if (extension != null) { + element.setAttribute(EXTENSION, extension); + } + element.setAttribute(IS_TEST, isTest ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ + + if (makeCommand != null) { + element.setAttribute(MAKE_COMMAND, makeCommand); + } else { + // Make sure we use the default + } + + if (makeArguments != null) { + element.setAttribute(MAKE_ARGS, makeArguments); + } + if (errorParserIds != null) { + element.setAttribute(ERROR_PARSERS, errorParserIds); + } + + // Serialize the configuration settings + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + ConfigurationV2 config = (ConfigurationV2) iter.next(); + Element configElement = doc.createElement(IConfigurationV2.CONFIGURATION_ELEMENT_NAME); + element.appendChild(configElement); + config.serialize(doc, configElement); + } + + // I am clean now + isDirty = false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#setArtifactExtension(java.lang.String) + */ + public void setArtifactExtension(String extension) { + if (extension != null) { + this.extension = extension; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITarget#setArtifactName(java.lang.String) + */ + public void setArtifactName(String name) { + if (name != null) { + artifactName = name; + setRebuildState(true); + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + // Override the dirty flag here + this.isDirty = isDirty; + // and in the configurations + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + IConfigurationV2 config = (IConfigurationV2)iter.next(); + config.setDirty(isDirty); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#setErrorParserIds() + */ + public void setErrorParserIds(String ids) { + if (ids == null) return; + String currentIds = getErrorParserIds(); + if (currentIds == null || !(currentIds.equals(ids))) { + errorParserIds = ids; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#setMakeArguments(java.lang.String) + */ + public void setMakeArguments(String makeArgs) { + if (makeArgs != null && !getMakeArguments().equals(makeArgs)) { + makeArguments = makeArgs; + setRebuildState(true); + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#setMakeCommand(java.lang.String) + */ + public void setMakeCommand(String command) { + if (command != null && !getMakeCommand().equals(command)) { + makeCommand = command; + setRebuildState(true); + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#setRebuildState(boolean) + */ + public void setRebuildState(boolean rebuild) { + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + ((IConfigurationV2)iter.next()).setRebuildState(rebuild); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#updateOwner(org.eclipse.core.resources.IResource) + */ + public void updateOwner(IResource resource) { + if (!resource.equals(owner)) { + // Set the owner correctly + owner = resource; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#convertToProjectType() + */ + public void convertToProjectType(String managedBuildRevision) { + // Create a ProjectType + Configuration + Toolchain + Builder + TargetPlatform + // from the Target + + // The "parent" needs to have been converted already. + // Do it now if necessary. + ProjectType parentProj = null; + if (parent != null) { + parentProj = parent.getCreatedProjectType(); + if (parentProj == null) { + parent.convertToProjectType(managedBuildRevision); + parentProj = parent.getCreatedProjectType(); + } + } + ProjectType projectType = new ProjectType(parentProj, getId(), getName(), managedBuildRevision); + createdProjectType = projectType; + // Set the project type attributes + projectType.setIsAbstract(isAbstract); + projectType.setIsTest(isTest); + // Add children + // Add configurations (Configuration -> ToolChain -> Builder -> TargetPlatform) + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + IConfigurationV2 configV2 = (IConfigurationV2)iter.next(); + if (configV2.getCreatedConfig() != null) continue; + // The new config's superClass needs to be the + // Configuration created from the ConfigurationV2 parent... + IConfiguration configSuperClass = null; + IConfigurationV2 parentV2 = configV2.getParent(); + if (parentV2 != null) { + configSuperClass = parentV2.getCreatedConfig(); + } + String id = configV2.getId(); + String name = configV2.getName(); + IConfiguration config = projectType.createConfiguration(configSuperClass, id, name); + configV2.setCreatedConfig(config); + // Set the configuration attributes + config.setArtifactName(getArtifactName()); + config.setArtifactExtension(getArtifactExtension()); + config.setCleanCommand(getCleanCommand()); + config.setErrorParserIds(getErrorParserIds()); + // Create the Tool-chain + String subId; + String subName; + subId = id + ".toolchain"; //$NON-NLS-1$ + subName = name + ".toolchain"; //$NON-NLS-1$ + IToolChain toolChain = config.createToolChain(null, subId, subName, true); + // Set the tool chain attributes + toolChain.setIsAbstract(isAbstract); + toolChain.setOSList(getTargetOSList()); + toolChain.setArchList(getTargetArchList()); + // In target element had a scannerInfoCollector element here which + // is now replaced with scanner config discovery profile id. + // Using the default per project profile for managed make + if(scannerInfoCollectorId != null && scannerInfoCollectorId.equals("org.eclipse.cdt.managedbuilder.internal.scannerconfig.DefaultGCCScannerInfoCollector")) //$NON-NLS-1$ + toolChain.setScannerConfigDiscoveryProfileId(ManagedBuildCPathEntryContainer.MM_PP_DISCOVERY_PROFILE_ID); + // Create the Builder + subId = id + ".builder"; //$NON-NLS-1$ + subName = name + ".builder"; //$NON-NLS-1$ + IBuilder builder = toolChain.createBuilder(null, subId, subName, true); + // Set the builder attributes + builder.setIsAbstract(isAbstract); + builder.setCommand(getMakeCommand()); + builder.setArguments(getMakeArguments()); + IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); + if (element instanceof DefaultManagedConfigElement) { + ((Builder)builder).setBuildFileGeneratorElement(((DefaultManagedConfigElement)element).getConfigurationElement()); + } + // Create the TargetPlatform + subId = id + ".targetplatform"; //$NON-NLS-1$ + subName = name + ".targetplatform"; //$NON-NLS-1$ + ITargetPlatform targetPlatform = toolChain.createTargetPlatform(null, subId, subName, true); + // Set the target platform attributes + targetPlatform.setIsAbstract(isAbstract); + targetPlatform.setOSList(getTargetOSList()); + targetPlatform.setArchList(getTargetArchList()); + targetPlatform.setBinaryParserList(new String[]{getBinaryParserId()}); // Older projects will always have only one binary parser set. + + // Handle ConfigurationV2 children (ToolReference) + // The tools references fetched here are strictly local to the configuration, + // so additional work is required to fetch the tool references from the target + IToolReference[] configToolRefs = configV2.getToolReferences(); + // Add the "local" tool references (they are direct children of the target and + // its parent targets) + Vector targetToolRefs = new Vector(); + addTargetToolReferences(targetToolRefs); + IToolReference[] toolRefs; + if (targetToolRefs.size() > 0) { + toolRefs = new IToolReference[targetToolRefs.size() + configToolRefs.length]; + int i; + for (i = 0; i < configToolRefs.length; ++i) { + toolRefs[i] = configToolRefs[i]; + } + Iterator localToolRefIter = targetToolRefs.iterator(); + while (localToolRefIter.hasNext()) { + toolRefs[i++] = (IToolReference)localToolRefIter.next(); + } + } else { + toolRefs = configToolRefs; + } + for (int i = 0; i < toolRefs.length; ++i) { + IToolReference toolRef = toolRefs[i]; + subId = id + "." + toolRef.getId(); //$NON-NLS-1$ + // The ToolReference's Tool becomes the newTool's SuperClass + ITool newTool = toolChain.createTool(toolRef.getTool(), subId, toolRef.getName(), true); + // Set the tool attributes + newTool.setToolCommand(toolRef.getRawToolCommand()); + newTool.setOutputPrefix(toolRef.getRawOutputPrefix()); + newTool.setOutputFlag(toolRef.getRawOutputFlag()); + newTool.setOutputsAttribute(toolRef.getRawOutputExtensions()); + // Handle ToolReference children (OptionReference) + Iterator optRefIter = toolRef.getOptionReferenceList().listIterator(); + while (optRefIter.hasNext()) { + OptionReference optRef = (OptionReference)optRefIter.next(); + subId = id + "." + optRef.getId(); //$NON-NLS-1$ + IOption newOption = newTool.createOption(optRef.getOption(), subId, optRef.getName(), true); + // Set the option attributes + newOption.setValue(optRef.getValue()); + newOption.setValueType(optRef.getValueType()); + ((Option)newOption).setWasOptRef(true); + } + } + + // Process the tools in the configuration, adding them to the toolchain + // Tools for a configuration are stored in the enclosing target, so getting + // the tools for the configuration ultimately gets them from the enclosing target + ITool[] configTools = configV2.getTools(); + for (int i = 0; i < configTools.length; ++i) { + ITool tool = configTools[i]; + // If tool references encountered, they have already been processed, above, + // so ignore them now + if (!(tool instanceof ToolReference)) { + // See if the toolchain already has a tool with a SuperClass that has an id + // equal to the tool that we are considering adding to the toolchain; if so, + // don't add it + // This case arises when we have added a tool to the toolchain because + // we processed a ToolReference (above) that references this tool + // The original tool referenced in the ToolReference becomes the SuperClass + // of the tool that is created because of the ToolReference + boolean found = false; + ITool[] tools = toolChain.getTools(); + ITool currentTool; + ITool supercurrentTool; + for (int j = 0; j < tools.length; ++j) { + currentTool = tools[j]; + supercurrentTool = currentTool.getSuperClass(); + if (supercurrentTool != null) { + if (supercurrentTool.getId() == tool.getId()) { + found = true; + // If this tool was already added to the toolchain because of a + // ToolReference, then we disconnent this redundant + // tool from the target by setting the parent to null + ((Tool)tool).setToolParent(null); + break; + } + } + } + + if (!found) + // This tool is not in the toolchain yet, so add it to the toolchain + ((ToolChain)toolChain).addTool((Tool)tool); + + } + } + // Normalize the outputextensions list by adding an empty string for each tool + // which did not have an explicit output file extension specified + ((ToolChain)toolChain).normalizeOutputExtensions(); + } + } + + /* + * A target element may contain toolReference elements. These get applied to all of the configurations + * of the target. The method adds the list of this target's local tool references to the passed in vector. + */ + public void addTargetToolReferences(Vector toolRefs) { + toolRefs.addAll(getLocalToolReferences()); + if (parent != null) { + Target targetParent = (Target)parent; + targetParent.addTargetToolReferences(toolRefs); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITarget#getCreatedProjectType() + */ + public ProjectType getCreatedProjectType() { + return createdProjectType; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if ( version == null) { + if ( getParent() != null) { + return getParent().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java index c2b0c270a4d..36c8dc24405 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java @@ -1,2825 +1,2825 @@ -/******************************************************************************* - * Copyright (c) 2003, 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.managedbuilder.internal.core; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.macros.BuildfileMacroSubstitutor; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ProjectScope; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.core.runtime.content.IContentTypeSettings; -import org.eclipse.core.runtime.preferences.IScopeContext; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Represents a tool that can be invoked during a build. - * Note that this class implements IOptionCategory to represent the top - * category. - */ -public class Tool extends HoldsOptions implements ITool, IOptionCategory { - - public static final String DEFAULT_PATTERN = "${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}"; //$NON-NLS-1$ - public static final String DEFAULT_CBS_PATTERN = "${COMMAND}"; //$NON-NLS-1$ - - private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ - //private static final IOptionCategory[] EMPTY_CATEGORIES = new IOptionCategory[0]; - //private static final IOption[] EMPTY_OPTIONS = new IOption[0]; - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - private static final String DEFAULT_ANNOUNCEMENT_PREFIX = "Tool.default.announcement"; //$NON-NLS-1$ - private static final String WHITESPACE = " "; //$NON-NLS-1$ - - private static final boolean resolvedDefault = true; - - // Superclass - // Note that superClass itself is defined in the base and that the methods - // getSuperClass() and setSuperClassInternal(), defined in Tool must be used to - // access it. This avoids widespread casts from IHoldsOptions to ITool. - private String superClassId; - // Parent and children - private IBuildObject parent; - private Vector inputTypeList; - private Map inputTypeMap; - private Vector outputTypeList; - private Map outputTypeMap; - private List envVarBuildPathList; - // Managed Build model attributes - private String unusedChildren; - private Boolean isAbstract; - private String command; - private List inputExtensions; - private List interfaceExtensions; - private Integer natureFilter; - private String outputExtensions; - private String outputFlag; - private String outputPrefix; - private String errorParserIds; - private String commandLinePattern; - private String versionsSupported; - private String convertToId; - private Boolean advancedInputCategory; - private Boolean customBuildStep; - private String announcement; - private IConfigurationElement commandLineGeneratorElement = null; - private IManagedCommandLineGenerator commandLineGenerator = null; - private IConfigurationElement dependencyGeneratorElement = null; - private IManagedDependencyGeneratorType dependencyGenerator = null; - private URL iconPathURL; - // Miscellaneous - private boolean isExtensionTool = false; - private boolean isDirty = false; - private boolean resolved = resolvedDefault; - private IConfigurationElement previousMbsVersionConversionElement = null; - private IConfigurationElement currentMbsVersionConversionElement = null; - - /* - * C O N S T R U C T O R S - */ - - /** - * Constructor to create a tool based on an element from the plugin - * manifest. - * - * @param element The element containing the information about the tool. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Tool(IManagedConfigElement element, String managedBuildRevision) { - // setup for resolving - super(false); - resolved = false; - - isExtensionTool = true; - - // Set the managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - loadFromManifest(element); - - // hook me up - ManagedBuildManager.addExtensionTool(this); - - // set up the category map - addOptionCategory(this); - - // Load children - IManagedConfigElement[] toolElements = element.getChildren(); - for (int l = 0; l < toolElements.length; ++l) { - IManagedConfigElement toolElement = toolElements[l]; - if (loadChild(toolElement)) { - // do nothing - } else if (toolElement.getName().equals(ITool.INPUT_TYPE)) { - InputType inputType = new InputType(this, toolElement); - addInputType(inputType); - } else if (toolElement.getName().equals(ITool.OUTPUT_TYPE)) { - OutputType outputType = new OutputType(this, toolElement); - addOutputType(outputType); - } else if (toolElement.getName().equals(IEnvVarBuildPath.BUILD_PATH_ELEMENT_NAME)){ - addEnvVarBuildPath(new EnvVarBuildPath(this,toolElement)); - } - } - } - - /** - * Constructor to create a new tool for a tool-chain based on the information - * defined in the plugin.xml manifest. - * - * @param parent The parent of this tool. This can be a ToolChain or a - * ResourceConfiguration. - * @param element The element containing the information about the tool. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Tool(IBuildObject parent, IManagedConfigElement element, String managedBuildRevision) { - this(element, managedBuildRevision); - this.parent = parent; - } - - /** - * This constructor is called to create a Tool whose attributes and children will be - * added by separate calls. - * - * @param ToolChain The parent of the tool, if any - * @param Tool The superClass, if any - * @param String The id for the new tool - * @param String The name for the new tool - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public Tool(ToolChain parent, ITool superClass, String Id, String name, boolean isExtensionElement) { - super(resolvedDefault); - this.parent = parent; - setSuperClassInternal(superClass); - setManagedBuildRevision(parent.getManagedBuildRevision()); - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - - setId(Id); - setName(name); - setVersion(getVersionFromId()); - - isExtensionTool = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionTool(this); - } else { - setDirty(true); - } - } - - /** - * This constructor is called to create a Tool whose attributes and children will be - * added by separate calls. - * - * @param ResourceConfiguration, The parent of the tool, if any - * @param Tool The superClass, if any - * @param String The id for the new tool - * @param String The name for the new tool - * @param boolean Indicates whether this is an extension element or a managed project element - */ - - public Tool(ResourceConfiguration parent, ITool superClass, String Id, String name, boolean isExtensionElement) { - super(resolvedDefault); - this.parent = parent; - setSuperClassInternal( superClass ); - setManagedBuildRevision(parent.getManagedBuildRevision()); - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - setId(Id); - setName(name); - setVersion(getVersionFromId()); - - isExtensionTool = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionTool(this); - } else { - setDirty(true); - } - } - - /** - * Create a Tool based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The IToolChain or IResourceConfiguration - * the tool will be added to. - * @param element The XML element that contains the tool settings. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Tool(IBuildObject parent, Element element, String managedBuildRevision) { - super(resolvedDefault); - this.parent = parent; - isExtensionTool = false; - - // Set the managedBuildRevsion - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromProject(element); - - // set up the category map - addOptionCategory(this); - - // Load children - NodeList toolElements = element.getChildNodes(); - for (int i = 0; i < toolElements.getLength(); ++i) { - Node toolElement = toolElements.item(i); - if (loadChild(toolElement)) { - // do nothing - } else if (toolElement.getNodeName().equals(ITool.INPUT_TYPE)) { - InputType inputType = new InputType(this, (Element)toolElement); - addInputType(inputType); - } else if (toolElement.getNodeName().equals(ITool.OUTPUT_TYPE)) { - OutputType outputType = new OutputType(this, (Element)toolElement); - addOutputType(outputType); - } - } - } - - /** - * Create a Tool based upon an existing tool. - * - * @param parent The IToolChain or IResourceConfiguration - * the tool will be added to. - * @param tool The existing tool to clone. - */ - public Tool(IBuildObject parent, ITool toolSuperClass, String Id, String name, Tool tool){ - super(resolvedDefault); - this.parent = parent; - if (toolSuperClass != null) { - setSuperClassInternal( toolSuperClass ); - } else { - setSuperClassInternal( tool.getSuperClass() ); - } - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - setId(Id); - setName(name); - - // Set the managedBuildRevision & the version - setManagedBuildRevision(tool.getManagedBuildRevision()); - setVersion(getVersionFromId()); - - isExtensionTool = false; - - // Copy the remaining attributes - if(tool.versionsSupported != null) { - versionsSupported = new String(tool.versionsSupported); - } - if(tool.convertToId != null) { - convertToId = new String(tool.convertToId); - } - if (tool.unusedChildren != null) { - unusedChildren = new String(tool.unusedChildren); - } - if (tool.errorParserIds != null) { - errorParserIds = new String(tool.errorParserIds); - } - if (tool.isAbstract != null) { - isAbstract = new Boolean(tool.isAbstract.booleanValue()); - } - if (tool.command != null) { - command = new String(tool.command); - } - if (tool.commandLinePattern != null) { - commandLinePattern = new String(tool.commandLinePattern); - } - if (tool.inputExtensions != null) { - inputExtensions = new ArrayList(tool.inputExtensions); - } - if (tool.interfaceExtensions != null) { - interfaceExtensions = new ArrayList(tool.interfaceExtensions); - } - if (tool.natureFilter != null) { - natureFilter = new Integer(tool.natureFilter.intValue()); - } - if (tool.outputExtensions != null) { - outputExtensions = new String(tool.outputExtensions); - } - if (tool.outputFlag != null) { - outputFlag = new String(tool.outputFlag); - } - if (tool.outputPrefix != null) { - outputPrefix = new String(tool.outputPrefix); - } - if (tool.advancedInputCategory != null) { - advancedInputCategory = new Boolean(tool.advancedInputCategory.booleanValue()); - } - if (tool.customBuildStep != null) { - customBuildStep = new Boolean(tool.customBuildStep.booleanValue()); - } - if (tool.announcement != null) { - announcement = new String(tool.announcement); - } - - commandLineGeneratorElement = tool.commandLineGeneratorElement; - commandLineGenerator = tool.commandLineGenerator; - dependencyGeneratorElement = tool.dependencyGeneratorElement; - dependencyGenerator = tool.dependencyGenerator; - - if(tool.envVarBuildPathList != null) - envVarBuildPathList = new ArrayList(tool.envVarBuildPathList); - - // Clone the children in superclass - super.copyChildren(tool); - // Clone the children - if (tool.inputTypeList != null) { - Iterator iter = tool.getInputTypeList().listIterator(); - while (iter.hasNext()) { - InputType inputType = (InputType) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (inputType.getSuperClass() != null) { - subId = inputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = inputType.getSuperClass().getName(); - } else { - subId = inputType.getId() + "." + nnn; //$NON-NLS-1$ - subName = inputType.getName(); - } - InputType newInputType = new InputType(this, subId, subName, inputType); - addInputType(newInputType); - } - } - if (tool.outputTypeList != null) { - Iterator iter = tool.getOutputTypeList().listIterator(); - while (iter.hasNext()) { - OutputType outputType = (OutputType) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (outputType.getSuperClass() != null) { - subId = outputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = outputType.getSuperClass().getName(); - } else { - subId = outputType.getId() + "." + nnn; //$NON-NLS-1$ - subName = outputType.getName(); - } - OutputType newOutputType = new OutputType(this, subId, subName, outputType); - addOutputType(newOutputType); - } - } - - // icon - if ( tool.iconPathURL != null ) { - iconPathURL = tool.iconPathURL; - } - - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Load the tool information from the XML element specified in the - * argument - * @param element An XML element containing the tool information - */ - protected void loadFromManifest(IManagedConfigElement element) { - // setup for resolving - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(ITool.ID)); - - // name - setName(element.getAttribute(ITool.NAME)); - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // Get the unused children, if any - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - - // Get the 'versionsSupported' attribute - versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); - - // Get the 'convertToId' attribute - convertToId = element.getAttribute(CONVERT_TO_ID); - - // isAbstract - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - - // Get the semicolon separated list of IDs of the error parsers - errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); - - // Get the nature filter - String nature = element.getAttribute(NATURE); - if (nature != null) { - if ("both".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_BOTH); - } else if ("cnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_C); - } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_CC); - } else { - natureFilter = new Integer(FILTER_BOTH); - } - } - - // Get the supported input file extensions - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - - // Get the interface (header file) extensions - String headers = element.getAttribute(INTERFACE_EXTS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInterfaceExtensionsList().add(tokenizer.nextElement()); - } - } - - // Get the output extension - outputExtensions = element.getAttribute(ITool.OUTPUTS); - - // Get the tool invocation command - command = element.getAttribute(ITool.COMMAND); - - // Get the flag to control output - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - - // Get the output prefix - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - - // Get command line pattern - commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); - - // Get advancedInputCategory - String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); - if (advInput != null){ - advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ - } - - // Get customBuildStep - String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); - if (cbs != null){ - customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ - } - - // Get the announcement text - announcement = element.getAttribute(ITool.ANNOUNCEMENT); - - // Store the configuration element IFF there is a command line generator defined - String commandLineGenerator = element.getAttribute(COMMAND_LINE_GENERATOR); - if (commandLineGenerator != null && element instanceof DefaultManagedConfigElement) { - commandLineGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // Store the configuration element IFF there is a dependency generator defined - String depGenerator = element.getAttribute(DEP_CALC_ID); - if (depGenerator != null && element instanceof DefaultManagedConfigElement) { - dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // icon - if ( element.getAttribute(IOptionCategory.ICON) != null && element instanceof DefaultManagedConfigElement) - { - String icon = element.getAttribute(IOptionCategory.ICON); - iconPathURL = ManagedBuildManager.getURLInBuildDefinitions( (DefaultManagedConfigElement)element, new Path(icon) ); - } - } - - /* (non-Javadoc) - * Initialize the tool information from the XML element - * specified in the argument - * - * @param element An XML element containing the tool information - */ - protected void loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - if( getParent() instanceof IResourceConfiguration ) { - IResourceConfiguration resConfig = (IResourceConfiguration) getParent(); - setSuperClassInternal( resConfig.getParent().getTool(superClassId) ); - } else { - setSuperClassInternal( ManagedBuildManager.getExtensionTool(superClassId) ); - } - - // Check for migration support - checkForMigrationSupport(); - - } - - // Get the unused children, if any - if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - } - - // isAbstract - if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - } - - // Get the 'versionSupported' attribute - if (element.hasAttribute(VERSIONS_SUPPORTED)) { - versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); - } - - // Get the 'convertToId' id - if (element.hasAttribute(CONVERT_TO_ID)) { - convertToId = element.getAttribute(CONVERT_TO_ID); - } - - // Get the semicolon separated list of IDs of the error parsers - if (element.hasAttribute(IToolChain.ERROR_PARSERS)) { - errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); - } - - // Get the nature filter - if (element.hasAttribute(NATURE)) { - String nature = element.getAttribute(NATURE); - if (nature != null) { - if ("both".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_BOTH); - } else if ("cnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_C); - } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_CC); - } else { - natureFilter = new Integer(FILTER_BOTH); - } - } - } - - // Get the supported input file extension - if (element.hasAttribute(ITool.SOURCES)) { - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // Get the interface (header file) extensions - if (element.hasAttribute(INTERFACE_EXTS)) { - String headers = element.getAttribute(INTERFACE_EXTS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInterfaceExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // Get the output extension - if (element.hasAttribute(ITool.OUTPUTS)) { - outputExtensions = element.getAttribute(ITool.OUTPUTS); - } - - // Get the tool invocation command - if (element.hasAttribute(ITool.COMMAND)) { - command = element.getAttribute(ITool.COMMAND); - } - - // Get the flag to control output - if (element.hasAttribute(ITool.OUTPUT_FLAG)) { - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - } - - // Get the output prefix - if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - } - - // Get command line pattern - if( element.hasAttribute( ITool.COMMAND_LINE_PATTERN ) ) { - commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); - } - - // advancedInputCategory - if (element.hasAttribute(ITool.ADVANCED_INPUT_CATEGORY)) { - String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); - if (advInput != null){ - advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ - } - } - - // customBuildStep - if (element.hasAttribute(ITool.CUSTOM_BUILD_STEP)) { - String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); - if (cbs != null){ - customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ - } - } - - // Get the announcement text - if (element.hasAttribute(ITool.ANNOUNCEMENT)) { - announcement = element.getAttribute(ITool.ANNOUNCEMENT); - } - - // icon - was saved as URL in string form - if (element.hasAttribute(IOptionCategory.ICON)) { - String iconPath = element.getAttribute(IOptionCategory.ICON); - try { - iconPathURL = new URL(iconPath); - } catch (MalformedURLException e) { - // Print a warning - ManagedBuildManager.OutputIconError(iconPath); - iconPathURL = null; - } - } - } - - /** - * Persist the tool to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - try { - if (getSuperClass() != null) - element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); - - // id - element.setAttribute(IBuildObject.ID, id); - - // name - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - // unused children - if (unusedChildren != null) { - element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); - } - - // isAbstract - if (isAbstract != null) { - element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); - } - - // versionsSupported - if (versionsSupported != null) { - element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); - } - - // convertToId - if (convertToId != null) { - element.setAttribute(CONVERT_TO_ID, convertToId); - } - - // error parsers - if (errorParserIds != null) { - element.setAttribute(IToolChain.ERROR_PARSERS, errorParserIds); - } - - // nature filter - if (natureFilter != null) { - String nature; - if (natureFilter.intValue() == FILTER_C) { - nature = "cnature"; //$NON-NLS-1$ - } else if (natureFilter.intValue() == FILTER_CC) { - nature = "ccnature"; //$NON-NLS-1$ - } else { - nature = "both"; //$NON-NLS-1$ - } - element.setAttribute(NATURE, nature); - } - - // input file extensions - if (getInputExtensionsList().size() > 0) { - String inputs; - List list = getInputExtensionsList(); - Iterator iter = list.listIterator(); - inputs = (String)iter.next(); - while (iter.hasNext()) { - inputs += DEFAULT_SEPARATOR; - inputs += iter.next(); - } - element.setAttribute(ITool.SOURCES, inputs); - } - - // interface (header file) extensions - if (getInterfaceExtensionsList().size() > 0) { - String headers; - List list = getInterfaceExtensionsList(); - Iterator iter = list.listIterator(); - headers = (String)iter.next(); - while (iter.hasNext()) { - headers += DEFAULT_SEPARATOR; - headers += iter.next(); - } - element.setAttribute(INTERFACE_EXTS, headers); - } - - // output extension - if (outputExtensions != null) { - element.setAttribute(ITool.OUTPUTS, outputExtensions); - } - - // command - if (command != null) { - element.setAttribute(ITool.COMMAND, command); - } - - // flag to control output - if (outputFlag != null) { - element.setAttribute(ITool.OUTPUT_FLAG, outputFlag); - } - - // output prefix - if (outputPrefix != null) { - element.setAttribute(ITool.OUTPUT_PREFIX, outputPrefix); - } - - // command line pattern - if (commandLinePattern != null) { - element.setAttribute(ITool.COMMAND_LINE_PATTERN, commandLinePattern); - } - - // advancedInputCategory - if (advancedInputCategory != null) { - element.setAttribute(ITool.ADVANCED_INPUT_CATEGORY, advancedInputCategory.toString()); - } - - // customBuildStep - if (customBuildStep != null) { - element.setAttribute(ITool.CUSTOM_BUILD_STEP, customBuildStep.toString()); - } - - // announcement text - if (announcement != null) { - element.setAttribute(ITool.ANNOUNCEMENT, announcement); - } - - // Serialize elements from my super class - super.serialize(doc, element); - - // Serialize my children - Iterator iter; - List typeElements = getInputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - InputType type = (InputType) iter.next(); - Element typeElement = doc.createElement(INPUT_TYPE); - element.appendChild(typeElement); - type.serialize(doc, typeElement); - } - typeElements = getOutputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - OutputType type = (OutputType) iter.next(); - Element typeElement = doc.createElement(OUTPUT_TYPE); - element.appendChild(typeElement); - type.serialize(doc, typeElement); - } - - // Note: command line generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (commandLineGeneratorElement != null) { - // TODO: issue warning? - } - - // Note: dependency generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (dependencyGeneratorElement != null) { - // TODO: issue warning? - } - - if (iconPathURL != null) { - // Save as URL in string form - element.setAttribute(IOptionCategory.ICON, iconPathURL.toString()); - } - - // I am clean now - isDirty = false; - } catch (Exception e) { - // TODO: issue an error message - } - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getParent() - */ - public IBuildObject getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) - */ - public void setToolParent(IBuildObject newParent) { - this.parent = newParent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() - */ - public IOptionCategory getTopOptionCategory() { - return this; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#createInputType(IInputType, String, String, boolean) - */ - public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { - InputType type = new InputType(this, superClass, Id, name, isExtensionElement); - addInputType(type); - setDirty(true); - return type; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#removeInputType(IInputType) - */ - public void removeInputType(IInputType type) { - getInputTypeList().remove(type); - getInputTypeMap().remove(type.getId()); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputTypes() - */ - public IInputType[] getInputTypes() { - IInputType[] types = null; - // Merge our input types with our superclass' input types. - if (getSuperClass() != null) { - types = getSuperClass().getInputTypes(); - } - // Our options take precedence. - Vector ourTypes = getInputTypeList(); - if (types != null) { - for (int i = 0; i < ourTypes.size(); i++) { - IInputType ourType = (IInputType)ourTypes.get(i); - int j; - for (j = 0; j < types.length; j++) { - if (ourType.getSuperClass() != null && - ourType.getSuperClass().getId().equals(types[j].getId())) { - types[j] = ourType; - break; - } - } - // No Match? Add it. - if (j == types.length) { - IInputType[] newTypes = new IInputType[types.length + 1]; - for (int k = 0; k < types.length; k++) { - newTypes[k] = types[k]; - } - newTypes[j] = ourType; - types = newTypes; - } - } - } else { - types = (IInputType[])ourTypes.toArray(new IInputType[ourTypes.size()]); - } - return types; - } - - private boolean hasInputTypes() { - Vector ourTypes = getInputTypeList(); - if (ourTypes.size() > 0) return true; - return false; - } - - public IInputType getInputTypeById(String id) { - IInputType type = (IInputType)getInputTypeMap().get(id); - if (type == null) { - if (getSuperClass() != null) { - return getSuperClass().getInputTypeById(id); - } - } - return type; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#createOutputType(IOutputType, String, String, boolean) - */ - public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { - OutputType type = new OutputType(this, superClass, Id, name, isExtensionElement); - addOutputType(type); - setDirty(true); - return type; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOutputType(IOutputType) - */ - public void removeOutputType(IOutputType type) { - getOutputTypeList().remove(type); - getOutputTypeMap().remove(type.getId()); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputTypes() - */ - public IOutputType[] getOutputTypes() { - IOutputType[] types = null; - // Merge our output types with our superclass' output types. - if (getSuperClass() != null) { - types = getSuperClass().getOutputTypes(); - } - // Our options take precedence. - Vector ourTypes = getOutputTypeList(); - if (types != null) { - for (int i = 0; i < ourTypes.size(); i++) { - IOutputType ourType = (IOutputType)ourTypes.get(i); - int j; - for (j = 0; j < types.length; j++) { - if (ourType.getSuperClass() != null && - ourType.getSuperClass().getId().equals(types[j].getId())) { - types[j] = ourType; - break; - } - } - // No Match? Add it. - if (j == types.length) { - IOutputType[] newTypes = new IOutputType[types.length + 1]; - for (int k = 0; k < types.length; k++) { - newTypes[k] = types[k]; - } - newTypes[j] = ourType; - types = newTypes; - } - } - } else { - types = (IOutputType[])ourTypes.toArray(new IOutputType[ourTypes.size()]); - } - return types; - } - - private boolean hasOutputTypes() { - Vector ourTypes = getOutputTypeList(); - if (ourTypes.size() > 0) return true; - return false; - } - - public IOutputType getPrimaryOutputType() { - IOutputType type = null; - IOutputType[] types = getOutputTypes(); - if (types != null && types.length > 0) { - for (int i=0; i 0) return exts[0]; - } - // If none, use the input extensions specified for the Tool (backwards compatibility) - List extsList = getInputExtensionsAttribute(); - // Use the first entry in the list - if (extsList != null && extsList.size() > 0) return (String)extsList.get(0); - return EMPTY_STRING; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getPrimaryInputExtensions() - */ - public String[] getPrimaryInputExtensions() { - IInputType type = getPrimaryInputType(); - if (type != null) { - String[] exts = type.getSourceExtensions(this); - // Use the first entry in the list - if (exts.length > 0) return exts; - } - // If none, use the input extensions specified for the Tool (backwards compatibility) - List extsList = getInputExtensionsAttribute(); - // Use the first entry in the list - if (extsList != null && extsList.size() > 0) { - return (String[])extsList.toArray(new String[extsList.size()]); - } - return EMPTY_STRING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllInputExtensions() - */ - public String[] getAllInputExtensions() { - IInputType[] types = getInputTypes(); - if (types != null && types.length > 0) { - List allExts = new ArrayList(); - for (int i=0; i 0) { - return (String[])allExts.toArray(new String[allExts.size()]); - } - } - // If none, use the input extensions specified for the Tool (backwards compatibility) - List extsList = getInputExtensionsAttribute(); - if (extsList != null && extsList.size() > 0) { - return (String[])extsList.toArray(new String[extsList.size()]); - } - return EMPTY_STRING_ARRAY; - } - - public IInputType getPrimaryInputType() { - IInputType type = null; - IInputType[] types = getInputTypes(); - if (types != null && types.length > 0) { - for (int i=0; i 0) { - for (int i=0; i 0) { - allDeps.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - return (IPath[])allDeps.toArray(new IPath[allDeps.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getAdditionalResources() - */ - public IPath[] getAdditionalResources() { - List allRes = new ArrayList(); - IInputType[] types = getInputTypes(); - for (int i=0; i 0) { - allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - return (IPath[])allRes.toArray(new IPath[allRes.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllDependencyExtensions() - */ - public String[] getAllDependencyExtensions() { - IInputType[] types = getInputTypes(); - if (types != null && types.length > 0) { - List allExts = new ArrayList(); - for (int i=0; i 0) { - return (String[])allExts.toArray(new String[allExts.size()]); - } - } - // If none, use the header extensions specified for the Tool (backwards compatibility) - List extsList = getHeaderExtensionsAttribute(); - if (extsList != null && extsList.size() > 0) { - return (String[])extsList.toArray(new String[extsList.size()]); - } - return EMPTY_STRING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getInterfaceExtension() - * @deprecated - */ - public List getInterfaceExtensions() { - return getHeaderExtensionsAttribute(); - } - - private List getHeaderExtensionsAttribute() { - if (interfaceExtensions == null || interfaceExtensions.size() == 0) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return ((Tool)getSuperClass()).getHeaderExtensionsAttribute(); - } else { - if (interfaceExtensions == null) { - interfaceExtensions = new ArrayList(); - } - } - } - return interfaceExtensions; - } - - private List getInterfaceExtensionsList() { - if (interfaceExtensions == null) { - interfaceExtensions = new ArrayList(); - } - return interfaceExtensions; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOutputFlag() - */ - public String getOutputFlag() { - if (outputFlag == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getOutputFlag(); - } else { - return EMPTY_STRING; - } - } - return outputFlag; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOutputPrefix() - */ - public String getOutputPrefix() { - // Get the outputPrefix from an OutputType, if any. - IOutputType type = null; - IOutputType[] types = getOutputTypes(); - if (types != null && types.length > 0) { - for (int i=0; i 0) { - List allExts = new ArrayList(); - for (int i=0; i 0) { - return (String[])allExts.toArray(new String[allExts.size()]); - } - } - // If none, use the outputs specified for the Tool (backwards compatibility) - String[] extsList = getOutputsAttribute(); - if (extsList != null && extsList.length > 0) { - return extsList; - } - return EMPTY_STRING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() - * @deprecated - */ - public String[] getOutputExtensions() { - return getOutputsAttribute(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputsAttribute() - */ - public String[] getOutputsAttribute() { - // TODO: Why is this treated differently than inputExtensions? - if (outputExtensions == null) { - if (getSuperClass() != null) { - return getSuperClass().getOutputsAttribute(); - } else { - return null; - } - } - return outputExtensions.split(DEFAULT_SEPARATOR); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOutputExtension(java.lang.String) - */ - public String getOutputExtension(String inputExtension) { - // Search thru the output-types to find one that has a primary input type with this extension - IOutputType[] types = getOutputTypes(); - int i; - if (types != null) { - for (i=0; i 0) { - return exts[0]; - } - } - } - // Does any input type produce this extension? - if (getInputType(inputExtension) != null) { - // Return the first extension of the primary output type - IOutputType outType = getPrimaryOutputType(); - String[] exts = outType.getOutputExtensions(this); - if (exts != null && exts.length > 0) { - return exts[0]; - } - } - } - // If no OutputTypes specified, examine the list of input extensions - String[] inputExts = getAllInputExtensions(); - for (i=0; i 0) { - for (int i=0; i 0) { - sb.append(boolCmd); - } - break; - - case IOption.ENUMERATED : - String enumVal = option.getEnumCommand(option.getSelectedEnum()); - if (enumVal.length() > 0) { - sb.append(enumVal); - } - break; - - case IOption.STRING : - String strCmd = option.getCommand(); - String val = option.getStringValue(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - if (val.length() > 0 - && (val = MacroResolver.resolveToString(val, macroSubstitutor)).length() > 0) { - sb.append( evaluateCommand( strCmd, val ) ); - } - break; - - case IOption.STRING_LIST : - String listCmd = option.getCommand(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - String[] list = MacroResolver.resolveStringListValues(option.getStringListValue(), macroSubstitutor, true); - if(list != null){ - for (int j = 0; j < list.length; j++) { - String temp = list[j]; - if(temp.length() > 0) - sb.append( evaluateCommand( listCmd, temp ) + WHITE_SPACE ); - } - } - break; - - case IOption.INCLUDE_PATH : - String incCmd = option.getCommand(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - String[] paths = MacroResolver.resolveStringListValues(option.getIncludePaths(), macroSubstitutor, true); - if(paths != null){ - for (int j = 0; j < paths.length; j++) { - String temp = paths[j]; - if(temp.length() > 0) - sb.append( evaluateCommand( incCmd, temp ) + WHITE_SPACE); - } - } - break; - - case IOption.PREPROCESSOR_SYMBOLS : - String defCmd = option.getCommand(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - String[] symbols = MacroResolver.resolveStringListValues(option.getDefinedSymbols(), macroSubstitutor, true); - if(symbols != null){ - for (int j = 0; j < symbols.length; j++) { - String temp = symbols[j]; - if(temp.length() > 0) - sb.append( evaluateCommand( defCmd, temp ) + WHITE_SPACE); - } - } - break; - - default : - break; - } - - if (sb.toString().trim().length() > 0) - flags.add(sb.toString().trim()); - } catch (BuildMacroException e) { - - } - } - } - String[] f = new String[ flags.size() ]; - return (String[])flags.toArray( f ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - IMacroSubstitutor macroSubstitutor = new BuildfileMacroSubstitutor(null,EMPTY_STRING,WHITE_SPACE); - return getToolCommandFlags(inputFileLocation, outputFileLocation, macroSubstitutor ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - // Get all of the optionList - StringBuffer buf = new StringBuffer(); - String[] flags = getToolCommandFlags(inputFileLocation,outputFileLocation); - for (int index = 0; index < flags.length; index++) { - if( flags[ index ] != null ) { - buf.append( flags[ index ] + WHITE_SPACE ); - } - } - - return buf.toString().trim(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) - */ - public boolean isHeaderFile(String ext) { - if (ext == null) { - return false; - } - String[] exts = getAllDependencyExtensions(); - for (int i=0; i 0) { - return false; - } - // 3. If the assignToOption attribute is specified, no - if (it.getAssignToOptionId() != null && it.getAssignToOptionId().length() > 0) { - return false; - } - // Else, yes - return true; - } - // If no InputTypes, check the inputExtensions attribute - if (!hasInputTypes()) { - return getInputExtensionsAttribute().contains(extension); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#isInputFileType(java.lang.String) - */ - public boolean isInputFileType(String extension) { - if (extension == null) { - return false; - } - IInputType it = getInputType(extension); - if (it != null) { - return true; - } - // If no InputTypes, check the inputExtensions attribute - if (!hasInputTypes()) { - return getInputExtensionsAttribute().contains(extension); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) - */ - public boolean producesFileType(String extension) { - if (extension == null) { - return false; - } - // Check the output-types first - if (getOutputType(extension) != null) { - return true; - } - // If there are no OutputTypes, check the attribute - if (!hasOutputTypes()) { - String[] exts = getOutputsAttribute(); - if (exts != null) { - for (int i = 0; i < exts.length; i++) { - if (exts[i].equals(extension)) - return true; - } - } - } - return false; - } - -/* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() - */ - public boolean isExtensionElement() { - return isExtensionTool; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isDirty() - */ - public boolean isDirty() { - // This shouldn't be called for an extension tool - if (isExtensionTool) return false; - - // If I need saving, just say yes - if (isDirty) return true; - - // Check my children - List typeElements = getInputTypeList(); - Iterator iter = typeElements.listIterator(); - while (iter.hasNext()) { - InputType type = (InputType) iter.next(); - if (type.isDirty()) return true; - } - typeElements = getOutputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - OutputType type = (OutputType) iter.next(); - if (type.isDirty()) return true; - } - - // Otherwise see if any options need saving - if (super.isDirty()) { - return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to options - super.setDirty(isDirty); - // Propagate "false" to the children - if (!isDirty) { - List typeElements = getInputTypeList(); - Iterator iter = typeElements.listIterator(); - while (iter.hasNext()) { - InputType type = (InputType) iter.next(); - type.setDirty(false); - } - typeElements = getOutputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - OutputType type = (OutputType) iter.next(); - type.setDirty(false); - } - } - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references - */ - public void resolveReferences() { - if (!resolved) { - resolved = true; - // Resolve superClass - if (superClassId != null && superClassId.length() > 0) { - setSuperClassInternal( ManagedBuildManager.getExtensionTool(superClassId) ); - if (getSuperClass() == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "tool", //$NON-NLS-1$ - getId()); - } - } - // Resolve HoldsOptions - super.resolveReferences(); - // Call resolveReferences on our children - Iterator typeIter = getInputTypeList().iterator(); - while (typeIter.hasNext()) { - InputType current = (InputType)typeIter.next(); - current.resolveReferences(); - } - typeIter = getOutputTypeList().iterator(); - while (typeIter.hasNext()) { - OutputType current = (OutputType)typeIter.next(); - current.resolveReferences(); - } - } - } - - /** - * Look for ${VALUE} in the command string - */ - public String evaluateCommand( String command, String values ) { - final int DOLLAR_VALUE_LENGTH = 8; - - if( command == null ) return values.trim(); - - String ret = command; - boolean found = false; - int start = 0; - int index; - int len; - while ((index = ret.indexOf( "${", start )) >= 0 && //$NON-NLS-1$ - (len = ret.length()) >= index + DOLLAR_VALUE_LENGTH) { - start = index; - index = index+2; - int ch = ret.charAt(index); - if ( ch == 'v' || ch == 'V' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'a' || ch == 'A' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'l' || ch == 'L' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'u' || ch == 'U' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'e' || ch == 'E' ) { - index++; - ch = ret.charAt(index); - if ( ch == '}' ) { - String temp = ""; //$NON-NLS-1$ - index++; - found = true; - if (start > 0) { - temp = ret.substring(0, start); - } - temp = temp.concat(values.trim()); - if (len > index) { - start = temp.length(); - ret = temp.concat(ret.substring(index)); - index = start; - } - else { - ret = temp; - break; - } - } - } - } - } - } - } - start = index; - } - if (found) - return ret.trim(); - return (new String(command + values)).trim(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() - */ - public String getConvertToId() { - if (convertToId == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getConvertToId(); - } else { - return EMPTY_STRING; - } - } - return convertToId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) - */ - public void setConvertToId(String convertToId) { - if (convertToId == null && this.convertToId == null) return; - if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { - this.convertToId = convertToId; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() - */ - public String getVersionsSupported() { - if (versionsSupported == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getVersionsSupported(); - } else { - return EMPTY_STRING; - } - } - return versionsSupported; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) - */ - public void setVersionsSupported(String versionsSupported) { - if (versionsSupported == null && this.versionsSupported == null) return; - if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { - this.versionsSupported = versionsSupported; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getEnvVarBuildPaths() - */ - public IEnvVarBuildPath[] getEnvVarBuildPaths(){ - if(envVarBuildPathList != null){ - return (IEnvVarBuildPath[])envVarBuildPathList.toArray( - new IEnvVarBuildPath[envVarBuildPathList.size()]); - } - else if(getSuperClass() != null) - return getSuperClass().getEnvVarBuildPaths(); - return null; - } - - private void addEnvVarBuildPath(IEnvVarBuildPath path){ - if(path == null) - return; - if(envVarBuildPathList == null) - envVarBuildPathList = new ArrayList(); - - envVarBuildPathList.add(path); - } - - /* - * This function checks for migration support for the tool, while - * loading. If migration support is needed, looks for the available - * converters and stores them. - */ - - public void checkForMigrationSupport() { - - boolean isExists = false; - - if ( getSuperClass() == null) { - // If 'getSuperClass()' is null, then there is no tool available in - // plugin manifest file with the same 'id' & version. - // Look for the 'versionsSupported' attribute - String high = (String) ManagedBuildManager.getExtensionToolMap() - .lastKey(); - - SortedMap subMap = null; - if (superClassId.compareTo(high) <= 0) { - subMap = ManagedBuildManager.getExtensionToolMap().subMap( - superClassId, high + "\0"); //$NON-NLS-1$ - } else { - // It means there are no entries in the map for the given id. - // make the project is invalid - - // It means there are no entries in the map for the given id. - // make the project is invalid - // If the parent is a tool chain - IToolChain parent = (IToolChain) getParent(); - IConfiguration parentConfig = parent.getParent(); - IManagedProject managedProject = parentConfig - .getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - return; - } - - // for each element in the 'subMap', - // check the 'versionsSupported' attribute whether the given - // builder version is supported - - String baseId = ManagedBuildManager - .getIdFromIdAndVersion(superClassId); - String version = ManagedBuildManager - .getVersionFromIdAndVersion(superClassId); - - ITool[] toolElements = (ITool[]) subMap.values().toArray(); - - for (int i = 0; i < toolElements.length; i++) { - ITool toolElement = toolElements[i]; - - if (ManagedBuildManager.getIdFromIdAndVersion( - toolElement.getId()).compareTo(baseId) > 0) - break; - - // First check if both base ids are equal - if (ManagedBuildManager.getIdFromIdAndVersion( - toolElement.getId()).equals(baseId)) { - - // Check if 'versionsSupported' attribute is available' - String versionsSupported = toolElement - .getVersionsSupported(); - - if ((versionsSupported != null) - && (!versionsSupported.equals(""))) { //$NON-NLS-1$ - String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ - - for (int j = 0; j < tmpVersions.length; j++) { - if (new PluginVersionIdentifier(version) - .equals(new PluginVersionIdentifier( - tmpVersions[j]))) { - // version is supported. - // Do the automatic conversion without - // prompting the user. - // Get the supported version - String supportedVersion = ManagedBuildManager - .getVersionFromIdAndVersion(toolElement - .getId()); - setId(ManagedBuildManager - .getIdFromIdAndVersion(getId()) - + "_" + supportedVersion); //$NON-NLS-1$ - - // If control comes here means that superClass - // is null. - // So, set the superClass to this tool element - setSuperClassInternal(toolElement); - superClassId = getSuperClass().getId(); - isExists = true; - break; - } - } - if (isExists) - break; // break the outer for loop if 'isExists' is - // true - } - } - } - } - - if (getSuperClass() != null) { - // If 'getSuperClass()' is not null, look for 'convertToId' - // attribute in plugin - // manifest file for this tool. - String convertToId = getSuperClass().getConvertToId(); - if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ - // It means there is no 'convertToId' attribute available and - // the version is still actively - // supported by the tool integrator. So do nothing, just return - return; - } else { - // Incase the 'convertToId' attribute is available, - // it means that Tool integrator currently does not support this - // version of tool. - // Look for the converters available for this tool version. - - getConverter(convertToId); - } - - } else { - // make the project is invalid - // - // It means there are no entries in the map for the given id. - // make the project is invalid - IToolChain parent = (IToolChain) getParent(); - IConfiguration parentConfig = parent.getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - } - return; - } - - - private void getConverter(String convertToId) { - - String fromId = null; - String toId = null; - - // Get the Converter Extension Point - IExtensionPoint extensionPoint = Platform.getExtensionRegistry() - .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ - "projectConverter"); //$NON-NLS-1$ - if (extensionPoint != null) { - // Get the extensions - IExtension[] extensions = extensionPoint.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - // Get the configuration elements of each extension - IConfigurationElement[] configElements = extensions[i] - .getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - - IConfigurationElement element = configElements[j]; - - if (element.getName().equals("converter")) { //$NON-NLS-1$ - - fromId = element.getAttribute("fromId"); //$NON-NLS-1$ - toId = element.getAttribute("toId"); //$NON-NLS-1$ - // Check whether the current converter can be used for - // the selected tool - - if (fromId.equals(getSuperClass().getId()) - && toId.equals(convertToId)) { - // If it matches - String mbsVersion = element - .getAttribute("mbsVersion"); //$NON-NLS-1$ - PluginVersionIdentifier currentMbsVersion = ManagedBuildManager - .getBuildInfoVersion(); - - // set the converter element based on the MbsVersion - if (currentMbsVersion - .isGreaterThan(new PluginVersionIdentifier( - mbsVersion))) { - previousMbsVersionConversionElement = element; - } else { - currentMbsVersionConversionElement = element; - } - return; - } - } - } - } - } - - // If control comes here, it means 'Tool Integrator' specified - // 'convertToId' attribute in toolchain definition file, but - // has not provided any converter. - // So, make the project is invalid - - // It means there are no entries in the map for the given id. - // make the project is invalid - IToolChain parent = (IToolChain) getParent(); - IConfiguration parentConfig = parent.getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - return; - } - - public IConfigurationElement getPreviousMbsVersionConversionElement() { - return previousMbsVersionConversionElement; - } - - public IConfigurationElement getCurrentMbsVersionConversionElement() { - return currentMbsVersionConversionElement; - } - - public IProject getProject() { - IBuildObject toolParent = getParent(); - if (toolParent != null) { - if (toolParent instanceof IToolChain) { - IConfiguration config = ((IToolChain)toolParent).getParent(); - if (config == null) return null; - return (IProject)config.getOwner(); - } else if (toolParent instanceof IResourceConfiguration) { - return (IProject)((IResourceConfiguration)toolParent).getOwner(); - } - } - return null; - } - - public String[] getContentTypeFileSpecs (IContentType type) { - String[] globalSpecs = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - IContentTypeSettings settings = null; - IProject project = getProject(); - if (project != null) { - IScopeContext projectScope = new ProjectScope(project); - try { - settings = type.getSettings(projectScope); - } catch (Exception e) {} - if (settings != null) { - String[] specs = settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - if (specs.length > 0) { - int total = globalSpecs.length + specs.length; - String[] projSpecs = new String[total]; - int i=0; - for (int j=0; jTool based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The IToolChain or IResourceConfiguration + * the tool will be added to. + * @param element The XML element that contains the tool settings. + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public Tool(IBuildObject parent, Element element, String managedBuildRevision) { + super(resolvedDefault); + this.parent = parent; + isExtensionTool = false; + + // Set the managedBuildRevsion + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromProject(element); + + // set up the category map + addOptionCategory(this); + + // Load children + NodeList toolElements = element.getChildNodes(); + for (int i = 0; i < toolElements.getLength(); ++i) { + Node toolElement = toolElements.item(i); + if (loadChild(toolElement)) { + // do nothing + } else if (toolElement.getNodeName().equals(ITool.INPUT_TYPE)) { + InputType inputType = new InputType(this, (Element)toolElement); + addInputType(inputType); + } else if (toolElement.getNodeName().equals(ITool.OUTPUT_TYPE)) { + OutputType outputType = new OutputType(this, (Element)toolElement); + addOutputType(outputType); + } + } + } + + /** + * Create a Tool based upon an existing tool. + * + * @param parent The IToolChain or IResourceConfiguration + * the tool will be added to. + * @param tool The existing tool to clone. + */ + public Tool(IBuildObject parent, ITool toolSuperClass, String Id, String name, Tool tool){ + super(resolvedDefault); + this.parent = parent; + if (toolSuperClass != null) { + setSuperClassInternal( toolSuperClass ); + } else { + setSuperClassInternal( tool.getSuperClass() ); + } + if (getSuperClass() != null) { + superClassId = getSuperClass().getId(); + } + setId(Id); + setName(name); + + // Set the managedBuildRevision & the version + setManagedBuildRevision(tool.getManagedBuildRevision()); + setVersion(getVersionFromId()); + + isExtensionTool = false; + + // Copy the remaining attributes + if(tool.versionsSupported != null) { + versionsSupported = new String(tool.versionsSupported); + } + if(tool.convertToId != null) { + convertToId = new String(tool.convertToId); + } + if (tool.unusedChildren != null) { + unusedChildren = new String(tool.unusedChildren); + } + if (tool.errorParserIds != null) { + errorParserIds = new String(tool.errorParserIds); + } + if (tool.isAbstract != null) { + isAbstract = new Boolean(tool.isAbstract.booleanValue()); + } + if (tool.command != null) { + command = new String(tool.command); + } + if (tool.commandLinePattern != null) { + commandLinePattern = new String(tool.commandLinePattern); + } + if (tool.inputExtensions != null) { + inputExtensions = new ArrayList(tool.inputExtensions); + } + if (tool.interfaceExtensions != null) { + interfaceExtensions = new ArrayList(tool.interfaceExtensions); + } + if (tool.natureFilter != null) { + natureFilter = new Integer(tool.natureFilter.intValue()); + } + if (tool.outputExtensions != null) { + outputExtensions = new String(tool.outputExtensions); + } + if (tool.outputFlag != null) { + outputFlag = new String(tool.outputFlag); + } + if (tool.outputPrefix != null) { + outputPrefix = new String(tool.outputPrefix); + } + if (tool.advancedInputCategory != null) { + advancedInputCategory = new Boolean(tool.advancedInputCategory.booleanValue()); + } + if (tool.customBuildStep != null) { + customBuildStep = new Boolean(tool.customBuildStep.booleanValue()); + } + if (tool.announcement != null) { + announcement = new String(tool.announcement); + } + + commandLineGeneratorElement = tool.commandLineGeneratorElement; + commandLineGenerator = tool.commandLineGenerator; + dependencyGeneratorElement = tool.dependencyGeneratorElement; + dependencyGenerator = tool.dependencyGenerator; + + if(tool.envVarBuildPathList != null) + envVarBuildPathList = new ArrayList(tool.envVarBuildPathList); + + // Clone the children in superclass + super.copyChildren(tool); + // Clone the children + if (tool.inputTypeList != null) { + Iterator iter = tool.getInputTypeList().listIterator(); + while (iter.hasNext()) { + InputType inputType = (InputType) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (inputType.getSuperClass() != null) { + subId = inputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = inputType.getSuperClass().getName(); + } else { + subId = inputType.getId() + "." + nnn; //$NON-NLS-1$ + subName = inputType.getName(); + } + InputType newInputType = new InputType(this, subId, subName, inputType); + addInputType(newInputType); + } + } + if (tool.outputTypeList != null) { + Iterator iter = tool.getOutputTypeList().listIterator(); + while (iter.hasNext()) { + OutputType outputType = (OutputType) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (outputType.getSuperClass() != null) { + subId = outputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = outputType.getSuperClass().getName(); + } else { + subId = outputType.getId() + "." + nnn; //$NON-NLS-1$ + subName = outputType.getName(); + } + OutputType newOutputType = new OutputType(this, subId, subName, outputType); + addOutputType(newOutputType); + } + } + + // icon + if ( tool.iconPathURL != null ) { + iconPathURL = tool.iconPathURL; + } + + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Load the tool information from the XML element specified in the + * argument + * @param element An XML element containing the tool information + */ + protected void loadFromManifest(IManagedConfigElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(ITool.ID)); + + // name + setName(element.getAttribute(ITool.NAME)); + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // Get the unused children, if any + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + + // Get the 'versionsSupported' attribute + versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); + + // Get the 'convertToId' attribute + convertToId = element.getAttribute(CONVERT_TO_ID); + + // isAbstract + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + + // Get the semicolon separated list of IDs of the error parsers + errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); + + // Get the nature filter + String nature = element.getAttribute(NATURE); + if (nature != null) { + if ("both".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_BOTH); + } else if ("cnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_C); + } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_CC); + } else { + natureFilter = new Integer(FILTER_BOTH); + } + } + + // Get the supported input file extensions + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + + // Get the interface (header file) extensions + String headers = element.getAttribute(INTERFACE_EXTS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInterfaceExtensionsList().add(tokenizer.nextElement()); + } + } + + // Get the output extension + outputExtensions = element.getAttribute(ITool.OUTPUTS); + + // Get the tool invocation command + command = element.getAttribute(ITool.COMMAND); + + // Get the flag to control output + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + + // Get the output prefix + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + + // Get command line pattern + commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); + + // Get advancedInputCategory + String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); + if (advInput != null){ + advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ + } + + // Get customBuildStep + String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); + if (cbs != null){ + customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ + } + + // Get the announcement text + announcement = element.getAttribute(ITool.ANNOUNCEMENT); + + // Store the configuration element IFF there is a command line generator defined + String commandLineGenerator = element.getAttribute(COMMAND_LINE_GENERATOR); + if (commandLineGenerator != null && element instanceof DefaultManagedConfigElement) { + commandLineGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // Store the configuration element IFF there is a dependency generator defined + String depGenerator = element.getAttribute(DEP_CALC_ID); + if (depGenerator != null && element instanceof DefaultManagedConfigElement) { + dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // icon + if ( element.getAttribute(IOptionCategory.ICON) != null && element instanceof DefaultManagedConfigElement) + { + String icon = element.getAttribute(IOptionCategory.ICON); + iconPathURL = ManagedBuildManager.getURLInBuildDefinitions( (DefaultManagedConfigElement)element, new Path(icon) ); + } + } + + /* (non-Javadoc) + * Initialize the tool information from the XML element + * specified in the argument + * + * @param element An XML element containing the tool information + */ + protected void loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + if( getParent() instanceof IResourceConfiguration ) { + IResourceConfiguration resConfig = (IResourceConfiguration) getParent(); + setSuperClassInternal( resConfig.getParent().getTool(superClassId) ); + } else { + setSuperClassInternal( ManagedBuildManager.getExtensionTool(superClassId) ); + } + + // Check for migration support + checkForMigrationSupport(); + + } + + // Get the unused children, if any + if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + } + + // isAbstract + if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + } + + // Get the 'versionSupported' attribute + if (element.hasAttribute(VERSIONS_SUPPORTED)) { + versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); + } + + // Get the 'convertToId' id + if (element.hasAttribute(CONVERT_TO_ID)) { + convertToId = element.getAttribute(CONVERT_TO_ID); + } + + // Get the semicolon separated list of IDs of the error parsers + if (element.hasAttribute(IToolChain.ERROR_PARSERS)) { + errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); + } + + // Get the nature filter + if (element.hasAttribute(NATURE)) { + String nature = element.getAttribute(NATURE); + if (nature != null) { + if ("both".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_BOTH); + } else if ("cnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_C); + } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_CC); + } else { + natureFilter = new Integer(FILTER_BOTH); + } + } + } + + // Get the supported input file extension + if (element.hasAttribute(ITool.SOURCES)) { + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // Get the interface (header file) extensions + if (element.hasAttribute(INTERFACE_EXTS)) { + String headers = element.getAttribute(INTERFACE_EXTS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInterfaceExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // Get the output extension + if (element.hasAttribute(ITool.OUTPUTS)) { + outputExtensions = element.getAttribute(ITool.OUTPUTS); + } + + // Get the tool invocation command + if (element.hasAttribute(ITool.COMMAND)) { + command = element.getAttribute(ITool.COMMAND); + } + + // Get the flag to control output + if (element.hasAttribute(ITool.OUTPUT_FLAG)) { + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + } + + // Get the output prefix + if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + } + + // Get command line pattern + if( element.hasAttribute( ITool.COMMAND_LINE_PATTERN ) ) { + commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); + } + + // advancedInputCategory + if (element.hasAttribute(ITool.ADVANCED_INPUT_CATEGORY)) { + String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); + if (advInput != null){ + advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ + } + } + + // customBuildStep + if (element.hasAttribute(ITool.CUSTOM_BUILD_STEP)) { + String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); + if (cbs != null){ + customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ + } + } + + // Get the announcement text + if (element.hasAttribute(ITool.ANNOUNCEMENT)) { + announcement = element.getAttribute(ITool.ANNOUNCEMENT); + } + + // icon - was saved as URL in string form + if (element.hasAttribute(IOptionCategory.ICON)) { + String iconPath = element.getAttribute(IOptionCategory.ICON); + try { + iconPathURL = new URL(iconPath); + } catch (MalformedURLException e) { + // Print a warning + ManagedBuildManager.OutputIconError(iconPath); + iconPathURL = null; + } + } + } + + /** + * Persist the tool to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + try { + if (getSuperClass() != null) + element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); + + // id + element.setAttribute(IBuildObject.ID, id); + + // name + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + // unused children + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + // isAbstract + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + // versionsSupported + if (versionsSupported != null) { + element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); + } + + // convertToId + if (convertToId != null) { + element.setAttribute(CONVERT_TO_ID, convertToId); + } + + // error parsers + if (errorParserIds != null) { + element.setAttribute(IToolChain.ERROR_PARSERS, errorParserIds); + } + + // nature filter + if (natureFilter != null) { + String nature; + if (natureFilter.intValue() == FILTER_C) { + nature = "cnature"; //$NON-NLS-1$ + } else if (natureFilter.intValue() == FILTER_CC) { + nature = "ccnature"; //$NON-NLS-1$ + } else { + nature = "both"; //$NON-NLS-1$ + } + element.setAttribute(NATURE, nature); + } + + // input file extensions + if (getInputExtensionsList().size() > 0) { + String inputs; + List list = getInputExtensionsList(); + Iterator iter = list.listIterator(); + inputs = (String)iter.next(); + while (iter.hasNext()) { + inputs += DEFAULT_SEPARATOR; + inputs += iter.next(); + } + element.setAttribute(ITool.SOURCES, inputs); + } + + // interface (header file) extensions + if (getInterfaceExtensionsList().size() > 0) { + String headers; + List list = getInterfaceExtensionsList(); + Iterator iter = list.listIterator(); + headers = (String)iter.next(); + while (iter.hasNext()) { + headers += DEFAULT_SEPARATOR; + headers += iter.next(); + } + element.setAttribute(INTERFACE_EXTS, headers); + } + + // output extension + if (outputExtensions != null) { + element.setAttribute(ITool.OUTPUTS, outputExtensions); + } + + // command + if (command != null) { + element.setAttribute(ITool.COMMAND, command); + } + + // flag to control output + if (outputFlag != null) { + element.setAttribute(ITool.OUTPUT_FLAG, outputFlag); + } + + // output prefix + if (outputPrefix != null) { + element.setAttribute(ITool.OUTPUT_PREFIX, outputPrefix); + } + + // command line pattern + if (commandLinePattern != null) { + element.setAttribute(ITool.COMMAND_LINE_PATTERN, commandLinePattern); + } + + // advancedInputCategory + if (advancedInputCategory != null) { + element.setAttribute(ITool.ADVANCED_INPUT_CATEGORY, advancedInputCategory.toString()); + } + + // customBuildStep + if (customBuildStep != null) { + element.setAttribute(ITool.CUSTOM_BUILD_STEP, customBuildStep.toString()); + } + + // announcement text + if (announcement != null) { + element.setAttribute(ITool.ANNOUNCEMENT, announcement); + } + + // Serialize elements from my super class + super.serialize(doc, element); + + // Serialize my children + Iterator iter; + List typeElements = getInputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + InputType type = (InputType) iter.next(); + Element typeElement = doc.createElement(INPUT_TYPE); + element.appendChild(typeElement); + type.serialize(doc, typeElement); + } + typeElements = getOutputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + OutputType type = (OutputType) iter.next(); + Element typeElement = doc.createElement(OUTPUT_TYPE); + element.appendChild(typeElement); + type.serialize(doc, typeElement); + } + + // Note: command line generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (commandLineGeneratorElement != null) { + // TODO: issue warning? + } + + // Note: dependency generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (dependencyGeneratorElement != null) { + // TODO: issue warning? + } + + if (iconPathURL != null) { + // Save as URL in string form + element.setAttribute(IOptionCategory.ICON, iconPathURL.toString()); + } + + // I am clean now + isDirty = false; + } catch (Exception e) { + // TODO: issue an error message + } + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getParent() + */ + public IBuildObject getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) + */ + public void setToolParent(IBuildObject newParent) { + this.parent = newParent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() + */ + public IOptionCategory getTopOptionCategory() { + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#createInputType(IInputType, String, String, boolean) + */ + public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { + InputType type = new InputType(this, superClass, Id, name, isExtensionElement); + addInputType(type); + setDirty(true); + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#removeInputType(IInputType) + */ + public void removeInputType(IInputType type) { + getInputTypeList().remove(type); + getInputTypeMap().remove(type.getId()); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputTypes() + */ + public IInputType[] getInputTypes() { + IInputType[] types = null; + // Merge our input types with our superclass' input types. + if (getSuperClass() != null) { + types = getSuperClass().getInputTypes(); + } + // Our options take precedence. + Vector ourTypes = getInputTypeList(); + if (types != null) { + for (int i = 0; i < ourTypes.size(); i++) { + IInputType ourType = (IInputType)ourTypes.get(i); + int j; + for (j = 0; j < types.length; j++) { + if (ourType.getSuperClass() != null && + ourType.getSuperClass().getId().equals(types[j].getId())) { + types[j] = ourType; + break; + } + } + // No Match? Add it. + if (j == types.length) { + IInputType[] newTypes = new IInputType[types.length + 1]; + for (int k = 0; k < types.length; k++) { + newTypes[k] = types[k]; + } + newTypes[j] = ourType; + types = newTypes; + } + } + } else { + types = (IInputType[])ourTypes.toArray(new IInputType[ourTypes.size()]); + } + return types; + } + + private boolean hasInputTypes() { + Vector ourTypes = getInputTypeList(); + if (ourTypes.size() > 0) return true; + return false; + } + + public IInputType getInputTypeById(String id) { + IInputType type = (IInputType)getInputTypeMap().get(id); + if (type == null) { + if (getSuperClass() != null) { + return getSuperClass().getInputTypeById(id); + } + } + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#createOutputType(IOutputType, String, String, boolean) + */ + public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { + OutputType type = new OutputType(this, superClass, Id, name, isExtensionElement); + addOutputType(type); + setDirty(true); + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOutputType(IOutputType) + */ + public void removeOutputType(IOutputType type) { + getOutputTypeList().remove(type); + getOutputTypeMap().remove(type.getId()); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputTypes() + */ + public IOutputType[] getOutputTypes() { + IOutputType[] types = null; + // Merge our output types with our superclass' output types. + if (getSuperClass() != null) { + types = getSuperClass().getOutputTypes(); + } + // Our options take precedence. + Vector ourTypes = getOutputTypeList(); + if (types != null) { + for (int i = 0; i < ourTypes.size(); i++) { + IOutputType ourType = (IOutputType)ourTypes.get(i); + int j; + for (j = 0; j < types.length; j++) { + if (ourType.getSuperClass() != null && + ourType.getSuperClass().getId().equals(types[j].getId())) { + types[j] = ourType; + break; + } + } + // No Match? Add it. + if (j == types.length) { + IOutputType[] newTypes = new IOutputType[types.length + 1]; + for (int k = 0; k < types.length; k++) { + newTypes[k] = types[k]; + } + newTypes[j] = ourType; + types = newTypes; + } + } + } else { + types = (IOutputType[])ourTypes.toArray(new IOutputType[ourTypes.size()]); + } + return types; + } + + private boolean hasOutputTypes() { + Vector ourTypes = getOutputTypeList(); + if (ourTypes.size() > 0) return true; + return false; + } + + public IOutputType getPrimaryOutputType() { + IOutputType type = null; + IOutputType[] types = getOutputTypes(); + if (types != null && types.length > 0) { + for (int i=0; i 0) return exts[0]; + } + // If none, use the input extensions specified for the Tool (backwards compatibility) + List extsList = getInputExtensionsAttribute(); + // Use the first entry in the list + if (extsList != null && extsList.size() > 0) return (String)extsList.get(0); + return EMPTY_STRING; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getPrimaryInputExtensions() + */ + public String[] getPrimaryInputExtensions() { + IInputType type = getPrimaryInputType(); + if (type != null) { + String[] exts = type.getSourceExtensions(this); + // Use the first entry in the list + if (exts.length > 0) return exts; + } + // If none, use the input extensions specified for the Tool (backwards compatibility) + List extsList = getInputExtensionsAttribute(); + // Use the first entry in the list + if (extsList != null && extsList.size() > 0) { + return (String[])extsList.toArray(new String[extsList.size()]); + } + return EMPTY_STRING_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllInputExtensions() + */ + public String[] getAllInputExtensions() { + IInputType[] types = getInputTypes(); + if (types != null && types.length > 0) { + List allExts = new ArrayList(); + for (int i=0; i 0) { + return (String[])allExts.toArray(new String[allExts.size()]); + } + } + // If none, use the input extensions specified for the Tool (backwards compatibility) + List extsList = getInputExtensionsAttribute(); + if (extsList != null && extsList.size() > 0) { + return (String[])extsList.toArray(new String[extsList.size()]); + } + return EMPTY_STRING_ARRAY; + } + + public IInputType getPrimaryInputType() { + IInputType type = null; + IInputType[] types = getInputTypes(); + if (types != null && types.length > 0) { + for (int i=0; i 0) { + for (int i=0; i 0) { + allDeps.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + return (IPath[])allDeps.toArray(new IPath[allDeps.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getAdditionalResources() + */ + public IPath[] getAdditionalResources() { + List allRes = new ArrayList(); + IInputType[] types = getInputTypes(); + for (int i=0; i 0) { + allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + return (IPath[])allRes.toArray(new IPath[allRes.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllDependencyExtensions() + */ + public String[] getAllDependencyExtensions() { + IInputType[] types = getInputTypes(); + if (types != null && types.length > 0) { + List allExts = new ArrayList(); + for (int i=0; i 0) { + return (String[])allExts.toArray(new String[allExts.size()]); + } + } + // If none, use the header extensions specified for the Tool (backwards compatibility) + List extsList = getHeaderExtensionsAttribute(); + if (extsList != null && extsList.size() > 0) { + return (String[])extsList.toArray(new String[extsList.size()]); + } + return EMPTY_STRING_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getInterfaceExtension() + * @deprecated + */ + public List getInterfaceExtensions() { + return getHeaderExtensionsAttribute(); + } + + private List getHeaderExtensionsAttribute() { + if (interfaceExtensions == null || interfaceExtensions.size() == 0) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return ((Tool)getSuperClass()).getHeaderExtensionsAttribute(); + } else { + if (interfaceExtensions == null) { + interfaceExtensions = new ArrayList(); + } + } + } + return interfaceExtensions; + } + + private List getInterfaceExtensionsList() { + if (interfaceExtensions == null) { + interfaceExtensions = new ArrayList(); + } + return interfaceExtensions; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOutputFlag() + */ + public String getOutputFlag() { + if (outputFlag == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getOutputFlag(); + } else { + return EMPTY_STRING; + } + } + return outputFlag; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOutputPrefix() + */ + public String getOutputPrefix() { + // Get the outputPrefix from an OutputType, if any. + IOutputType type = null; + IOutputType[] types = getOutputTypes(); + if (types != null && types.length > 0) { + for (int i=0; i 0) { + List allExts = new ArrayList(); + for (int i=0; i 0) { + return (String[])allExts.toArray(new String[allExts.size()]); + } + } + // If none, use the outputs specified for the Tool (backwards compatibility) + String[] extsList = getOutputsAttribute(); + if (extsList != null && extsList.length > 0) { + return extsList; + } + return EMPTY_STRING_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() + * @deprecated + */ + public String[] getOutputExtensions() { + return getOutputsAttribute(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputsAttribute() + */ + public String[] getOutputsAttribute() { + // TODO: Why is this treated differently than inputExtensions? + if (outputExtensions == null) { + if (getSuperClass() != null) { + return getSuperClass().getOutputsAttribute(); + } else { + return null; + } + } + return outputExtensions.split(DEFAULT_SEPARATOR); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOutputExtension(java.lang.String) + */ + public String getOutputExtension(String inputExtension) { + // Search thru the output-types to find one that has a primary input type with this extension + IOutputType[] types = getOutputTypes(); + int i; + if (types != null) { + for (i=0; i 0) { + return exts[0]; + } + } + } + // Does any input type produce this extension? + if (getInputType(inputExtension) != null) { + // Return the first extension of the primary output type + IOutputType outType = getPrimaryOutputType(); + String[] exts = outType.getOutputExtensions(this); + if (exts != null && exts.length > 0) { + return exts[0]; + } + } + } + // If no OutputTypes specified, examine the list of input extensions + String[] inputExts = getAllInputExtensions(); + for (i=0; i 0) { + for (int i=0; i 0) { + sb.append(boolCmd); + } + break; + + case IOption.ENUMERATED : + String enumVal = option.getEnumCommand(option.getSelectedEnum()); + if (enumVal.length() > 0) { + sb.append(enumVal); + } + break; + + case IOption.STRING : + String strCmd = option.getCommand(); + String val = option.getStringValue(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + if (val.length() > 0 + && (val = MacroResolver.resolveToString(val, macroSubstitutor)).length() > 0) { + sb.append( evaluateCommand( strCmd, val ) ); + } + break; + + case IOption.STRING_LIST : + String listCmd = option.getCommand(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + String[] list = MacroResolver.resolveStringListValues(option.getStringListValue(), macroSubstitutor, true); + if(list != null){ + for (int j = 0; j < list.length; j++) { + String temp = list[j]; + if(temp.length() > 0) + sb.append( evaluateCommand( listCmd, temp ) + WHITE_SPACE ); + } + } + break; + + case IOption.INCLUDE_PATH : + String incCmd = option.getCommand(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + String[] paths = MacroResolver.resolveStringListValues(option.getIncludePaths(), macroSubstitutor, true); + if(paths != null){ + for (int j = 0; j < paths.length; j++) { + String temp = paths[j]; + if(temp.length() > 0) + sb.append( evaluateCommand( incCmd, temp ) + WHITE_SPACE); + } + } + break; + + case IOption.PREPROCESSOR_SYMBOLS : + String defCmd = option.getCommand(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + String[] symbols = MacroResolver.resolveStringListValues(option.getDefinedSymbols(), macroSubstitutor, true); + if(symbols != null){ + for (int j = 0; j < symbols.length; j++) { + String temp = symbols[j]; + if(temp.length() > 0) + sb.append( evaluateCommand( defCmd, temp ) + WHITE_SPACE); + } + } + break; + + default : + break; + } + + if (sb.toString().trim().length() > 0) + flags.add(sb.toString().trim()); + } catch (BuildMacroException e) { + + } + } + } + String[] f = new String[ flags.size() ]; + return (String[])flags.toArray( f ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + IMacroSubstitutor macroSubstitutor = new BuildfileMacroSubstitutor(null,EMPTY_STRING,WHITE_SPACE); + return getToolCommandFlags(inputFileLocation, outputFileLocation, macroSubstitutor ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + // Get all of the optionList + StringBuffer buf = new StringBuffer(); + String[] flags = getToolCommandFlags(inputFileLocation,outputFileLocation); + for (int index = 0; index < flags.length; index++) { + if( flags[ index ] != null ) { + buf.append( flags[ index ] + WHITE_SPACE ); + } + } + + return buf.toString().trim(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) + */ + public boolean isHeaderFile(String ext) { + if (ext == null) { + return false; + } + String[] exts = getAllDependencyExtensions(); + for (int i=0; i 0) { + return false; + } + // 3. If the assignToOption attribute is specified, no + if (it.getAssignToOptionId() != null && it.getAssignToOptionId().length() > 0) { + return false; + } + // Else, yes + return true; + } + // If no InputTypes, check the inputExtensions attribute + if (!hasInputTypes()) { + return getInputExtensionsAttribute().contains(extension); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#isInputFileType(java.lang.String) + */ + public boolean isInputFileType(String extension) { + if (extension == null) { + return false; + } + IInputType it = getInputType(extension); + if (it != null) { + return true; + } + // If no InputTypes, check the inputExtensions attribute + if (!hasInputTypes()) { + return getInputExtensionsAttribute().contains(extension); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) + */ + public boolean producesFileType(String extension) { + if (extension == null) { + return false; + } + // Check the output-types first + if (getOutputType(extension) != null) { + return true; + } + // If there are no OutputTypes, check the attribute + if (!hasOutputTypes()) { + String[] exts = getOutputsAttribute(); + if (exts != null) { + for (int i = 0; i < exts.length; i++) { + if (exts[i].equals(extension)) + return true; + } + } + } + return false; + } + +/* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() + */ + public boolean isExtensionElement() { + return isExtensionTool; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isDirty() + */ + public boolean isDirty() { + // This shouldn't be called for an extension tool + if (isExtensionTool) return false; + + // If I need saving, just say yes + if (isDirty) return true; + + // Check my children + List typeElements = getInputTypeList(); + Iterator iter = typeElements.listIterator(); + while (iter.hasNext()) { + InputType type = (InputType) iter.next(); + if (type.isDirty()) return true; + } + typeElements = getOutputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + OutputType type = (OutputType) iter.next(); + if (type.isDirty()) return true; + } + + // Otherwise see if any options need saving + if (super.isDirty()) { + return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to options + super.setDirty(isDirty); + // Propagate "false" to the children + if (!isDirty) { + List typeElements = getInputTypeList(); + Iterator iter = typeElements.listIterator(); + while (iter.hasNext()) { + InputType type = (InputType) iter.next(); + type.setDirty(false); + } + typeElements = getOutputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + OutputType type = (OutputType) iter.next(); + type.setDirty(false); + } + } + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references + */ + public void resolveReferences() { + if (!resolved) { + resolved = true; + // Resolve superClass + if (superClassId != null && superClassId.length() > 0) { + setSuperClassInternal( ManagedBuildManager.getExtensionTool(superClassId) ); + if (getSuperClass() == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "tool", //$NON-NLS-1$ + getId()); + } + } + // Resolve HoldsOptions + super.resolveReferences(); + // Call resolveReferences on our children + Iterator typeIter = getInputTypeList().iterator(); + while (typeIter.hasNext()) { + InputType current = (InputType)typeIter.next(); + current.resolveReferences(); + } + typeIter = getOutputTypeList().iterator(); + while (typeIter.hasNext()) { + OutputType current = (OutputType)typeIter.next(); + current.resolveReferences(); + } + } + } + + /** + * Look for ${VALUE} in the command string + */ + public String evaluateCommand( String command, String values ) { + final int DOLLAR_VALUE_LENGTH = 8; + + if( command == null ) return values.trim(); + + String ret = command; + boolean found = false; + int start = 0; + int index; + int len; + while ((index = ret.indexOf( "${", start )) >= 0 && //$NON-NLS-1$ + (len = ret.length()) >= index + DOLLAR_VALUE_LENGTH) { + start = index; + index = index+2; + int ch = ret.charAt(index); + if ( ch == 'v' || ch == 'V' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'a' || ch == 'A' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'l' || ch == 'L' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'u' || ch == 'U' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'e' || ch == 'E' ) { + index++; + ch = ret.charAt(index); + if ( ch == '}' ) { + String temp = ""; //$NON-NLS-1$ + index++; + found = true; + if (start > 0) { + temp = ret.substring(0, start); + } + temp = temp.concat(values.trim()); + if (len > index) { + start = temp.length(); + ret = temp.concat(ret.substring(index)); + index = start; + } + else { + ret = temp; + break; + } + } + } + } + } + } + } + start = index; + } + if (found) + return ret.trim(); + return (new String(command + values)).trim(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() + */ + public String getConvertToId() { + if (convertToId == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getConvertToId(); + } else { + return EMPTY_STRING; + } + } + return convertToId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) + */ + public void setConvertToId(String convertToId) { + if (convertToId == null && this.convertToId == null) return; + if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { + this.convertToId = convertToId; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() + */ + public String getVersionsSupported() { + if (versionsSupported == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getVersionsSupported(); + } else { + return EMPTY_STRING; + } + } + return versionsSupported; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) + */ + public void setVersionsSupported(String versionsSupported) { + if (versionsSupported == null && this.versionsSupported == null) return; + if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { + this.versionsSupported = versionsSupported; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getEnvVarBuildPaths() + */ + public IEnvVarBuildPath[] getEnvVarBuildPaths(){ + if(envVarBuildPathList != null){ + return (IEnvVarBuildPath[])envVarBuildPathList.toArray( + new IEnvVarBuildPath[envVarBuildPathList.size()]); + } + else if(getSuperClass() != null) + return getSuperClass().getEnvVarBuildPaths(); + return null; + } + + private void addEnvVarBuildPath(IEnvVarBuildPath path){ + if(path == null) + return; + if(envVarBuildPathList == null) + envVarBuildPathList = new ArrayList(); + + envVarBuildPathList.add(path); + } + + /* + * This function checks for migration support for the tool, while + * loading. If migration support is needed, looks for the available + * converters and stores them. + */ + + public void checkForMigrationSupport() { + + boolean isExists = false; + + if ( getSuperClass() == null) { + // If 'getSuperClass()' is null, then there is no tool available in + // plugin manifest file with the same 'id' & version. + // Look for the 'versionsSupported' attribute + String high = (String) ManagedBuildManager.getExtensionToolMap() + .lastKey(); + + SortedMap subMap = null; + if (superClassId.compareTo(high) <= 0) { + subMap = ManagedBuildManager.getExtensionToolMap().subMap( + superClassId, high + "\0"); //$NON-NLS-1$ + } else { + // It means there are no entries in the map for the given id. + // make the project is invalid + + // It means there are no entries in the map for the given id. + // make the project is invalid + // If the parent is a tool chain + IToolChain parent = (IToolChain) getParent(); + IConfiguration parentConfig = parent.getParent(); + IManagedProject managedProject = parentConfig + .getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + return; + } + + // for each element in the 'subMap', + // check the 'versionsSupported' attribute whether the given + // builder version is supported + + String baseId = ManagedBuildManager + .getIdFromIdAndVersion(superClassId); + String version = ManagedBuildManager + .getVersionFromIdAndVersion(superClassId); + + ITool[] toolElements = (ITool[]) subMap.values().toArray(); + + for (int i = 0; i < toolElements.length; i++) { + ITool toolElement = toolElements[i]; + + if (ManagedBuildManager.getIdFromIdAndVersion( + toolElement.getId()).compareTo(baseId) > 0) + break; + + // First check if both base ids are equal + if (ManagedBuildManager.getIdFromIdAndVersion( + toolElement.getId()).equals(baseId)) { + + // Check if 'versionsSupported' attribute is available' + String versionsSupported = toolElement + .getVersionsSupported(); + + if ((versionsSupported != null) + && (!versionsSupported.equals(""))) { //$NON-NLS-1$ + String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ + + for (int j = 0; j < tmpVersions.length; j++) { + if (new PluginVersionIdentifier(version) + .equals(new PluginVersionIdentifier( + tmpVersions[j]))) { + // version is supported. + // Do the automatic conversion without + // prompting the user. + // Get the supported version + String supportedVersion = ManagedBuildManager + .getVersionFromIdAndVersion(toolElement + .getId()); + setId(ManagedBuildManager + .getIdFromIdAndVersion(getId()) + + "_" + supportedVersion); //$NON-NLS-1$ + + // If control comes here means that superClass + // is null. + // So, set the superClass to this tool element + setSuperClassInternal(toolElement); + superClassId = getSuperClass().getId(); + isExists = true; + break; + } + } + if (isExists) + break; // break the outer for loop if 'isExists' is + // true + } + } + } + } + + if (getSuperClass() != null) { + // If 'getSuperClass()' is not null, look for 'convertToId' + // attribute in plugin + // manifest file for this tool. + String convertToId = getSuperClass().getConvertToId(); + if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ + // It means there is no 'convertToId' attribute available and + // the version is still actively + // supported by the tool integrator. So do nothing, just return + return; + } else { + // Incase the 'convertToId' attribute is available, + // it means that Tool integrator currently does not support this + // version of tool. + // Look for the converters available for this tool version. + + getConverter(convertToId); + } + + } else { + // make the project is invalid + // + // It means there are no entries in the map for the given id. + // make the project is invalid + IToolChain parent = (IToolChain) getParent(); + IConfiguration parentConfig = parent.getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + } + return; + } + + + private void getConverter(String convertToId) { + + String fromId = null; + String toId = null; + + // Get the Converter Extension Point + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ + "projectConverter"); //$NON-NLS-1$ + if (extensionPoint != null) { + // Get the extensions + IExtension[] extensions = extensionPoint.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + // Get the configuration elements of each extension + IConfigurationElement[] configElements = extensions[i] + .getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + + IConfigurationElement element = configElements[j]; + + if (element.getName().equals("converter")) { //$NON-NLS-1$ + + fromId = element.getAttribute("fromId"); //$NON-NLS-1$ + toId = element.getAttribute("toId"); //$NON-NLS-1$ + // Check whether the current converter can be used for + // the selected tool + + if (fromId.equals(getSuperClass().getId()) + && toId.equals(convertToId)) { + // If it matches + String mbsVersion = element + .getAttribute("mbsVersion"); //$NON-NLS-1$ + PluginVersionIdentifier currentMbsVersion = ManagedBuildManager + .getBuildInfoVersion(); + + // set the converter element based on the MbsVersion + if (currentMbsVersion + .isGreaterThan(new PluginVersionIdentifier( + mbsVersion))) { + previousMbsVersionConversionElement = element; + } else { + currentMbsVersionConversionElement = element; + } + return; + } + } + } + } + } + + // If control comes here, it means 'Tool Integrator' specified + // 'convertToId' attribute in toolchain definition file, but + // has not provided any converter. + // So, make the project is invalid + + // It means there are no entries in the map for the given id. + // make the project is invalid + IToolChain parent = (IToolChain) getParent(); + IConfiguration parentConfig = parent.getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + return; + } + + public IConfigurationElement getPreviousMbsVersionConversionElement() { + return previousMbsVersionConversionElement; + } + + public IConfigurationElement getCurrentMbsVersionConversionElement() { + return currentMbsVersionConversionElement; + } + + public IProject getProject() { + IBuildObject toolParent = getParent(); + if (toolParent != null) { + if (toolParent instanceof IToolChain) { + IConfiguration config = ((IToolChain)toolParent).getParent(); + if (config == null) return null; + return (IProject)config.getOwner(); + } else if (toolParent instanceof IResourceConfiguration) { + return (IProject)((IResourceConfiguration)toolParent).getOwner(); + } + } + return null; + } + + public String[] getContentTypeFileSpecs (IContentType type) { + String[] globalSpecs = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + IContentTypeSettings settings = null; + IProject project = getProject(); + if (project != null) { + IScopeContext projectScope = new ProjectScope(project); + try { + settings = type.getSettings(projectScope); + } catch (Exception e) {} + if (settings != null) { + String[] specs = settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + if (specs.length > 0) { + int total = globalSpecs.length + specs.length; + String[] projSpecs = new String[total]; + int i=0; + for (int j=0; jnull if - * defined at the top level - * @param element The tool-chain definition from the manifest file or a dynamic element - * provider - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public ToolChain(IConfiguration parent, IManagedConfigElement element, String managedBuildRevision) { - // setup for resolving - super(false); - resolved = false; - - this.parent = parent; - isExtensionToolChain = true; - - // Set the managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionToolChain(this); - - // Load the TargetPlatform child - IManagedConfigElement[] targetPlatforms = - element.getChildren(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); - if (targetPlatforms.length < 1 || targetPlatforms.length > 1) { - // TODO: Report error - } - if (targetPlatforms.length > 0) { - targetPlatform = new TargetPlatform(this, targetPlatforms[0], managedBuildRevision); - } - - // Load the Builder child - IManagedConfigElement[] builders = - element.getChildren(IBuilder.BUILDER_ELEMENT_NAME); - if (builders.length < 1 || builders.length > 1) { - // TODO: Report error - } - if (builders.length > 0) { - builder = new Builder(this, builders[0], managedBuildRevision); - } - - // Load children - IManagedConfigElement[] toolChainElements = element.getChildren(); - for (int l = 0; l < toolChainElements.length; ++l) { - IManagedConfigElement toolChainElement = toolChainElements[l]; - if (loadChild(toolChainElement)) { - // do nothing - } else if (toolChainElement.getName().equals(ITool.TOOL_ELEMENT_NAME)) { - Tool toolChild = new Tool(this, toolChainElement, managedBuildRevision); - addTool(toolChild); - } - } - } - - /** - * This constructor is called to create a ToolChain whose attributes and children will be - * added by separate calls. - * - * @param Configuration The parent of the tool chain, if any - * @param ToolChain The superClass, if any - * @param String The id for the new tool chain - * @param String The name for the new tool chain - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public ToolChain(Configuration parent, IToolChain superClass, String Id, String name, boolean isExtensionElement) { - super(resolvedDefault); - this.parent = parent; - setSuperClassInternal(superClass); - setManagedBuildRevision(parent.getManagedBuildRevision()); - - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - setId(Id); - setName(name); - setVersion(getVersionFromId()); - - isExtensionToolChain = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionToolChain(this); - } else { - setDirty(true); - } - } - - /** - * Create a ToolChain based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The IConfiguration the tool-chain will be added to. - * @param element The XML element that contains the tool-chain settings. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public ToolChain(IConfiguration parent, Element element, String managedBuildRevision) { - super(resolvedDefault); - this.parent = parent; - isExtensionToolChain = false; - - // Set the managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromProject(element); - - // Load children - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (loadChild(configElement)) { - // do nothing - } else if (configElement.getNodeName().equals(ITool.TOOL_ELEMENT_NAME)) { - Tool tool = new Tool(this, (Element)configElement, managedBuildRevision); - addTool(tool); - }else if (configElement.getNodeName().equals(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME)) { - if (targetPlatform != null) { - // TODO: report error - } - targetPlatform = new TargetPlatform(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(IBuilder.BUILDER_ELEMENT_NAME)) { - if (builder != null) { - // TODO: report error - } - builder = new Builder(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { - //load user-defined macros - userDefinedMacros = new StorableMacros((Element)configElement); - - } - } - } - - /** - * Create a ToolChain based upon an existing tool chain. - * - * @param parent The IConfiguration the tool-chain will be added to. - * @param toolChain The existing tool-chain to clone. - */ - public ToolChain(IConfiguration parent, String Id, String name, ToolChain toolChain) { - super(resolvedDefault); - this.parent = parent; - setSuperClassInternal(toolChain.getSuperClass()); - if (getSuperClass() != null) { - if (toolChain.superClassId != null) { - superClassId = new String(toolChain.superClassId); - } - } - setId(Id); - setName(name); - - // Set the managedBuildRevision and the version - setManagedBuildRevision(toolChain.getManagedBuildRevision()); - setVersion(getVersionFromId()); - - isExtensionToolChain = false; - - // Copy the remaining attributes - if(toolChain.versionsSupported != null) { - versionsSupported = new String(toolChain.versionsSupported); - } - if(toolChain.convertToId != null) { - convertToId = new String(toolChain.convertToId); - } - - if (toolChain.unusedChildren != null) { - unusedChildren = new String(toolChain.unusedChildren); - } - if (toolChain.errorParserIds != null) { - errorParserIds = new String(toolChain.errorParserIds); - } - if (toolChain.osList != null) { - osList = new ArrayList(toolChain.osList); - } - if (toolChain.archList != null) { - archList = new ArrayList(toolChain.archList); - } - if (toolChain.targetToolIds != null) { - targetToolIds = new String(toolChain.targetToolIds); - } - if (toolChain.secondaryOutputIds != null) { - secondaryOutputIds = new String(toolChain.secondaryOutputIds); - } - if (toolChain.isAbstract != null) { - isAbstract = new Boolean(toolChain.isAbstract.booleanValue()); - } - if (toolChain.scannerConfigDiscoveryProfileId != null) { - scannerConfigDiscoveryProfileId = new String(toolChain.scannerConfigDiscoveryProfileId); - } - managedIsToolChainSupportedElement = toolChain.managedIsToolChainSupportedElement; - managedIsToolChainSupported = toolChain.managedIsToolChainSupported; - - environmentVariableSupplierElement = toolChain.environmentVariableSupplierElement; - environmentVariableSupplier = toolChain.environmentVariableSupplier; - - buildMacroSupplierElement = toolChain.buildMacroSupplierElement; - buildMacroSupplier = toolChain.buildMacroSupplier; - - // Clone the children in superclass - super.copyChildren(toolChain); - // Clone the children - if (toolChain.builder != null) { - String subId; - String subName; - - if (toolChain.builder.getSuperClass() != null) { - subId = ManagedBuildManager.calculateChildId( - toolChain.builder.getSuperClass().getId(), - null); - subName = toolChain.builder.getSuperClass().getName(); - } else { - subId = ManagedBuildManager.calculateChildId( - toolChain.builder.getId(), - null); - subName = toolChain.builder.getName(); - } - - builder = new Builder(this, subId, subName, toolChain.builder); - } - if (toolChain.targetPlatform != null) { - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (toolChain.targetPlatform.getSuperClass() != null) { - subId = toolChain.targetPlatform.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = toolChain.targetPlatform.getSuperClass().getName(); - } else { - subId = toolChain.targetPlatform.getId() + "." + nnn; //$NON-NLS-1$ - subName = toolChain.targetPlatform.getName(); - } - targetPlatform = new TargetPlatform(this, subId, subName, toolChain.targetPlatform); - } - if (toolChain.toolList != null) { - Iterator iter = toolChain.getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String tmpId; - String subName; - String version; - - if (toolChild.getSuperClass() != null) { - tmpId = toolChild.getSuperClass().getId(); - subName = toolChild.getSuperClass().getName(); - } else { - tmpId = toolChild.getId(); - subName = toolChild.getName(); - } - version = ManagedBuildManager.getVersionFromIdAndVersion(tmpId); - if ( version != null) { // If the 'tmpId' contains version information - subId = ManagedBuildManager.getIdFromIdAndVersion(tmpId) + "." + nnn + "_" + version; //$NON-NLS-1$ //$NON-NLS-2$ - } else { - subId = tmpId + "." + nnn; //$NON-NLS-1$ - } - - Tool newTool = new Tool(this, null, subId, subName, toolChild); - addTool(newTool); - } - } - - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Loads the tool-chain information from the ManagedConfigElement specified in the - * argument. - * - * @param element Contains the tool-chain information - */ - protected void loadFromManifest(IManagedConfigElement element) { - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // Get the name - setName(element.getAttribute(IBuildObject.NAME)); - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // Get the unused children, if any - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - - // isAbstract - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - - // Get the semicolon separated list of IDs of the error parsers - errorParserIds = element.getAttribute(ERROR_PARSERS); - - // Get the semicolon separated list of IDs of the secondary outputs - secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); - - // Get the target tool id - targetToolIds = element.getAttribute(TARGET_TOOL); - - // Get the scanner config discovery profile id - scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); - - // Get the 'versionsSupported' attribute - versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); - - // Get the 'convertToId' attribute - convertToId = element.getAttribute(CONVERT_TO_ID); - - // Get the comma-separated list of valid OS - String os = element.getAttribute(OS_LIST); - if (os != null) { - osList = new ArrayList(); - String[] osTokens = os.split(","); //$NON-NLS-1$ - for (int i = 0; i < osTokens.length; ++i) { - osList.add(osTokens[i].trim()); - } - } - - // Get the comma-separated list of valid Architectures - String arch = element.getAttribute(ARCH_LIST); - if (arch != null) { - archList = new ArrayList(); - String[] archTokens = arch.split(","); //$NON-NLS-1$ - for (int j = 0; j < archTokens.length; ++j) { - archList.add(archTokens[j].trim()); - } - } - - // Get the isToolchainSupported configuration element - String managedIsToolChainSupported = element.getAttribute(IS_TOOL_CHAIN_SUPPORTED); - if (managedIsToolChainSupported != null && element instanceof DefaultManagedConfigElement) { - managedIsToolChainSupportedElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // Get the environmentVariableSupplier configuration element - String environmentVariableSupplier = element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER); - if(environmentVariableSupplier != null && element instanceof DefaultManagedConfigElement){ - environmentVariableSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // Get the configurationMacroSupplier configuration element - String buildMacroSupplier = element.getAttribute(CONFIGURATION_MACRO_SUPPLIER); - if(buildMacroSupplier != null && element instanceof DefaultManagedConfigElement){ - buildMacroSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - } - - - /* (non-Javadoc) - * Initialize the tool-chain information from the XML element - * specified in the argument - * - * @param element An XML element containing the tool-chain information - */ - protected void loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - setSuperClassInternal( ManagedBuildManager.getExtensionToolChain(superClassId) ); - // Check for migration support - checkForMigrationSupport(); - } - - // Get the unused children, if any - if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - } - - // isAbstract - if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - } - - // Get the semicolon separated list of IDs of the error parsers - if (element.hasAttribute(ERROR_PARSERS)) { - errorParserIds = element.getAttribute(ERROR_PARSERS); - } - - // Get the semicolon separated list of IDs of the secondary outputs - if (element.hasAttribute(SECONDARY_OUTPUTS)) { - secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); - } - - // Get the target tool id - if (element.hasAttribute(TARGET_TOOL)) { - targetToolIds = element.getAttribute(TARGET_TOOL); - } - - // Get the scanner config discovery profile id - if (element.hasAttribute(SCANNER_CONFIG_PROFILE_ID)) { - scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); - } - - // Get the 'versionSupported' attribute - if (element.hasAttribute(VERSIONS_SUPPORTED)) { - versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); - } - - // Get the 'convertToId' id - if (element.hasAttribute(CONVERT_TO_ID)) { - convertToId = element.getAttribute(CONVERT_TO_ID); - } - - // Get the comma-separated list of valid OS - if (element.hasAttribute(OS_LIST)) { - String os = element.getAttribute(OS_LIST); - if (os != null) { - osList = new ArrayList(); - String[] osTokens = os.split(","); //$NON-NLS-1$ - for (int i = 0; i < osTokens.length; ++i) { - osList.add(osTokens[i].trim()); - } - } - } - - // Get the comma-separated list of valid Architectures - if (element.hasAttribute(ARCH_LIST)) { - String arch = element.getAttribute(ARCH_LIST); - if (arch != null) { - archList = new ArrayList(); - String[] archTokens = arch.split(","); //$NON-NLS-1$ - for (int j = 0; j < archTokens.length; ++j) { - archList.add(archTokens[j].trim()); - } - } - } - } - - /** - * Persist the tool-chain to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - try { - if (getSuperClass() != null) - element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); - - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - if (unusedChildren != null) { - element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); - } - - if (isAbstract != null) { - element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); - } - - if (errorParserIds != null) { - element.setAttribute(ERROR_PARSERS, errorParserIds); - } - - if (secondaryOutputIds != null) { - element.setAttribute(SECONDARY_OUTPUTS, secondaryOutputIds); - } - - if (targetToolIds != null) { - element.setAttribute(TARGET_TOOL, targetToolIds); - } - - if (scannerConfigDiscoveryProfileId != null) { - element.setAttribute(SCANNER_CONFIG_PROFILE_ID, scannerConfigDiscoveryProfileId); - } - - // versionsSupported - if (versionsSupported != null) { - element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); - } - - // convertToId - if (convertToId != null) { - element.setAttribute(CONVERT_TO_ID, convertToId); - } - - if (osList != null) { - Iterator osIter = osList.listIterator(); - String listValue = EMPTY_STRING; - while (osIter.hasNext()) { - String current = (String) osIter.next(); - listValue += current; - if ((osIter.hasNext())) { - listValue += ","; //$NON-NLS-1$ - } - } - element.setAttribute(OS_LIST, listValue); - } - - if (archList != null) { - Iterator archIter = archList.listIterator(); - String listValue = EMPTY_STRING; - while (archIter.hasNext()) { - String current = (String) archIter.next(); - listValue += current; - if ((archIter.hasNext())) { - listValue += ","; //$NON-NLS-1$ - } - } - element.setAttribute(ARCH_LIST, listValue); - } - - // Serialize elements from my super class - super.serialize(doc, element); - - // Serialize my children - if (targetPlatform != null) { - Element targetPlatformElement = doc.createElement(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); - element.appendChild(targetPlatformElement); - targetPlatform.serialize(doc, targetPlatformElement); - } - if (builder != null) { - Element builderElement = doc.createElement(IBuilder.BUILDER_ELEMENT_NAME); - element.appendChild(builderElement); - builder.serialize(doc, builderElement); - } - List toolElements = getToolList(); - Iterator iter = toolElements.listIterator(); - while (iter.hasNext()) { - Tool tool = (Tool) iter.next(); - Element toolElement = doc.createElement(ITool.TOOL_ELEMENT_NAME); - element.appendChild(toolElement); - tool.serialize(doc, toolElement); - } - - // Note: isToolChainSupported cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (managedIsToolChainSupportedElement != null) { - // TODO: issue warning? - } - - // Note: environmentVariableSupplier cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if(environmentVariableSupplierElement != null) { - // TODO: issue warning? - } - - // Note: buildMacroSupplier cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if(buildMacroSupplierElement != null) { - // TODO: issue warning? - } - - //serialize user-defined macros - if(userDefinedMacros != null){ - Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); - element.appendChild(macrosElement); - userDefinedMacros.serialize(doc,macrosElement); - } - - if(userDefinedEnvironment != null) - EnvironmentVariableProvider.fUserSupplier.storeEnvironment(getParent(),true); - - // I am clean now - isDirty = false; - } catch (Exception e) { - // TODO: issue an error message - } -} - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getConfiguration() - */ - public IConfiguration getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#createTargetPlatform(ITargetPlatform, String, String, boolean) - */ - public ITargetPlatform createTargetPlatform(ITargetPlatform superClass, String id, String name, boolean isExtensionElement) { - targetPlatform = new TargetPlatform(this, superClass, id, name, isExtensionElement); - setDirty(true); - return (ITargetPlatform)targetPlatform; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getTargetPlatform() - */ - public ITargetPlatform getTargetPlatform() { - if (targetPlatform == null) { - if (getSuperClass() != null) { - return getSuperClass().getTargetPlatform(); - } - } - return (ITargetPlatform)targetPlatform; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalTargetPlatform() - */ - public void removeLocalTargetPlatform() { - if (targetPlatform == null) return; - targetPlatform = null; - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#createBuilder(IBuilder, String, String, boolean) - */ - public IBuilder createBuilder(IBuilder superClass, String id, String name, boolean isExtensionElement) { - builder = new Builder(this, superClass, id, name, isExtensionElement); - setDirty(true); - return (IBuilder)builder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getBuilder() - */ - public IBuilder getBuilder() { - if (builder == null) { - if (getSuperClass() != null) { - return getSuperClass().getBuilder(); - } - } - return (IBuilder)builder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalBuilder() - */ - public void removeLocalBuilder() { - if (builder == null) return; - builder = null; - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#createTool(ITool, String, String, boolean) - */ - public ITool createTool(ITool superClass, String id, String name, boolean isExtensionElement) { - Tool tool = new Tool(this, superClass, id, name, isExtensionElement); - addTool(tool); - setDirty(true); - return (ITool)tool; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getTools() - */ - public ITool[] getTools() { - ITool[] tools = null; - // Merge our tools with our superclass' tools - if (getSuperClass() != null) { - tools = getSuperClass().getTools(); - } - // Our tools take precedence - if (tools != null) { - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool tool = (Tool)iter.next(); - int j; - for (j = 0; j < tools.length; j++) { - if (tool.getSuperClass() != null // Remove assumption that ALL tools must have superclasses - && tool.getSuperClass().getId().equals(tools[j].getId())) { - tools[j] = tool; - break; - } - } - // No Match? Insert it (may be re-ordered) - if (j == tools.length) { - ITool[] newTools = new ITool[tools.length + 1]; - for (int k = 0; k < tools.length; k++) { - newTools[k] = tools[k]; - } - newTools[j] = tool; - tools = newTools; - } - } - } else { - tools = new ITool[getToolList().size()]; - Iterator iter = getToolList().listIterator(); - int i = 0; - while (iter.hasNext()) { - Tool tool = (Tool)iter.next(); - tools[i++] = (ITool)tool; - } - } - return tools; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getTool(java.lang.String) - */ - public ITool getTool(String id) { - Tool tool = (Tool)getToolMap().get(id); - return (ITool)tool; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getToolsBySuperClassId(java.lang.String) - */ - public ITool[] getToolsBySuperClassId(String id) { - List retTools = new ArrayList(); - if (id != null) { - // Look for a tool with this ID, or the tool(s) with a superclass with this id - ITool[] tools = getTools(); - for (int i = 0; i < tools.length; i++) { - ITool targetTool = tools[i]; - ITool tool = targetTool; - do { - if (id.equals(tool.getId())) { - retTools.add(targetTool); - break; - } - tool = tool.getSuperClass(); - } while (tool != null); - } - } - return (ITool[])retTools.toArray( new ITool[retTools.size()]); - } - - /* (non-Javadoc) - * Safe accessor for the list of tools. - * - * @return List containing the tools - */ - public List getToolList() { - if (toolList == null) { - toolList = new ArrayList(); - } - return toolList; - } - - /* (non-Javadoc) - * Safe accessor for the map of tool ids to tools - * - * @return - */ - private Map getToolMap() { - if (toolMap == null) { - toolMap = new HashMap(); - } - return toolMap; - } - - /* (non-Javadoc) - * Adds the Tool to the Tool-chain list and map - * - * @param Tool - */ - public void addTool(Tool tool) { - getToolList().add(tool); - getToolMap().put(tool.getId(), tool); - } - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSuperClass() - */ - public IToolChain getSuperClass() { - return (IToolChain)superClass; - } - - /* (non-Javadoc) - * Access function to set the superclass element that is defined in - * the base class. - */ - private void setSuperClassInternal(IToolChain superClass) { - this.superClass = superClass; - } - - public void setSuperClass(IToolChain superClass) { - if ( this.superClass != superClass ) { - this.superClass = superClass; - if ( this.superClass == null) { - superClassId = null; - } else { - superClassId = this.superClass.getId(); - } - - if(!isExtensionElement()) - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getName() - */ - public String getName() { - return (name == null && getSuperClass() != null) ? getSuperClass().getName() : name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#isAbstract() - */ - public boolean isAbstract() { - if (isAbstract != null) { - return isAbstract.booleanValue(); - } else { - return false; // Note: no inheritance from superClass - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getUnusedChildren() - */ - public String getUnusedChildren() { - if (unusedChildren != null) { - return unusedChildren; - } else - return EMPTY_STRING; // Note: no inheritance from superClass - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserIds() - */ - public String getErrorParserIds() { - String ids = errorParserIds; - if (ids == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - ids = getSuperClass().getErrorParserIds(); - } - } - if (ids == null) { - // Collect the error parsers from my children - ids = builder.getErrorParserIds(); - ITool[] tools = getTools(); - for (int i = 0; i < tools.length; i++) { - ITool tool = tools[i]; - String toolIds = tool.getErrorParserIds(); - if (toolIds != null && toolIds.length() > 0) { - if (ids != null) { - ids += ";"; //$NON-NLS-1$ - ids += toolIds; - } else { - ids = toolIds; - } - } - } - } - return ids; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSecondaryOutputs() - */ - public IOutputType[] getSecondaryOutputs() { - IOutputType[] types = null; - String ids = secondaryOutputIds; - if (ids == null) { - if (getSuperClass() != null) { - return getSuperClass().getSecondaryOutputs(); - } - else { - return new IOutputType[0]; - } - } - StringTokenizer tok = new StringTokenizer(ids, ";"); //$NON-NLS-1$ - types = new IOutputType[tok.countTokens()]; - ITool[] tools = getTools(); - int i = 0; - while (tok.hasMoreElements()) { - String id = tok.nextToken(); - for (int j=0; j 0) { - if (ids != null) { - ids += ";"; //$NON-NLS-1$ - ids += toolIds; - } else { - ids = toolIds; - } - } - } - } - return ids; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserList() - */ - public String[] getErrorParserList() { - String parserIDs = getErrorParserIds(); - String[] errorParsers; - if (parserIDs != null) { - // Check for an empty string - if (parserIDs.length() == 0) { - errorParsers = new String[0]; - } else { - StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ - List list = new ArrayList(tok.countTokens()); - while (tok.hasMoreElements()) { - list.add(tok.nextToken()); - } - String[] strArr = {""}; //$NON-NLS-1$ - errorParsers = (String[]) list.toArray(strArr); - } - } else { - errorParsers = new String[0]; - } - return errorParsers; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getArchList() - */ - public String[] getArchList() { - if (archList == null) { - // Ask superClass for its list - if (getSuperClass() != null) { - return getSuperClass().getArchList(); - } else { - // I have no superClass and no defined list - return new String[] {"all"}; //$NON-NLS-1$ - } - } - return (String[]) archList.toArray(new String[archList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getOSList() - */ - public String[] getOSList() { - if (osList == null) { - // Ask superClass for its list - if (getSuperClass() != null) { - return getSuperClass().getOSList(); - } else { - // I have no superClass and no defined filter list - return new String[] {"all"}; //$NON-NLS-1$ - } - } - return (String[]) osList.toArray(new String[osList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setIsAbstract(boolean) - */ - public void setIsAbstract(boolean b) { - isAbstract = new Boolean(b); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setErrorParserIds(String) - */ - public void setErrorParserIds(String ids) { - String currentIds = getErrorParserIds(); - if (ids == null && currentIds == null) return; - if (currentIds == null || ids == null || !(currentIds.equals(ids))) { - errorParserIds = ids; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setSecondaryOutputs() - */ - public void setSecondaryOutputs(String newIds) { - if (secondaryOutputIds == null && newIds == null) return; - if (secondaryOutputIds == null || newIds == null || !newIds.equals(secondaryOutputIds)) { - secondaryOutputIds = newIds; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setTargetToolIds() - */ - public void setTargetToolIds(String newIds) { - if (targetToolIds == null && newIds == null) return; - if (targetToolIds == null || newIds == null || !newIds.equals(targetToolIds)) { - targetToolIds = newIds; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setOSList(String[]) - */ - public void setOSList(String[] OSs) { - if (osList == null) { - osList = new ArrayList(); - } else { - osList.clear(); - } - for (int i = 0; i < OSs.length; i++) { - osList.add(OSs[i]); - } - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setArchList(String[]) - */ - public void setArchList(String[] archs) { - if (archList == null) { - archList = new ArrayList(); - } else { - archList.clear(); - } - for (int i = 0; i < archs.length; i++) { - archList.add(archs[i]); - } - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getScannerConfigDiscoveryProfileId() - */ - public String getScannerConfigDiscoveryProfileId() { - if (scannerConfigDiscoveryProfileId == null) { - if (getSuperClass() != null) { - return getSuperClass().getScannerConfigDiscoveryProfileId(); - } - } - return scannerConfigDiscoveryProfileId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setScannerConfigDiscoveryProfileId(java.lang.String) - */ - public void setScannerConfigDiscoveryProfileId(String profileId) { - if (scannerConfigDiscoveryProfileId == null && profileId == null) return; - if (scannerConfigDiscoveryProfileId == null || - !scannerConfigDiscoveryProfileId.equals(profileId)) { - scannerConfigDiscoveryProfileId = profileId; - setDirty(true); - } - } - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isExtensionElement() - */ - public boolean isExtensionElement() { - return isExtensionToolChain; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isDirty() - */ - public boolean isDirty() { - // This shouldn't be called for an extension tool-chain - if (isExtensionToolChain) return false; - - // If I need saving, just say yes - if (isDirty) return true; - - //check whether the tool-chain - specific macros are dirty - if(userDefinedMacros != null && userDefinedMacros.isDirty()) - return true; - - if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) - return true; - - if(builder != null && builder.isDirty()) - return true; - - // Otherwise see if any tools need saving - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - if (toolChild.isDirty()) return true; - } - - // Otherwise see if any options need saving - if (super.isDirty()) { - return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to options - super.setDirty(isDirty); - // Propagate "false" to the children - if (!isDirty) { - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - toolChild.setDirty(false); - } - } - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references - */ - public void resolveReferences() { - if (!resolved) { - resolved = true; - // Resolve superClass - if (superClassId != null && superClassId.length() > 0) { - setSuperClassInternal(ManagedBuildManager.getExtensionToolChain(superClassId)); - if (getSuperClass() == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "toolChain", //$NON-NLS-1$ - getId()); - } - } - // Resolve HoldsOptions - super.resolveReferences(); - // Call resolveReferences on our children - if (targetPlatform != null) { - targetPlatform.resolveReferences(); - } - if (builder != null) { - builder.resolveReferences(); - } - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - toolChild.resolveReferences(); - } - } - } - - /* (non-Javadoc) - * Normalize the list of output extensions,for all tools in the toolchain by populating the list - * with an empty string for those tools which have no explicit output extension (as defined in the - * manifest file. In a post 2.1 manifest, all tools must have a specifed output extension, even - * if it is "") - */ - public void normalizeOutputExtensions(){ - ITool[] tools = getTools(); - if (tools != null) { - for (int i = 0; i < tools.length; i++) { - ITool tool = tools[i]; - String[] extensions = tool.getOutputsAttribute(); - if (extensions == null) { - tool.setOutputsAttribute(""); //$NON-NLS-1$ - continue; - } - if (extensions.length == 0){ - tool.setOutputsAttribute(""); //$NON-NLS-1$ - continue; - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getConvertToId() - */ - public String getConvertToId() { - if (convertToId == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getConvertToId(); - } else { - return EMPTY_STRING; - } - } - return convertToId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setConvertToId(String) - */ - public void setConvertToId(String convertToId) { - if (convertToId == null && this.convertToId == null) return; - if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { - this.convertToId = convertToId; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getVersionsSupported() - */ - public String getVersionsSupported() { - if (versionsSupported == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getVersionsSupported(); - } else { - return EMPTY_STRING; - } - } - return versionsSupported; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setVersionsSupported(String) - */ - public void setVersionsSupported(String versionsSupported) { - if (versionsSupported == null && this.versionsSupported == null) return; - if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { - this.versionsSupported = versionsSupported; - setDirty(true); - } - return; - } - - private IConfigurationElement getIsToolChainSupportedElement(){ - if (managedIsToolChainSupportedElement == null) { - if (superClass != null && superClass instanceof ToolChain) { - return ((ToolChain)superClass).getIsToolChainSupportedElement(); - } - } - return managedIsToolChainSupportedElement; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isSupported() - */ - public boolean isSupported(){ - if (managedIsToolChainSupported == null) { - IConfigurationElement element = getIsToolChainSupportedElement(); - if (element != null) { - try { - if (element.getAttribute(IS_TOOL_CHAIN_SUPPORTED) != null) { - managedIsToolChainSupported = (IManagedIsToolChainSupported) element.createExecutableExtension(IS_TOOL_CHAIN_SUPPORTED); - } - } catch (CoreException e) {} - } - } - - if(managedIsToolChainSupported != null) - return managedIsToolChainSupported.isSupported(this,null,null); - return true; - } - - /** - * Returns the plugin.xml element of the configurationEnvironmentSupplier extension or null if none. - * - * @return IConfigurationElement - */ - public IConfigurationElement getEnvironmentVariableSupplierElement(){ - if (environmentVariableSupplierElement == null) { - if (getSuperClass() != null && getSuperClass() instanceof ToolChain) { - return ((ToolChain)getSuperClass()).getEnvironmentVariableSupplierElement(); - } - } - return environmentVariableSupplierElement; - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getEnvironmentVariableSupplier() - */ - public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(){ - if (environmentVariableSupplier != null) { - return environmentVariableSupplier; - } - IConfigurationElement element = getEnvironmentVariableSupplierElement(); - if (element != null) { - try { - if (element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER) != null) { - environmentVariableSupplier = (IConfigurationEnvironmentVariableSupplier) element.createExecutableExtension(CONFIGURATION_ENVIRONMENT_SUPPLIER); - return environmentVariableSupplier; - } - } catch (CoreException e) {} - } - return null; - } - - /* - * this method is called by the UserDefinedMacroSupplier to obtain user-defined - * macros available for this tool-chain - */ - public StorableMacros getUserDefinedMacros(){ - if(isExtensionToolChain) - return null; - - if(userDefinedMacros == null) - userDefinedMacros = new StorableMacros(); - return userDefinedMacros; - } - - public StorableEnvironment getUserDefinedEnvironment(){ - if(isExtensionToolChain) - return null; - - return userDefinedEnvironment; - } - - public void setUserDefinedEnvironment(StorableEnvironment env){ - if(!isExtensionToolChain) - userDefinedEnvironment = env; - } - - - /** - * Returns the plugin.xml element of the configurationMacroSupplier extension or null if none. - * - * @return IConfigurationElement - */ - public IConfigurationElement getBuildMacroSupplierElement(){ - if (buildMacroSupplierElement == null) { - if (superClass != null && superClass instanceof ToolChain) { - return ((ToolChain)superClass).getBuildMacroSupplierElement(); - } - } - return buildMacroSupplierElement; - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getBuildMacroSupplier() - */ - public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ - if (buildMacroSupplier != null) { - return buildMacroSupplier; - } - IConfigurationElement element = getBuildMacroSupplierElement(); - if (element != null) { - try { - if (element.getAttribute(CONFIGURATION_MACRO_SUPPLIER) != null) { - buildMacroSupplier = (IConfigurationBuildMacroSupplier) element.createExecutableExtension(CONFIGURATION_MACRO_SUPPLIER); - return buildMacroSupplier; - } - } catch (CoreException e) {} - } - return null; - } - - /* - * This function checks for migration support for the toolchain, while - * loading. If migration support is needed, looks for the available - * converters and adds them to the list. - */ - - public void checkForMigrationSupport() { - - boolean isExists = false; - - if (getSuperClass() == null) { - // If 'getSuperClass()' is null, then there is no toolchain available in - // plugin manifest file with the 'id' & version. - // Look for the 'versionsSupported' attribute - String high = (String) ManagedBuildManager - .getExtensionToolChainMap().lastKey(); - - SortedMap subMap = null; - if (superClassId.compareTo(high) <= 0) { - subMap = ManagedBuildManager.getExtensionToolChainMap().subMap( - superClassId, high + "\0"); //$NON-NLS-1$ - } else { - // It means there are no entries in the map for the given id. - // make the project is invalid - IConfiguration parentConfig = getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - return; - } - - // for each element in the 'subMap', - // check the 'versionsSupported' attribute whether the given - // toolChain version is supported - - String baseId = ManagedBuildManager.getIdFromIdAndVersion(superClassId); - String version = getVersionFromId().toString(); - - IToolChain[] toolChainElements = (IToolChain[]) subMap.values().toArray(); - - for (int i = 0; i < toolChainElements.length; i++) { - IToolChain toolChainElement = toolChainElements[i]; - - if (ManagedBuildManager.getIdFromIdAndVersion( - toolChainElement.getId()).compareTo(baseId) > 0) - break; - - // First check if both base ids are equal - if (ManagedBuildManager.getIdFromIdAndVersion( - toolChainElement.getId()).equals(baseId)) { - - // Check if 'versionsSupported' attribute is available' - String versionsSupported = toolChainElement.getVersionsSupported(); - - if ((versionsSupported != null) - && (!versionsSupported.equals(""))) { //$NON-NLS-1$ - String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ - - for (int j = 0; j < tmpVersions.length; j++) { - if (new PluginVersionIdentifier(version).equals(new PluginVersionIdentifier(tmpVersions[j]))) { - // version is supported. - // Do the automatic conversion without - // prompting the user. - // Get the supported version - String supportedVersion = ManagedBuildManager.getVersionFromIdAndVersion( - toolChainElement.getId()); - setId(ManagedBuildManager.getIdFromIdAndVersion(getId()) - + "_" + supportedVersion); //$NON-NLS-1$ - - // If control comes here means that 'superClass' is null - // So, set the superClass to this toolChain element - setSuperClassInternal(toolChainElement); - superClassId = getSuperClass().getId(); - isExists = true; - break; - } - } - if(isExists) - break; // break the outer for loop if 'isExists' is true - } - } - } - } - - if (getSuperClass() != null) { - // If 'getSuperClass()' is not null, look for 'convertToId' attribute in plugin - // manifest file for this toolchain. - String convertToId = getSuperClass().getConvertToId(); - if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ - // It means there is no 'convertToId' attribute available and - // the version is still actively - // supported by the tool integrator. So do nothing, just return - return; - } else { - // In case the 'convertToId' attribute is available, - // it means that Tool integrator currently does not support this - // version of toolchain. - // Look for the converters available for this toolchain version. - - getConverter(convertToId); - } - - } else { - // make the project is invalid - // - IConfiguration parentConfig = getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - } - return; - } - - private void getConverter(String convertToId) { - - String fromId = null; - String toId = null; - - // Get the Converter Extension Point - IExtensionPoint extensionPoint = Platform.getExtensionRegistry() - .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ - "projectConverter"); //$NON-NLS-1$ - if (extensionPoint != null) { - // Get the extensions - IExtension[] extensions = extensionPoint.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - // Get the configuration elements of each extension - IConfigurationElement[] configElements = extensions[i] - .getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - - IConfigurationElement element = configElements[j]; - - if (element.getName().equals("converter")) { //$NON-NLS-1$ - - fromId = element.getAttribute("fromId"); //$NON-NLS-1$ - toId = element.getAttribute("toId"); //$NON-NLS-1$ - // Check whether the current converter can be used for - // the selected toolchain - - if (fromId.equals(getSuperClass().getId()) - && toId.equals(convertToId)) { - // If it matches - String mbsVersion = element - .getAttribute("mbsVersion"); //$NON-NLS-1$ - PluginVersionIdentifier currentMbsVersion = ManagedBuildManager - .getBuildInfoVersion(); - - // set the converter element based on the MbsVersion - if (currentMbsVersion - .isGreaterThan(new PluginVersionIdentifier( - mbsVersion))) { - previousMbsVersionConversionElement = element; - } else { - currentMbsVersionConversionElement = element; - } - return; - } - } - } - } - } - - // If control comes here, it means 'Tool Integrator' specified - // 'convertToId' attribute in toolchain definition file, but - // has not provided any converter. - // So, make the project is invalid - - IConfiguration parentConfig = getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - } - - - public IConfigurationElement getPreviousMbsVersionConversionElement() { - return previousMbsVersionConversionElement; - } - - public IConfigurationElement getCurrentMbsVersionConversionElement() { - return currentMbsVersionConversionElement; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) - */ - public void updateManagedBuildRevision(String revision){ - super.updateManagedBuildRevision(revision); - - for(Iterator iter = getToolList().iterator(); iter.hasNext();){ - ((Tool)iter.next()).updateManagedBuildRevision(revision); - } - - if(builder != null) - builder.updateManagedBuildRevision(revision); - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2005 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.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.StringTokenizer; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.StorableEnvironment; +import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; +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; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class ToolChain extends HoldsOptions implements IToolChain { + + private static final String EMPTY_STRING = new String(); + + private static final boolean resolvedDefault = true; + + // Superclass + // Note that superClass itself is defined in the base and that the methods + // getSuperClass() and setSuperClassInternal(), defined in ToolChain must be used + // to access it. This avoids widespread casts from IHoldsOptions to IToolChain. + private String superClassId; + // Parent and children + private IConfiguration parent; + private List toolList; + private Map toolMap; + private TargetPlatform targetPlatform; + private Builder builder; + // Managed Build model attributes + private String unusedChildren; + private String errorParserIds; + private List osList; + private List archList; + private String targetToolIds; + private String secondaryOutputIds; + private Boolean isAbstract; + private String scannerConfigDiscoveryProfileId; + private String versionsSupported; + private String convertToId; + private IConfigurationElement managedIsToolChainSupportedElement = null; + private IManagedIsToolChainSupported managedIsToolChainSupported = null; + private IConfigurationElement environmentVariableSupplierElement = null; + private IConfigurationEnvironmentVariableSupplier environmentVariableSupplier = null; + private IConfigurationElement buildMacroSupplierElement = null; + private IConfigurationBuildMacroSupplier buildMacroSupplier = null; + + // Miscellaneous + private boolean isExtensionToolChain = false; + private boolean isDirty = false; + private boolean resolved = resolvedDefault; + //holds the user-defined macros + private StorableMacros userDefinedMacros; + //holds user-defined macros + private StorableEnvironment userDefinedEnvironment; + + private IConfigurationElement previousMbsVersionConversionElement = null; + private IConfigurationElement currentMbsVersionConversionElement = null; + + /* + * C O N S T R U C T O R S + */ + + /** + * This constructor is called to create a tool-chain defined by an extension point in + * a plugin manifest file, or returned by a dynamic element provider + * + * @param parent The IConfiguration parent of this tool-chain, or null if + * defined at the top level + * @param element The tool-chain definition from the manifest file or a dynamic element + * provider + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public ToolChain(IConfiguration parent, IManagedConfigElement element, String managedBuildRevision) { + // setup for resolving + super(false); + resolved = false; + + this.parent = parent; + isExtensionToolChain = true; + + // Set the managedBuildRevision + setManagedBuildRevision(managedBuildRevision); + + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionToolChain(this); + + // Load the TargetPlatform child + IManagedConfigElement[] targetPlatforms = + element.getChildren(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); + if (targetPlatforms.length < 1 || targetPlatforms.length > 1) { + // TODO: Report error + } + if (targetPlatforms.length > 0) { + targetPlatform = new TargetPlatform(this, targetPlatforms[0], managedBuildRevision); + } + + // Load the Builder child + IManagedConfigElement[] builders = + element.getChildren(IBuilder.BUILDER_ELEMENT_NAME); + if (builders.length < 1 || builders.length > 1) { + // TODO: Report error + } + if (builders.length > 0) { + builder = new Builder(this, builders[0], managedBuildRevision); + } + + // Load children + IManagedConfigElement[] toolChainElements = element.getChildren(); + for (int l = 0; l < toolChainElements.length; ++l) { + IManagedConfigElement toolChainElement = toolChainElements[l]; + if (loadChild(toolChainElement)) { + // do nothing + } else if (toolChainElement.getName().equals(ITool.TOOL_ELEMENT_NAME)) { + Tool toolChild = new Tool(this, toolChainElement, managedBuildRevision); + addTool(toolChild); + } + } + } + + /** + * This constructor is called to create a ToolChain whose attributes and children will be + * added by separate calls. + * + * @param Configuration The parent of the tool chain, if any + * @param ToolChain The superClass, if any + * @param String The id for the new tool chain + * @param String The name for the new tool chain + * @param boolean Indicates whether this is an extension element or a managed project element + */ + public ToolChain(Configuration parent, IToolChain superClass, String Id, String name, boolean isExtensionElement) { + super(resolvedDefault); + this.parent = parent; + setSuperClassInternal(superClass); + setManagedBuildRevision(parent.getManagedBuildRevision()); + + if (getSuperClass() != null) { + superClassId = getSuperClass().getId(); + } + setId(Id); + setName(name); + setVersion(getVersionFromId()); + + isExtensionToolChain = isExtensionElement; + if (isExtensionElement) { + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionToolChain(this); + } else { + setDirty(true); + } + } + + /** + * Create a ToolChain based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The IConfiguration the tool-chain will be added to. + * @param element The XML element that contains the tool-chain settings. + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public ToolChain(IConfiguration parent, Element element, String managedBuildRevision) { + super(resolvedDefault); + this.parent = parent; + isExtensionToolChain = false; + + // Set the managedBuildRevision + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromProject(element); + + // Load children + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (loadChild(configElement)) { + // do nothing + } else if (configElement.getNodeName().equals(ITool.TOOL_ELEMENT_NAME)) { + Tool tool = new Tool(this, (Element)configElement, managedBuildRevision); + addTool(tool); + }else if (configElement.getNodeName().equals(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME)) { + if (targetPlatform != null) { + // TODO: report error + } + targetPlatform = new TargetPlatform(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(IBuilder.BUILDER_ELEMENT_NAME)) { + if (builder != null) { + // TODO: report error + } + builder = new Builder(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { + //load user-defined macros + userDefinedMacros = new StorableMacros((Element)configElement); + + } + } + } + + /** + * Create a ToolChain based upon an existing tool chain. + * + * @param parent The IConfiguration the tool-chain will be added to. + * @param toolChain The existing tool-chain to clone. + */ + public ToolChain(IConfiguration parent, String Id, String name, ToolChain toolChain) { + super(resolvedDefault); + this.parent = parent; + setSuperClassInternal(toolChain.getSuperClass()); + if (getSuperClass() != null) { + if (toolChain.superClassId != null) { + superClassId = new String(toolChain.superClassId); + } + } + setId(Id); + setName(name); + + // Set the managedBuildRevision and the version + setManagedBuildRevision(toolChain.getManagedBuildRevision()); + setVersion(getVersionFromId()); + + isExtensionToolChain = false; + + // Copy the remaining attributes + if(toolChain.versionsSupported != null) { + versionsSupported = new String(toolChain.versionsSupported); + } + if(toolChain.convertToId != null) { + convertToId = new String(toolChain.convertToId); + } + + if (toolChain.unusedChildren != null) { + unusedChildren = new String(toolChain.unusedChildren); + } + if (toolChain.errorParserIds != null) { + errorParserIds = new String(toolChain.errorParserIds); + } + if (toolChain.osList != null) { + osList = new ArrayList(toolChain.osList); + } + if (toolChain.archList != null) { + archList = new ArrayList(toolChain.archList); + } + if (toolChain.targetToolIds != null) { + targetToolIds = new String(toolChain.targetToolIds); + } + if (toolChain.secondaryOutputIds != null) { + secondaryOutputIds = new String(toolChain.secondaryOutputIds); + } + if (toolChain.isAbstract != null) { + isAbstract = new Boolean(toolChain.isAbstract.booleanValue()); + } + if (toolChain.scannerConfigDiscoveryProfileId != null) { + scannerConfigDiscoveryProfileId = new String(toolChain.scannerConfigDiscoveryProfileId); + } + managedIsToolChainSupportedElement = toolChain.managedIsToolChainSupportedElement; + managedIsToolChainSupported = toolChain.managedIsToolChainSupported; + + environmentVariableSupplierElement = toolChain.environmentVariableSupplierElement; + environmentVariableSupplier = toolChain.environmentVariableSupplier; + + buildMacroSupplierElement = toolChain.buildMacroSupplierElement; + buildMacroSupplier = toolChain.buildMacroSupplier; + + // Clone the children in superclass + super.copyChildren(toolChain); + // Clone the children + if (toolChain.builder != null) { + String subId; + String subName; + + if (toolChain.builder.getSuperClass() != null) { + subId = ManagedBuildManager.calculateChildId( + toolChain.builder.getSuperClass().getId(), + null); + subName = toolChain.builder.getSuperClass().getName(); + } else { + subId = ManagedBuildManager.calculateChildId( + toolChain.builder.getId(), + null); + subName = toolChain.builder.getName(); + } + + builder = new Builder(this, subId, subName, toolChain.builder); + } + if (toolChain.targetPlatform != null) { + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (toolChain.targetPlatform.getSuperClass() != null) { + subId = toolChain.targetPlatform.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = toolChain.targetPlatform.getSuperClass().getName(); + } else { + subId = toolChain.targetPlatform.getId() + "." + nnn; //$NON-NLS-1$ + subName = toolChain.targetPlatform.getName(); + } + targetPlatform = new TargetPlatform(this, subId, subName, toolChain.targetPlatform); + } + if (toolChain.toolList != null) { + Iterator iter = toolChain.getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String tmpId; + String subName; + String version; + + if (toolChild.getSuperClass() != null) { + tmpId = toolChild.getSuperClass().getId(); + subName = toolChild.getSuperClass().getName(); + } else { + tmpId = toolChild.getId(); + subName = toolChild.getName(); + } + version = ManagedBuildManager.getVersionFromIdAndVersion(tmpId); + if ( version != null) { // If the 'tmpId' contains version information + subId = ManagedBuildManager.getIdFromIdAndVersion(tmpId) + "." + nnn + "_" + version; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + subId = tmpId + "." + nnn; //$NON-NLS-1$ + } + + Tool newTool = new Tool(this, null, subId, subName, toolChild); + addTool(newTool); + } + } + + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Loads the tool-chain information from the ManagedConfigElement specified in the + * argument. + * + * @param element Contains the tool-chain information + */ + protected void loadFromManifest(IManagedConfigElement element) { + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // Get the name + setName(element.getAttribute(IBuildObject.NAME)); + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // Get the unused children, if any + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + + // isAbstract + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + + // Get the semicolon separated list of IDs of the error parsers + errorParserIds = element.getAttribute(ERROR_PARSERS); + + // Get the semicolon separated list of IDs of the secondary outputs + secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); + + // Get the target tool id + targetToolIds = element.getAttribute(TARGET_TOOL); + + // Get the scanner config discovery profile id + scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); + + // Get the 'versionsSupported' attribute + versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); + + // Get the 'convertToId' attribute + convertToId = element.getAttribute(CONVERT_TO_ID); + + // Get the comma-separated list of valid OS + String os = element.getAttribute(OS_LIST); + if (os != null) { + osList = new ArrayList(); + String[] osTokens = os.split(","); //$NON-NLS-1$ + for (int i = 0; i < osTokens.length; ++i) { + osList.add(osTokens[i].trim()); + } + } + + // Get the comma-separated list of valid Architectures + String arch = element.getAttribute(ARCH_LIST); + if (arch != null) { + archList = new ArrayList(); + String[] archTokens = arch.split(","); //$NON-NLS-1$ + for (int j = 0; j < archTokens.length; ++j) { + archList.add(archTokens[j].trim()); + } + } + + // Get the isToolchainSupported configuration element + String managedIsToolChainSupported = element.getAttribute(IS_TOOL_CHAIN_SUPPORTED); + if (managedIsToolChainSupported != null && element instanceof DefaultManagedConfigElement) { + managedIsToolChainSupportedElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // Get the environmentVariableSupplier configuration element + String environmentVariableSupplier = element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER); + if(environmentVariableSupplier != null && element instanceof DefaultManagedConfigElement){ + environmentVariableSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // Get the configurationMacroSupplier configuration element + String buildMacroSupplier = element.getAttribute(CONFIGURATION_MACRO_SUPPLIER); + if(buildMacroSupplier != null && element instanceof DefaultManagedConfigElement){ + buildMacroSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + } + + + /* (non-Javadoc) + * Initialize the tool-chain information from the XML element + * specified in the argument + * + * @param element An XML element containing the tool-chain information + */ + protected void loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + setSuperClassInternal( ManagedBuildManager.getExtensionToolChain(superClassId) ); + // Check for migration support + checkForMigrationSupport(); + } + + // Get the unused children, if any + if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + } + + // isAbstract + if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + } + + // Get the semicolon separated list of IDs of the error parsers + if (element.hasAttribute(ERROR_PARSERS)) { + errorParserIds = element.getAttribute(ERROR_PARSERS); + } + + // Get the semicolon separated list of IDs of the secondary outputs + if (element.hasAttribute(SECONDARY_OUTPUTS)) { + secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); + } + + // Get the target tool id + if (element.hasAttribute(TARGET_TOOL)) { + targetToolIds = element.getAttribute(TARGET_TOOL); + } + + // Get the scanner config discovery profile id + if (element.hasAttribute(SCANNER_CONFIG_PROFILE_ID)) { + scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); + } + + // Get the 'versionSupported' attribute + if (element.hasAttribute(VERSIONS_SUPPORTED)) { + versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); + } + + // Get the 'convertToId' id + if (element.hasAttribute(CONVERT_TO_ID)) { + convertToId = element.getAttribute(CONVERT_TO_ID); + } + + // Get the comma-separated list of valid OS + if (element.hasAttribute(OS_LIST)) { + String os = element.getAttribute(OS_LIST); + if (os != null) { + osList = new ArrayList(); + String[] osTokens = os.split(","); //$NON-NLS-1$ + for (int i = 0; i < osTokens.length; ++i) { + osList.add(osTokens[i].trim()); + } + } + } + + // Get the comma-separated list of valid Architectures + if (element.hasAttribute(ARCH_LIST)) { + String arch = element.getAttribute(ARCH_LIST); + if (arch != null) { + archList = new ArrayList(); + String[] archTokens = arch.split(","); //$NON-NLS-1$ + for (int j = 0; j < archTokens.length; ++j) { + archList.add(archTokens[j].trim()); + } + } + } + } + + /** + * Persist the tool-chain to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + try { + if (getSuperClass() != null) + element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + if (errorParserIds != null) { + element.setAttribute(ERROR_PARSERS, errorParserIds); + } + + if (secondaryOutputIds != null) { + element.setAttribute(SECONDARY_OUTPUTS, secondaryOutputIds); + } + + if (targetToolIds != null) { + element.setAttribute(TARGET_TOOL, targetToolIds); + } + + if (scannerConfigDiscoveryProfileId != null) { + element.setAttribute(SCANNER_CONFIG_PROFILE_ID, scannerConfigDiscoveryProfileId); + } + + // versionsSupported + if (versionsSupported != null) { + element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); + } + + // convertToId + if (convertToId != null) { + element.setAttribute(CONVERT_TO_ID, convertToId); + } + + if (osList != null) { + Iterator osIter = osList.listIterator(); + String listValue = EMPTY_STRING; + while (osIter.hasNext()) { + String current = (String) osIter.next(); + listValue += current; + if ((osIter.hasNext())) { + listValue += ","; //$NON-NLS-1$ + } + } + element.setAttribute(OS_LIST, listValue); + } + + if (archList != null) { + Iterator archIter = archList.listIterator(); + String listValue = EMPTY_STRING; + while (archIter.hasNext()) { + String current = (String) archIter.next(); + listValue += current; + if ((archIter.hasNext())) { + listValue += ","; //$NON-NLS-1$ + } + } + element.setAttribute(ARCH_LIST, listValue); + } + + // Serialize elements from my super class + super.serialize(doc, element); + + // Serialize my children + if (targetPlatform != null) { + Element targetPlatformElement = doc.createElement(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); + element.appendChild(targetPlatformElement); + targetPlatform.serialize(doc, targetPlatformElement); + } + if (builder != null) { + Element builderElement = doc.createElement(IBuilder.BUILDER_ELEMENT_NAME); + element.appendChild(builderElement); + builder.serialize(doc, builderElement); + } + List toolElements = getToolList(); + Iterator iter = toolElements.listIterator(); + while (iter.hasNext()) { + Tool tool = (Tool) iter.next(); + Element toolElement = doc.createElement(ITool.TOOL_ELEMENT_NAME); + element.appendChild(toolElement); + tool.serialize(doc, toolElement); + } + + // Note: isToolChainSupported cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (managedIsToolChainSupportedElement != null) { + // TODO: issue warning? + } + + // Note: environmentVariableSupplier cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if(environmentVariableSupplierElement != null) { + // TODO: issue warning? + } + + // Note: buildMacroSupplier cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if(buildMacroSupplierElement != null) { + // TODO: issue warning? + } + + //serialize user-defined macros + if(userDefinedMacros != null){ + Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); + element.appendChild(macrosElement); + userDefinedMacros.serialize(doc,macrosElement); + } + + if(userDefinedEnvironment != null) + EnvironmentVariableProvider.fUserSupplier.storeEnvironment(getParent(),true); + + // I am clean now + isDirty = false; + } catch (Exception e) { + // TODO: issue an error message + } +} + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getConfiguration() + */ + public IConfiguration getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#createTargetPlatform(ITargetPlatform, String, String, boolean) + */ + public ITargetPlatform createTargetPlatform(ITargetPlatform superClass, String id, String name, boolean isExtensionElement) { + targetPlatform = new TargetPlatform(this, superClass, id, name, isExtensionElement); + setDirty(true); + return (ITargetPlatform)targetPlatform; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getTargetPlatform() + */ + public ITargetPlatform getTargetPlatform() { + if (targetPlatform == null) { + if (getSuperClass() != null) { + return getSuperClass().getTargetPlatform(); + } + } + return (ITargetPlatform)targetPlatform; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalTargetPlatform() + */ + public void removeLocalTargetPlatform() { + if (targetPlatform == null) return; + targetPlatform = null; + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#createBuilder(IBuilder, String, String, boolean) + */ + public IBuilder createBuilder(IBuilder superClass, String id, String name, boolean isExtensionElement) { + builder = new Builder(this, superClass, id, name, isExtensionElement); + setDirty(true); + return (IBuilder)builder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getBuilder() + */ + public IBuilder getBuilder() { + if (builder == null) { + if (getSuperClass() != null) { + return getSuperClass().getBuilder(); + } + } + return (IBuilder)builder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalBuilder() + */ + public void removeLocalBuilder() { + if (builder == null) return; + builder = null; + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#createTool(ITool, String, String, boolean) + */ + public ITool createTool(ITool superClass, String id, String name, boolean isExtensionElement) { + Tool tool = new Tool(this, superClass, id, name, isExtensionElement); + addTool(tool); + setDirty(true); + return (ITool)tool; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getTools() + */ + public ITool[] getTools() { + ITool[] tools = null; + // Merge our tools with our superclass' tools + if (getSuperClass() != null) { + tools = getSuperClass().getTools(); + } + // Our tools take precedence + if (tools != null) { + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool tool = (Tool)iter.next(); + int j; + for (j = 0; j < tools.length; j++) { + if (tool.getSuperClass() != null // Remove assumption that ALL tools must have superclasses + && tool.getSuperClass().getId().equals(tools[j].getId())) { + tools[j] = tool; + break; + } + } + // No Match? Insert it (may be re-ordered) + if (j == tools.length) { + ITool[] newTools = new ITool[tools.length + 1]; + for (int k = 0; k < tools.length; k++) { + newTools[k] = tools[k]; + } + newTools[j] = tool; + tools = newTools; + } + } + } else { + tools = new ITool[getToolList().size()]; + Iterator iter = getToolList().listIterator(); + int i = 0; + while (iter.hasNext()) { + Tool tool = (Tool)iter.next(); + tools[i++] = (ITool)tool; + } + } + return tools; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getTool(java.lang.String) + */ + public ITool getTool(String id) { + Tool tool = (Tool)getToolMap().get(id); + return (ITool)tool; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getToolsBySuperClassId(java.lang.String) + */ + public ITool[] getToolsBySuperClassId(String id) { + List retTools = new ArrayList(); + if (id != null) { + // Look for a tool with this ID, or the tool(s) with a superclass with this id + ITool[] tools = getTools(); + for (int i = 0; i < tools.length; i++) { + ITool targetTool = tools[i]; + ITool tool = targetTool; + do { + if (id.equals(tool.getId())) { + retTools.add(targetTool); + break; + } + tool = tool.getSuperClass(); + } while (tool != null); + } + } + return (ITool[])retTools.toArray( new ITool[retTools.size()]); + } + + /* (non-Javadoc) + * Safe accessor for the list of tools. + * + * @return List containing the tools + */ + public List getToolList() { + if (toolList == null) { + toolList = new ArrayList(); + } + return toolList; + } + + /* (non-Javadoc) + * Safe accessor for the map of tool ids to tools + * + * @return + */ + private Map getToolMap() { + if (toolMap == null) { + toolMap = new HashMap(); + } + return toolMap; + } + + /* (non-Javadoc) + * Adds the Tool to the Tool-chain list and map + * + * @param Tool + */ + public void addTool(Tool tool) { + getToolList().add(tool); + getToolMap().put(tool.getId(), tool); + } + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSuperClass() + */ + public IToolChain getSuperClass() { + return (IToolChain)superClass; + } + + /* (non-Javadoc) + * Access function to set the superclass element that is defined in + * the base class. + */ + private void setSuperClassInternal(IToolChain superClass) { + this.superClass = superClass; + } + + public void setSuperClass(IToolChain superClass) { + if ( this.superClass != superClass ) { + this.superClass = superClass; + if ( this.superClass == null) { + superClassId = null; + } else { + superClassId = this.superClass.getId(); + } + + if(!isExtensionElement()) + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getName() + */ + public String getName() { + return (name == null && getSuperClass() != null) ? getSuperClass().getName() : name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#isAbstract() + */ + public boolean isAbstract() { + if (isAbstract != null) { + return isAbstract.booleanValue(); + } else { + return false; // Note: no inheritance from superClass + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getUnusedChildren() + */ + public String getUnusedChildren() { + if (unusedChildren != null) { + return unusedChildren; + } else + return EMPTY_STRING; // Note: no inheritance from superClass + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserIds() + */ + public String getErrorParserIds() { + String ids = errorParserIds; + if (ids == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + ids = getSuperClass().getErrorParserIds(); + } + } + if (ids == null) { + // Collect the error parsers from my children + ids = builder.getErrorParserIds(); + ITool[] tools = getTools(); + for (int i = 0; i < tools.length; i++) { + ITool tool = tools[i]; + String toolIds = tool.getErrorParserIds(); + if (toolIds != null && toolIds.length() > 0) { + if (ids != null) { + ids += ";"; //$NON-NLS-1$ + ids += toolIds; + } else { + ids = toolIds; + } + } + } + } + return ids; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSecondaryOutputs() + */ + public IOutputType[] getSecondaryOutputs() { + IOutputType[] types = null; + String ids = secondaryOutputIds; + if (ids == null) { + if (getSuperClass() != null) { + return getSuperClass().getSecondaryOutputs(); + } + else { + return new IOutputType[0]; + } + } + StringTokenizer tok = new StringTokenizer(ids, ";"); //$NON-NLS-1$ + types = new IOutputType[tok.countTokens()]; + ITool[] tools = getTools(); + int i = 0; + while (tok.hasMoreElements()) { + String id = tok.nextToken(); + for (int j=0; j 0) { + if (ids != null) { + ids += ";"; //$NON-NLS-1$ + ids += toolIds; + } else { + ids = toolIds; + } + } + } + } + return ids; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserList() + */ + public String[] getErrorParserList() { + String parserIDs = getErrorParserIds(); + String[] errorParsers; + if (parserIDs != null) { + // Check for an empty string + if (parserIDs.length() == 0) { + errorParsers = new String[0]; + } else { + StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ + List list = new ArrayList(tok.countTokens()); + while (tok.hasMoreElements()) { + list.add(tok.nextToken()); + } + String[] strArr = {""}; //$NON-NLS-1$ + errorParsers = (String[]) list.toArray(strArr); + } + } else { + errorParsers = new String[0]; + } + return errorParsers; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getArchList() + */ + public String[] getArchList() { + if (archList == null) { + // Ask superClass for its list + if (getSuperClass() != null) { + return getSuperClass().getArchList(); + } else { + // I have no superClass and no defined list + return new String[] {"all"}; //$NON-NLS-1$ + } + } + return (String[]) archList.toArray(new String[archList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getOSList() + */ + public String[] getOSList() { + if (osList == null) { + // Ask superClass for its list + if (getSuperClass() != null) { + return getSuperClass().getOSList(); + } else { + // I have no superClass and no defined filter list + return new String[] {"all"}; //$NON-NLS-1$ + } + } + return (String[]) osList.toArray(new String[osList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setIsAbstract(boolean) + */ + public void setIsAbstract(boolean b) { + isAbstract = new Boolean(b); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setErrorParserIds(String) + */ + public void setErrorParserIds(String ids) { + String currentIds = getErrorParserIds(); + if (ids == null && currentIds == null) return; + if (currentIds == null || ids == null || !(currentIds.equals(ids))) { + errorParserIds = ids; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setSecondaryOutputs() + */ + public void setSecondaryOutputs(String newIds) { + if (secondaryOutputIds == null && newIds == null) return; + if (secondaryOutputIds == null || newIds == null || !newIds.equals(secondaryOutputIds)) { + secondaryOutputIds = newIds; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setTargetToolIds() + */ + public void setTargetToolIds(String newIds) { + if (targetToolIds == null && newIds == null) return; + if (targetToolIds == null || newIds == null || !newIds.equals(targetToolIds)) { + targetToolIds = newIds; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setOSList(String[]) + */ + public void setOSList(String[] OSs) { + if (osList == null) { + osList = new ArrayList(); + } else { + osList.clear(); + } + for (int i = 0; i < OSs.length; i++) { + osList.add(OSs[i]); + } + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setArchList(String[]) + */ + public void setArchList(String[] archs) { + if (archList == null) { + archList = new ArrayList(); + } else { + archList.clear(); + } + for (int i = 0; i < archs.length; i++) { + archList.add(archs[i]); + } + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getScannerConfigDiscoveryProfileId() + */ + public String getScannerConfigDiscoveryProfileId() { + if (scannerConfigDiscoveryProfileId == null) { + if (getSuperClass() != null) { + return getSuperClass().getScannerConfigDiscoveryProfileId(); + } + } + return scannerConfigDiscoveryProfileId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setScannerConfigDiscoveryProfileId(java.lang.String) + */ + public void setScannerConfigDiscoveryProfileId(String profileId) { + if (scannerConfigDiscoveryProfileId == null && profileId == null) return; + if (scannerConfigDiscoveryProfileId == null || + !scannerConfigDiscoveryProfileId.equals(profileId)) { + scannerConfigDiscoveryProfileId = profileId; + setDirty(true); + } + } + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isExtensionElement() + */ + public boolean isExtensionElement() { + return isExtensionToolChain; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isDirty() + */ + public boolean isDirty() { + // This shouldn't be called for an extension tool-chain + if (isExtensionToolChain) return false; + + // If I need saving, just say yes + if (isDirty) return true; + + //check whether the tool-chain - specific macros are dirty + if(userDefinedMacros != null && userDefinedMacros.isDirty()) + return true; + + if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) + return true; + + if(builder != null && builder.isDirty()) + return true; + + // Otherwise see if any tools need saving + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + if (toolChild.isDirty()) return true; + } + + // Otherwise see if any options need saving + if (super.isDirty()) { + return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to options + super.setDirty(isDirty); + // Propagate "false" to the children + if (!isDirty) { + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + toolChild.setDirty(false); + } + } + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references + */ + public void resolveReferences() { + if (!resolved) { + resolved = true; + // Resolve superClass + if (superClassId != null && superClassId.length() > 0) { + setSuperClassInternal(ManagedBuildManager.getExtensionToolChain(superClassId)); + if (getSuperClass() == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "toolChain", //$NON-NLS-1$ + getId()); + } + } + // Resolve HoldsOptions + super.resolveReferences(); + // Call resolveReferences on our children + if (targetPlatform != null) { + targetPlatform.resolveReferences(); + } + if (builder != null) { + builder.resolveReferences(); + } + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + toolChild.resolveReferences(); + } + } + } + + /* (non-Javadoc) + * Normalize the list of output extensions,for all tools in the toolchain by populating the list + * with an empty string for those tools which have no explicit output extension (as defined in the + * manifest file. In a post 2.1 manifest, all tools must have a specifed output extension, even + * if it is "") + */ + public void normalizeOutputExtensions(){ + ITool[] tools = getTools(); + if (tools != null) { + for (int i = 0; i < tools.length; i++) { + ITool tool = tools[i]; + String[] extensions = tool.getOutputsAttribute(); + if (extensions == null) { + tool.setOutputsAttribute(""); //$NON-NLS-1$ + continue; + } + if (extensions.length == 0){ + tool.setOutputsAttribute(""); //$NON-NLS-1$ + continue; + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getConvertToId() + */ + public String getConvertToId() { + if (convertToId == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getConvertToId(); + } else { + return EMPTY_STRING; + } + } + return convertToId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setConvertToId(String) + */ + public void setConvertToId(String convertToId) { + if (convertToId == null && this.convertToId == null) return; + if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { + this.convertToId = convertToId; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getVersionsSupported() + */ + public String getVersionsSupported() { + if (versionsSupported == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getVersionsSupported(); + } else { + return EMPTY_STRING; + } + } + return versionsSupported; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setVersionsSupported(String) + */ + public void setVersionsSupported(String versionsSupported) { + if (versionsSupported == null && this.versionsSupported == null) return; + if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { + this.versionsSupported = versionsSupported; + setDirty(true); + } + return; + } + + private IConfigurationElement getIsToolChainSupportedElement(){ + if (managedIsToolChainSupportedElement == null) { + if (superClass != null && superClass instanceof ToolChain) { + return ((ToolChain)superClass).getIsToolChainSupportedElement(); + } + } + return managedIsToolChainSupportedElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isSupported() + */ + public boolean isSupported(){ + if (managedIsToolChainSupported == null) { + IConfigurationElement element = getIsToolChainSupportedElement(); + if (element != null) { + try { + if (element.getAttribute(IS_TOOL_CHAIN_SUPPORTED) != null) { + managedIsToolChainSupported = (IManagedIsToolChainSupported) element.createExecutableExtension(IS_TOOL_CHAIN_SUPPORTED); + } + } catch (CoreException e) {} + } + } + + if(managedIsToolChainSupported != null) + return managedIsToolChainSupported.isSupported(this,null,null); + return true; + } + + /** + * Returns the plugin.xml element of the configurationEnvironmentSupplier extension or null if none. + * + * @return IConfigurationElement + */ + public IConfigurationElement getEnvironmentVariableSupplierElement(){ + if (environmentVariableSupplierElement == null) { + if (getSuperClass() != null && getSuperClass() instanceof ToolChain) { + return ((ToolChain)getSuperClass()).getEnvironmentVariableSupplierElement(); + } + } + return environmentVariableSupplierElement; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getEnvironmentVariableSupplier() + */ + public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(){ + if (environmentVariableSupplier != null) { + return environmentVariableSupplier; + } + IConfigurationElement element = getEnvironmentVariableSupplierElement(); + if (element != null) { + try { + if (element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER) != null) { + environmentVariableSupplier = (IConfigurationEnvironmentVariableSupplier) element.createExecutableExtension(CONFIGURATION_ENVIRONMENT_SUPPLIER); + return environmentVariableSupplier; + } + } catch (CoreException e) {} + } + return null; + } + + /* + * this method is called by the UserDefinedMacroSupplier to obtain user-defined + * macros available for this tool-chain + */ + public StorableMacros getUserDefinedMacros(){ + if(isExtensionToolChain) + return null; + + if(userDefinedMacros == null) + userDefinedMacros = new StorableMacros(); + return userDefinedMacros; + } + + public StorableEnvironment getUserDefinedEnvironment(){ + if(isExtensionToolChain) + return null; + + return userDefinedEnvironment; + } + + public void setUserDefinedEnvironment(StorableEnvironment env){ + if(!isExtensionToolChain) + userDefinedEnvironment = env; + } + + + /** + * Returns the plugin.xml element of the configurationMacroSupplier extension or null if none. + * + * @return IConfigurationElement + */ + public IConfigurationElement getBuildMacroSupplierElement(){ + if (buildMacroSupplierElement == null) { + if (superClass != null && superClass instanceof ToolChain) { + return ((ToolChain)superClass).getBuildMacroSupplierElement(); + } + } + return buildMacroSupplierElement; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getBuildMacroSupplier() + */ + public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ + if (buildMacroSupplier != null) { + return buildMacroSupplier; + } + IConfigurationElement element = getBuildMacroSupplierElement(); + if (element != null) { + try { + if (element.getAttribute(CONFIGURATION_MACRO_SUPPLIER) != null) { + buildMacroSupplier = (IConfigurationBuildMacroSupplier) element.createExecutableExtension(CONFIGURATION_MACRO_SUPPLIER); + return buildMacroSupplier; + } + } catch (CoreException e) {} + } + return null; + } + + /* + * This function checks for migration support for the toolchain, while + * loading. If migration support is needed, looks for the available + * converters and adds them to the list. + */ + + public void checkForMigrationSupport() { + + boolean isExists = false; + + if (getSuperClass() == null) { + // If 'getSuperClass()' is null, then there is no toolchain available in + // plugin manifest file with the 'id' & version. + // Look for the 'versionsSupported' attribute + String high = (String) ManagedBuildManager + .getExtensionToolChainMap().lastKey(); + + SortedMap subMap = null; + if (superClassId.compareTo(high) <= 0) { + subMap = ManagedBuildManager.getExtensionToolChainMap().subMap( + superClassId, high + "\0"); //$NON-NLS-1$ + } else { + // It means there are no entries in the map for the given id. + // make the project is invalid + IConfiguration parentConfig = getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + return; + } + + // for each element in the 'subMap', + // check the 'versionsSupported' attribute whether the given + // toolChain version is supported + + String baseId = ManagedBuildManager.getIdFromIdAndVersion(superClassId); + String version = getVersionFromId().toString(); + + IToolChain[] toolChainElements = (IToolChain[]) subMap.values().toArray(); + + for (int i = 0; i < toolChainElements.length; i++) { + IToolChain toolChainElement = toolChainElements[i]; + + if (ManagedBuildManager.getIdFromIdAndVersion( + toolChainElement.getId()).compareTo(baseId) > 0) + break; + + // First check if both base ids are equal + if (ManagedBuildManager.getIdFromIdAndVersion( + toolChainElement.getId()).equals(baseId)) { + + // Check if 'versionsSupported' attribute is available' + String versionsSupported = toolChainElement.getVersionsSupported(); + + if ((versionsSupported != null) + && (!versionsSupported.equals(""))) { //$NON-NLS-1$ + String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ + + for (int j = 0; j < tmpVersions.length; j++) { + if (new PluginVersionIdentifier(version).equals(new PluginVersionIdentifier(tmpVersions[j]))) { + // version is supported. + // Do the automatic conversion without + // prompting the user. + // Get the supported version + String supportedVersion = ManagedBuildManager.getVersionFromIdAndVersion( + toolChainElement.getId()); + setId(ManagedBuildManager.getIdFromIdAndVersion(getId()) + + "_" + supportedVersion); //$NON-NLS-1$ + + // If control comes here means that 'superClass' is null + // So, set the superClass to this toolChain element + setSuperClassInternal(toolChainElement); + superClassId = getSuperClass().getId(); + isExists = true; + break; + } + } + if(isExists) + break; // break the outer for loop if 'isExists' is true + } + } + } + } + + if (getSuperClass() != null) { + // If 'getSuperClass()' is not null, look for 'convertToId' attribute in plugin + // manifest file for this toolchain. + String convertToId = getSuperClass().getConvertToId(); + if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ + // It means there is no 'convertToId' attribute available and + // the version is still actively + // supported by the tool integrator. So do nothing, just return + return; + } else { + // In case the 'convertToId' attribute is available, + // it means that Tool integrator currently does not support this + // version of toolchain. + // Look for the converters available for this toolchain version. + + getConverter(convertToId); + } + + } else { + // make the project is invalid + // + IConfiguration parentConfig = getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + } + return; + } + + private void getConverter(String convertToId) { + + String fromId = null; + String toId = null; + + // Get the Converter Extension Point + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ + "projectConverter"); //$NON-NLS-1$ + if (extensionPoint != null) { + // Get the extensions + IExtension[] extensions = extensionPoint.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + // Get the configuration elements of each extension + IConfigurationElement[] configElements = extensions[i] + .getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + + IConfigurationElement element = configElements[j]; + + if (element.getName().equals("converter")) { //$NON-NLS-1$ + + fromId = element.getAttribute("fromId"); //$NON-NLS-1$ + toId = element.getAttribute("toId"); //$NON-NLS-1$ + // Check whether the current converter can be used for + // the selected toolchain + + if (fromId.equals(getSuperClass().getId()) + && toId.equals(convertToId)) { + // If it matches + String mbsVersion = element + .getAttribute("mbsVersion"); //$NON-NLS-1$ + PluginVersionIdentifier currentMbsVersion = ManagedBuildManager + .getBuildInfoVersion(); + + // set the converter element based on the MbsVersion + if (currentMbsVersion + .isGreaterThan(new PluginVersionIdentifier( + mbsVersion))) { + previousMbsVersionConversionElement = element; + } else { + currentMbsVersionConversionElement = element; + } + return; + } + } + } + } + } + + // If control comes here, it means 'Tool Integrator' specified + // 'convertToId' attribute in toolchain definition file, but + // has not provided any converter. + // So, make the project is invalid + + IConfiguration parentConfig = getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + } + + + public IConfigurationElement getPreviousMbsVersionConversionElement() { + return previousMbsVersionConversionElement; + } + + public IConfigurationElement getCurrentMbsVersionConversionElement() { + return currentMbsVersionConversionElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) + */ + public void updateManagedBuildRevision(String revision){ + super.updateManagedBuildRevision(revision); + + for(Iterator iter = getToolList().iterator(); iter.hasNext();){ + ((Tool)iter.next()).updateManagedBuildRevision(revision); + } + + if(builder != null) + builder.updateManagedBuildRevision(revision); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java index 34feff3a9cd..cb150d7e7d8 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java @@ -1,1254 +1,1254 @@ -/******************************************************************************* - * Copyright (c) 2003, 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.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfigurationV2; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.IToolReference; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class ToolReference implements IToolReference { - private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ - - private String command; - private boolean isDirty = false; - private List optionReferences; - private IBuildObject owner; - private String outputExtensions; - private String outputFlag; - private String outputPrefix; - protected ITool parent; - private boolean resolved = true; - private String versionsSupported; - private String convertToId; - - /** - * Create a new tool reference based on information contained in - * a project file. - * - * @param owner The ConfigurationV2 the receiver will be added to. - * @param element The element defined in the project file containing build information - * for the receiver. - */ - public ToolReference(BuildObject owner, Element element) { - this.owner = owner; - - if (owner instanceof ConfigurationV2) { - if (parent == null) { - Target parentTarget = (Target) ((ConfigurationV2)owner).getTarget(); - try { - parent = ((Target)parentTarget.getParent()).getTool(element.getAttribute(ID)); - } catch (NullPointerException e) { - parent = null; - } - } - ((ConfigurationV2)owner).addToolReference(this); - } else if (owner instanceof Target) { - if (parent == null) { - try { - parent = ((Target)((Target)owner).getParent()).getTool(element.getAttribute(ID)); - } catch (NullPointerException e) { - parent = null; - } - } - ((Target)owner).addToolReference(this); - } - - // Get the overridden tool command (if any) - if (element.hasAttribute(ITool.COMMAND)) { - command = element.getAttribute(ITool.COMMAND); - } - - // Get the overridden output prefix (if any) - if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - } - - // Get the output extensions the reference produces - if (element.hasAttribute(ITool.OUTPUTS)) { - outputExtensions = element.getAttribute(ITool.OUTPUTS); - } - // Get the flag to control output - if (element.hasAttribute(ITool.OUTPUT_FLAG)) - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(ITool.OPTION_REF)) { - new OptionReference(this, (Element)configElement); - } - } - } - - /** - * Created tool reference from an extension defined in a plugin manifest. - * - * @param owner The BuildObject the receiver will be added to. - * @param element The element containing build information for the reference. - */ - public ToolReference(BuildObject owner, IManagedConfigElement element) { - // setup for resolving - ManagedBuildManager.putConfigElement(this, element); - resolved = false; - - this.owner = owner; - - // hook me up - if (owner instanceof ConfigurationV2) { - ((ConfigurationV2)owner).addToolReference(this); - } else if (owner instanceof Target) { - ((Target)owner).addToolReference(this); - } - - // Get the overridden tool command (if any) - command = element.getAttribute(ITool.COMMAND); - - // Get the overridden output prefix, if any - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - - // Get the overridden output extensions (if any) - String output = element.getAttribute(ITool.OUTPUTS); - if (output != null) { - outputExtensions = output; - } - - // Get the flag to control output - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - - IManagedConfigElement[] toolElements = element.getChildren(); - for (int m = 0; m < toolElements.length; ++m) { - IManagedConfigElement toolElement = toolElements[m]; - if (toolElement.getName().equals(ITool.OPTION_REF)) { - new OptionReference(this, toolElement); - } - } - } - - /** - * Created a tool reference on the fly based on an existing tool or tool reference. - * - * @param owner The BuildObject the receiver will be added to. - * @param tool The ITooltool the reference will be based on. - */ - public ToolReference(BuildObject owner, ITool tool) { - this.owner = owner; - if (tool instanceof ToolReference) { - parent = ((ToolReference)tool).getTool(); - } else { - parent = tool; - } - command = tool.getToolCommand(); - outputFlag = tool.getOutputFlag(); - outputPrefix = tool.getOutputPrefix(); - String[] extensions = tool.getOutputsAttribute(); - outputExtensions = new String(); - if (extensions != null) { - for (int index = 0; index < extensions.length; ++index) { - if (extensions[index] == null) continue; - outputExtensions += extensions[index]; - if (index < extensions.length - 1) { - outputExtensions += DEFAULT_SEPARATOR; - } - } - } - - // Create a copy of the option references of the parent in the receiver - if (tool instanceof ToolReference) { - List parentRefs = ((ToolReference)tool).getOptionReferenceList(); - Iterator iter = parentRefs.iterator(); - while (iter.hasNext()) { - IOption parent = (IOption)iter.next(); - OptionReference clone = createOptionReference(parent); - try { - switch (parent.getValueType()) { - case IOption.BOOLEAN: - clone.setValue(parent.getBooleanValue()); - break; - case IOption.STRING: - clone.setValue(parent.getStringValue()); - case IOption.ENUMERATED: - clone.setValue(parent.getSelectedEnum()); - break; - default: - clone.setValue(parent.getStringListValue()); - break; - } - } catch (BuildException e) { - // Likely a mismatch between the value and option type - continue; - } - } - } - - if (owner instanceof ConfigurationV2) { - ((ConfigurationV2)owner).addToolReference(this); - } else if (owner instanceof Target) { - ((Target)owner).addToolReference(this); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#references(org.eclipse.cdt.managedbuilder.core.ITool) - */ - public boolean references(ITool target) { - if (equals(target)) { - // we are the target - return true; - } else if (parent == null) { - // basic sanity before proceeding - return false; - } else if (parent instanceof IToolReference) { - // check the reference we are overriding - return ((IToolReference)parent).references(target); - } else if (target instanceof IToolReference) { - return parent.equals(((IToolReference)target).getTool()); - } else { - // the real reference - return parent.equals(target); - } - } - - public void resolveReferences() { - if (!resolved) { - resolved = true; - IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); - // resolve my parent - if (owner instanceof ConfigurationV2) { - Target target = (Target) ((ConfigurationV2)owner).getTarget(); - parent = target.getTool(element.getAttribute(ID)); - } else if (owner instanceof Target) { - parent = ((Target)owner).getTool(element.getAttribute(ID)); - } - // recursively resolve my parent - if (parent instanceof Tool) { - ((Tool)parent).resolveReferences(); - } else if (parent instanceof ToolReference) { - ((ToolReference)parent).resolveReferences(); - } - - Iterator it = getOptionReferenceList().iterator(); - while (it.hasNext()) { - OptionReference optRef = (OptionReference)it.next(); - optRef.resolveReferences(); - } - } - } - - /** - * Adds the option reference specified in the argument to the receiver. - * - * @param optionRef - */ - public void addOptionReference(OptionReference optionRef) { - getOptionReferenceList().add(optionRef); - isDirty = true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) - */ - public boolean buildsFileType(String extension) { - if (parent == null) { - // bad reference - return false; - } - return parent.buildsFileType(extension); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) - */ - public boolean isInputFileType(String extension) { - if (parent == null) { - // bad reference - return false; - } - return parent.isInputFileType(extension); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#createOptionReference(org.eclipse.cdt.managedbuilder.core.IOption) - */ - public OptionReference createOptionReference(IOption option) { - // Check if the option reference already exists - OptionReference ref = getOptionReference(option); - // It is possible that the search will return an option reference - // that is supplied by another element of the build model, not the caller. - // For example, if the search is starated by a configuration and the target - // the caller belongs to has an option reference for the option, it - // will be returned. While this is correct behaviour for a search, the - // caller will need to create a clone for itself, so make sure the tool - // reference of the search result is owned by the caller - if (ref == null || !ref.getToolReference().owner.equals(this.owner)) { - ref = new OptionReference(this, option); - } - return ref; - } - - /* (non-Javadoc) - * @return - */ - protected List getAllOptionRefs() { - // First get all the option references this tool reference contains - if (owner instanceof ConfigurationV2) { - return ((ConfigurationV2)owner).getOptionReferences(parent); - } else if (owner instanceof Target) { - return ((Target)owner).getOptionReferences(parent); - } else { - // this shouldn't happen - return null; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getId() - */ - public String getId() { - if (parent == null) { - // bad reference - return new String(); - } - return parent.getId(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getBaseId() - */ - public String getBaseId() { - if (parent == null) { - // bad reference - return new String(); - } - return parent.getBaseId(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputExtensions() - */ - public List getInputExtensions() { - String[] exts = getPrimaryInputExtensions(); - List extList = new ArrayList(); - for (int i=0; i 0) { - buf.append(boolCmd + WHITE_SPACE); - } - break; - - case IOption.ENUMERATED : - String enumVal = option.getEnumCommand(option.getSelectedEnum()); - if (enumVal.length() > 0) { - buf.append(enumVal + WHITE_SPACE); - } - break; - - case IOption.STRING : - String strCmd = option.getCommand(); - String val = option.getStringValue(); - if (val.length() > 0) { - if (strCmd != null) buf.append(strCmd); - buf.append(val + WHITE_SPACE); - } - break; - - case IOption.STRING_LIST : - String cmd = option.getCommand(); - String[] list = option.getStringListValue(); - for (int j = 0; j < list.length; j++) { - String temp = list[j]; - if (cmd != null) buf.append(cmd); - buf.append(temp + WHITE_SPACE); - } - break; - - case IOption.INCLUDE_PATH : - String incCmd = option.getCommand(); - String[] paths = option.getIncludePaths(); - for (int j = 0; j < paths.length; j++) { - String temp = paths[j]; - buf.append(incCmd + temp + WHITE_SPACE); - } - break; - - case IOption.PREPROCESSOR_SYMBOLS : - String defCmd = option.getCommand(); - String[] symbols = option.getDefinedSymbols(); - for (int j = 0; j < symbols.length; j++) { - String temp = symbols[j]; - buf.append(defCmd + temp + WHITE_SPACE); - } - break; - - default : - break; - } - } - } - - return buf.toString().trim(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() - */ - public IOptionCategory getTopOptionCategory() { - try { - return parent.getTopOptionCategory(); - } catch (NullPointerException e) { - return null; - } - } - - /* (non-Javadoc) - * Answers an option reference that overrides the option, or null - * - * @param option - * @return OptionReference - */ - private OptionReference getOptionReference(IOption option) { - // Get all the option references for this option - Iterator iter = getAllOptionRefs().listIterator(); - while (iter.hasNext()) { - OptionReference optionRef = (OptionReference) iter.next(); - if (optionRef.references(option)) - return optionRef; - } - - return null; - } - - /* (non-Javadoc) - * - * @param id - * @return - */ - /* - private OptionReference getOptionReference(String id) { - Iterator it = getOptionReferenceList().iterator(); - while (it.hasNext()) { - OptionReference current = (OptionReference)it.next(); - if (current.getId().equals(id)) { - return current; - } - } - return null; - } - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getOptionReferenceList() - */ - public List getOptionReferenceList() { - if (optionReferences == null) { - optionReferences = new ArrayList(); - } - return optionReferences; - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOptions() - */ - public IOption[] getOptions() { - IOption[] options = parent.getOptions(); - - // Replace with our references - for (int i = 0; i < options.length; ++i) { - OptionReference ref = getOptionReference(options[i]); - if (ref != null) - options[i] = ref; - } - - return options; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() - */ - public String[] getOutputExtensions() { - if (outputExtensions == null){ - if (parent != null) { - return parent.getOutputsAttribute(); - } else { - return new String[0]; - } - } - return outputExtensions.split(DEFAULT_SEPARATOR); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtension(java.lang.String) - */ - public String getOutputExtension(String inputExtension) { - if (parent == null) { - // bad reference - return new String(); - } - return parent.getOutputExtension(inputExtension); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputFlag() - */ - public String getOutputFlag() { - if (outputFlag == null) { - if (parent != null) { - return parent.getOutputFlag(); - } else { - // We never should be here - return new String(); - } - } - return outputFlag; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputPrefix() - */ - public String getOutputPrefix() { - if (outputPrefix == null) { - if (parent != null) { - return parent.getOutputPrefix(); - } - return new String(); // bad reference - } - return outputPrefix; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#isDirty() - */ - public boolean isDirty() { - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) - */ - public boolean isHeaderFile(String ext) { - if (parent == null) { - // bad reference - return false; - } - return parent.isHeaderFile(ext); - } - - /** - * Answers true if the owner of the receiver matches - * the argument. - * - * @param config - * @return - */ - public boolean ownedByConfiguration(IConfigurationV2 config) { - if (owner instanceof ConfigurationV2) { - return ((IConfigurationV2)owner).equals(config); - } - return false; - } - - /** - * Persist receiver to project file. - * - * @param doc The persistent store for the reference information. - * @param element The root element in the store the receiver must use - * to persist settings. - */ - public void serialize(Document doc, Element element) { - if (parent == null) return; // This is a bad reference - element.setAttribute(ITool.ID, parent.getId()); - - // Output the command - if (command != null) { - element.setAttribute(ITool.COMMAND, getToolCommand()); - } - - // Save output prefix - if (outputPrefix != null) { - element.setAttribute(ITool.OUTPUT_PREFIX, getOutputPrefix()); - } - - // Save the output flag - if (outputFlag != null) { - element.setAttribute(ITool.OUTPUT_FLAG, getOutputFlag()); - } - - // Save the outputs - if (outputExtensions != null) { - element.setAttribute(ITool.OUTPUTS, outputExtensions); - } - - // Output the option references - Iterator iter = getOptionReferenceList().listIterator(); - while (iter.hasNext()) { - OptionReference optionRef = (OptionReference) iter.next(); - Element optionRefElement = doc.createElement(ITool.OPTION_REF); - element.appendChild(optionRefElement); - optionRef.serialize(doc, optionRefElement); - } - - // Set the reference to clean - isDirty = false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - // Override the local flag - this.isDirty = isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setToolCommand(java.lang.String) - */ - public boolean setToolCommand(String cmd) { - if (cmd != null && !cmd.equals(command)) { - command = cmd; - isDirty = true; - return true; - } else { - return false; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputFlag(java.lang.String) - */ - public void setOutputFlag(String flag) { - if (flag == null) return; - if (outputFlag == null || !(flag.equals(outputFlag))) { - outputFlag = flag; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputPrefix(java.lang.String) - */ - public void setOutputPrefix(String prefix) { - if (prefix == null) return; - if (outputPrefix == null || !(prefix.equals(outputPrefix))) { - outputPrefix = prefix; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputExtensions(java.lang.String) - */ - public void setOutputExtensions(String ext) { - if (ext == null) return; - if (outputExtensions == null || !(ext.equals(outputExtensions))) { - outputExtensions = ext; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) - */ - public void setToolParent(IBuildObject newParent) { - if (parent == null) { - // bad reference - return; - } - // Set the parent in the parent of this ToolRefernce, the tool - ((Tool)parent).setToolParent(newParent); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getParent() - */ - public IBuildObject getParent() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() - */ - public String getCommandLinePattern() { - if( parent == null ) return new String(); - return parent.getCommandLinePattern(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() - */ - public IManagedCommandLineGenerator getCommandLineGenerator() { - if( parent == null ) return null; - return parent.getCommandLineGenerator(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getDependencyGenerator() - */ - public IManagedDependencyGenerator getDependencyGenerator() { - if( parent == null ) return null; - return parent.getDependencyGenerator(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandFlags() - */ - public String[] getCommandFlags() throws BuildException { - if( parent == null ) return null; - return parent.getToolCommandFlags(null, null); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - return getCommandFlags(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - return getToolFlags(); - - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - String answer = new String(); - if (parent != null) { - answer += "Reference to " + parent.getName(); //$NON-NLS-1$ - } - - if (answer.length() > 0) { - return answer; - } else { - return super.toString(); - } - } - - /* - * The following methods are here in order to implement the new ITool methods. - * They should never be called. - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getSuperClass() - */ - public ITool getSuperClass() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#isAbstract() - */ - public boolean isAbstract() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getUnusedChildren() - */ - public String getUnusedChildren() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserList() - */ - public String[] getErrorParserList() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserIds() - */ - public String getErrorParserIds() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setErrorParserIds() - */ - public void setErrorParserIds(String ids) { - } - - public List getInterfaceExtensions() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() - */ - public boolean isExtensionElement() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#createOption() - */ - public IOption createOption(IOption superClass, String Id, String name, boolean b) { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOptions() - */ - public void createOptions(IHoldsOptions options) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOption() - */ - public void removeOption(IOption o) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IOptionCategory#getChildCategories() - */ - public IOptionCategory[] getChildCategories() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setIsAbstract(boolean) - */ - public void setIsAbstract(boolean b) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() - */ - public void setCommandLinePattern(String pattern) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) - */ - public void setCommandLineGeneratorElement(IConfigurationElement element) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() - */ - public IConfigurationElement getDependencyGeneratorElement() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) - */ - public void setDependencyGeneratorElement(IConfigurationElement element) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGeneratorElement() - */ - public IConfigurationElement getCommandLineGeneratorElement() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getAdvancedInputCategory() - */ - public boolean getAdvancedInputCategory() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#setAdvancedInputCategory() - */ - public void setAdvancedInputCategory(boolean display) { - } - - public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { - return null; - } - - public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { - return null; - } - - public String getAnnouncement() { - return null; - } - - public IInputType getInputTypeById(String id) { - return null; - } - - public IInputType[] getInputTypes() { - return null; - } - - public IOutputType getOutputTypeById(String id) { - return null; - } - - public IOutputType[] getOutputTypes() { - return null; - } - - public void removeInputType(IInputType type) { - } - - public void removeOutputType(IOutputType type) { - } - - public void setAnnouncement(String announcement) { - } - - public String getDefaultInputExtension() { - return null; - } - - public String[] getAllInputExtensions() { - return null; - } - - public String[] getPrimaryInputExtensions() { - return null; - } - - public IInputType getInputType(String inputExtension) { - return null; - } - - public String[] getOutputsAttribute() { - return null; - } - - public IOutputType getOutputType(String outputExtension) { - return null; - } - - public void setOutputsAttribute(String extensions) { - } - - public String[] getAllOutputExtensions() { - return null; - } - - public String[] getAllDependencyExtensions() { - return null; - } - - public IInputType getPrimaryInputType() { - return null; - } - - public IOutputType getPrimaryOutputType() { - return null; - } - - public IPath[] getAdditionalDependencies() { - return null; - } - - public IPath[] getAdditionalResources() { - return null; - } - - public IConfigurationElement getDependencyGeneratorElementForExtension(String sourceExt) { - return null; - } - - public IManagedDependencyGeneratorType getDependencyGeneratorForExtension(String sourceExt) { - return null; - } - - public boolean getCustomBuildStep() { - return false; - } - - public void setCustomBuildStep(boolean customBuildStep) { - } - - public IOption getOptionBySuperClassId(String id) { - return null; - } - - public IOptionCategory getOptionCategory(String id) { - // return null as class is deprecated - return null; - } - - public void addOptionCategory(IOptionCategory category) { - } - - /* - * The following methods are added to allow the converter from ToolReference -> Tool - * to retrieve the actual value of attributes. These routines do not go to the - * referenced Tool for a value if the ToolReference does not have a value. - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputExtensions() - */ - public String getRawOutputExtensions() { - return outputExtensions; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputFlag() - */ - public String getRawOutputFlag() { - return outputFlag; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputPrefix() - */ - public String getRawOutputPrefix() { - return outputPrefix; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawToolCommand() - */ - public String getRawToolCommand() { - return command; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() - */ - public String getConvertToId() { - if (convertToId == null) { - // If I have a superClass, ask it - if (parent != null) { - return parent.getConvertToId(); - } else { - return new String(); - } - } - return convertToId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) - */ - public void setConvertToId(String convertToId) { - if (convertToId == null && this.convertToId == null) return; - if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { - this.convertToId = convertToId; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() - */ - public String getVersionsSupported() { - if (versionsSupported == null) { - // If I have a superClass, ask it - if (parent != null) { - return parent.getVersionsSupported(); - } else { - return new String(); - } - } - return versionsSupported; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) - */ - public void setVersionsSupported(String versionsSupported) { - if (versionsSupported == null && this.versionsSupported == null) return; - if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { - this.versionsSupported = versionsSupported; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getEnvVarBuildPaths() - */ - public IEnvVarBuildPath[] getEnvVarBuildPaths(){ - return null; - } - - public PluginVersionIdentifier getVersion() { - return null; - } - - public void setVersion(PluginVersionIdentifier version) { - // TODO Auto-generated method stub - } - - public String getManagedBuildRevision() { - return null; - } - - public IOption getOptionToSet(IOption option, boolean adjustExtension){ - return null; - } -} +/******************************************************************************* + * Copyright (c) 2003, 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.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfigurationV2; +import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionCategory; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.IToolReference; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class ToolReference implements IToolReference { + private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ + + private String command; + private boolean isDirty = false; + private List optionReferences; + private IBuildObject owner; + private String outputExtensions; + private String outputFlag; + private String outputPrefix; + protected ITool parent; + private boolean resolved = true; + private String versionsSupported; + private String convertToId; + + /** + * Create a new tool reference based on information contained in + * a project file. + * + * @param owner The ConfigurationV2 the receiver will be added to. + * @param element The element defined in the project file containing build information + * for the receiver. + */ + public ToolReference(BuildObject owner, Element element) { + this.owner = owner; + + if (owner instanceof ConfigurationV2) { + if (parent == null) { + Target parentTarget = (Target) ((ConfigurationV2)owner).getTarget(); + try { + parent = ((Target)parentTarget.getParent()).getTool(element.getAttribute(ID)); + } catch (NullPointerException e) { + parent = null; + } + } + ((ConfigurationV2)owner).addToolReference(this); + } else if (owner instanceof Target) { + if (parent == null) { + try { + parent = ((Target)((Target)owner).getParent()).getTool(element.getAttribute(ID)); + } catch (NullPointerException e) { + parent = null; + } + } + ((Target)owner).addToolReference(this); + } + + // Get the overridden tool command (if any) + if (element.hasAttribute(ITool.COMMAND)) { + command = element.getAttribute(ITool.COMMAND); + } + + // Get the overridden output prefix (if any) + if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + } + + // Get the output extensions the reference produces + if (element.hasAttribute(ITool.OUTPUTS)) { + outputExtensions = element.getAttribute(ITool.OUTPUTS); + } + // Get the flag to control output + if (element.hasAttribute(ITool.OUTPUT_FLAG)) + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(ITool.OPTION_REF)) { + new OptionReference(this, (Element)configElement); + } + } + } + + /** + * Created tool reference from an extension defined in a plugin manifest. + * + * @param owner The BuildObject the receiver will be added to. + * @param element The element containing build information for the reference. + */ + public ToolReference(BuildObject owner, IManagedConfigElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + + this.owner = owner; + + // hook me up + if (owner instanceof ConfigurationV2) { + ((ConfigurationV2)owner).addToolReference(this); + } else if (owner instanceof Target) { + ((Target)owner).addToolReference(this); + } + + // Get the overridden tool command (if any) + command = element.getAttribute(ITool.COMMAND); + + // Get the overridden output prefix, if any + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + + // Get the overridden output extensions (if any) + String output = element.getAttribute(ITool.OUTPUTS); + if (output != null) { + outputExtensions = output; + } + + // Get the flag to control output + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + + IManagedConfigElement[] toolElements = element.getChildren(); + for (int m = 0; m < toolElements.length; ++m) { + IManagedConfigElement toolElement = toolElements[m]; + if (toolElement.getName().equals(ITool.OPTION_REF)) { + new OptionReference(this, toolElement); + } + } + } + + /** + * Created a tool reference on the fly based on an existing tool or tool reference. + * + * @param owner The BuildObject the receiver will be added to. + * @param tool The ITooltool the reference will be based on. + */ + public ToolReference(BuildObject owner, ITool tool) { + this.owner = owner; + if (tool instanceof ToolReference) { + parent = ((ToolReference)tool).getTool(); + } else { + parent = tool; + } + command = tool.getToolCommand(); + outputFlag = tool.getOutputFlag(); + outputPrefix = tool.getOutputPrefix(); + String[] extensions = tool.getOutputsAttribute(); + outputExtensions = new String(); + if (extensions != null) { + for (int index = 0; index < extensions.length; ++index) { + if (extensions[index] == null) continue; + outputExtensions += extensions[index]; + if (index < extensions.length - 1) { + outputExtensions += DEFAULT_SEPARATOR; + } + } + } + + // Create a copy of the option references of the parent in the receiver + if (tool instanceof ToolReference) { + List parentRefs = ((ToolReference)tool).getOptionReferenceList(); + Iterator iter = parentRefs.iterator(); + while (iter.hasNext()) { + IOption parent = (IOption)iter.next(); + OptionReference clone = createOptionReference(parent); + try { + switch (parent.getValueType()) { + case IOption.BOOLEAN: + clone.setValue(parent.getBooleanValue()); + break; + case IOption.STRING: + clone.setValue(parent.getStringValue()); + case IOption.ENUMERATED: + clone.setValue(parent.getSelectedEnum()); + break; + default: + clone.setValue(parent.getStringListValue()); + break; + } + } catch (BuildException e) { + // Likely a mismatch between the value and option type + continue; + } + } + } + + if (owner instanceof ConfigurationV2) { + ((ConfigurationV2)owner).addToolReference(this); + } else if (owner instanceof Target) { + ((Target)owner).addToolReference(this); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#references(org.eclipse.cdt.managedbuilder.core.ITool) + */ + public boolean references(ITool target) { + if (equals(target)) { + // we are the target + return true; + } else if (parent == null) { + // basic sanity before proceeding + return false; + } else if (parent instanceof IToolReference) { + // check the reference we are overriding + return ((IToolReference)parent).references(target); + } else if (target instanceof IToolReference) { + return parent.equals(((IToolReference)target).getTool()); + } else { + // the real reference + return parent.equals(target); + } + } + + public void resolveReferences() { + if (!resolved) { + resolved = true; + IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); + // resolve my parent + if (owner instanceof ConfigurationV2) { + Target target = (Target) ((ConfigurationV2)owner).getTarget(); + parent = target.getTool(element.getAttribute(ID)); + } else if (owner instanceof Target) { + parent = ((Target)owner).getTool(element.getAttribute(ID)); + } + // recursively resolve my parent + if (parent instanceof Tool) { + ((Tool)parent).resolveReferences(); + } else if (parent instanceof ToolReference) { + ((ToolReference)parent).resolveReferences(); + } + + Iterator it = getOptionReferenceList().iterator(); + while (it.hasNext()) { + OptionReference optRef = (OptionReference)it.next(); + optRef.resolveReferences(); + } + } + } + + /** + * Adds the option reference specified in the argument to the receiver. + * + * @param optionRef + */ + public void addOptionReference(OptionReference optionRef) { + getOptionReferenceList().add(optionRef); + isDirty = true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) + */ + public boolean buildsFileType(String extension) { + if (parent == null) { + // bad reference + return false; + } + return parent.buildsFileType(extension); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) + */ + public boolean isInputFileType(String extension) { + if (parent == null) { + // bad reference + return false; + } + return parent.isInputFileType(extension); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#createOptionReference(org.eclipse.cdt.managedbuilder.core.IOption) + */ + public OptionReference createOptionReference(IOption option) { + // Check if the option reference already exists + OptionReference ref = getOptionReference(option); + // It is possible that the search will return an option reference + // that is supplied by another element of the build model, not the caller. + // For example, if the search is starated by a configuration and the target + // the caller belongs to has an option reference for the option, it + // will be returned. While this is correct behaviour for a search, the + // caller will need to create a clone for itself, so make sure the tool + // reference of the search result is owned by the caller + if (ref == null || !ref.getToolReference().owner.equals(this.owner)) { + ref = new OptionReference(this, option); + } + return ref; + } + + /* (non-Javadoc) + * @return + */ + protected List getAllOptionRefs() { + // First get all the option references this tool reference contains + if (owner instanceof ConfigurationV2) { + return ((ConfigurationV2)owner).getOptionReferences(parent); + } else if (owner instanceof Target) { + return ((Target)owner).getOptionReferences(parent); + } else { + // this shouldn't happen + return null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getId() + */ + public String getId() { + if (parent == null) { + // bad reference + return new String(); + } + return parent.getId(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getBaseId() + */ + public String getBaseId() { + if (parent == null) { + // bad reference + return new String(); + } + return parent.getBaseId(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputExtensions() + */ + public List getInputExtensions() { + String[] exts = getPrimaryInputExtensions(); + List extList = new ArrayList(); + for (int i=0; i 0) { + buf.append(boolCmd + WHITE_SPACE); + } + break; + + case IOption.ENUMERATED : + String enumVal = option.getEnumCommand(option.getSelectedEnum()); + if (enumVal.length() > 0) { + buf.append(enumVal + WHITE_SPACE); + } + break; + + case IOption.STRING : + String strCmd = option.getCommand(); + String val = option.getStringValue(); + if (val.length() > 0) { + if (strCmd != null) buf.append(strCmd); + buf.append(val + WHITE_SPACE); + } + break; + + case IOption.STRING_LIST : + String cmd = option.getCommand(); + String[] list = option.getStringListValue(); + for (int j = 0; j < list.length; j++) { + String temp = list[j]; + if (cmd != null) buf.append(cmd); + buf.append(temp + WHITE_SPACE); + } + break; + + case IOption.INCLUDE_PATH : + String incCmd = option.getCommand(); + String[] paths = option.getIncludePaths(); + for (int j = 0; j < paths.length; j++) { + String temp = paths[j]; + buf.append(incCmd + temp + WHITE_SPACE); + } + break; + + case IOption.PREPROCESSOR_SYMBOLS : + String defCmd = option.getCommand(); + String[] symbols = option.getDefinedSymbols(); + for (int j = 0; j < symbols.length; j++) { + String temp = symbols[j]; + buf.append(defCmd + temp + WHITE_SPACE); + } + break; + + default : + break; + } + } + } + + return buf.toString().trim(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() + */ + public IOptionCategory getTopOptionCategory() { + try { + return parent.getTopOptionCategory(); + } catch (NullPointerException e) { + return null; + } + } + + /* (non-Javadoc) + * Answers an option reference that overrides the option, or null + * + * @param option + * @return OptionReference + */ + private OptionReference getOptionReference(IOption option) { + // Get all the option references for this option + Iterator iter = getAllOptionRefs().listIterator(); + while (iter.hasNext()) { + OptionReference optionRef = (OptionReference) iter.next(); + if (optionRef.references(option)) + return optionRef; + } + + return null; + } + + /* (non-Javadoc) + * + * @param id + * @return + */ + /* + private OptionReference getOptionReference(String id) { + Iterator it = getOptionReferenceList().iterator(); + while (it.hasNext()) { + OptionReference current = (OptionReference)it.next(); + if (current.getId().equals(id)) { + return current; + } + } + return null; + } + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getOptionReferenceList() + */ + public List getOptionReferenceList() { + if (optionReferences == null) { + optionReferences = new ArrayList(); + } + return optionReferences; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOptions() + */ + public IOption[] getOptions() { + IOption[] options = parent.getOptions(); + + // Replace with our references + for (int i = 0; i < options.length; ++i) { + OptionReference ref = getOptionReference(options[i]); + if (ref != null) + options[i] = ref; + } + + return options; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() + */ + public String[] getOutputExtensions() { + if (outputExtensions == null){ + if (parent != null) { + return parent.getOutputsAttribute(); + } else { + return new String[0]; + } + } + return outputExtensions.split(DEFAULT_SEPARATOR); + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtension(java.lang.String) + */ + public String getOutputExtension(String inputExtension) { + if (parent == null) { + // bad reference + return new String(); + } + return parent.getOutputExtension(inputExtension); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputFlag() + */ + public String getOutputFlag() { + if (outputFlag == null) { + if (parent != null) { + return parent.getOutputFlag(); + } else { + // We never should be here + return new String(); + } + } + return outputFlag; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputPrefix() + */ + public String getOutputPrefix() { + if (outputPrefix == null) { + if (parent != null) { + return parent.getOutputPrefix(); + } + return new String(); // bad reference + } + return outputPrefix; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#isDirty() + */ + public boolean isDirty() { + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) + */ + public boolean isHeaderFile(String ext) { + if (parent == null) { + // bad reference + return false; + } + return parent.isHeaderFile(ext); + } + + /** + * Answers true if the owner of the receiver matches + * the argument. + * + * @param config + * @return + */ + public boolean ownedByConfiguration(IConfigurationV2 config) { + if (owner instanceof ConfigurationV2) { + return ((IConfigurationV2)owner).equals(config); + } + return false; + } + + /** + * Persist receiver to project file. + * + * @param doc The persistent store for the reference information. + * @param element The root element in the store the receiver must use + * to persist settings. + */ + public void serialize(Document doc, Element element) { + if (parent == null) return; // This is a bad reference + element.setAttribute(ITool.ID, parent.getId()); + + // Output the command + if (command != null) { + element.setAttribute(ITool.COMMAND, getToolCommand()); + } + + // Save output prefix + if (outputPrefix != null) { + element.setAttribute(ITool.OUTPUT_PREFIX, getOutputPrefix()); + } + + // Save the output flag + if (outputFlag != null) { + element.setAttribute(ITool.OUTPUT_FLAG, getOutputFlag()); + } + + // Save the outputs + if (outputExtensions != null) { + element.setAttribute(ITool.OUTPUTS, outputExtensions); + } + + // Output the option references + Iterator iter = getOptionReferenceList().listIterator(); + while (iter.hasNext()) { + OptionReference optionRef = (OptionReference) iter.next(); + Element optionRefElement = doc.createElement(ITool.OPTION_REF); + element.appendChild(optionRefElement); + optionRef.serialize(doc, optionRefElement); + } + + // Set the reference to clean + isDirty = false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + // Override the local flag + this.isDirty = isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setToolCommand(java.lang.String) + */ + public boolean setToolCommand(String cmd) { + if (cmd != null && !cmd.equals(command)) { + command = cmd; + isDirty = true; + return true; + } else { + return false; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputFlag(java.lang.String) + */ + public void setOutputFlag(String flag) { + if (flag == null) return; + if (outputFlag == null || !(flag.equals(outputFlag))) { + outputFlag = flag; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputPrefix(java.lang.String) + */ + public void setOutputPrefix(String prefix) { + if (prefix == null) return; + if (outputPrefix == null || !(prefix.equals(outputPrefix))) { + outputPrefix = prefix; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputExtensions(java.lang.String) + */ + public void setOutputExtensions(String ext) { + if (ext == null) return; + if (outputExtensions == null || !(ext.equals(outputExtensions))) { + outputExtensions = ext; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) + */ + public void setToolParent(IBuildObject newParent) { + if (parent == null) { + // bad reference + return; + } + // Set the parent in the parent of this ToolRefernce, the tool + ((Tool)parent).setToolParent(newParent); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getParent() + */ + public IBuildObject getParent() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() + */ + public String getCommandLinePattern() { + if( parent == null ) return new String(); + return parent.getCommandLinePattern(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() + */ + public IManagedCommandLineGenerator getCommandLineGenerator() { + if( parent == null ) return null; + return parent.getCommandLineGenerator(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getDependencyGenerator() + */ + public IManagedDependencyGenerator getDependencyGenerator() { + if( parent == null ) return null; + return parent.getDependencyGenerator(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandFlags() + */ + public String[] getCommandFlags() throws BuildException { + if( parent == null ) return null; + return parent.getToolCommandFlags(null, null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + return getCommandFlags(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + return getToolFlags(); + + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + String answer = new String(); + if (parent != null) { + answer += "Reference to " + parent.getName(); //$NON-NLS-1$ + } + + if (answer.length() > 0) { + return answer; + } else { + return super.toString(); + } + } + + /* + * The following methods are here in order to implement the new ITool methods. + * They should never be called. + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getSuperClass() + */ + public ITool getSuperClass() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#isAbstract() + */ + public boolean isAbstract() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getUnusedChildren() + */ + public String getUnusedChildren() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserList() + */ + public String[] getErrorParserList() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserIds() + */ + public String getErrorParserIds() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setErrorParserIds() + */ + public void setErrorParserIds(String ids) { + } + + public List getInterfaceExtensions() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() + */ + public boolean isExtensionElement() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#createOption() + */ + public IOption createOption(IOption superClass, String Id, String name, boolean b) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOptions() + */ + public void createOptions(IHoldsOptions options) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOption() + */ + public void removeOption(IOption o) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IOptionCategory#getChildCategories() + */ + public IOptionCategory[] getChildCategories() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setIsAbstract(boolean) + */ + public void setIsAbstract(boolean b) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() + */ + public void setCommandLinePattern(String pattern) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) + */ + public void setCommandLineGeneratorElement(IConfigurationElement element) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() + */ + public IConfigurationElement getDependencyGeneratorElement() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) + */ + public void setDependencyGeneratorElement(IConfigurationElement element) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGeneratorElement() + */ + public IConfigurationElement getCommandLineGeneratorElement() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getAdvancedInputCategory() + */ + public boolean getAdvancedInputCategory() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#setAdvancedInputCategory() + */ + public void setAdvancedInputCategory(boolean display) { + } + + public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { + return null; + } + + public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { + return null; + } + + public String getAnnouncement() { + return null; + } + + public IInputType getInputTypeById(String id) { + return null; + } + + public IInputType[] getInputTypes() { + return null; + } + + public IOutputType getOutputTypeById(String id) { + return null; + } + + public IOutputType[] getOutputTypes() { + return null; + } + + public void removeInputType(IInputType type) { + } + + public void removeOutputType(IOutputType type) { + } + + public void setAnnouncement(String announcement) { + } + + public String getDefaultInputExtension() { + return null; + } + + public String[] getAllInputExtensions() { + return null; + } + + public String[] getPrimaryInputExtensions() { + return null; + } + + public IInputType getInputType(String inputExtension) { + return null; + } + + public String[] getOutputsAttribute() { + return null; + } + + public IOutputType getOutputType(String outputExtension) { + return null; + } + + public void setOutputsAttribute(String extensions) { + } + + public String[] getAllOutputExtensions() { + return null; + } + + public String[] getAllDependencyExtensions() { + return null; + } + + public IInputType getPrimaryInputType() { + return null; + } + + public IOutputType getPrimaryOutputType() { + return null; + } + + public IPath[] getAdditionalDependencies() { + return null; + } + + public IPath[] getAdditionalResources() { + return null; + } + + public IConfigurationElement getDependencyGeneratorElementForExtension(String sourceExt) { + return null; + } + + public IManagedDependencyGeneratorType getDependencyGeneratorForExtension(String sourceExt) { + return null; + } + + public boolean getCustomBuildStep() { + return false; + } + + public void setCustomBuildStep(boolean customBuildStep) { + } + + public IOption getOptionBySuperClassId(String id) { + return null; + } + + public IOptionCategory getOptionCategory(String id) { + // return null as class is deprecated + return null; + } + + public void addOptionCategory(IOptionCategory category) { + } + + /* + * The following methods are added to allow the converter from ToolReference -> Tool + * to retrieve the actual value of attributes. These routines do not go to the + * referenced Tool for a value if the ToolReference does not have a value. + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputExtensions() + */ + public String getRawOutputExtensions() { + return outputExtensions; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputFlag() + */ + public String getRawOutputFlag() { + return outputFlag; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputPrefix() + */ + public String getRawOutputPrefix() { + return outputPrefix; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawToolCommand() + */ + public String getRawToolCommand() { + return command; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() + */ + public String getConvertToId() { + if (convertToId == null) { + // If I have a superClass, ask it + if (parent != null) { + return parent.getConvertToId(); + } else { + return new String(); + } + } + return convertToId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) + */ + public void setConvertToId(String convertToId) { + if (convertToId == null && this.convertToId == null) return; + if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { + this.convertToId = convertToId; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() + */ + public String getVersionsSupported() { + if (versionsSupported == null) { + // If I have a superClass, ask it + if (parent != null) { + return parent.getVersionsSupported(); + } else { + return new String(); + } + } + return versionsSupported; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) + */ + public void setVersionsSupported(String versionsSupported) { + if (versionsSupported == null && this.versionsSupported == null) return; + if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { + this.versionsSupported = versionsSupported; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getEnvVarBuildPaths() + */ + public IEnvVarBuildPath[] getEnvVarBuildPaths(){ + return null; + } + + public PluginVersionIdentifier getVersion() { + return null; + } + + public void setVersion(PluginVersionIdentifier version) { + // TODO Auto-generated method stub + } + + public String getManagedBuildRevision() { + return null; + } + + public IOption getOptionToSet(IOption option, boolean adjustExtension){ + return null; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java index 71775b26b28..842ebd2bf03 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java @@ -1,79 +1,79 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen; - -import org.eclipse.core.runtime.IPath; - -/** - * @since 3.1 - * - * A Tool dependency calculator may implement this interface or - * IManagedDependencyCommands or IManagedDependencyPreBuild. - * An object implementing the interface is returned from a call to - * IManagedDependencyGenerator2.getDependencySourceInfo. - * - * Discussion of Dependency Calculation: - * - * There are two major, and multiple minor, modes of dependency calculation - * supported by the MBS. The major modes are: - * - * 1. The build file generator invokes tool integrator provided methods - * that calculate all dependencies using whatever method the tool - * integrator wants. The build file generator then adds the dependencies - * to the build file using the appropriate build file syntax. - * This type of dependency calculator implements the - * IManagedDependencyCalculator interface defined in this module. - * - * One minor mode of this mode is to use a dependency calculator provided - * by a language integration (e.g. C, C++ or Fortran) that uses the - * language's parsing support to return information regarding source file - * dependencies. An example of this is using the C/C++ Indexer to - * compute dependencies. - * - * 2. The build file generator and the tool-chain cooperate in creating and - * using separate "dependency" files. In this case, dependency calculation - * is done at "build time", rather than at "build file generation time" as - * in mode #1. This currently supports the GNU concept of using .d files - * in GNU make. See the IManagedDependencyCommands and - * IManagedDependencyPreBuild interfaces for more information. - * - */ - -public interface IManagedDependencyCalculator extends IManagedDependencyInfo { - - /** - * Returns the list of source file specific dependencies. - * - * The paths can be either relative to the project directory, or absolute - * in the file system. - * - * @return IPath[] - */ - public IPath[] getDependencies(); - - /** - * Returns the list of source file specific additional targets that the - * source file creates. Most source files will return null. An example - * of where additional targets should be returned is for a Fortran 90 - * source file that creates one or more Fortran Modules. - * - * Note that these output files that are dependencies to other invocations - * of the same tool can be specified here, or as another output type - * of the tool. If the output file can be used as the input of a different - * tool, then use the output type mechanism. - * - * The paths can be either relative to the top build directory, or absolute - * in the file system. - * - * @return IPath[] - */ - public IPath[] getAdditionalTargets(); -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen; + +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * A Tool dependency calculator may implement this interface or + * IManagedDependencyCommands or IManagedDependencyPreBuild. + * An object implementing the interface is returned from a call to + * IManagedDependencyGenerator2.getDependencySourceInfo. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * This type of dependency calculator implements the + * IManagedDependencyCalculator interface defined in this module. + * + * One minor mode of this mode is to use a dependency calculator provided + * by a language integration (e.g. C, C++ or Fortran) that uses the + * language's parsing support to return information regarding source file + * dependencies. An example of this is using the C/C++ Indexer to + * compute dependencies. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. In this case, dependency calculation + * is done at "build time", rather than at "build file generation time" as + * in mode #1. This currently supports the GNU concept of using .d files + * in GNU make. See the IManagedDependencyCommands and + * IManagedDependencyPreBuild interfaces for more information. + * + */ + +public interface IManagedDependencyCalculator extends IManagedDependencyInfo { + + /** + * Returns the list of source file specific dependencies. + * + * The paths can be either relative to the project directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getDependencies(); + + /** + * Returns the list of source file specific additional targets that the + * source file creates. Most source files will return null. An example + * of where additional targets should be returned is for a Fortran 90 + * source file that creates one or more Fortran Modules. + * + * Note that these output files that are dependencies to other invocations + * of the same tool can be specified here, or as another output type + * of the tool. If the output file can be used as the input of a different + * tool, then use the output type mechanism. + * + * The paths can be either relative to the top build directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getAdditionalTargets(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java index 3e451e6a5eb..077e712fe6e 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java @@ -1,168 +1,168 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen; - -import org.eclipse.core.runtime.IPath; - -/** - * @since 3.1 - * - * A Tool dependency calculator may implement this interface or - * IManagedDependencyCalculator or IManagedDependencyPreBuild. - * An object implementing the interface is returned from a call to - * IManagedDependencyGenerator2.getDependencySourceInfo. - * - * Discussion of Dependency Calculation: - * - * There are two major, and multiple minor, modes of dependency calculation - * supported by the MBS. The major modes are: - * - * 1. The build file generator invokes tool integrator provided methods - * that calculate all dependencies using whatever method the tool - * integrator wants. The build file generator then adds the dependencies - * to the build file using the appropriate build file syntax. - * See the IManagedDependencyCalculator interface for more information. - * - * 2. The build file generator and the tool-chain cooperate in creating and - * using separate "dependency" files. The build file generator calls - * the dependency calculator to get the dependency file names and to get - * commands that need to be added to the build file. In this case, - * dependency calculation is done at "build time", rather than at - * "build file generation time" as in mode #1. This currently - * supports the GNU concept of using .d files in GNU make. - * - * There are multiple ways that these separate dependency files can - * be created by the tool-chain and used by the builder. - * - * a. In some cases (e.g., Fortran 90 using modules) the dependency files - * must be created/updated prior to invoking the build of the project - * artifact (e.g., an application). In this case, the dependency - * generation step must occur separately before the main build. - * See the IManagedDependencyPreBuild interface for more information. - * - * b. In other cases (e.g., C/C++) the dependency files can be created as - * a side effect of the main build. This implies that the up to date - * dependency files are not required for the current build, but for - * the next build. C/C++ builds can be treated in this manner as is - * described in the following link: - * http://sourceware.org/automake/automake.html#Dependency-Tracking-Evolution - * - * Use the IManagedDependencyCommands interface defined in this file - * for this mode. - * - * Two sub-scenarios of this mode are to: - * - * Create dependency files in the same invocation of the tool that - * creates the tool's build artifact - by adding additional options - * to the tool invocation command line. - * - * Create dependency files in a separate invocation of the tool, or - * by the invocation of another tool. - * - * MBS can also help in the generation of the dependency files. Prior to - * CDT 3.1, MBS and gcc cooperated in generating dependency files using the - * following steps: - * - * 1. Gcc is invoked to perform the compilation that generates the object - * file. - * - * 2. An "echo" command creates the .d file, adding the name of the .d - * file to the beginning of the newly created .d file. Note that this - * causes problems with some implementations of "echo" that don't - * work exactly the way that we want (e.g., it doesn't support the -n - * switch). - - * 3. Gcc is invoked again with the appropriate additional command line - * options to append its dependency file information to the .d file - * that was created by "echo". - * - * 4. Steps 1 - 3 are invoked in the make file. Step 4 occurs after the - * make invocation has finished. In step 4, MBS code post-processes - * the .d files to add a dummy dependency for each header file, for - * the reason explained in the link above. - * - * This mode is no longer used by the default gcc implementation, but can - * still be used by selecting the DefaultGCCDependencyCalculator. - * - * - * Note for GNU make: these separate dependency files are "include"d by - * a main makefile. Therefore, if the dependency files are required to - * be up to date before the main build begins, they must be updated by - * a separate invocation of make. Also, the configuration "clean" step - * must be invoked by a separate invocation of make. This is so that - * we can exclude the dependency files for a "make clean" invocation - * using syntax like: - * - * ifneq ($(MAKECMDGOALS), clean) - * -include $(DEPS) - * endif - * - * Otherwise, because GNU make attempts to re-make make files, we - * can end up with out of date or missing dependency files being - * re-generated and then immediately "clean"ed. - */ - -public interface IManagedDependencyCommands extends IManagedDependencyInfo { - - /** - * Returns the list of generated dependency files. - * - * The paths can be either relative to the top build directory, or absolute - * in the file system. - * - * @return IPath[] - */ - public IPath[] getDependencyFiles(); - - /** - * Returns the command lines to be invoked before the normal tool invocation - * to calculate dependencies. - * - * @return String[] This can be null or an empty array if no dependency - * generation command needs to be invoked before the normal - * tool invocation. - */ - public String[] getPreToolDependencyCommands(); - - /** - * Returns the command line options to be used to calculate dependencies. - * The options are added to the normal tool invocation. - * - * @return String[] This can be null or an empty array if no additional - * arguments need to be added to the tool invocation. - * SHOULD THIS RETURN AN IOption[]? - */ - public String[] getDependencyCommandOptions(); - // IMPLEMENTATION NOTE: This should be called from addRuleFromSource for both resconfig & non-resconfig - - /** - * Returns the command lines to be invoked after the normal tool invocation - * to calculate dependencies. - * - * @return String[] This can be null or an empty array if no dependency - * generation commands needs to be invoked after the normal - * tool invocation - */ - public String[] getPostToolDependencyCommands(); - - /** - * Returns true if the command lines and/or options returned by this interface - * are not specific to the particular source file, but are only specific to, - * at most, the configuration and tool. If the build context is a resource - * configuration, this method should return false if any of the command lines - * and/or options are different than if the build context were the parent - * configuration. This can be used by the build file generator in helping - * to determine if a "pattern" (generic) rule can be used. - * - * @return boolean - */ - public boolean areCommandsGeneric(); -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen; + +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * A Tool dependency calculator may implement this interface or + * IManagedDependencyCalculator or IManagedDependencyPreBuild. + * An object implementing the interface is returned from a call to + * IManagedDependencyGenerator2.getDependencySourceInfo. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. The build file generator calls + * the dependency calculator to get the dependency file names and to get + * commands that need to be added to the build file. In this case, + * dependency calculation is done at "build time", rather than at + * "build file generation time" as in mode #1. This currently + * supports the GNU concept of using .d files in GNU make. + * + * There are multiple ways that these separate dependency files can + * be created by the tool-chain and used by the builder. + * + * a. In some cases (e.g., Fortran 90 using modules) the dependency files + * must be created/updated prior to invoking the build of the project + * artifact (e.g., an application). In this case, the dependency + * generation step must occur separately before the main build. + * See the IManagedDependencyPreBuild interface for more information. + * + * b. In other cases (e.g., C/C++) the dependency files can be created as + * a side effect of the main build. This implies that the up to date + * dependency files are not required for the current build, but for + * the next build. C/C++ builds can be treated in this manner as is + * described in the following link: + * http://sourceware.org/automake/automake.html#Dependency-Tracking-Evolution + * + * Use the IManagedDependencyCommands interface defined in this file + * for this mode. + * + * Two sub-scenarios of this mode are to: + * + * Create dependency files in the same invocation of the tool that + * creates the tool's build artifact - by adding additional options + * to the tool invocation command line. + * + * Create dependency files in a separate invocation of the tool, or + * by the invocation of another tool. + * + * MBS can also help in the generation of the dependency files. Prior to + * CDT 3.1, MBS and gcc cooperated in generating dependency files using the + * following steps: + * + * 1. Gcc is invoked to perform the compilation that generates the object + * file. + * + * 2. An "echo" command creates the .d file, adding the name of the .d + * file to the beginning of the newly created .d file. Note that this + * causes problems with some implementations of "echo" that don't + * work exactly the way that we want (e.g., it doesn't support the -n + * switch). + + * 3. Gcc is invoked again with the appropriate additional command line + * options to append its dependency file information to the .d file + * that was created by "echo". + * + * 4. Steps 1 - 3 are invoked in the make file. Step 4 occurs after the + * make invocation has finished. In step 4, MBS code post-processes + * the .d files to add a dummy dependency for each header file, for + * the reason explained in the link above. + * + * This mode is no longer used by the default gcc implementation, but can + * still be used by selecting the DefaultGCCDependencyCalculator. + * + * + * Note for GNU make: these separate dependency files are "include"d by + * a main makefile. Therefore, if the dependency files are required to + * be up to date before the main build begins, they must be updated by + * a separate invocation of make. Also, the configuration "clean" step + * must be invoked by a separate invocation of make. This is so that + * we can exclude the dependency files for a "make clean" invocation + * using syntax like: + * + * ifneq ($(MAKECMDGOALS), clean) + * -include $(DEPS) + * endif + * + * Otherwise, because GNU make attempts to re-make make files, we + * can end up with out of date or missing dependency files being + * re-generated and then immediately "clean"ed. + */ + +public interface IManagedDependencyCommands extends IManagedDependencyInfo { + + /** + * Returns the list of generated dependency files. + * + * The paths can be either relative to the top build directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getDependencyFiles(); + + /** + * Returns the command lines to be invoked before the normal tool invocation + * to calculate dependencies. + * + * @return String[] This can be null or an empty array if no dependency + * generation command needs to be invoked before the normal + * tool invocation. + */ + public String[] getPreToolDependencyCommands(); + + /** + * Returns the command line options to be used to calculate dependencies. + * The options are added to the normal tool invocation. + * + * @return String[] This can be null or an empty array if no additional + * arguments need to be added to the tool invocation. + * SHOULD THIS RETURN AN IOption[]? + */ + public String[] getDependencyCommandOptions(); + // IMPLEMENTATION NOTE: This should be called from addRuleFromSource for both resconfig & non-resconfig + + /** + * Returns the command lines to be invoked after the normal tool invocation + * to calculate dependencies. + * + * @return String[] This can be null or an empty array if no dependency + * generation commands needs to be invoked after the normal + * tool invocation + */ + public String[] getPostToolDependencyCommands(); + + /** + * Returns true if the command lines and/or options returned by this interface + * are not specific to the particular source file, but are only specific to, + * at most, the configuration and tool. If the build context is a resource + * configuration, this method should return false if any of the command lines + * and/or options are different than if the build context were the parent + * configuration. This can be used by the build file generator in helping + * to determine if a "pattern" (generic) rule can be used. + * + * @return boolean + */ + public boolean areCommandsGeneric(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java index 5511d473dfe..f3870e8e606 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java @@ -1,27 +1,27 @@ -/******************************************************************************* - * 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.managedbuilder.makegen; - -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; - -/** - * @since 2.0 - * @deprecated 3.1 - * - * Use IManagedDependencyGenerator2 instead. -*/ -public interface IManagedDependencyGenerator extends IManagedDependencyGeneratorType { - - public IResource[] findDependencies(IResource resource, IProject project); - public String getDependencyCommand(IResource resource, IManagedBuildInfo info); -} +/******************************************************************************* + * 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.managedbuilder.makegen; + +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; + +/** + * @since 2.0 + * @deprecated 3.1 + * + * Use IManagedDependencyGenerator2 instead. +*/ +public interface IManagedDependencyGenerator extends IManagedDependencyGeneratorType { + + public IResource[] findDependencies(IResource resource, IProject project); + public String getDependencyCommand(IResource resource, IManagedBuildInfo info); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java index 3d16344053c..1e28c6046cf 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java @@ -1,114 +1,114 @@ -/******************************************************************************* - * Copyright (c) 2005, 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 of IManagedDependencyGenerator - * Intel - Initial API and implementation of IManagedDependencyGenerator2 - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.core.runtime.IPath; -import org.eclipse.cdt.managedbuilder.core.ITool; - -/** - * @since 3.1 - * - * A Tool dependency calculator must implement this interface. This interface - * replaces IManagedDependencyGenerator which is deprecated. - * - * Discussion of Dependency Calculation: - * - * There are two major, and multiple minor, modes of dependency calculation - * supported by the MBS. The major modes are: - * - * 1. The build file generator invokes tool integrator provided methods - * that calculate all dependencies using whatever method the tool - * integrator wants. The build file generator then adds the dependencies - * to the build file using the appropriate build file syntax. - * This is a TYPE_CUSTOM dependency calculator as defined below. - * See the IManagedDependencyCalculator interface for more information. - * - * 2. The build file generator and the tool-chain cooperate in creating and - * using separate "dependency" files. In this case, dependency calculation - * is done at "build time", rather than at "build file generation time" as - * in mode #1. This currently supports the GNU concept of using .d files - * in GNU make. - * This is either a TYPE_BUILD_COMMANDS dependency calculator or a - * TYPE_PREBUILD_COMMANDS dependency calculator as defined below. - * See the IManagedDependencyCommands and IManagedDependencyPreBuild - * interfaces for more information. - * - */ - -public interface IManagedDependencyGenerator2 extends IManagedDependencyGeneratorType { - - /** - * Returns an instance of IManagedDependencyInfo for this source file. - * IManagedDependencyCalculator, IManagedDependencyCommands - * and IManagedDependencyPreBuild are all derived from - * IManagedDependencyInfo, and any one of the three can be returned. - * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS, - * TYPE_CUSTOM or TYPE_PREBUILD_COMMANDS. - * - * @param source The source file for which dependencies should be calculated - * The IPath can be either relative to the project directory, or absolute in the file system. - * @param buildContext The IConfiguration or IResourceConfiguration that - * contains the context in which the source file will be built - * @param tool The tool associated with the source file - * @param topBuildDirectory The top build directory of the configuration. This is - * the working directory for the tool. This IPath is relative to the project directory. - * @return IManagedDependencyInfo - */ - public IManagedDependencyInfo getDependencySourceInfo( - IPath source, - IBuildObject buildContext, - ITool tool, - IPath topBuildDirectory); - - /** - * Returns the file extension used by dependency files created - * by this dependency generator. - * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS or - * TYPE_PREBUILD_COMMANDS. - * - * @param buildContext The IConfiguration that contains the context of the build - * @param tool The tool associated with the dependency generator. - * - * @return String - */ - public String getDependencyFileExtension( - IConfiguration buildContext, - ITool tool); - - /** - * Called to allow the dependency calculator to post-process dependency files. - * This method is called after the build has completed for at least every - * dependency file that has changed, and possibly for those that have not - * changed as well. It may also be called with dependency files created by - * another tool. This method should be able to recognize dependency files - * that don't belong to it, or that it has already post-processed. - * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS or - * TYPE_PREBUILD_COMMANDS. - * - * @param dependencyFile The dependency file - * The IPath can be either relative to the top build directory, or absolute in the file system. - * @param buildContext The IConfiguration that contains the context of the build - * @param tool The tool associated with the dependency generator. Note that this is - * not necessarily the tool that created the dependency file - * @param topBuildDirectory The top build directory of the project. This is - * the working directory for the tool. - * - * @return boolean True if the method modified the dependency (e.g., .d) file - */ - public boolean postProcessDependencyFile( - IPath dependencyFile, - IConfiguration buildContext, - ITool tool, - IPath topBuildDirectory); -} +/******************************************************************************* + * Copyright (c) 2005, 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 of IManagedDependencyGenerator + * Intel - Initial API and implementation of IManagedDependencyGenerator2 + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.core.runtime.IPath; +import org.eclipse.cdt.managedbuilder.core.ITool; + +/** + * @since 3.1 + * + * A Tool dependency calculator must implement this interface. This interface + * replaces IManagedDependencyGenerator which is deprecated. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * This is a TYPE_CUSTOM dependency calculator as defined below. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. In this case, dependency calculation + * is done at "build time", rather than at "build file generation time" as + * in mode #1. This currently supports the GNU concept of using .d files + * in GNU make. + * This is either a TYPE_BUILD_COMMANDS dependency calculator or a + * TYPE_PREBUILD_COMMANDS dependency calculator as defined below. + * See the IManagedDependencyCommands and IManagedDependencyPreBuild + * interfaces for more information. + * + */ + +public interface IManagedDependencyGenerator2 extends IManagedDependencyGeneratorType { + + /** + * Returns an instance of IManagedDependencyInfo for this source file. + * IManagedDependencyCalculator, IManagedDependencyCommands + * and IManagedDependencyPreBuild are all derived from + * IManagedDependencyInfo, and any one of the three can be returned. + * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS, + * TYPE_CUSTOM or TYPE_PREBUILD_COMMANDS. + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + * @return IManagedDependencyInfo + */ + public IManagedDependencyInfo getDependencySourceInfo( + IPath source, + IBuildObject buildContext, + ITool tool, + IPath topBuildDirectory); + + /** + * Returns the file extension used by dependency files created + * by this dependency generator. + * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS or + * TYPE_PREBUILD_COMMANDS. + * + * @param buildContext The IConfiguration that contains the context of the build + * @param tool The tool associated with the dependency generator. + * + * @return String + */ + public String getDependencyFileExtension( + IConfiguration buildContext, + ITool tool); + + /** + * Called to allow the dependency calculator to post-process dependency files. + * This method is called after the build has completed for at least every + * dependency file that has changed, and possibly for those that have not + * changed as well. It may also be called with dependency files created by + * another tool. This method should be able to recognize dependency files + * that don't belong to it, or that it has already post-processed. + * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS or + * TYPE_PREBUILD_COMMANDS. + * + * @param dependencyFile The dependency file + * The IPath can be either relative to the top build directory, or absolute in the file system. + * @param buildContext The IConfiguration that contains the context of the build + * @param tool The tool associated with the dependency generator. Note that this is + * not necessarily the tool that created the dependency file + * @param topBuildDirectory The top build directory of the project. This is + * the working directory for the tool. + * + * @return boolean True if the method modified the dependency (e.g., .d) file + */ + public boolean postProcessDependencyFile( + IPath dependencyFile, + IConfiguration buildContext, + ITool tool, + IPath topBuildDirectory); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java index bca6f078f11..a510e4fb424 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java @@ -1,87 +1,87 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen; - -/** - * @since 3.1 - * - * IManagedDependencyGenerator (deprecated) and IManagedDependencyGenerator2 - * extend this interface. - * - * Discussion of Dependency Calculation: - * - * There are two major, and multiple minor, modes of dependency calculation - * supported by the MBS. The major modes are: - * - * 1. The build file generator invokes tool integrator provided methods - * that calculate all dependencies using whatever method the tool - * integrator wants. The build file generator then adds the dependencies - * to the build file using the appropriate build file syntax. - * This is a TYPE_CUSTOM dependency calculator as defined below. - * See the IManagedDependencyCalculator interface for more information. - * - * 2. The build file generator and the tool-chain cooperate in creating and - * using separate "dependency" files. In this case, dependency calculation - * is done at "build time", rather than at "build file generation time" as - * in mode #1. This currently supports the GNU concept of using .d files - * in GNU make. - * This is either a TYPE_BUILD_COMMANDS dependency calculator or a - * TYPE_PREBUILD_COMMANDS dependency calculator as defined below. - * See the IManagedDependencyCommands and IManagedDependencyPreBuild - * interfaces for more information. - * - */ - -public interface IManagedDependencyGeneratorType { - /** - * Constants returned by getCalculatorType - */ - public int TYPE_NODEPS = 0; // Deprecated - use TYPE_NODEPENDENCIES - public int TYPE_COMMAND = 1; // Deprecated - use TYPE_BUILD_COMMANDS - public int TYPE_INDEXER = 2; // Deprecated - use TYPE_CUSTOM - public int TYPE_EXTERNAL = 3; // Deprecated - use TYPE_CUSTOM - public int TYPE_OLD_TYPE_LIMIT = 3; - - // Use these types - public int TYPE_NODEPENDENCIES = 4; - public int TYPE_BUILD_COMMANDS = 5; - public int TYPE_PREBUILD_COMMANDS = 6; - public int TYPE_CUSTOM = 7; - - /** - * Returns the type of dependency generator that is implemented. - * - * TYPE_NODEPENDENCIES indicates that no dependency generator is - * supplied or needed. - * TYPE_CUSTOM indicates that a custom, "build file generation time" - * dependency calculator is implemented. Note that the dependency - * calculator will be called when the makefile is generated, and - * for every source file that is built by this tool in the build - * file, not just for those that have changed since the last build - * file generation. - * TYPE_BUILD_COMMANDS indicates that command lines or options will - * be returned to be used to calculate dependencies. These - * commands/options are added to the build file to perform dependency - * calculation at "build time". This currently supports - * compilers/tools that generate .d files either as a - * side-effect of tool invocation, or as a separate step that is - * invoked immediately before or after the tool invocation. - * TYPE_PREBUILD_COMMANDS indicates that a separate build step is - * invoked, prior to the the normal build steps, to update the - * dependency information. These commands are added to the build - * file to perform dependency calculation at "build time". Note - * that this step will be invoked every time a build is done in - * order to determine if dependency files need to be re-generated. - * - * @return int - */ - public int getCalculatorType(); -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen; + +/** + * @since 3.1 + * + * IManagedDependencyGenerator (deprecated) and IManagedDependencyGenerator2 + * extend this interface. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * This is a TYPE_CUSTOM dependency calculator as defined below. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. In this case, dependency calculation + * is done at "build time", rather than at "build file generation time" as + * in mode #1. This currently supports the GNU concept of using .d files + * in GNU make. + * This is either a TYPE_BUILD_COMMANDS dependency calculator or a + * TYPE_PREBUILD_COMMANDS dependency calculator as defined below. + * See the IManagedDependencyCommands and IManagedDependencyPreBuild + * interfaces for more information. + * + */ + +public interface IManagedDependencyGeneratorType { + /** + * Constants returned by getCalculatorType + */ + public int TYPE_NODEPS = 0; // Deprecated - use TYPE_NODEPENDENCIES + public int TYPE_COMMAND = 1; // Deprecated - use TYPE_BUILD_COMMANDS + public int TYPE_INDEXER = 2; // Deprecated - use TYPE_CUSTOM + public int TYPE_EXTERNAL = 3; // Deprecated - use TYPE_CUSTOM + public int TYPE_OLD_TYPE_LIMIT = 3; + + // Use these types + public int TYPE_NODEPENDENCIES = 4; + public int TYPE_BUILD_COMMANDS = 5; + public int TYPE_PREBUILD_COMMANDS = 6; + public int TYPE_CUSTOM = 7; + + /** + * Returns the type of dependency generator that is implemented. + * + * TYPE_NODEPENDENCIES indicates that no dependency generator is + * supplied or needed. + * TYPE_CUSTOM indicates that a custom, "build file generation time" + * dependency calculator is implemented. Note that the dependency + * calculator will be called when the makefile is generated, and + * for every source file that is built by this tool in the build + * file, not just for those that have changed since the last build + * file generation. + * TYPE_BUILD_COMMANDS indicates that command lines or options will + * be returned to be used to calculate dependencies. These + * commands/options are added to the build file to perform dependency + * calculation at "build time". This currently supports + * compilers/tools that generate .d files either as a + * side-effect of tool invocation, or as a separate step that is + * invoked immediately before or after the tool invocation. + * TYPE_PREBUILD_COMMANDS indicates that a separate build step is + * invoked, prior to the the normal build steps, to update the + * dependency information. These commands are added to the build + * file to perform dependency calculation at "build time". Note + * that this step will be invoked every time a build is done in + * order to determine if dependency files need to be re-generated. + * + * @return int + */ + public int getCalculatorType(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java index 849bbd774c2..cd73d580c09 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java @@ -1,35 +1,35 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.core.runtime.IPath; - -/** - * @since 3.1 - * - * This interface is the base interface for IManagedDependencyCalculator, - * IManagedDependencyCommands and IManagedDependencyPreBuild. See these - * interfaces and IManagedDependencyGenerator2 for more information on - * writing a dependency calculator. - * - * The methods below simply return the arguments passed to the - * IManagedDependencyGenerator2.getDependency*Info call that created the - * IManagedDependencyInfo instance. - * - */ -public interface IManagedDependencyInfo { - public IPath getSource(); - public IBuildObject getBuildContext(); - public ITool getTool(); - public IPath getTopBuildDirectory(); -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * This interface is the base interface for IManagedDependencyCalculator, + * IManagedDependencyCommands and IManagedDependencyPreBuild. See these + * interfaces and IManagedDependencyGenerator2 for more information on + * writing a dependency calculator. + * + * The methods below simply return the arguments passed to the + * IManagedDependencyGenerator2.getDependency*Info call that created the + * IManagedDependencyInfo instance. + * + */ +public interface IManagedDependencyInfo { + public IPath getSource(); + public IBuildObject getBuildContext(); + public ITool getTool(); + public IPath getTopBuildDirectory(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java index 83ef41a83da..d43a686646a 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java @@ -1,136 +1,136 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen; - -import org.eclipse.core.runtime.IPath; - -/** - * @since 3.1 - * - * A Tool dependency calculator may implement this interface or - * IManagedDependencyCalculator or IManagedDependencyCommands. - * An object implementing the interface is returned from a call to - * IManagedDependencyGenerator2.getDependencySourceInfo. - * - * Discussion of Dependency Calculation: - * - * There are two major, and multiple minor, modes of dependency calculation - * supported by the MBS. The major modes are: - * - * 1. The build file generator invokes tool integrator provided methods - * that calculate all dependencies using whatever method the tool - * integrator wants. The build file generator then adds the dependencies - * to the build file using the appropriate build file syntax. - * See the IManagedDependencyCalculator interface for more information. - * - * 2. The build file generator and the tool-chain cooperate in creating and - * using separate "dependency" files. The build file generator calls - * the dependency calculator to get the dependency file names and to get - * commands that need to be added to the build file. In this case, - * dependency calculation is done at "build time", rather than at - * "build file generation time" as in mode #1. This currently - * supports the GNU concept of using .d files in GNU make. - * - * There are multiple ways that these separate dependency files can - * be created by the tool-chain and used by the builder. - * - * a. In some cases (e.g., Fortran 90 using modules) the dependency files - * must be created/updated prior to invoking the build of the project - * artifact (e.g., an application). In this case, the dependency - * generation step must occur separately before the main build. - * Use the IManagedDependencyPreBuild interface defined in this file - * for this mode. - * - * b. In other cases (e.g., C/C++) the dependency files can be created as - * a side effect of the main build. This implies that the up to date - * dependency files are not required for the current build, but for - * the next build. C/C++ builds can be treated in this manner as is - * described in the following link: - * http://sourceware.org/automake/automake.html#Dependency-Tracking-Evolution - * - * See the IManagedDependencyCommands interface for more information. - * - * - * Note for GNU make: these separate dependency files are "include"d by - * a main makefile. Make performs special processing on make files: - * - * "To this end, after reading in all makefiles, make will consider - * each as a goal target and attempt to update it. If a makefile has a - * rule which says how to update it (found either in that very - * makefile or in another one)..., it will be updated if necessary. - * After all makefiles have been checked, if any have actually been - * changed, make starts with a clean slate and reads all the makefiles - * over again." - * - * We can use this to ensure that the dependency files are up to date - * by adding rules to the make file for generating the dependency files. - * These rules are returned by the call to getDependencyCommands. - * However, this has a significant problem when we don’t want to build - * the build target, but only want to “clean” the configuration, - * for example. If we invoke make just to clean the configuration, - * make will still update the dependency files if necessary, thereby - * re-generating the dependency files only to immediately delete them. - * The workaround suggested by the make documentation is to check for - * an invocation using the “clean” target, and to not include the - * dependency files it that case. For example, - * - * ifneq ($(MAKECMDGOALS),clean) - * include $(DEPS) - * endif - * - * The restriction with this is that it only works if “clean” is the only - * target specified on the make command line. Therefore, the build - * "clean" step must be invoked separately. - */ - -public interface IManagedDependencyPreBuild extends IManagedDependencyInfo { - - /** - * Returns the list of generated dependency files. - * - * The paths can be either relative to the top build directory, or absolute - * in the file system. - * - * @return IPath[] - */ - public IPath[] getDependencyFiles(); - - /** - * Returns the name to be used in the build file to identify the separate - * build step. Note that this name should be unique to the tool since - * multiple tools in a tool-chain may be using this method of - * dependency calculation. - * - * @return String - */ - public String getBuildStepName(); - - /** - * Returns the command line(s) to be invoked in the separate - * dependencies pre-build step. - * - * @return String[] - */ - public String[] getDependencyCommands(); - - /** - * Returns true if the command lines returned by this interface - * are not specific to the particular source file, but are only specific to, - * at most, the configuration and tool. If the build context is a resource - * configuration, this method should return false if any of the command lines - * are different than if the build context were the parent configuration. - * This can be used by the build file generator in helping to determine if - * a "pattern" (generic) rule can be used. - * - * @return boolean - */ - public boolean areCommandsGeneric(); -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen; + +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * A Tool dependency calculator may implement this interface or + * IManagedDependencyCalculator or IManagedDependencyCommands. + * An object implementing the interface is returned from a call to + * IManagedDependencyGenerator2.getDependencySourceInfo. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. The build file generator calls + * the dependency calculator to get the dependency file names and to get + * commands that need to be added to the build file. In this case, + * dependency calculation is done at "build time", rather than at + * "build file generation time" as in mode #1. This currently + * supports the GNU concept of using .d files in GNU make. + * + * There are multiple ways that these separate dependency files can + * be created by the tool-chain and used by the builder. + * + * a. In some cases (e.g., Fortran 90 using modules) the dependency files + * must be created/updated prior to invoking the build of the project + * artifact (e.g., an application). In this case, the dependency + * generation step must occur separately before the main build. + * Use the IManagedDependencyPreBuild interface defined in this file + * for this mode. + * + * b. In other cases (e.g., C/C++) the dependency files can be created as + * a side effect of the main build. This implies that the up to date + * dependency files are not required for the current build, but for + * the next build. C/C++ builds can be treated in this manner as is + * described in the following link: + * http://sourceware.org/automake/automake.html#Dependency-Tracking-Evolution + * + * See the IManagedDependencyCommands interface for more information. + * + * + * Note for GNU make: these separate dependency files are "include"d by + * a main makefile. Make performs special processing on make files: + * + * "To this end, after reading in all makefiles, make will consider + * each as a goal target and attempt to update it. If a makefile has a + * rule which says how to update it (found either in that very + * makefile or in another one)..., it will be updated if necessary. + * After all makefiles have been checked, if any have actually been + * changed, make starts with a clean slate and reads all the makefiles + * over again." + * + * We can use this to ensure that the dependency files are up to date + * by adding rules to the make file for generating the dependency files. + * These rules are returned by the call to getDependencyCommands. + * However, this has a significant problem when we don�t want to build + * the build target, but only want to �clean� the configuration, + * for example. If we invoke make just to clean the configuration, + * make will still update the dependency files if necessary, thereby + * re-generating the dependency files only to immediately delete them. + * The workaround suggested by the make documentation is to check for + * an invocation using the �clean� target, and to not include the + * dependency files it that case. For example, + * + * ifneq ($(MAKECMDGOALS),clean) + * include $(DEPS) + * endif + * + * The restriction with this is that it only works if �clean� is the only + * target specified on the make command line. Therefore, the build + * "clean" step must be invoked separately. + */ + +public interface IManagedDependencyPreBuild extends IManagedDependencyInfo { + + /** + * Returns the list of generated dependency files. + * + * The paths can be either relative to the top build directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getDependencyFiles(); + + /** + * Returns the name to be used in the build file to identify the separate + * build step. Note that this name should be unique to the tool since + * multiple tools in a tool-chain may be using this method of + * dependency calculation. + * + * @return String + */ + public String getBuildStepName(); + + /** + * Returns the command line(s) to be invoked in the separate + * dependencies pre-build step. + * + * @return String[] + */ + public String[] getDependencyCommands(); + + /** + * Returns true if the command lines returned by this interface + * are not specific to the particular source file, but are only specific to, + * at most, the configuration and tool. If the build context is a resource + * configuration, this method should return false if any of the command lines + * are different than if the build context were the parent configuration. + * This can be used by the build file generator in helping to determine if + * a "pattern" (generic) rule can be used. + * + * @return boolean + */ + public boolean areCommandsGeneric(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java index 900502650da..8fa330cf536 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java @@ -1,300 +1,300 @@ -/******************************************************************************* - * 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.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; - -/** - * @since 2.0 - */ -public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerator { - - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - public final String WHITESPACE = " "; //$NON-NLS-1$ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) - */ - public IResource[] findDependencies(IResource resource, IProject project) { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() - */ - public int getCalculatorType() { - return TYPE_COMMAND; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() - */ - public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { - /* - * For a given input, /., return a string containing - * echo -n $(@:%.=%.d) '/' >> $(@:%.=%.d) && \ - * -P -MM -MG $< >> $(@:%.=%.d) - * - */ - StringBuffer buffer = new StringBuffer(); - - // Get what we need to create the dependency generation command - IConfiguration config = info.getDefaultConfiguration(); - - // We need to check whether we have any resource specific build information. - IResourceConfiguration resConfig = null; - if( config != null ) resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); - - String inputExtension = resource.getFileExtension(); - String outputExtension = info.getOutputExtension(inputExtension); - - // Work out the build-relative path for the output files - IContainer resourceLocation = resource.getParent(); - String relativePath = new String(); - if (resourceLocation != null) { - relativePath += resourceLocation.getProjectRelativePath().toString(); - } - if (relativePath.length() > 0) { - relativePath += IManagedBuilderMakefileGenerator.SEPARATOR; - } - - // Calculate the dependency rule - // /$(@:%.=%.d) - String depRule = "'$(@:%." + //$NON-NLS-1$ - outputExtension + - "=%." + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.DEP_EXT + - ")'"; //$NON-NLS-1$ - - // Add the rule that will actually create the right format for the dep - buffer.append(IManagedBuilderMakefileGenerator.TAB + - IManagedBuilderMakefileGenerator.ECHO + - IManagedBuilderMakefileGenerator.WHITESPACE + - "-n" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - depRule + - IManagedBuilderMakefileGenerator.WHITESPACE + - "$(dir $@)" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - ">" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - depRule + - IManagedBuilderMakefileGenerator.WHITESPACE + - IManagedBuilderMakefileGenerator.LOGICAL_AND + - IManagedBuilderMakefileGenerator.WHITESPACE + - IManagedBuilderMakefileGenerator.LINEBREAK); - - // Add the line that will do the work to calculate dependencies - IManagedCommandLineInfo cmdLInfo = null; - String buildCmd = null; - String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO; - String outflag = ""; //$NON-NLS-1$ - String outputPrefix = ""; //$NON-NLS-1$ - String outputFile = ""; //$NON-NLS-1$ - ITool[] tools; - if( resConfig != null && (tools = resConfig.getToolsToInvoke()) != null && tools.length > 0) { - ITool tool = tools[0]; - String cmd = tool.getToolCommand(); - //try to resolve the build macros in the tool command - try { - String resolvedCommand = null; - - // does the resource have spaces in its name? - if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { - // use fully qualified strings - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } else { - // use builder variables - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } - - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - String[] toolFlags = null; - try { - toolFlags = tool.getToolCommandFlags(resource.getLocation(),null); - } catch( BuildException ex ) { - // TODO add some routines to catch this - toolFlags = EMPTY_STRING_ARRAY; - } - String[] flags = new String[toolFlags.length + 4]; - flags[0] = "-MM"; //$NON-NLS-1$ - flags[1] = "-MG"; //$NON-NLS-1$ - flags[2] = "-P"; //$NON-NLS-1$ - flags[3] = "-w"; //$NON-NLS-1$ - for (int i=0; i 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - - } else { - ITool tool = null; - tools = config.getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tmp = tools[index]; - if (tmp.buildsFileType(inputExtension)) { - tool = tmp; - break; - } - } - String cmd = tool != null ? tool.getToolCommand() : null; - - //try to resolve the build macros in the tool command - try{ - String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(),null,null,tool)); - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - String buildFlags = "-MM -MG -P -w " + info.getToolFlagsForSource(inputExtension, resource.getLocation(), null); //$NON-NLS-1$ - String[] flags = buildFlags.split( "\\s" ); //$NON-NLS-1$ - cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix, - outputFile, inputs, resource.getLocation(), null); - // The command to build - if( cmdLInfo == null ) buildCmd = - cmd + - IManagedBuilderMakefileGenerator.WHITESPACE + - "-MM -MG -P -w " + //$NON-NLS-1$ - buildFlags + - IManagedBuilderMakefileGenerator.WHITESPACE + - IManagedBuilderMakefileGenerator.IN_MACRO; - else { - buildCmd = cmdLInfo.getCommandLine(); - } - - // resolve any remaining macros in the command after it has been - // generated - try { - String resolvedCommand = null; - - // does the resource have spaces in its name? - if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { - // use fully qualified strings - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - buildCmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } else { - // use builder variables - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - buildCmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - } - - buffer.append(IManagedBuilderMakefileGenerator.TAB + - buildCmd + - IManagedBuilderMakefileGenerator.WHITESPACE + - ">>" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + depRule ); - - return buffer.toString(); - } - -} +/******************************************************************************* + * 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.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * @since 2.0 + */ +public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerator { + + private static final String EMPTY_STRING = new String(); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + public final String WHITESPACE = " "; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) + */ + public IResource[] findDependencies(IResource resource, IProject project) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_COMMAND; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() + */ + public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { + /* + * For a given input, /., return a string containing + * echo -n $(@:%.=%.d) '/' >> $(@:%.=%.d) && \ + * -P -MM -MG $< >> $(@:%.=%.d) + * + */ + StringBuffer buffer = new StringBuffer(); + + // Get what we need to create the dependency generation command + IConfiguration config = info.getDefaultConfiguration(); + + // We need to check whether we have any resource specific build information. + IResourceConfiguration resConfig = null; + if( config != null ) resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); + + String inputExtension = resource.getFileExtension(); + String outputExtension = info.getOutputExtension(inputExtension); + + // Work out the build-relative path for the output files + IContainer resourceLocation = resource.getParent(); + String relativePath = new String(); + if (resourceLocation != null) { + relativePath += resourceLocation.getProjectRelativePath().toString(); + } + if (relativePath.length() > 0) { + relativePath += IManagedBuilderMakefileGenerator.SEPARATOR; + } + + // Calculate the dependency rule + // /$(@:%.=%.d) + String depRule = "'$(@:%." + //$NON-NLS-1$ + outputExtension + + "=%." + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.DEP_EXT + + ")'"; //$NON-NLS-1$ + + // Add the rule that will actually create the right format for the dep + buffer.append(IManagedBuilderMakefileGenerator.TAB + + IManagedBuilderMakefileGenerator.ECHO + + IManagedBuilderMakefileGenerator.WHITESPACE + + "-n" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + depRule + + IManagedBuilderMakefileGenerator.WHITESPACE + + "$(dir $@)" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + ">" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + depRule + + IManagedBuilderMakefileGenerator.WHITESPACE + + IManagedBuilderMakefileGenerator.LOGICAL_AND + + IManagedBuilderMakefileGenerator.WHITESPACE + + IManagedBuilderMakefileGenerator.LINEBREAK); + + // Add the line that will do the work to calculate dependencies + IManagedCommandLineInfo cmdLInfo = null; + String buildCmd = null; + String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO; + String outflag = ""; //$NON-NLS-1$ + String outputPrefix = ""; //$NON-NLS-1$ + String outputFile = ""; //$NON-NLS-1$ + ITool[] tools; + if( resConfig != null && (tools = resConfig.getToolsToInvoke()) != null && tools.length > 0) { + ITool tool = tools[0]; + String cmd = tool.getToolCommand(); + //try to resolve the build macros in the tool command + try { + String resolvedCommand = null; + + // does the resource have spaces in its name? + if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { + // use fully qualified strings + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } else { + // use builder variables + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } + + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + String[] toolFlags = null; + try { + toolFlags = tool.getToolCommandFlags(resource.getLocation(),null); + } catch( BuildException ex ) { + // TODO add some routines to catch this + toolFlags = EMPTY_STRING_ARRAY; + } + String[] flags = new String[toolFlags.length + 4]; + flags[0] = "-MM"; //$NON-NLS-1$ + flags[1] = "-MG"; //$NON-NLS-1$ + flags[2] = "-P"; //$NON-NLS-1$ + flags[3] = "-w"; //$NON-NLS-1$ + for (int i=0; i 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + + } else { + ITool tool = null; + tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tmp = tools[index]; + if (tmp.buildsFileType(inputExtension)) { + tool = tmp; + break; + } + } + String cmd = tool != null ? tool.getToolCommand() : null; + + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(),null,null,tool)); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + String buildFlags = "-MM -MG -P -w " + info.getToolFlagsForSource(inputExtension, resource.getLocation(), null); //$NON-NLS-1$ + String[] flags = buildFlags.split( "\\s" ); //$NON-NLS-1$ + cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix, + outputFile, inputs, resource.getLocation(), null); + // The command to build + if( cmdLInfo == null ) buildCmd = + cmd + + IManagedBuilderMakefileGenerator.WHITESPACE + + "-MM -MG -P -w " + //$NON-NLS-1$ + buildFlags + + IManagedBuilderMakefileGenerator.WHITESPACE + + IManagedBuilderMakefileGenerator.IN_MACRO; + else { + buildCmd = cmdLInfo.getCommandLine(); + } + + // resolve any remaining macros in the command after it has been + // generated + try { + String resolvedCommand = null; + + // does the resource have spaces in its name? + if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { + // use fully qualified strings + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + buildCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } else { + // use builder variables + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + buildCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + } + + buffer.append(IManagedBuilderMakefileGenerator.TAB + + buildCmd + + IManagedBuilderMakefileGenerator.WHITESPACE + + ">>" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + depRule ); + + return buffer.toString(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java index f6a7494bf31..5fd84519ae3 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java @@ -1,70 +1,70 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; -import org.eclipse.core.runtime.IPath; - -/** - * This dependency calculator uses the GCC -MMD -MF -MP -MT options in order to - * generate .d files as a side effect of compilation. - * See bugzilla 108715 for the discussion of dependency management that led to - * the creation of this dependency calculator. Note also that this technique - * exhibits the failure modes discussed in comment #5. - * - * This dependency calculator uses the class DefaultGCCDependencyCalculator2Commands - * which implements the per-source command information - * - * @since 3.1 - */ - -public class DefaultGCCDependencyCalculator2 implements - IManagedDependencyGenerator2 { - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() - */ - public int getCalculatorType() { - return TYPE_BUILD_COMMANDS; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) - */ - public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { - return IManagedBuilderMakefileGenerator.DEP_EXT; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) - */ - public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { - return new DefaultGCCDependencyCalculator2Commands(source, buildContext, tool, topBuildDirectory); - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) - */ - public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { - // Nothing - return false; - } - -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.core.runtime.IPath; + +/** + * This dependency calculator uses the GCC -MMD -MF -MP -MT options in order to + * generate .d files as a side effect of compilation. + * See bugzilla 108715 for the discussion of dependency management that led to + * the creation of this dependency calculator. Note also that this technique + * exhibits the failure modes discussed in comment #5. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculator2Commands + * which implements the per-source command information + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculator2 implements + IManagedDependencyGenerator2 { + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_BUILD_COMMANDS; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) + */ + public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { + return IManagedBuilderMakefileGenerator.DEP_EXT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + return new DefaultGCCDependencyCalculator2Commands(source, buildContext, tool, topBuildDirectory); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { + // Nothing + return false; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java index 9bfdb088f23..c570177e9ea 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java @@ -1,203 +1,203 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.resources.IProject;; - -/** - * This dependency calculator uses the GCC -MMD -MF -MP -MT options in order to - * generate .d files as a side effect of compilation. - * See bugzilla 108715 for the discussion of dependency management that led to - * the creation of this dependency calculator. Note also that this technique - * exhibits the failure modes discussed in comment #5. - * - * This class is used with DefaultGCCDependencyCalculator2. - * - * @since 3.1 - */ - -public class DefaultGCCDependencyCalculator2Commands implements - IManagedDependencyCommands { - - // Member variables set by the constructor - IPath source; - IBuildObject buildContext; - ITool tool; - IPath topBuildDirectory; - - // Other Member variables - IProject project; - IPath sourceLocation; - IPath outputLocation; - boolean needExplicitRuleForFile; - Boolean genericCommands = null; - - /** - * Constructor - * - * @param source The source file for which dependencies should be calculated - * The IPath can be either relative to the project directory, or absolute in the file system. - * @param buildContext The IConfiguration or IResourceConfiguration that - * contains the context in which the source file will be built - * @param tool The tool associated with the source file - * @param topBuildDirectory The top build directory of the configuration. This is - * the working directory for the tool. This IPath is relative to the project directory. - */ - public DefaultGCCDependencyCalculator2Commands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { - this.source = source; - this.buildContext = buildContext; - this.tool = tool; - this.topBuildDirectory = topBuildDirectory; - - // Compute the project - if (buildContext instanceof IConfiguration) { - IConfiguration config = (IConfiguration)buildContext; - project = (IProject)config.getOwner(); - } else if (buildContext instanceof IResourceConfiguration) { - IResourceConfiguration resConfig = (IResourceConfiguration)buildContext; - project = (IProject)resConfig.getOwner(); - } - - sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); - outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); - - // A separate rule is needed for the resource in the case where explicit file-specific macros - // are referenced, or if the resource contains special characters in its path (e.g., whitespace) - needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || - MacroResolver.getReferencedExplitFileMacros(tool).length > 0 - || MacroResolver.getReferencedExplitFileMacros( - tool.getToolCommand(), - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, outputLocation, - null, tool)).length > 0; - - if (needExplicitRuleForFile) genericCommands = new Boolean(false); - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#areCommandsGeneric() - */ - public boolean areCommandsGeneric() { - if (genericCommands == null) genericCommands = new Boolean(true); - return genericCommands.booleanValue(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyCommandOptions() - */ - public String[] getDependencyCommandOptions() { - - String[] options = new String[4]; - // -MMD - options[0] = "-MMD"; //$NON-NLS-1$ - // -MP - options[1] = "-MP"; //$NON-NLS-1$ - // -MF$(@:%.o=%.d) - options[2] = "-MF\"$(@:%.o=%.d)\""; //$NON-NLS-1$ - //options[2] = "-MF\"${OutputDirRelPath}${OutputFileBaseName}.d\""; //$NON-NLS-1$ - if( buildContext instanceof IResourceConfiguration || needExplicitRuleForFile ) { - IPath outPath = getDependencyFiles()[0]; - // -MT"dependecy-file-name" - String optTxt = "-MT\""; //$NON-NLS-1$ - optTxt += GnuMakefileGenerator.escapeWhitespaces(outPath.toString()) + "\""; //$NON-NLS-1$ - options[3] = optTxt; - } else { - // -MT"$(@:%.o=%.d) %.o" - options[3] = "-MT\"$(@:%.o=%.d)\""; //$NON-NLS-1$ - //options[3] = "-MT\"${OutputDirRelPath}${OutputFileBaseName}.d\""; //$NON-NLS-1$ - } - - return options; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyFiles() - */ - public IPath[] getDependencyFiles() { - // The source file is project relative and the dependency file is top build directory relative - // Remove the source extension and add the dependency extension - IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); - // Remember that the source folder hierarchy and the build output folder hierarchy are the same - // but if this is a generated resource, then it may already be under the top build directory - if (!depFilePath.isAbsolute()) { - if (topBuildDirectory.isPrefixOf(depFilePath)) { - depFilePath = depFilePath.removeFirstSegments(1); - } - } - IPath[] paths = new IPath[1]; - paths[0] = depFilePath; - return paths; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPostToolDependencyCommands() - */ - public String[] getPostToolDependencyCommands() { - // Nothing - return null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPreToolDependencyCommands() - */ - public String[] getPreToolDependencyCommands() { - // Nothing - return null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() - */ - public IBuildObject getBuildContext() { - return buildContext; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() - */ - public IPath getSource() { - return source; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() - */ - public ITool getTool() { - return tool; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() - */ - public IPath getTopBuildDirectory() { - return topBuildDirectory; - } - -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.resources.IProject;; + +/** + * This dependency calculator uses the GCC -MMD -MF -MP -MT options in order to + * generate .d files as a side effect of compilation. + * See bugzilla 108715 for the discussion of dependency management that led to + * the creation of this dependency calculator. Note also that this technique + * exhibits the failure modes discussed in comment #5. + * + * This class is used with DefaultGCCDependencyCalculator2. + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculator2Commands implements + IManagedDependencyCommands { + + // Member variables set by the constructor + IPath source; + IBuildObject buildContext; + ITool tool; + IPath topBuildDirectory; + + // Other Member variables + IProject project; + IPath sourceLocation; + IPath outputLocation; + boolean needExplicitRuleForFile; + Boolean genericCommands = null; + + /** + * Constructor + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + */ + public DefaultGCCDependencyCalculator2Commands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + this.source = source; + this.buildContext = buildContext; + this.tool = tool; + this.topBuildDirectory = topBuildDirectory; + + // Compute the project + if (buildContext instanceof IConfiguration) { + IConfiguration config = (IConfiguration)buildContext; + project = (IProject)config.getOwner(); + } else if (buildContext instanceof IResourceConfiguration) { + IResourceConfiguration resConfig = (IResourceConfiguration)buildContext; + project = (IProject)resConfig.getOwner(); + } + + sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); + outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); + + // A separate rule is needed for the resource in the case where explicit file-specific macros + // are referenced, or if the resource contains special characters in its path (e.g., whitespace) + needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || + MacroResolver.getReferencedExplitFileMacros(tool).length > 0 + || MacroResolver.getReferencedExplitFileMacros( + tool.getToolCommand(), + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + if (needExplicitRuleForFile) genericCommands = new Boolean(false); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#areCommandsGeneric() + */ + public boolean areCommandsGeneric() { + if (genericCommands == null) genericCommands = new Boolean(true); + return genericCommands.booleanValue(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyCommandOptions() + */ + public String[] getDependencyCommandOptions() { + + String[] options = new String[4]; + // -MMD + options[0] = "-MMD"; //$NON-NLS-1$ + // -MP + options[1] = "-MP"; //$NON-NLS-1$ + // -MF$(@:%.o=%.d) + options[2] = "-MF\"$(@:%.o=%.d)\""; //$NON-NLS-1$ + //options[2] = "-MF\"${OutputDirRelPath}${OutputFileBaseName}.d\""; //$NON-NLS-1$ + if( buildContext instanceof IResourceConfiguration || needExplicitRuleForFile ) { + IPath outPath = getDependencyFiles()[0]; + // -MT"dependecy-file-name" + String optTxt = "-MT\""; //$NON-NLS-1$ + optTxt += GnuMakefileGenerator.escapeWhitespaces(outPath.toString()) + "\""; //$NON-NLS-1$ + options[3] = optTxt; + } else { + // -MT"$(@:%.o=%.d) %.o" + options[3] = "-MT\"$(@:%.o=%.d)\""; //$NON-NLS-1$ + //options[3] = "-MT\"${OutputDirRelPath}${OutputFileBaseName}.d\""; //$NON-NLS-1$ + } + + return options; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyFiles() + */ + public IPath[] getDependencyFiles() { + // The source file is project relative and the dependency file is top build directory relative + // Remove the source extension and add the dependency extension + IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); + // Remember that the source folder hierarchy and the build output folder hierarchy are the same + // but if this is a generated resource, then it may already be under the top build directory + if (!depFilePath.isAbsolute()) { + if (topBuildDirectory.isPrefixOf(depFilePath)) { + depFilePath = depFilePath.removeFirstSegments(1); + } + } + IPath[] paths = new IPath[1]; + paths[0] = depFilePath; + return paths; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPostToolDependencyCommands() + */ + public String[] getPostToolDependencyCommands() { + // Nothing + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPreToolDependencyCommands() + */ + public String[] getPreToolDependencyCommands() { + // Nothing + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() + */ + public IBuildObject getBuildContext() { + return buildContext; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() + */ + public IPath getSource() { + return source; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() + */ + public ITool getTool() { + return tool; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() + */ + public IPath getTopBuildDirectory() { + return topBuildDirectory; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3.java index 4346fb4fbeb..65eddf9d909 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3.java @@ -1,98 +1,98 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import java.io.IOException; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; - -/** - * This dependency calculator uses the same dependency management technique as the - * DefaultGCCDependencyCalculator. That is: - * - * 1. An echo command creates the dependency file (.d). - * 2. A second invocation of the compiler is made in order to append to the dependency file. - * The additional options -MM -MG -P -w are added to the command line. - * 3. The dependency files are post-processed to add the empty header rules. - * - * This dependency calculator uses the class DefaultGCCDependencyCalculator3Commands - * which implements the per-source command information - * - * This is an example dependency calculator that is not used by the CDT GCC tool-chain. - * - * @since 3.1 - */ - -public class DefaultGCCDependencyCalculator3 implements - IManagedDependencyGenerator2 { - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() - */ - public int getCalculatorType() { - return TYPE_BUILD_COMMANDS; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) - */ - public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { - return IManagedBuilderMakefileGenerator.DEP_EXT; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) - */ - public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { - return new DefaultGCCDependencyCalculator3Commands(source, buildContext, tool, topBuildDirectory); - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) - */ - public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { - try { - IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); - IFile makefile; - IPath makefilePath; - if (dependencyFile.isAbsolute()) { - makefilePath = dependencyFile; - } else { - makefilePath = topBuildDirectory.append(dependencyFile); - } - IPath rootPath = root.getLocation(); - if (rootPath.isPrefixOf(makefilePath)) { - makefilePath = makefilePath.removeFirstSegments(rootPath.segmentCount()); - } - makefile = root.getFile(makefilePath); - return GnuMakefileGenerator.populateDummyTargets(buildContext, makefile, false); - } catch (CoreException e) { - } catch (IOException e) { - } - return false; - } - -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import java.io.IOException; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * This dependency calculator uses the same dependency management technique as the + * DefaultGCCDependencyCalculator. That is: + * + * 1. An echo command creates the dependency file (.d). + * 2. A second invocation of the compiler is made in order to append to the dependency file. + * The additional options -MM -MG -P -w are added to the command line. + * 3. The dependency files are post-processed to add the empty header rules. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculator3Commands + * which implements the per-source command information + * + * This is an example dependency calculator that is not used by the CDT GCC tool-chain. + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculator3 implements + IManagedDependencyGenerator2 { + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_BUILD_COMMANDS; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) + */ + public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { + return IManagedBuilderMakefileGenerator.DEP_EXT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + return new DefaultGCCDependencyCalculator3Commands(source, buildContext, tool, topBuildDirectory); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { + try { + IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); + IFile makefile; + IPath makefilePath; + if (dependencyFile.isAbsolute()) { + makefilePath = dependencyFile; + } else { + makefilePath = topBuildDirectory.append(dependencyFile); + } + IPath rootPath = root.getLocation(); + if (rootPath.isPrefixOf(makefilePath)) { + makefilePath = makefilePath.removeFirstSegments(rootPath.segmentCount()); + } + makefile = root.getFile(makefilePath); + return GnuMakefileGenerator.populateDummyTargets(buildContext, makefile, false); + } catch (CoreException e) { + } catch (IOException e) { + } + return false; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3Commands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3Commands.java index 967d99dac1e..b79d9e3b321 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3Commands.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator3Commands.java @@ -1,330 +1,330 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.resources.IProject;; - -/** - * This dependency calculator uses the same dependency management technique as the - * DefaultGCCDependencyCalculator. That is: - * - * 1. An echo command creates the dependency file (.d). - * 2. A second invocation of the compiler is made in order to append to the dependency file. - * The additional options -MM -MG -P -w are added to the command line. - * 3. The dependency files are post-processed to add the empty header rules. - * - * This class is used with DefaultGCCDependencyCalculator3. - * - * This is an example dependency calculator that is not used by the CDT GCC tool-chain. - * - * @since 3.1 - */ - -public class DefaultGCCDependencyCalculator3Commands implements - IManagedDependencyCommands { - - private static final String EMPTY_STRING = new String(); - - // Member variables set by the constructor - IPath source; - IBuildObject buildContext; - ITool tool; - IPath topBuildDirectory; - - // Other Member variables - IProject project; - IConfiguration config; - IResourceConfiguration resConfig; - IPath sourceLocation; - IPath outputLocation; - boolean needExplicitRuleForFile; - boolean genericCommands = true; - - /** - * Constructor - * - * @param source The source file for which dependencies should be calculated - * The IPath can be either relative to the project directory, or absolute in the file system. - * @param buildContext The IConfiguration or IResourceConfiguration that - * contains the context in which the source file will be built - * @param tool The tool associated with the source file - * @param topBuildDirectory The top build directory of the configuration. This is - * the working directory for the tool. This IPath is relative to the project directory. - */ - public DefaultGCCDependencyCalculator3Commands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { - this.source = source; - this.buildContext = buildContext; - this.tool = tool; - this.topBuildDirectory = topBuildDirectory; - - // Compute the project - if (buildContext instanceof IConfiguration) { - resConfig = null; - config = (IConfiguration)buildContext; - project = (IProject)config.getOwner(); - } else if (buildContext instanceof IResourceConfiguration) { - resConfig = (IResourceConfiguration)buildContext; - config = resConfig.getParent(); - project = (IProject)resConfig.getOwner(); - } - - sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); - outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); - - // A separate rule is needed for the resource in the case where explicit file-specific macros - // are referenced, or if the resource contains special characters in its path (e.g., whitespace) - needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || - MacroResolver.getReferencedExplitFileMacros(tool).length > 0 - || MacroResolver.getReferencedExplitFileMacros( - tool.getToolCommand(), - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, outputLocation, - null, tool)).length > 0; - - if (buildContext instanceof IResourceConfiguration || needExplicitRuleForFile) - genericCommands = false; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#areCommandsGeneric() - */ - public boolean areCommandsGeneric() { - return genericCommands; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyCommandOptions() - */ - public String[] getDependencyCommandOptions() { - // Nothing - return null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyFiles() - */ - public IPath[] getDependencyFiles() { - // The source file is project relative and the dependency file is top build directory relative - // Remove the source extension and add the dependency extension - IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); - // Remember that the source folder hierarchy and the build output folder hierarchy are the same - // but if this is a generated resource, then it may already be under the top build directory - if (!depFilePath.isAbsolute()) { - if (topBuildDirectory.isPrefixOf(depFilePath)) { - depFilePath = depFilePath.removeFirstSegments(1); - } - } - IPath[] paths = new IPath[1]; - paths[0] = depFilePath; - return paths; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPostToolDependencyCommands() - */ - public String[] getPostToolDependencyCommands() { - /* - * For a given input, /., return a string containing - * echo -n $(@:%.=%.d) '/' >> $(@:%.=%.d) && \ - * -P -MM -MG $< >> $(@:%.=%.d) - * - */ - String[] commands = new String[2]; - - // Get what we need to create the dependency generation command - String inputExtension = source.getFileExtension(); - String outputExtension = tool.getOutputExtension(inputExtension); - - // Calculate the dependency rule - // /$(@:%.=%.d) - String depRule = "'$(@:%." + //$NON-NLS-1$ - outputExtension + - "=%." + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.DEP_EXT + - ")'"; //$NON-NLS-1$ - - // Add the Echo command that will actually create the right format for the dep - commands[0] = - IManagedBuilderMakefileGenerator.TAB + - IManagedBuilderMakefileGenerator.ECHO + - IManagedBuilderMakefileGenerator.WHITESPACE + - "-n" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - depRule + - IManagedBuilderMakefileGenerator.WHITESPACE + - "$(dir $@)" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - ">" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - depRule; - - // Add the line that will do the work to calculate dependencies - IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider(); - IManagedCommandLineInfo cmdLInfo = null; - String buildCmd = null; - String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO; - String outputFile = ""; //$NON-NLS-1$ - String outflag = ""; //$NON-NLS-1$ - String outputPrefix = ""; //$NON-NLS-1$ - String cmd = tool.getToolCommand(); - //try to resolve the build macros in the tool command - try { - String resolvedCommand = null; - - if (!needExplicitRuleForFile) { - resolvedCommand = provider.resolveValueToMakefileFormat( - cmd, - EMPTY_STRING, - IManagedBuilderMakefileGenerator.WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } else { - // if we need an explicit rule then don't use any builder - // variables, resolve everything - // to explicit strings - resolvedCommand = provider.resolveValue( - cmd, - EMPTY_STRING, - IManagedBuilderMakefileGenerator.WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } - - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - String[] toolFlags = null; - try { - toolFlags = tool.getToolCommandFlags(sourceLocation, outputLocation); - } catch( BuildException ex ) { - toolFlags = new String[0]; - } - String[] flags = new String[toolFlags.length + 4]; - flags[0] = "-MM"; //$NON-NLS-1$ - flags[1] = "-MG"; //$NON-NLS-1$ - flags[2] = "-P"; //$NON-NLS-1$ - flags[3] = "-w"; //$NON-NLS-1$ - for (int i=0; i 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - commands[1] = - IManagedBuilderMakefileGenerator.TAB + - buildCmd + - IManagedBuilderMakefileGenerator.WHITESPACE + - ">>" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + depRule; - - return commands; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPreToolDependencyCommands() - */ - public String[] getPreToolDependencyCommands() { - // Nothing - return null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() - */ - public IBuildObject getBuildContext() { - return buildContext; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() - */ - public IPath getSource() { - return source; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() - */ - public ITool getTool() { - return tool; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() - */ - public IPath getTopBuildDirectory() { - return topBuildDirectory; - } - -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.resources.IProject;; + +/** + * This dependency calculator uses the same dependency management technique as the + * DefaultGCCDependencyCalculator. That is: + * + * 1. An echo command creates the dependency file (.d). + * 2. A second invocation of the compiler is made in order to append to the dependency file. + * The additional options -MM -MG -P -w are added to the command line. + * 3. The dependency files are post-processed to add the empty header rules. + * + * This class is used with DefaultGCCDependencyCalculator3. + * + * This is an example dependency calculator that is not used by the CDT GCC tool-chain. + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculator3Commands implements + IManagedDependencyCommands { + + private static final String EMPTY_STRING = new String(); + + // Member variables set by the constructor + IPath source; + IBuildObject buildContext; + ITool tool; + IPath topBuildDirectory; + + // Other Member variables + IProject project; + IConfiguration config; + IResourceConfiguration resConfig; + IPath sourceLocation; + IPath outputLocation; + boolean needExplicitRuleForFile; + boolean genericCommands = true; + + /** + * Constructor + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + */ + public DefaultGCCDependencyCalculator3Commands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + this.source = source; + this.buildContext = buildContext; + this.tool = tool; + this.topBuildDirectory = topBuildDirectory; + + // Compute the project + if (buildContext instanceof IConfiguration) { + resConfig = null; + config = (IConfiguration)buildContext; + project = (IProject)config.getOwner(); + } else if (buildContext instanceof IResourceConfiguration) { + resConfig = (IResourceConfiguration)buildContext; + config = resConfig.getParent(); + project = (IProject)resConfig.getOwner(); + } + + sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); + outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); + + // A separate rule is needed for the resource in the case where explicit file-specific macros + // are referenced, or if the resource contains special characters in its path (e.g., whitespace) + needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || + MacroResolver.getReferencedExplitFileMacros(tool).length > 0 + || MacroResolver.getReferencedExplitFileMacros( + tool.getToolCommand(), + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + if (buildContext instanceof IResourceConfiguration || needExplicitRuleForFile) + genericCommands = false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#areCommandsGeneric() + */ + public boolean areCommandsGeneric() { + return genericCommands; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyCommandOptions() + */ + public String[] getDependencyCommandOptions() { + // Nothing + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyFiles() + */ + public IPath[] getDependencyFiles() { + // The source file is project relative and the dependency file is top build directory relative + // Remove the source extension and add the dependency extension + IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); + // Remember that the source folder hierarchy and the build output folder hierarchy are the same + // but if this is a generated resource, then it may already be under the top build directory + if (!depFilePath.isAbsolute()) { + if (topBuildDirectory.isPrefixOf(depFilePath)) { + depFilePath = depFilePath.removeFirstSegments(1); + } + } + IPath[] paths = new IPath[1]; + paths[0] = depFilePath; + return paths; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPostToolDependencyCommands() + */ + public String[] getPostToolDependencyCommands() { + /* + * For a given input, /., return a string containing + * echo -n $(@:%.=%.d) '/' >> $(@:%.=%.d) && \ + * -P -MM -MG $< >> $(@:%.=%.d) + * + */ + String[] commands = new String[2]; + + // Get what we need to create the dependency generation command + String inputExtension = source.getFileExtension(); + String outputExtension = tool.getOutputExtension(inputExtension); + + // Calculate the dependency rule + // /$(@:%.=%.d) + String depRule = "'$(@:%." + //$NON-NLS-1$ + outputExtension + + "=%." + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.DEP_EXT + + ")'"; //$NON-NLS-1$ + + // Add the Echo command that will actually create the right format for the dep + commands[0] = + IManagedBuilderMakefileGenerator.TAB + + IManagedBuilderMakefileGenerator.ECHO + + IManagedBuilderMakefileGenerator.WHITESPACE + + "-n" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + depRule + + IManagedBuilderMakefileGenerator.WHITESPACE + + "$(dir $@)" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + ">" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + depRule; + + // Add the line that will do the work to calculate dependencies + IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider(); + IManagedCommandLineInfo cmdLInfo = null; + String buildCmd = null; + String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO; + String outputFile = ""; //$NON-NLS-1$ + String outflag = ""; //$NON-NLS-1$ + String outputPrefix = ""; //$NON-NLS-1$ + String cmd = tool.getToolCommand(); + //try to resolve the build macros in the tool command + try { + String resolvedCommand = null; + + if (!needExplicitRuleForFile) { + resolvedCommand = provider.resolveValueToMakefileFormat( + cmd, + EMPTY_STRING, + IManagedBuilderMakefileGenerator.WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } else { + // if we need an explicit rule then don't use any builder + // variables, resolve everything + // to explicit strings + resolvedCommand = provider.resolveValue( + cmd, + EMPTY_STRING, + IManagedBuilderMakefileGenerator.WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } + + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + String[] toolFlags = null; + try { + toolFlags = tool.getToolCommandFlags(sourceLocation, outputLocation); + } catch( BuildException ex ) { + toolFlags = new String[0]; + } + String[] flags = new String[toolFlags.length + 4]; + flags[0] = "-MM"; //$NON-NLS-1$ + flags[1] = "-MG"; //$NON-NLS-1$ + flags[2] = "-P"; //$NON-NLS-1$ + flags[3] = "-w"; //$NON-NLS-1$ + for (int i=0; i 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + commands[1] = + IManagedBuilderMakefileGenerator.TAB + + buildCmd + + IManagedBuilderMakefileGenerator.WHITESPACE + + ">>" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + depRule; + + return commands; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPreToolDependencyCommands() + */ + public String[] getPreToolDependencyCommands() { + // Nothing + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() + */ + public IBuildObject getBuildContext() { + return buildContext; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() + */ + public IPath getSource() { + return source; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() + */ + public ITool getTool() { + return tool; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() + */ + public IPath getTopBuildDirectory() { + return topBuildDirectory; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java index f92456c4178..b78d15357e2 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java @@ -1,69 +1,69 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; -import org.eclipse.core.runtime.IPath; - - -/** - * This dependency calculator uses the GCC -MM -MF -MP -MT options in order to - * generate .d files as separate step prior to the source compilations. - * - * This dependency calculator uses the class DefaultGCCDependencyCalculatorPreBuildCommands - * which implements the per-source command information - * - * @since 3.1 - */ - -public class DefaultGCCDependencyCalculatorPreBuild implements - IManagedDependencyGenerator2 { - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() - */ - public int getCalculatorType() { - return TYPE_PREBUILD_COMMANDS; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) - */ - public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { - return IManagedBuilderMakefileGenerator.DEP_EXT; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) - */ - public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { - return new DefaultGCCDependencyCalculatorPreBuildCommands(source, buildContext, tool, topBuildDirectory); - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) - */ - public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { - // Nothing - return false; - } - -} - +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.core.runtime.IPath; + + +/** + * This dependency calculator uses the GCC -MM -MF -MP -MT options in order to + * generate .d files as separate step prior to the source compilations. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculatorPreBuildCommands + * which implements the per-source command information + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculatorPreBuild implements + IManagedDependencyGenerator2 { + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_PREBUILD_COMMANDS; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) + */ + public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { + return IManagedBuilderMakefileGenerator.DEP_EXT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + return new DefaultGCCDependencyCalculatorPreBuildCommands(source, buildContext, tool, topBuildDirectory); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { + // Nothing + return false; + } + +} + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java index 6a6265aeeb4..97bc24bfd17 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java @@ -1,306 +1,306 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.resources.IProject; -import java.util.Vector; - -/** - * This dependency calculator uses the GCC -MM -MF -MP -MT options in order to - * generate .d files as separate step prior to the source compilations. - * - * This dependency calculator uses the class DefaultGCCDependencyCalculatorPreBuildCommands - * which implements the per-source command information - * - * This class is used with DefaultGCCDependencyCalculatorPreBuild. - * - * @since 3.1 - */ - -public class DefaultGCCDependencyCalculatorPreBuildCommands implements IManagedDependencyPreBuild { - - private static final String EMPTY_STRING = new String(); - - // Member variables set by the constructor - IPath source; - IBuildObject buildContext; - ITool tool; - IPath topBuildDirectory; - - // Other Member variables - IProject project; - IPath sourceLocation; - IPath outputLocation; - boolean needExplicitRuleForFile; - Boolean genericCommands = null; - - /** - * Constructor - * - * @param source The source file for which dependencies should be calculated - * The IPath can be either relative to the project directory, or absolute in the file system. - * @param buildContext The IConfiguration or IResourceConfiguration that - * contains the context in which the source file will be built - * @param tool The tool associated with the source file - * @param topBuildDirectory The top build directory of the configuration. This is - * the working directory for the tool. This IPath is relative to the project directory. - */ - public DefaultGCCDependencyCalculatorPreBuildCommands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { - this.source = source; - this.buildContext = buildContext; - this.tool = tool; - this.topBuildDirectory = topBuildDirectory; - - // Compute the project - if (buildContext instanceof IConfiguration) { - IConfiguration config = (IConfiguration)buildContext; - project = (IProject)config.getOwner(); - } else if (buildContext instanceof IResourceConfiguration) { - IResourceConfiguration resConfig = (IResourceConfiguration)buildContext; - project = (IProject)resConfig.getOwner(); - } - - sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); - outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); - - // A separate rule is needed for the resource in the case where explicit file-specific macros - // are referenced, or if the resource contains special characters in its path (e.g., whitespace) - needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || - MacroResolver.getReferencedExplitFileMacros(tool).length > 0 - || MacroResolver.getReferencedExplitFileMacros( - tool.getToolCommand(), - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, outputLocation, - null, tool)).length > 0; - - if (needExplicitRuleForFile) genericCommands = new Boolean(false); - } - - public boolean areCommandsGeneric() { - if (genericCommands != null) return genericCommands.booleanValue(); - // If the context is a Configuration, yes - if (buildContext instanceof IConfiguration) { - genericCommands = new Boolean(true); - return true; - } - // If the context is a Resource Configuration, determine if it overrides any - // of its parent configuration's options that would affect dependency file - // generation. - // TODO - genericCommands = new Boolean(false); - return false; - } - - public String getBuildStepName() { - return new String("GCC_DEPENDS"); //$NON-NLS-1$ - } - - public String[] getDependencyCommands() { - - String[] commands = new String[1]; - String depCmd = EMPTY_STRING; - IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider(); - - // Get and resolve the command - String cmd = tool.getToolCommand(); - try { - String resolvedCommand = null; - if (!needExplicitRuleForFile) { - resolvedCommand = provider.resolveValueToMakefileFormat( - cmd, - EMPTY_STRING, - IManagedBuilderMakefileGenerator.WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } else { - // if we need an explicit rule then don't use any builder - // variables, resolve everything - // to explicit strings - resolvedCommand = provider.resolveValue( - cmd, - EMPTY_STRING, - IManagedBuilderMakefileGenerator.WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } - - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - IManagedCommandLineInfo cmdLInfo = null; - - // Set up the command line options that will generate the dependency file - Vector options = new Vector(); - // -w - options.add("-w"); //$NON-NLS-1$ - // -MM - options.add("-MM"); //$NON-NLS-1$ - // -MP - options.add("-MP"); //$NON-NLS-1$ - - String optTxt; - - if( buildContext instanceof IResourceConfiguration || needExplicitRuleForFile ) { - IPath outPath = getDependencyFiles()[0]; - // -MT"dependecy-file-name" - optTxt = "-MT\""; //$NON-NLS-1$ - optTxt += GnuMakefileGenerator.escapeWhitespaces(outPath.toString()) + "\""; //$NON-NLS-1$ - options.add(optTxt); - // -MT"object-file-filename" - optTxt = "-MT\""; //$NON-NLS-1$ - optTxt += GnuMakefileGenerator.escapeWhitespaces((outPath.removeFileExtension()).toString()); - String outExt = tool.getOutputExtension(source.getFileExtension()); - if (outExt != null) optTxt += "." + outExt; //$NON-NLS-1$ - optTxt += "\""; //$NON-NLS-1$ - options.add(optTxt); - } else { - // -MT"$@" - options.add("-MT\"$@\""); //$NON-NLS-1$ - // -MT'$(@:%.d=%.o)' - optTxt = "-MT\"$(@:%.d=%.o)\""; //$NON-NLS-1$ - //optTxt = "-MT\"${OutputDirRelPath}${OutputFileBaseName}"; - //if (outExt != null) optTxt += "." + outExt; - //optTxt += "\""; //$NON-NLS-1$ - options.add(optTxt); - } - - // Save the -I, -D, -U options and discard the rest - try { - String[] allFlags = tool.getToolCommandFlags(sourceLocation, outputLocation); - for (int i=0; i 0) - depCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - } - - commands[0] = depCmd; - return commands; - } - - public IPath[] getDependencyFiles() { - // The source file is project relative and the dependency file is top build directory relative - // Remove the source extension and add the dependency extension - IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); - // Remember that the source folder hierarchy and the build output folder hierarchy are the same - // but if this is a generated resource, then it may already be under the top build directory - if (!depFilePath.isAbsolute()) { - if (topBuildDirectory.isPrefixOf(depFilePath)) { - depFilePath = depFilePath.removeFirstSegments(1); - } - } - IPath[] paths = new IPath[1]; - paths[0] = depFilePath; - return paths; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() - */ - public IBuildObject getBuildContext() { - return buildContext; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() - */ - public IPath getSource() { - return source; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() - */ - public ITool getTool() { - return tool; - } - - /* - * (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() - */ - public IPath getTopBuildDirectory() { - return topBuildDirectory; - } - -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.resources.IProject; +import java.util.Vector; + +/** + * This dependency calculator uses the GCC -MM -MF -MP -MT options in order to + * generate .d files as separate step prior to the source compilations. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculatorPreBuildCommands + * which implements the per-source command information + * + * This class is used with DefaultGCCDependencyCalculatorPreBuild. + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculatorPreBuildCommands implements IManagedDependencyPreBuild { + + private static final String EMPTY_STRING = new String(); + + // Member variables set by the constructor + IPath source; + IBuildObject buildContext; + ITool tool; + IPath topBuildDirectory; + + // Other Member variables + IProject project; + IPath sourceLocation; + IPath outputLocation; + boolean needExplicitRuleForFile; + Boolean genericCommands = null; + + /** + * Constructor + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + */ + public DefaultGCCDependencyCalculatorPreBuildCommands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + this.source = source; + this.buildContext = buildContext; + this.tool = tool; + this.topBuildDirectory = topBuildDirectory; + + // Compute the project + if (buildContext instanceof IConfiguration) { + IConfiguration config = (IConfiguration)buildContext; + project = (IProject)config.getOwner(); + } else if (buildContext instanceof IResourceConfiguration) { + IResourceConfiguration resConfig = (IResourceConfiguration)buildContext; + project = (IProject)resConfig.getOwner(); + } + + sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); + outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); + + // A separate rule is needed for the resource in the case where explicit file-specific macros + // are referenced, or if the resource contains special characters in its path (e.g., whitespace) + needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || + MacroResolver.getReferencedExplitFileMacros(tool).length > 0 + || MacroResolver.getReferencedExplitFileMacros( + tool.getToolCommand(), + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + if (needExplicitRuleForFile) genericCommands = new Boolean(false); + } + + public boolean areCommandsGeneric() { + if (genericCommands != null) return genericCommands.booleanValue(); + // If the context is a Configuration, yes + if (buildContext instanceof IConfiguration) { + genericCommands = new Boolean(true); + return true; + } + // If the context is a Resource Configuration, determine if it overrides any + // of its parent configuration's options that would affect dependency file + // generation. + // TODO + genericCommands = new Boolean(false); + return false; + } + + public String getBuildStepName() { + return new String("GCC_DEPENDS"); //$NON-NLS-1$ + } + + public String[] getDependencyCommands() { + + String[] commands = new String[1]; + String depCmd = EMPTY_STRING; + IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider(); + + // Get and resolve the command + String cmd = tool.getToolCommand(); + try { + String resolvedCommand = null; + if (!needExplicitRuleForFile) { + resolvedCommand = provider.resolveValueToMakefileFormat( + cmd, + EMPTY_STRING, + IManagedBuilderMakefileGenerator.WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } else { + // if we need an explicit rule then don't use any builder + // variables, resolve everything + // to explicit strings + resolvedCommand = provider.resolveValue( + cmd, + EMPTY_STRING, + IManagedBuilderMakefileGenerator.WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } + + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + IManagedCommandLineInfo cmdLInfo = null; + + // Set up the command line options that will generate the dependency file + Vector options = new Vector(); + // -w + options.add("-w"); //$NON-NLS-1$ + // -MM + options.add("-MM"); //$NON-NLS-1$ + // -MP + options.add("-MP"); //$NON-NLS-1$ + + String optTxt; + + if( buildContext instanceof IResourceConfiguration || needExplicitRuleForFile ) { + IPath outPath = getDependencyFiles()[0]; + // -MT"dependecy-file-name" + optTxt = "-MT\""; //$NON-NLS-1$ + optTxt += GnuMakefileGenerator.escapeWhitespaces(outPath.toString()) + "\""; //$NON-NLS-1$ + options.add(optTxt); + // -MT"object-file-filename" + optTxt = "-MT\""; //$NON-NLS-1$ + optTxt += GnuMakefileGenerator.escapeWhitespaces((outPath.removeFileExtension()).toString()); + String outExt = tool.getOutputExtension(source.getFileExtension()); + if (outExt != null) optTxt += "." + outExt; //$NON-NLS-1$ + optTxt += "\""; //$NON-NLS-1$ + options.add(optTxt); + } else { + // -MT"$@" + options.add("-MT\"$@\""); //$NON-NLS-1$ + // -MT'$(@:%.d=%.o)' + optTxt = "-MT\"$(@:%.d=%.o)\""; //$NON-NLS-1$ + //optTxt = "-MT\"${OutputDirRelPath}${OutputFileBaseName}"; + //if (outExt != null) optTxt += "." + outExt; + //optTxt += "\""; //$NON-NLS-1$ + options.add(optTxt); + } + + // Save the -I, -D, -U options and discard the rest + try { + String[] allFlags = tool.getToolCommandFlags(sourceLocation, outputLocation); + for (int i=0; i 0) + depCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + } + + commands[0] = depCmd; + return commands; + } + + public IPath[] getDependencyFiles() { + // The source file is project relative and the dependency file is top build directory relative + // Remove the source extension and add the dependency extension + IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); + // Remember that the source folder hierarchy and the build output folder hierarchy are the same + // but if this is a generated resource, then it may already be under the top build directory + if (!depFilePath.isAbsolute()) { + if (topBuildDirectory.isPrefixOf(depFilePath)) { + depFilePath = depFilePath.removeFirstSegments(1); + } + } + IPath[] paths = new IPath[1]; + paths[0] = depFilePath; + return paths; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() + */ + public IBuildObject getBuildContext() { + return buildContext; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() + */ + public IPath getSource() { + return source; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() + */ + public ITool getTool() { + return tool; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() + */ + public IPath getTopBuildDirectory() { + return topBuildDirectory; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java index bbfa734237f..4f109267cdc 100755 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java @@ -1,37 +1,37 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.makegen.gnu; - -import java.util.ArrayList; - -/** - * - * This class contains the desciption of a group of generated dependency files, - * e.g., .d files created by compilations - * - */ - -public class GnuDependencyGroupInfo { - - // Member Variables - String groupBuildVar; - boolean conditionallyInclude; - ArrayList groupFiles; - - // Constructor - public GnuDependencyGroupInfo(String groupName, boolean bConditionallyInclude) { - groupBuildVar = groupName; - conditionallyInclude = bConditionallyInclude; - // Note: not yet needed - groupFiles = null; - } - -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.makegen.gnu; + +import java.util.ArrayList; + +/** + * + * This class contains the desciption of a group of generated dependency files, + * e.g., .d files created by compilations + * + */ + +public class GnuDependencyGroupInfo { + + // Member Variables + String groupBuildVar; + boolean conditionallyInclude; + ArrayList groupFiles; + + // Constructor + public GnuDependencyGroupInfo(String groupName, boolean bConditionallyInclude) { + groupBuildVar = groupName; + conditionallyInclude = bConditionallyInclude; + // Note: not yet needed + groupFiles = null; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java index 5acd6e0fe78..b44679793ef 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java @@ -1,4302 +1,4302 @@ -/******************************************************************************* - * Copyright (c) 2003, 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 Rational Software - Initial API and implementation - * ARM Ltd. - Minor changes to echo commands - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen.gnu; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; // Note: We use LinkedHashMap instead of HashMap - // only to keep the generation of makefiles constant - // for our test set. Make itself doesn't care - // about the order. -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Vector; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.internal.core.model.Util; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCalculator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -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.resources.IResourceProxy; -import org.eclipse.core.resources.IResourceProxyVisitor; -import org.eclipse.core.resources.IResourceStatus; -import org.eclipse.core.resources.IWorkspaceRoot; -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.MultiStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; - -/** - * This is a specialized makefile generator that takes advantage of the - * extensions present in Gnu Make. - * - * @since 1.2 - */ - -public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { - - /** - * This class walks the delta supplied by the build system to determine - * what resources have been changed. The logic is very simple. If a - * buildable resource (non-header) has been added or removed, the directories - * in which they are located are "dirty" so the makefile fragments for them - * have to be regenerated. - *

- * The actual dependencies are recalculated as a result of the build step - * itself. We are relying on make to do the right things when confronted - * with a dependency on a moved header file. That said, make will treat - * the missing header file in a dependency rule as a target it has to build - * unless told otherwise. These dummy targets are added to the makefile - * to avoid a missing target error. - */ - public class ResourceDeltaVisitor implements IResourceDeltaVisitor { - private GnuMakefileGenerator generator; - private IManagedBuildInfo info; - - /** - * The constructor - */ - public ResourceDeltaVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) { - this.generator = generator; - this.info = info; - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) - */ - public boolean visit(IResourceDelta delta) throws CoreException { - // Should the visitor keep iterating in current directory - boolean keepLooking = false; - IResource resource = delta.getResource(); - - // What kind of resource change has occurred - if (resource.getType() == IResource.FILE) { - String ext = resource.getFileExtension(); - switch (delta.getKind()) { - case IResourceDelta.ADDED: - if (!generator.isGeneratedResource(resource)) { - // This is a source file so just add its container - if (info.buildsFileType(ext)) { - generator.appendModifiedSubdirectory(resource); - } - } - break; - case IResourceDelta.REMOVED: - // we get this notification if a resource is moved too - if (!generator.isGeneratedResource(resource)) { - // This is a source file so just add its container - if (info.buildsFileType(ext)) { - generator.appendDeletedFile(resource); - generator.appendModifiedSubdirectory(resource); - } - } - break; - default: - keepLooking = true; - break; - } - } - if (resource.getType() == IResource.FOLDER) { - // I only care about delete event - switch (delta.getKind()) { - case IResourceDelta.REMOVED: - if (!generator.isGeneratedResource(resource)) { - generator.appendDeletedSubdirectory((IContainer)resource); - } - default: - break; - } - } - if (resource.getType() == IResource.PROJECT) { - // If there is a zero-length delta, something the project depends on has changed so just call make - IResourceDelta[] children = delta.getAffectedChildren(); - if (children != null && children.length > 0) { - keepLooking = true; - } - } else { - // If the resource is part of the generated directory structure don't recurse - if (!generator.isGeneratedResource(resource)) { - keepLooking = true; - } - } - - return keepLooking; - } - } - - - - /** - * This class is used to recursively walk the project and determine which - * modules contribute buildable source files. - */ - protected class ResourceProxyVisitor implements IResourceProxyVisitor { - private GnuMakefileGenerator generator; - private IManagedBuildInfo info; - - /** - * Constructs a new resource proxy visitor to quickly visit project - * resources. - */ - public ResourceProxyVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) { - this.generator = generator; - this.info = info; - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy) - */ - public boolean visit(IResourceProxy proxy) throws CoreException { - // No point in proceeding, is there - if (generator == null) { - return false; - } - - // Is this a resource we should even consider - if (proxy.getType() == IResource.FILE) { - // If this resource has a Resource Configuration and is not excluded or - // if it has a file extension that one of the tools builds, add the sudirectory to the list - IResource resource = proxy.requestResource(); - boolean willBuild = false; - IResourceConfiguration resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); - if (resConfig != null) willBuild = true; - if (!willBuild) { - String ext = resource.getFileExtension(); - if (info.buildsFileType(ext) && - // If this file resource is a generated resource, then it is uninteresting - !generator.isGeneratedResource(resource)) { - willBuild = true; - } - } - if (willBuild) { - if ((resConfig == null) || (!(resConfig.isExcluded()))) { - generator.appendBuildSubdirectory(resource); - } - } - return false; - } - - // Recurse into subdirectories - return true; - } - - } - - // String constants for makefile contents and messages - private static final String COMMENT = "MakefileGenerator.comment"; //$NON-NLS-1$ - //private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$ - //private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$ - //private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$ - - //private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$ - private static final String HEADER = COMMENT + ".header"; //$NON-NLS-1$ - - protected static final String MESSAGE_FINISH_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.build"); //$NON-NLS-1$ - protected static final String MESSAGE_FINISH_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.file"); //$NON-NLS-1$ - protected static final String MESSAGE_START_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.build"); //$NON-NLS-1$ - protected static final String MESSAGE_START_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.file"); //$NON-NLS-1$ - protected static final String MESSAGE_START_DEPENDENCY = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.dependency"); //$NON-NLS-1$ - protected static final String MESSAGE_NO_TARGET_TOOL = ManagedMakeMessages.getResourceString("MakefileGenerator.message.no.target"); //$NON-NLS-1$ - //private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$ - private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$ - private static final String MOD_VARS = COMMENT + ".module.variables"; //$NON-NLS-1$ - private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$ - private static final String BUILD_TOP = COMMENT + ".build.toprules"; //$NON-NLS-1$ - private static final String ALL_TARGET = COMMENT + ".build.alltarget"; //$NON-NLS-1$ - private static final String MAINBUILD_TARGET = COMMENT + ".build.mainbuildtarget"; //$NON-NLS-1$ - private static final String BUILD_TARGETS = COMMENT + ".build.toptargets"; //$NON-NLS-1$ - private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$ - - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - - private static final String OBJS_MACRO = "OBJS"; //$NON-NLS-1$ - private static final String MACRO_ADDITION_ADDPREFIX_HEADER = "${addprefix "; //$NON-NLS-1$ - private static final String MACRO_ADDITION_ADDPREFIX_SUFFIX = "," + WHITESPACE + LINEBREAK; //$NON-NLS-1$ - private static final String MACRO_ADDITION_PREFIX_SUFFIX = "+=" + WHITESPACE + LINEBREAK; //$NON-NLS-1$ - private static final String PREBUILD = "pre-build"; //$NON-NLS-1$ - private static final String MAINBUILD = "main-build"; //$NON-NLS-1$ - private static final String POSTBUILD = "post-build"; //$NON-NLS-1$ - private static final String SECONDARY_OUTPUTS = "secondary-outputs"; //$NON-NLS-1$ - - // Enumerations - public static final int - PROJECT_RELATIVE = 1, - PROJECT_SUBDIR_RELATIVE = 2, - ABSOLUTE = 3; - - // Local variables needed by generator - private String buildTargetName; - private String buildTargetExt; - private IConfiguration config; - private ITool[] buildTools; - private boolean[] buildToolsUsed; - private ManagedBuildGnuToolInfo[] gnuToolInfos; - private Vector deletedFileList; - private Vector deletedDirList; - private IManagedBuildInfo info; - private Vector invalidDirList; - private Vector modifiedList; - private IProgressMonitor monitor; - private IProject project; - private IResource[] projectResources; - private Vector ruleList; - private Vector depLineList; // String's of additional dependency lines - private Vector depRuleList; // String's of rules for generating dependency files - private Vector subdirList; - private IPath topBuildDir; // Build directory - relative to the workspace - private Set outputExtensionsSet; - // Maps of macro names (String) to values (List) - private HashMap buildSrcVars = new HashMap(); // Map of source file build variable names - // to a List of source file Path's - private HashMap buildOutVars = new HashMap(); // Map of output file build variable names - // to a List of output file Path's - private HashMap buildDepVars = new HashMap(); // Map of dependency file build variable names - // to a List of GnuDependencyGroupInfo objects - private LinkedHashMap topBuildOutVars = new LinkedHashMap(); - // Dependency file variables - private Vector dependencyMakefiles; // IPath's - relative to the top build directory or absolute - - - public GnuMakefileGenerator() { - super(); - } - - - /************************************************************************* - * IManagedBuilderMakefileGenerator M E T H O D S - ************************************************************************/ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#initialize() - * - * @param project - * @param info - * @param monitor - */ - public void initialize(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) { - // Save the project so we can get path and member information - this.project = project; - try { - projectResources = project.members(); - } catch (CoreException e) { - projectResources = null; - } - // Save the monitor reference for reporting back to the user - this.monitor = monitor; - // Get the build info for the project - this.info = info; - // Get the name of the build target - buildTargetName = info.getBuildArtifactName(); - // Get its extension - buildTargetExt = info.getBuildArtifactExtension(); - - try{ - //try to resolve the build macros in the target extension - buildTargetExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - buildTargetExt, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - } catch (BuildMacroException e){ - } - - try{ - //try to resolve the build macros in the target name - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - buildTargetName, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - if((resolved = resolved.trim()).length() > 0) - buildTargetName = resolved; - } catch (BuildMacroException e){ - } - - - if (buildTargetExt == null) { - buildTargetExt = new String(); - } - // Cache the build tools - config = info.getDefaultConfiguration(); - buildTools = config.getFilteredTools(); - buildToolsUsed = new boolean[buildTools.length]; - for (int i=0; iStringBuffer containing all of the required targets to - * properly build the project. - * - * @param outputVarsAdditionsList list to add needed build output variables to - * @param rebuild - * @return StringBuffer - */ - private StringBuffer addTargets(List outputVarsAdditionsList, boolean rebuild) { - StringBuffer buffer = new StringBuffer(); - - IConfiguration config = info.getDefaultConfiguration(); - - // Assemble the information needed to generate the targets - String prebuildStep = info.getPrebuildStep(); - try{ - //try to resolve the build macros in the prebuild step - prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - prebuildStep, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_CONFIGURATION, - config); - } catch (BuildMacroException e){ - } - prebuildStep = prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters) - - String postbuildStep = info.getPostbuildStep(); - try{ - //try to resolve the build macros in the postbuild step - postbuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - postbuildStep, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_CONFIGURATION, - config); - - } catch (BuildMacroException e){ - } - postbuildStep = postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters) - String preannouncebuildStep = info.getPreannouncebuildStep(); - String postannouncebuildStep = info.getPostannouncebuildStep(); - String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$ - - ITool targetTool = config.getTargetTool(); - if (targetTool == null) { - targetTool = info.getToolFromOutputExtension(buildTargetExt); - } - - // Get all the projects the build target depends on - IProject[] refdProjects = null; - try { - refdProjects = project.getReferencedProjects(); - } catch (CoreException e) { - // There are 2 exceptions; the project does not exist or it is not open - // and neither conditions apply if we are building for it .... - } - - // If a prebuild step exists, redefine the all target to be - // all: {pre-build} main-build - // and then reset the "traditional" all target to main-build - // This will allow something meaningful to happen if the generated - // makefile is - // extracted and run standalone via "make all" - // - String defaultTarget = "all:"; //$NON-NLS-1$ - if (prebuildStep.length() > 0) { - - // Add the comment for the "All" target - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); - - buffer.append(defaultTarget + WHITESPACE); - buffer.append(PREBUILD + WHITESPACE); - - // Reset defaultTarget for now and for subsequent use, below - defaultTarget = MAINBUILD; - buffer.append(defaultTarget); - - // Update the defaultTarget, main-build, by adding a colon, which is - // needed below - defaultTarget = defaultTarget.concat(COLON); - buffer.append(NEWLINE + NEWLINE); - - // Add the comment for the "main-build" target - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MAINBUILD_TARGET) + NEWLINE); - } - else - // Add the comment for the "All" target - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); - - // Write out the all target first in case someone just runs make - // all: or mainbuild: - - String outputPrefix = EMPTY_STRING; - if (targetTool != null) { - outputPrefix = targetTool.getOutputPrefix(); - } - buffer.append(defaultTarget + WHITESPACE + outputPrefix + buildTargetName); - if (buildTargetExt.length() > 0) { - buffer.append(DOT + buildTargetExt); - } - - // Add the Secondary Outputs to the all target, if any - IOutputType[] secondaryOutputs = config.getToolChain().getSecondaryOutputs(); - if (secondaryOutputs.length > 0) { - buffer.append(WHITESPACE + SECONDARY_OUTPUTS); - } - - buffer.append(NEWLINE + NEWLINE); - - /* - * The build target may depend on other projects in the workspace. These - * are captured in the deps target: deps: ; - * $(MAKE) [clean all | all]> - */ - Vector managedProjectOutputs = new Vector(refdProjects.length); - if (refdProjects.length > 0) { - boolean addDeps = true; - if (refdProjects != null) { - for (int i = 0; i < refdProjects.length; i++) { - IProject dep = refdProjects[i]; - if (!dep.exists()) continue; - if (addDeps) { - buffer.append("dependents:" + NEWLINE); //$NON-NLS-1$ - addDeps = false; - } - String buildDir = dep.getLocation().toString(); - String depTargets = targets; - if (ManagedBuildManager.manages(dep)) { - // Add the current configuration to the makefile path - IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep); - buildDir += SEPARATOR + depInfo.getConfigurationName(); - - // Extract the build artifact to add to the dependency list - String depTarget = depInfo.getBuildArtifactName(); - String depExt = depInfo.getBuildArtifactExtension(); - - try{ - //try to resolve the build macros in the artifact extension - depExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - depExt, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - } catch (BuildMacroException e){ - } - - try{ - //try to resolve the build macros in the artifact name - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - depTarget, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - if((resolved = resolved.trim()).length() > 0) - depTarget = resolved; - } catch (BuildMacroException e){ - } - - String depPrefix = depInfo.getOutputPrefix(depExt); - if (depInfo.needsRebuild()) { - depTargets = "clean all"; //$NON-NLS-1$ - } - String dependency = buildDir + SEPARATOR + depPrefix + depTarget; - if (depExt.length() > 0) { - dependency += DOT + depExt; - } - dependency = escapeWhitespaces(dependency); - managedProjectOutputs.add(dependency); - } - buffer.append(TAB + "-cd" + WHITESPACE + escapeWhitespaces(buildDir) + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - buffer.append(NEWLINE); - } - - // Add the targets tool rules - buffer.append(addTargetsRules(targetTool, - outputVarsAdditionsList, managedProjectOutputs, (postbuildStep.length() > 0))); - - // Add the prebuild step target, if specified - if (prebuildStep.length() > 0) { - buffer.append(PREBUILD + COLON + NEWLINE); - if (preannouncebuildStep.length() > 0) { - buffer.append(TAB + DASH + AT + escapedEcho(preannouncebuildStep)); - } - buffer.append(TAB + DASH + prebuildStep + NEWLINE); - buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); - } - - // Add the postbuild step, if specified - if (postbuildStep.length() > 0) { - buffer.append(POSTBUILD + COLON + NEWLINE); - if (postannouncebuildStep.length() > 0) { - buffer.append(TAB + DASH + AT + escapedEcho(postannouncebuildStep)); - } - buffer.append(TAB + DASH + postbuildStep + NEWLINE); - buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); - } - - // Add the Secondary Outputs target, if needed - if (secondaryOutputs.length > 0) { - buffer.append(SECONDARY_OUTPUTS + COLON); - Vector outs2 = calculateSecondaryOutputs(secondaryOutputs); - for (int i=0; i 0) { - buffer.append(WHITESPACE + MAINBUILD + WHITESPACE + PREBUILD); - } - if (postbuildStep.length() > 0) { - buffer.append(WHITESPACE + POSTBUILD); - } - buffer.append(NEWLINE); - Iterator refIter = managedProjectOutputs.listIterator(); - while(refIter.hasNext()) { - buffer.append((String)refIter.next() + COLON + NEWLINE); - } - buffer.append(NEWLINE); - - // Include makefile.targets supplemental makefile - buffer.append("-include " + ROOT + SEPARATOR + MAKEFILE_TARGETS + NEWLINE); //$NON-NLS-1$ - - return buffer; - } - - /* (non-javadoc) - * Returns the targets rules. The targets make file (top makefile) contains: - * 1 the rule for the final target tool - * 2 the rules for all of the tools that use multipleOfType in their primary input type - * 3 the rules for all tools that use the output of #2 tools - * - * @param outputVarsAdditionsList list to add needed build output variables to - * @param managedProjectOutputs Other projects in the workspace that this project depends upon - * @return StringBuffer - */ - private StringBuffer addTargetsRules(ITool targetTool, - List outputVarsAdditionsList, Vector managedProjectOutputs, boolean postbuildStep) { - StringBuffer buffer = new StringBuffer(); - // Add the comment - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(BUILD_TOP) + NEWLINE); - - // Get the target tool and generate the rule - if (targetTool != null) { - if (addRuleForTool(targetTool, buffer, true, buildTargetName, buildTargetExt, - outputVarsAdditionsList, managedProjectOutputs, postbuildStep)) { - // Mark the target tool as processed - for (int i=0; i 0) { - buffer.append(DOT + buildTargetExt); - } - buffer.append(NEWLINE); - buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); - - return buffer; - } - - /* (non-Javadoc) - * Create the rule - * - * @param tool - * @param buffer Buffer to add makefile rules to - * @param bTargetTool True if this is the target tool - * @param targetName If this is the "targetTool", the target file name, else null - * @param targetName If this is the "targetTool", the target file extension, else null - * @param outputVarsAdditionsList list to add needed build output variables to - * @param managedProjectOutputs Other projects in the workspace that this project depends upon - * @param bPostBuildStep Emit post-build step invocation - */ - protected boolean addRuleForTool(ITool tool, StringBuffer buffer, boolean bTargetTool, String targetName, String targetExt, - List outputVarsAdditionsList, Vector managedProjectOutputs, boolean bEmitPostBuildStepCall) { - - // Get the tool's inputs and outputs - Vector inputs = new Vector(); - Vector dependencies = new Vector(); - Vector outputs = new Vector(); - Vector enumeratedPrimaryOutputs = new Vector(); - Vector enumeratedSecondaryOutputs = new Vector(); - Vector outputVariables = new Vector(); - Vector additionalTargets = new Vector(); - String outputPrefix = EMPTY_STRING; - - if (!getToolInputsOutputs(tool, inputs, dependencies, outputs, - enumeratedPrimaryOutputs, enumeratedSecondaryOutputs, - outputVariables, additionalTargets, bTargetTool, managedProjectOutputs)) { - return false; - } - - // If we have no primary output, make all of the secondary outputs the primary output - if (enumeratedPrimaryOutputs.size() == 0) { - enumeratedPrimaryOutputs = enumeratedSecondaryOutputs; - enumeratedSecondaryOutputs.clear(); - } - - // Add the output variables for this tool to our list - outputVarsAdditionsList.addAll(outputVariables); - - // Create the build rule - String buildRule = EMPTY_STRING; - String outflag = tool.getOutputFlag(); - - String primaryOutputs = EMPTY_STRING; - boolean first = true; - for (int i=0; i 0) - command = resolvedCommand; - - } catch (BuildMacroException e){ - } - String[] cmdInputs = (String[])inputs.toArray(new String[inputs.size()]); - IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - IManagedCommandLineInfo cmdLInfo = gen.generateCommandLineInfo( tool, command, - flags, outflag, outputPrefix, primaryOutputs, cmdInputs, tool.getCommandLinePattern() ); - - // The command to build - String buildCmd = null; - if( cmdLInfo == null ) { - String toolFlags; - try { - toolFlags = tool.getToolCommandFlagsString(null,null); - } catch( BuildException ex ) { - // TODO report error - toolFlags = EMPTY_STRING; - } - buildCmd = command + WHITESPACE + toolFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + primaryOutputs + WHITESPACE + IN_MACRO; - } - else buildCmd = cmdLInfo.getCommandLine(); - - // resolve any remaining macros in the command after it has been - // generated - try { - String resolvedCommand = ManagedBuildManager - .getBuildMacroProvider().resolveValueToMakefileFormat( - buildCmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(null, null, null, tool)); - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - - buffer.append(TAB + AT + escapedEcho(buildCmd)); - buffer.append(TAB + AT + buildCmd); - - // TODO - // NOTE WELL: Dependency file generation is not handled for this type of Tool - - // Echo finished message - buffer.append(NEWLINE); - buffer.append(TAB + AT + escapedEcho((bTargetTool ? MESSAGE_FINISH_BUILD : MESSAGE_FINISH_FILE) + WHITESPACE + OUT_MACRO)); - buffer.append(TAB + AT + ECHO_BLANK_LINE); - - // If there is a post build step, then add a recursive invocation of MAKE to invoke it after the main build - // Note that $(MAKE) will instantiate in the recusive invocation to the make command that was used to invoke - // the makefile originally - if (bEmitPostBuildStepCall) { - buffer.append(TAB + MAKE + WHITESPACE + NO_PRINT_DIR + WHITESPACE + POSTBUILD + NEWLINE + NEWLINE); - } - else { - // Just emit a blank line - buffer.append(NEWLINE); - } - } - - // If we have secondary outputs, output dependency rules without commands - if (enumeratedSecondaryOutputs.size() > 0 || additionalTargets.size() > 0) { - String primaryOutput = (String)enumeratedPrimaryOutputs.get(0); - Vector addlOutputs = new Vector(); - addlOutputs.addAll(enumeratedSecondaryOutputs); - addlOutputs.addAll(additionalTargets); - for (int i=0; i 0) { - for (int j=0; j 0) { - for (int j=0; jStringBuffer containing the comment(s) - * for a fragment makefile (subdir.mk). - */ - protected StringBuffer addFragmentMakefileHeader() { - return addDefaultHeader(); - } - - /* (non-javadoc) - * Returns a StringBuffer containing makefile text for all of the sources - * contributed by a container (project directory/subdirectory) to the fragement makefile - * - * @param module project resource directory/subdirectory - * @return StringBuffer generated text for the fragement makefile - */ - protected StringBuffer addSources(IContainer module) throws CoreException { - // Calculate the new directory relative to the build output - IPath moduleRelativePath = module.getProjectRelativePath(); - String relativePath = moduleRelativePath.toString(); - relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$ - - // For build macros in the configuration, create a map which will map them - // to a string which holds its list of sources. - LinkedHashMap buildVarToRuleStringMap = new LinkedHashMap(); - - // Add statements that add the source files in this folder, - // and generated source files, and generated dependency files - // to the build macros - Iterator iterator = buildSrcVars.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, null, false); - } - iterator = buildOutVars.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, "./" + relativePath, false); //$NON-NLS-1$ - } - - // String buffers - StringBuffer buffer = new StringBuffer(); // Return buffer - StringBuffer ruleBuffer = new StringBuffer(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_RULES) + NEWLINE); - - // Visit the resources in this folder and add each one to a sources macro, and generate a build rule, if appropriate - IResource[] resources = module.members(); - - IResourceConfiguration resConfig; - IFolder folder = project.getFolder(info.getConfigurationName()); - - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - if (resource.getType() == IResource.FILE) { - // Check whether this resource is excluded from build - resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); - if( (resConfig != null) && (resConfig.isExcluded()) ) - continue; - addFragmentMakefileEntriesForSource(buildVarToRuleStringMap, ruleBuffer, - folder, relativePath, resource, resource.getLocation(), resConfig, null, false); - } - } - - // Write out the macro addition entries to the buffer - buffer.append(writeAdditionMacros(buildVarToRuleStringMap)); - return buffer.append(ruleBuffer + NEWLINE); - } - - /* (non-Javadoc - * Adds the entries for a particular source file to the fragment makefile - * - * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable - * @param ruleBuffer buffer to add generated nmakefile text to - * @param folder the top level build output directory - * @param relativePath build output directory relative path of the current output directory - * @param resource the source file for this invocation of the tool - this may be null for a generated output - * @param sourceLocation the full path of the source - * @param resConfig the IResourceConfiguration associated with this file or null - * @param varName the build variable to add this invocation's outputs to - * if null, use the file extension to find the name - * @param generatedSource if true, this file was generated by another tool in the tool-chain - */ - protected void addFragmentMakefileEntriesForSource (LinkedHashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, - IFolder folder, String relativePath, IResource resource, IPath sourceLocation, IResourceConfiguration resConfig, - String varName, boolean generatedSource) { - - // Determine which tool, if any, builds files with this extension - String ext = sourceLocation.getFileExtension(); - ITool tool = null; - - // Use the tool from the resource configuration if there is one - if (resConfig != null) { - ITool[] tools = resConfig.getToolsToInvoke(); - if (tools != null && tools.length > 0) { - tool = tools[0]; - } - } - for (int j=0; j 0) { - for (int k=0; k 0) { - IPath firstOutput = (IPath)generatedOutputs.get(0); - String firstExt = firstOutput.getFileExtension(); - for (int j=0; j 0) { - buildVariable = bV; - break; - } - } - } - } - } else { - buildVariable = outType.getBuildVariable(); - } - } else { - // For support of pre-CDT 3.0 integrations. - buildVariable = OBJS_MACRO; - } - - for (int k=0; k 0) { - if (isSecondaryOutputVar(secondaryOutputs, varName)) { - addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); - } - } - } - } - } - - /* (non-Javadoc) - * Adds the source file to the appropriate build variable - * - * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable - * @param ext the file extension of the file - * @param varName the build variable to add this invocation's outputs to - * if null, use the file extension to find the name - * @param relativePath build output directory relative path of the current output directory - * @param sourceLocation the full path of the source - * @param generatedSource if true, this file was generated by another tool in the tool-chain - */ - protected void addToBuildVar (LinkedHashMap buildVarToRuleStringMap, String ext, - String varName, String relativePath, IPath sourceLocation, boolean generatedSource) { - List varList = null; - if (varName == null) { - // Get the proper source build variable based upon the extension - varName = getSourceMacroName(ext).toString(); - varList = (List)buildSrcVars.get(varName); - } else { - varList = (List)buildOutVars.get(varName); - } - // Add the resource to the list of all resources associated with a variable. - // Do not allow duplicates - there is no reason to and it can be 'bad' - - // e.g., having the same object in the OBJS list can cause duplicate symbol errors from the linker - if ((varList != null) && !(varList.contains(sourceLocation))) { - // Since we don't know how these files will be used, we store them using a "location" - // path rather than a relative path - varList.add(sourceLocation); - if (!buildVarToRuleStringMap.containsKey(varName)) { - // TODO - is this an error? - } else { - // Add the resource name to the makefile line that adds resources to the build variable - addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); - } - } - } - - /* (non-Javadoc) - * Create a rule for this source file. We create a pattern rule if possible. - * - * This is an example of a pattern rule: - * - * /%.: ..//%. - * @echo Building file: $< - * @echo Invoking tool xxx - * @echo $@ $< - * @ $@ $< && \ - * echo -n $(@:%.o=%.d) ' /' >> $(@:%.o=%.d) && \ - * -P -MM -MG $< >> $(@:%.o=%.d) - * @echo Finished building: $< - * @echo ' ' - * - * Note that the macros all come from the build model and are - * resolved to a real command before writing to the module - * makefile, so a real command might look something like: - * source1/%.o: ../source1/%.cpp - * @echo Building file: $< - * @echo Invoking tool xxx - * @echo g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< - * @ g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< && \ - * echo -n $(@:%.o=%.d) ' source1/' >> $(@:%.o=%.d) && \ - * g++ -P -MM -MG -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers $< >> $(@:%.o=%.d) - * @echo Finished building: $< - * @echo ' ' - * - * @param relativePath top build output directory relative path of the current output directory - * @param buffer buffer to populate with the build rule - * @param resource the source file for this invocation of the tool - * @param sourceLocation the full path of the source - * @param resConfig the IResourceConfiguration associated with this file or null - * @param generatedSource true if the resource is a generated output - * @param generatedDepFile build directory relative paths of the dependency files generated by the rule - * @param enumeratedOutputs vector of the filenames that are the output of this rule - */ - protected void addRuleForSource(String relativePath, StringBuffer buffer, IResource resource, - IPath sourceLocation, IResourceConfiguration resConfig, - boolean generatedSource, Vector generatedDepFiles, Vector enumeratedOutputs) { - - String fileName = sourceLocation.removeFileExtension().lastSegment(); - String inputExtension = sourceLocation.getFileExtension(); - String outputExtension = info.getOutputExtension(inputExtension); - - ITool tool = null; - if( resConfig != null) { - ITool[] tools = resConfig.getToolsToInvoke(); - if (tools != null && tools.length > 0) { - tool = tools[0]; - } - } - if (tool == null) { - tool = info.getToolFromInputExtension(inputExtension); - } - - // Get the dependency generator information for this tool and file extension - IManagedDependencyGenerator oldDepGen = null; // This interface is deprecated but still supported - IManagedDependencyGenerator2 depGen = null; // This is the recommended interface - IManagedDependencyInfo depInfo = null; - IManagedDependencyCommands depCommands = null; - IManagedDependencyPreBuild depPreBuild = null; - IPath[] depFiles = null; - boolean doDepGen = false; - { - IManagedDependencyGeneratorType t = tool.getDependencyGeneratorForExtension(inputExtension); - if (t != null) { - int calcType = t.getCalculatorType(); - if (calcType <= IManagedDependencyGeneratorType.TYPE_OLD_TYPE_LIMIT) { - oldDepGen = (IManagedDependencyGenerator)t; - doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND); - if (doDepGen) { - IPath depFile = Path.fromOSString(relativePath + fileName + DOT + DEP_EXT); - getDependencyMakefiles().add(depFile); - generatedDepFiles.add(depFile); - } - } else { - depGen = (IManagedDependencyGenerator2)t; - doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS); - IBuildObject buildContext = (resConfig != null) ? (IBuildObject)resConfig : (IBuildObject)config; - depInfo = depGen.getDependencySourceInfo(resource.getProjectRelativePath(), buildContext, tool, getBuildWorkingDir()); - if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) { - depCommands = (IManagedDependencyCommands)depInfo; - depFiles = depCommands.getDependencyFiles(); - } else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { - depPreBuild = (IManagedDependencyPreBuild)depInfo; - depFiles = depPreBuild.getDependencyFiles(); - } - if (depFiles != null) { - for (int i=0; i 0) - optDotExt = DOT + outputExtension; - - Vector ruleOutputs = new Vector(); - Vector enumeratedPrimaryOutputs = new Vector(); // IPaths relative to the top build directory - Vector enumeratedSecondaryOutputs = new Vector(); // IPaths relative to the top build directory - calculateOutputsForSource(tool, relativePath, resource, sourceLocation, ruleOutputs, enumeratedPrimaryOutputs, enumeratedSecondaryOutputs); - enumeratedOutputs.addAll(enumeratedPrimaryOutputs); - enumeratedOutputs.addAll(enumeratedSecondaryOutputs); - String primaryOutputName = null; - if (enumeratedPrimaryOutputs.size() > 0) { - primaryOutputName = escapeWhitespaces(((IPath)enumeratedPrimaryOutputs.get(0)).toString()); - } else { - primaryOutputName = escapeWhitespaces(relativePath + fileName + optDotExt); - } - String otherPrimaryOutputs = EMPTY_STRING; - for (int i=1; i 0 - || MacroResolver.getReferencedExplitFileMacros(tool - .getToolCommand(), IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, outputLocation, - null, tool)).length > 0; - - // Get and resolve the command - String cmd = tool.getToolCommand(); - - try { - String resolvedCommand = null; - if (!needExplicitRuleForFile) { - resolvedCommand = ManagedBuildManager.getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } else { - // if we need an explicit rule then don't use any builder - // variables, resolve everything - // to explicit strings - resolvedCommand = ManagedBuildManager.getBuildMacroProvider() - .resolveValue( - cmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } - - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - String defaultOutputName = EMPTY_STRING; - String primaryDependencyName = EMPTY_STRING; - String patternPrimaryDependencyName = EMPTY_STRING; - String home = (generatedSource)? DOT : ROOT; - String resourcePath = null; - boolean patternRule = true; - boolean isItLinked = false; - //if (resource.isLinked()) { NOTE: we don't use this since children of linked resources return false - if(!sourceLocation.toString().startsWith(projectLocation)) { - // it IS linked, so use the actual location - isItLinked = true; - resourcePath = sourceLocation.toString(); - // Need a hardcoded rule, not a pattern rule, as a linked file - // can reside in any path - defaultOutputName = escapeWhitespaces(relativePath + fileName + optDotExt); - primaryDependencyName = escapeWhitespaces(resourcePath); - patternRule = false; - } else { - // Use the relative path (not really needed to store per se but in the future someone may want this) - resourcePath = relativePath; - // The rule and command to add to the makefile - if( resConfig != null || needExplicitRuleForFile) { - // Need a hardcoded rule, not a pattern rule - defaultOutputName = escapeWhitespaces(resourcePath + fileName + optDotExt); - patternRule = false; - } else { - defaultOutputName = relativePath + WILDCARD + optDotExt; - } - primaryDependencyName = escapeWhitespaces(home + SEPARATOR + resourcePath + fileName + DOT + inputExtension); - patternPrimaryDependencyName = home + SEPARATOR + resourcePath + WILDCARD + DOT + inputExtension; - } // end fix for PR 70491 - - // If the tool specifies a dependency calculator of TYPE_BUILD_COMMANDS, ask whether - // the dependency commands are "generic" (i.e., we can use a pattern rule) - boolean needExplicitDependencyCommands = false; - if (depCommands != null) { - needExplicitDependencyCommands = !depCommands.areCommandsGeneric(); - } - - // If we still think that we are using a pattern rule, check a few more things - if (patternRule) { - patternRule = false; - // Make sure that at least one of the rule outputs contains a %. - for (int i=0; i= 0) { //$NON-NLS-1$ - patternRule = true; - break; - } - } - if (patternRule) { - patternRule = !needExplicitDependencyCommands; - } - } - - // Begin building the rule for this source file - String buildRule = EMPTY_STRING; - - if (patternRule) { - if (ruleOutputs.size() == 0) { - buildRule += defaultOutputName; - } else { - boolean first = true; - for (int i=0; i= 0) { //$NON-NLS-1$ - if (first) { - first = false; - } else { - buildRule += WHITESPACE; - } - buildRule += ruleOutput; - } - } - } - } else { - buildRule += primaryOutputName; - } - - String buildRuleDependencies = primaryDependencyName; - String patternBuildRuleDependencies = patternPrimaryDependencyName; - - // Other additional inputs - // Get any additional dependencies specified for the tool in other InputType elements and AdditionalInput elements - IPath[] addlDepPaths = tool.getAdditionalDependencies(); - for (int i=0; i 0) { - for (int i=0; i 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - buffer.append(TAB + AT + escapedEcho(buildCmd)); - buffer.append(TAB + AT + buildCmd); - - // Determine if there are any dependencies to calculate - if (doDepGen) { - // Get the dependency rule out of the generator - String[] depCmds = null; - if (oldDepGen != null) { - depCmds = new String[1]; - depCmds[0] = oldDepGen.getDependencyCommand(resource, info); - } else { - if (depCommands != null) { - depCmds = depCommands.getPostToolDependencyCommands(); - } - } - - if (depCmds != null) { - for (int i=0; i 0) { - calculatedDependencies = new String(); - for (int i=0; i 1) { - // Starting with 1 is intentional in order to skip the primary output - for (int i=1; i 0) depLine += WHITESPACE; - if (patternRule) { - optDotExt = EMPTY_STRING; - String depExt = depFiles[i].getFileExtension(); - if (depExt != null && depExt.length() > 0) - optDotExt = DOT + depExt; - depLine += escapeWhitespaces(relativePath + WILDCARD + optDotExt); - } else { - depLine += escapeWhitespaces((depFiles[i]).toString()); - } - } - depLine += COLON + WHITESPACE + (patternRule ? patternBuildRuleDependencies : buildRuleDependencies); - if (!getDepRuleList().contains(depLine)) { - getDepRuleList().add(depLine); - addedDepLines = true; - buffer.append(depLine + NEWLINE); - buffer.append(TAB + AT + escapedEcho(MESSAGE_START_DEPENDENCY + WHITESPACE + OUT_MACRO)); - for (int i=0; i 0) { - int flagsLen = flags.length; - String[] flagsCopy = new String[flags.length + depOptions.length]; - for (int i=0; i 0) { - allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - // Use file extensions - String[] typeExts = type.getSourceExtensions(tool); - for (int j=0; j 0) b = true; - if (toolParent instanceof IToolChain) { - IConfiguration config = ((IToolChain)toolParent).getParent(); - if (config != null) { - ManagedBuildManager.setOption(config, tool, assignToOption, b); - } - } else if (toolParent instanceof IResourceConfiguration) { - ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, b); - } - } else if (optType == IOption.ENUMERATED) { - if (allRes.size() > 0) { - String s = allRes.get(0).toString(); - if (toolParent instanceof IToolChain) { - IConfiguration config = ((IToolChain)toolParent).getParent(); - if (config != null) { - ManagedBuildManager.setOption(config, tool, assignToOption, s); - } - } else if (toolParent instanceof IResourceConfiguration) { - ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, s); - } - } - } - allRes.clear(); - } - } catch( BuildException ex ) { - } - } - } - } - return (IPath[])allRes.toArray(new IPath[allRes.size()]); - } - - - /* (non-Javadoc) - * Returns the output IPaths for this invocation of the tool with the specified source file - /* - * The priorities for determining the names of the outputs of a tool are: - * 1. If the tool is the build target and primary output, use artifact name & extension - - * This case does not apply here... - * 2. If an option is specified, use the value of the option - * 3. If a nameProvider is specified, call it - * 4. If outputNames is specified, use it - * 5. Use the name pattern to generate a transformation macro - * so that the source names can be transformed into the target names - * using the built-in string substitution functions of make. - * - * @param tool - * @param relativePath build output directory relative path of the current output directory - * @param resource - * @param ruleOutputs Vector of rule IPaths that are relative to the build directory - * @param enumeratedPrimaryOutputs Vector of IPaths of primary outputs - * that are relative to the build directory - * @param enumeratedSecondaryOutputs Vector of IPaths of secondary outputs - * that are relative to the build directory - */ - protected void calculateOutputsForSource(ITool tool, String relativePath, IResource resource, - IPath sourceLocation, Vector ruleOutputs, Vector enumeratedPrimaryOutputs, Vector enumeratedSecondaryOutputs) { - String inExt = sourceLocation.getFileExtension(); - String outExt = tool.getOutputExtension(inExt); - - IOutputType[] outTypes = tool.getOutputTypes(); - if (outTypes != null && outTypes.length > 0) { - for (int i=0; i 0) { - for (int j=0; j 0) - outputName = resolved; - } catch (BuildMacroException e){ - } - - IPath outPath = Path.fromOSString(outputName); - // If only a file name is specified, add the relative path of this output directory - if (outPath.segmentCount() == 1) { - outPath = Path.fromOSString(relativePath + (String)outputList.get(j)); - } - if (primaryOutput) { - ruleOutputs.add(j, outPath); - enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); - } else { - ruleOutputs.add(outPath); - enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); - } - } - } catch( BuildException ex ) {} - } else - // 3. If a nameProvider is specified, call it - if (nameProvider != null) { - IPath[] inPaths = new IPath[1]; - inPaths[0] = sourceLocation; - IPath[] outPaths = nameProvider.getOutputNames(tool, inPaths); - for (int j=0; j 0) - outputName = resolved; - } catch (BuildMacroException e) { - } - - // If only a file name is specified, add the relative path of this output directory - if (outPath.segmentCount() == 1) { - outPath = Path.fromOSString(relativePath + outPath.toString()); - } - if (primaryOutput) { - ruleOutputs.add(j, outPath); - enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); - } else { - ruleOutputs.add(outPath); - enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); - } - } - } else - // 4. If outputNames is specified, use it - if (outputNames != null) { - for (int j = 0; j < outputNames.length; j++) { - String outputName = outputNames[j]; - try{ - //try to resolve the build macros in the output names - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - outputName, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, null, option, tool)); - if((resolved = resolved.trim()).length() > 0) - outputName = resolved; - } catch (BuildMacroException e){ - } - - IPath outPath = Path.fromOSString(outputName); - // If only a file name is specified, add the relative path of this output directory - if (outPath.segmentCount() == 1) { - outPath = Path.fromOSString(relativePath + outPath.toString()); - } - if (primaryOutput) { - ruleOutputs.add(j, outPath); - enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); - } else { - ruleOutputs.add(outPath); - enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); - } - } - } else { - // 5. Use the name pattern to generate a transformation macro - // so that the source names can be transformed into the target names - // using the built-in string substitution functions of make. - if (multOfType) { - // This case is not handled - a nameProvider or outputNames must be specified - // TODO - report error - } else { - String namePattern = type.getNamePattern(); - IPath namePatternPath = null; - if (namePattern == null || namePattern.length() == 0) { - namePattern = relativePath + outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; - if (outExt != null && outExt.length() > 0) { - namePattern += DOT + outExt; - } - namePatternPath = Path.fromOSString(namePattern); - } - else { - if (outputPrefix.length() > 0) { - namePattern = outputPrefix + namePattern; - } - namePatternPath = Path.fromOSString(namePattern); - // If only a file name is specified, add the relative path of this output directory - if (namePatternPath.segmentCount() == 1) { - namePatternPath = Path.fromOSString(relativePath + namePatternPath.toString()); - } - } - - if (primaryOutput) { - ruleOutputs.add(0, namePatternPath); - enumeratedPrimaryOutputs.add(0, resolvePercent(namePatternPath, sourceLocation)); - } else { - ruleOutputs.add(namePatternPath); - enumeratedSecondaryOutputs.add(resolvePercent(namePatternPath, sourceLocation)); - } - } - } - } - } else { - // For support of pre-CDT 3.0 integrations. - // NOTE WELL: This only supports the case of a single "target tool" - // that consumes exactly all of the object files, $OBJS, produced - // by other tools in the build and produces a single output. - // In this case, the output file name is the input file name with - // the output extension. - - //if (!ignorePrimary) { - String outPrefix = tool.getOutputPrefix(); - IPath outPath = Path.fromOSString(relativePath + outPrefix + WILDCARD); - outPath = outPath.addFileExtension(outExt); - ruleOutputs.add(0, outPath); - enumeratedPrimaryOutputs.add(0, resolvePercent(outPath, sourceLocation)); - //} - } - } - - /* (non-Javadoc) - * If the path contains a %, returns the path resolved using the resource name - * - */ - protected IPath resolvePercent(IPath outPath, IPath sourceLocation) { - // Get the input file name - String fileName = sourceLocation.removeFileExtension().lastSegment(); - // Replace the % with the file name - String outName = outPath.toOSString().replaceAll("%", fileName); //$NON-NLS-1$ - return Path.fromOSString(outName); - } - - /* (non-Javadoc) - * Returns the dependency IPaths for this invocation of the tool with the specified source file - * - * @param depGen the dependency calculator - * @param tool tool used to build the source file - * @param relativePath build output directory relative path of the current output directory - * @param resource source file to scan for dependencies - * @return Vector of IPaths that are relative to the build directory - */ - protected IPath[] oldCalculateDependenciesForSource(IManagedDependencyGenerator depGen, ITool tool, String relativePath, IResource resource) { - Vector deps = new Vector(); - int type = depGen.getCalculatorType(); - - switch (type) { - - case IManagedDependencyGeneratorType.TYPE_INDEXER: - case IManagedDependencyGeneratorType.TYPE_EXTERNAL: - IResource[] res = depGen.findDependencies(resource, project); - if (res != null) { - for (int i=0; iIPaths relative to the build directory - * - * @param depCalculator the dependency calculator - * @return IPath[] that are relative to the build directory - */ - protected IPath[] calculateDependenciesForSource(IManagedDependencyCalculator depCalculator) { - IPath[] addlDeps = depCalculator.getDependencies(); - if (addlDeps != null) { - for (int i=0; iSet containing all of the output extensions - */ - public Set getOutputExtensions() { - if (outputExtensionsSet == null) { - // The set of output extensions which will be produced by this tool. - // It is presumed that this set is not very large (likely < 10) so - // a HashSet should provide good performance. - outputExtensionsSet = new HashSet(); - - // For each tool for the target, lookup the kinds of sources it outputs - // and add that to our list of output extensions. - for (int i=0; itrue if the dependency file is modified - */ - static public boolean populateDummyTargets(IConfiguration cfg, IFile makefile, boolean force) throws CoreException, IOException { - if (makefile == null || !makefile.exists()) return false; - - // Get the contents of the dependency file - InputStream contentStream = makefile.getContents(false); - Reader in = new InputStreamReader(contentStream); - StringBuffer inBuffer = null; - int chunkSize = contentStream.available(); - inBuffer = new StringBuffer(chunkSize); - char[] readBuffer = new char[chunkSize]; - int n = in.read(readBuffer); - while (n > 0) { - inBuffer.append(readBuffer); - n = in.read(readBuffer); - } - contentStream.close(); - - // The rest of this operation is equally expensive, so - // if we are doing an incremental build, only update the - // files that do not have a comment - if (inBuffer == null) return false; - String inBufferString = inBuffer.toString(); - if (!force && inBufferString.startsWith(COMMENT_SYMBOL)) { - return false; - } - - // Try to determine if this file already has dummy targets defined. - // If so, we will only add the comment. - String[] bufferLines = inBufferString.split("[\\r\\n]"); //$NON-NLS-1$ - for (int i=0; i 1) { //$NON-NLS-1$ - // This is escaped so keep adding to the token until we find the end - while (tokenIter.hasNext()) { - String nextToken = (String)tokenIter.next(); - token += WHITESPACE + nextToken; - if (!nextToken.endsWith("\\")) { //$NON-NLS-1$ - break; - } - } - } - deps.add(token); - } - deps.trimToSize(); - - // Now find the header file dependencies and make dummy targets for them - boolean save = false; - StringBuffer outBuffer = null; - - // If we are doing an incremental build, only update the files that do not have a comment - String firstToken; - try { - firstToken = (String) deps.get(0); - } catch (ArrayIndexOutOfBoundsException e) { - // This makes no sense so bail - return false; - } - - // Put the generated comments in the output buffer - if (!firstToken.startsWith(COMMENT_SYMBOL)) { - outBuffer = addDefaultHeader(); - } else { - outBuffer = new StringBuffer(); - } - - // Some echo implementations misbehave and put the -n and newline in the output - if (firstToken.startsWith("-n")) { //$NON-NLS-1$ - - // Now let's parse: - // Win32 outputs -n '/.d /' - // POSIX outputs -n /.d / - // Get the dep file name - String secondToken; - try { - secondToken = (String) deps.get(1); - } catch (ArrayIndexOutOfBoundsException e) { - secondToken = new String(); - } - if (secondToken.startsWith("'")) { //$NON-NLS-1$ - // This is the Win32 implementation of echo (MinGW without MSYS) - outBuffer.append(secondToken.substring(1) + WHITESPACE); - } else { - outBuffer.append(secondToken + WHITESPACE); - } - - // The relative path to the build goal comes next - String thirdToken; - try { - thirdToken = (String) deps.get(2); - } catch (ArrayIndexOutOfBoundsException e) { - thirdToken = new String(); - } - int lastIndex = thirdToken.lastIndexOf("'"); //$NON-NLS-1$ - if (lastIndex != -1) { - if (lastIndex == 0) { - outBuffer.append(WHITESPACE); - } else { - outBuffer.append(thirdToken.substring(0, lastIndex - 1)); - } - } else { - outBuffer.append(thirdToken); - } - - // Followed by the target output by the compiler plus ':' - // If we see any empty tokens here, assume they are the result of - // a line feed output by "echo" and skip them - String fourthToken; - int nToken = 3; - try { - do { - fourthToken = (String) deps.get(nToken++); - } while (fourthToken.length() == 0); - - } catch (ArrayIndexOutOfBoundsException e) { - fourthToken = new String(); - } - outBuffer.append(fourthToken + WHITESPACE); - - // Followed by the actual dependencies - try { - Iterator iter = deps.listIterator(nToken); - while (iter.hasNext()) { - String nextElement = (String)iter.next(); - if (nextElement.endsWith("\\")) { //$NON-NLS-1$ - outBuffer.append(nextElement + NEWLINE + WHITESPACE); - } else { - outBuffer.append(nextElement + WHITESPACE); - } - } - } catch (IndexOutOfBoundsException e) { - } - - } else { - outBuffer.append(inBuffer); - } - - outBuffer.append(NEWLINE); - save = true; - - // Dummy targets to add to the makefile - Iterator dummyIter = deps.iterator(); - while (dummyIter.hasNext()) { - String dummy = (String)dummyIter.next(); - IPath dep = new Path(dummy); - String extension = dep.getFileExtension(); - if (cfg.isHeaderFile(extension)) { - /* - * The formatting here is - * : - */ - outBuffer.append(dummy + COLON + NEWLINE + NEWLINE); - } - } - - // Write them out to the makefile - if (save) { - Util.save(outBuffer, makefile); - return true; - } - return false; - } - - /** - * prepend all instanced of '\' or '"' with a backslash - * - * @param string - * @return - */ - static public String escapedEcho(String string) { - String escapedString = string.replaceAll("(['\"\\\\])", "\\\\$1"); - return ECHO + WHITESPACE + escapedString + NEWLINE; - } - - static public String ECHO_BLANK_LINE = ECHO + WHITESPACE + SINGLE_QUOTE + WHITESPACE + SINGLE_QUOTE + NEWLINE; - - /* (non-Javadoc) - * Outputs a comment formatted as follows: - * ##### ....... ##### - * # - * ##### ....... ##### - */ - static protected StringBuffer addDefaultHeader() { - StringBuffer buffer = new StringBuffer(); - outputCommentLine(buffer); - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(HEADER) + NEWLINE); - outputCommentLine(buffer); - buffer.append(NEWLINE); - return buffer; - } - - /* (non-Javadoc) - * Put COLS_PER_LINE comment charaters in the argument. - */ - static protected void outputCommentLine(StringBuffer buffer) { - for (int i = 0; i < COLS_PER_LINE; i++) { - buffer.append(COMMENT_SYMBOL); - } - buffer.append(NEWLINE); - } - - static public boolean containsSpecialCharacters(String path) - { - return path.matches(".*(\\s|[\\{\\}\\(\\)\\$\\@%=;]).*"); - } - - /* (non-Javadoc) - * Answers the argument with all whitespaces replaced with an escape sequence. - * - * @param path - */ - static public String escapeWhitespaces(String path) { - // Escape the spaces in the path/filename if it has any - String[] segments = path.split("\\s"); //$NON-NLS-1$ - if (segments.length > 1) { - StringBuffer escapedPath = new StringBuffer(); - for (int index = 0; index < segments.length; ++index) { - escapedPath.append(segments[index]); - if (index + 1 < segments.length) { - escapedPath.append("\\ "); //$NON-NLS-1$ - } - } - return escapedPath.toString().trim(); - } else { - return path; - } - } - - /* (non-Javadoc) - * Adds a macro addition prefix to a map of macro names to entries. - * Entry prefixes look like: - * C_SRCS += \ - * ${addprefix $(ROOT)/, \ - */ - // TODO fix comment - protected void addMacroAdditionPrefix(LinkedHashMap map, String macroName, String relativePath, boolean addPrefix) { - // there is no entry in the map, so create a buffer for this macro - StringBuffer tempBuffer = new StringBuffer(); - tempBuffer.append(macroName + WHITESPACE + MACRO_ADDITION_PREFIX_SUFFIX); - if (addPrefix) { - tempBuffer.append(MACRO_ADDITION_ADDPREFIX_HEADER + relativePath + MACRO_ADDITION_ADDPREFIX_SUFFIX); - } - - // have to store the buffer in String form as StringBuffer is not a sublcass of Object - map.put(macroName, tempBuffer.toString()); - } - - /* (non-Javadoc) - * Adds a file to an entry in a map of macro names to entries. - * File additions look like: - * example.c, \ - */ - protected void addMacroAdditionFile(HashMap map, String macroName, String filename) { - StringBuffer buffer = new StringBuffer(); - buffer.append(map.get(macroName)); - - // escape whitespace in the filename - filename = escapeWhitespaces(filename); - - buffer.append(filename + WHITESPACE + LINEBREAK); - // re-insert string in the map - map.put(macroName, buffer.toString()); - } - - /* (non-Javadoc) - * Adds a file to an entry in a map of macro names to entries. - * File additions look like: - * example.c, \ - */ - protected void addMacroAdditionFile(HashMap map, String macroName, - String relativePath, IPath sourceLocation, boolean generatedSource) { - // Add the source file path to the makefile line that adds source files to the build variable - String srcName; - IPath projectLocation = project.getLocation(); - IPath dirLocation = projectLocation; - if (generatedSource) { - dirLocation = dirLocation.append(getBuildWorkingDir()); - } - if (dirLocation.isPrefixOf(sourceLocation)) { - IPath srcPath = sourceLocation.removeFirstSegments(dirLocation.segmentCount()).setDevice(null); - if (generatedSource) { - srcName = "./" + srcPath.toString(); //$NON-NLS-1$ - } else { - srcName = ROOT + "/" + srcPath.toString(); //$NON-NLS-1$ - } - } else { - if (generatedSource && !sourceLocation.isAbsolute()) { - srcName = "./" + relativePath + sourceLocation.lastSegment().toString(); //$NON-NLS-1$ - } else { - // TODO: Should we use relative paths when possible (e.g., see MbsMacroSupplier.calculateRelPath) - srcName = sourceLocation.toString(); - } - } - addMacroAdditionFile(map, macroName, srcName); - } - - /* (non-Javadoc) - * Adds file(s) to an entry in a map of macro names to entries. - * File additions look like: - * example.c, \ - */ - public void addMacroAdditionFiles(HashMap map, String macroName, Vector filenames) { - StringBuffer buffer = new StringBuffer(); - buffer.append(map.get(macroName)); - for (int i=0; i 0) { - buffer.append(filename + WHITESPACE + LINEBREAK); - } - } - // re-insert string in the map - map.put(macroName, buffer.toString()); - } - - /* (non-Javadoc) - * Write all macro addition entries in a map to the buffer - */ - protected StringBuffer writeAdditionMacros(LinkedHashMap map) { - StringBuffer buffer = new StringBuffer(); - // Add the comment - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); - - Collection bufferCollection = map.values(); - Iterator collectionIterator = bufferCollection.iterator(); - while(collectionIterator.hasNext()) - { - String macroString = collectionIterator.next().toString(); - // Check if we added any files to the rule - // Currently, we do this by comparing the end of the rule buffer to MACRO_ADDITION_PREFIX_SUFFIX - if (!(macroString.endsWith(MACRO_ADDITION_PREFIX_SUFFIX))) { - StringBuffer currentBuffer = new StringBuffer(); - - // Remove the final "/" - if (macroString.endsWith(LINEBREAK)) { - macroString = macroString.substring(0, (macroString - .length() - 2)) - + NEWLINE; - } - currentBuffer.append(macroString); - - currentBuffer.append(NEWLINE); - - // append the contents of the buffer to the master buffer for - // the whole file - buffer.append(currentBuffer); - } - } - return buffer.append(NEWLINE); - } - - /* (non-Javadoc) - * Write all macro addition entries in a map to the buffer - */ - protected StringBuffer writeTopAdditionMacros(List varList, HashMap varMap) { - StringBuffer buffer = new StringBuffer(); - // Add the comment - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); - - for (int i=0; i 0) - name = resolved; - } catch (BuildMacroException e){ - } - - gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], true, - name, ext); - } else { - gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], false, null, null); - } - doneState[i] = 0; - } - - // Initialize the build output variable to file additions map - LinkedHashMap map = getTopBuildOutputVars(); - Iterator iterator = buildOutVars.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - addMacroAdditionPrefix(map, macroName, "", false); //$NON-NLS-1$ - } - - // Set of input extensions for which macros have been created so far - HashSet handledDepsInputExtensions = new HashSet(); - HashSet handledOutsInputExtensions = new HashSet(); - - while (!done) { - int[] testState = new int[doneState.length]; - for (int i=0; iOperationCanceledException. - * - * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() - */ - protected void checkCancel() { - if (monitor != null && monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } - - /* (non-Javadoc) - * Return or create the folder needed for the build output. If we are - * creating the folder, set the derived bit to true so the CM system - * ignores the contents. If the resource exists, respect the existing - * derived setting. - * - * @param string - * @return IPath - */ - private IPath createDirectory(String dirName) throws CoreException { - // Create or get the handle for the build directory - IFolder folder = project.getFolder(dirName); - if (!folder.exists()) { - // Make sure that parent folders exist - IPath parentPath = (new Path(dirName)).removeLastSegments(1); - // Assume that the parent exists if the path is empty - if (!parentPath.isEmpty()) { - IFolder parent = project.getFolder(parentPath); - if (!parent.exists()) { - createDirectory(parentPath.toString()); - } - } - - // Now make the requested folder - try { - folder.create(true, true, null); - } - catch (CoreException e) { - if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) - folder.refreshLocal(IResource.DEPTH_ZERO, null); - else - throw e; - } - - // Make sure the folder is marked as derived so it is not added to CM - if (!folder.isDerived()) { - folder.setDerived(true); - } - } - - return folder.getFullPath(); - } - - /* (non-Javadoc) - * Return or create the makefile needed for the build. If we are creating - * the resource, set the derived bit to true so the CM system ignores - * the contents. If the resource exists, respect the existing derived - * setting. - * - * @param makefilePath - * @return IFile - */ - private IFile createFile(IPath makefilePath) throws CoreException { - // Create or get the handle for the makefile - IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); - IFile newFile = root.getFileForLocation(makefilePath); - if (newFile == null) { - newFile = root.getFile(makefilePath); - } - // Create the file if it does not exist - ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]); - try { - newFile.create(contents, false, new SubProgressMonitor(monitor, 1)); - // Make sure the new file is marked as derived - if (!newFile.isDerived()) { - newFile.setDerived(true); - } - - } - catch (CoreException e) { - // If the file already existed locally, just refresh to get contents - if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) - newFile.refreshLocal(IResource.DEPTH_ZERO, null); - else - throw e; - } - - return newFile; - } - - /** - * @param deletedFile - */ - private void deleteBuildTarget(IResource deletedFile) { - // Get the project relative path of the file - String fileName = getFileName(deletedFile); - String srcExtension = deletedFile.getFileExtension(); - String targetExtension = info.getOutputExtension(srcExtension); - if (targetExtension != "") //$NON-NLS-1$ - fileName += DOT + targetExtension; - IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1); - IPath targetFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName); - IResource depFile = project.findMember(targetFilePath); - if (depFile != null && depFile.exists()) { - try { - depFile.delete(true, new SubProgressMonitor(monitor, 1)); - } catch (CoreException e) { - // This had better be allowed during a build - - } - } - } - - /** - * @param deletedFile - */ - private void deleteDepFile(IResource deletedFile) { - // Calculate the top build directory relative paths of the dependency files - IPath[] depFilePaths = null; - ITool tool = null; - IManagedDependencyGeneratorType depType = null; - String sourceExtension = deletedFile.getFileExtension(); - ITool[] tools = config.getFilteredTools(); - for (int index = 0; index < tools.length; ++index) { - if (tools[index].buildsFileType(sourceExtension)) { - tool = tools[index]; - depType = tool.getDependencyGeneratorForExtension(sourceExtension); - break; - } - } - if (depType != null) { - int calcType = depType.getCalculatorType(); - if (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND) { - depFilePaths = new IPath[1]; - IPath absolutePath = deletedFile.getLocation(); - depFilePaths[0] = ManagedBuildManager.calculateRelativePath(getTopBuildDir(), absolutePath); - depFilePaths[0] = depFilePaths[0].removeFileExtension().addFileExtension(DEP_EXT); - } else if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS || - calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { - IManagedDependencyGenerator2 depGen = (IManagedDependencyGenerator2)depType; - IManagedDependencyInfo depInfo = depGen.getDependencySourceInfo( - deletedFile.getProjectRelativePath(), config, tool, getBuildWorkingDir()); - if (depInfo != null) { - if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) { - IManagedDependencyCommands depCommands = (IManagedDependencyCommands)depInfo; - depFilePaths = depCommands.getDependencyFiles(); - } else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { - IManagedDependencyPreBuild depPreBuild = (IManagedDependencyPreBuild)depInfo; - depFilePaths = depPreBuild.getDependencyFiles(); - } - } - } - } - - // Delete the files if they exist - if (depFilePaths != null) { - for (int i=0; iString - * - * @param file - * @return - */ - private String getFileName(IResource file) { - String answer = new String(); - String lastSegment = file.getName(); - int extensionSeparator = lastSegment.lastIndexOf(DOT); - if (extensionSeparator != -1) { - answer = lastSegment.substring(0, extensionSeparator); - } - return answer; - } - - /* (non-Javadoc) - * Answers a Vector containing a list of directories that are invalid for the - * build for some reason. At the moment, the only reason a directory would - * not be considered for the build is if it contains a space in the relative - * path from the project root. - * - * @return a a list of directories that are invalid for the build - */ - private Vector getInvalidDirList() { - if (invalidDirList == null) { - invalidDirList = new Vector(); - } - return invalidDirList; - } - - /* (non-javadoc) - * - * @return Vector - */ - private Vector getModifiedList() { - if (modifiedList == null) { - modifiedList = new Vector(); - } - return modifiedList; - } - - /* (non-javadoc) - * Answers the list of subdirectories (IContainer's) contributing source code to the build - * - * @return List - */ - private Vector getSubdirList() { - if (subdirList == null) { - subdirList = new Vector(); - } - return subdirList; - } - - /* (non-Javadoc) - * @param subDir - */ - private void removeGeneratedDirectory(IContainer subDir) { - try { - // The source directory isn't empty - if (subDir.exists() && subDir.members().length > 0) return; - } catch (CoreException e) { - // The resource doesn't exist so we should delete the output folder - } - - // Figure out what the generated directory name is and delete it - IPath moduleRelativePath = subDir.getProjectRelativePath(); - IPath buildRoot = getBuildWorkingDir(); - if (buildRoot == null) { - return; - } - IPath moduleOutputPath = buildRoot.append(moduleRelativePath); - IFolder folder = project.getFolder(moduleOutputPath); - if (folder.exists()) { - try { - folder.delete(true, new SubProgressMonitor(monitor, 1)); - } catch (CoreException e) { - // TODO Log this - } - } - } - - /* (non-Javadoc) - * @param msg - */ - protected void updateMonitor(String msg) { - if (monitor!= null && !monitor.isCanceled()) { - monitor.subTask(msg); - monitor.worked(1); - } - } - - /** - * Return the configuration's top build directory as an absolute path - */ - public IPath getTopBuildDir() { - return project.getLocation().append(getBuildWorkingDir()); - } - -} +/******************************************************************************* + * Copyright (c) 2003, 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 Rational Software - Initial API and implementation + * ARM Ltd. - Minor changes to echo commands + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; // Note: We use LinkedHashMap instead of HashMap + // only to keep the generation of makefiles constant + // for our test set. Make itself doesn't care + // about the order. +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.internal.core.model.Util; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCalculator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +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.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.IWorkspaceRoot; +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.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * This is a specialized makefile generator that takes advantage of the + * extensions present in Gnu Make. + * + * @since 1.2 + */ + +public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { + + /** + * This class walks the delta supplied by the build system to determine + * what resources have been changed. The logic is very simple. If a + * buildable resource (non-header) has been added or removed, the directories + * in which they are located are "dirty" so the makefile fragments for them + * have to be regenerated. + *

+ * The actual dependencies are recalculated as a result of the build step + * itself. We are relying on make to do the right things when confronted + * with a dependency on a moved header file. That said, make will treat + * the missing header file in a dependency rule as a target it has to build + * unless told otherwise. These dummy targets are added to the makefile + * to avoid a missing target error. + */ + public class ResourceDeltaVisitor implements IResourceDeltaVisitor { + private GnuMakefileGenerator generator; + private IManagedBuildInfo info; + + /** + * The constructor + */ + public ResourceDeltaVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) { + this.generator = generator; + this.info = info; + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) + */ + public boolean visit(IResourceDelta delta) throws CoreException { + // Should the visitor keep iterating in current directory + boolean keepLooking = false; + IResource resource = delta.getResource(); + + // What kind of resource change has occurred + if (resource.getType() == IResource.FILE) { + String ext = resource.getFileExtension(); + switch (delta.getKind()) { + case IResourceDelta.ADDED: + if (!generator.isGeneratedResource(resource)) { + // This is a source file so just add its container + if (info.buildsFileType(ext)) { + generator.appendModifiedSubdirectory(resource); + } + } + break; + case IResourceDelta.REMOVED: + // we get this notification if a resource is moved too + if (!generator.isGeneratedResource(resource)) { + // This is a source file so just add its container + if (info.buildsFileType(ext)) { + generator.appendDeletedFile(resource); + generator.appendModifiedSubdirectory(resource); + } + } + break; + default: + keepLooking = true; + break; + } + } + if (resource.getType() == IResource.FOLDER) { + // I only care about delete event + switch (delta.getKind()) { + case IResourceDelta.REMOVED: + if (!generator.isGeneratedResource(resource)) { + generator.appendDeletedSubdirectory((IContainer)resource); + } + default: + break; + } + } + if (resource.getType() == IResource.PROJECT) { + // If there is a zero-length delta, something the project depends on has changed so just call make + IResourceDelta[] children = delta.getAffectedChildren(); + if (children != null && children.length > 0) { + keepLooking = true; + } + } else { + // If the resource is part of the generated directory structure don't recurse + if (!generator.isGeneratedResource(resource)) { + keepLooking = true; + } + } + + return keepLooking; + } + } + + + + /** + * This class is used to recursively walk the project and determine which + * modules contribute buildable source files. + */ + protected class ResourceProxyVisitor implements IResourceProxyVisitor { + private GnuMakefileGenerator generator; + private IManagedBuildInfo info; + + /** + * Constructs a new resource proxy visitor to quickly visit project + * resources. + */ + public ResourceProxyVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) { + this.generator = generator; + this.info = info; + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy) + */ + public boolean visit(IResourceProxy proxy) throws CoreException { + // No point in proceeding, is there + if (generator == null) { + return false; + } + + // Is this a resource we should even consider + if (proxy.getType() == IResource.FILE) { + // If this resource has a Resource Configuration and is not excluded or + // if it has a file extension that one of the tools builds, add the sudirectory to the list + IResource resource = proxy.requestResource(); + boolean willBuild = false; + IResourceConfiguration resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); + if (resConfig != null) willBuild = true; + if (!willBuild) { + String ext = resource.getFileExtension(); + if (info.buildsFileType(ext) && + // If this file resource is a generated resource, then it is uninteresting + !generator.isGeneratedResource(resource)) { + willBuild = true; + } + } + if (willBuild) { + if ((resConfig == null) || (!(resConfig.isExcluded()))) { + generator.appendBuildSubdirectory(resource); + } + } + return false; + } + + // Recurse into subdirectories + return true; + } + + } + + // String constants for makefile contents and messages + private static final String COMMENT = "MakefileGenerator.comment"; //$NON-NLS-1$ + //private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$ + //private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$ + //private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$ + + //private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$ + private static final String HEADER = COMMENT + ".header"; //$NON-NLS-1$ + + protected static final String MESSAGE_FINISH_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.build"); //$NON-NLS-1$ + protected static final String MESSAGE_FINISH_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.file"); //$NON-NLS-1$ + protected static final String MESSAGE_START_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.build"); //$NON-NLS-1$ + protected static final String MESSAGE_START_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.file"); //$NON-NLS-1$ + protected static final String MESSAGE_START_DEPENDENCY = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.dependency"); //$NON-NLS-1$ + protected static final String MESSAGE_NO_TARGET_TOOL = ManagedMakeMessages.getResourceString("MakefileGenerator.message.no.target"); //$NON-NLS-1$ + //private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$ + private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$ + private static final String MOD_VARS = COMMENT + ".module.variables"; //$NON-NLS-1$ + private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$ + private static final String BUILD_TOP = COMMENT + ".build.toprules"; //$NON-NLS-1$ + private static final String ALL_TARGET = COMMENT + ".build.alltarget"; //$NON-NLS-1$ + private static final String MAINBUILD_TARGET = COMMENT + ".build.mainbuildtarget"; //$NON-NLS-1$ + private static final String BUILD_TARGETS = COMMENT + ".build.toptargets"; //$NON-NLS-1$ + private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = new String(); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + private static final String OBJS_MACRO = "OBJS"; //$NON-NLS-1$ + private static final String MACRO_ADDITION_ADDPREFIX_HEADER = "${addprefix "; //$NON-NLS-1$ + private static final String MACRO_ADDITION_ADDPREFIX_SUFFIX = "," + WHITESPACE + LINEBREAK; //$NON-NLS-1$ + private static final String MACRO_ADDITION_PREFIX_SUFFIX = "+=" + WHITESPACE + LINEBREAK; //$NON-NLS-1$ + private static final String PREBUILD = "pre-build"; //$NON-NLS-1$ + private static final String MAINBUILD = "main-build"; //$NON-NLS-1$ + private static final String POSTBUILD = "post-build"; //$NON-NLS-1$ + private static final String SECONDARY_OUTPUTS = "secondary-outputs"; //$NON-NLS-1$ + + // Enumerations + public static final int + PROJECT_RELATIVE = 1, + PROJECT_SUBDIR_RELATIVE = 2, + ABSOLUTE = 3; + + // Local variables needed by generator + private String buildTargetName; + private String buildTargetExt; + private IConfiguration config; + private ITool[] buildTools; + private boolean[] buildToolsUsed; + private ManagedBuildGnuToolInfo[] gnuToolInfos; + private Vector deletedFileList; + private Vector deletedDirList; + private IManagedBuildInfo info; + private Vector invalidDirList; + private Vector modifiedList; + private IProgressMonitor monitor; + private IProject project; + private IResource[] projectResources; + private Vector ruleList; + private Vector depLineList; // String's of additional dependency lines + private Vector depRuleList; // String's of rules for generating dependency files + private Vector subdirList; + private IPath topBuildDir; // Build directory - relative to the workspace + private Set outputExtensionsSet; + // Maps of macro names (String) to values (List) + private HashMap buildSrcVars = new HashMap(); // Map of source file build variable names + // to a List of source file Path's + private HashMap buildOutVars = new HashMap(); // Map of output file build variable names + // to a List of output file Path's + private HashMap buildDepVars = new HashMap(); // Map of dependency file build variable names + // to a List of GnuDependencyGroupInfo objects + private LinkedHashMap topBuildOutVars = new LinkedHashMap(); + // Dependency file variables + private Vector dependencyMakefiles; // IPath's - relative to the top build directory or absolute + + + public GnuMakefileGenerator() { + super(); + } + + + /************************************************************************* + * IManagedBuilderMakefileGenerator M E T H O D S + ************************************************************************/ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#initialize() + * + * @param project + * @param info + * @param monitor + */ + public void initialize(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) { + // Save the project so we can get path and member information + this.project = project; + try { + projectResources = project.members(); + } catch (CoreException e) { + projectResources = null; + } + // Save the monitor reference for reporting back to the user + this.monitor = monitor; + // Get the build info for the project + this.info = info; + // Get the name of the build target + buildTargetName = info.getBuildArtifactName(); + // Get its extension + buildTargetExt = info.getBuildArtifactExtension(); + + try{ + //try to resolve the build macros in the target extension + buildTargetExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + buildTargetExt, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + try{ + //try to resolve the build macros in the target name + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + buildTargetName, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + buildTargetName = resolved; + } catch (BuildMacroException e){ + } + + + if (buildTargetExt == null) { + buildTargetExt = new String(); + } + // Cache the build tools + config = info.getDefaultConfiguration(); + buildTools = config.getFilteredTools(); + buildToolsUsed = new boolean[buildTools.length]; + for (int i=0; iStringBuffer containing all of the required targets to + * properly build the project. + * + * @param outputVarsAdditionsList list to add needed build output variables to + * @param rebuild + * @return StringBuffer + */ + private StringBuffer addTargets(List outputVarsAdditionsList, boolean rebuild) { + StringBuffer buffer = new StringBuffer(); + + IConfiguration config = info.getDefaultConfiguration(); + + // Assemble the information needed to generate the targets + String prebuildStep = info.getPrebuildStep(); + try{ + //try to resolve the build macros in the prebuild step + prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + prebuildStep, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_CONFIGURATION, + config); + } catch (BuildMacroException e){ + } + prebuildStep = prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + + String postbuildStep = info.getPostbuildStep(); + try{ + //try to resolve the build macros in the postbuild step + postbuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + postbuildStep, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_CONFIGURATION, + config); + + } catch (BuildMacroException e){ + } + postbuildStep = postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + String preannouncebuildStep = info.getPreannouncebuildStep(); + String postannouncebuildStep = info.getPostannouncebuildStep(); + String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$ + + ITool targetTool = config.getTargetTool(); + if (targetTool == null) { + targetTool = info.getToolFromOutputExtension(buildTargetExt); + } + + // Get all the projects the build target depends on + IProject[] refdProjects = null; + try { + refdProjects = project.getReferencedProjects(); + } catch (CoreException e) { + // There are 2 exceptions; the project does not exist or it is not open + // and neither conditions apply if we are building for it .... + } + + // If a prebuild step exists, redefine the all target to be + // all: {pre-build} main-build + // and then reset the "traditional" all target to main-build + // This will allow something meaningful to happen if the generated + // makefile is + // extracted and run standalone via "make all" + // + String defaultTarget = "all:"; //$NON-NLS-1$ + if (prebuildStep.length() > 0) { + + // Add the comment for the "All" target + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); + + buffer.append(defaultTarget + WHITESPACE); + buffer.append(PREBUILD + WHITESPACE); + + // Reset defaultTarget for now and for subsequent use, below + defaultTarget = MAINBUILD; + buffer.append(defaultTarget); + + // Update the defaultTarget, main-build, by adding a colon, which is + // needed below + defaultTarget = defaultTarget.concat(COLON); + buffer.append(NEWLINE + NEWLINE); + + // Add the comment for the "main-build" target + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MAINBUILD_TARGET) + NEWLINE); + } + else + // Add the comment for the "All" target + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); + + // Write out the all target first in case someone just runs make + // all: or mainbuild: + + String outputPrefix = EMPTY_STRING; + if (targetTool != null) { + outputPrefix = targetTool.getOutputPrefix(); + } + buffer.append(defaultTarget + WHITESPACE + outputPrefix + buildTargetName); + if (buildTargetExt.length() > 0) { + buffer.append(DOT + buildTargetExt); + } + + // Add the Secondary Outputs to the all target, if any + IOutputType[] secondaryOutputs = config.getToolChain().getSecondaryOutputs(); + if (secondaryOutputs.length > 0) { + buffer.append(WHITESPACE + SECONDARY_OUTPUTS); + } + + buffer.append(NEWLINE + NEWLINE); + + /* + * The build target may depend on other projects in the workspace. These + * are captured in the deps target: deps: ; + * $(MAKE) [clean all | all]> + */ + Vector managedProjectOutputs = new Vector(refdProjects.length); + if (refdProjects.length > 0) { + boolean addDeps = true; + if (refdProjects != null) { + for (int i = 0; i < refdProjects.length; i++) { + IProject dep = refdProjects[i]; + if (!dep.exists()) continue; + if (addDeps) { + buffer.append("dependents:" + NEWLINE); //$NON-NLS-1$ + addDeps = false; + } + String buildDir = dep.getLocation().toString(); + String depTargets = targets; + if (ManagedBuildManager.manages(dep)) { + // Add the current configuration to the makefile path + IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep); + buildDir += SEPARATOR + depInfo.getConfigurationName(); + + // Extract the build artifact to add to the dependency list + String depTarget = depInfo.getBuildArtifactName(); + String depExt = depInfo.getBuildArtifactExtension(); + + try{ + //try to resolve the build macros in the artifact extension + depExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + depExt, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + try{ + //try to resolve the build macros in the artifact name + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + depTarget, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + depTarget = resolved; + } catch (BuildMacroException e){ + } + + String depPrefix = depInfo.getOutputPrefix(depExt); + if (depInfo.needsRebuild()) { + depTargets = "clean all"; //$NON-NLS-1$ + } + String dependency = buildDir + SEPARATOR + depPrefix + depTarget; + if (depExt.length() > 0) { + dependency += DOT + depExt; + } + dependency = escapeWhitespaces(dependency); + managedProjectOutputs.add(dependency); + } + buffer.append(TAB + "-cd" + WHITESPACE + escapeWhitespaces(buildDir) + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + buffer.append(NEWLINE); + } + + // Add the targets tool rules + buffer.append(addTargetsRules(targetTool, + outputVarsAdditionsList, managedProjectOutputs, (postbuildStep.length() > 0))); + + // Add the prebuild step target, if specified + if (prebuildStep.length() > 0) { + buffer.append(PREBUILD + COLON + NEWLINE); + if (preannouncebuildStep.length() > 0) { + buffer.append(TAB + DASH + AT + escapedEcho(preannouncebuildStep)); + } + buffer.append(TAB + DASH + prebuildStep + NEWLINE); + buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); + } + + // Add the postbuild step, if specified + if (postbuildStep.length() > 0) { + buffer.append(POSTBUILD + COLON + NEWLINE); + if (postannouncebuildStep.length() > 0) { + buffer.append(TAB + DASH + AT + escapedEcho(postannouncebuildStep)); + } + buffer.append(TAB + DASH + postbuildStep + NEWLINE); + buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); + } + + // Add the Secondary Outputs target, if needed + if (secondaryOutputs.length > 0) { + buffer.append(SECONDARY_OUTPUTS + COLON); + Vector outs2 = calculateSecondaryOutputs(secondaryOutputs); + for (int i=0; i 0) { + buffer.append(WHITESPACE + MAINBUILD + WHITESPACE + PREBUILD); + } + if (postbuildStep.length() > 0) { + buffer.append(WHITESPACE + POSTBUILD); + } + buffer.append(NEWLINE); + Iterator refIter = managedProjectOutputs.listIterator(); + while(refIter.hasNext()) { + buffer.append((String)refIter.next() + COLON + NEWLINE); + } + buffer.append(NEWLINE); + + // Include makefile.targets supplemental makefile + buffer.append("-include " + ROOT + SEPARATOR + MAKEFILE_TARGETS + NEWLINE); //$NON-NLS-1$ + + return buffer; + } + + /* (non-javadoc) + * Returns the targets rules. The targets make file (top makefile) contains: + * 1 the rule for the final target tool + * 2 the rules for all of the tools that use multipleOfType in their primary input type + * 3 the rules for all tools that use the output of #2 tools + * + * @param outputVarsAdditionsList list to add needed build output variables to + * @param managedProjectOutputs Other projects in the workspace that this project depends upon + * @return StringBuffer + */ + private StringBuffer addTargetsRules(ITool targetTool, + List outputVarsAdditionsList, Vector managedProjectOutputs, boolean postbuildStep) { + StringBuffer buffer = new StringBuffer(); + // Add the comment + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(BUILD_TOP) + NEWLINE); + + // Get the target tool and generate the rule + if (targetTool != null) { + if (addRuleForTool(targetTool, buffer, true, buildTargetName, buildTargetExt, + outputVarsAdditionsList, managedProjectOutputs, postbuildStep)) { + // Mark the target tool as processed + for (int i=0; i 0) { + buffer.append(DOT + buildTargetExt); + } + buffer.append(NEWLINE); + buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); + + return buffer; + } + + /* (non-Javadoc) + * Create the rule + * + * @param tool + * @param buffer Buffer to add makefile rules to + * @param bTargetTool True if this is the target tool + * @param targetName If this is the "targetTool", the target file name, else null + * @param targetName If this is the "targetTool", the target file extension, else null + * @param outputVarsAdditionsList list to add needed build output variables to + * @param managedProjectOutputs Other projects in the workspace that this project depends upon + * @param bPostBuildStep Emit post-build step invocation + */ + protected boolean addRuleForTool(ITool tool, StringBuffer buffer, boolean bTargetTool, String targetName, String targetExt, + List outputVarsAdditionsList, Vector managedProjectOutputs, boolean bEmitPostBuildStepCall) { + + // Get the tool's inputs and outputs + Vector inputs = new Vector(); + Vector dependencies = new Vector(); + Vector outputs = new Vector(); + Vector enumeratedPrimaryOutputs = new Vector(); + Vector enumeratedSecondaryOutputs = new Vector(); + Vector outputVariables = new Vector(); + Vector additionalTargets = new Vector(); + String outputPrefix = EMPTY_STRING; + + if (!getToolInputsOutputs(tool, inputs, dependencies, outputs, + enumeratedPrimaryOutputs, enumeratedSecondaryOutputs, + outputVariables, additionalTargets, bTargetTool, managedProjectOutputs)) { + return false; + } + + // If we have no primary output, make all of the secondary outputs the primary output + if (enumeratedPrimaryOutputs.size() == 0) { + enumeratedPrimaryOutputs = enumeratedSecondaryOutputs; + enumeratedSecondaryOutputs.clear(); + } + + // Add the output variables for this tool to our list + outputVarsAdditionsList.addAll(outputVariables); + + // Create the build rule + String buildRule = EMPTY_STRING; + String outflag = tool.getOutputFlag(); + + String primaryOutputs = EMPTY_STRING; + boolean first = true; + for (int i=0; i 0) + command = resolvedCommand; + + } catch (BuildMacroException e){ + } + String[] cmdInputs = (String[])inputs.toArray(new String[inputs.size()]); + IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); + IManagedCommandLineInfo cmdLInfo = gen.generateCommandLineInfo( tool, command, + flags, outflag, outputPrefix, primaryOutputs, cmdInputs, tool.getCommandLinePattern() ); + + // The command to build + String buildCmd = null; + if( cmdLInfo == null ) { + String toolFlags; + try { + toolFlags = tool.getToolCommandFlagsString(null,null); + } catch( BuildException ex ) { + // TODO report error + toolFlags = EMPTY_STRING; + } + buildCmd = command + WHITESPACE + toolFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + primaryOutputs + WHITESPACE + IN_MACRO; + } + else buildCmd = cmdLInfo.getCommandLine(); + + // resolve any remaining macros in the command after it has been + // generated + try { + String resolvedCommand = ManagedBuildManager + .getBuildMacroProvider().resolveValueToMakefileFormat( + buildCmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(null, null, null, tool)); + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + + buffer.append(TAB + AT + escapedEcho(buildCmd)); + buffer.append(TAB + AT + buildCmd); + + // TODO + // NOTE WELL: Dependency file generation is not handled for this type of Tool + + // Echo finished message + buffer.append(NEWLINE); + buffer.append(TAB + AT + escapedEcho((bTargetTool ? MESSAGE_FINISH_BUILD : MESSAGE_FINISH_FILE) + WHITESPACE + OUT_MACRO)); + buffer.append(TAB + AT + ECHO_BLANK_LINE); + + // If there is a post build step, then add a recursive invocation of MAKE to invoke it after the main build + // Note that $(MAKE) will instantiate in the recusive invocation to the make command that was used to invoke + // the makefile originally + if (bEmitPostBuildStepCall) { + buffer.append(TAB + MAKE + WHITESPACE + NO_PRINT_DIR + WHITESPACE + POSTBUILD + NEWLINE + NEWLINE); + } + else { + // Just emit a blank line + buffer.append(NEWLINE); + } + } + + // If we have secondary outputs, output dependency rules without commands + if (enumeratedSecondaryOutputs.size() > 0 || additionalTargets.size() > 0) { + String primaryOutput = (String)enumeratedPrimaryOutputs.get(0); + Vector addlOutputs = new Vector(); + addlOutputs.addAll(enumeratedSecondaryOutputs); + addlOutputs.addAll(additionalTargets); + for (int i=0; i 0) { + for (int j=0; j 0) { + for (int j=0; jStringBuffer containing the comment(s) + * for a fragment makefile (subdir.mk). + */ + protected StringBuffer addFragmentMakefileHeader() { + return addDefaultHeader(); + } + + /* (non-javadoc) + * Returns a StringBuffer containing makefile text for all of the sources + * contributed by a container (project directory/subdirectory) to the fragement makefile + * + * @param module project resource directory/subdirectory + * @return StringBuffer generated text for the fragement makefile + */ + protected StringBuffer addSources(IContainer module) throws CoreException { + // Calculate the new directory relative to the build output + IPath moduleRelativePath = module.getProjectRelativePath(); + String relativePath = moduleRelativePath.toString(); + relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$ + + // For build macros in the configuration, create a map which will map them + // to a string which holds its list of sources. + LinkedHashMap buildVarToRuleStringMap = new LinkedHashMap(); + + // Add statements that add the source files in this folder, + // and generated source files, and generated dependency files + // to the build macros + Iterator iterator = buildSrcVars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, null, false); + } + iterator = buildOutVars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, "./" + relativePath, false); //$NON-NLS-1$ + } + + // String buffers + StringBuffer buffer = new StringBuffer(); // Return buffer + StringBuffer ruleBuffer = new StringBuffer(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_RULES) + NEWLINE); + + // Visit the resources in this folder and add each one to a sources macro, and generate a build rule, if appropriate + IResource[] resources = module.members(); + + IResourceConfiguration resConfig; + IFolder folder = project.getFolder(info.getConfigurationName()); + + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (resource.getType() == IResource.FILE) { + // Check whether this resource is excluded from build + resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); + if( (resConfig != null) && (resConfig.isExcluded()) ) + continue; + addFragmentMakefileEntriesForSource(buildVarToRuleStringMap, ruleBuffer, + folder, relativePath, resource, resource.getLocation(), resConfig, null, false); + } + } + + // Write out the macro addition entries to the buffer + buffer.append(writeAdditionMacros(buildVarToRuleStringMap)); + return buffer.append(ruleBuffer + NEWLINE); + } + + /* (non-Javadoc + * Adds the entries for a particular source file to the fragment makefile + * + * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable + * @param ruleBuffer buffer to add generated nmakefile text to + * @param folder the top level build output directory + * @param relativePath build output directory relative path of the current output directory + * @param resource the source file for this invocation of the tool - this may be null for a generated output + * @param sourceLocation the full path of the source + * @param resConfig the IResourceConfiguration associated with this file or null + * @param varName the build variable to add this invocation's outputs to + * if null, use the file extension to find the name + * @param generatedSource if true, this file was generated by another tool in the tool-chain + */ + protected void addFragmentMakefileEntriesForSource (LinkedHashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, + IFolder folder, String relativePath, IResource resource, IPath sourceLocation, IResourceConfiguration resConfig, + String varName, boolean generatedSource) { + + // Determine which tool, if any, builds files with this extension + String ext = sourceLocation.getFileExtension(); + ITool tool = null; + + // Use the tool from the resource configuration if there is one + if (resConfig != null) { + ITool[] tools = resConfig.getToolsToInvoke(); + if (tools != null && tools.length > 0) { + tool = tools[0]; + } + } + for (int j=0; j 0) { + for (int k=0; k 0) { + IPath firstOutput = (IPath)generatedOutputs.get(0); + String firstExt = firstOutput.getFileExtension(); + for (int j=0; j 0) { + buildVariable = bV; + break; + } + } + } + } + } else { + buildVariable = outType.getBuildVariable(); + } + } else { + // For support of pre-CDT 3.0 integrations. + buildVariable = OBJS_MACRO; + } + + for (int k=0; k 0) { + if (isSecondaryOutputVar(secondaryOutputs, varName)) { + addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); + } + } + } + } + } + + /* (non-Javadoc) + * Adds the source file to the appropriate build variable + * + * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable + * @param ext the file extension of the file + * @param varName the build variable to add this invocation's outputs to + * if null, use the file extension to find the name + * @param relativePath build output directory relative path of the current output directory + * @param sourceLocation the full path of the source + * @param generatedSource if true, this file was generated by another tool in the tool-chain + */ + protected void addToBuildVar (LinkedHashMap buildVarToRuleStringMap, String ext, + String varName, String relativePath, IPath sourceLocation, boolean generatedSource) { + List varList = null; + if (varName == null) { + // Get the proper source build variable based upon the extension + varName = getSourceMacroName(ext).toString(); + varList = (List)buildSrcVars.get(varName); + } else { + varList = (List)buildOutVars.get(varName); + } + // Add the resource to the list of all resources associated with a variable. + // Do not allow duplicates - there is no reason to and it can be 'bad' - + // e.g., having the same object in the OBJS list can cause duplicate symbol errors from the linker + if ((varList != null) && !(varList.contains(sourceLocation))) { + // Since we don't know how these files will be used, we store them using a "location" + // path rather than a relative path + varList.add(sourceLocation); + if (!buildVarToRuleStringMap.containsKey(varName)) { + // TODO - is this an error? + } else { + // Add the resource name to the makefile line that adds resources to the build variable + addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); + } + } + } + + /* (non-Javadoc) + * Create a rule for this source file. We create a pattern rule if possible. + * + * This is an example of a pattern rule: + * + * /%.: ..//%. + * @echo Building file: $< + * @echo Invoking tool xxx + * @echo $@ $< + * @ $@ $< && \ + * echo -n $(@:%.o=%.d) ' /' >> $(@:%.o=%.d) && \ + * -P -MM -MG $< >> $(@:%.o=%.d) + * @echo Finished building: $< + * @echo ' ' + * + * Note that the macros all come from the build model and are + * resolved to a real command before writing to the module + * makefile, so a real command might look something like: + * source1/%.o: ../source1/%.cpp + * @echo Building file: $< + * @echo Invoking tool xxx + * @echo g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< + * @ g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< && \ + * echo -n $(@:%.o=%.d) ' source1/' >> $(@:%.o=%.d) && \ + * g++ -P -MM -MG -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers $< >> $(@:%.o=%.d) + * @echo Finished building: $< + * @echo ' ' + * + * @param relativePath top build output directory relative path of the current output directory + * @param buffer buffer to populate with the build rule + * @param resource the source file for this invocation of the tool + * @param sourceLocation the full path of the source + * @param resConfig the IResourceConfiguration associated with this file or null + * @param generatedSource true if the resource is a generated output + * @param generatedDepFile build directory relative paths of the dependency files generated by the rule + * @param enumeratedOutputs vector of the filenames that are the output of this rule + */ + protected void addRuleForSource(String relativePath, StringBuffer buffer, IResource resource, + IPath sourceLocation, IResourceConfiguration resConfig, + boolean generatedSource, Vector generatedDepFiles, Vector enumeratedOutputs) { + + String fileName = sourceLocation.removeFileExtension().lastSegment(); + String inputExtension = sourceLocation.getFileExtension(); + String outputExtension = info.getOutputExtension(inputExtension); + + ITool tool = null; + if( resConfig != null) { + ITool[] tools = resConfig.getToolsToInvoke(); + if (tools != null && tools.length > 0) { + tool = tools[0]; + } + } + if (tool == null) { + tool = info.getToolFromInputExtension(inputExtension); + } + + // Get the dependency generator information for this tool and file extension + IManagedDependencyGenerator oldDepGen = null; // This interface is deprecated but still supported + IManagedDependencyGenerator2 depGen = null; // This is the recommended interface + IManagedDependencyInfo depInfo = null; + IManagedDependencyCommands depCommands = null; + IManagedDependencyPreBuild depPreBuild = null; + IPath[] depFiles = null; + boolean doDepGen = false; + { + IManagedDependencyGeneratorType t = tool.getDependencyGeneratorForExtension(inputExtension); + if (t != null) { + int calcType = t.getCalculatorType(); + if (calcType <= IManagedDependencyGeneratorType.TYPE_OLD_TYPE_LIMIT) { + oldDepGen = (IManagedDependencyGenerator)t; + doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND); + if (doDepGen) { + IPath depFile = Path.fromOSString(relativePath + fileName + DOT + DEP_EXT); + getDependencyMakefiles().add(depFile); + generatedDepFiles.add(depFile); + } + } else { + depGen = (IManagedDependencyGenerator2)t; + doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS); + IBuildObject buildContext = (resConfig != null) ? (IBuildObject)resConfig : (IBuildObject)config; + depInfo = depGen.getDependencySourceInfo(resource.getProjectRelativePath(), buildContext, tool, getBuildWorkingDir()); + if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) { + depCommands = (IManagedDependencyCommands)depInfo; + depFiles = depCommands.getDependencyFiles(); + } else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { + depPreBuild = (IManagedDependencyPreBuild)depInfo; + depFiles = depPreBuild.getDependencyFiles(); + } + if (depFiles != null) { + for (int i=0; i 0) + optDotExt = DOT + outputExtension; + + Vector ruleOutputs = new Vector(); + Vector enumeratedPrimaryOutputs = new Vector(); // IPaths relative to the top build directory + Vector enumeratedSecondaryOutputs = new Vector(); // IPaths relative to the top build directory + calculateOutputsForSource(tool, relativePath, resource, sourceLocation, ruleOutputs, enumeratedPrimaryOutputs, enumeratedSecondaryOutputs); + enumeratedOutputs.addAll(enumeratedPrimaryOutputs); + enumeratedOutputs.addAll(enumeratedSecondaryOutputs); + String primaryOutputName = null; + if (enumeratedPrimaryOutputs.size() > 0) { + primaryOutputName = escapeWhitespaces(((IPath)enumeratedPrimaryOutputs.get(0)).toString()); + } else { + primaryOutputName = escapeWhitespaces(relativePath + fileName + optDotExt); + } + String otherPrimaryOutputs = EMPTY_STRING; + for (int i=1; i 0 + || MacroResolver.getReferencedExplitFileMacros(tool + .getToolCommand(), IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + // Get and resolve the command + String cmd = tool.getToolCommand(); + + try { + String resolvedCommand = null; + if (!needExplicitRuleForFile) { + resolvedCommand = ManagedBuildManager.getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } else { + // if we need an explicit rule then don't use any builder + // variables, resolve everything + // to explicit strings + resolvedCommand = ManagedBuildManager.getBuildMacroProvider() + .resolveValue( + cmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } + + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + String defaultOutputName = EMPTY_STRING; + String primaryDependencyName = EMPTY_STRING; + String patternPrimaryDependencyName = EMPTY_STRING; + String home = (generatedSource)? DOT : ROOT; + String resourcePath = null; + boolean patternRule = true; + boolean isItLinked = false; + //if (resource.isLinked()) { NOTE: we don't use this since children of linked resources return false + if(!sourceLocation.toString().startsWith(projectLocation)) { + // it IS linked, so use the actual location + isItLinked = true; + resourcePath = sourceLocation.toString(); + // Need a hardcoded rule, not a pattern rule, as a linked file + // can reside in any path + defaultOutputName = escapeWhitespaces(relativePath + fileName + optDotExt); + primaryDependencyName = escapeWhitespaces(resourcePath); + patternRule = false; + } else { + // Use the relative path (not really needed to store per se but in the future someone may want this) + resourcePath = relativePath; + // The rule and command to add to the makefile + if( resConfig != null || needExplicitRuleForFile) { + // Need a hardcoded rule, not a pattern rule + defaultOutputName = escapeWhitespaces(resourcePath + fileName + optDotExt); + patternRule = false; + } else { + defaultOutputName = relativePath + WILDCARD + optDotExt; + } + primaryDependencyName = escapeWhitespaces(home + SEPARATOR + resourcePath + fileName + DOT + inputExtension); + patternPrimaryDependencyName = home + SEPARATOR + resourcePath + WILDCARD + DOT + inputExtension; + } // end fix for PR 70491 + + // If the tool specifies a dependency calculator of TYPE_BUILD_COMMANDS, ask whether + // the dependency commands are "generic" (i.e., we can use a pattern rule) + boolean needExplicitDependencyCommands = false; + if (depCommands != null) { + needExplicitDependencyCommands = !depCommands.areCommandsGeneric(); + } + + // If we still think that we are using a pattern rule, check a few more things + if (patternRule) { + patternRule = false; + // Make sure that at least one of the rule outputs contains a %. + for (int i=0; i= 0) { //$NON-NLS-1$ + patternRule = true; + break; + } + } + if (patternRule) { + patternRule = !needExplicitDependencyCommands; + } + } + + // Begin building the rule for this source file + String buildRule = EMPTY_STRING; + + if (patternRule) { + if (ruleOutputs.size() == 0) { + buildRule += defaultOutputName; + } else { + boolean first = true; + for (int i=0; i= 0) { //$NON-NLS-1$ + if (first) { + first = false; + } else { + buildRule += WHITESPACE; + } + buildRule += ruleOutput; + } + } + } + } else { + buildRule += primaryOutputName; + } + + String buildRuleDependencies = primaryDependencyName; + String patternBuildRuleDependencies = patternPrimaryDependencyName; + + // Other additional inputs + // Get any additional dependencies specified for the tool in other InputType elements and AdditionalInput elements + IPath[] addlDepPaths = tool.getAdditionalDependencies(); + for (int i=0; i 0) { + for (int i=0; i 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + buffer.append(TAB + AT + escapedEcho(buildCmd)); + buffer.append(TAB + AT + buildCmd); + + // Determine if there are any dependencies to calculate + if (doDepGen) { + // Get the dependency rule out of the generator + String[] depCmds = null; + if (oldDepGen != null) { + depCmds = new String[1]; + depCmds[0] = oldDepGen.getDependencyCommand(resource, info); + } else { + if (depCommands != null) { + depCmds = depCommands.getPostToolDependencyCommands(); + } + } + + if (depCmds != null) { + for (int i=0; i 0) { + calculatedDependencies = new String(); + for (int i=0; i 1) { + // Starting with 1 is intentional in order to skip the primary output + for (int i=1; i 0) depLine += WHITESPACE; + if (patternRule) { + optDotExt = EMPTY_STRING; + String depExt = depFiles[i].getFileExtension(); + if (depExt != null && depExt.length() > 0) + optDotExt = DOT + depExt; + depLine += escapeWhitespaces(relativePath + WILDCARD + optDotExt); + } else { + depLine += escapeWhitespaces((depFiles[i]).toString()); + } + } + depLine += COLON + WHITESPACE + (patternRule ? patternBuildRuleDependencies : buildRuleDependencies); + if (!getDepRuleList().contains(depLine)) { + getDepRuleList().add(depLine); + addedDepLines = true; + buffer.append(depLine + NEWLINE); + buffer.append(TAB + AT + escapedEcho(MESSAGE_START_DEPENDENCY + WHITESPACE + OUT_MACRO)); + for (int i=0; i 0) { + int flagsLen = flags.length; + String[] flagsCopy = new String[flags.length + depOptions.length]; + for (int i=0; i 0) { + allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + // Use file extensions + String[] typeExts = type.getSourceExtensions(tool); + for (int j=0; j 0) b = true; + if (toolParent instanceof IToolChain) { + IConfiguration config = ((IToolChain)toolParent).getParent(); + if (config != null) { + ManagedBuildManager.setOption(config, tool, assignToOption, b); + } + } else if (toolParent instanceof IResourceConfiguration) { + ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, b); + } + } else if (optType == IOption.ENUMERATED) { + if (allRes.size() > 0) { + String s = allRes.get(0).toString(); + if (toolParent instanceof IToolChain) { + IConfiguration config = ((IToolChain)toolParent).getParent(); + if (config != null) { + ManagedBuildManager.setOption(config, tool, assignToOption, s); + } + } else if (toolParent instanceof IResourceConfiguration) { + ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, s); + } + } + } + allRes.clear(); + } + } catch( BuildException ex ) { + } + } + } + } + return (IPath[])allRes.toArray(new IPath[allRes.size()]); + } + + + /* (non-Javadoc) + * Returns the output IPaths for this invocation of the tool with the specified source file + /* + * The priorities for determining the names of the outputs of a tool are: + * 1. If the tool is the build target and primary output, use artifact name & extension - + * This case does not apply here... + * 2. If an option is specified, use the value of the option + * 3. If a nameProvider is specified, call it + * 4. If outputNames is specified, use it + * 5. Use the name pattern to generate a transformation macro + * so that the source names can be transformed into the target names + * using the built-in string substitution functions of make. + * + * @param tool + * @param relativePath build output directory relative path of the current output directory + * @param resource + * @param ruleOutputs Vector of rule IPaths that are relative to the build directory + * @param enumeratedPrimaryOutputs Vector of IPaths of primary outputs + * that are relative to the build directory + * @param enumeratedSecondaryOutputs Vector of IPaths of secondary outputs + * that are relative to the build directory + */ + protected void calculateOutputsForSource(ITool tool, String relativePath, IResource resource, + IPath sourceLocation, Vector ruleOutputs, Vector enumeratedPrimaryOutputs, Vector enumeratedSecondaryOutputs) { + String inExt = sourceLocation.getFileExtension(); + String outExt = tool.getOutputExtension(inExt); + + IOutputType[] outTypes = tool.getOutputTypes(); + if (outTypes != null && outTypes.length > 0) { + for (int i=0; i 0) { + for (int j=0; j 0) + outputName = resolved; + } catch (BuildMacroException e){ + } + + IPath outPath = Path.fromOSString(outputName); + // If only a file name is specified, add the relative path of this output directory + if (outPath.segmentCount() == 1) { + outPath = Path.fromOSString(relativePath + (String)outputList.get(j)); + } + if (primaryOutput) { + ruleOutputs.add(j, outPath); + enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); + } else { + ruleOutputs.add(outPath); + enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); + } + } + } catch( BuildException ex ) {} + } else + // 3. If a nameProvider is specified, call it + if (nameProvider != null) { + IPath[] inPaths = new IPath[1]; + inPaths[0] = sourceLocation; + IPath[] outPaths = nameProvider.getOutputNames(tool, inPaths); + for (int j=0; j 0) + outputName = resolved; + } catch (BuildMacroException e) { + } + + // If only a file name is specified, add the relative path of this output directory + if (outPath.segmentCount() == 1) { + outPath = Path.fromOSString(relativePath + outPath.toString()); + } + if (primaryOutput) { + ruleOutputs.add(j, outPath); + enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); + } else { + ruleOutputs.add(outPath); + enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); + } + } + } else + // 4. If outputNames is specified, use it + if (outputNames != null) { + for (int j = 0; j < outputNames.length; j++) { + String outputName = outputNames[j]; + try{ + //try to resolve the build macros in the output names + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + outputName, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, null, option, tool)); + if((resolved = resolved.trim()).length() > 0) + outputName = resolved; + } catch (BuildMacroException e){ + } + + IPath outPath = Path.fromOSString(outputName); + // If only a file name is specified, add the relative path of this output directory + if (outPath.segmentCount() == 1) { + outPath = Path.fromOSString(relativePath + outPath.toString()); + } + if (primaryOutput) { + ruleOutputs.add(j, outPath); + enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); + } else { + ruleOutputs.add(outPath); + enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); + } + } + } else { + // 5. Use the name pattern to generate a transformation macro + // so that the source names can be transformed into the target names + // using the built-in string substitution functions of make. + if (multOfType) { + // This case is not handled - a nameProvider or outputNames must be specified + // TODO - report error + } else { + String namePattern = type.getNamePattern(); + IPath namePatternPath = null; + if (namePattern == null || namePattern.length() == 0) { + namePattern = relativePath + outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + if (outExt != null && outExt.length() > 0) { + namePattern += DOT + outExt; + } + namePatternPath = Path.fromOSString(namePattern); + } + else { + if (outputPrefix.length() > 0) { + namePattern = outputPrefix + namePattern; + } + namePatternPath = Path.fromOSString(namePattern); + // If only a file name is specified, add the relative path of this output directory + if (namePatternPath.segmentCount() == 1) { + namePatternPath = Path.fromOSString(relativePath + namePatternPath.toString()); + } + } + + if (primaryOutput) { + ruleOutputs.add(0, namePatternPath); + enumeratedPrimaryOutputs.add(0, resolvePercent(namePatternPath, sourceLocation)); + } else { + ruleOutputs.add(namePatternPath); + enumeratedSecondaryOutputs.add(resolvePercent(namePatternPath, sourceLocation)); + } + } + } + } + } else { + // For support of pre-CDT 3.0 integrations. + // NOTE WELL: This only supports the case of a single "target tool" + // that consumes exactly all of the object files, $OBJS, produced + // by other tools in the build and produces a single output. + // In this case, the output file name is the input file name with + // the output extension. + + //if (!ignorePrimary) { + String outPrefix = tool.getOutputPrefix(); + IPath outPath = Path.fromOSString(relativePath + outPrefix + WILDCARD); + outPath = outPath.addFileExtension(outExt); + ruleOutputs.add(0, outPath); + enumeratedPrimaryOutputs.add(0, resolvePercent(outPath, sourceLocation)); + //} + } + } + + /* (non-Javadoc) + * If the path contains a %, returns the path resolved using the resource name + * + */ + protected IPath resolvePercent(IPath outPath, IPath sourceLocation) { + // Get the input file name + String fileName = sourceLocation.removeFileExtension().lastSegment(); + // Replace the % with the file name + String outName = outPath.toOSString().replaceAll("%", fileName); //$NON-NLS-1$ + return Path.fromOSString(outName); + } + + /* (non-Javadoc) + * Returns the dependency IPaths for this invocation of the tool with the specified source file + * + * @param depGen the dependency calculator + * @param tool tool used to build the source file + * @param relativePath build output directory relative path of the current output directory + * @param resource source file to scan for dependencies + * @return Vector of IPaths that are relative to the build directory + */ + protected IPath[] oldCalculateDependenciesForSource(IManagedDependencyGenerator depGen, ITool tool, String relativePath, IResource resource) { + Vector deps = new Vector(); + int type = depGen.getCalculatorType(); + + switch (type) { + + case IManagedDependencyGeneratorType.TYPE_INDEXER: + case IManagedDependencyGeneratorType.TYPE_EXTERNAL: + IResource[] res = depGen.findDependencies(resource, project); + if (res != null) { + for (int i=0; iIPaths relative to the build directory + * + * @param depCalculator the dependency calculator + * @return IPath[] that are relative to the build directory + */ + protected IPath[] calculateDependenciesForSource(IManagedDependencyCalculator depCalculator) { + IPath[] addlDeps = depCalculator.getDependencies(); + if (addlDeps != null) { + for (int i=0; iSet containing all of the output extensions + */ + public Set getOutputExtensions() { + if (outputExtensionsSet == null) { + // The set of output extensions which will be produced by this tool. + // It is presumed that this set is not very large (likely < 10) so + // a HashSet should provide good performance. + outputExtensionsSet = new HashSet(); + + // For each tool for the target, lookup the kinds of sources it outputs + // and add that to our list of output extensions. + for (int i=0; itrue if the dependency file is modified + */ + static public boolean populateDummyTargets(IConfiguration cfg, IFile makefile, boolean force) throws CoreException, IOException { + if (makefile == null || !makefile.exists()) return false; + + // Get the contents of the dependency file + InputStream contentStream = makefile.getContents(false); + Reader in = new InputStreamReader(contentStream); + StringBuffer inBuffer = null; + int chunkSize = contentStream.available(); + inBuffer = new StringBuffer(chunkSize); + char[] readBuffer = new char[chunkSize]; + int n = in.read(readBuffer); + while (n > 0) { + inBuffer.append(readBuffer); + n = in.read(readBuffer); + } + contentStream.close(); + + // The rest of this operation is equally expensive, so + // if we are doing an incremental build, only update the + // files that do not have a comment + if (inBuffer == null) return false; + String inBufferString = inBuffer.toString(); + if (!force && inBufferString.startsWith(COMMENT_SYMBOL)) { + return false; + } + + // Try to determine if this file already has dummy targets defined. + // If so, we will only add the comment. + String[] bufferLines = inBufferString.split("[\\r\\n]"); //$NON-NLS-1$ + for (int i=0; i 1) { //$NON-NLS-1$ + // This is escaped so keep adding to the token until we find the end + while (tokenIter.hasNext()) { + String nextToken = (String)tokenIter.next(); + token += WHITESPACE + nextToken; + if (!nextToken.endsWith("\\")) { //$NON-NLS-1$ + break; + } + } + } + deps.add(token); + } + deps.trimToSize(); + + // Now find the header file dependencies and make dummy targets for them + boolean save = false; + StringBuffer outBuffer = null; + + // If we are doing an incremental build, only update the files that do not have a comment + String firstToken; + try { + firstToken = (String) deps.get(0); + } catch (ArrayIndexOutOfBoundsException e) { + // This makes no sense so bail + return false; + } + + // Put the generated comments in the output buffer + if (!firstToken.startsWith(COMMENT_SYMBOL)) { + outBuffer = addDefaultHeader(); + } else { + outBuffer = new StringBuffer(); + } + + // Some echo implementations misbehave and put the -n and newline in the output + if (firstToken.startsWith("-n")) { //$NON-NLS-1$ + + // Now let's parse: + // Win32 outputs -n '/.d /' + // POSIX outputs -n /.d / + // Get the dep file name + String secondToken; + try { + secondToken = (String) deps.get(1); + } catch (ArrayIndexOutOfBoundsException e) { + secondToken = new String(); + } + if (secondToken.startsWith("'")) { //$NON-NLS-1$ + // This is the Win32 implementation of echo (MinGW without MSYS) + outBuffer.append(secondToken.substring(1) + WHITESPACE); + } else { + outBuffer.append(secondToken + WHITESPACE); + } + + // The relative path to the build goal comes next + String thirdToken; + try { + thirdToken = (String) deps.get(2); + } catch (ArrayIndexOutOfBoundsException e) { + thirdToken = new String(); + } + int lastIndex = thirdToken.lastIndexOf("'"); //$NON-NLS-1$ + if (lastIndex != -1) { + if (lastIndex == 0) { + outBuffer.append(WHITESPACE); + } else { + outBuffer.append(thirdToken.substring(0, lastIndex - 1)); + } + } else { + outBuffer.append(thirdToken); + } + + // Followed by the target output by the compiler plus ':' + // If we see any empty tokens here, assume they are the result of + // a line feed output by "echo" and skip them + String fourthToken; + int nToken = 3; + try { + do { + fourthToken = (String) deps.get(nToken++); + } while (fourthToken.length() == 0); + + } catch (ArrayIndexOutOfBoundsException e) { + fourthToken = new String(); + } + outBuffer.append(fourthToken + WHITESPACE); + + // Followed by the actual dependencies + try { + Iterator iter = deps.listIterator(nToken); + while (iter.hasNext()) { + String nextElement = (String)iter.next(); + if (nextElement.endsWith("\\")) { //$NON-NLS-1$ + outBuffer.append(nextElement + NEWLINE + WHITESPACE); + } else { + outBuffer.append(nextElement + WHITESPACE); + } + } + } catch (IndexOutOfBoundsException e) { + } + + } else { + outBuffer.append(inBuffer); + } + + outBuffer.append(NEWLINE); + save = true; + + // Dummy targets to add to the makefile + Iterator dummyIter = deps.iterator(); + while (dummyIter.hasNext()) { + String dummy = (String)dummyIter.next(); + IPath dep = new Path(dummy); + String extension = dep.getFileExtension(); + if (cfg.isHeaderFile(extension)) { + /* + * The formatting here is + * : + */ + outBuffer.append(dummy + COLON + NEWLINE + NEWLINE); + } + } + + // Write them out to the makefile + if (save) { + Util.save(outBuffer, makefile); + return true; + } + return false; + } + + /** + * prepend all instanced of '\' or '"' with a backslash + * + * @param string + * @return + */ + static public String escapedEcho(String string) { + String escapedString = string.replaceAll("(['\"\\\\])", "\\\\$1"); + return ECHO + WHITESPACE + escapedString + NEWLINE; + } + + static public String ECHO_BLANK_LINE = ECHO + WHITESPACE + SINGLE_QUOTE + WHITESPACE + SINGLE_QUOTE + NEWLINE; + + /* (non-Javadoc) + * Outputs a comment formatted as follows: + * ##### ....... ##### + * # + * ##### ....... ##### + */ + static protected StringBuffer addDefaultHeader() { + StringBuffer buffer = new StringBuffer(); + outputCommentLine(buffer); + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(HEADER) + NEWLINE); + outputCommentLine(buffer); + buffer.append(NEWLINE); + return buffer; + } + + /* (non-Javadoc) + * Put COLS_PER_LINE comment charaters in the argument. + */ + static protected void outputCommentLine(StringBuffer buffer) { + for (int i = 0; i < COLS_PER_LINE; i++) { + buffer.append(COMMENT_SYMBOL); + } + buffer.append(NEWLINE); + } + + static public boolean containsSpecialCharacters(String path) + { + return path.matches(".*(\\s|[\\{\\}\\(\\)\\$\\@%=;]).*"); + } + + /* (non-Javadoc) + * Answers the argument with all whitespaces replaced with an escape sequence. + * + * @param path + */ + static public String escapeWhitespaces(String path) { + // Escape the spaces in the path/filename if it has any + String[] segments = path.split("\\s"); //$NON-NLS-1$ + if (segments.length > 1) { + StringBuffer escapedPath = new StringBuffer(); + for (int index = 0; index < segments.length; ++index) { + escapedPath.append(segments[index]); + if (index + 1 < segments.length) { + escapedPath.append("\\ "); //$NON-NLS-1$ + } + } + return escapedPath.toString().trim(); + } else { + return path; + } + } + + /* (non-Javadoc) + * Adds a macro addition prefix to a map of macro names to entries. + * Entry prefixes look like: + * C_SRCS += \ + * ${addprefix $(ROOT)/, \ + */ + // TODO fix comment + protected void addMacroAdditionPrefix(LinkedHashMap map, String macroName, String relativePath, boolean addPrefix) { + // there is no entry in the map, so create a buffer for this macro + StringBuffer tempBuffer = new StringBuffer(); + tempBuffer.append(macroName + WHITESPACE + MACRO_ADDITION_PREFIX_SUFFIX); + if (addPrefix) { + tempBuffer.append(MACRO_ADDITION_ADDPREFIX_HEADER + relativePath + MACRO_ADDITION_ADDPREFIX_SUFFIX); + } + + // have to store the buffer in String form as StringBuffer is not a sublcass of Object + map.put(macroName, tempBuffer.toString()); + } + + /* (non-Javadoc) + * Adds a file to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + protected void addMacroAdditionFile(HashMap map, String macroName, String filename) { + StringBuffer buffer = new StringBuffer(); + buffer.append(map.get(macroName)); + + // escape whitespace in the filename + filename = escapeWhitespaces(filename); + + buffer.append(filename + WHITESPACE + LINEBREAK); + // re-insert string in the map + map.put(macroName, buffer.toString()); + } + + /* (non-Javadoc) + * Adds a file to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + protected void addMacroAdditionFile(HashMap map, String macroName, + String relativePath, IPath sourceLocation, boolean generatedSource) { + // Add the source file path to the makefile line that adds source files to the build variable + String srcName; + IPath projectLocation = project.getLocation(); + IPath dirLocation = projectLocation; + if (generatedSource) { + dirLocation = dirLocation.append(getBuildWorkingDir()); + } + if (dirLocation.isPrefixOf(sourceLocation)) { + IPath srcPath = sourceLocation.removeFirstSegments(dirLocation.segmentCount()).setDevice(null); + if (generatedSource) { + srcName = "./" + srcPath.toString(); //$NON-NLS-1$ + } else { + srcName = ROOT + "/" + srcPath.toString(); //$NON-NLS-1$ + } + } else { + if (generatedSource && !sourceLocation.isAbsolute()) { + srcName = "./" + relativePath + sourceLocation.lastSegment().toString(); //$NON-NLS-1$ + } else { + // TODO: Should we use relative paths when possible (e.g., see MbsMacroSupplier.calculateRelPath) + srcName = sourceLocation.toString(); + } + } + addMacroAdditionFile(map, macroName, srcName); + } + + /* (non-Javadoc) + * Adds file(s) to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + public void addMacroAdditionFiles(HashMap map, String macroName, Vector filenames) { + StringBuffer buffer = new StringBuffer(); + buffer.append(map.get(macroName)); + for (int i=0; i 0) { + buffer.append(filename + WHITESPACE + LINEBREAK); + } + } + // re-insert string in the map + map.put(macroName, buffer.toString()); + } + + /* (non-Javadoc) + * Write all macro addition entries in a map to the buffer + */ + protected StringBuffer writeAdditionMacros(LinkedHashMap map) { + StringBuffer buffer = new StringBuffer(); + // Add the comment + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); + + Collection bufferCollection = map.values(); + Iterator collectionIterator = bufferCollection.iterator(); + while(collectionIterator.hasNext()) + { + String macroString = collectionIterator.next().toString(); + // Check if we added any files to the rule + // Currently, we do this by comparing the end of the rule buffer to MACRO_ADDITION_PREFIX_SUFFIX + if (!(macroString.endsWith(MACRO_ADDITION_PREFIX_SUFFIX))) { + StringBuffer currentBuffer = new StringBuffer(); + + // Remove the final "/" + if (macroString.endsWith(LINEBREAK)) { + macroString = macroString.substring(0, (macroString + .length() - 2)) + + NEWLINE; + } + currentBuffer.append(macroString); + + currentBuffer.append(NEWLINE); + + // append the contents of the buffer to the master buffer for + // the whole file + buffer.append(currentBuffer); + } + } + return buffer.append(NEWLINE); + } + + /* (non-Javadoc) + * Write all macro addition entries in a map to the buffer + */ + protected StringBuffer writeTopAdditionMacros(List varList, HashMap varMap) { + StringBuffer buffer = new StringBuffer(); + // Add the comment + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); + + for (int i=0; i 0) + name = resolved; + } catch (BuildMacroException e){ + } + + gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], true, + name, ext); + } else { + gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], false, null, null); + } + doneState[i] = 0; + } + + // Initialize the build output variable to file additions map + LinkedHashMap map = getTopBuildOutputVars(); + Iterator iterator = buildOutVars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + addMacroAdditionPrefix(map, macroName, "", false); //$NON-NLS-1$ + } + + // Set of input extensions for which macros have been created so far + HashSet handledDepsInputExtensions = new HashSet(); + HashSet handledOutsInputExtensions = new HashSet(); + + while (!done) { + int[] testState = new int[doneState.length]; + for (int i=0; iOperationCanceledException. + * + * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() + */ + protected void checkCancel() { + if (monitor != null && monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } + + /* (non-Javadoc) + * Return or create the folder needed for the build output. If we are + * creating the folder, set the derived bit to true so the CM system + * ignores the contents. If the resource exists, respect the existing + * derived setting. + * + * @param string + * @return IPath + */ + private IPath createDirectory(String dirName) throws CoreException { + // Create or get the handle for the build directory + IFolder folder = project.getFolder(dirName); + if (!folder.exists()) { + // Make sure that parent folders exist + IPath parentPath = (new Path(dirName)).removeLastSegments(1); + // Assume that the parent exists if the path is empty + if (!parentPath.isEmpty()) { + IFolder parent = project.getFolder(parentPath); + if (!parent.exists()) { + createDirectory(parentPath.toString()); + } + } + + // Now make the requested folder + try { + folder.create(true, true, null); + } + catch (CoreException e) { + if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) + folder.refreshLocal(IResource.DEPTH_ZERO, null); + else + throw e; + } + + // Make sure the folder is marked as derived so it is not added to CM + if (!folder.isDerived()) { + folder.setDerived(true); + } + } + + return folder.getFullPath(); + } + + /* (non-Javadoc) + * Return or create the makefile needed for the build. If we are creating + * the resource, set the derived bit to true so the CM system ignores + * the contents. If the resource exists, respect the existing derived + * setting. + * + * @param makefilePath + * @return IFile + */ + private IFile createFile(IPath makefilePath) throws CoreException { + // Create or get the handle for the makefile + IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); + IFile newFile = root.getFileForLocation(makefilePath); + if (newFile == null) { + newFile = root.getFile(makefilePath); + } + // Create the file if it does not exist + ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]); + try { + newFile.create(contents, false, new SubProgressMonitor(monitor, 1)); + // Make sure the new file is marked as derived + if (!newFile.isDerived()) { + newFile.setDerived(true); + } + + } + catch (CoreException e) { + // If the file already existed locally, just refresh to get contents + if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) + newFile.refreshLocal(IResource.DEPTH_ZERO, null); + else + throw e; + } + + return newFile; + } + + /** + * @param deletedFile + */ + private void deleteBuildTarget(IResource deletedFile) { + // Get the project relative path of the file + String fileName = getFileName(deletedFile); + String srcExtension = deletedFile.getFileExtension(); + String targetExtension = info.getOutputExtension(srcExtension); + if (targetExtension != "") //$NON-NLS-1$ + fileName += DOT + targetExtension; + IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1); + IPath targetFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName); + IResource depFile = project.findMember(targetFilePath); + if (depFile != null && depFile.exists()) { + try { + depFile.delete(true, new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + // This had better be allowed during a build + + } + } + } + + /** + * @param deletedFile + */ + private void deleteDepFile(IResource deletedFile) { + // Calculate the top build directory relative paths of the dependency files + IPath[] depFilePaths = null; + ITool tool = null; + IManagedDependencyGeneratorType depType = null; + String sourceExtension = deletedFile.getFileExtension(); + ITool[] tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; ++index) { + if (tools[index].buildsFileType(sourceExtension)) { + tool = tools[index]; + depType = tool.getDependencyGeneratorForExtension(sourceExtension); + break; + } + } + if (depType != null) { + int calcType = depType.getCalculatorType(); + if (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND) { + depFilePaths = new IPath[1]; + IPath absolutePath = deletedFile.getLocation(); + depFilePaths[0] = ManagedBuildManager.calculateRelativePath(getTopBuildDir(), absolutePath); + depFilePaths[0] = depFilePaths[0].removeFileExtension().addFileExtension(DEP_EXT); + } else if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS || + calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { + IManagedDependencyGenerator2 depGen = (IManagedDependencyGenerator2)depType; + IManagedDependencyInfo depInfo = depGen.getDependencySourceInfo( + deletedFile.getProjectRelativePath(), config, tool, getBuildWorkingDir()); + if (depInfo != null) { + if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) { + IManagedDependencyCommands depCommands = (IManagedDependencyCommands)depInfo; + depFilePaths = depCommands.getDependencyFiles(); + } else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { + IManagedDependencyPreBuild depPreBuild = (IManagedDependencyPreBuild)depInfo; + depFilePaths = depPreBuild.getDependencyFiles(); + } + } + } + } + + // Delete the files if they exist + if (depFilePaths != null) { + for (int i=0; iString + * + * @param file + * @return + */ + private String getFileName(IResource file) { + String answer = new String(); + String lastSegment = file.getName(); + int extensionSeparator = lastSegment.lastIndexOf(DOT); + if (extensionSeparator != -1) { + answer = lastSegment.substring(0, extensionSeparator); + } + return answer; + } + + /* (non-Javadoc) + * Answers a Vector containing a list of directories that are invalid for the + * build for some reason. At the moment, the only reason a directory would + * not be considered for the build is if it contains a space in the relative + * path from the project root. + * + * @return a a list of directories that are invalid for the build + */ + private Vector getInvalidDirList() { + if (invalidDirList == null) { + invalidDirList = new Vector(); + } + return invalidDirList; + } + + /* (non-javadoc) + * + * @return Vector + */ + private Vector getModifiedList() { + if (modifiedList == null) { + modifiedList = new Vector(); + } + return modifiedList; + } + + /* (non-javadoc) + * Answers the list of subdirectories (IContainer's) contributing source code to the build + * + * @return List + */ + private Vector getSubdirList() { + if (subdirList == null) { + subdirList = new Vector(); + } + return subdirList; + } + + /* (non-Javadoc) + * @param subDir + */ + private void removeGeneratedDirectory(IContainer subDir) { + try { + // The source directory isn't empty + if (subDir.exists() && subDir.members().length > 0) return; + } catch (CoreException e) { + // The resource doesn't exist so we should delete the output folder + } + + // Figure out what the generated directory name is and delete it + IPath moduleRelativePath = subDir.getProjectRelativePath(); + IPath buildRoot = getBuildWorkingDir(); + if (buildRoot == null) { + return; + } + IPath moduleOutputPath = buildRoot.append(moduleRelativePath); + IFolder folder = project.getFolder(moduleOutputPath); + if (folder.exists()) { + try { + folder.delete(true, new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + // TODO Log this + } + } + } + + /* (non-Javadoc) + * @param msg + */ + protected void updateMonitor(String msg) { + if (monitor!= null && !monitor.isCanceled()) { + monitor.subTask(msg); + monitor.worked(1); + } + } + + /** + * Return the configuration's top build directory as an absolute path + */ + public IPath getTopBuildDir() { + return project.getLocation().append(getBuildWorkingDir()); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java index 09f7f160232..e08a4a6d80f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java @@ -1,122 +1,122 @@ -/******************************************************************************* - * Copyright (c) 2005, 2006 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.managedbuilder.makegen.gnu; - -import java.util.Vector; - -/** - * This interface returns information about a Tool's inputs - * and outputs while a Gnu makefile is being generated. - */ -public interface IManagedBuildGnuToolInfo { - public final String DOT = "."; //$NON-NLS-1$ - - /** - * Returns true if the tool's inputs have been calculated, - * else false. - * - * @return boolean - */ - public boolean areInputsCalculated(); - - /** - * Returns the tool's inputs in command line format. This will use - * variables rather than actual file names as appropriate. - * - * @return Vector - */ - public Vector getCommandInputs(); - - /** - * Returns the raw list of tool's input file names. - * - * @return Vector - */ - public Vector getEnumeratedInputs(); - - /** - * Returns true if the tool's outputs have been calculated, - * else false. - * - * @return boolean - */ - public boolean areOutputsCalculated(); - - /** - * Returns the tool's outputs in command line format. This will use - * variables rather than actual file names as appropriate. - * - * @return Vector - */ - public Vector getCommandOutputs(); - - /** - * Returns the raw list of tool's primary output file names. - * - * @return Vector - */ - public Vector getEnumeratedPrimaryOutputs(); - - /** - * Returns the raw list of tool's secondary output file names. - * - * @return Vector - */ - public Vector getEnumeratedSecondaryOutputs(); - - /** - * Returns the raw list of tool's output variable names. - * - * @return Vector - */ - public Vector getOutputVariables(); - - /** - * Returns true if the tool's dependencies have been calculated, - * else false. - * - * @return boolean - */ - public boolean areDependenciesCalculated(); - - /** - * Returns the tool's dependencies in command line format. This will use - * variables rather than actual file names as appropriate. - * Dependencies are top build directory relative. - * - * @return Vector - */ - public Vector getCommandDependencies(); - - /** - * Returns the tool's additional targets as determined by the - * dependency calculator. - * Additional targets are top build directory relative - * - * @return Vector - */ - public Vector getAdditionalTargets(); - - /** - * Returns the raw list of tool's input dependencies. - * - * @return Vector - */ - //public Vector getEnumeratedDependencies(); - - /** - * Returns true if this is the target tool - * else false. - * - * @return boolean - */ - public boolean isTargetTool(); -} +/******************************************************************************* + * Copyright (c) 2005, 2006 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.managedbuilder.makegen.gnu; + +import java.util.Vector; + +/** + * This interface returns information about a Tool's inputs + * and outputs while a Gnu makefile is being generated. + */ +public interface IManagedBuildGnuToolInfo { + public final String DOT = "."; //$NON-NLS-1$ + + /** + * Returns true if the tool's inputs have been calculated, + * else false. + * + * @return boolean + */ + public boolean areInputsCalculated(); + + /** + * Returns the tool's inputs in command line format. This will use + * variables rather than actual file names as appropriate. + * + * @return Vector + */ + public Vector getCommandInputs(); + + /** + * Returns the raw list of tool's input file names. + * + * @return Vector + */ + public Vector getEnumeratedInputs(); + + /** + * Returns true if the tool's outputs have been calculated, + * else false. + * + * @return boolean + */ + public boolean areOutputsCalculated(); + + /** + * Returns the tool's outputs in command line format. This will use + * variables rather than actual file names as appropriate. + * + * @return Vector + */ + public Vector getCommandOutputs(); + + /** + * Returns the raw list of tool's primary output file names. + * + * @return Vector + */ + public Vector getEnumeratedPrimaryOutputs(); + + /** + * Returns the raw list of tool's secondary output file names. + * + * @return Vector + */ + public Vector getEnumeratedSecondaryOutputs(); + + /** + * Returns the raw list of tool's output variable names. + * + * @return Vector + */ + public Vector getOutputVariables(); + + /** + * Returns true if the tool's dependencies have been calculated, + * else false. + * + * @return boolean + */ + public boolean areDependenciesCalculated(); + + /** + * Returns the tool's dependencies in command line format. This will use + * variables rather than actual file names as appropriate. + * Dependencies are top build directory relative. + * + * @return Vector + */ + public Vector getCommandDependencies(); + + /** + * Returns the tool's additional targets as determined by the + * dependency calculator. + * Additional targets are top build directory relative + * + * @return Vector + */ + public Vector getAdditionalTargets(); + + /** + * Returns the raw list of tool's input dependencies. + * + * @return Vector + */ + //public Vector getEnumeratedDependencies(); + + /** + * Returns true if this is the target tool + * else false. + * + * @return boolean + */ + public boolean isTargetTool(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java index ca0d780621a..c12413dbe59 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java @@ -1,996 +1,996 @@ -/******************************************************************************* - * Copyright (c) 2005, 2006 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.managedbuilder.makegen.gnu; - -import java.util.Iterator; -import java.util.List; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Vector; -import java.util.Map; -import java.util.HashMap; -import java.util.HashSet; - -import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCalculator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; -import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; -import org.eclipse.cdt.managedbuilder.internal.core.Tool; -import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; -import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; - -/** - * This class represents information about a Tool's inputs - * and outputs while a Gnu makefile is being generated. - */ -public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { - - /* - * Members - */ - private IProject project; - private Tool tool; - private boolean bIsTargetTool; - private String targetName; - private String targetExt; - private boolean inputsCalculated = false; - private boolean outputsCalculated = false; - private boolean outputVariablesCalculated = false; - private boolean dependenciesCalculated = false; - private Vector commandInputs = new Vector(); - private Vector enumeratedInputs = new Vector(); - private Vector commandOutputs = new Vector(); - private Vector enumeratedPrimaryOutputs = new Vector(); - private Vector enumeratedSecondaryOutputs = new Vector(); - private Vector outputVariables = new Vector(); - private Vector commandDependencies = new Vector(); - private Vector additionalTargets = new Vector(); - //private Vector enumeratedDependencies = new Vector(); - // Map of macro names (String) to values (List) - - /* - * Constructor - */ - public ManagedBuildGnuToolInfo(IProject project, ITool tool, boolean targetTool, String name, String ext) { - this.project = project; - this.tool = (Tool)tool; - bIsTargetTool = targetTool; - if (bIsTargetTool) { - targetName = name; - targetExt = ext; - } - } - - /* - * IManagedBuildGnuToolInfo Methods - */ - public boolean areInputsCalculated() { - return inputsCalculated; - } - - // Command inputs are top build directory relative - public Vector getCommandInputs() { - return commandInputs; - } - - // Enumerated inputs are project relative - public Vector getEnumeratedInputs() { - return enumeratedInputs; - } - - public boolean areOutputsCalculated() { - return outputsCalculated; - } - - // Command outputs are top build directory relative - public Vector getCommandOutputs() { - return commandOutputs; - } - - public Vector getEnumeratedPrimaryOutputs() { - return enumeratedPrimaryOutputs; - } - - public Vector getEnumeratedSecondaryOutputs() { - return enumeratedSecondaryOutputs; - } - - public Vector getOutputVariables() { - return outputVariables; - } - - public boolean areOutputVariablesCalculated() { - return outputVariablesCalculated; - } - - public boolean areDependenciesCalculated() { - return dependenciesCalculated; - } - - // Command dependencies are top build directory relative - public Vector getCommandDependencies() { - return commandDependencies; - } - - // Additional targets are top build directory relative - public Vector getAdditionalTargets() { - return additionalTargets; - } - - //public Vector getEnumeratedDependencies() { - // return enumeratedDependencies; - //} - - public boolean isTargetTool() { - return bIsTargetTool; - } - - /* - * Other Methods - */ - - public boolean calculateInputs(GnuMakefileGenerator makeGen, IConfiguration config, IResource[] projResources, boolean lastChance) { - // Get the inputs for this tool invocation - // Note that command inputs that are also dependencies are also added to the command dependencies list - - /* The priorities for determining the names of the inputs of a tool are: - * 1. If an option is specified, use the value of the option. - * 2. If a build variable is specified, use the files that have been added to the build variable as - * the output(s) of other build steps. - * 3. Use the file extensions and the resources in the project - */ - boolean done = true; - Vector myCommandInputs = new Vector(); // Inputs for the tool command line - Vector myCommandDependencies = new Vector(); // Dependencies for the make rule - Vector myEnumeratedInputs = new Vector(); // Complete list of individual inputs - - IInputType[] inTypes = tool.getInputTypes(); - if (inTypes != null && inTypes.length > 0) { - for (int i=0; i 0) - inputName = resolved; - } catch (BuildMacroException e) { - } - - if (primaryInput) { - itCommandDependencies.add(j, inputName); - } else { - itCommandDependencies.add(inputName); - } - // NO - itCommandInputs.add(inputName); - // NO - itEnumeratedInputs.add(inputName); - } - } catch( BuildException ex ) { - } - - } else { - - // Build Variable? - if (variable.length() > 0) { - String cmdVariable = variable = "$(" + variable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - itCommandInputs.add(cmdVariable); - if (primaryInput) { - itCommandDependencies.add(0, cmdVariable); - } else { - itCommandDependencies.add(cmdVariable); - } - // If there is an output variable with the same name, get - // the files associated with it. - List outMacroList = makeGen.getBuildVariableList(variable, GnuMakefileGenerator.PROJECT_RELATIVE, - null, true); - if (outMacroList != null) { - itEnumeratedInputs.addAll(outMacroList); - } else { - // If "last chance", then calculate using file extensions below - if (lastChance) { - useFileExts = true; - } else { - done = false; - break; - } - } - } - - // Use file extensions - if (variable.length() == 0 || useFileExts) { - //if (type.getMultipleOfType()) { - // Calculate EnumeratedInputs using the file extensions and the resources in the project - // Note: This is only correct for tools with multipleOfType == true, but for other tools - // it gives us an input resource for generating default names - // Determine the set of source input macros to use - HashSet handledInputExtensions = new HashSet(); - String[] exts = type.getSourceExtensions(tool); - if (projResources != null) { - for (int j=0; j 0) { - ManagedBuildManager.setOption(config, tool, assignToOption, true); - } else { - ManagedBuildManager.setOption(config, tool, assignToOption, false); - } - } else if (optType == IOption.ENUMERATED) { - if (itCommandInputs.size() > 0) { - ManagedBuildManager.setOption(config, tool, assignToOption, (String)itCommandInputs.firstElement()); - } - } - itCommandInputs.removeAllElements(); - //itEnumeratedInputs.removeAllElements(); - } catch( BuildException ex ) { - } - } - - myCommandInputs.addAll(itCommandInputs); - myCommandDependencies.addAll(itCommandDependencies); - myEnumeratedInputs.addAll(itEnumeratedInputs); - } - } else { - // For support of pre-CDT 3.0 integrations. - if (bIsTargetTool) { - // NOTE WELL: This only supports the case of a single "target tool" - // with the following characteristics: - // 1. The tool consumes exactly all of the object files produced - // by other tools in the build and produces a single output - // 2. The target name comes from the configuration artifact name - // The rule looks like: - // .: $(OBJS) - myCommandInputs.add("$(OBJS)"); //$NON-NLS-1$ - myCommandInputs.add("$(USER_OBJS)"); //$NON-NLS-1$ - myCommandInputs.add("$(LIBS)"); //$NON-NLS-1$ - } else { - // Rule will be generated by addRuleForSource - } - } - - if (done) { - commandInputs.addAll(myCommandInputs); - commandDependencies.addAll(0, myCommandDependencies); - enumeratedInputs.addAll(myEnumeratedInputs); - inputsCalculated = true; - return true; - } - - return false; - } - - /* - * The priorities for determining the names of the outputs of a tool are: - * 1. If the tool is the build target and primary output, use artifact name & extension - * 2. If an option is specified, use the value of the option - * 3. If a nameProvider is specified, call it - * 4. If outputNames is specified, use it - * 5. Use the name pattern to generate a transformation macro - * so that the source names can be transformed into the target names - * using the built-in string substitution functions of make. - * - * NOTE: If an option is not specified and this is not the primary output type, the outputs - * from the type are not added to the command line - */ - public boolean calculateOutputs(GnuMakefileGenerator makeGen, IConfiguration config, HashSet handledInputExtensions, boolean lastChance) { - - boolean done = true; - Vector myCommandOutputs = new Vector(); - Vector myEnumeratedPrimaryOutputs = new Vector(); - Vector myEnumeratedSecondaryOutputs = new Vector(); - HashMap myOutputMacros = new HashMap(); - // The next two fields are used together - Vector myBuildVars = new Vector(); - Vector myBuildVarsValues = new Vector(); - - // Get the outputs for this tool invocation - IOutputType[] outTypes = tool.getOutputTypes(); - if (outTypes != null && outTypes.length > 0) { - for (int i=0; i 0) { - outputName += (DOT + targetExt); - } - myCommandOutputs.add(outputName); - typeEnumeratedOutputs.add(outputName); - // But this doesn't use any output macro... - } else - // 2. If an option is specified, use the value of the option - if (option != null) { - try { - List outputs = new ArrayList(); - int optType = option.getValueType(); - if (optType == IOption.STRING) { - outputs.add(outputPrefix + option.getStringValue()); - } else if ( - optType == IOption.STRING_LIST || - optType == IOption.LIBRARIES || - optType == IOption.OBJECTS) { - outputs = (List)option.getValue(); - // Add outputPrefix to each if necessary - if (outputPrefix.length() > 0) { - for (int j=0; j 0) - outputs.set(j, resolved); - } catch (BuildMacroException e){ - } - } - - // NO - myCommandOutputs.addAll(outputs); - typeEnumeratedOutputs.addAll(outputs); - if (variable.length() > 0) { - List outputPaths = new ArrayList(); - for (int j=0; j 0) { - outputName = resolved; - outNames[j] = Path.fromOSString(resolved); - } - } catch (BuildMacroException e){ - } - - if (primaryOutput) { - myCommandOutputs.add(outputName); - } - typeEnumeratedOutputs.add(outputName); - } - } - } - if (variable.length() > 0 && outNames != null) { - if (myOutputMacros.containsKey(variable)) { - List currList = (List)myOutputMacros.get(variable); - currList.addAll(Arrays.asList(outNames)); - myOutputMacros.put(variable, currList); - } else { - myOutputMacros.put(variable, Arrays.asList(outNames)); - } - } - } else - // 4. If outputNames is specified, use it - if (outputNames != null) { - if (outputNames.length > 0) { - for (int j=0; j 0) - outputNames[j] = resolved; - } catch (BuildMacroException e){ - } - } - List namesList = Arrays.asList(outputNames); - if (primaryOutput) { - myCommandOutputs.addAll(namesList); - } - typeEnumeratedOutputs.addAll(namesList); - if (variable.length() > 0) { - List outputPaths = new ArrayList(); - for (int j=0; jmake. - if (multOfType) { - // This case is not handled - a nameProvider or outputNames must be specified - List errList = new ArrayList(); - errList.add(ManagedMakeMessages.getResourceString("MakefileGenerator.error.no.nameprovider")); //$NON-NLS-1$ - myCommandOutputs.add(errList); - } else { - String namePattern = type.getNamePattern(); - if (namePattern == null || namePattern.length() == 0) { - namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; - String outExt = (type.getOutputExtensions(tool))[0]; - if (outExt != null && outExt.length() > 0) { - namePattern += DOT + outExt; - } - } - else if (outputPrefix.length() > 0) { - namePattern = outputPrefix + namePattern; - } - - // Calculate the output name - // The inputs must have been calculated before we can do this - if (!inputsCalculated) { - done = false; - } else { - Vector inputs = getEnumeratedInputs(); - String fileName; - if (inputs.size() > 0) { - // Get the input file name - fileName = (Path.fromOSString((String)inputs.get(0))).removeFileExtension().lastSegment(); - // Check if this is a build macro. If so, use the raw macro name. - if (fileName.startsWith("$(") && fileName.endsWith(")")) { //$NON-NLS-1$ //$NON-NLS-2$ - fileName = fileName.substring(2,fileName.length()-1); - } - } else { - fileName = "default"; //$NON-NLS-1$ - } - // Replace the % with the file name - if (primaryOutput) { - myCommandOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ - } - typeEnumeratedOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ - if (variable.length() > 0) { - List outputs = new ArrayList(); - outputs.add(Path.fromOSString(fileName)); - if (myOutputMacros.containsKey(variable)) { - List currList = (List)myOutputMacros.get(variable); - currList.addAll(outputs); - myOutputMacros.put(variable, currList); - } else { - myOutputMacros.put(variable, outputs); - } - } - } - } - } - if (variable.length() > 0) { - myBuildVars.add(variable); - myBuildVarsValues.add(typeEnumeratedOutputs); - } - if (primaryOutput) { - myEnumeratedPrimaryOutputs.addAll(typeEnumeratedOutputs); - } else { - myEnumeratedSecondaryOutputs.addAll(typeEnumeratedOutputs); - } - } - } else { - if (bIsTargetTool) { - String outputPrefix = tool.getOutputPrefix(); - String outputName = outputPrefix + targetName; - if (targetExt.length() > 0) { - outputName += (DOT + targetExt); - } - myCommandOutputs.add(outputName); - myEnumeratedPrimaryOutputs.add(outputName); - } else { - // For support of pre-CDT 3.0 integrations. - // NOTE WELL: This only supports the case of a single "target tool" - // that consumes exactly all of the object files, $OBJS, produced - // by other tools in the build and produces a single output - } - } - - // Add the output macros of this tool to the buildOutVars map - Iterator iterator = myOutputMacros.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - List newMacroValue = (List)entry.getValue(); - HashMap map = makeGen.getBuildOutputVars(); - if (map.containsKey(macroName)) { - List macroValue = (List)map.get(macroName); - macroValue.addAll(newMacroValue); - map.put(macroName, macroValue); - } else { - map.put(macroName, newMacroValue); - } - } - outputVariablesCalculated = true; - - if (done) { - commandOutputs.addAll(myCommandOutputs); - enumeratedPrimaryOutputs.addAll(myEnumeratedPrimaryOutputs); - enumeratedSecondaryOutputs.addAll(myEnumeratedSecondaryOutputs); - outputVariables.addAll(myOutputMacros.keySet()); - outputsCalculated = true; - for (int i=0; i 0) depExt = xt; - } - String depsMacroEntry = calculateSourceMacro(makeGen, extensionName, depExt, - IManagedBuilderMakefileGenerator.WILDCARD); - - List depsList = new ArrayList(); - depsList.add(Path.fromOSString(depsMacroEntry)); - String depsMacro = makeGen.getDepMacroName(extensionName).toString(); - if (myOutputMacros.containsKey(depsMacro)) { - List currList = (List)myOutputMacros.get(depsMacro); - currList.addAll(depsList); - myOutputMacros.put(depsMacro, currList); - } else { - myOutputMacros.put(depsMacro, depsList); - } - } - } - break; - - case IManagedDependencyGeneratorType.TYPE_INDEXER: - case IManagedDependencyGeneratorType.TYPE_EXTERNAL: - case IManagedDependencyGeneratorType.TYPE_CUSTOM: - // The inputs must have been calculated before we can do this - if (!inputsCalculated) { - done = false; - } else { - Vector inputs = getEnumeratedInputs(); - - if (calcType == IManagedDependencyGeneratorType.TYPE_CUSTOM) { - IManagedDependencyGenerator2 depGen2 = (IManagedDependencyGenerator2)depGen; - IManagedDependencyInfo depInfo = null; - for (int i=0; i 0) { - for (int i=0; i 0) { - for (int j=0; j.: $(OBJS) - myCommandDependencies.add("$(OBJS)"); //$NON-NLS-1$ - myCommandDependencies.add("$(USER_OBJS)"); //$NON-NLS-1$ - } else { - // Handle dependencies from the dependencyCalculator - IManagedDependencyGeneratorType depGen = tool.getDependencyGenerator(); - String[] extensionsList = tool.getAllInputExtensions(); - if (depGen != null) { - done = callDependencyCalculator (makeGen, config, handledInputExtensions, - depGen, extensionsList, myCommandDependencies, myOutputMacros, - myAdditionalTargets, done); - } - - } - } - - // Add the output macros of this tool to the buildOutVars map - Iterator iterator = myOutputMacros.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - List newMacroValue = (List)entry.getValue(); - HashMap map = makeGen.getBuildOutputVars(); - if (map.containsKey(macroName)) { - List macroValue = (List)map.get(macroName); - macroValue.addAll(newMacroValue); - map.put(macroName, macroValue); - } else { - map.put(macroName, newMacroValue); - } - } - - if (done) { - commandDependencies.addAll(myCommandDependencies); - additionalTargets.addAll(myAdditionalTargets); - //enumeratedDependencies.addAll(myEnumeratedDependencies); - dependenciesCalculated = true; - return true; - } - - return false; - } - - - /* - * Calculate the source macro for the given extension - */ - protected String calculateSourceMacro(GnuMakefileGenerator makeGen, String srcExtensionName, String outExtensionName, String wildcard) { - StringBuffer macroName = makeGen.getSourceMacroName(srcExtensionName); - String OptDotExt = ""; //$NON-NLS-1$ - if (outExtensionName != null) { - OptDotExt = DOT + outExtensionName; - } else - if (tool.getOutputExtension(srcExtensionName) != "") //$NON-NLS-1$ - OptDotExt = DOT + tool.getOutputExtension(srcExtensionName); - - // create rule of the form - // OBJS = $(macroName1: ../%.input1=%.output1) ... $(macroNameN: ../%.inputN=%.outputN) - StringBuffer objectsBuffer = new StringBuffer(); - objectsBuffer.append(IManagedBuilderMakefileGenerator.WHITESPACE + "$(" + macroName + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.COLON + IManagedBuilderMakefileGenerator.ROOT + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.SEPARATOR + IManagedBuilderMakefileGenerator.WILDCARD + - DOT + srcExtensionName + "=" + wildcard + OptDotExt + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ - return objectsBuffer.toString(); - } - -} +/******************************************************************************* + * Copyright (c) 2005, 2006 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.managedbuilder.makegen.gnu; + +import java.util.Iterator; +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Vector; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; + +import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCalculator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.managedbuilder.internal.core.Tool; +import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; +import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * This class represents information about a Tool's inputs + * and outputs while a Gnu makefile is being generated. + */ +public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { + + /* + * Members + */ + private IProject project; + private Tool tool; + private boolean bIsTargetTool; + private String targetName; + private String targetExt; + private boolean inputsCalculated = false; + private boolean outputsCalculated = false; + private boolean outputVariablesCalculated = false; + private boolean dependenciesCalculated = false; + private Vector commandInputs = new Vector(); + private Vector enumeratedInputs = new Vector(); + private Vector commandOutputs = new Vector(); + private Vector enumeratedPrimaryOutputs = new Vector(); + private Vector enumeratedSecondaryOutputs = new Vector(); + private Vector outputVariables = new Vector(); + private Vector commandDependencies = new Vector(); + private Vector additionalTargets = new Vector(); + //private Vector enumeratedDependencies = new Vector(); + // Map of macro names (String) to values (List) + + /* + * Constructor + */ + public ManagedBuildGnuToolInfo(IProject project, ITool tool, boolean targetTool, String name, String ext) { + this.project = project; + this.tool = (Tool)tool; + bIsTargetTool = targetTool; + if (bIsTargetTool) { + targetName = name; + targetExt = ext; + } + } + + /* + * IManagedBuildGnuToolInfo Methods + */ + public boolean areInputsCalculated() { + return inputsCalculated; + } + + // Command inputs are top build directory relative + public Vector getCommandInputs() { + return commandInputs; + } + + // Enumerated inputs are project relative + public Vector getEnumeratedInputs() { + return enumeratedInputs; + } + + public boolean areOutputsCalculated() { + return outputsCalculated; + } + + // Command outputs are top build directory relative + public Vector getCommandOutputs() { + return commandOutputs; + } + + public Vector getEnumeratedPrimaryOutputs() { + return enumeratedPrimaryOutputs; + } + + public Vector getEnumeratedSecondaryOutputs() { + return enumeratedSecondaryOutputs; + } + + public Vector getOutputVariables() { + return outputVariables; + } + + public boolean areOutputVariablesCalculated() { + return outputVariablesCalculated; + } + + public boolean areDependenciesCalculated() { + return dependenciesCalculated; + } + + // Command dependencies are top build directory relative + public Vector getCommandDependencies() { + return commandDependencies; + } + + // Additional targets are top build directory relative + public Vector getAdditionalTargets() { + return additionalTargets; + } + + //public Vector getEnumeratedDependencies() { + // return enumeratedDependencies; + //} + + public boolean isTargetTool() { + return bIsTargetTool; + } + + /* + * Other Methods + */ + + public boolean calculateInputs(GnuMakefileGenerator makeGen, IConfiguration config, IResource[] projResources, boolean lastChance) { + // Get the inputs for this tool invocation + // Note that command inputs that are also dependencies are also added to the command dependencies list + + /* The priorities for determining the names of the inputs of a tool are: + * 1. If an option is specified, use the value of the option. + * 2. If a build variable is specified, use the files that have been added to the build variable as + * the output(s) of other build steps. + * 3. Use the file extensions and the resources in the project + */ + boolean done = true; + Vector myCommandInputs = new Vector(); // Inputs for the tool command line + Vector myCommandDependencies = new Vector(); // Dependencies for the make rule + Vector myEnumeratedInputs = new Vector(); // Complete list of individual inputs + + IInputType[] inTypes = tool.getInputTypes(); + if (inTypes != null && inTypes.length > 0) { + for (int i=0; i 0) + inputName = resolved; + } catch (BuildMacroException e) { + } + + if (primaryInput) { + itCommandDependencies.add(j, inputName); + } else { + itCommandDependencies.add(inputName); + } + // NO - itCommandInputs.add(inputName); + // NO - itEnumeratedInputs.add(inputName); + } + } catch( BuildException ex ) { + } + + } else { + + // Build Variable? + if (variable.length() > 0) { + String cmdVariable = variable = "$(" + variable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + itCommandInputs.add(cmdVariable); + if (primaryInput) { + itCommandDependencies.add(0, cmdVariable); + } else { + itCommandDependencies.add(cmdVariable); + } + // If there is an output variable with the same name, get + // the files associated with it. + List outMacroList = makeGen.getBuildVariableList(variable, GnuMakefileGenerator.PROJECT_RELATIVE, + null, true); + if (outMacroList != null) { + itEnumeratedInputs.addAll(outMacroList); + } else { + // If "last chance", then calculate using file extensions below + if (lastChance) { + useFileExts = true; + } else { + done = false; + break; + } + } + } + + // Use file extensions + if (variable.length() == 0 || useFileExts) { + //if (type.getMultipleOfType()) { + // Calculate EnumeratedInputs using the file extensions and the resources in the project + // Note: This is only correct for tools with multipleOfType == true, but for other tools + // it gives us an input resource for generating default names + // Determine the set of source input macros to use + HashSet handledInputExtensions = new HashSet(); + String[] exts = type.getSourceExtensions(tool); + if (projResources != null) { + for (int j=0; j 0) { + ManagedBuildManager.setOption(config, tool, assignToOption, true); + } else { + ManagedBuildManager.setOption(config, tool, assignToOption, false); + } + } else if (optType == IOption.ENUMERATED) { + if (itCommandInputs.size() > 0) { + ManagedBuildManager.setOption(config, tool, assignToOption, (String)itCommandInputs.firstElement()); + } + } + itCommandInputs.removeAllElements(); + //itEnumeratedInputs.removeAllElements(); + } catch( BuildException ex ) { + } + } + + myCommandInputs.addAll(itCommandInputs); + myCommandDependencies.addAll(itCommandDependencies); + myEnumeratedInputs.addAll(itEnumeratedInputs); + } + } else { + // For support of pre-CDT 3.0 integrations. + if (bIsTargetTool) { + // NOTE WELL: This only supports the case of a single "target tool" + // with the following characteristics: + // 1. The tool consumes exactly all of the object files produced + // by other tools in the build and produces a single output + // 2. The target name comes from the configuration artifact name + // The rule looks like: + // .: $(OBJS) + myCommandInputs.add("$(OBJS)"); //$NON-NLS-1$ + myCommandInputs.add("$(USER_OBJS)"); //$NON-NLS-1$ + myCommandInputs.add("$(LIBS)"); //$NON-NLS-1$ + } else { + // Rule will be generated by addRuleForSource + } + } + + if (done) { + commandInputs.addAll(myCommandInputs); + commandDependencies.addAll(0, myCommandDependencies); + enumeratedInputs.addAll(myEnumeratedInputs); + inputsCalculated = true; + return true; + } + + return false; + } + + /* + * The priorities for determining the names of the outputs of a tool are: + * 1. If the tool is the build target and primary output, use artifact name & extension + * 2. If an option is specified, use the value of the option + * 3. If a nameProvider is specified, call it + * 4. If outputNames is specified, use it + * 5. Use the name pattern to generate a transformation macro + * so that the source names can be transformed into the target names + * using the built-in string substitution functions of make. + * + * NOTE: If an option is not specified and this is not the primary output type, the outputs + * from the type are not added to the command line + */ + public boolean calculateOutputs(GnuMakefileGenerator makeGen, IConfiguration config, HashSet handledInputExtensions, boolean lastChance) { + + boolean done = true; + Vector myCommandOutputs = new Vector(); + Vector myEnumeratedPrimaryOutputs = new Vector(); + Vector myEnumeratedSecondaryOutputs = new Vector(); + HashMap myOutputMacros = new HashMap(); + // The next two fields are used together + Vector myBuildVars = new Vector(); + Vector myBuildVarsValues = new Vector(); + + // Get the outputs for this tool invocation + IOutputType[] outTypes = tool.getOutputTypes(); + if (outTypes != null && outTypes.length > 0) { + for (int i=0; i 0) { + outputName += (DOT + targetExt); + } + myCommandOutputs.add(outputName); + typeEnumeratedOutputs.add(outputName); + // But this doesn't use any output macro... + } else + // 2. If an option is specified, use the value of the option + if (option != null) { + try { + List outputs = new ArrayList(); + int optType = option.getValueType(); + if (optType == IOption.STRING) { + outputs.add(outputPrefix + option.getStringValue()); + } else if ( + optType == IOption.STRING_LIST || + optType == IOption.LIBRARIES || + optType == IOption.OBJECTS) { + outputs = (List)option.getValue(); + // Add outputPrefix to each if necessary + if (outputPrefix.length() > 0) { + for (int j=0; j 0) + outputs.set(j, resolved); + } catch (BuildMacroException e){ + } + } + + // NO - myCommandOutputs.addAll(outputs); + typeEnumeratedOutputs.addAll(outputs); + if (variable.length() > 0) { + List outputPaths = new ArrayList(); + for (int j=0; j 0) { + outputName = resolved; + outNames[j] = Path.fromOSString(resolved); + } + } catch (BuildMacroException e){ + } + + if (primaryOutput) { + myCommandOutputs.add(outputName); + } + typeEnumeratedOutputs.add(outputName); + } + } + } + if (variable.length() > 0 && outNames != null) { + if (myOutputMacros.containsKey(variable)) { + List currList = (List)myOutputMacros.get(variable); + currList.addAll(Arrays.asList(outNames)); + myOutputMacros.put(variable, currList); + } else { + myOutputMacros.put(variable, Arrays.asList(outNames)); + } + } + } else + // 4. If outputNames is specified, use it + if (outputNames != null) { + if (outputNames.length > 0) { + for (int j=0; j 0) + outputNames[j] = resolved; + } catch (BuildMacroException e){ + } + } + List namesList = Arrays.asList(outputNames); + if (primaryOutput) { + myCommandOutputs.addAll(namesList); + } + typeEnumeratedOutputs.addAll(namesList); + if (variable.length() > 0) { + List outputPaths = new ArrayList(); + for (int j=0; jmake. + if (multOfType) { + // This case is not handled - a nameProvider or outputNames must be specified + List errList = new ArrayList(); + errList.add(ManagedMakeMessages.getResourceString("MakefileGenerator.error.no.nameprovider")); //$NON-NLS-1$ + myCommandOutputs.add(errList); + } else { + String namePattern = type.getNamePattern(); + if (namePattern == null || namePattern.length() == 0) { + namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + String outExt = (type.getOutputExtensions(tool))[0]; + if (outExt != null && outExt.length() > 0) { + namePattern += DOT + outExt; + } + } + else if (outputPrefix.length() > 0) { + namePattern = outputPrefix + namePattern; + } + + // Calculate the output name + // The inputs must have been calculated before we can do this + if (!inputsCalculated) { + done = false; + } else { + Vector inputs = getEnumeratedInputs(); + String fileName; + if (inputs.size() > 0) { + // Get the input file name + fileName = (Path.fromOSString((String)inputs.get(0))).removeFileExtension().lastSegment(); + // Check if this is a build macro. If so, use the raw macro name. + if (fileName.startsWith("$(") && fileName.endsWith(")")) { //$NON-NLS-1$ //$NON-NLS-2$ + fileName = fileName.substring(2,fileName.length()-1); + } + } else { + fileName = "default"; //$NON-NLS-1$ + } + // Replace the % with the file name + if (primaryOutput) { + myCommandOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ + } + typeEnumeratedOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ + if (variable.length() > 0) { + List outputs = new ArrayList(); + outputs.add(Path.fromOSString(fileName)); + if (myOutputMacros.containsKey(variable)) { + List currList = (List)myOutputMacros.get(variable); + currList.addAll(outputs); + myOutputMacros.put(variable, currList); + } else { + myOutputMacros.put(variable, outputs); + } + } + } + } + } + if (variable.length() > 0) { + myBuildVars.add(variable); + myBuildVarsValues.add(typeEnumeratedOutputs); + } + if (primaryOutput) { + myEnumeratedPrimaryOutputs.addAll(typeEnumeratedOutputs); + } else { + myEnumeratedSecondaryOutputs.addAll(typeEnumeratedOutputs); + } + } + } else { + if (bIsTargetTool) { + String outputPrefix = tool.getOutputPrefix(); + String outputName = outputPrefix + targetName; + if (targetExt.length() > 0) { + outputName += (DOT + targetExt); + } + myCommandOutputs.add(outputName); + myEnumeratedPrimaryOutputs.add(outputName); + } else { + // For support of pre-CDT 3.0 integrations. + // NOTE WELL: This only supports the case of a single "target tool" + // that consumes exactly all of the object files, $OBJS, produced + // by other tools in the build and produces a single output + } + } + + // Add the output macros of this tool to the buildOutVars map + Iterator iterator = myOutputMacros.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + List newMacroValue = (List)entry.getValue(); + HashMap map = makeGen.getBuildOutputVars(); + if (map.containsKey(macroName)) { + List macroValue = (List)map.get(macroName); + macroValue.addAll(newMacroValue); + map.put(macroName, macroValue); + } else { + map.put(macroName, newMacroValue); + } + } + outputVariablesCalculated = true; + + if (done) { + commandOutputs.addAll(myCommandOutputs); + enumeratedPrimaryOutputs.addAll(myEnumeratedPrimaryOutputs); + enumeratedSecondaryOutputs.addAll(myEnumeratedSecondaryOutputs); + outputVariables.addAll(myOutputMacros.keySet()); + outputsCalculated = true; + for (int i=0; i 0) depExt = xt; + } + String depsMacroEntry = calculateSourceMacro(makeGen, extensionName, depExt, + IManagedBuilderMakefileGenerator.WILDCARD); + + List depsList = new ArrayList(); + depsList.add(Path.fromOSString(depsMacroEntry)); + String depsMacro = makeGen.getDepMacroName(extensionName).toString(); + if (myOutputMacros.containsKey(depsMacro)) { + List currList = (List)myOutputMacros.get(depsMacro); + currList.addAll(depsList); + myOutputMacros.put(depsMacro, currList); + } else { + myOutputMacros.put(depsMacro, depsList); + } + } + } + break; + + case IManagedDependencyGeneratorType.TYPE_INDEXER: + case IManagedDependencyGeneratorType.TYPE_EXTERNAL: + case IManagedDependencyGeneratorType.TYPE_CUSTOM: + // The inputs must have been calculated before we can do this + if (!inputsCalculated) { + done = false; + } else { + Vector inputs = getEnumeratedInputs(); + + if (calcType == IManagedDependencyGeneratorType.TYPE_CUSTOM) { + IManagedDependencyGenerator2 depGen2 = (IManagedDependencyGenerator2)depGen; + IManagedDependencyInfo depInfo = null; + for (int i=0; i 0) { + for (int i=0; i 0) { + for (int j=0; j.: $(OBJS) + myCommandDependencies.add("$(OBJS)"); //$NON-NLS-1$ + myCommandDependencies.add("$(USER_OBJS)"); //$NON-NLS-1$ + } else { + // Handle dependencies from the dependencyCalculator + IManagedDependencyGeneratorType depGen = tool.getDependencyGenerator(); + String[] extensionsList = tool.getAllInputExtensions(); + if (depGen != null) { + done = callDependencyCalculator (makeGen, config, handledInputExtensions, + depGen, extensionsList, myCommandDependencies, myOutputMacros, + myAdditionalTargets, done); + } + + } + } + + // Add the output macros of this tool to the buildOutVars map + Iterator iterator = myOutputMacros.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + List newMacroValue = (List)entry.getValue(); + HashMap map = makeGen.getBuildOutputVars(); + if (map.containsKey(macroName)) { + List macroValue = (List)map.get(macroName); + macroValue.addAll(newMacroValue); + map.put(macroName, macroValue); + } else { + map.put(macroName, newMacroValue); + } + } + + if (done) { + commandDependencies.addAll(myCommandDependencies); + additionalTargets.addAll(myAdditionalTargets); + //enumeratedDependencies.addAll(myEnumeratedDependencies); + dependenciesCalculated = true; + return true; + } + + return false; + } + + + /* + * Calculate the source macro for the given extension + */ + protected String calculateSourceMacro(GnuMakefileGenerator makeGen, String srcExtensionName, String outExtensionName, String wildcard) { + StringBuffer macroName = makeGen.getSourceMacroName(srcExtensionName); + String OptDotExt = ""; //$NON-NLS-1$ + if (outExtensionName != null) { + OptDotExt = DOT + outExtensionName; + } else + if (tool.getOutputExtension(srcExtensionName) != "") //$NON-NLS-1$ + OptDotExt = DOT + tool.getOutputExtension(srcExtensionName); + + // create rule of the form + // OBJS = $(macroName1: ../%.input1=%.output1) ... $(macroNameN: ../%.inputN=%.outputN) + StringBuffer objectsBuffer = new StringBuffer(); + objectsBuffer.append(IManagedBuilderMakefileGenerator.WHITESPACE + "$(" + macroName + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.COLON + IManagedBuilderMakefileGenerator.ROOT + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.SEPARATOR + IManagedBuilderMakefileGenerator.WILDCARD + + DOT + srcExtensionName + "=" + wildcard + OptDotExt + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ + return objectsBuffer.toString(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java index f1ccd65b145..be8bd7cd372 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java @@ -1,87 +1,87 @@ -/******************************************************************************* - * 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.managedbuilder.makegen.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.search.ICSearchConstants; -import org.eclipse.cdt.core.search.ICSearchScope; -import org.eclipse.cdt.core.search.SearchEngine; -import org.eclipse.cdt.internal.core.search.PathCollector; -import org.eclipse.cdt.internal.core.search.PatternSearchJob; -import org.eclipse.cdt.internal.core.search.indexing.IndexManager; -import org.eclipse.cdt.internal.core.search.matching.CSearchPattern; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; - -/** - * @since 2.0 - */ -public class DefaultIndexerDependencyCalculator implements IManagedDependencyGenerator { - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) - */ - public IResource[] findDependencies(IResource resource, IProject project) { - PathCollector pathCollector = new PathCollector(); - ICSearchScope scope = SearchEngine.createWorkspaceScope(); - CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true); - IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager(); - indexManager.performConcurrentJob( - new PatternSearchJob( - (CSearchPattern) pattern, - scope, - pathCollector, - indexManager), - ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, - null, null); - - // We will get back an array of resource names relative to the workspace - String[] deps = pathCollector.getPaths(); - - // Convert them to something useful - List depList = new ArrayList(); - IResource res = null; - IWorkspaceRoot root = null; - if (project != null) { - root = project.getWorkspace().getRoot(); - } - for (int index = 0; index < deps.length; ++index) { - res = root.findMember(deps[index]); - if (res != null) { - depList.add(res); - } - } - - return (IResource[]) depList.toArray(new IResource[depList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() - */ - public int getCalculatorType() { - // Tell the - return TYPE_EXTERNAL; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() - */ - public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { - // There is no command - return null; - } -} +/******************************************************************************* + * 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.managedbuilder.makegen.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.search.ICSearchConstants; +import org.eclipse.cdt.core.search.ICSearchScope; +import org.eclipse.cdt.core.search.SearchEngine; +import org.eclipse.cdt.internal.core.search.PathCollector; +import org.eclipse.cdt.internal.core.search.PatternSearchJob; +import org.eclipse.cdt.internal.core.search.indexing.IndexManager; +import org.eclipse.cdt.internal.core.search.matching.CSearchPattern; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; + +/** + * @since 2.0 + */ +public class DefaultIndexerDependencyCalculator implements IManagedDependencyGenerator { + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) + */ + public IResource[] findDependencies(IResource resource, IProject project) { + PathCollector pathCollector = new PathCollector(); + ICSearchScope scope = SearchEngine.createWorkspaceScope(); + CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true); + IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager(); + indexManager.performConcurrentJob( + new PatternSearchJob( + (CSearchPattern) pattern, + scope, + pathCollector, + indexManager), + ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, + null, null); + + // We will get back an array of resource names relative to the workspace + String[] deps = pathCollector.getPaths(); + + // Convert them to something useful + List depList = new ArrayList(); + IResource res = null; + IWorkspaceRoot root = null; + if (project != null) { + root = project.getWorkspace().getRoot(); + } + for (int index = 0; index < deps.length; ++index) { + res = root.findMember(deps[index]); + if (res != null) { + depList.add(res); + } + } + + return (IResource[]) depList.toArray(new IResource[depList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() + */ + public int getCalculatorType() { + // Tell the + return TYPE_EXTERNAL; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() + */ + public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { + // There is no command + return null; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml index a823ca17d7e..dc07ebaf913 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml @@ -1,2969 +1,2969 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildConfigAction.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildConfigAction.java index 69950b13a26..e72eba8bd0b 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildConfigAction.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildConfigAction.java @@ -1,64 +1,64 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.ui.actions; - -import java.util.*; - -import org.eclipse.cdt.managedbuilder.core.*; -import org.eclipse.core.resources.IProject; -import org.eclipse.jface.action.Action; - -/** - * Action which changes active build configuration of the current project to - * the given one. - */ -public class BuildConfigAction extends Action { - - private String fConfigName = null; - private HashSet fProjects = null; - - /** - * Constructs the action. - * @param projects List of selected managed-built projects - * @param configName Build configuration name - * @param accel Number to be used as accelerator - */ - public BuildConfigAction(HashSet projects, String configName, String displayName, int accel) { - super("&" + accel + " " + displayName); //$NON-NLS-1$ //$NON-NLS-2$ - fProjects = projects; - fConfigName = configName; - } - - - - /** - * @see org.eclipse.jface.action.IAction#run() - */ - public void run() { - Iterator iter = fProjects.iterator(); - while (iter.hasNext()) { - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo((IProject)iter.next()); - if (info != null && info.isValid()) { - IConfiguration[] configs = info.getManagedProject().getConfigurations(); - int i = 0; - for (; i < configs.length; i++) { - if (configs[i].getName().equals(fConfigName)) { - break; - } - } - if (i != configs.length) { - info.setDefaultConfiguration(configs[i]); - info.setSelectedConfiguration(configs[i]); - } - } - } - } -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.ui.actions; + +import java.util.*; + +import org.eclipse.cdt.managedbuilder.core.*; +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.action.Action; + +/** + * Action which changes active build configuration of the current project to + * the given one. + */ +public class BuildConfigAction extends Action { + + private String fConfigName = null; + private HashSet fProjects = null; + + /** + * Constructs the action. + * @param projects List of selected managed-built projects + * @param configName Build configuration name + * @param accel Number to be used as accelerator + */ + public BuildConfigAction(HashSet projects, String configName, String displayName, int accel) { + super("&" + accel + " " + displayName); //$NON-NLS-1$ //$NON-NLS-2$ + fProjects = projects; + fConfigName = configName; + } + + + + /** + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + Iterator iter = fProjects.iterator(); + while (iter.hasNext()) { + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo((IProject)iter.next()); + if (info != null && info.isValid()) { + IConfiguration[] configs = info.getManagedProject().getConfigurations(); + int i = 0; + for (; i < configs.length; i++) { + if (configs[i].getName().equals(fConfigName)) { + break; + } + } + if (i != configs.length) { + info.setDefaultConfiguration(configs[i]); + info.setSelectedConfiguration(configs[i]); + } + } + } + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/ChangeBuildConfigActionBase.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/ChangeBuildConfigActionBase.java index 361bafd5b56..281648b8ffa 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/ChangeBuildConfigActionBase.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/ChangeBuildConfigActionBase.java @@ -1,215 +1,215 @@ -/******************************************************************************* - * Copyright (c) 2006 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.managedbuilder.ui.actions; - -import java.util.*; - -import org.eclipse.cdt.core.model.*; -import org.eclipse.cdt.managedbuilder.core.*; -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.action.*; -import org.eclipse.jface.viewers.*; -import org.eclipse.swt.widgets.*; - -/** - * Base class for build configuration actions. - */ -public class ChangeBuildConfigActionBase { - - /** - * List of selected managed-built projects - */ - protected HashSet fProjects = new HashSet(); - - /** - * Fills the menu with build configurations which are common for all selected projects - * @param menu The menu to fill - */ - protected void fillMenu(Menu menu) { - if (menu == null) { - // This should not happen - return; - } - - MenuItem[] items = menu.getItems(); - for (int i = 0; i < items.length; i++) { - items[i].dispose(); - } - - TreeSet configNames = new TreeSet(); - Iterator projIter = fProjects.iterator(); - String sCurrentConfig = null; - boolean bCurrentConfig = true; - while (projIter.hasNext()) { - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo((IProject)projIter.next()); - if (info != null && info.isValid()) { - if (bCurrentConfig) { - String sNewConfig = info.getDefaultConfiguration().getName(); - if (sCurrentConfig == null) { - sCurrentConfig = sNewConfig; - } - else { - if (!sCurrentConfig.equals(sNewConfig)) { - bCurrentConfig = false; - } - } - } - IConfiguration[] configs = info.getManagedProject().getConfigurations(); - for (int i = 0; i < configs.length; i++) { - configNames.add(configs[i].getName()); - } - } - } - - Iterator confIter = configNames.iterator(); - int accel = 0; - while (confIter.hasNext()) { - String sName = (String)confIter.next(); - String sDesc = null; - projIter = fProjects.iterator(); - boolean commonName = true; - boolean commonDesc = true; - boolean firstProj = true; - while (projIter.hasNext()) { - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo((IProject)projIter.next()); - if (info != null && info.isValid()) { - IConfiguration[] configs = info.getManagedProject().getConfigurations(); - int i = 0; - for (; i < configs.length; i++) { - if (configs[i].getName().equals(sName)) { - String sNewDesc = configs[i].getDescription(); - if (sNewDesc.equals("")) { //$NON-NLS-1$ - sNewDesc = null; - } - if (commonDesc) { - if (firstProj) { - sDesc = sNewDesc; - firstProj = false; - } else if (sNewDesc == null && sDesc != null || sNewDesc != null && !sNewDesc.equals(sDesc)) { - commonDesc = false; - } - } - break; - } - } - if (i == configs.length) { - commonName = false; - break; - } - } - } - if (commonName) { - StringBuffer builder = new StringBuffer(sName); - if (commonDesc) { - if (sDesc != null) { - builder.append(" ("); //$NON-NLS-1$ - builder.append(sDesc); - builder.append(")"); //$NON-NLS-1$ - } - } else { - builder.append(" (...)"); //$NON-NLS-1$ - } - - IAction action = new BuildConfigAction(fProjects, sName, builder.toString(), accel + 1); - if (bCurrentConfig && sCurrentConfig.equals(sName)) { - action.setChecked(true); - } - ActionContributionItem item = new ActionContributionItem(action); - item.fill(menu, -1); - accel++; - } - } - } - - /** - * selectionChanged() event handler. Fills the list of managed-built projects - * based on the selection. If some non-managed-built projects are selected, - * disables the action. - * @param action The action - * @param selection The selection - */ - protected void onSelectionChanged(IAction action, ISelection selection) { - fProjects.clear(); - - if (!action.isEnabled()) { - return; - } - - boolean found = false; - if (selection != null && selection instanceof IStructuredSelection) { - Iterator iter = ((IStructuredSelection)selection).iterator(); - while (iter.hasNext()) { - Object selItem = iter.next(); - IProject project = null; - if (selItem instanceof ICElement) { - ICProject cproject = ((ICElement)selItem).getCProject(); - if (cproject != null) { - project = cproject.getProject(); - } - } - else if (selItem instanceof IResource) { - project = ((IResource)selItem).getProject(); - } - if (project != null) { - try { - if (project != null && !project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)) { - project = null; - } - } - catch (CoreException xE) { - // do nothing - } - } - if (project != null) { - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - if (info != null && info.isValid()) { - fProjects.add(project); - } - } else { - found = true; - break; - } - } - } - - boolean enable = false; - if (!found && !fProjects.isEmpty()) { - Iterator iter = fProjects.iterator(); - IProject first = (IProject)iter.next(); - IConfiguration[] firstConfigs = ManagedBuildManager.getBuildInfo(first).getManagedProject().getConfigurations(); - for (int i = 0; i < firstConfigs.length; i++) - { - boolean common = true; - iter = fProjects.iterator(); - while (iter.hasNext()) { - IProject current = (IProject)iter.next(); - IConfiguration[] currentConfigs = ManagedBuildManager.getBuildInfo(current).getManagedProject().getConfigurations(); - int j = 0; - for (; j < currentConfigs.length; j++) { - if (firstConfigs[i].getName().equals(currentConfigs[j].getName())) { - break; - } - } - if (j == currentConfigs.length) { - common = false; - break; - } - } - if (common) { - enable = true; - break; - } - } - } - action.setEnabled(enable); - } -} +/******************************************************************************* + * Copyright (c) 2006 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.managedbuilder.ui.actions; + +import java.util.*; + +import org.eclipse.cdt.core.model.*; +import org.eclipse.cdt.managedbuilder.core.*; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.*; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.widgets.*; + +/** + * Base class for build configuration actions. + */ +public class ChangeBuildConfigActionBase { + + /** + * List of selected managed-built projects + */ + protected HashSet fProjects = new HashSet(); + + /** + * Fills the menu with build configurations which are common for all selected projects + * @param menu The menu to fill + */ + protected void fillMenu(Menu menu) { + if (menu == null) { + // This should not happen + return; + } + + MenuItem[] items = menu.getItems(); + for (int i = 0; i < items.length; i++) { + items[i].dispose(); + } + + TreeSet configNames = new TreeSet(); + Iterator projIter = fProjects.iterator(); + String sCurrentConfig = null; + boolean bCurrentConfig = true; + while (projIter.hasNext()) { + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo((IProject)projIter.next()); + if (info != null && info.isValid()) { + if (bCurrentConfig) { + String sNewConfig = info.getDefaultConfiguration().getName(); + if (sCurrentConfig == null) { + sCurrentConfig = sNewConfig; + } + else { + if (!sCurrentConfig.equals(sNewConfig)) { + bCurrentConfig = false; + } + } + } + IConfiguration[] configs = info.getManagedProject().getConfigurations(); + for (int i = 0; i < configs.length; i++) { + configNames.add(configs[i].getName()); + } + } + } + + Iterator confIter = configNames.iterator(); + int accel = 0; + while (confIter.hasNext()) { + String sName = (String)confIter.next(); + String sDesc = null; + projIter = fProjects.iterator(); + boolean commonName = true; + boolean commonDesc = true; + boolean firstProj = true; + while (projIter.hasNext()) { + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo((IProject)projIter.next()); + if (info != null && info.isValid()) { + IConfiguration[] configs = info.getManagedProject().getConfigurations(); + int i = 0; + for (; i < configs.length; i++) { + if (configs[i].getName().equals(sName)) { + String sNewDesc = configs[i].getDescription(); + if (sNewDesc.equals("")) { //$NON-NLS-1$ + sNewDesc = null; + } + if (commonDesc) { + if (firstProj) { + sDesc = sNewDesc; + firstProj = false; + } else if (sNewDesc == null && sDesc != null || sNewDesc != null && !sNewDesc.equals(sDesc)) { + commonDesc = false; + } + } + break; + } + } + if (i == configs.length) { + commonName = false; + break; + } + } + } + if (commonName) { + StringBuffer builder = new StringBuffer(sName); + if (commonDesc) { + if (sDesc != null) { + builder.append(" ("); //$NON-NLS-1$ + builder.append(sDesc); + builder.append(")"); //$NON-NLS-1$ + } + } else { + builder.append(" (...)"); //$NON-NLS-1$ + } + + IAction action = new BuildConfigAction(fProjects, sName, builder.toString(), accel + 1); + if (bCurrentConfig && sCurrentConfig.equals(sName)) { + action.setChecked(true); + } + ActionContributionItem item = new ActionContributionItem(action); + item.fill(menu, -1); + accel++; + } + } + } + + /** + * selectionChanged() event handler. Fills the list of managed-built projects + * based on the selection. If some non-managed-built projects are selected, + * disables the action. + * @param action The action + * @param selection The selection + */ + protected void onSelectionChanged(IAction action, ISelection selection) { + fProjects.clear(); + + if (!action.isEnabled()) { + return; + } + + boolean found = false; + if (selection != null && selection instanceof IStructuredSelection) { + Iterator iter = ((IStructuredSelection)selection).iterator(); + while (iter.hasNext()) { + Object selItem = iter.next(); + IProject project = null; + if (selItem instanceof ICElement) { + ICProject cproject = ((ICElement)selItem).getCProject(); + if (cproject != null) { + project = cproject.getProject(); + } + } + else if (selItem instanceof IResource) { + project = ((IResource)selItem).getProject(); + } + if (project != null) { + try { + if (project != null && !project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)) { + project = null; + } + } + catch (CoreException xE) { + // do nothing + } + } + if (project != null) { + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + if (info != null && info.isValid()) { + fProjects.add(project); + } + } else { + found = true; + break; + } + } + } + + boolean enable = false; + if (!found && !fProjects.isEmpty()) { + Iterator iter = fProjects.iterator(); + IProject first = (IProject)iter.next(); + IConfiguration[] firstConfigs = ManagedBuildManager.getBuildInfo(first).getManagedProject().getConfigurations(); + for (int i = 0; i < firstConfigs.length; i++) + { + boolean common = true; + iter = fProjects.iterator(); + while (iter.hasNext()) { + IProject current = (IProject)iter.next(); + IConfiguration[] currentConfigs = ManagedBuildManager.getBuildInfo(current).getManagedProject().getConfigurations(); + int j = 0; + for (; j < currentConfigs.length; j++) { + if (firstConfigs[i].getName().equals(currentConfigs[j].getName())) { + break; + } + } + if (j == currentConfigs.length) { + common = false; + break; + } + } + if (common) { + enable = true; + break; + } + } + } + action.setEnabled(enable); + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/NewConfigurationDialog.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/NewConfigurationDialog.java index 49e21bee17f..1560fdf86f0 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/NewConfigurationDialog.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/NewConfigurationDialog.java @@ -1,572 +1,572 @@ -/******************************************************************************* - * Copyright (c) 2003, 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 Rational Software - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.ui.properties; - -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; - -import java.util.ArrayList; -import java.util.Iterator; -import org.eclipse.cdt.internal.ui.dialogs.StatusDialog; -import org.eclipse.cdt.internal.ui.dialogs.StatusInfo; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.internal.ui.ManagedBuilderUIMessages; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -public class NewConfigurationDialog extends StatusDialog { - // String constants - private static final String PREFIX = "NewConfiguration"; //$NON-NLS-1$ - private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ - private static final String ERROR = PREFIX + ".error"; //$NON-NLS-1$ - private static final String NAME = LABEL + ".name"; //$NON-NLS-1$ - private static final String GROUP = LABEL + ".group"; //$NON-NLS-1$ - private static final String COPY = LABEL + ".copy"; //$NON-NLS-1$ - private static final String CLONE = LABEL + ".clone"; //$NON-NLS-1$ - private static final String SHOWALL = LABEL + ".showall"; //$NON-NLS-1$ - private static final String DUPLICATE = ERROR + ".duplicateName"; //$NON-NLS-1$ - private static final String CASE = ERROR + ".caseName"; //$NON-NLS-1$ - private static final String INVALID = ERROR + ".invalidName"; //$NON-NLS-1$ - private static final String DESCRIPTION = LABEL + ".description"; //$NON-NLS-1$ - - // Widgets - private Button btnClone; - private Button btnCopy; - private Text configName; - private Text configDescription; - private Combo copyConfigSelector; - private Combo cloneConfigSelector; - private Button btnShowAll; - - // Bookeeping - private boolean clone; - /** Default configurations defined in the toolchain description */ - private IConfiguration[] defaultConfigs; - /** Configurations defined in the target */ - private IConfiguration[] definedConfigs; - private IConfiguration parentConfig; - private IManagedProject managedProject; - private String newName; - private String newDescription; - /** A list containing config names that have been defined but not added to the target */ - final private ArrayList reservedNames; - final private String title; - - - /** - * @param parentShell - * @param managedTarget - * @param nameList A list of names (Strings) that have been added by the user but have not yet been added to the target - * @param title The title of the dialog - */ - protected NewConfigurationDialog(Shell parentShell, IManagedProject managedProject, String title) { - super(parentShell); - this.title = title; - setShellStyle(getShellStyle()|SWT.RESIZE); - newName = new String(); - newDescription = new String(); - parentConfig = null; - this.managedProject = managedProject; - reservedNames = new ArrayList(); - // The default behaviour is to clone the settings - clone = true; - - // Populate the list of default and defined configurations - definedConfigs = managedProject.getConfigurations(); - IProjectType projectType = managedProject.getProjectType(); - defaultConfigs = projectType.getConfigurations(); - - // Get the defined configuration names - for (int i = 0; i < definedConfigs.length; i++) { - reservedNames.add(definedConfigs[i].getName()); - } - - } - - /* (non-Javadoc) - * Method declared on Dialog. Cache the name and base config selections. - * We don't have to worry that the index or name is wrong because we - * enable the OK button IFF those conditions are met. - */ - protected void buttonPressed(int buttonId) { - if (buttonId == IDialogConstants.OK_ID) { - String description = new String(); - String nameAndDescription = new String(); - String baseConfigNameAndDescription = new String(); - - newName = configName.getText().trim(); - newDescription = configDescription.getText().trim(); - - if (clone) { - baseConfigNameAndDescription = cloneConfigSelector.getItem(cloneConfigSelector.getSelectionIndex()); - for (int i = 0; i < definedConfigs.length; i++) { - IConfiguration config = definedConfigs[i]; - description = config.getDescription(); - - if( (description == null) || (description.equals("")) ){ //$NON-NLS-1$ - nameAndDescription = config.getName(); - } else { - nameAndDescription = config.getName() + "( " + description + " )"; //$NON-NLS-1$ //$NON-NLS-2$ - } - if (nameAndDescription.equals(baseConfigNameAndDescription)) { - parentConfig = config; - break; - } - } - } else { - // Get the parent config out of the default config list - baseConfigNameAndDescription = copyConfigSelector.getItem(copyConfigSelector.getSelectionIndex()); - for (int i = 0; i < defaultConfigs.length; i++) { - IConfiguration config = defaultConfigs[i]; - description = config.getDescription(); - - if( (description == null) || (description.equals("")) ) { //$NON-NLS-1$ - nameAndDescription = config.getName(); - } else { - nameAndDescription = config.getName() + "( " + description + " )"; //$NON-NLS-1$ //$NON-NLS-2$ - } - if (nameAndDescription.equals(baseConfigNameAndDescription)) { - parentConfig = config; - break; - } - } - } - } else { - newName = null; - newDescription = null; - parentConfig = null; - } - super.buttonPressed(buttonId); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) - */ - protected void configureShell(Shell shell) { - super.configureShell(shell); - if (title != null) - shell.setText(title); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) - */ - protected void createButtonsForButtonBar(Composite parent) { - super.createButtonsForButtonBar(parent); - configName.setFocus(); - if (configName != null) { - configName.setText(newName); - } - validateState(); - } - - protected Control createDialogArea(Composite parent) { - - Composite composite = new Composite(parent, SWT.NULL); - composite.setFont(parent.getFont()); - composite.setLayout(new GridLayout(3, false)); - composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Create a group for the name & description - - final Group group1 = new Group(composite, SWT.NONE); - group1.setFont(composite.getFont()); - GridLayout layout1 = new GridLayout(3, false); - group1.setLayout(layout1); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 3; - group1.setLayoutData(gd); - - // Add a label and a text widget for Configuration's name - final Label nameLabel = new Label(group1, SWT.LEFT); - nameLabel.setFont(parent.getFont()); - nameLabel.setText(ManagedBuilderUIMessages.getResourceString(NAME)); - - gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 1; - gd.grabExcessHorizontalSpace = false; - nameLabel.setLayoutData(gd); - - configName = new Text(group1, SWT.SINGLE | SWT.BORDER); - configName.setFont(group1.getFont()); - configName.setText(getNewName()); - configName.setFocus(); - gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - gd.horizontalSpan = 2; - gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - configName.setLayoutData(gd); - configName.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - validateState(); - } - }); - -// Add a label and a text widget for Configuration's description - final Label descriptionLabel = new Label(group1, SWT.LEFT); - descriptionLabel.setFont(parent.getFont()); - descriptionLabel.setText(ManagedBuilderUIMessages.getResourceString(DESCRIPTION)); - - gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 1; - gd.grabExcessHorizontalSpace = false; - descriptionLabel.setLayoutData(gd); - configDescription = new Text(group1, SWT.SINGLE | SWT.BORDER); - configDescription.setFont(group1.getFont()); - configDescription.setText(getNewDescription()); - configDescription.setFocus(); - - gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - gd.horizontalSpan = 2; - gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - configDescription.setLayoutData(gd); - - // Create a group for the radio buttons - - final Group group = new Group(composite, SWT.NONE); - group.setFont(composite.getFont()); - group.setText(ManagedBuilderUIMessages.getResourceString(GROUP)); - GridLayout layout = new GridLayout(3, false); - group.setLayout(layout); - gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 3; - group.setLayoutData(gd); - - SelectionListener radioListener = new SelectionAdapter() { - public void widgetSelected(SelectionEvent event) { - clone = btnClone.getSelection(); - updateComboState(); - } - }; - // Add a radio button and combo box to copy from default config - btnCopy = new Button(group, SWT.RADIO); - btnCopy.setFont(group.getFont()); - btnCopy.setText(ManagedBuilderUIMessages.getResourceString(COPY)); - setButtonLayoutData(btnCopy); - btnCopy.addSelectionListener(radioListener); - - copyConfigSelector = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); - copyConfigSelector.setFont(group.getFont()); - int index = copyConfigSelector.indexOf(newName); - copyConfigSelector.select(index < 0 ? 0 : index); - gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - gd.horizontalSpan = 2; - gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - copyConfigSelector.setLayoutData(gd); - copyConfigSelector.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - validateState(); - } - }); - copyConfigSelector.setEnabled(false); - - // Create a radio button and combo for clonable configs - btnClone = new Button(group, SWT.RADIO); - btnClone.setFont(group.getFont()); - btnClone.setText(ManagedBuilderUIMessages.getResourceString(CLONE)); - setButtonLayoutData(btnClone); - btnClone.addSelectionListener(radioListener); - btnClone.setSelection(true); - - cloneConfigSelector = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); - cloneConfigSelector.setFont(group.getFont()); - cloneConfigSelector.setItems(getDefinedConfigNamesAndDescriptions()); - index = cloneConfigSelector.indexOf(newName); - cloneConfigSelector.select(index < 0 ? 0 : index); - gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); - gd.horizontalSpan = 2; - gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; - cloneConfigSelector.setLayoutData(gd); - cloneConfigSelector.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - validateState(); - } - }); - - // Create a "show all configurations" button - btnShowAll = new Button(composite, SWT.CHECK); - btnShowAll.setFont(composite.getFont()); - btnShowAll.setText(ManagedBuilderUIMessages.getResourceString(SHOWALL)); - gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 1; - btnShowAll.setLayoutData(gd); - btnShowAll.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - updateDefaultConfigs(); - } - }); - - updateComboState(); - updateDefaultConfigs(); - - return composite; - } - - - /** - * @return the IConfiguration the user selected as - * the parent of the new configuration. - */ - public IConfiguration getParentConfiguration() { - return parentConfig; - } - - /** - * updates the list of default configurations - */ - private void updateDefaultConfigs(){ - IConfiguration cfgs[] = managedProject.getProjectType().getConfigurations(); - boolean showAll = btnShowAll != null ? btnShowAll.getSelection() : false; - - if(showAll) - defaultConfigs = cfgs; - else { - ArrayList list = new ArrayList(); - for (int i = 0; i < cfgs.length; i++) { - if (cfgs[i].isSupported()) { - IToolChain tc = cfgs[i].getToolChain(); - - // Determine if the tool-chain has 'convertToId' attribute. - // If so, do not add this configuration to the list. - if (!tc.getConvertToId().equals("")) - continue; - list.add(cfgs[i]); - } - } - defaultConfigs = (IConfiguration[]) list - .toArray(new IConfiguration[list.size()]); - } - - if(defaultConfigs.length != 0){ - String namesAndDescriptions[] = new String[defaultConfigs.length]; - for (int i = 0; i < defaultConfigs.length; ++i) { - if ( (defaultConfigs[i].getDescription() == null) || defaultConfigs[i].getDescription().equals("")) //$NON-NLS-1$ - namesAndDescriptions[i] = defaultConfigs[i].getName(); - else - namesAndDescriptions[i] = defaultConfigs[i].getName() + "( " + defaultConfigs[i].getDescription() + " )"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - int selectionIndex = copyConfigSelector.getSelectionIndex(); - String oldSelection = null; - if(selectionIndex != -1) - oldSelection = copyConfigSelector.getItem(selectionIndex); - - copyConfigSelector.setItems(namesAndDescriptions); - if(oldSelection != null) - selectionIndex = copyConfigSelector.indexOf(oldSelection); - if(selectionIndex == -1) - selectionIndex = 0; - copyConfigSelector.select(selectionIndex); - } - else{ - copyConfigSelector.removeAll(); - } - validateState(); - } - - /* - * Returns the array of configuration names defined for this managed project. - * This list will be used to populate the list of configurations to - * clone. - */ - private String [] getDefinedConfigNamesAndDescriptions() { - String [] namesAndDescriptions = new String[definedConfigs.length]; - for (int index = 0; index < definedConfigs.length; ++index) { - IConfiguration config = definedConfigs[index]; - if ( (config.getDescription() == null) || config.getDescription().equals("")) //$NON-NLS-1$ - namesAndDescriptions[index] = config.getName(); - else - namesAndDescriptions[index] = config.getName() + "( " + config.getDescription() +" )"; //$NON-NLS-1$ //$NON-NLS-2$ - } - return namesAndDescriptions; - } - - /** - * @return String containing the name chosen by the user for the - * new configuration. - */ - public String getNewName() { - return newName; - } - - /* (non-Javadoc) - * Answers true if the name entered by the user clashes - * with an existing configuration name. - * - * @param newName - * @return - */ - protected boolean isDuplicateName(String newName) { - // Return true if there is already a config of that name defined - for (int index = 0; index < definedConfigs.length; index++) { - IConfiguration configuration = definedConfigs[index]; - if (configuration.getName().equals(newName)) { - return true; - } - } - if (reservedNames.contains(newName)) { - return true; - } - return false; - } - - /* (non-Javadoc) - * Answers true if the name entered by the user differs - * only in case from an existing name. - * - * @param newName - * @return - */ - protected boolean isSimilarName(String newName) { - // Return true if there is already a config of that name defined on the target - for (int index = 0; index < definedConfigs.length; index++) { - IConfiguration configuration = definedConfigs[index]; - if (configuration.getName().equalsIgnoreCase(newName)) { - return true; - } - } - Iterator iter = reservedNames.listIterator(); - while (iter.hasNext()) { - if (((String)iter.next()).equalsIgnoreCase(newName)) { - return true; - } - } - return false; - } - - /* (non-Javadoc) - * Radio button selection event handler calls this helper method to - * enable or disable the radio buttons. - */ - protected void updateComboState() { - cloneConfigSelector.setEnabled(clone); - copyConfigSelector.setEnabled(!clone); - btnShowAll.setVisible(!clone); - validateState(); - } - - /* (non-Javadoc) - * Checks the argument for leading whitespaces and invalid directory name characters. - * @param name - * @return true is the name is a valid directory name with no whitespaces - */ - private boolean validateName(String name) { - // Names must be at least one character in length - if (name.trim().length() == 0) - return false; - - // Iterate over the name checking for bad characters - char[] chars = name.toCharArray(); - // No whitespaces at the start of a name - if (Character.isWhitespace(chars[0])) { - return false; - } - for (int index = 0; index < chars.length; ++index) { - // Config name must be a valid dir name too, so we ban "\ / : * ? " < >" in the names - if (!Character.isLetterOrDigit(chars[index])) { - switch (chars[index]) { - case '/': - case '\\': - case ':': - case '*': - case '?': - case '\"': - case '<': - case '>': - return false; - default: - break; - } - } - } - return true; - } - /* (non-Javadoc) - * Update the status message and button state based on the input selected - * by the user - * - */ - private void validateState() { - StatusInfo status= new StatusInfo(); - String currentName = configName.getText(); - // Trim trailing whitespace - while (currentName.length() > 0 && Character.isWhitespace(currentName.charAt(currentName.length()-1))) { - currentName = currentName.substring(0, currentName.length()-1); - } - // Make sure that the name is at least one character in length - if (currentName.length() == 0) { - // No error message, but cannot select OK - status.setError(""); //$NON-NLS-1$ - } else if(clone ? definedConfigs.length == 0 : defaultConfigs.length == 0) { - // Not an error - status.setError(""); //$NON-NLS-1$ - // Make sure the name is not a duplicate - } else if (isDuplicateName(currentName)) { - status.setError(ManagedBuilderUIMessages.getFormattedString(DUPLICATE, currentName)); - } else if (isSimilarName(currentName)) { - status.setError(ManagedBuilderUIMessages.getFormattedString(CASE, currentName)); - } else if (!validateName(currentName)) { - // TODO Create a decent I18N string to describe this problem - status.setError(ManagedBuilderUIMessages.getFormattedString(INVALID, currentName)); - } - - updateStatus(status); - return; - } - public String getNewDescription() { - return newDescription; - } - - /** - * Create a new configuration, using the values currently set in - * the dialog. - */ - public IConfiguration newConfiguration(IManagedBuildInfo info) { - - String newId = null; - IConfiguration newConfig; - - if (parentConfig.isExtensionElement()) { - // If parent config is an extension element, - // Create ID for the new component based on the parentConfig's id and random component - newId = ManagedBuildManager.calculateChildId(parentConfig.getId(), null); - newConfig = info.getManagedProject().createConfiguration(parentConfig, newId); - } else { - // If parent config is not an extension element, then - // Create ID for the new component based on the parentConfig's parent id and random component - newId = ManagedBuildManager.calculateChildId(parentConfig.getParent().getId(), null); - newConfig = info.getManagedProject().createConfigurationClone(parentConfig, newId); - } - - newConfig.setName(newName); - newConfig.setDescription(newDescription); - newConfig.setArtifactName(info.getManagedProject().getDefaultArtifactName()); - return newConfig; - } - -} +/******************************************************************************* + * Copyright (c) 2003, 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 Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.ui.properties; + +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; + +import java.util.ArrayList; +import java.util.Iterator; +import org.eclipse.cdt.internal.ui.dialogs.StatusDialog; +import org.eclipse.cdt.internal.ui.dialogs.StatusInfo; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.internal.ui.ManagedBuilderUIMessages; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class NewConfigurationDialog extends StatusDialog { + // String constants + private static final String PREFIX = "NewConfiguration"; //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ + private static final String ERROR = PREFIX + ".error"; //$NON-NLS-1$ + private static final String NAME = LABEL + ".name"; //$NON-NLS-1$ + private static final String GROUP = LABEL + ".group"; //$NON-NLS-1$ + private static final String COPY = LABEL + ".copy"; //$NON-NLS-1$ + private static final String CLONE = LABEL + ".clone"; //$NON-NLS-1$ + private static final String SHOWALL = LABEL + ".showall"; //$NON-NLS-1$ + private static final String DUPLICATE = ERROR + ".duplicateName"; //$NON-NLS-1$ + private static final String CASE = ERROR + ".caseName"; //$NON-NLS-1$ + private static final String INVALID = ERROR + ".invalidName"; //$NON-NLS-1$ + private static final String DESCRIPTION = LABEL + ".description"; //$NON-NLS-1$ + + // Widgets + private Button btnClone; + private Button btnCopy; + private Text configName; + private Text configDescription; + private Combo copyConfigSelector; + private Combo cloneConfigSelector; + private Button btnShowAll; + + // Bookeeping + private boolean clone; + /** Default configurations defined in the toolchain description */ + private IConfiguration[] defaultConfigs; + /** Configurations defined in the target */ + private IConfiguration[] definedConfigs; + private IConfiguration parentConfig; + private IManagedProject managedProject; + private String newName; + private String newDescription; + /** A list containing config names that have been defined but not added to the target */ + final private ArrayList reservedNames; + final private String title; + + + /** + * @param parentShell + * @param managedTarget + * @param nameList A list of names (Strings) that have been added by the user but have not yet been added to the target + * @param title The title of the dialog + */ + protected NewConfigurationDialog(Shell parentShell, IManagedProject managedProject, String title) { + super(parentShell); + this.title = title; + setShellStyle(getShellStyle()|SWT.RESIZE); + newName = new String(); + newDescription = new String(); + parentConfig = null; + this.managedProject = managedProject; + reservedNames = new ArrayList(); + // The default behaviour is to clone the settings + clone = true; + + // Populate the list of default and defined configurations + definedConfigs = managedProject.getConfigurations(); + IProjectType projectType = managedProject.getProjectType(); + defaultConfigs = projectType.getConfigurations(); + + // Get the defined configuration names + for (int i = 0; i < definedConfigs.length; i++) { + reservedNames.add(definedConfigs[i].getName()); + } + + } + + /* (non-Javadoc) + * Method declared on Dialog. Cache the name and base config selections. + * We don't have to worry that the index or name is wrong because we + * enable the OK button IFF those conditions are met. + */ + protected void buttonPressed(int buttonId) { + if (buttonId == IDialogConstants.OK_ID) { + String description = new String(); + String nameAndDescription = new String(); + String baseConfigNameAndDescription = new String(); + + newName = configName.getText().trim(); + newDescription = configDescription.getText().trim(); + + if (clone) { + baseConfigNameAndDescription = cloneConfigSelector.getItem(cloneConfigSelector.getSelectionIndex()); + for (int i = 0; i < definedConfigs.length; i++) { + IConfiguration config = definedConfigs[i]; + description = config.getDescription(); + + if( (description == null) || (description.equals("")) ){ //$NON-NLS-1$ + nameAndDescription = config.getName(); + } else { + nameAndDescription = config.getName() + "( " + description + " )"; //$NON-NLS-1$ //$NON-NLS-2$ + } + if (nameAndDescription.equals(baseConfigNameAndDescription)) { + parentConfig = config; + break; + } + } + } else { + // Get the parent config out of the default config list + baseConfigNameAndDescription = copyConfigSelector.getItem(copyConfigSelector.getSelectionIndex()); + for (int i = 0; i < defaultConfigs.length; i++) { + IConfiguration config = defaultConfigs[i]; + description = config.getDescription(); + + if( (description == null) || (description.equals("")) ) { //$NON-NLS-1$ + nameAndDescription = config.getName(); + } else { + nameAndDescription = config.getName() + "( " + description + " )"; //$NON-NLS-1$ //$NON-NLS-2$ + } + if (nameAndDescription.equals(baseConfigNameAndDescription)) { + parentConfig = config; + break; + } + } + } + } else { + newName = null; + newDescription = null; + parentConfig = null; + } + super.buttonPressed(buttonId); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + protected void configureShell(Shell shell) { + super.configureShell(shell); + if (title != null) + shell.setText(title); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) + */ + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + configName.setFocus(); + if (configName != null) { + configName.setText(newName); + } + validateState(); + } + + protected Control createDialogArea(Composite parent) { + + Composite composite = new Composite(parent, SWT.NULL); + composite.setFont(parent.getFont()); + composite.setLayout(new GridLayout(3, false)); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Create a group for the name & description + + final Group group1 = new Group(composite, SWT.NONE); + group1.setFont(composite.getFont()); + GridLayout layout1 = new GridLayout(3, false); + group1.setLayout(layout1); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + group1.setLayoutData(gd); + + // Add a label and a text widget for Configuration's name + final Label nameLabel = new Label(group1, SWT.LEFT); + nameLabel.setFont(parent.getFont()); + nameLabel.setText(ManagedBuilderUIMessages.getResourceString(NAME)); + + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 1; + gd.grabExcessHorizontalSpace = false; + nameLabel.setLayoutData(gd); + + configName = new Text(group1, SWT.SINGLE | SWT.BORDER); + configName.setFont(group1.getFont()); + configName.setText(getNewName()); + configName.setFocus(); + gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + gd.horizontalSpan = 2; + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + configName.setLayoutData(gd); + configName.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateState(); + } + }); + +// Add a label and a text widget for Configuration's description + final Label descriptionLabel = new Label(group1, SWT.LEFT); + descriptionLabel.setFont(parent.getFont()); + descriptionLabel.setText(ManagedBuilderUIMessages.getResourceString(DESCRIPTION)); + + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 1; + gd.grabExcessHorizontalSpace = false; + descriptionLabel.setLayoutData(gd); + configDescription = new Text(group1, SWT.SINGLE | SWT.BORDER); + configDescription.setFont(group1.getFont()); + configDescription.setText(getNewDescription()); + configDescription.setFocus(); + + gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + gd.horizontalSpan = 2; + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + configDescription.setLayoutData(gd); + + // Create a group for the radio buttons + + final Group group = new Group(composite, SWT.NONE); + group.setFont(composite.getFont()); + group.setText(ManagedBuilderUIMessages.getResourceString(GROUP)); + GridLayout layout = new GridLayout(3, false); + group.setLayout(layout); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + group.setLayoutData(gd); + + SelectionListener radioListener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + clone = btnClone.getSelection(); + updateComboState(); + } + }; + // Add a radio button and combo box to copy from default config + btnCopy = new Button(group, SWT.RADIO); + btnCopy.setFont(group.getFont()); + btnCopy.setText(ManagedBuilderUIMessages.getResourceString(COPY)); + setButtonLayoutData(btnCopy); + btnCopy.addSelectionListener(radioListener); + + copyConfigSelector = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); + copyConfigSelector.setFont(group.getFont()); + int index = copyConfigSelector.indexOf(newName); + copyConfigSelector.select(index < 0 ? 0 : index); + gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + gd.horizontalSpan = 2; + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + copyConfigSelector.setLayoutData(gd); + copyConfigSelector.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + validateState(); + } + }); + copyConfigSelector.setEnabled(false); + + // Create a radio button and combo for clonable configs + btnClone = new Button(group, SWT.RADIO); + btnClone.setFont(group.getFont()); + btnClone.setText(ManagedBuilderUIMessages.getResourceString(CLONE)); + setButtonLayoutData(btnClone); + btnClone.addSelectionListener(radioListener); + btnClone.setSelection(true); + + cloneConfigSelector = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); + cloneConfigSelector.setFont(group.getFont()); + cloneConfigSelector.setItems(getDefinedConfigNamesAndDescriptions()); + index = cloneConfigSelector.indexOf(newName); + cloneConfigSelector.select(index < 0 ? 0 : index); + gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL); + gd.horizontalSpan = 2; + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; + cloneConfigSelector.setLayoutData(gd); + cloneConfigSelector.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + validateState(); + } + }); + + // Create a "show all configurations" button + btnShowAll = new Button(composite, SWT.CHECK); + btnShowAll.setFont(composite.getFont()); + btnShowAll.setText(ManagedBuilderUIMessages.getResourceString(SHOWALL)); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 1; + btnShowAll.setLayoutData(gd); + btnShowAll.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateDefaultConfigs(); + } + }); + + updateComboState(); + updateDefaultConfigs(); + + return composite; + } + + + /** + * @return the IConfiguration the user selected as + * the parent of the new configuration. + */ + public IConfiguration getParentConfiguration() { + return parentConfig; + } + + /** + * updates the list of default configurations + */ + private void updateDefaultConfigs(){ + IConfiguration cfgs[] = managedProject.getProjectType().getConfigurations(); + boolean showAll = btnShowAll != null ? btnShowAll.getSelection() : false; + + if(showAll) + defaultConfigs = cfgs; + else { + ArrayList list = new ArrayList(); + for (int i = 0; i < cfgs.length; i++) { + if (cfgs[i].isSupported()) { + IToolChain tc = cfgs[i].getToolChain(); + + // Determine if the tool-chain has 'convertToId' attribute. + // If so, do not add this configuration to the list. + if (!tc.getConvertToId().equals("")) + continue; + list.add(cfgs[i]); + } + } + defaultConfigs = (IConfiguration[]) list + .toArray(new IConfiguration[list.size()]); + } + + if(defaultConfigs.length != 0){ + String namesAndDescriptions[] = new String[defaultConfigs.length]; + for (int i = 0; i < defaultConfigs.length; ++i) { + if ( (defaultConfigs[i].getDescription() == null) || defaultConfigs[i].getDescription().equals("")) //$NON-NLS-1$ + namesAndDescriptions[i] = defaultConfigs[i].getName(); + else + namesAndDescriptions[i] = defaultConfigs[i].getName() + "( " + defaultConfigs[i].getDescription() + " )"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + int selectionIndex = copyConfigSelector.getSelectionIndex(); + String oldSelection = null; + if(selectionIndex != -1) + oldSelection = copyConfigSelector.getItem(selectionIndex); + + copyConfigSelector.setItems(namesAndDescriptions); + if(oldSelection != null) + selectionIndex = copyConfigSelector.indexOf(oldSelection); + if(selectionIndex == -1) + selectionIndex = 0; + copyConfigSelector.select(selectionIndex); + } + else{ + copyConfigSelector.removeAll(); + } + validateState(); + } + + /* + * Returns the array of configuration names defined for this managed project. + * This list will be used to populate the list of configurations to + * clone. + */ + private String [] getDefinedConfigNamesAndDescriptions() { + String [] namesAndDescriptions = new String[definedConfigs.length]; + for (int index = 0; index < definedConfigs.length; ++index) { + IConfiguration config = definedConfigs[index]; + if ( (config.getDescription() == null) || config.getDescription().equals("")) //$NON-NLS-1$ + namesAndDescriptions[index] = config.getName(); + else + namesAndDescriptions[index] = config.getName() + "( " + config.getDescription() +" )"; //$NON-NLS-1$ //$NON-NLS-2$ + } + return namesAndDescriptions; + } + + /** + * @return String containing the name chosen by the user for the + * new configuration. + */ + public String getNewName() { + return newName; + } + + /* (non-Javadoc) + * Answers true if the name entered by the user clashes + * with an existing configuration name. + * + * @param newName + * @return + */ + protected boolean isDuplicateName(String newName) { + // Return true if there is already a config of that name defined + for (int index = 0; index < definedConfigs.length; index++) { + IConfiguration configuration = definedConfigs[index]; + if (configuration.getName().equals(newName)) { + return true; + } + } + if (reservedNames.contains(newName)) { + return true; + } + return false; + } + + /* (non-Javadoc) + * Answers true if the name entered by the user differs + * only in case from an existing name. + * + * @param newName + * @return + */ + protected boolean isSimilarName(String newName) { + // Return true if there is already a config of that name defined on the target + for (int index = 0; index < definedConfigs.length; index++) { + IConfiguration configuration = definedConfigs[index]; + if (configuration.getName().equalsIgnoreCase(newName)) { + return true; + } + } + Iterator iter = reservedNames.listIterator(); + while (iter.hasNext()) { + if (((String)iter.next()).equalsIgnoreCase(newName)) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * Radio button selection event handler calls this helper method to + * enable or disable the radio buttons. + */ + protected void updateComboState() { + cloneConfigSelector.setEnabled(clone); + copyConfigSelector.setEnabled(!clone); + btnShowAll.setVisible(!clone); + validateState(); + } + + /* (non-Javadoc) + * Checks the argument for leading whitespaces and invalid directory name characters. + * @param name + * @return true is the name is a valid directory name with no whitespaces + */ + private boolean validateName(String name) { + // Names must be at least one character in length + if (name.trim().length() == 0) + return false; + + // Iterate over the name checking for bad characters + char[] chars = name.toCharArray(); + // No whitespaces at the start of a name + if (Character.isWhitespace(chars[0])) { + return false; + } + for (int index = 0; index < chars.length; ++index) { + // Config name must be a valid dir name too, so we ban "\ / : * ? " < >" in the names + if (!Character.isLetterOrDigit(chars[index])) { + switch (chars[index]) { + case '/': + case '\\': + case ':': + case '*': + case '?': + case '\"': + case '<': + case '>': + return false; + default: + break; + } + } + } + return true; + } + /* (non-Javadoc) + * Update the status message and button state based on the input selected + * by the user + * + */ + private void validateState() { + StatusInfo status= new StatusInfo(); + String currentName = configName.getText(); + // Trim trailing whitespace + while (currentName.length() > 0 && Character.isWhitespace(currentName.charAt(currentName.length()-1))) { + currentName = currentName.substring(0, currentName.length()-1); + } + // Make sure that the name is at least one character in length + if (currentName.length() == 0) { + // No error message, but cannot select OK + status.setError(""); //$NON-NLS-1$ + } else if(clone ? definedConfigs.length == 0 : defaultConfigs.length == 0) { + // Not an error + status.setError(""); //$NON-NLS-1$ + // Make sure the name is not a duplicate + } else if (isDuplicateName(currentName)) { + status.setError(ManagedBuilderUIMessages.getFormattedString(DUPLICATE, currentName)); + } else if (isSimilarName(currentName)) { + status.setError(ManagedBuilderUIMessages.getFormattedString(CASE, currentName)); + } else if (!validateName(currentName)) { + // TODO Create a decent I18N string to describe this problem + status.setError(ManagedBuilderUIMessages.getFormattedString(INVALID, currentName)); + } + + updateStatus(status); + return; + } + public String getNewDescription() { + return newDescription; + } + + /** + * Create a new configuration, using the values currently set in + * the dialog. + */ + public IConfiguration newConfiguration(IManagedBuildInfo info) { + + String newId = null; + IConfiguration newConfig; + + if (parentConfig.isExtensionElement()) { + // If parent config is an extension element, + // Create ID for the new component based on the parentConfig's id and random component + newId = ManagedBuildManager.calculateChildId(parentConfig.getId(), null); + newConfig = info.getManagedProject().createConfiguration(parentConfig, newId); + } else { + // If parent config is not an extension element, then + // Create ID for the new component based on the parentConfig's parent id and random component + newId = ManagedBuildManager.calculateChildId(parentConfig.getParent().getId(), null); + newConfig = info.getManagedProject().createConfigurationClone(parentConfig, newId); + } + + newConfig.setName(newName); + newConfig.setDescription(newDescription); + newConfig.setArtifactName(info.getManagedProject().getDefaultArtifactName()); + return newConfig; + } + +}