Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools')
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsBuilder.java79
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsDefaultBuildDirHandler.java155
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsMakefileBuilder.java512
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsPlugin.java324
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectNature.java175
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectPropertyTester.java31
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfo.java431
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfoProvider.java112
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/MakeGenerator.java1374
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/Resources.properties95
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractAutotoolsHandler.java57
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractTargetAction.java93
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AclocalHandler.java37
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoconfHandler.java33
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoheaderHandler.java37
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutomakeHandler.java33
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoreconfHandler.java37
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAclocalAction.java104
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAction.java442
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoconfAction.java57
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoheaderAction.java79
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutomakeAction.java98
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoreconfAction.java78
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeLibtoolizeAction.java78
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.java53
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.properties56
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/LibtoolizeHandler.java37
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureAction.java78
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureHandler.java37
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/SingleInputDialog.java63
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/TwoInputDialog.java111
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseConditionElement.java22
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.java117
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.properties47
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElement.java138
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElifElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElseElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfForElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfIfElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java32
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroDetector.java31
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java39
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java136
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfParser.java1041
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfRootElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java434
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java18
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfErrorHandler.java28
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroDetector.java30
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroValidator.java28
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IMacroDetector.java22
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ITokenConstants.java87
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ParseException.java72
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/Token.java84
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsBuildPropertyPage.java243
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsEditorPropertyPage.java278
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyConstants.java47
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyManager.java61
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.java40
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.properties41
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyPage.java376
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsToolsPropertyPage.java343
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IProjectPropertyListener.java25
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IPropertyChangeManager.java40
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/MarkerGenerator.java155
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/AutotoolsConsole.java27
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CBuildStepsConsole.java27
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CConfigureConsole.java26
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CWordFinder.java283
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/Console.java57
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.java32
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.properties25
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/HTMLPrinter.java116
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/LineBreakingReader.java111
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SingleCharReader.java62
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SubstitutionTextReader.java138
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java80
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/OverlayPreferenceStore.java455
-rw-r--r--autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/StatusInfo.java173
82 files changed, 10797 insertions, 0 deletions
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsBuilder.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsBuilder.java
new file mode 100644
index 0000000000..f51c2b64d7
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsBuilder.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import org.eclipse.cdt.core.settings.model.COutputEntry;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICOutputEntry;
+import org.eclipse.cdt.managedbuilder.core.IBuilder;
+import org.eclipse.cdt.managedbuilder.internal.core.Builder;
+import org.eclipse.cdt.managedbuilder.internal.core.ToolChain;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+
+
+
+// Proxy class for IBuilder to allow overriding of getBuildLocation().
+
+@SuppressWarnings("restriction")
+public class AutotoolsBuilder extends Builder {
+
+ private String buildPath;
+ private IProject project;
+
+ public AutotoolsBuilder(IBuilder builder, IProject project, ToolChain toolChain) {
+ super(toolChain, builder.getId(), builder.getName(), (Builder)builder);
+ this.project = project;
+ }
+
+ protected IProject getProject() {
+ return project;
+ }
+
+
+ public String getBuildPath() {
+ // TODO Auto-generated method stub
+ return buildPath;
+ }
+
+
+ public void setBuildPath(String path) {
+ // TODO Auto-generated method stub
+ this.buildPath = path;
+ }
+
+ public String getCleanBuildTarget() {
+ String target = null;
+ try {
+ target = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+ if (target == null)
+ target = AutotoolsPropertyConstants.CLEAN_MAKE_TARGET_DEFAULT;
+ return target;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IBuilder#getBuildFileGenerator()
+ */
+ public IManagedBuilderMakefileGenerator getBuildFileGenerator() {
+ return new MakeGenerator();
+ }
+
+ /* @override */
+ public ICOutputEntry[] getOutputEntries() {
+ return new ICOutputEntry[]{new COutputEntry(buildPath, null, ICLanguageSettingEntry.VALUE_WORKSPACE_PATH | ICLanguageSettingEntry.RESOLVED)};
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsDefaultBuildDirHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsDefaultBuildDirHandler.java
new file mode 100644
index 0000000000..e1a3e5ae59
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsDefaultBuildDirHandler.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+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.IHoldsOptions;
+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.ITool;
+import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler;
+
+public class AutotoolsDefaultBuildDirHandler extends ManagedOptionValueHandler
+ implements IOptionApplicability {
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler#handleValue(IConfiguration,IToolChain,IOption,String,int)
+ */
+
+ public final static String DEFAULT_BUILD_DIR = "build"; //$NON-NLS-1$
+ public final static String CONFIGURE_TOOL_ID = "org.eclipse.linuxtools.cdt.autotools.gnu.toolchain.tool.configure"; //$NON-NLS-1$
+ public final static String BUILD_DIR_OPTION_ID = "org.eclipse.linuxtools.cdt.autotools.option.configure.builddir"; //$NON-NLS-1$
+ public final static String BUILD_DIR_APPLY = "BuildDir.apply"; //$NON-NLS-1$
+ public final static String BUILD_DIR_DEFAULT_QUESTION = "BuildDir.default"; //$NON-NLS-1$
+ public final static String BUILD_DIR_YES = "BuildDir.yes"; //$NON-NLS-1$
+ public final static String BUILD_DIR_NO = "BuildDir.no"; //$NON-NLS-1$
+
+ //FIXME: Use holder to set option value, not the "option" parameter
+ public boolean handleValue(IBuildObject buildObject,
+ IHoldsOptions holder,
+ IOption option,
+ String extraArgument, int event)
+ {
+ // Get the current value of the build dir option.
+ String value = (String)option.getValue();
+ String valueBase = value;
+
+ if (buildObject instanceof IConfiguration &&
+ (event == IManagedOptionValueHandler.EVENT_OPEN)) {
+// || event == IManagedOptionValueHandler.EVENT_APPLY)) {
+ SortedSet<Integer> nums = new TreeSet<Integer>();
+ IConfiguration configuration = (IConfiguration)buildObject;
+ IConfiguration[] cfgs = configuration.getManagedProject().getConfigurations();
+ int index = 1;
+ boolean valueFound = false;
+ for (int i = 0; i < cfgs.length; ++i) {
+ IConfiguration config = cfgs[i];
+ if (config == null || config.getName().equals(configuration.getName())) {
+ continue;
+ }
+ ITool tool = config.getToolFromOutputExtension("status"); //$NON-NLS-1$
+ if (tool == null) // can happen if user has purposely mixed autotools and non-autotools cfgs
+ continue;
+
+ // We now want to get the builddir option for the tool. If we use
+ // getOptionById(), we must know the full id which in our case has a generated
+ // numeric extension at the end. Otherwise, the base builddir option id
+ // will get us the default option, not the one for the configuration we
+ // are currently looking at. We use getOptionBySuperClassId() instead
+ // which will find us options that are based off the original builddir
+ // option which include those with generated extensions at the end.
+ IOption buildDirOption = tool.getOptionBySuperClassId(BUILD_DIR_OPTION_ID);
+ String buildDir = (String)buildDirOption.getValue();
+ if (buildDir.equals(value)) {
+ valueFound = true;
+ }
+ // For "buildXX" values, store the XX values in a list of used extensions.
+ if (buildDir.startsWith(DEFAULT_BUILD_DIR)) {
+ String numstr = buildDir.substring(DEFAULT_BUILD_DIR.length());
+ try {
+ Integer k = Integer.valueOf(numstr);
+ // Assume the value to start with is the last value in the list
+ // plus 1.
+ index = k.intValue() + 1;
+ nums.add(k);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ }
+
+ // If there is no name collision for the configurations, then we simply return.
+ if (!valueFound)
+ return true;
+
+// // If the user has applied a change and it matches an existing build directory,
+// // then warn and ask if the user wants the value defaulted to a safe value.
+// if (event == EVENT_APPLY) {
+// String title = AutotoolsPlugin.getResourceString(BUILD_DIR_APPLY);
+// String question = AutotoolsPlugin.getResourceString(BUILD_DIR_DEFAULT_QUESTION);
+// String[] buttonLabels = new String[2];
+// buttonLabels[0] = AutotoolsPlugin.getResourceString(BUILD_DIR_YES);
+// buttonLabels[1] = AutotoolsPlugin.getResourceString(BUILD_DIR_NO);
+// MessageDialog d = new MessageDialog(AutotoolsPlugin.getActiveWorkbenchShell(),
+// title, null, question, MessageDialog.QUESTION, buttonLabels, 0);
+// int result = d.open();
+// if (result == 1)
+// return true;
+// }
+
+ // For defaulted buildXX values, we support defaulting a unique XX value.
+ if (value.startsWith(DEFAULT_BUILD_DIR)) {
+ valueBase = DEFAULT_BUILD_DIR;
+ // Try and establish a unique "buildXX" name that hasn't been used yet.
+ while (nums.contains(Integer.valueOf(index))) {
+ ++index;
+ }
+ }
+
+ // Reset the default build directory for this opened configuration.
+ try {
+ IOption optionToSet = holder.getOptionToSet(option, false);
+ optionToSet.setValue(valueBase + index);
+ } catch (BuildException e) {
+ return false;
+ }
+ }
+
+ // The event was not handled, thus return false
+ return true;
+ }
+
+ // IOptionApplicability methods
+
+ public boolean isOptionEnabled(IBuildObject configuration,
+ IHoldsOptions holder, IOption option) {
+ return true;
+ }
+
+ public boolean isOptionUsedInCommandLine(IBuildObject configuration,
+ IHoldsOptions holder, IOption option) {
+ return false;
+ }
+
+ public boolean isOptionVisible(IBuildObject configuration,
+ IHoldsOptions holder, IOption option) {
+ if (option.getName().equals("includes") || option.getName().equals("symbols"))
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsMakefileBuilder.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsMakefileBuilder.java
new file mode 100644
index 0000000000..198d89d075
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsMakefileBuilder.java
@@ -0,0 +1,512 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+import org.eclipse.cdt.core.resources.IConsole;
+import org.eclipse.cdt.make.core.IMakeCommonBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IBuilder;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IManagedProject;
+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.internal.core.Builder;
+import org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder;
+import org.eclipse.cdt.managedbuilder.internal.core.ToolChain;
+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.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+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.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+
+
+/**
+ * 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
+ */
+@SuppressWarnings("restriction")
+public class AutotoolsMakefileBuilder extends CommonBuilder {
+ public static final String BUILDER_NAME = "genmakebuilder"; //$NON-NLS-1$
+ public static final String BUILDER_ID = AutotoolsPlugin.getUniqueIdentifier() + "." + BUILDER_NAME; //$NON-NLS-1$
+ public static final String MANAGED_BUILDER_ID = ManagedBuilderCorePlugin.getUniqueIdentifier() + "." + BUILDER_NAME; //$NON-NLS-1$
+ public static final String AUTOTOOLS_CONFIG_ID = AutotoolsPlugin.getUniqueIdentifier() + ".configuration.build"; //$NON-NLS-1$
+ public static final String AUTOTOOLS_PROJECT_TYPE_ID = AutotoolsPlugin.getUniqueIdentifier() + ".projectType"; //$NON-NLS-1$
+
+ private static final String BUILD_FINISHED = "AutotoolsMakefileBuilder.message.finished"; //$NON-NLS-1$
+ private static final String TYPE_CLEAN = "AutotoolsMakefileBuilder.type.clean"; //$NON-NLS-1$
+ private static final String CONSOLE_HEADER = "AutotoolsMakefileBuilder.message.console.header"; //$NON-NLS-1$
+
+ private static final String EMPTY_STRING = new String();
+ public final String WHITESPACE = " "; //$NON-NLS-1$
+
+ protected boolean buildCalled;
+
+ private String makeTargetName;
+
+ @SuppressWarnings("unused")
+ private String preBuildErrMsg = new String();
+ @SuppressWarnings("unused")
+ private String postBuildErrMsg = new String();
+
+ public static String getBuilderId() {
+ return BUILDER_ID;
+ }
+
+ public static boolean hasTargetBuilder(IProject project) {
+ try {
+ // When a project is converted to an Autotools project, we
+ // replace the ManagedMake builder with a special one that
+ // handles MakeTargets. If a project is brought into Eclipse and
+ // uses the New Project Wizard to create a ManagedMake project that
+ // is of type: Autotools, this added step is not done. If we know
+ // we have an Autotools project from the configuration id, then
+ // we should add the builder now. We also should replace the
+ // default ManagedMake scanner provider with the Autotools one,
+ // then return true.
+ if (project.getNature(ManagedCProjectNature.MNG_NATURE_ID) != null) {
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ IManagedProject m = info.getManagedProject();
+ if (m != null && m.getProjectType().getId().equals(AUTOTOOLS_PROJECT_TYPE_ID)) {
+ AutotoolsProjectNature.addAutotoolsBuilder(project, new NullProgressMonitor());
+ AutotoolsPlugin.verifyScannerInfoProvider(project);
+ return true;
+ }
+ }
+ } catch (CoreException e) {
+ // Don't care...fall through to not found.
+ } catch (Exception f) {
+ // Don't care...fall through to not found.
+ }
+ // Otherwise not found.
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
+ IProject[] results = null;
+ IProject project = getProject();
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ IManagedBuilderMakefileGenerator generator = null;
+ try {
+ // Figure out the working directory for the build and make sure there is a makefile there
+ // If not, mark a rebuild is required so that configuration will get
+ // invoked.
+ IWorkspace workspace = project.getWorkspace();
+ if (workspace != null) {
+ IWorkspaceRoot root = workspace.getRoot();
+ if (root != null) {
+ if (info.getDefaultConfiguration() == null)
+ return null;
+ generator = new MakeGenerator();
+ generator.initialize(getProject(), info, monitor);
+ IPath buildDir = project.getLocation().append(generator.getBuildWorkingDir());
+ IPath makefilePath = buildDir.append(generator.getMakefileName());
+ IFile makefile = root.getFileForLocation(makefilePath);
+ if (makefile == null || !makefile.exists()) {
+ info.setRebuildState(true);
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ makeTargetName = (String)args.get("org.eclipse.cdt.make.core.build.target.inc"); //$NON-NLS-1$
+
+ buildCalled = true;
+ /**
+ * @see IncrementalProjectBuilder#build
+ */
+// fBuildSet.start(this);
+
+ // Hijack the build. This is because the CommonBuilder code will
+ // try and create builders for a MakeTarget build. We don't want
+ // that because this will default to using the GnuMakefileGenerator
+ // which fails. We want to use our Autotools MakeGenerator and
+ // perform a make from the top-level.
+ if(VERBOSE)
+ outputTrace(project.getName(), ">>build requested, type = " + kind); //$NON-NLS-1$
+
+ IConfiguration cfg = info.getDefaultConfiguration();
+
+ // Assemble the information needed to generate the targets
+ String prebuildStep = cfg.getPrebuildStep();
+ try{
+ //try to resolve the build macros in the prebuild step
+ prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(
+ prebuildStep,
+ EMPTY_STRING,
+ WHITESPACE,
+ IBuildMacroProvider.CONTEXT_CONFIGURATION,
+ cfg);
+ } catch (BuildMacroException e){
+ }
+ prebuildStep = prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters)
+
+ String postbuildStep = cfg.getPostbuildStep();
+ try{
+ //try to resolve the build macros in the postbuild step
+ postbuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(
+ postbuildStep,
+ EMPTY_STRING,
+ WHITESPACE,
+ IBuildMacroProvider.CONTEXT_CONFIGURATION,
+ cfg);
+
+ } catch (BuildMacroException e){
+ }
+ postbuildStep = postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters)
+ String preannouncebuildStep = cfg.getPreannouncebuildStep();
+ String postannouncebuildStep = cfg.getPostannouncebuildStep();
+
+ IConsole console = null;
+ ConsoleOutputStream consoleOutStream = null;
+ CommandLauncher launcher = null;
+ String[] env = null;
+ Process proc = null;
+ OutputStream stdout = null;
+ OutputStream stderr = null;
+
+ // If we have a prebuild or postbuild step, set up a command launcher to use.
+ if (!prebuildStep.equals("") || !postbuildStep.equals("")) {
+ console = CCorePlugin.getDefault().getConsole("org.eclipse.linuxtools.cdt.autotools.buildStepsConsole"); // $NON-NLS-1$
+ console.start(project);
+ consoleOutStream = console.getOutputStream();
+ stdout = consoleOutStream;
+ stderr = consoleOutStream;
+ launcher = new CommandLauncher();
+ // Set the environment
+ IEnvironmentVariable variables[] = ManagedBuildManager
+ .getEnvironmentVariableProvider().getVariables(cfg, true);
+ ArrayList<String> envList = new ArrayList<String>();
+ 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()]);
+ }
+ }
+
+ // Check for a prebuild step and execute it if it exists.
+ if (!prebuildStep.equals("")) {
+ monitor.subTask(preannouncebuildStep);
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(preannouncebuildStep);
+ buffer.append(System.getProperty("line.separator", "\n")); // $NON-NLS-1$ // $NON-NLS-2$
+
+ try {
+ consoleOutStream.write(buffer.toString().getBytes());
+ consoleOutStream.flush();
+ } catch (IOException e) {
+ // do nothing
+ }
+
+ launcher.showCommand(true);
+ String[] tmp = prebuildStep.split("\\s");
+ String[] cmdargs = new String[tmp.length - 1];
+ if (tmp.length > 1)
+ System.arraycopy(tmp, 1, cmdargs, 0, tmp.length - 1);
+ proc = launcher.execute(new Path(tmp[0]), cmdargs, env,
+ project.getLocation().append(generator.getBuildWorkingDir()), monitor);
+ 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(stdout, stderr, new SubProgressMonitor(
+ monitor, IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) {
+ preBuildErrMsg = launcher.getErrorMessage();
+ }
+ }
+ }
+
+ // Perform build
+
+ ToolChain toolChain = (ToolChain)cfg.getToolChain();
+ IBuilder oldBuilder = cfg.getBuilder();
+ String workingDir = generator.getBuildWorkingDir().toString();
+ IPath location = project.getLocation().append(workingDir);
+ oldBuilder.setBuildPath(location.toString());
+ oldBuilder.setBuildFileGeneratorElement(AutotoolsPlugin.getDefault().getGeneratorElement());
+ IBuilder builder = new AutotoolsBuilder(cfg.getEditableBuilder(), project, toolChain);
+ String buildLocation = null;
+ String buildCommand = null;
+ String buildArguments = null;
+ if (makeTargetName != null) {
+ // We have a MakeTarget. Get the location and command.
+ buildLocation = (String)args.get("org.eclipse.cdt.make.core.build.location"); // $NON-NLS-1$
+ buildCommand = (String)args.get("org.eclipse.cdt.make.core.build.command"); // $NON-NLS-1$
+ buildArguments = (String)args.get("org.eclipse.cdt.make.core.build.arguments"); // $NON-NLS-1$
+ }
+ if (buildLocation == null) {
+ builder.setBuildPath(location.toString());
+ }
+ else {
+ IWorkspace workspace = project.getWorkspace();
+ builder.setBuildPath(workspace.getRoot().getLocation().append(buildLocation).toString());
+ builder.setManagedBuildOn(false); // needed to avoid ManagedBuild from defaulting directory of makefile.
+ }
+ if (buildCommand != null)
+ builder.setBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, buildCommand);
+ if (buildArguments != null)
+ builder.setBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, buildArguments);
+ builder.setAutoBuildEnable(true);
+ builder.setCleanBuildEnable(false); // Don't want clean build done ahead of our build.
+ // Following is needed to circumvent the CommonBuilder from using the default
+ // GNUMakefileGenerator.
+ builder.setBuildFileGeneratorElement(AutotoolsPlugin.getDefault().getGeneratorElement());
+ toolChain.setBuilder((Builder)builder);
+
+ IProject[] projects = null;
+ try {
+ projects = super.build(kind, args, monitor);
+ } finally {
+ // Must ensure we reset everything back so configuration will be run in future.
+ toolChain.setBuilder((Builder)oldBuilder);
+ }
+
+ if(VERBOSE)
+ outputTrace(project.getName(), "<<done build requested, type = " + kind); //$NON-NLS-1$
+
+ results = projects;
+ buildCalled = false;
+ // Check for a postbuild step and execute it if it exists.
+ if (!postbuildStep.equals("")) {
+ monitor.subTask(postannouncebuildStep);
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(postannouncebuildStep);
+ buffer.append(System.getProperty("line.separator", "\n")); // $NON-NLS-1$ // $NON-NLS-2$
+
+ try {
+ consoleOutStream.write(buffer.toString().getBytes());
+ consoleOutStream.flush();
+ } catch (IOException e) {
+ // do nothing
+ }
+ String[] tmp = postbuildStep.split("\\s");
+ String[] cmdargs = new String[tmp.length - 1];
+ if (tmp.length > 1)
+ System.arraycopy(tmp, 1, cmdargs, 0, tmp.length - 1);
+ proc = launcher.execute(new Path(tmp[0]), cmdargs, env,
+ project.getLocation().append(generator.getBuildWorkingDir()), monitor);
+ 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(stdout, stderr, new SubProgressMonitor(
+ monitor, IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) {
+ postBuildErrMsg = launcher.getErrorMessage();
+ }
+ }
+ }
+ }
+ return results;
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ protected void clean(IProgressMonitor monitor) throws CoreException {
+ // See what type of cleaning the user has set up in the
+ // build properties dialog.
+ String cleanDelete = null;
+ try {
+ cleanDelete = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+
+ if (cleanDelete != null && cleanDelete.equals(AutotoolsPropertyConstants.TRUE))
+ removeBuildDir(monitor);
+ else {
+ IProject project = getProject();
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ IConfiguration cfg = info.getDefaultConfiguration();
+ IManagedBuilderMakefileGenerator generator = new MakeGenerator();
+ generator.initialize(getProject(), info, monitor);
+
+// // Hijack the builder itself so that instead of ManagedMake
+// // policy of defaulting the build path to the configuration name,
+// // we get the build occurring in the builddir configure tool setting.
+// builders[0] = new AutotoolsBuilder(cfg.getEditableBuilder(), project);
+// builders[0].setBuildPath(project.getLocation().append(generator.getBuildWorkingDir()).toOSString());
+// builders[0].setAutoBuildEnable(true);
+// builders[0].setCleanBuildEnable(true);
+// builders[0].setManagedBuildOn(false);
+
+ ToolChain toolChain = (ToolChain)cfg.getToolChain();
+ IBuilder oldBuilder = cfg.getBuilder();
+ IBuilder builder = new AutotoolsBuilder(cfg.getEditableBuilder(), project, toolChain);
+ builder.setBuildPath(project.getLocation().append(generator.getBuildWorkingDir()).toOSString());
+ builder.setAutoBuildEnable(true);
+ builder.setCleanBuildEnable(true);
+ builder.setManagedBuildOn(false);
+ // Following is needed to circumvent the CommonBuilder from using the default
+ // GNUMakefileGenerator.
+ builder.setBuildFileGeneratorElement(AutotoolsPlugin.getDefault().getGeneratorElement());
+ toolChain.setBuilder((Builder)builder);
+
+ try {
+ super.build(CLEAN_BUILD, (Map)null, monitor);
+ } finally {
+ toolChain.setBuilder((Builder)oldBuilder);
+ }
+ }
+ }
+
+ protected void removeBuildDir(IProgressMonitor monitor) {
+ try {
+ // use brute force approach
+ IProject project = getProject();
+ IWorkspace workspace = AutotoolsPlugin.getWorkspace();
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ IConfiguration cfg = info.getDefaultConfiguration();
+ IManagedBuilderMakefileGenerator generator = new MakeGenerator();
+ generator.initialize(getProject(), info, monitor);
+ String buildPath = project.getFullPath().append(generator.getBuildWorkingDir()).toOSString();
+ IResource rc = workspace.getRoot().findMember(buildPath);
+ if (rc == null || rc.getType() != IResource.FOLDER)
+ return;
+ IFolder buildDir = (IFolder)rc;
+ String status = AutotoolsPlugin.getFormattedString("AutotoolsMakefileBuilder.message.clean.deleting.output", new String[]{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());
+ // Get a build console for the project
+ IConsole console = CCorePlugin.getDefault().getConsole();
+ console.start(project);
+// IConsole console = bInfo.getConsole();
+ ConsoleOutputStream consoleOutStream = console.getOutputStream();
+ String[] consoleHeader = new String[3];
+ consoleHeader[0] = AutotoolsPlugin.getResourceString(TYPE_CLEAN);
+ consoleHeader[1] = cfg.getName();
+ consoleHeader[2] = project.getName();
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ buf.append(AutotoolsPlugin.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 = AutotoolsPlugin.getFormattedString(BUILD_FINISHED, new String[]{project.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 (IOException io) {
+ // Ignore console failures...
+ } catch (CoreException e) {
+ // Ignore console failures...
+ }
+ }
+
+ /* (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[] getTargets(int kind, IBuilder builder) {
+ List<String> args = new ArrayList<String>();
+ String buildTarget = "all";
+ switch (kind) {
+ case CLEAN_BUILD:
+ // For a clean build, we use the clean make target set up by the user
+ // in the build properties dialog. Otherwise, we use the default for
+ // an autotools project.
+ String target = null;
+ try {
+ target = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+ if (target == null)
+ target = AutotoolsPropertyConstants.CLEAN_MAKE_TARGET_DEFAULT;
+ args.add(target);
+ break;
+ case FULL_BUILD:
+ if (makeTargetName != null)
+ buildTarget = makeTargetName;
+ case AUTO_BUILD:
+ case INCREMENTAL_BUILD:
+ args.addAll(makeArrayList(buildTarget));
+ break;
+ }
+ return (String[])args.toArray(new String[args.size()]);
+ }
+
+ // Turn the string into an array.
+ ArrayList<String> makeArrayList(String string) {
+ string.trim();
+ char[] array = string.toCharArray();
+ ArrayList<String> aList = new ArrayList<String>();
+ StringBuffer buffer = new StringBuffer();
+ boolean inComment = false;
+ for (int i = 0; i < array.length; i++) {
+ char c = array[i];
+ if (array[i] == '"' || array[i] == '\'') {
+ if (i > 0 && array[i - 1] == '\\') {
+ inComment = false;
+ } else {
+ inComment = !inComment;
+ }
+ }
+ if (c == ' ' && !inComment) {
+ aList.add(buffer.toString());
+ buffer = new StringBuffer();
+ } else {
+ buffer.append(c);
+ }
+ }
+ if (buffer.length() > 0)
+ aList.add(buffer.toString());
+ return aList;
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsPlugin.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsPlugin.java
new file mode 100644
index 0000000000..5e2e495cbe
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsPlugin.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.ICDescriptor;
+import org.eclipse.cdt.core.ICExtensionReference;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+@SuppressWarnings("deprecation")
+public class AutotoolsPlugin extends AbstractUIPlugin {
+
+ //The shared instance.
+ private static AutotoolsPlugin plugin;
+ private ResourceBundle resourceBundle;
+
+ public static final String PLUGIN_ID = "org.eclipse.linuxtools.cdt.autotools"; //$NON-NLS-1$
+
+ private IConfigurationElement generatorElement;
+
+ public static final String EXTENSION_POINT_ID = ManagedBuilderCorePlugin.getUniqueIdentifier() + ".buildDefinitions"; //$NON-NLS-1$
+ public static final String BUILDER = "builder"; //$NON-NLS-1$
+ public static final String ID_ELEMENT_NAME = "id"; // $NON-NLS-1$
+ public static final String AUTOTOOLS_BUILDER_ID = PLUGIN_ID + ".builder"; // $NON-NLS-1$
+
+ /**
+ * The constructor.
+ */
+ public AutotoolsPlugin() {
+ plugin = this;
+ try {
+ resourceBundle = ResourceBundle.getBundle("org.eclipse.linuxtools.cdt.autotools.Resources"); //$NON-NLS-1$
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+
+ }
+
+ public static String getPluginId() {
+ return PLUGIN_ID;
+ }
+
+ public static String getUniqueIdentifier() {
+ if (getDefault() == null) {
+ // If the default instance is not yet initialized,
+ // return a static identifier. This identifier must
+ // match the plugin id defined in plugin.xml
+ return PLUGIN_ID;
+ }
+ return getDefault().getBundle().getSymbolicName();
+ }
+
+ public static void verifyScannerInfoProvider(IProject project) throws CoreException {
+ boolean found = false;
+ ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(project, true);
+ ICExtensionReference[] refs = desc.get(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID);
+ for (int i = 0; i < refs.length; ++i) {
+ if (refs[i].getID().equals(AutotoolsScannerInfoProvider.INTERFACE_IDENTITY))
+ found = true;
+ }
+ if (!found) {
+ setScannerInfoProvider(project);
+ }
+ }
+
+ public static void setScannerInfoProvider(IProject project) throws CoreException {
+ ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(project, true);
+ desc.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID);
+ desc.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, AutotoolsScannerInfoProvider.INTERFACE_IDENTITY);
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ plugin = null;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static AutotoolsPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns active shell.
+ */
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow window = getDefault().getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getShell();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ *
+ * @param key the message key
+ * @return the resource bundle message
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = AutotoolsPlugin.getDefault().getResourceBundle();
+ try {
+ return bundle.getString(key);
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ *
+ * @param key the message key
+ * @param args an array of substituition strings
+ * @return the resource bundle message
+ */
+ public static String getFormattedString(String key, String[] args) {
+ return MessageFormat.format(getResourceString(key), (Object[])args);
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ /**
+ * Get the configuration element for the Autotools Makefile generator
+ * @return the generator element
+ */
+ public IConfigurationElement getGeneratorElement() {
+ if (generatorElement == null) {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(EXTENSION_POINT_ID);
+ if( extensionPoint != null) {
+ IExtension[] extensions = extensionPoint.getExtensions();
+ if (extensions != null) {
+ for (int i = 0; i < extensions.length; ++i) {
+ IExtension extension = extensions[i];
+
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+
+ // Get the managedBuildRevsion of the extension.
+ for (int j = 0; j < elements.length; j++) {
+ IConfigurationElement element = elements[j];
+ if (element.getName().equals(BUILDER)) {
+ String id = element.getAttribute(ID_ELEMENT_NAME);
+ if (id.equals(AUTOTOOLS_BUILDER_ID)) {
+ generatorElement = element;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return generatorElement;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given
+ * plug-in relative path.
+ *
+ * @param path the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.linuxtools.cdt.autotools", path);
+ }
+
+ public static void log(IStatus status) {
+ ResourcesPlugin.getPlugin().getLog().log(status);
+ }
+
+ public static void logErrorMessage(String message) {
+ log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null));
+ }
+
+ public static void logException(Throwable e, final String title, String message) {
+ if (e instanceof InvocationTargetException) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+ IStatus status = null;
+ if (e instanceof CoreException)
+ status = ((CoreException) e).getStatus();
+ else {
+ if (message == null)
+ message = e.getMessage();
+ if (message == null)
+ message = e.toString();
+ status = new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.OK, message, e);
+ }
+ ResourcesPlugin.getPlugin().getLog().log(status);
+ Display display;
+ display = Display.getCurrent();
+ if (display == null)
+ display = Display.getDefault();
+ final IStatus fstatus = status;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ ErrorDialog.openError(null, title, null, fstatus);
+ }
+ });
+ }
+
+ public static void logException(Throwable e) {
+ logException(e, null, null);
+ }
+
+ public static void log(Throwable e) {
+ if (e instanceof InvocationTargetException)
+ e = ((InvocationTargetException) e).getTargetException();
+ IStatus status = null;
+ if (e instanceof CoreException)
+ status = ((CoreException) e).getStatus();
+ else
+ status = new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.OK, e.getMessage(), e);
+ log(status);
+ }
+
+ /**
+ * Utility method with conventions
+ */
+ public static void errorDialog(Shell shell, String title, String message, IStatus s) {
+ log(s);
+ // if the 'message' resource string and the IStatus' message are the same,
+ // don't show both in the dialog
+ if (s != null && message.equals(s.getMessage())) {
+ message = null;
+ }
+ ErrorDialog.openError(shell, title, message, s);
+ }
+
+ /**
+ * Utility method with conventions
+ */
+ public static void errorDialog(Shell shell, String title, String message, Throwable t) {
+ log(t);
+ IStatus status;
+ if (t instanceof CoreException) {
+ status = ((CoreException) t).getStatus();
+ // if the 'message' resource string and the IStatus' message are the same,
+ // don't show both in the dialog
+ if (status != null && message.equals(status.getMessage())) {
+ message = null;
+ }
+ } else {
+ status = new Status(IStatus.ERROR, AutotoolsPlugin.getUniqueIdentifier(), -1, "Internal Error: ", t); //$NON-NLS-1$
+ }
+ ErrorDialog.openError(shell, title, message, status);
+ }
+
+ /**
+ * Returns the workspace instance.
+ */
+ public static IWorkspace getWorkspace() {
+ return ResourcesPlugin.getWorkspace();
+ }
+
+ /**
+ * Returns the active workbench window or <code>null</code> if none
+ */
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ return getDefault().getWorkbench().getActiveWorkbenchWindow();
+ }
+
+ /**
+ * Returns the active workbench page or <code>null</code> if none.
+ */
+ public static IWorkbenchPage getActivePage() {
+ IWorkbenchWindow window= getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getActivePage();
+ }
+ return null;
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectNature.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectNature.java
new file mode 100644
index 0000000000..5a7f311a29
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectNature.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Red Hat Inc.. 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:
+ * Red Hat Incorporated - initial implementation
+ * IBM Rational Software - add and remove nature static methods
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+public class AutotoolsProjectNature implements IProjectNature {
+
+ public static final String AUTOTOOLS_NATURE_ID = AutotoolsPlugin.getUniqueIdentifier() + ".autotoolsNature"; //$NON-NLS-1$
+
+ private IProject project;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IProjectNature#configure()
+ */
+ public void configure() throws CoreException {
+ addAutotoolsBuilder(project, new NullProgressMonitor());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+ */
+ public void deconfigure() throws CoreException {
+ // TODO remove builder from here
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IProjectNature#getProject()
+ */
+ public IProject getProject() {
+ return project;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
+ */
+ public void setProject(IProject project) {
+ this.project = project;
+ }
+
+ /**
+ * Add the Autotools builder to the project
+ * @param project
+ * @param monitor
+ * @throws CoreException
+ */
+ public static void addAutotoolsBuilder(IProject project, IProgressMonitor monitor) throws CoreException {
+ // Add the builder to the project
+ IProjectDescription description = project.getDescription();
+ ICommand[] commands = description.getBuildSpec();
+
+ // TODO Remove the cbuilder check when the new StandardBuild nature adds the cbuilder
+ for (int i = 0; i < commands.length; i++) {
+ ICommand command = commands[i];
+ String builderName = command.getBuilderName();
+ // If there is a ManagedMake makefile generator, remove it as it will
+ // cause an additional build "all" to occur when we are making any target.
+ if (builderName.equals("org.eclipse.cdt.core.cbuilder") ||
+ builderName.equals(AutotoolsMakefileBuilder.MANAGED_BUILDER_ID)) { //$NON-NLS-1$
+ // Remove the command
+ Vector<ICommand> vec = new Vector<ICommand>(Arrays.asList(commands));
+ vec.removeElementAt(i);
+ vec.trimToSize();
+ ICommand[] tempCommands = (ICommand[]) vec.toArray(new ICommand[commands.length-1]);
+ description.setBuildSpec(tempCommands);
+ project.setDescription(description, new NullProgressMonitor());
+ break;
+ }
+ }
+
+ commands = description.getBuildSpec();
+ boolean found = false;
+ // See if the builder is already there
+ for (int i = 0; i < commands.length; ++i) {
+ if (commands[i].getBuilderName().equals(AutotoolsMakefileBuilder.BUILDER_ID)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ //add builder to project
+ ICommand command = description.newCommand();
+ command.setBuilderName(AutotoolsMakefileBuilder.BUILDER_ID);
+ ICommand[] newCommands = new ICommand[commands.length + 1];
+ // Add it before other builders.
+ System.arraycopy(commands, 0, newCommands, 1, commands.length);
+ newCommands[0] = command;
+ description.setBuildSpec(newCommands);
+ project.setDescription(description, new NullProgressMonitor());
+ }
+ }
+
+ /**
+ * Utility method for adding an autotools nature to a project.
+ *
+ * @param proj the project to add the autotools nature to.
+ * @param monitor a progress monitor to indicate the duration of the operation, or
+ * <code>null</code> if progress reporting is not required.
+ */
+ public static void addAutotoolsNature(IProject project, IProgressMonitor monitor) throws CoreException {
+ addNature(project, AUTOTOOLS_NATURE_ID, monitor);
+ }
+
+ /**
+ * Utility method for adding a nature to a project.
+ *
+ * @param proj the project to add the nature to.
+ * @param natureId the id of the nature to assign to the project
+ * @param monitor a progress monitor to indicate the duration of the operation, or
+ * <code>null</code> if progress reporting is not required.
+ */
+ public static void addNature(IProject project, String natureId, IProgressMonitor monitor) throws CoreException {
+ IProjectDescription description = project.getDescription();
+ String[] prevNatures = description.getNatureIds();
+ for (int i = 0; i < prevNatures.length; i++) {
+ if (natureId.equals(prevNatures[i]))
+ return;
+ }
+ String[] newNatures = new String[prevNatures.length + 1];
+ System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+ newNatures[prevNatures.length] = natureId;
+ description.setNatureIds(newNatures);
+ project.setDescription(description, monitor);
+ }
+
+ /**
+ * Utility method to remove the autotools nature from a project.
+ *
+ * @param project to remove the autotools nature from
+ * @param mon progress monitor to indicate the duration of the operation, or
+ * <code>null</code> if progress reporting is not required.
+ * @throws CoreException
+ */
+ public static void removeAutotoolsNature(IProject project, IProgressMonitor mon) throws CoreException {
+ removeNature(project, AUTOTOOLS_NATURE_ID, mon);
+ }
+
+ /**
+ * Utility method for removing a project nature from a project.
+ *
+ * @param proj the project to remove the nature from
+ * @param natureId the nature id to remove
+ * @param monitor a progress monitor to indicate the duration of the operation, or
+ * <code>null</code> if progress reporting is not required.
+ */
+ public static void removeNature(IProject project, String natureId, IProgressMonitor monitor) throws CoreException {
+ IProjectDescription description = project.getDescription();
+ String[] prevNatures = description.getNatureIds();
+ List<String> newNatures = new ArrayList<String>(Arrays.asList(prevNatures));
+ newNatures.remove(natureId);
+ description.setNatureIds((String[])newNatures.toArray(new String[newNatures.size()]));
+ project.setDescription(description, monitor);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectPropertyTester.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectPropertyTester.java
new file mode 100644
index 0000000000..a561d6a4d8
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsProjectPropertyTester.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+public class AutotoolsProjectPropertyTester extends PropertyTester {
+
+ public AutotoolsProjectPropertyTester() {
+ // nothing needed
+ }
+
+ public boolean test(Object receiver, String property, Object[] args,
+ Object expectedValue) {
+ IProject project = null;
+ IResource resource = (IResource)receiver;
+ project = resource.getProject();
+ return AutotoolsMakefileBuilder.hasTargetBuilder(project);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfo.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfo.java
new file mode 100644
index 0000000000..83c331d6e1
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfo.java
@@ -0,0 +1,431 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
+import org.eclipse.cdt.managedbuilder.core.BuildException;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IOption;
+import org.eclipse.cdt.managedbuilder.core.ITool;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+
+
+// This class is used to get and store information from the Autotools
+// makefiles for a specific file in a specific Autotools project.
+// It gets information by invoking make with special options
+// to find out what occurs if the file in question has changed.
+public class AutotoolsScannerInfo implements IScannerInfo {
+
+ private IResource res;
+ private IProject project;
+ private IPath filePath;
+ private String[] includePaths;
+ @SuppressWarnings("unchecked")
+ private HashMap definedSymbols;
+ private boolean isDirty;
+ private String compilationString;
+ private String dirName;
+ private HashSet<IScannerInfoChangeListener> listeners = new HashSet<IScannerInfoChangeListener>();
+
+ public AutotoolsScannerInfo (IResource res) {
+ this.res = res;
+ this.project = res.getProject();
+ this.filePath = res.getFullPath();
+ }
+
+ public void addListener(IScannerInfoChangeListener listener) {
+ if (!listeners.contains(listener)) {
+ listeners.add(listener);
+ }
+ }
+
+ public void removeListener(IScannerInfoChangeListener listener) {
+ if (listeners.contains(listener)) {
+ listeners.remove(listener);
+ }
+ }
+
+ // TODO: Should make a listener to watch all Makefiles up the
+ // tree from the resource. If any change, the include
+ // paths and options passed to make the file in question
+ // could change.
+ public void setDirty (boolean isDirty) {
+ this.isDirty = isDirty;
+ }
+
+ private String buildFile (IPath filePath, IFile makefile, IManagedBuildInfo info) {
+ String outString = "";
+ IPath dir = makefile.getFullPath().removeLastSegments(1);
+ IPath relFilePath = filePath.removeFirstSegments(dir.segmentCount());
+ CommandLauncher launcher = new CommandLauncher();
+ String[] env = null;
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = stdout;
+ IPath makeCommandPath = new Path(info.getBuildCommand());
+ ITool tool = info.getToolFromOutputExtension("status"); // $NON-NLS-1$
+ IOption[] options = tool.getOptions();
+ IPath runPath = null;
+ boolean done = false;
+
+ for (int i = 0; i < options.length && !done; ++i) {
+ try {
+ if (options[i].getValueType() == IOption.STRING) {
+ String value = (String) options[i].getValue();
+ String id = options[i].getId();
+ if (id.indexOf("builddir") > 0) { // $NON-NLS-1$
+ runPath = makefile.getProject().getLocation().append(value.trim());
+ done = true;
+ }
+ }
+ } catch (BuildException e) {
+ // do nothing
+ }
+ }
+
+ IProgressMonitor monitor = new NullProgressMonitor();
+ String errMsg = null;
+ String[] makeArgs = new String[3];
+ makeArgs[0] = "-n"; // $NON-NLS-1$
+ makeArgs[1] = "all"; // $NON-NLS-1$
+ makeArgs[2] = "MAKE=make -W " + relFilePath.toOSString(); //$NON-NLS-1$
+
+ try {
+ Process proc = launcher.execute(makeCommandPath, makeArgs, env,
+ runPath, new NullProgressMonitor());
+ 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(stdout, stderr, new SubProgressMonitor(
+ monitor, IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) {
+ errMsg = launcher.getErrorMessage();
+ }
+ outString = stdout.toString();
+ } else {
+ errMsg = launcher.getErrorMessage();
+ }
+ } catch (CoreException e) {
+ errMsg = e.getLocalizedMessage();
+ AutotoolsPlugin.logErrorMessage(errMsg);
+ }
+ return outString;
+ }
+
+ private IFile getMakefile (IManagedBuildInfo info, IPath filePath) {
+ IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
+ IPath dir = filePath.removeLastSegments(1);
+ IFile makefile = null;
+ boolean done = false;
+ IPath makefilePath = null;
+ // Look starting at source file directory for the
+ // Makefile.in or Makefile for the given file.
+ while (!done) {
+ makefilePath = dir.append("Makefile.in"); // $NON-NLS-1$
+ makefile = root.getFile(makefilePath);
+ if (makefile != null && makefile.exists()) {
+ done = true;
+ continue;
+ }
+ makefilePath = dir.append("Makefile"); // $NON-NLS-1$
+ makefile = root.getFile(makefilePath);
+ if (makefile != null && makefile.exists()) {
+ done = true;
+ }
+ else {
+ dir = dir.removeLastSegments(1);
+ if (dir.lastSegment() == null)
+ done = true;
+ }
+ }
+ return makefile;
+ }
+
+ private String getCompilationString() {
+ if (compilationString != null && !isDirty)
+ return compilationString;
+ String makeWEnabled = null;
+ try {
+ makeWEnabled = project.getPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W);
+ } catch (CoreException e) {
+ // do nothing
+ }
+ if (!(res instanceof IFile) ||
+ makeWEnabled == null ||
+ makeWEnabled.equals("false")) // $NON-NLS-1$
+ return null;
+ isDirty = false;
+ IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
+ IFile file = root.getFile(filePath);
+ IFile makefile = null;
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ // If the given file exists and we have a ManagedBuild, we may have
+ // an Autotools project source file.
+ if (file != null && file.exists() && info != null) {
+ makefile = getMakefile(info, filePath);
+ }
+ // We now have the closest directory to the given path
+ // that contains a Makefile.in or Makefile. This Makefile
+ // should contain a relative reference to the file in
+ // question. We now want to try and extract the include
+ // path from the top-level make run with the assumption
+ // that the file in question has been altered.
+ if (makefile != null) {
+ IPath dir = makefile.getFullPath().removeLastSegments(1);
+ // Get relative name of file as we assume the Makefile will
+ // refer to it this way.
+ String out = buildFile(filePath, makefile, info);
+ try {
+ boolean topLevel = dir.equals(project.getFullPath());
+ Pattern p = null;
+ Matcher m = null;
+ if (!topLevel) {
+ String regex1 = "^Making.*in.*" + dir.lastSegment(); // $NON-NLS-1$
+ p = Pattern.compile(regex1, Pattern.MULTILINE);
+ m = p.matcher(out);
+ }
+ if (topLevel || m.find()) {
+ Pattern p2 = null;
+ Matcher m2 = null;
+ String substr2 = out;
+ if (!topLevel) {
+ substr2 = out.substring(m.end());
+ String regex2 = "^make.*Entering directory.*`(.*)'"; // $NON-NLS-1$
+ p2 = Pattern.compile(regex2, Pattern.MULTILINE);
+ m2 = p2.matcher(substr2);
+ }
+ if (topLevel || m2.find()) {
+ String substr3 = null;
+ if (!topLevel) {
+ dirName = m2.group(1);
+ substr3 = substr2.substring(m2.start());
+ } else {
+ dirName = "";
+ substr3 = out;
+ }
+ // We need to test for both gcc and g++ compilers.
+ String regex3 = "^.*gcc.*?-I.*?" + filePath.lastSegment(); // $NON-NLS-1$
+ String regex4 = "^.*g[+][+].*?-I.*?" + filePath.lastSegment(); // $NON-NLS-1$
+ // Replace all continuation markers so we don't have to worry about newlines in
+ // the middle of a compilation string.
+ substr3 = substr3.replaceAll("\\\\\\n", "");
+ Pattern p3 = Pattern.compile(regex3, Pattern.MULTILINE);
+ Matcher m3 = p3.matcher(substr3);
+ if (m3.find())
+ compilationString = substr3.substring(m3.start(),m3.end());
+ else {
+ String substr4 = substr3;
+ Pattern p4 = Pattern.compile(regex4, Pattern.MULTILINE);
+ Matcher m4 = p4.matcher(substr4);
+ if (m4.find())
+ compilationString = substr3.substring(m4.start(),m4.end());
+ }
+ }
+ } else if (!out.equals("")) {
+ compilationString = "";
+ }
+ } catch (IllegalStateException t) {
+ // Mark as dirty for next time.
+ isDirty = true;
+ }
+ }
+ return compilationString;
+ }
+
+ public String[] getIncludePaths() {
+ String[] pathArray = new String[0];
+ if (project == null || filePath == null)
+ return pathArray;
+ if (includePaths != null && !isDirty && compilationString != null) {
+ return includePaths;
+ }
+ ArrayList<String> pathList = new ArrayList<String>();
+ String cs = getCompilationString();
+ if (cs != null) {
+ // Grab include paths specified via -I
+ Pattern p4 = Pattern.compile(" -I");
+ String[] tokens = p4.split(cs);
+ for (int j = 1; j < tokens.length; ++j) {
+ String x = tokens[j].trim();
+ int firstSpace = x.indexOf(' ');
+ if (firstSpace != -1) {
+ x = x.substring(0, firstSpace);
+ }
+ if (x.charAt(0) == '/') {
+ pathList.add(x);
+ } else {
+ IPath relPath = new Path(dirName);
+ relPath = relPath.append(x);
+ pathList.add(relPath.toOSString());
+ }
+ }
+ // Grab include paths that are specified via -isystem
+ Pattern p5 = Pattern.compile(" -isystem");
+ tokens = p5.split(cs);
+ for (int j = 1; j < tokens.length; ++j) {
+ String x = tokens[j].trim();
+ int firstSpace = x.indexOf(' ');
+ if (firstSpace != -1) {
+ x = x.substring(0, firstSpace);
+ }
+ if (x.charAt(0) == '/') {
+ pathList.add(x);
+ } else {
+ IPath relPath = new Path(dirName);
+ relPath = relPath.append(x);
+ pathList.add(relPath.toOSString());
+ }
+ }
+ }
+
+ // The ManagedBuildManager is the normal default IScannerInfoProvider
+ // for Managed Projects. It has the ability to check gcc for the
+ // default include paths and we don't want to lose that. Append
+ // the include paths from it to the end of our list which is dynamically
+ // picking up the -I options.
+
+ // TODO: Should we even allow the user-defined includePaths in settings?
+ // These will be picked up by the ManagedBuildManager.
+ IScannerInfo info = (IScannerInfo)ManagedBuildManager.getBuildInfo(project);
+ if (info != null) {
+ String[] extraIncludePaths = info.getIncludePaths();
+ for (int i = 0; i < extraIncludePaths.length; ++i) {
+ pathList.add(extraIncludePaths[i]);
+ }
+ }
+
+ includePaths = (String[])pathList.toArray(pathArray);
+
+ // FIXME: Info has been updated. Is this the best place to notify listeners?
+ Iterator<IScannerInfoChangeListener> i = listeners.iterator();
+ while (i.hasNext()) {
+ IScannerInfoChangeListener listener = (IScannerInfoChangeListener)i.next();
+ listener.changeNotification(project, this);
+ }
+ return includePaths;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map getDefinedSymbols () {
+ HashMap symbolMap = new HashMap();
+ if (project == null || filePath == null)
+ return symbolMap;
+ if (definedSymbols != null && !isDirty && compilationString != null) {
+ return definedSymbols;
+ }
+ // Extract -D directives from the compilation string.
+ // TODO: Handle -U directives as well.
+ String cs = getCompilationString();
+ if (cs != null) {
+ Pattern p4 = Pattern.compile("\\s-D([^\\s=]+)(?:=(\\\\\".*?\\\\\"|\\S*))?"); // $NON-NLS-1$
+ Matcher m = p4.matcher(cs);
+ while(m.find()) {
+ String name = m.group(1);
+ String value = m.group(2);
+ if(value != null)
+ symbolMap.put(name, value.replace("\\", "")); // $NON-NLS-1$ $NON-NLS-2$
+ else
+ symbolMap.put(name, "");
+ }
+ }
+ // Add the defined symbols from ManagedBuildManager. This will include
+ // the builtin implicit defines from the compiler and the user-set
+ // defines from settings. Since these are added last, they will overwrite
+ // existing defines fished out of the Makefiles above. For the user-defined
+ // symbols, this is the correct behavior. For the implicit defines,
+ // this is not; however, this is not valid programming behavior and
+ // the compiler definitely warns against it.
+ IScannerInfo info = (IScannerInfo)ManagedBuildManager.getBuildInfo(project);
+ if (info != null) {
+ Map builtinDefinedSymbols = info.getDefinedSymbols();
+ symbolMap.putAll(builtinDefinedSymbols);
+ }
+
+ definedSymbols = symbolMap;
+ return definedSymbols;
+ }
+
+ public void createIncludeChain(IFile include, IResource res) {
+ try {
+ // We store two different values. The first only lasts for the
+ // the session and is the actual resource. We prefer to work with
+ // this form as it is quicker. To handle persistence across
+ // sessions, we also store a persistent copy of the resource's
+ // path. When the session is brought back again, we will recreate
+ // the session chain again using the persistent data.
+ include.setSessionProperty(AutotoolsPropertyConstants.OPEN_INCLUDE, res);
+ include.setPersistentProperty(AutotoolsPropertyConstants.OPEN_INCLUDE_P, res.getLocation().toPortableString());
+ } catch (CoreException e) {
+ // Do nothing
+ }
+ }
+
+ /**
+ *
+ * @param resource the resource we are scanning
+ * @return the final resource in the include chain if one exists
+ * otherwise the resource itself
+ */
+ public static IResource followIncludeChain(IResource resource) {
+ IResource res = resource;
+ try {
+ boolean done = false;
+ // In the case of include files, we chain to the file that
+ // included the header file. This may end up ultimately as
+ // a source file which has build parameters such as flag
+ // defines and a separate include path.
+ while (!done) {
+ while (res.getSessionProperty(AutotoolsPropertyConstants.OPEN_INCLUDE) != null)
+ res = (IResource)res.getSessionProperty(AutotoolsPropertyConstants.OPEN_INCLUDE);
+ String chainPath = res.getPersistentProperty(AutotoolsPropertyConstants.OPEN_INCLUDE_P);
+ if (chainPath != null) {
+ IPath location = Path.fromPortableString(chainPath);
+ IResource next = res.getWorkspace().getRoot().getFileForLocation(location);
+ res.setSessionProperty(AutotoolsPropertyConstants.OPEN_INCLUDE, next);
+ res = next;
+ } else
+ done = true;
+ }
+ } catch (CoreException e) {
+ // Do nothing
+ } finally {
+ resource = res;
+ }
+ return resource;
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfoProvider.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfoProvider.java
new file mode 100644
index 0000000000..572ce76d5e
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/AutotoolsScannerInfoProvider.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.cdt.core.AbstractCExtension;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
+import org.eclipse.cdt.core.parser.IScannerInfoProvider;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+
+
+public class AutotoolsScannerInfoProvider extends AbstractCExtension implements IScannerInfoProvider {
+
+ static private Map<String, Map<IResource, AutotoolsScannerInfo>> infoCollections = new HashMap<String, Map<IResource, AutotoolsScannerInfo>>();
+ static public final String INTERFACE_IDENTITY =
+ AutotoolsPlugin.PLUGIN_ID + "." + "AutotoolsScannerInfoProvider"; // $NON-NLS-1$
+
+ protected String getCollectionName(IProject project) {
+ IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project);
+ String config = project.getName() + "." + buildInfo.getConfigurationName();
+ return config;
+ }
+
+ public synchronized IScannerInfo getScannerInformation(IResource resource) {
+ IResource res = AutotoolsScannerInfo.followIncludeChain(resource);
+ // We keep scanner info separate per configuration.
+ // This is because one configuration may result in a file being
+ // compiled with one include path while another configuration
+ // may change the include path / defined symbols.
+ IProject project = resource.getProject();
+
+ // We punt for non-Autotools projects. This ScannerInfoProvider is used for
+ // all C Projects and we might get called for a non-Autotools project (e.g.
+ // unsubscribe operation when converting to C project).
+ if (!AutotoolsMakefileBuilder.hasTargetBuilder(project))
+ return null;
+
+ // Check if the scanner info has been marked dirty, in which case we need
+ // to mark all entries dirty.
+ Boolean isDirty = Boolean.FALSE;
+ try {
+ isDirty = (Boolean)project.getSessionProperty(AutotoolsPropertyConstants.SCANNER_INFO_DIRTY);
+ } catch (CoreException e) {
+ // do nothing
+ }
+ if (isDirty != null && isDirty.equals(Boolean.TRUE)) {
+ setDirty(project);
+ try {
+ project.setSessionProperty(AutotoolsPropertyConstants.SCANNER_INFO_DIRTY, Boolean.FALSE);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+ }
+ String config = getCollectionName(project);
+ // Get the ScannerInfo collection for current configuration or else
+ // create an empty collection if one doesn't already exist.
+ Map<IResource, AutotoolsScannerInfo> infoCollection = infoCollections.get(config);
+ if (infoCollection == null) {
+ infoCollection = new HashMap<IResource, AutotoolsScannerInfo>();
+ infoCollections.put(config, infoCollection);
+ }
+ AutotoolsScannerInfo info = (AutotoolsScannerInfo)infoCollection.get(res);
+ if (info == null) {
+ info = new AutotoolsScannerInfo(res);
+ infoCollection.put(res, info);
+ }
+ return info;
+ }
+
+ private void setDirty(IProject project) {
+ String config = getCollectionName(project);
+ Map<IResource, AutotoolsScannerInfo> infoCollection = infoCollections.get(config);
+ if (infoCollection != null) {
+ Collection<AutotoolsScannerInfo> s = infoCollection.values();
+ for (Iterator<AutotoolsScannerInfo> i = s.iterator(); i.hasNext();) {
+ AutotoolsScannerInfo info = (AutotoolsScannerInfo)i.next();
+ info.setDirty(true);
+ }
+ }
+ }
+
+ public void subscribe(IResource resource,
+ IScannerInfoChangeListener listener) {
+ AutotoolsScannerInfo info = (AutotoolsScannerInfo)getScannerInformation(resource);
+ info.addListener(listener);
+ }
+
+ public void unsubscribe(IResource resource,
+ IScannerInfoChangeListener listener) {
+ AutotoolsScannerInfo info = (AutotoolsScannerInfo)getScannerInformation(resource);
+ if (info != null)
+ info.removeListener(listener);
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/MakeGenerator.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/MakeGenerator.java
new file mode 100644
index 0000000000..aca5677d0e
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/MakeGenerator.java
@@ -0,0 +1,1374 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.core.ICDescriptor;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+import org.eclipse.cdt.core.resources.IConsole;
+import org.eclipse.cdt.core.settings.model.ICStorageElement;
+import org.eclipse.cdt.make.core.IMakeTarget;
+import org.eclipse.cdt.make.core.IMakeTargetManager;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.makefile.IMakefile;
+import org.eclipse.cdt.make.core.makefile.ITarget;
+import org.eclipse.cdt.make.core.makefile.ITargetRule;
+import org.eclipse.cdt.managedbuilder.core.BuildException;
+import org.eclipse.cdt.managedbuilder.core.IBuilder;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IOption;
+import org.eclipse.cdt.managedbuilder.core.ITool;
+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.IManagedBuilderMakefileGenerator2;
+import org.eclipse.cdt.newmake.core.IMakeCommonBuildInfo;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+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.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+import org.eclipse.linuxtools.internal.cdt.autotools.MarkerGenerator;
+
+
+@SuppressWarnings("deprecation")
+public class MakeGenerator extends MarkerGenerator implements IManagedBuilderMakefileGenerator, IManagedBuilderMakefileGenerator2 {
+
+ public final String CONFIG_STATUS = "config.status"; //$NON-NLS-1$
+ public final String MAKEFILE = "Makefile"; //$NON-NLS-1$
+ public final String MAKEFILE_CVS = "Makefile.cvs"; //$NON-NLS-1$
+ public final String SETTINGS_FILE_NAME = ".cdtconfigure"; //$NON-NLS-1$
+ public final String SHELL_COMMAND = "sh"; //$NON-NLS-1$
+
+ public final String AUTOGEN_TOOL_ID = "org.eclipse.linuxtools.cdt.autotools.tool.autogen"; //$NON-NLS-1$
+ public final String CONFIGURE_TOOL_ID = "org.eclipse.linuxtools.cdt.autotools.tool.configure"; //$NON-NLS-1$
+
+ public final String GENERATED_TARGET = AutotoolsPlugin.PLUGIN_ID + ".generated.MakeTarget"; //$NON-NLS-1$
+
+ private static final String MAKE_TARGET_KEY = MakeCorePlugin.getUniqueIdentifier() + ".buildtargets"; //$NON-NLS-1$
+ private static final String BUILD_TARGET_ELEMENT = "buildTargets"; //$NON-NLS-1$
+ private static final String TARGET_ELEMENT = "target"; //$NON-NLS-1$
+ private static final String TARGET_ATTR_ID = "targetID"; //$NON-NLS-1$
+ private static final String TARGET_ATTR_PATH = "path"; //$NON-NLS-1$
+ private static final String TARGET_ATTR_NAME = "name"; //$NON-NLS-1$
+ private static final String TARGET_STOP_ON_ERROR = "stopOnError"; //$NON-NLS-1$
+ private static final String TARGET_USE_DEFAULT_CMD = "useDefaultCommand"; //$NON-NLS-1$
+ private static final String TARGET_ARGUMENTS = "buildArguments"; //$NON-NLS-1$
+ private static final String TARGET_COMMAND = "buildCommand"; //$NON-NLS-1$
+ private static final String TARGET_RUN_ALL_BUILDERS = "runAllBuilders";
+ private static final String TARGET = "buildTarget"; //$NON-NLS-1$
+
+ private IProject project;
+
+ private IProgressMonitor monitor;
+
+ private String buildDir;
+ private String srcDir;
+
+ private IConfiguration cfg;
+ private IBuilder builder;
+
+ public void generateDependencies() throws CoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public MultiStatus generateMakefiles(IResourceDelta delta)
+ throws CoreException {
+ return regenerateMakefiles();
+ }
+
+ private void initializeBuildConfigDirs() {
+ ITool tool = cfg.getToolFromOutputExtension("status"); //$NON-NLS-1$
+ IOption[] options = tool.getOptions();
+ for (int i = 0; i < options.length; ++i) {
+ String id = options[i].getId();
+ if (id.indexOf("builddir") > 0) { //$NON-NLS-1$
+ buildDir = (String) options[i].getValue();
+ try {
+ String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValue(buildDir, "build", null,
+ IBuildMacroProvider.CONTEXT_CONFIGURATION, cfg);
+ buildDir = resolved;
+ } catch (BuildMacroException e) {
+ // do nothing
+ }
+// try {
+// builder.setBuildAttribute(IMakeCommonBuildInfo.BUILD_LOCATION,
+// project.getLocation().append(buildDir).toOSString());
+// } catch (CoreException e) {
+// e.printStackTrace();
+// }
+ } else if (id.indexOf("configdir") > 0) { //$NON-NLS-1$
+ srcDir = (String) options[i].getValue();
+ try {
+ String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValue(srcDir, "", null,
+ IBuildMacroProvider.CONTEXT_CONFIGURATION, cfg);
+ srcDir = resolved;
+ } catch (BuildMacroException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
+ public void initialize(IProject project, IManagedBuildInfo info,
+ IProgressMonitor monitor) {
+ this.project = project;
+ this.cfg = info.getDefaultConfiguration();
+ this.builder = cfg.getBuilder();
+ this.monitor = monitor;
+ initializeBuildConfigDirs();
+ }
+
+ public void initialize(int buildKind, IConfiguration cfg, IBuilder builder,
+ IProgressMonitor monitor) {
+ this.cfg = cfg;
+ this.builder = builder;
+ this.monitor = monitor;
+ this.project = (IProject)cfg.getManagedProject().getOwner();
+ initializeBuildConfigDirs();
+ }
+
+ public IProject getProject() {
+ return project;
+ }
+
+ public boolean isGeneratedResource(IResource resource) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void regenerateDependencies(boolean force) throws CoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc) Check whether the build has been cancelled. Cancellation
+ * requests propagated to the caller by throwing <code>OperationCanceledException</code>.
+ *
+ * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException()
+ */
+ protected void checkCancel() {
+ if (monitor != null && monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ /*
+ * (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
+ */
+ protected 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;
+ }
+
+ /*
+ * (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 boolean createDirectory(String dirName) throws CoreException {
+ // Create or get the handle for the build directory
+ boolean rc = true;
+ IPath path = new Path(dirName);
+ if (dirName.length() == 0 || dirName.startsWith(".") || !dirName.startsWith("/"))
+ path = project.getLocation().append(dirName);
+ File f = path.toFile();
+ if (!f.exists())
+ rc = f.mkdirs();
+
+ return rc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#getBuildWorkingDir()
+ */
+ public IPath getBuildWorkingDir() {
+ return new Path(buildDir);
+ }
+
+ /*
+ * (non-Javadoc) Get the project's absolute path. @return IPath
+ */
+ private IPath getProjectLocation() {
+ return project.getLocation();
+ }
+
+ private String getAbsoluteDirectory(String dir) {
+ IPath path = new Path(dir);
+ if (!path.isAbsolute()) {
+ IPath absPath = getProjectLocation().addTrailingSeparator().append(
+ path);
+ return getPathString(absPath);
+ }
+ return dir;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#getMakefileName()
+ */
+ public String getMakefileName() {
+ return new String(MAKEFILE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @return the path to the configuration settings file
+ */
+ protected IPath getConfigSettingsPath() {
+ IPath path = project.getWorkingLocation(AutotoolsPlugin.PLUGIN_ID).append(SETTINGS_FILE_NAME + "." + cfg.getName()); //$NON-NLS-1$
+ return path;
+ }
+
+ public void removeConfigSettings() {
+ File f = getConfigSettingsPath().toFile();
+ try {
+ f.delete();
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+
+ public MultiStatus regenerateMakefiles() throws CoreException {
+ MultiStatus status;
+ int rc = IStatus.OK;
+ String errMsg = new String();
+ boolean needFullConfigure = true;
+
+ // See if the user has cancelled the build
+ checkCancel();
+
+ // Create the top-level directory for the build output
+ if (!createDirectory(buildDir)) {
+ rc = IStatus.ERROR;
+ errMsg = AutotoolsPlugin.getFormattedString("MakeGenerator.createdir.error", //$NON-NLS-1$
+ new String[] {buildDir});
+ return new MultiStatus(AutotoolsPlugin.getUniqueIdentifier(),
+ rc, errMsg, null);
+ }
+
+ checkCancel();
+
+ // // How did we do
+ // if (!getInvalidDirList().isEmpty()) {
+ // status = new MultiStatus (
+ // ManagedBuilderCorePlugin.getUniqueIdentifier(),
+ // IStatus.WARNING,
+ // new String(),
+ // null);
+ // // Add a new status for each of the bad folders
+ // iter = getInvalidDirList().iterator();
+ // while (iter.hasNext()) {
+ // status.add(new Status (
+ // IStatus.WARNING,
+ // ManagedBuilderCorePlugin.getUniqueIdentifier(),
+ // SPACES_IN_PATH,
+ // ((IContainer)iter.next()).getFullPath().toString(),
+ // null));
+ // }
+ // } else {
+ // status = new MultiStatus(
+ // ManagedBuilderCorePlugin.getUniqueIdentifier(),
+ // IStatus.OK,
+ // new String(),
+ // null);
+ // }
+
+ // Get a build console for the project
+ IConsole console = CCorePlugin.getDefault().getConsole("org.eclipse.linuxtools.cdt.autotools.configureConsole"); //$NON-NLS-1$
+
+ // Get the project and make sure there's a monitor to cancel the build
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+
+ try {
+ // If a config.status file exists in the build directory, we call it
+ // to
+ // regenerate the makefile
+ IPath configfile = getProjectLocation().append(buildDir).append(
+ CONFIG_STATUS);
+ IPath makefilePath = getProjectLocation().append(buildDir).append(MAKEFILE);
+ File configStatus = configfile.toFile();
+ File makefile = makefilePath.toFile();
+ IPath configSettingsPath = getConfigSettingsPath();
+ File configSettings = configSettingsPath.toFile();
+ String[] configArgs = getConfigArgs();
+
+ // We need to figure out if the end-user has changed the configuration
+ // settings. In such a case, we need to reconfigure from scratch
+ // regardless of whether config.status exists or not.
+ // We figure this out by saving the configuration settings to
+ // a special file and reading/comparing whenever we are asked to build.
+ if (configSettings.exists()) {
+ int i = 0;
+ boolean needSaveConfigArgs = false;
+ needFullConfigure = false;
+ try {
+ DataInputStream settings = new DataInputStream(
+ new BufferedInputStream(new FileInputStream(configSettings)));
+ // Get the first String in the configure settings file.
+ // Newer configure settings file start with the project name.
+ // If the project name is present and doesn't match the
+ // current project name, the project has been refactored and
+ // we need to do a full reconfigure.
+ settings.mark(100);
+ String s = settings.readUTF();
+ if (s.startsWith("project=")) { //$NON-NLS-1$
+ if (!s.substring(8).equals(project.getName())) {
+ needFullConfigure = true;
+ }
+ } else {
+ // An older configure arguments file. Reset
+ // to beginning and process as normal.
+ needSaveConfigArgs = true;
+ settings.reset();
+ }
+ while (i < configArgs.length) {
+ s = settings.readUTF();
+ if (!s.equals(configArgs[i])) {
+ i = configArgs.length;
+ needFullConfigure = true;
+ }
+ ++i;
+ }
+ if (settings.available() > 0)
+ needFullConfigure = true;
+ } catch (EOFException e) {
+ needFullConfigure = true;
+ } catch (IOException e) {
+ needFullConfigure = true;
+ }
+ if (needFullConfigure) {
+ // If we are going to do a full reconfigure, then if the current
+ // build directory exists, we should clean it out first. This is
+ // because the reconfiguration could change compile flags, etc..
+ // and the Makefile might not detect a rebuild is required. In
+ // addition, the build directory itself could have been changed and
+ // we should remove the previous build.
+ File r = project.getLocation().append(buildDir).toFile();
+ if (r != null && r.exists()) {
+ // See what type of cleaning the user has set up in the
+ // build properties dialog.
+ String cleanDelete = null;
+ try {
+ cleanDelete = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+
+ if (cleanDelete != null && cleanDelete.equals(AutotoolsPropertyConstants.TRUE)) {
+ SubProgressMonitor sub = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN);
+ sub.beginTask(AutotoolsPlugin.getResourceString("MakeGenerator.clean.builddir"), IProgressMonitor.UNKNOWN);
+ try {
+ r.delete();
+ } finally {
+ sub.done();
+ }
+ }
+ else {
+ // There is a make target for cleaning.
+ if (makefile != null && makefile.exists()) {
+ String[] makeargs = new String[1];
+ IPath makeCmd = new Path("make"); //$NON-NLS-1$
+ String target = null;
+ try {
+ target = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+ if (target == null)
+ target = AutotoolsPropertyConstants.CLEAN_MAKE_TARGET_DEFAULT;
+ String args = builder.getBuildArguments();
+ if (args != null && !(args = args.trim()).equals("")) { //$NON-NLS-1$
+ String[] newArgs = makeArray(args);
+ makeargs = new String[newArgs.length + 1];
+ System.arraycopy(newArgs, 0, makeargs, 0, newArgs.length);
+ }
+ makeargs[makeargs.length - 1] = target;
+ rc = runCommand(makeCmd,
+ project.getLocation().append(buildDir),
+ makeargs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.clean.builddir"), //$NON-NLS-1$
+ errMsg, console, true);
+ }
+ }
+ }
+ initializeBuildConfigDirs();
+ createDirectory(buildDir);
+ // Mark the scanner info as dirty.
+ try {
+ project.setSessionProperty(AutotoolsPropertyConstants.SCANNER_INFO_DIRTY, Boolean.TRUE);
+ } catch (CoreException ce) {
+ // do nothing
+ }
+ } else if (needSaveConfigArgs) {
+ // No change in configuration args, but we have old
+ // style settings format which can't determine if project has
+ // been renamed. Refresh the settings file.
+ saveConfigArgs(configArgs);
+ }
+ }
+
+ ArrayList<String> configureEnvs = new ArrayList<String>();
+ IPath configurePath = getConfigurePath(configureEnvs);
+ ArrayList<String> autogenEnvs = new ArrayList<String>();
+ IPath autogenPath = getAutogenPath(autogenEnvs);
+
+ // Check if we have a config.status (meaning configure has already run).
+ if (!needFullConfigure && configStatus != null && configStatus.exists()) {
+ // If no corresponding Makefile in the same build location, then we
+ // can simply run config.status again to ensure the top level Makefile has been
+ // created.
+ if (makefile == null || !makefile.exists()) {
+ rc = runScript(configfile, project.getLocation().append(
+ buildDir), null,
+ AutotoolsPlugin.getResourceString("MakeGenerator.run.config.status"), //$NON-NLS-1$
+ errMsg, console, null, true);
+ }
+ }
+ // Look for configure and configure from scratch
+ else if (configurePath.toFile().exists()) {
+ rc = runScript(configurePath,
+ project.getLocation().append(buildDir),
+ configArgs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.gen.makefile"), //$NON-NLS-1$
+ errMsg, console, configureEnvs, true);
+ if (rc != IStatus.ERROR) {
+ File makefileFile = project.getLocation().append(buildDir)
+ .append(MAKEFILE).toFile();
+ addMakeTargetsToManager(makefileFile);
+ // TODO: should we do something special if configure doesn't
+ // return ok?
+ saveConfigArgs(configArgs);
+ }
+ }
+ // If no configure, look for autogen.sh which may create configure and
+ // possibly even run it.
+ else if (autogenPath.toFile().exists()) {
+ // Remove the existing config.status file since we use it
+ // to figure out if configure was run.
+ if (configStatus.exists())
+ configStatus.delete();
+ // Get any user-specified arguments for autogen.
+ String[] autogenArgs = getAutogenArgs();
+ rc = runScript(autogenPath,
+ autogenPath.removeLastSegments(1), autogenArgs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.autogen.sh"), //$NON-NLS-1$
+ errMsg, console, autogenEnvs, true);
+ if (rc != IStatus.ERROR) {
+ configStatus =configfile.toFile();
+ // Check for config.status. If it is created, then
+ // autogen.sh ran configure and we should not run it
+ // ourselves.
+ if (configStatus == null || !configStatus.exists()) {
+ rc = runScript(configurePath,
+ project.getLocation().append(buildDir),
+ configArgs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.gen.makefile"), //$NON-NLS-1$
+ errMsg, console, configureEnvs, false);
+ if (rc != IStatus.ERROR) {
+ File makefileFile = project.getLocation().append(buildDir)
+ .append(MAKEFILE).toFile();
+ addMakeTargetsToManager(makefileFile);
+ }
+ } else {
+ File makefileFile = project.getLocation().append(buildDir)
+ .append(MAKEFILE).toFile();
+ addMakeTargetsToManager(makefileFile);
+ }
+ }
+ }
+ // If nothing this far, look for a Makefile.cvs file which needs to be run.
+ else if (makefileCvsExists()) {
+ String[] makeargs = new String[1];
+ IPath makeCmd = new Path("make"); //$NON-NLS-1$
+ makeargs[0] = "-f" + getMakefileCVSPath().toOSString(); //$NON-NLS-1$
+ rc = runCommand(makeCmd,
+ project.getLocation().append(buildDir),
+ makeargs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.makefile.cvs"), //$NON-NLS-1$
+ errMsg, console, true);
+ if (rc != IStatus.ERROR) {
+ File makefileFile = project.getLocation().append(buildDir)
+ .append(MAKEFILE).toFile();
+ addMakeTargetsToManager(makefileFile);
+ saveConfigArgs(configArgs);
+ }
+ }
+ // If nothing this far, try running autoreconf -i
+ else {
+ String[] reconfArgs = new String[1];
+ String reconfCmd = project.getPersistentProperty(AutotoolsPropertyConstants.AUTORECONF_TOOL);
+ if (reconfCmd == null)
+ reconfCmd = "autoreconf"; // $NON-NLS-1$
+ IPath reconfCmdPath = new Path(reconfCmd);
+ reconfArgs[0] = "-i"; //$NON-NLS-1$
+ rc = runCommand(reconfCmdPath,
+ project.getLocation().append(srcDir),
+ reconfArgs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.autoreconf"), //$NON-NLS-1$
+ errMsg, console, true);
+ // Check if configure generated and if yes, run it.
+ if (rc != IStatus.ERROR) {
+ if (configurePath.toFile().exists()) {
+
+ rc = runScript(configurePath,
+ project.getLocation().append(buildDir),
+ configArgs,
+ AutotoolsPlugin.getResourceString("MakeGenerator.gen.makefile"), //$NON-NLS-1$
+ errMsg, console, configureEnvs, false);
+ if (rc != IStatus.ERROR) {
+ File makefileFile = project.getLocation().append(buildDir)
+ .append(MAKEFILE).toFile();
+ addMakeTargetsToManager(makefileFile);
+ // TODO: should we do something special if configure doesn't
+ // return ok?
+ saveConfigArgs(configArgs);
+ }
+ }
+ }
+ }
+
+ // Treat no Makefile as generation error.
+ if (makefile == null || !makefile.exists()) {
+ rc = IStatus.ERROR;
+ errMsg = AutotoolsPlugin.getResourceString("MakeGenerator.didnt.generate"); //$NON-NLS-1$
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ // forgetLastBuiltState();
+ rc = IStatus.ERROR;
+ } finally {
+ // getGenerationProblems().clear();
+ status = new MultiStatus(AutotoolsPlugin
+ .getUniqueIdentifier(), rc, errMsg, null);
+ }
+ return status;
+ }
+
+ /**
+ * Strip a command of VAR=VALUE pairs that appear ahead of the command and add
+ * them to a list of environment variables.
+ *
+ * @param command - command to strip
+ * @param envVars - ArrayList to add environment variables to
+ * @return stripped command
+ */
+ public static String stripEnvVars(String command, ArrayList<String> envVars) {
+ Pattern p = Pattern.compile("(\\w+[=]([$]?\\w+[:;]?)+\\s+)\\w+.*");
+ Pattern p2 = Pattern.compile("(\\w+[=]\\\".*?\\\"\\s+)\\w+.*");
+ Pattern p3 = Pattern.compile("(\\w+[=]'.*?'\\s+)\\w+.*");
+ boolean finished = false;
+ while (!finished) {
+ Matcher m = p.matcher(command);
+ if (m.matches()) {
+ command = command.replaceFirst("\\w+[=]([$]?\\w+[:;]?)+", "").trim();
+ envVars.add(m.group(1).trim());
+ } else {
+ Matcher m2 = p2.matcher(command);
+ if (m2.matches()) {
+ command = command.replaceFirst("\\w+[=]\\\".*?\\\"","").trim();
+ String s = m2.group(1).trim();
+ envVars.add(s.replaceAll("\\\"", ""));
+ } else {
+ Matcher m3 = p3.matcher(command);
+ if (m3.matches()) {
+ command = command.replaceFirst("\\w+[=]'.*?'", "").trim();
+ String s = m3.group(1).trim();
+ envVars.add(s.replaceAll("'", ""));
+ } else {
+ finished = true;
+ }
+ }
+ }
+ }
+ return command;
+ }
+
+ protected IPath getConfigurePath(ArrayList<String> envVars) {
+ IPath configPath;
+ ITool[] tool = cfg.getToolsBySuperClassId(CONFIGURE_TOOL_ID);
+ String command = stripEnvVars(tool[0].getToolCommand().trim(), envVars);
+
+ if (srcDir.equals(""))
+ configPath = project.getLocation().append(command);
+ else
+ configPath = project.getLocation().append(srcDir).append(command);
+ return configPath;
+ }
+
+ protected IPath getMakefileCVSPath() {
+ IPath makefileCVSPath;
+ if (srcDir.equals(""))
+ makefileCVSPath = project.getLocation().append(MAKEFILE_CVS);
+ else
+ makefileCVSPath= project.getLocation().append(srcDir).append(
+ MAKEFILE_CVS);
+ return makefileCVSPath;
+ }
+
+ protected boolean makefileCvsExists() {
+ IPath makefileCVSPath = getMakefileCVSPath();
+ return makefileCVSPath.toFile().exists();
+ }
+
+ protected IPath getAutogenPath(ArrayList<String> envVars) {
+ IPath autogenPath;
+ ITool[] tool = cfg.getToolsBySuperClassId(AUTOGEN_TOOL_ID);
+ String command = stripEnvVars(tool[0].getToolCommand().trim(), envVars);
+
+ if (srcDir.equals(""))
+ autogenPath = project.getLocation().append(command);
+ else
+ autogenPath = project.getLocation().append(srcDir).append(command);
+ return autogenPath;
+ }
+
+ private void saveConfigArgs(String[] args) {
+ IPath settingsPath = getConfigSettingsPath();
+ try {
+ File f = settingsPath.toFile();
+ DataOutputStream settings = new DataOutputStream(
+ new BufferedOutputStream(new FileOutputStream(f)));
+ // Write the project name in the configure arguments
+ // so we know if the project gets refactored.
+ settings.writeUTF("project=" + project.getName()); //$NON-NLS-1$
+ for (int i = 0; i < args.length; ++i) {
+ settings.writeUTF(args[i]);
+ }
+ settings.close();
+ } catch (IOException e) {
+ /* What should we do? */
+ }
+ }
+
+ private String[] getAutogenArgs() throws BuildException {
+ // Get the arguments to be passed to config from build model
+ ITool[] tool = cfg.getToolsBySuperClassId(AUTOGEN_TOOL_ID);
+ IOption[] options = tool[0].getOptions();
+ ArrayList<String> autogenArgs = new ArrayList<String>();
+
+ for (int i = 0; i < options.length; ++i) {
+ if (options[i].getValueType() == IOption.STRING) {
+ String value = (String) options[i].getValue();
+ try {
+ String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValue(value, "", null,
+ IBuildMacroProvider.CONTEXT_CONFIGURATION, cfg);
+ value = resolved;
+ } catch (BuildMacroException e) {
+ // do nothing
+ }
+ String id = options[i].getId();
+ if (id.indexOf("user") > 0) { //$NON-NLS-1$
+ // May be multiple user-specified options in which case we
+ // need to split them up into individual options
+ value = value.trim();
+ boolean finished = false;
+ int lastIndex = value.indexOf("--"); //$NON-NLS-1$
+ if (lastIndex != -1) {
+ while (!finished) {
+ int index = value.indexOf("--",lastIndex+2); //$NON-NLS-1$
+ if (index != -1) {
+ String previous = value.substring(lastIndex, index).trim();
+ autogenArgs.add(previous);
+ value = value.substring(index);
+ } else {
+ autogenArgs.add(value);
+ finished = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return (String[]) autogenArgs.toArray(new String[autogenArgs.size()]);
+ }
+
+ private String[] getConfigArgs() throws BuildException {
+ // Get the arguments to be passed to config from build model
+ ITool tool = cfg.getToolFromOutputExtension("status"); //$NON-NLS-1$
+ IOption[] options = tool.getOptions();
+ ArrayList<String> configArgs = new ArrayList<String>();
+ for (int i = 0; i < options.length; ++i) {
+ if (options[i].getValueType() == IOption.STRING) {
+ String value = (String) options[i].getValue();
+ try {
+ String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValue(value, "", null,
+ IBuildMacroProvider.CONTEXT_CONFIGURATION, cfg);
+ value = resolved;
+ } catch (BuildMacroException e) {
+ // do nothing
+ }
+ String id = options[i].getId();
+ if (id.indexOf("configdir") > 0 || id.indexOf("builddir") > 0) //$NON-NLS-1$ $NON-NLS-2$
+ continue;
+ else if (id.indexOf("user") > 0) { //$NON-NLS-1$
+ // May be multiple user-specified options in which case we
+ // need to split them up into individual options
+ value = value.trim();
+ boolean finished = false;
+ int lastIndex = value.indexOf("--"); //$NON-NLS-1$
+ if (lastIndex != -1) {
+ while (!finished) {
+ int index = value.indexOf("--",lastIndex+2); //$NON-NLS-1$
+ if (index != -1) {
+ String previous = value.substring(lastIndex, index).trim();
+ configArgs.add(previous);
+ value = value.substring(index);
+ } else {
+ configArgs.add(value);
+ finished = true;
+ }
+ }
+ } else {
+ // No --xxx arguments, but there might still be some NAME=VALUE args
+ // and we should pass them on regardless
+ configArgs.add(value);
+ }
+ }
+ else if (value.trim().length() > 0) {
+ String categoryId = options[i].getCategory().getId();
+ if (categoryId.indexOf("directories") >= 0) //$NON-NLS-1$
+ value = getAbsoluteDirectory(value);
+ String cmd = options[i].getCommand().concat(value);
+ configArgs.add(cmd);
+ }
+ } else if (options[i].getValueType() == IOption.BOOLEAN) {
+ Boolean value = (Boolean) options[i].getValue();
+ if (value.booleanValue())
+ configArgs.add(options[i].getCommand());
+ else if (!options[i].getCommandFalse().equals(""))
+ configArgs.add(options[i].getCommandFalse());
+ }
+ }
+ return (String[]) configArgs.toArray(new String[configArgs.size()]);
+ }
+
+ // Run a command or executable (e.g. make).
+ private int runCommand(IPath commandPath, IPath runPath, String[] args,
+ String jobDescription, String errMsg, IConsole console,
+ boolean consoleStart) throws BuildException, CoreException,
+ NullPointerException, IOException {
+ // TODO: Figure out what this next stuff is used for
+ // //try to resolve the build macros in the builder command
+ // try{
+ // String resolved =
+ // ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(
+ // configCmd,
+ // "", //$NON-NLS-1$
+ // " ", //$NON-NLS-1$
+ // IBuildMacroProvider.CONTEXT_CONFIGURATION,
+ // info.getDefaultConfiguration());
+ // if((resolved = resolved.trim()).length() > 0)
+ // configCmd = resolved;
+ // } catch (BuildMacroException e){
+ // }
+
+ int rc = IStatus.OK;
+
+ removeAllMarkers(project);
+
+ String[] configTargets = args;
+ if (args == null)
+ configTargets = new String[0];
+
+ String[] msgs = new String[2];
+ msgs[0] = commandPath.toString();
+ msgs[1] = project.getName();
+ monitor.subTask(AutotoolsPlugin.getFormattedString(
+ "MakeGenerator.make.message", msgs)); //$NON-NLS-1$
+
+
+ ConsoleOutputStream consoleOutStream = null;
+ StringBuffer buf = new StringBuffer();
+
+ // Launch command - main invocation
+ if (consoleStart)
+ console.start(project);
+ consoleOutStream = console.getOutputStream();
+ String[] consoleHeader = new String[3];
+
+ consoleHeader[0] = jobDescription;
+ consoleHeader[1] = cfg.getName();
+ consoleHeader[2] = project.getName();
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ buf.append(jobDescription);
+ 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$
+
+ if (!cfg.isSupported()) {
+ String msgArgs[] = new String[1];
+ msgArgs[0] = cfg.getName();
+ buf.append(AutotoolsPlugin.getFormattedString("MakeGenerator.unsupportedConfig", msgArgs));
+ 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();
+
+ // Get a launcher for the config command
+ CommandLauncher launcher = new CommandLauncher();
+ // Set the environment
+ IEnvironmentVariable variables[] = ManagedBuildManager
+ .getEnvironmentVariableProvider().getVariables(cfg, true);
+ String[] env = null;
+ ArrayList<String> envList = new ArrayList<String>();
+ 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(project, topBuildDir,
+ // this, errorParsers);
+ // epm.setOutputStream(consoleOutStream);
+ OutputStream stdout = consoleOutStream;
+ OutputStream stderr = consoleOutStream;
+
+ launcher.showCommand(true);
+ Process proc = launcher.execute(commandPath, configTargets, env,
+ runPath, new NullProgressMonitor());
+ 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(stdout, stderr, 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
+ // ensure
+ // the UI is up-to-date with the build results
+ // monitor.subTask(ManagedMakeMessages
+ // .getResourceString(REFRESH));
+ monitor.subTask(AutotoolsPlugin.getResourceString("MakeGenerator.refresh")); //$NON-NLS-1$
+ try {
+ project.refreshLocal(IResource.DEPTH_INFINITE, null);
+ } catch (CoreException e) {
+ monitor.subTask(AutotoolsPlugin
+ .getResourceString("MakeGenerator.refresh.error")); //$NON-NLS-1$
+ }
+ } else {
+ errMsg = launcher.getErrorMessage();
+ }
+
+ // Report either the success or failure of our mission
+ buf = new StringBuffer();
+ if (errMsg != null && errMsg.length() > 0) {
+ String errorDesc = AutotoolsPlugin
+ .getResourceString("MakeGenerator.generation.error"); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ 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$
+ rc = IStatus.ERROR;
+ } else if (proc.exitValue() >= 1 || proc.exitValue() < 0) {
+ // We have an invalid return code from configuration.
+ String[] errArg = new String[2];
+ errArg[0] = Integer.toString(proc.exitValue());
+ errArg[1] = commandPath.toString();
+ errMsg = AutotoolsPlugin.getFormattedString(
+ "MakeGenerator.config.error", errArg); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ buf.append(AutotoolsPlugin.getResourceString("MakeGenerator.generation.error")); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ if (proc.exitValue() == 1)
+ rc = IStatus.WARNING;
+ else
+ rc = IStatus.ERROR;
+ } else {
+ // Report a successful build
+ String successMsg =
+ AutotoolsPlugin.getResourceString("MakeGenerator.success"); //$NON-NLS-1$
+ buf.append(successMsg);
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ rc = IStatus.OK;
+ }
+
+ // Write message on the console
+ consoleOutStream.write(buf.toString().getBytes());
+ consoleOutStream.flush();
+
+ // // Generate any error markers that the build has discovered
+ // monitor.subTask(ManagedMakeMessages
+ // .getResourceString(MARKERS));
+ // epm.reportProblems();
+ consoleOutStream.close();
+
+ // TODO: For now, add a marker with our generated error message.
+ // In the future, we might add an error parser to do this properly
+ // and give the actual error line, etc..
+ if (rc == IStatus.ERROR) {
+ addMarker(project, -1, errMsg, SEVERITY_ERROR_BUILD, null);
+ // Mark the configuration as needing a full rebuild.
+ cfg.setRebuildState(true);
+ }
+
+ return rc;
+ }
+
+ // Get the path string. We add a Win check to handle MingW.
+ // For MingW, we would rather represent C:\a\b as /C/a/b which
+ // doesn't cause Makefile to choke.
+ // TODO: further logic would be needed to handle cygwin if desired
+ private String getPathString(IPath path) {
+ String s = path.toString();
+ if (Platform.getOS().equals(Platform.OS_WIN32))
+ s = s.replaceAll("^([A-Z])(:)", "/$1");
+ return s;
+ }
+
+ // Run an autotools script (e.g. configure, autogen.sh, config.status).
+ private int runScript(IPath commandPath, IPath runPath, String[] args,
+ String jobDescription, String errMsg, IConsole console,
+ ArrayList<String> additionalEnvs,
+ boolean consoleStart) throws BuildException, CoreException,
+ NullPointerException, IOException {
+ // TODO: Figure out what this next stuff is used for
+ // //try to resolve the build macros in the builder command
+ // try{
+ // String resolved =
+ // ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(
+ // configCmd,
+ // "", //$NON-NLS-1$
+ // " ", //$NON-NLS-1$
+ // IBuildMacroProvider.CONTEXT_CONFIGURATION,
+ // info.getDefaultConfiguration());
+ // if((resolved = resolved.trim()).length() > 0)
+ // configCmd = resolved;
+ // } catch (BuildMacroException e){
+ // }
+
+ int rc = IStatus.OK;
+
+ removeAllMarkers(project);
+
+ // We want to run the script via the shell command. So, we add the command
+ // script as the first argument and expect "sh" to be on the runtime path.
+ // Any other arguments are placed after the script name.
+ String[] configTargets = null;
+ if (args == null)
+ configTargets = new String[1];
+ else {
+ configTargets = new String[args.length+1];
+ System.arraycopy(args, 0, configTargets, 1, args.length);
+ }
+ configTargets[0] = getPathString(commandPath);
+
+ String[] msgs = new String[2];
+ msgs[0] = commandPath.toString();
+ msgs[1] = project.getName();
+ monitor.subTask(AutotoolsPlugin.getFormattedString(
+ "MakeGenerator.make.message", msgs)); //$NON-NLS-1$
+
+
+ ConsoleOutputStream consoleOutStream = null;
+ StringBuffer buf = new StringBuffer();
+
+ // Launch command - main invocation
+ if (consoleStart)
+ console.start(project);
+ consoleOutStream = console.getOutputStream();
+ String[] consoleHeader = new String[3];
+
+ consoleHeader[0] = jobDescription;
+ consoleHeader[1] = cfg.getName();
+ consoleHeader[2] = project.getName();
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ buf.append(jobDescription);
+ 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$
+
+ if (!cfg.isSupported()) {
+ String msgArgs[] = new String[1];
+ msgArgs[0] = cfg.getName();
+ buf.append(AutotoolsPlugin.getFormattedString("MakeGenerator.unsupportedConfig", msgArgs)); // $NON-NLS-1$
+ 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();
+
+ // Get a launcher for the config command
+ CommandLauncher launcher = new CommandLauncher();
+ // Set the environment
+ IEnvironmentVariable variables[] = ManagedBuildManager
+ .getEnvironmentVariableProvider().getVariables(cfg, true);
+ String[] env = null;
+ ArrayList<String> envList = new ArrayList<String>();
+ if (variables != null) {
+ for (int i = 0; i < variables.length; i++) {
+ envList.add(variables[i].getName()
+ + "=" + variables[i].getValue()); //$NON-NLS-1$
+ }
+ if (additionalEnvs != null)
+ envList.addAll(additionalEnvs); // add any additional environment variables specified ahead of script
+ env = (String[]) envList.toArray(new String[envList.size()]);
+ }
+
+ // // Hook up an error parser manager
+ // String[] errorParsers =
+ // info.getDefaultConfiguration().getErrorParserList();
+ // ErrorParserManager epm = new ErrorParserManager(project, topBuildDir,
+ // this, errorParsers);
+ // epm.setOutputStream(consoleOutStream);
+ OutputStream stdout = consoleOutStream;
+ OutputStream stderr = consoleOutStream;
+
+ launcher.showCommand(true);
+ // Run the shell script via shell command.
+ Process proc = launcher.execute(new Path(SHELL_COMMAND), configTargets, env,
+ runPath, new NullProgressMonitor());
+ 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(stdout, stderr, 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
+ // ensure
+ // the UI is up-to-date with the build results
+ // monitor.subTask(ManagedMakeMessages
+ // .getResourceString(REFRESH));
+ monitor.subTask(AutotoolsPlugin.getResourceString("MakeGenerator.refresh")); //$NON-NLS-1$
+ try {
+ project.refreshLocal(IResource.DEPTH_INFINITE, null);
+ } catch (CoreException e) {
+ monitor.subTask(AutotoolsPlugin
+ .getResourceString("MakeGenerator.refresh.error")); //$NON-NLS-1$
+ }
+ } else {
+ errMsg = launcher.getErrorMessage();
+ }
+
+ // Report either the success or failure of our mission
+ buf = new StringBuffer();
+ if (errMsg != null && errMsg.length() > 0) {
+ String errorDesc = AutotoolsPlugin
+ .getResourceString("MakeGenerator.generation.error"); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ 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$
+ rc = IStatus.ERROR;
+ } else if (proc.exitValue() >= 1 || proc.exitValue() < 0) {
+ // We have an invalid return code from configuration.
+ String[] errArg = new String[2];
+ errArg[0] = Integer.toString(proc.exitValue());
+ errArg[1] = commandPath.toString();
+ errMsg = AutotoolsPlugin.getFormattedString(
+ "MakeGenerator.config.error", errArg); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ buf.append(AutotoolsPlugin.getResourceString("MakeGenerator.generation.error")); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ if (proc.exitValue() == 1)
+ rc = IStatus.WARNING;
+ else
+ rc = IStatus.ERROR;
+ } else {
+ // Report a successful build
+ String successMsg =
+ AutotoolsPlugin.getResourceString("MakeGenerator.success"); //$NON-NLS-1$
+ buf.append(successMsg);
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
+ rc = IStatus.OK;
+ }
+
+ // Write message on the console
+ consoleOutStream.write(buf.toString().getBytes());
+ consoleOutStream.flush();
+
+ // // Generate any error markers that the build has discovered
+ // monitor.subTask(ManagedMakeMessages
+ // .getResourceString(MARKERS));
+ // epm.reportProblems();
+ consoleOutStream.close();
+
+ // TODO: For now, add a marker with our generated error message.
+ // In the future, we might add an error parser to do this properly
+ // and give the actual error line, etc..
+ if (rc == IStatus.ERROR) {
+ addMarker(project, -1, errMsg, SEVERITY_ERROR_BUILD, null);
+ // Mark the configuration as needing a full rebuild.
+ cfg.setRebuildState(true);
+ }
+
+ return rc;
+ }
+
+ private ICStorageElement createTargetElement(ICStorageElement parent, IMakeTarget target) {
+ ICStorageElement targetElem = parent.createChild(TARGET_ELEMENT);
+ targetElem.setAttribute(TARGET_ATTR_NAME, target.getName());
+ targetElem.setAttribute(TARGET_ATTR_ID, target.getTargetBuilderID());
+ targetElem.setAttribute(TARGET_ATTR_PATH, target.getContainer().getProjectRelativePath().toString());
+ ICStorageElement elem = targetElem.createChild(TARGET_COMMAND);
+ elem.setValue(target.getBuildAttribute(IMakeCommonBuildInfo.BUILD_COMMAND, "make")); //$NON-NLS-1$
+
+ String targetAttr = target.getBuildAttribute(IMakeCommonBuildInfo.BUILD_ARGUMENTS, null);
+ if ( targetAttr != null) {
+ elem = targetElem.createChild(TARGET_ARGUMENTS);
+ elem.setValue(targetAttr);
+ }
+
+ targetAttr = target.getBuildAttribute(IMakeTarget.BUILD_TARGET, null);
+ if (targetAttr != null) {
+ elem = targetElem.createChild(TARGET);
+ elem.setValue(targetAttr);
+ }
+
+ elem = targetElem.createChild(TARGET_STOP_ON_ERROR);
+ elem.setValue(new Boolean(target.isStopOnError()).toString());
+
+ elem = targetElem.createChild(TARGET_USE_DEFAULT_CMD);
+ elem.setValue(new Boolean(target.isDefaultBuildCmd()).toString());
+
+ elem = targetElem.createChild(TARGET_RUN_ALL_BUILDERS);
+ elem.setValue(new Boolean(target.runAllBuilders()).toString());
+
+ return targetElem;
+ }
+
+ /**
+ * This output method saves the information into the .cdtproject metadata file.
+ *
+ * @param doc
+ * @throws CoreException
+ */
+ private void saveTargets(IMakeTarget[] makeTargets) throws CoreException {
+ ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(getProject(), true);
+ ICStorageElement rootElement = descriptor.getProjectStorageElement(MAKE_TARGET_KEY);
+
+ //Nuke the children since we are going to write out new ones
+ rootElement.clear();
+
+ // Fetch the ProjectTargets as ICStorageElements
+ rootElement = rootElement.createChild(BUILD_TARGET_ELEMENT);
+ for (int i = 0; i < makeTargets.length; ++i)
+ createTargetElement(rootElement, makeTargets[i]);
+
+ //Save the results
+ descriptor.saveProjectData();
+ }
+
+
+ protected class MakeTargetComparator implements Comparator<Object> {
+ public int compare(Object a, Object b) {
+ IMakeTarget make1 = (IMakeTarget)a;
+ IMakeTarget make2 = (IMakeTarget)b;
+ return make1.getName().compareToIgnoreCase(make2.getName());
+ }
+
+ }
+
+ /**
+ * This method parses the given Makefile and produces MakeTargets for all targets so the
+ * end-user can access them from the MakeTargets popup-menu.
+ *
+ * @param makefileFile the Makefile to parse
+ * @throws CoreException
+ */
+ private void addMakeTargetsToManager(File makefileFile) throws CoreException {
+ // Return immediately if no Makefile.
+ if (makefileFile == null || !makefileFile.exists())
+ return;
+
+ checkCancel();
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
+ String statusMsg = AutotoolsPlugin.getResourceString("MakeGenerator.refresh.MakeTargets"); //$NON-NLS-1$
+ monitor.subTask(statusMsg);
+
+ IMakeTargetManager makeTargetManager =
+ MakeCorePlugin.getDefault().getTargetManager();
+
+ IMakefile makefile = MakeCorePlugin.createMakefile(makefileFile.toURI(), false, null);
+ ITargetRule[] targets = makefile.getTargetRules();
+ ITarget target = null;
+ Map<String, IMakeTarget> makeTargets = new HashMap<String, IMakeTarget>(); // use a HashMap so duplicate names are handled
+ for (int i = 0; i < targets.length; i++) {
+ target = targets[i].getTarget();
+ String targetName = target.toString();
+ if (!isValidTarget(targetName, makeTargetManager))
+ continue;
+ try {
+ IMakeTarget makeTarget = makeTargetManager.createTarget(
+ project, targetName, "org.eclipse.linuxtools.cdt.autotools.builder1"); //$NON-NLS-1$
+ makeTarget.setContainer(project);
+ makeTarget.setStopOnError(true);
+ makeTarget.setRunAllBuilders(false);
+ makeTarget.setUseDefaultBuildCmd(true);
+
+ makeTarget.setBuildAttribute(GENERATED_TARGET, "true");
+ makeTarget.setBuildAttribute(IMakeTarget.BUILD_TARGET,
+ targetName);
+
+ makeTarget.setBuildAttribute(IMakeTarget.BUILD_LOCATION,
+ buildDir);
+ makeTargets.put(makeTarget.getName(), makeTarget);
+ } catch (CoreException e) {
+ // Duplicate target. Ignore.
+ }
+ }
+
+ IMakeTarget[] makeTargetArray = new IMakeTarget[makeTargets.size()];
+ Collection<IMakeTarget> values = makeTargets.values();
+ ArrayList<IMakeTarget> valueList = new ArrayList<IMakeTarget>(values);
+ valueList.toArray(makeTargetArray);
+ MakeTargetComparator compareMakeTargets = new MakeTargetComparator();
+ Arrays.sort(makeTargetArray, compareMakeTargets);
+
+ saveTargets(makeTargetArray);
+ }
+
+ private boolean isValidTarget(String targetName, IMakeTargetManager makeTargetManager) {
+ return !(targetName.endsWith("-am") //$NON-NLS-1$
+ || targetName.endsWith("PROGRAMS") //$NON-NLS-1$
+ || targetName.endsWith("-generic") //$NON-NLS-1$
+ || (targetName.indexOf('$') >= 0)
+ || (targetName.charAt(0) == '.')
+ || targetName.equals(targetName.toUpperCase()));
+ }
+
+ // Turn the string into an array.
+ private String[] makeArray(String string) {
+ string = string.trim();
+ char[] array = string.toCharArray();
+ ArrayList<String> aList = new ArrayList<String>();
+ StringBuilder buffer = new StringBuilder();
+ boolean inComment = false;
+ for (int i = 0; i < array.length; i++) {
+ char c = array[i];
+ boolean needsToAdd = true;
+ if (array[i] == '"' || array[i] == '\'') {
+ if (i > 0 && array[i - 1] == '\\') {
+ inComment = false;
+ } else {
+ inComment = !inComment;
+ needsToAdd = false; // skip it
+ }
+ }
+ if (c == ' ' && !inComment) {
+ if (buffer.length() > 0){
+ String str = buffer.toString().trim();
+ if(str.length() > 0){
+ aList.add(str);
+ }
+ }
+ buffer = new StringBuilder();
+ } else {
+ if (needsToAdd)
+ buffer.append(c);
+ }
+ }
+ if (buffer.length() > 0){
+ String str = buffer.toString().trim();
+ if(str.length() > 0){
+ aList.add(str);
+ }
+ }
+ return (String[])aList.toArray(new String[aList.size()]);
+ }
+
+} \ No newline at end of file
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/Resources.properties b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/Resources.properties
new file mode 100644
index 0000000000..7b4c9179b2
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/Resources.properties
@@ -0,0 +1,95 @@
+#################################################################################
+# Copyright (c) 2006, 2007 Red Hat, Inc.
+# 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:
+# Red Hat Incorporated - initial API and implementation
+# IBM Rational Software - ManagedMakeMessages copied to AutotoolsMakefileBuilder
+#################################################################################
+MakeCWizard.title=C/Make Project
+MakeCWizard.description=Create a New C Project using 'make' to build it
+
+WARNING_UNSUPPORTED_CONFIGURATION=Warning: unsupported configuration
+
+AutotoolsMakefileBuilder.message.finished=Build complete for project {0}
+AutotoolsMakefileBuilder.type.clean=Clean-only build
+AutotoolsMakefileBuilder.message.clean.deleting.output=Removing build artifacts from {0}
+AutotoolsMakefileBuilder.message.console.header=**** {0} of configuration {1} for project {2} ****
+
+MakeGenerator.makefile.built=Makefile built
+MakeGenerator.refresh=Refresh
+MakeGenerator.refresh.error=Refresh error
+MakeGenerator.generation.error=Configuration failed with error
+MakeGenerator.configuring=Configuring
+MakeGenerator.createdir.error=Error creating build directory: {0}
+MakeGenerator.make.message=Invoking {0} for project {1}
+MakeGenerator.config.error=Error {0} occurred while running {1}
+MakeGenerator.run.config.status=Running config.status
+MakeGenerator.makefile.cvs=Invoking Makefile.cvs
+MakeGenerator.autogen.sh=Invoking autogen.sh
+MakeGenerator.autoreconf=Invoking autoreconf
+MakeGenerator.gen.makefile=Generating Makefile
+MakeGenerator.gen.configure=Generating configure
+MakeGenerator.unsupportedConfig=Warning: unsupported configuration {0}
+MakeGenerator.success=[Operation successful]
+MakeGenerator.didnt.generate=No Makefile generated
+MakeGenerator.refresh.MakeTargets=Refreshing Make Targets
+MakeGenerator.clean.builddir=Cleaning build directory before reconfiguring
+
+
+BuildDir.apply=Build directory already in use
+BuildDir.default=Default build directory to unused value?
+BuildDir.yes=Yes
+BuildDir.no=No
+
+WizardAutotoolsProjectConversion.title=Convert to a CVS C/C++ Autotools Project
+WizardAutotoolsProjectConversion.description=Convert a CVS source repository to C/C++ Autotools Project
+WizardAutotoolsProjectConversion.message.add_nature=Adding C/C++ Autotools Managed Project Nature
+WizardAutotoolsProjectConversion.message.add_builder=Adding C/C++ Autotools Managed Project Builder
+WizardMakeProjectConversion.monitor.convertingToMakeProject=Converting Project...
+WizardAutotoolsConversion=CVS C/C++ Autotools Conversion
+WizardAutotoolsConversion.windowTitle=Conversion to CVS C/C++ Autotools Project
+WizardAutotoolsConversion.config.title=Select a configuration
+WizardAutotoolsConversion.config.desc=Select the configuration you wish to deploy on
+WizardAutotoolsConversion.options.title=Additional Project Settings
+WizardAutotoolsConversion.options.desc=Define the inter-project dependencies, if any.
+WizardAutotoolsConversion.message.save=Saving new build options
+
+WizardAutotoolsNewCProject.title=Autotools C Project
+WizardAutotoolsNewCProject.description=Create a new C Autotools project
+WizardAutotoolsNewCProject.monitor.creatingProject=Creating Project...
+WizardAutotoolsNewCProject.windowTitle=GNU Autotools C Project
+WizardAutotoolsNewCProject.config.title=Select a configuration
+WizardAutotoolsNewCProject.config.desc=Select the configuration you wish to deploy on
+WizardAutotoolsNewCProject.options.title=Additional Project Settings
+WizardAutotoolsNewCProject.options.desc=Define the inter-project dependencies, if any.
+WizardAutotoolsNewCProject.message.save=Saving new build options
+
+WizardAutotoolsNewCCProject.title=Autotools C++ Project
+WizardAutotoolsNewCCProject.description=Create a new C++ Autotools project
+WizardAutotoolsNewCCProject.monitor.creatingProject=Creating Project...
+WizardAutotoolsNewCCProject.windowTitle=GNU Autotools C++ Project
+WizardAutotoolsNewCCProject.config.title=Select a configuration
+WizardAutotoolsNewCCProject.config.desc=Select the configuration you wish to deploy on
+WizardAutotoolsNewCCProject.options.title=Additional Project Settings
+WizardAutotoolsNewCCProject.options.desc=Define the inter-project dependencies, if any.
+WizardAutotoolsNewCCProject.message.save=Saving new build options
+
+
+BuildTargetDialog.title.buildTarget=Build Special Targets
+BuildTargetDialog.title.makeTargetsFor=Make targets for
+BuildTargetDialog.button.build=Build
+
+TargetListViewer.button.add=Add...
+TargetListViewer.button.remove=Remove
+TargetListViewer.button.edit=Edit...
+TargetListViewer.label.target=Target
+TargetListViewer.label.location=Location
+TargetListViewer.exception.error=Error
+TargetListViewer.exception.message=An error occurred performing the selected action
+
+AutotoolsPreferencePage.useAutotoolsFileScanner.label=Use make -w for includepath scanning
+MakeTargetPreferencePage.buildTargetInBackground.label=Build target in background
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractAutotoolsHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractAutotoolsHandler.java
new file mode 100644
index 0000000000..be54ee8fb5
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractAutotoolsHandler.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import java.util.Collection;
+
+import org.eclipse.cdt.core.model.ICContainer;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+
+public abstract class AbstractAutotoolsHandler extends AbstractHandler {
+
+ @SuppressWarnings("unchecked")
+ protected IContainer getContainer(IEvaluationContext e) {
+ IContainer fContainer = null;
+
+ Object obj = e.getDefaultVariable();
+ if (obj instanceof Collection) {
+ Collection<Object> c = (Collection<Object>)obj;
+ Object[] objArray = c.toArray();
+ if (objArray.length > 0)
+ obj = objArray[0];
+ }
+ if (obj instanceof ICElement) {
+ if ( obj instanceof ICContainer || obj instanceof ICProject) {
+ fContainer = (IContainer) ((ICElement) obj).getUnderlyingResource();
+ } else {
+ obj = ((ICElement)obj).getResource();
+ if ( obj != null) {
+ fContainer = ((IResource)obj).getParent();
+ }
+ }
+ } else if (obj instanceof IResource) {
+ if (obj instanceof IContainer) {
+ fContainer = (IContainer) obj;
+ } else {
+ fContainer = ((IResource)obj).getParent();
+ }
+ } else {
+ fContainer = null;
+ }
+ return fContainer;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractTargetAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractTargetAction.java
new file mode 100644
index 0000000000..367d63a7be
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AbstractTargetAction.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.cdt.core.model.ICContainer;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsMakefileBuilder;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsPlugin;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.actions.ActionDelegate;
+
+
+public abstract class AbstractTargetAction
+ extends ActionDelegate
+ implements IObjectActionDelegate, IWorkbenchWindowActionDelegate {
+ private IWorkbenchPart fPart;
+ private IWorkbenchWindow fWindow;
+ private IContainer fContainer;
+
+ protected Shell getShell() {
+ if (fPart != null) {
+ return fPart.getSite().getShell();
+ } else if (fWindow != null) {
+ return fWindow.getShell();
+ }
+ return AutotoolsPlugin.getActiveWorkbenchShell();
+ }
+
+ protected IContainer getSelectedContainer() {
+ return fContainer;
+ }
+
+ public void setSelectedContainer(IContainer container) {
+ fContainer = container;
+ }
+
+ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+ fPart = targetPart;
+ }
+
+ public void init(IWorkbenchWindow window) {
+ fWindow = window;
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ boolean enabled = false;
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection sel = (IStructuredSelection) selection;
+ Object obj = sel.getFirstElement();
+ if (obj instanceof ICElement) {
+ if ( obj instanceof ICContainer || obj instanceof ICProject) {
+ fContainer = (IContainer) ((ICElement) obj).getUnderlyingResource();
+ } else {
+ obj = ((ICElement)obj).getResource();
+ if ( obj != null) {
+ fContainer = ((IResource)obj).getParent();
+ }
+ }
+ } else if (obj instanceof IResource) {
+ if (obj instanceof IContainer) {
+ fContainer = (IContainer) obj;
+ } else {
+ fContainer = ((IResource)obj).getParent();
+ }
+ } else {
+ fContainer = null;
+ }
+ if (fContainer != null && AutotoolsMakefileBuilder.hasTargetBuilder(fContainer.getProject())) {
+ enabled = true;
+ }
+ }
+ action.setEnabled(enabled);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AclocalHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AclocalHandler.java
new file mode 100644
index 0000000000..b534cfe06a
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AclocalHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+/**
+ * @author Jeff Johnston
+ *
+ */
+public class AclocalHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ InvokeAclocalAction a = new InvokeAclocalAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoconfHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoconfHandler.java
new file mode 100644
index 0000000000..9dc28e2935
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoconfHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+public class AutoconfHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ InvokeAutoconfAction a = new InvokeAutoconfAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoheaderHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoheaderHandler.java
new file mode 100644
index 0000000000..e64ad41799
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoheaderHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+/**
+ * @author Jeff Johnston
+ *
+ */
+public class AutoheaderHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ InvokeAutoheaderAction a = new InvokeAutoheaderAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutomakeHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutomakeHandler.java
new file mode 100644
index 0000000000..c1bbcf4f47
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutomakeHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+public class AutomakeHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ InvokeAutomakeAction a = new InvokeAutomakeAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoreconfHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoreconfHandler.java
new file mode 100644
index 0000000000..d9b0c8c72f
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/AutoreconfHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+/**
+ * @author Jeff Johnston
+ *
+ */
+public class AutoreconfHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ InvokeAutoreconfAction a = new InvokeAutoreconfAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAclocalAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAclocalAction.java
new file mode 100644
index 0000000000..0834ef434b
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAclocalAction.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class InvokeAclocalAction extends InvokeAction {
+
+ private static final String DEFAULT_OPTION = ""; //$NON-NLS-1$
+ private static final String DEFAULT_COMMAND = "aclocal"; //$NON-NLS-1$
+
+ public void run(IAction action) {
+
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ IPath execDir = getExecDir(container);
+ String cwd = InvokeMessages.getString("CWD") + getCWD(container); //$NON-NLS-1$
+
+ TwoInputDialog optionDialog = new TwoInputDialog(
+ new Shell(),
+ cwd,
+ InvokeMessages
+ .getString("InvokeAclocalAction.windowTitle.options"), //$NON-NLS-1$
+ InvokeMessages
+ .getString("InvokeAclocalAction.message.options.otherOptions"), //$NON-NLS-1$
+ InvokeMessages
+ .getString("InvokeAclocalAction.message.options.includeDir"), DEFAULT_OPTION, null); //$NON-NLS-1$
+
+ optionDialog.open();
+
+ // chop args into string array
+ String rawArgList = optionDialog.getValue();
+
+ String[] optionsList = separateOptions(rawArgList);
+
+ // chop args into string array
+ rawArgList = optionDialog.getSecondValue();
+
+ String[] targetList = separateTargets(rawArgList);
+
+ if (targetList == null) {
+
+ showError(InvokeMessages
+ .getString("InvokeAction.execute.windowTitle.error"), //$NON-NLS-1$
+ InvokeMessages
+ .getString("InvokeAction.windowTitle.quoteError")); //$NON-NLS-1$
+ return;
+ }
+
+ int iOption = 0;
+ if (targetList.length > 0)
+ iOption = 1;
+
+ String[] argumentList = new String[targetList.length
+ + optionsList.length + iOption];
+
+ System.arraycopy(optionsList, 0, argumentList, 0, optionsList.length);
+
+ if (iOption == 1)
+ argumentList[optionsList.length] = "-I"; //$NON-NLS-1$
+
+ System.arraycopy(targetList, 0, argumentList, optionsList.length
+ + iOption, targetList.length);
+
+ if (container != null) {
+ String aclocalCommand = null;
+ IProject project = getSelectedContainer().getProject();
+ try {
+ aclocalCommand = project.getPersistentProperty(AutotoolsPropertyConstants.ACLOCAL_TOOL);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // If unset, use default system path
+ if (aclocalCommand == null)
+ aclocalCommand = DEFAULT_COMMAND;
+
+ executeConsoleCommand(DEFAULT_COMMAND, aclocalCommand,
+ argumentList, execDir);
+ }
+ }
+
+ public void dispose() {
+
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAction.java
new file mode 100644
index 0000000000..01979735f6
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAction.java
@@ -0,0 +1,442 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007, 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+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.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsPlugin;
+import org.eclipse.linuxtools.cdt.autotools.MakeGenerator;
+import org.eclipse.swt.widgets.Shell;
+
+public abstract class InvokeAction extends AbstractTargetAction {
+
+ protected void showInformation(String title, String content) {
+
+ MessageDialog.openInformation(new Shell(), title, content);
+ }
+
+ protected void showError(String title, String content) {
+
+ MessageDialog.openError(new Shell(), title, content);
+ }
+
+ protected void showSuccess(String title) {
+ MessageDialog.openInformation(new Shell(), title,
+ InvokeMessages.getString("InvokeAction.success")); //$NON-NLS-1$
+ }
+
+ protected String showInput(String title, String content, String defaultTxt) {
+ InputDialog getOptionDialog = new InputDialog(new Shell(), title,
+ content, defaultTxt, null);
+
+ getOptionDialog.open();
+
+ return getOptionDialog.getValue();
+ }
+
+ /**
+ * Separate targets to array from a string.
+ *
+ * @param rawArgList
+ * @return targets in string[] array. if targets are not formatted properly,
+ * returns null
+ */
+ protected String[] separateTargets(String rawArgList) {
+
+ StringTokenizer st = new StringTokenizer(rawArgList, " "); //$NON-NLS-1$
+ ArrayList<String> targetList = new ArrayList<String>();
+
+ while (st.hasMoreTokens()) {
+ String currentWord = st.nextToken().trim();
+
+ if (currentWord.startsWith("'")) { //$NON-NLS-1$
+ String tmpTarget = ""; //$NON-NLS-1$
+ while (!currentWord.endsWith("'")) { //$NON-NLS-1$
+ tmpTarget += currentWord + " "; //$NON-NLS-1$
+ if (!st.hasMoreTokens()) {
+ // quote not closed properly, so return null
+ return null;
+ }
+ currentWord = st.nextToken().trim();
+ }
+
+ tmpTarget += currentWord;
+ targetList.add(tmpTarget);
+ continue;
+ }
+
+ if (currentWord.startsWith("\"")) { //$NON-NLS-1$
+ String tmpTarget = ""; //$NON-NLS-1$
+ while (!currentWord.endsWith("\"")) { //$NON-NLS-1$
+ tmpTarget += currentWord + " "; //$NON-NLS-1$
+ if (!st.hasMoreTokens()) {
+ // double quote not closed properly, so return null
+ return null;
+ }
+ currentWord = st.nextToken().trim();
+ }
+
+ tmpTarget += currentWord;
+ targetList.add(tmpTarget);
+ continue;
+ }
+
+ // for targets without quote/double quotes.
+ targetList.add(currentWord);
+
+ }
+
+ return (String[])targetList.toArray(new String[targetList.size()]);
+ }
+
+ protected String[] separateOptions(String rawArgList) {
+ ArrayList<String> argList = new ArrayList<String>();
+ // May be multiple user-specified options in which case we
+ // need to split them up into individual options
+ rawArgList = rawArgList.trim();
+ boolean finished = false;
+ int lastIndex = rawArgList.indexOf("--"); //$NON-NLS-1$
+ if (lastIndex != -1) {
+ while (!finished) {
+ int index = rawArgList.indexOf("--", lastIndex + 2); //$NON-NLS-1$
+ if (index != -1) {
+ String previous = rawArgList.substring(lastIndex, index)
+ .trim();
+ argList.add(previous);
+ rawArgList = rawArgList.substring(index);
+ } else {
+ argList.add(rawArgList);
+ finished = true;
+ }
+ }
+ }
+
+ return (String[])argList.toArray(new String[argList.size()]);
+
+ }
+
+ protected String[] simpleParseOptions(String rawArgList) {
+ ArrayList<String> argList = new ArrayList<String>();
+ int lastArgIndex = -1;
+ int i = 0;
+ while (i < rawArgList.length()) {
+ char ch = rawArgList.charAt(i);
+ // Skip white-space
+ while (Character.isWhitespace(ch)) {
+ ++i;
+ if (i < rawArgList.length())
+ ch = rawArgList.charAt(i);
+ else // Otherwise we are done
+ return argList.toArray(new String[argList.size()]);
+ }
+
+ // Simplistic parser. We break up into strings delimited
+ // by blanks. If quotes are used, we ignore blanks within.
+ // If a backslash is used, we ignore the next character and
+ // pass it through.
+ lastArgIndex = i;
+ boolean inString = false;
+ while (i < rawArgList.length()) {
+ ch = rawArgList.charAt(i);
+ if (ch == '\\') // escape character
+ ++i; // skip over the next character
+ else if (ch == '\"') { // double quotes
+ inString = !inString;
+ } else if (Character.isWhitespace(ch)) {
+ if (!inString) {
+ argList.add(rawArgList.substring(lastArgIndex, i));
+ break;
+ }
+ }
+ ++i;
+ }
+ // Look for the case where we ran out of chars for the last
+ // token.
+ if (i >= rawArgList.length())
+ argList.add(rawArgList.substring(lastArgIndex));
+ ++i;
+ }
+ return argList.toArray(new String[argList.size()]);
+ }
+
+ protected IPath getExecDir(IContainer container) {
+ int type = container.getType();
+ IPath execDir = null;
+ if (type == IContainer.FILE) {
+ execDir = container.getLocation().removeLastSegments(1);
+ } else {
+ execDir = container.getLocation();
+ }
+ return execDir;
+ }
+
+ protected IPath getCWD(IContainer container) {
+ int type = container.getType();
+ IPath cwd = null;
+ if (type == IContainer.FILE) {
+ cwd = container.getFullPath().removeLastSegments(1);
+ } else {
+ cwd = container.getFullPath();
+ }
+ return cwd;
+ }
+
+ private class ExecuteProgressDialog implements IRunnableWithProgress {
+ private IPath command;
+ private String[] argumentList;
+ private String[] envList;
+ private IPath execDir;
+ private int status;
+ private HashMap<String, String> outputs = null;
+
+ public ExecuteProgressDialog(IPath command, String[] argumentList,
+ String[] envList, IPath execDir) {
+ this.command = command;
+ this.argumentList = argumentList;
+ this.envList = envList;
+ this.execDir = execDir;
+ }
+
+ public void run(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+ CommandLauncher cmdL = new CommandLauncher();
+ outputs = null;
+
+ // invoke command
+ try {
+ monitor.beginTask(
+ InvokeMessages.getFormattedString("InvokeAction.progress.message", // $NON-NLS-1$
+ new String[]{command.toOSString()}), IProgressMonitor.UNKNOWN);
+ monitor.worked(1);
+ Process process = cmdL.execute(command, argumentList, envList,
+ execDir, new NullProgressMonitor());
+
+ if (cmdL.waitAndRead(stdout, stderr) == CommandLauncher.OK) {
+ try {
+ status = 0;
+ monitor.done();
+ process.getOutputStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ } else {
+ // failed to execute command
+ status = -1;
+ monitor.done();
+ return;
+ }
+ } catch (CoreException e) {
+ monitor.done();
+ throw new InvocationTargetException(e);
+ }
+
+ outputs = new HashMap<String, String>();
+
+ outputs.put("stdout", stdout.toString()); //$NON-NLS-1$
+ outputs.put("stderr", stderr.toString()); //$NON-NLS-1$
+
+ try {
+ stdout.close();
+ stderr.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ public HashMap<String, String> getOutputs() {
+ return outputs;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+ }
+
+
+ protected HashMap<String, String> executeCommand(IPath command,
+ String[] argumentList, String[] envList, IPath execDir) {
+ try {
+ ExecuteProgressDialog d = new ExecuteProgressDialog(command,
+ argumentList, envList, execDir);
+ new ProgressMonitorDialog(new Shell()).run(false, false, d);
+ if (d.getStatus() == -1)
+ showError(InvokeMessages
+ .getString("InvokeAction.execute.windowTitle.error"), InvokeMessages //$NON-NLS-1$
+ .getString("InvokeAction.execute.message") //$NON-NLS-1$
+ + command.toOSString()); //$NON-NLS-1$
+ return d.getOutputs();
+ } catch (InvocationTargetException e) {
+ showError(InvokeMessages
+ .getString("InvokeAction.execute.windowTitle.error"), InvokeMessages //$NON-NLS-1$
+ .getString("InvokeAction.execute.message") //$NON-NLS-1$
+ + command.toOSString()); //$NON-NLS-1$
+ AutotoolsPlugin.logException(e);
+ return null;
+ } catch (InterruptedException e) {
+ return null;
+ }
+ }
+
+ protected void executeConsoleCommand(final String actionName, final String command,
+ final String[] argumentList, final IPath execDir) {
+ // We need to use a workspace root scheduling rule because adding MakeTargets
+ // may end up saving the project description which runs under a workspace root rule.
+ final ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRoot();
+
+ Job backgroundJob = new Job(actionName) {
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ try {
+ String errMsg = null;
+ IProject project = getSelectedContainer().getProject();
+ // Get a build console for the project
+ IConsole console = CCorePlugin.getDefault().getConsole("org.eclipse.linuxtools.cdt.autotools.autotoolsConsole"); //$NON-NLS-1$
+ console.start(project);
+ ConsoleOutputStream consoleOutStream = console.getOutputStream();
+ // FIXME: we want to remove need for ManagedBuilderManager, but how do we
+ // get environment variables.
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ IConfiguration cfg = info.getDefaultConfiguration();
+
+ StringBuffer buf = new StringBuffer();
+ String[] consoleHeader = new String[3];
+
+ consoleHeader[0] = actionName;
+ consoleHeader[1] = cfg.getName();
+ consoleHeader[2] = project.getName();
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ String invokeMsg = InvokeMessages.getFormattedString("InvokeAction.console.message", //$NON-NLS-1$
+ new String[]{actionName, execDir.toString()}); //$NON-NLS-1$
+ buf.append(invokeMsg);
+ 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();
+
+ ArrayList<String> additionalEnvs = new ArrayList<String>();
+ String strippedCommand = MakeGenerator.stripEnvVars(command, additionalEnvs);
+ // Get a launcher for the config command
+ CommandLauncher launcher = new CommandLauncher();
+ // Set the environment
+ IEnvironmentVariable variables[] = ManagedBuildManager
+ .getEnvironmentVariableProvider().getVariables(cfg, true);
+ String[] env = null;
+ ArrayList<String> envList = new ArrayList<String>();
+ if (variables != null) {
+ for (int i = 0; i < variables.length; i++) {
+ envList.add(variables[i].getName()
+ + "=" + variables[i].getValue()); //$NON-NLS-1$
+ }
+ if (additionalEnvs.size() > 0)
+ envList.addAll(additionalEnvs); // add any additional environment variables specified ahead of script
+ env = (String[]) envList.toArray(new String[envList.size()]);
+ }
+ OutputStream stdout = consoleOutStream;
+ OutputStream stderr = consoleOutStream;
+
+ launcher.showCommand(true);
+ // Run the shell script via shell command.
+ Process proc = launcher.execute(new Path(strippedCommand), argumentList, env,
+ execDir, new NullProgressMonitor());
+ 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(stdout, stderr, 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
+ // ensure
+ // the UI is up-to-date with the build results
+ // monitor.subTask(ManagedMakeMessages
+ // .getResourceString(REFRESH));
+ monitor.subTask(AutotoolsPlugin.getResourceString("MakeGenerator.refresh")); //$NON-NLS-1$
+ try {
+ project.refreshLocal(IResource.DEPTH_INFINITE, null);
+ } catch (CoreException e) {
+ monitor.subTask(AutotoolsPlugin
+ .getResourceString("MakeGenerator.refresh.error")); //$NON-NLS-1$
+ }
+ } else {
+ errMsg = launcher.getErrorMessage();
+ }
+
+ if (errMsg != null)
+ AutotoolsPlugin.logErrorMessage(errMsg);
+
+ } catch (IOException e) {
+ AutotoolsPlugin.log(e);
+ }
+ }
+ }, rule, IWorkspace.AVOID_UPDATE, monitor);
+ } catch (CoreException e) {
+ return e.getStatus();
+ }
+ IStatus returnStatus = Status.OK_STATUS;
+ return returnStatus;
+ }
+ };
+
+ backgroundJob.setRule(rule);
+ backgroundJob.schedule();
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoconfAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoconfAction.java
new file mode 100644
index 0000000000..6440dfa025
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoconfAction.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+
+
+/**
+ * Class responsible for invoking autoconf.
+ *
+ * @author klee
+ *
+ */
+public class InvokeAutoconfAction extends InvokeAction {
+
+ private final static String DEFAULT_COMMAND = "autoconf"; //$NON-NLS-1$
+ public void run(IAction action) {
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ IPath execDir = getExecDir(container);
+
+ if (container != null) {
+ IProject project = container.getProject();
+ String autoconfCommand = null;
+ try {
+ autoconfCommand = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_TOOL);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // If unset for the project, default to system path
+ if (autoconfCommand == null)
+ autoconfCommand = DEFAULT_COMMAND;
+
+ executeConsoleCommand(DEFAULT_COMMAND, autoconfCommand, new String[]{}, execDir);
+ }
+ }
+
+
+ public void dispose() {
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoheaderAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoheaderAction.java
new file mode 100644
index 0000000000..1057d45743
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoheaderAction.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class InvokeAutoheaderAction extends InvokeAction {
+
+ private static final String DEFAULT_OPTION = ""; //$NON-NLS-1$
+ private static final String DEFAULT_COMMAND = "autoheader"; //$NON-NLS-1$
+
+ public void run(IAction action) {
+
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ IPath execDir = getExecDir(container);
+ String cwd = InvokeMessages.getString("CWD") + getCWD(container); //$NON-NLS-1$
+
+ InputDialog optionDialog = new SingleInputDialog(
+ new Shell(),
+ cwd,
+ InvokeMessages
+ .getString("InvokeAutoheaderAction.windowTitle.options"), //$NON-NLS-1$
+ InvokeMessages
+ .getString("InvokeAutoheaderAction.message.options.otherOptions"), //$NON-NLS-1$
+ DEFAULT_OPTION, null);
+ optionDialog.open();
+
+ // chop args into string array
+ String rawArgList = optionDialog.getValue();
+
+ String[] optionsList = simpleParseOptions(rawArgList);
+
+ String[] argumentList = new String[optionsList.length];
+
+ System.arraycopy(optionsList, 0, argumentList, 0, optionsList.length);
+
+ if (container != null) {
+ String autoheaderCommand = null;
+ IProject project = getSelectedContainer().getProject();
+ try {
+ autoheaderCommand = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOHEADER_TOOL);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // If unset, use default system path
+ if (autoheaderCommand == null)
+ autoheaderCommand = DEFAULT_COMMAND;
+
+ executeConsoleCommand(DEFAULT_COMMAND, autoheaderCommand,
+ argumentList, execDir);
+ }
+
+ }
+
+ public void dispose() {
+
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutomakeAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutomakeAction.java
new file mode 100644
index 0000000000..2e973849f9
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutomakeAction.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * Class responsible for invoking automake.
+ *
+ * @author klee
+ *
+ */
+public class InvokeAutomakeAction extends InvokeAction {
+
+ private static final String DEFAULT_OPTION = ""; //$NON-NLS-1$
+ private static final String DEFAULT_COMMAND = "automake"; //$NON-NLS-1$
+
+ public void run(IAction action) {
+
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ IPath execDir = getExecDir(container);
+ String cwd = InvokeMessages.getString("CWD") + getCWD(container); //$NON-NLS-1$
+;
+ TwoInputDialog optionDialog = new TwoInputDialog(new Shell(), cwd,
+ InvokeMessages
+ .getString("InvokeAutomakeAction.windowTitle.options"), //$NON-NLS-1$
+InvokeMessages
+ .getString("InvokeAutomakeAction.message.options.otherOptions"),InvokeMessages //$NON-NLS-1$
+ .getString("InvokeAutomakeAction.message.options.makeTargets"), DEFAULT_OPTION, null); //$NON-NLS-1$
+
+ optionDialog.open();
+
+ // chop args into string array
+ String rawArgList = optionDialog.getValue();
+
+ String[] optionsList = separateOptions(rawArgList);
+
+
+ // chop args into string array
+ rawArgList = optionDialog.getSecondValue();
+
+ String[] targetList = separateTargets(rawArgList);
+
+ if (targetList == null) {
+
+ showError(InvokeMessages.getString("InvokeAction.execute.windowTitle.error"), //$NON-NLS-1$
+ InvokeMessages.getString("InvokeAction.windowTitle.quoteError")); //$NON-NLS-1$
+ return;
+ }
+
+ String[] argumentList = new String[targetList.length
+ + optionsList.length];
+
+ System.arraycopy(optionsList, 0, argumentList, 0, optionsList.length);
+ System.arraycopy(targetList, 0, argumentList, optionsList.length,
+ targetList.length);
+
+ if (container != null) {
+ IProject project = container.getProject();
+ String automakeCommand = null;
+ try {
+ automakeCommand = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_TOOL);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // If automake path not set for the project, default to system path
+ if (automakeCommand == null)
+ automakeCommand = DEFAULT_COMMAND;
+
+ executeConsoleCommand(DEFAULT_COMMAND, automakeCommand,
+ argumentList, execDir);
+ }
+ }
+
+ public void dispose() {
+
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoreconfAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoreconfAction.java
new file mode 100644
index 0000000000..b16de919d3
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeAutoreconfAction.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class InvokeAutoreconfAction extends InvokeAction {
+
+ private static final String DEFAULT_OPTION = ""; //$NON-NLS-1$
+ private static final String DEFAULT_COMMAND = "autoreconf"; //$NON-NLS-1$
+
+ public void run(IAction action) {
+
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ IPath execDir = getExecDir(container);
+ String cwd = InvokeMessages.getString("CWD") + getCWD(container); //$NON-NLS-1$
+
+ InputDialog optionDialog = new SingleInputDialog(
+ new Shell(),
+ cwd,
+ InvokeMessages
+ .getString("InvokeAutoreconfAction.windowTitle.options"), //$NON-NLS-1$
+ InvokeMessages
+ .getString("InvokeAutoreconfAction.message.options.otherOptions"), //$NON-NLS-1$
+ DEFAULT_OPTION, null);
+ optionDialog.open();
+
+ // chop args into string array
+ String rawArgList = optionDialog.getValue();
+
+ String[] optionsList = simpleParseOptions(rawArgList);
+
+ String[] argumentList = new String[optionsList.length];
+
+ System.arraycopy(optionsList, 0, argumentList, 0, optionsList.length);
+
+ if (container != null) {
+ String autoreconfCommand = null;
+ IProject project = getSelectedContainer().getProject();
+ try {
+ autoreconfCommand = project.getPersistentProperty(AutotoolsPropertyConstants.AUTORECONF_TOOL);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // If unset, use default system path
+ if (autoreconfCommand == null)
+ autoreconfCommand = DEFAULT_COMMAND;
+
+ executeConsoleCommand(DEFAULT_COMMAND, autoreconfCommand,
+ argumentList, execDir);
+ }
+ }
+
+ public void dispose() {
+
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeLibtoolizeAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeLibtoolizeAction.java
new file mode 100644
index 0000000000..03e04273db
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeLibtoolizeAction.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.linuxtools.cdt.autotools.ui.properties.AutotoolsPropertyConstants;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class InvokeLibtoolizeAction extends InvokeAction {
+
+ private static final String DEFAULT_OPTION = ""; //$NON-NLS-1$
+ private static final String DEFAULT_COMMAND = "libtoolize"; //$NON-NLS-1$
+
+ public void run(IAction action) {
+
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ IPath execDir = getExecDir(container);
+ String cwd = InvokeMessages.getString("CWD") + getCWD(container); //$NON-NLS-1$
+
+ InputDialog optionDialog = new SingleInputDialog(
+ new Shell(),
+ cwd,
+ InvokeMessages
+ .getString("InvokeLibtoolizeAction.windowTitle.options"), //$NON-NLS-1$
+ InvokeMessages
+ .getString("InvokeLibtoolizeAction.message.options.otherOptions"), //$NON-NLS-1$
+ DEFAULT_OPTION, null);
+ optionDialog.open();
+
+ // chop args into string array
+ String rawArgList = optionDialog.getValue();
+
+ String[] optionsList = simpleParseOptions(rawArgList);
+
+ String[] argumentList = new String[optionsList.length];
+
+ System.arraycopy(optionsList, 0, argumentList, 0, optionsList.length);
+
+ if (container != null) {
+ String libtoolizeCommand = null;
+ IProject project = getSelectedContainer().getProject();
+ try {
+ libtoolizeCommand = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOHEADER_TOOL);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // If unset, use default system path
+ if (libtoolizeCommand == null)
+ libtoolizeCommand = DEFAULT_COMMAND;
+
+ executeConsoleCommand(DEFAULT_COMMAND, libtoolizeCommand,
+ argumentList, execDir);
+ }
+ }
+
+ public void dispose() {
+
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.java
new file mode 100644
index 0000000000..b62632a1c2
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007, 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class InvokeMessages {
+ private static final String BUNDLE_NAME = InvokeMessages.class.getName();
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private InvokeMessages() {
+ }
+
+ /**
+ * Returns the string from the resource bundle,
+ * or 'key' if not found.
+ *
+ * @param key the message key
+ * @return the resource bundle message
+ */
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Returns the formatted string from the resource bundle,
+ * or 'key' if not found.
+ *
+ * @param key the message key
+ * @param args an array of substituition strings
+ * @return the resource bundle message
+ */
+ public static String getFormattedString(String key, String[] args) {
+ return MessageFormat.format(getString(key), (Object[])args);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.properties b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.properties
new file mode 100644
index 0000000000..b2da117fef
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/InvokeMessages.properties
@@ -0,0 +1,56 @@
+#################################################################################
+# Copyright (c) 2006, 2007, 2009 Red Hat, Inc.
+# 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:
+# Red Hat Incorporated - initial API and implementation
+#################################################################################
+CWD=Working Directory:
+
+InvokeAction.windowTitle.quoteError=Quote/Double quote not correct
+InvokeAction.progress.message=Running {0}
+InvokeAction.execute.windowTitle.error=Invoke Action Error
+InvokeAction.execute.message=Couldn't execute command :
+InvokeAction.success=Command executed successfully
+InvokeAction.console.message=Invoking {0} in {1}
+
+
+InvokeAutoconfAction.command=Running autoconf in {0}
+InvokeAutoconfAction.windowTitle.stdout=Invoke Autoconf - Output
+InvokeAutoconfAction.windowTitle.stderr=Invoke Autoconf - Error
+
+
+InvokeAutomakeAction.command=Running automake
+InvokeAutomakeAction.windowTitle.options=Automake Options
+InvokeAutomakeAction.message.options.makeTargets=Enter targets separated by space :
+InvokeAutomakeAction.message.options.otherOptions=Enter options separated by space :
+InvokeAutomakeAction.windowTitle.stdout=Invoke Automake - Output
+InvokeAutomakeAction.windowTitle.stderr=Invoke Automake - Error
+
+InvokeAutoheaderAction.command=Running autoheader
+InvokeAutoheaderAction.windowTitle.options=Autoheader Options
+InvokeAutoheaderAction.message.options.otherOptions=Enter options separated by space :
+InvokeAutoheaderAction.windowTitle.stdout=Invoke Autoheader - Output
+InvokeAutoheaderAction.windowTitle.stderr=Invoke Autoheader - Error
+
+InvokeAutoreconfAction.command=Running autoreconf
+InvokeAutoreconfAction.windowTitle.options=Autoreconf Options
+InvokeAutoreconfAction.message.options.otherOptions=Enter options separated by space :
+InvokeAutoreconfAction.windowTitle.stdout=Invoke Autoreconf - Output
+InvokeAutoreconfAction.windowTitle.stderr=Invoke Autoreconf - Error
+
+InvokeAclocalAction.command=Running aclocal
+InvokeAclocalAction.windowTitle.options=Aclocal Options
+InvokeAclocalAction.message.options.includeDir=Add directory to search list for .m4 files :
+InvokeAclocalAction.message.options.otherOptions=Enter options separated by space :
+InvokeAclocalAction.windowTitle.stdout=Invoke Automake - Output
+InvokeAclocalAction.windowTitle.stderr=Invoke Automake - Error
+
+InvokeLibtoolizeAction.command=Running libtoolize
+InvokeLibtoolizeAction.windowTitle.options=Libtoolize Options
+InvokeLibtoolizeAction.message.options.otherOptions=Enter options separated by space :
+InvokeLibtoolizeAction.windowTitle.stdout=Invoke Libtoolize - Output
+InvokeLibtoolizeAction.windowTitle.stderr=Invoke Libtoolize - Error
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/LibtoolizeHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/LibtoolizeHandler.java
new file mode 100644
index 0000000000..202f1b6476
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/LibtoolizeHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+/**
+ * @author Jeff Johnston
+ *
+ */
+public class LibtoolizeHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ InvokeLibtoolizeAction a = new InvokeLibtoolizeAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureAction.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureAction.java
new file mode 100644
index 0000000000..96ef9a6823
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureAction.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.linuxtools.cdt.autotools.MakeGenerator;
+
+
+public class ReconfigureAction extends InvokeAction {
+
+ public void run(IAction action) {
+ IContainer container = getSelectedContainer();
+ if (container == null)
+ return;
+
+ // We need to use a workspace root scheduling rule because adding MakeTargets
+ // may end up saving the project description which runs under a workspace root rule.
+ final ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRoot();
+
+ Job backgroundJob = new Job("Reconfigure Action"){ //$NON-NLS-1$
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IProject project = getSelectedContainer().getProject();
+ MakeGenerator m = new MakeGenerator();
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ m.initialize(project, info, monitor);
+ m.removeConfigSettings();
+ try {
+ m.regenerateMakefiles();
+ } catch (CoreException e) {
+ // do nothing for now
+ }
+ }
+ }, rule, IWorkspace.AVOID_UPDATE, monitor);
+ } catch (CoreException e) {
+ return e.getStatus();
+ }
+ IStatus returnStatus = Status.OK_STATUS;
+ return returnStatus;
+ }
+ };
+
+ backgroundJob.setRule(rule);
+ backgroundJob.schedule();
+ }
+
+ public void dispose() {
+
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureHandler.java
new file mode 100644
index 0000000000..843d7bbabc
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/ReconfigureHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.resources.IContainer;
+
+/**
+ * @author Jeff Johnston
+ *
+ */
+public class ReconfigureHandler extends AbstractAutotoolsHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ReconfigureAction a = new ReconfigureAction();
+ Object o = event.getApplicationContext();
+ if (o instanceof IEvaluationContext) {
+ IContainer container = getContainer((IEvaluationContext)o);
+ if (container != null) {
+ a.setSelectedContainer(container);
+ a.run(null);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/SingleInputDialog.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/SingleInputDialog.java
new file mode 100644
index 0000000000..8a5f8bc456
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/SingleInputDialog.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+public class SingleInputDialog extends InputDialog {
+
+ private String firstMessage;
+
+ public SingleInputDialog(Shell parentShell, String firstMessage, String dialogTitle,
+ String dialogMessage, String initialValue,
+ IInputValidator validator) {
+ super(parentShell, dialogTitle, dialogMessage, initialValue, validator);
+
+ this.firstMessage = firstMessage;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Dialog.
+ */
+ protected void buttonPressed(int buttonId) {
+ super.buttonPressed(buttonId);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+
+ // create composite
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ CLabel label0 = new CLabel(composite, SWT.WRAP);
+ label0.setText(firstMessage);
+ GridData data = new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
+ | GridData.VERTICAL_ALIGN_CENTER);
+ data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+ label0.setLayoutData(data);
+ label0.setFont(parent.getFont());
+
+ // remove error message dialog from focusing.
+ composite.getTabList()[2].setVisible(false);
+ composite.getTabList()[2].setEnabled(false);
+
+ return composite;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/TwoInputDialog.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/TwoInputDialog.java
new file mode 100644
index 0000000000..f786e449f2
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/actions/TwoInputDialog.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Red Hat Inc..
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.actions;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class TwoInputDialog extends InputDialog {
+
+ private Text secondText;
+
+ private String secondValue;
+
+ private String secondMessage;
+
+ private String firstMessage;
+
+ public TwoInputDialog(Shell parentShell, String firstMessage, String dialogTitle,
+ String dialogMessage, String secondMessage, String initialValue,
+ IInputValidator validator) {
+ super(parentShell, dialogTitle, dialogMessage, initialValue, validator);
+
+ this.firstMessage = firstMessage;
+ this.secondMessage = secondMessage;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Dialog.
+ */
+ protected void buttonPressed(int buttonId) {
+ if (buttonId == IDialogConstants.OK_ID) {
+ secondValue = secondText.getText();
+ } else {
+ secondValue = null;
+ }
+ super.buttonPressed(buttonId);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+
+ // create composite
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ CLabel label0 = new CLabel(composite, SWT.WRAP);
+ label0.setText(firstMessage);
+ Label label = new Label(composite, SWT.WRAP);
+ label.setText(secondMessage);
+ GridData data = new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
+ | GridData.VERTICAL_ALIGN_CENTER);
+ data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+ label0.setLayoutData(data);
+ label0.setFont(parent.getFont());
+ label.setLayoutData(data);
+ label.setFont(parent.getFont());
+
+
+ secondText = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ secondText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.HORIZONTAL_ALIGN_FILL));
+ secondText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ validateInput();
+ }
+ });
+
+ // remove error message dialog from focusing.
+ composite.getTabList()[2].setVisible(false);
+ composite.getTabList()[2].setEnabled(false);
+
+ return composite;
+ }
+
+ /**
+ * Returns the text area.
+ *
+ * @return the text area
+ */
+ protected Text getSecondText() {
+ return secondText;
+ }
+
+ /**
+ * Returns the string typed into this input dialog.
+ *
+ * @return the input string
+ */
+ public String getSecondValue() {
+ return secondValue;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseConditionElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseConditionElement.java
new file mode 100644
index 0000000000..d06e73d091
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseConditionElement.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfCaseConditionElement extends AutoconfElement {
+
+ public AutoconfCaseConditionElement() {
+ super("");
+ }
+
+ public AutoconfCaseConditionElement(String name) {
+ super(name);
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseElement.java
new file mode 100644
index 0000000000..c8ad284dd4
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfCaseElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfCaseElement extends AutoconfElement {
+
+ public AutoconfCaseElement() {
+ super("case"); //$NON-NLS-1$
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.java
new file mode 100644
index 0000000000..53c7a7d857
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+
+/**
+ * AutoconfEditorMessages
+ */
+public class AutoconfEditorMessages {
+
+ private static final String RESOURCE_BUNDLE= AutoconfEditorMessages.class.getName();
+
+ private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+ private AutoconfEditorMessages() {
+ }
+
+ public static ResourceBundle getResourceBundle() {
+ return fgResourceBundle;
+ }
+
+ public static String getString(String key) {
+ try {
+ return fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+ /**
+ * Gets a string from the resource bundle and formats it with the argument
+ *
+ * @param key the string used to get the bundle value, must not be null
+ * @since 3.0
+ */
+ public static String getFormattedString(String key, Object arg) {
+ String format= null;
+ try {
+ format= fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ if (arg == null)
+ arg= ""; //$NON-NLS-1$
+ return MessageFormat.format(format, new Object[] { arg });
+ }
+ /**
+ * Gets a string from the resource bundle and formats it with the arguments
+ *
+ * @param key the string used to get the bundle value, must not be null
+ * @since 3.0
+ */
+ public static String getFormattedString(String key, Object arg1, Object arg2) {
+ String format= null;
+ try {
+ format= fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ if (arg1 == null)
+ arg1= ""; //$NON-NLS-1$
+ if (arg2 == null)
+ arg2= ""; //$NON-NLS-1$
+ return MessageFormat.format(format, new Object[] { arg1, arg2 });
+ }
+
+ /**
+ * Gets a string from the resource bundle and formats it with the arguments
+ *
+ * @param key the string used to get the bundle value, must not be null
+ * @since 3.0
+ */
+ public static String getFormattedString(String key, Object arg1, Object arg2, Object arg3) {
+ String format= null;
+ try {
+ format= fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ if (arg1 == null)
+ arg1= ""; //$NON-NLS-1$
+ if (arg2 == null)
+ arg2= ""; //$NON-NLS-1$
+ if (arg3 == null)
+ arg3= ""; //$NON-NLS-1$
+ return MessageFormat.format(format, new Object[] { arg1, arg2, arg3 });
+ }
+
+ /**
+ * Gets a string from the resource bundle and formats it with the argument
+ *
+ * @param key the string used to get the bundle value, must not be null
+ * @since 3.0
+ */
+ public static String getFormattedString(String key, boolean arg) {
+ String format= null;
+ try {
+ format= fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ return MessageFormat.format(format, new Object[] { new Boolean(arg) });
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.properties b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.properties
new file mode 100644
index 0000000000..692d0649fb
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfEditorMessages.properties
@@ -0,0 +1,47 @@
+#################################################################################
+# Copyright (c) 2007 Red Hat, Inc., (c) 2008 Nokia Inc
+# 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:
+# Red Hat Incorporated - initial API and implementation
+# Nokia Inc - refactoring
+#################################################################################
+UnmatchedRightParenthesis=Unmatched right parenthesis
+UnmatchedLeftParenthesis=Unmatched left parenthesis
+UnmatchedRightQuote=Unmatched right quote, expected {0}
+UnmatchedLeftQuote=Unmatched left quote, expected {0}
+UnmatchedCloseComment=Unmatched end of comment, expected {0}
+UnterminatedString=Unterminated string, expected {0}
+
+AutoconfMacroArgsTooFew=The autoconf version {0} definition of macro "{1}" requires at least {2} arguments
+AutoconfMacroArgsTooMany=The autoconf version {0} definition of macro "{1}" may have a maximum of {2} arguments
+M4MacroArgsTooFew=The m4 macro "{0}" requires at least {1} arguments
+M4MacroArgsTooMany=The m4 macro "{0}" may have a maximum of {1} arguments
+MissingSpecifier=Missing "{0}" specifier
+InvalidSpecifier=The specifier "{0}" should be separated from condition by semicolon or newline
+InvalidTermination=The specifier "{0}" should appear after semicolon or newline
+UnterminatedConstruct=This "{0}" construct is unterminated
+MissingCondition=Missing condition for {0} specifier
+InvalidElif=The "elif" keyword should appear in an "if" or "elif" construct
+InvalidElse=The "else" keyword should appear in an "if" or "elif" construct
+InvalidFi=The "fi" keyword should terminate an "if", "elif", or "else" construct
+InvalidEsac=The "esac" keyword should terminate a "case" statement
+InvalidDone=The "done" keyword should terminate a "for", "while", "until", or "select" statement
+InvalidDo=The "do" keyword should appear in a "for", "while", "until", or "select" statement
+InvalidThen=The "then" keyword should appear in an "if" or "elif" statement
+InvalidIn=The "in" keyword should appear in a "case" statement
+UnterminatedCaseCondition=Case condition is not terminated before "esac" keyword
+ImproperCaseCondition=Case condition expected to end with ")"
+UnterminatedInlineDocument=Inline document started with "<<" is unterminated
+IncompleteInlineMarker=Inline document marker has incomplete quote
+MissingInlineMarker=Inline document specification is missing end marker
+AutoconfAnnotationHover.multipleMarkers=Multiple markers at this line
+
+ShowToolTip.label=Show T&ooltip Description
+ContentAssistProposal.label=Co&ntent Assist
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.description=Content Assist
+
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElement.java
new file mode 100644
index 0000000000..2bf2a28c39
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElement.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+public class AutoconfElement {
+
+ protected String name;
+ protected String var;
+ protected int startOffset;
+ protected int endOffset;
+ protected ArrayList<AutoconfElement> children;
+ protected AutoconfElement parent;
+ private IDocument document;
+
+ public AutoconfElement(String name) {
+ this(name, null);
+ }
+
+ public AutoconfElement(String name, String var) {
+ this.name = name;
+ this.var = var;
+ this.startOffset = 0;
+ this.children = new ArrayList<AutoconfElement>();
+ }
+
+
+ public String toString() {
+ String source = getSource();
+ if (source == null) {
+ StringBuffer kids = new StringBuffer();
+ for (Iterator<AutoconfElement> iterator = children.iterator(); iterator.hasNext();) {
+ AutoconfElement kid = (AutoconfElement) iterator.next();
+ kids.append(kid.toString());
+ kids.append(",");
+ }
+ source = kids.toString();
+ }
+ return getClass().getSimpleName() + ": '" + source + "'";
+ }
+
+ public void addChild(AutoconfElement element) {
+ children.add(element);
+ if (element.getParent() == null)
+ element.setParent(this);
+ }
+
+ public void addSibling(AutoconfElement element) {
+ parent.addChild(element);
+ }
+
+ public AutoconfElement getLastChild() {
+ if (hasChildren())
+ return (AutoconfElement)children.get(children.size() - 1);
+ return null;
+ }
+
+ public AutoconfElement getParent() {
+ return parent;
+ }
+
+ public void setParent(AutoconfElement parent) {
+ this.parent = parent;
+ }
+
+ public AutoconfElement[] getChildren() {
+ return (AutoconfElement[]) children.toArray(new AutoconfElement[children.size()]);
+ }
+
+ public boolean hasChildren() {
+ return !children.isEmpty();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String string) {
+ this.name = string;
+ }
+
+
+ public String getVar() {
+ return var;
+ }
+
+ public void setVar(String value) {
+ var = value;
+ }
+
+ public void setDocument(IDocument document) {
+ this.document = document;
+ }
+
+ public IDocument getDocument() {
+ return document;
+ }
+
+ public void setStartOffset(int offset) {
+ this.startOffset = offset;
+ }
+
+ public int getStartOffset() {
+ return startOffset;
+ }
+
+ public void setEndOffset(int offset) {
+ this.endOffset = offset;
+ }
+
+ public int getEndOffset() {
+ return endOffset;
+ }
+
+ public String getSource() {
+ if (document != null && startOffset >= 0 && endOffset >= startOffset) {
+ try {
+ return document.get(startOffset, endOffset - startOffset);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElifElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElifElement.java
new file mode 100644
index 0000000000..a990ea82d5
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElifElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfElifElement extends AutoconfElement {
+
+ public AutoconfElifElement() {
+ super("elif"); //$NON-NLS-1$
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElseElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElseElement.java
new file mode 100644
index 0000000000..bbaa2c2c76
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfElseElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfElseElement extends AutoconfElement {
+
+ public AutoconfElseElement() {
+ super("else"); //$NON-NLS-1$
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfForElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfForElement.java
new file mode 100644
index 0000000000..6b0ffcc9a4
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfForElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfForElement extends AutoconfElement {
+
+ public AutoconfForElement() {
+ super("for"); //$NON-NLS-1$
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfIfElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfIfElement.java
new file mode 100644
index 0000000000..6ad658979c
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfIfElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfIfElement extends AutoconfElement {
+
+ public AutoconfIfElement() {
+ super("if"); //$NON-NLS-1$
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java
new file mode 100644
index 0000000000..24bf1d5f0b
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+/**
+ * This is a macro argument node. It may also hold
+ * other AutoconfMacroElements. The source range includes any quotes around an argument
+ * but the #getName() has them stripped.
+ * @author eswartz
+ *
+ */
+public class AutoconfMacroArgumentElement extends AutoconfElement {
+
+ public AutoconfMacroArgumentElement() {
+ super(""); // //$NON-NLS-N$
+ }
+ public AutoconfMacroArgumentElement(String name) {
+ super(name); // //$NON-NLS-N$
+ }
+ public String getVar() {
+ return super.getVar();
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroDetector.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroDetector.java
new file mode 100644
index 0000000000..3635bcd5a9
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroDetector.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc., (c) 2008 Nokia Corporation.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ * Ed Swartz (Nokia) - refactoring
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import java.util.regex.Pattern;
+
+/**
+ *
+ */
+public class AutoconfMacroDetector implements IAutoconfMacroDetector {
+
+ private static final Pattern AUTOCONF_MACRO_PATTERN = Pattern.compile("PKG_.*|AC_.*|AM_.*|m4.*"); //$NON-NLS-1$
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.cdt.autotools.ui.editors.parser.IAutoconfMacroDetector#isMacroIdentifier(java.lang.String)
+ */
+ public boolean isMacroIdentifier(String name) {
+ return AUTOCONF_MACRO_PATTERN.matcher(name).matches();
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java
new file mode 100644
index 0000000000..1168f910cc
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ * Ed Swartz (NOKIA Inc) - support standalone parser
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+/**
+ * A call to a macro.
+ * <p>
+ * Macro element now stores arguments as AutoconfMacroElement or AutoconfMacroArgument children
+ *
+ */
+public class AutoconfMacroElement extends AutoconfElement {
+
+ public AutoconfMacroElement(String name) {
+ super(name);
+ }
+
+ public String getVar() {
+ if (children.size() > 0)
+ return getParameter(0);
+ else
+ return null;
+ }
+ public int getParameterCount() {
+ return children.size();
+ }
+
+ public String getParameter(int num) {
+ return ((AutoconfElement) children.get(num)).getName();
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java
new file mode 100644
index 0000000000..9a5100eff7
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsPlugin;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+
+
+public class AutoconfOutlineErrorHandler {
+
+ public static final String PARSE_ERROR_MARKER_ID = AutotoolsPlugin.PLUGIN_ID
+ + ".outlineparsefileerror";
+
+ private IFile file;
+ private IDocument document;
+
+ public AutoconfOutlineErrorHandler(IStorageEditorInput input, IDocument document)
+ {
+ this.document = document;
+ IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
+ try {
+ IPath absPath = input.getStorage().getFullPath();
+ IPath rootPath = root.getLocation();
+ IPath relPath = new Path("");
+
+ for (int i = 0; i < rootPath.segmentCount(); ++i) {
+ relPath = relPath.append("../");
+ }
+ relPath = relPath.append(absPath);
+ this.file = root.getFileForLocation(relPath);
+ if (this.file == null) {
+ this.file = root.getFile(relPath);
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public IDocument getDocument() {
+ return document;
+ }
+
+ public void handleError(ParseException e) {
+ if (!file.exists())
+ return;
+
+ int lineNumber = e.getLineNumber();
+
+ Map<String, Object> map = new HashMap<String, Object>();
+ MarkerUtilities.setLineNumber(map, lineNumber);
+ MarkerUtilities.setMessage(map, e.getMessage());
+ map.put(IMarker.MESSAGE, e.getMessage());
+ map.put(IMarker.LOCATION, file.getFullPath().toString());
+
+ Integer charStart = getCharOffset(lineNumber, e.getStartColumn());
+ if (charStart != null) {
+ map.put(IMarker.CHAR_START, charStart);
+ }
+ Integer charEnd = getCharOffset(lineNumber, e.getEndColumn());
+ if (charEnd != null) {
+ map.put(IMarker.CHAR_END, charEnd);
+ }
+
+ // FIXME: add severity level
+ map.put(IMarker.SEVERITY, new Integer(e.getSeverity()));
+
+ try {
+ MarkerUtilities.createMarker(file, map, PARSE_ERROR_MARKER_ID);
+ } catch (CoreException ee) {
+ ee.printStackTrace();
+ }
+ return;
+ }
+
+ public void removeAllExistingMarkers() {
+ if (!file.exists())
+ return;
+
+ try {
+ file.deleteMarkers(PARSE_ERROR_MARKER_ID, true, IResource.DEPTH_ZERO);
+ } catch (CoreException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ public void removeExistingMarkers(int offset, int length) {
+ if (!file.exists())
+ return;
+
+ try {
+ IMarker[] markers = file.findMarkers(PARSE_ERROR_MARKER_ID, true, IResource.DEPTH_ZERO);
+ // Delete all markers that start in the given document range.
+ for (int i = 0; i < markers.length; ++i) {
+ IMarker marker = markers[i];
+ int charEnd = MarkerUtilities.getCharEnd(marker);
+ int charStart = MarkerUtilities.getCharStart(marker);
+ if (charStart >= offset && charEnd <= (offset + length))
+ marker.delete();
+ }
+ } catch (CoreException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ private Integer getCharOffset(int lineNumber, int columnNumber) {
+ try {
+ return new Integer(document.getLineOffset(lineNumber) + columnNumber);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfParser.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfParser.java
new file mode 100644
index 0000000000..e6996035c2
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfParser.java
@@ -0,0 +1,1041 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc., (c) 2008 Nokia
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ * Ed Swartz (Nokia) - refactoring
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * Tokenizing autoconf parser, based on original work by Jeff Johnston
+ * @author eswartz
+ */
+public class AutoconfParser {
+
+ public static final String MISSING_SPECIFIER = "MissingSpecifier"; //$NON-NLS-1$
+ public static final String INVALID_SPECIFIER = "InvalidSpecifier"; //$NON-NLS-1$
+ public static final String INVALID_TERMINATION = "InvalidTermination"; //$NON-NLS-1$
+ public static final String UNTERMINATED_CONSTRUCT = "UnterminatedConstruct"; //$NON-NLS-1$
+ public static final String MISSING_CONDITION = "MissingCondition"; //$NON-NLS-1$
+ public static final String INVALID_ELIF = "InvalidElif"; //$NON-NLS-1$
+ public static final String INVALID_ELSE = "InvalidElse"; //$NON-NLS-1$
+ public static final String INVALID_FI = "InvalidFi"; //$NON-NLS-1$
+ public static final String INVALID_DONE = "InvalidDone"; //$NON-NLS-1$
+ public static final String INVALID_ESAC = "InvalidEsac"; //$NON-NLS-1$
+ public static final String INVALID_DO = "InvalidDo"; //$NON-NLS-1$
+ public static final String INVALID_THEN = "InvalidThen"; //$NON-NLS-1$
+ public static final String INVALID_IN = "InvalidIn"; //$NON-NLS-1$
+ public static final String IMPROPER_CASE_CONDITION = "ImproperCaseCondition"; //$NON-NLS-1$
+ public static final String UNTERMINATED_CASE_CONDITION = "UnterminatedCaseCondition"; //$NON-NLS-1$
+ public static final String UNTERMINATED_INLINE_DOCUMENT = "UnterminatedInlineDocument"; //$NON-NLS-1$
+ public static final String INCOMPLETE_INLINE_MARKER="IncompleteInlineMarker"; //$NON-NLS-1$
+ public static final String MISSING_INLINE_MARKER="MissingInlineMarker"; //$NON-NLS-1$
+ public static final String UNMATCHED_RIGHT_PARENTHESIS = "UnmatchedRightParenthesis"; //$NON-NLS-1$
+ public static final String UNMATCHED_LEFT_PARENTHESIS = "UnmatchedLeftParenthesis"; //$NON-NLS-1$
+
+ private IAutoconfErrorHandler errorHandler;
+ private IAutoconfMacroValidator macroValidator;
+ private AutoconfTokenizer tokenizer;
+ private IAutoconfMacroDetector macroDetector;
+
+ private static final String M4_BUILTINS =
+ "define undefine defn pushdef popdef indir builtin ifdef ifelse shift reverse cond " +
+ "dumpdef traceon traceoff debugmode debugfile dnl changequote changecom changeword " +
+ "m4wrap " +
+ "include sinclude divert undivert divnum len index regexp substr translit patsubst " +
+ "format incr decr eval syscmd esyscmd sysval mkstemp maketemp errprint m4exit " +
+ "__file__ __line__ __program__ ";
+
+ private static List<String> m4builtins = new ArrayList<String>();
+ static {
+ m4builtins.addAll(Arrays.asList(M4_BUILTINS.split(" ")));
+ }
+
+ /**
+ * Create a parser for autoconf-style sources.
+ * @param errorHandler
+ * @param macroDetector
+ * @param macroValidator
+ */
+ public AutoconfParser(IAutoconfErrorHandler errorHandler,
+ IAutoconfMacroDetector macroDetector,
+ IAutoconfMacroValidator macroValidator) {
+ this.errorHandler = errorHandler;
+ this.macroDetector = macroDetector;
+ this.macroValidator = macroValidator;
+ }
+
+ /**
+ * Parse the given document and produce an AutoconfElement tree
+ * @param errorHandler
+ * @param macroValidator
+ * @param document
+ * @return element tree
+ */
+ public AutoconfElement parse(IDocument document) {
+ return parse(document, true);
+ }
+
+ /**
+ * Parse the given document and produce an AutoconfElement tree,
+ * and control whether the initial quoting style is m4 style (`...')
+ * or autoconf style ([ ... ]).
+ * @param errorHandler
+ * @param macroValidator
+ * @param document
+ * @param useAutoconfQuotes
+ * @return element tree
+ */
+ public AutoconfElement parse(IDocument document, boolean useAutoconfQuotes) {
+ this.tokenizer = new AutoconfTokenizer(document, errorHandler);
+ if (useAutoconfQuotes)
+ tokenizer.setM4Quote("[", "]");
+
+ AutoconfElement root = new AutoconfRootElement();
+ Token eof = parseTopLevel(root);
+
+ root.setStartOffset(0);
+ root.setDocument(document);
+
+ setSourceEnd(root, eof);
+
+ return root;
+ }
+
+
+ static class BlockEndCondition extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private Token token;
+
+ public BlockEndCondition(Token token) {
+ this.token = token;
+ }
+
+ public Token getToken() {
+ return token;
+ }
+
+ }
+
+ static class ExprEndCondition extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private Token token;
+
+ public ExprEndCondition(Token token) {
+ this.token = token;
+ }
+
+ public Token getToken() {
+ return token;
+ }
+
+ }
+
+ /**
+ * Parse individual top-level nodes: divide text into macro calls
+ * and recognized shell constructs. Anything else is not accounted for.
+ * @param parent
+ * @return
+ */
+ protected Token parseTopLevel(AutoconfElement parent) {
+ while (true) {
+ try {
+ parseStatement(parent);
+ } catch (BlockEndCondition e) {
+ // don't terminate here; we may have constructs closed too early
+ Token token = tokenizer.peekToken();
+ if (token.getType() == ITokenConstants.EOF)
+ return token;
+ }
+ }
+ }
+
+ /**
+ * Parse a block of nodes, which starts with an expression and contains
+ * subnodes. Divide text into macro calls and recognized shell constructs.
+ * Anything else is not accounted for.
+ * @param parent
+ */
+ protected void parseBlock(AutoconfElement parent, Token open, AutoconfElement block) throws BlockEndCondition {
+ parent.addChild(block);
+
+ setSourceStart(block, open);
+
+ // get the expression part
+ Token token;
+ try {
+ token = parseBlockExpression(open, block);
+ } catch (BlockEndCondition e) {
+ setSourceEndBefore(block, e.getToken());
+ throw e;
+ }
+
+ // parse the block proper
+ if (token.getType() != ITokenConstants.EOF) {
+ while (true) {
+ try {
+ parseStatement(block);
+ } catch (BlockEndCondition e) {
+ setSourceEnd(block, e.getToken());
+ return;
+ }
+ }
+ } else {
+ setSourceEnd(block, token);
+ }
+ }
+
+ private Token parseBlockExpression(Token open, AutoconfElement block) throws BlockEndCondition {
+ Token token;
+ try {
+ if (block instanceof AutoconfIfElement
+ || block instanceof AutoconfElifElement
+ || block instanceof AutoconfCaseElement
+ || block instanceof AutoconfWhileElement) {
+ token = parseExpression(block);
+ } else if (block instanceof AutoconfForElement) {
+ token = parseForExpression(block);
+ } else {
+ // no expression
+ return open;
+ }
+ block.setVar(getTokenSpanTextBetween(open, token));
+ } catch (BlockEndCondition e) {
+ // oops, premature end
+ setSourceEnd(block, e.getToken());
+ throw e;
+ }
+
+ // check for expected token
+ while (true) {
+ token = tokenizer.readToken();
+ if (token.getType() == ITokenConstants.EOF)
+ break;
+ if (token.getType() != ITokenConstants.EOL)
+ break;
+ }
+
+ if (token.getType() == ITokenConstants.SH_DO) {
+ checkBlockValidity(block, token,
+ new Class[] { AutoconfForElement.class, AutoconfWhileElement.class },
+ INVALID_DO);
+ }
+ else if (token.getType() == ITokenConstants.SH_THEN) {
+ checkBlockValidity(block, token,
+ new Class[] { AutoconfIfElement.class, AutoconfElifElement.class },
+ INVALID_THEN);
+ }
+ else {
+ String exp;
+ if (block instanceof AutoconfIfElement || block instanceof AutoconfElifElement)
+ exp = "then";
+ else
+ exp = "do";
+
+ handleError(block, token, AutoconfEditorMessages.getFormattedString(MISSING_SPECIFIER, exp));
+
+ // assume we're still in the block...
+ tokenizer.unreadToken(token);
+ }
+ return token;
+ }
+
+ /**
+ * Parse a case statement. Scoop up statements into case conditional blocks.
+ * <pre>
+ * 'case' EXPR 'in'
+ * { EXPR ')' { STMTS } ';;' }
+ * 'esac'
+ * </pre>
+ * @param parent
+ * @return
+ */
+ protected void parseCaseBlock(AutoconfElement parent, Token open, AutoconfElement block) throws BlockEndCondition {
+ parent.addChild(block);
+
+ setSourceStart(block, open);
+
+ // get the case expression, terminating at 'in'
+ Token token;
+ try {
+ token = parseCaseExpression(block);
+ } catch (BlockEndCondition e) {
+ // oops, premature end
+ setSourceEnd(block, e.getToken());
+ throw e;
+ }
+
+ block.setVar(getTokenSpanTextBetween(open, token));
+
+ // now get the statements, which are themselves blocks... just read statements
+ // that terminate with ';;' and stuff those into blocks.
+
+ while (true) {
+ AutoconfCaseConditionElement condition = new AutoconfCaseConditionElement();
+
+ // skip EOLs and get the first "real" token
+ while (true) {
+ token = tokenizer.readToken();
+ setSourceStart(condition, token);
+ if (token.getType() == ITokenConstants.EOF)
+ break;
+ if (token.getType() == ITokenConstants.EOL)
+ continue;
+ break;
+ }
+
+ if (token.getType() == ITokenConstants.SH_ESAC) {
+ break;
+ }
+
+ try {
+ Token start = token;
+ token = parseCaseExpression(condition);
+ condition.setName(getTokenSpanTextFromUpTo(start, token));
+
+ while (true) {
+ parseStatement(condition);
+ }
+ } catch (BlockEndCondition e) {
+ setSourceEnd(condition, e.getToken());
+
+ if (condition.getSource().length() > 0)
+ block.addChild(condition);
+
+ if (e.getToken().getType() != ITokenConstants.SH_CASE_CONDITION_END) {
+ token = e.getToken();
+ break;
+ }
+ }
+ }
+
+ setSourceEnd(block, token);
+
+ if (token.getType() != ITokenConstants.SH_ESAC) {
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(UNTERMINATED_CONSTRUCT, block.getName()));
+ }
+ }
+
+ private String getTokenSpanTextBetween(Token open, Token close) {
+ int startOffset = open.getOffset() + open.getLength();
+ int endOffset = close.getOffset();
+ if (open.getDocument() != close.getDocument())
+ return open.getText();
+
+ String text;
+ try {
+ text = open.getDocument().get(startOffset, endOffset - startOffset).trim();
+ } catch (BadLocationException e) {
+ text = open.getText();
+ // TODO: error
+ }
+
+ return text;
+ }
+
+ private String getTokenSpanTextFromUpTo(Token open, Token close) {
+ int startOffset = open.getOffset();
+ int endOffset = close.getOffset();
+ if (open.getDocument() != close.getDocument())
+ return open.getText();
+
+ String text;
+ try {
+ text = open.getDocument().get(startOffset, endOffset - startOffset).trim();
+ } catch (BadLocationException e) {
+ text = open.getText();
+ // TODO: error
+ }
+
+ return text;
+ }
+ private void setSourceStart(AutoconfElement block, Token open) {
+ int offset = open.getOffset();
+ block.setDocument(open.getDocument());
+ block.setStartOffset(offset);
+ }
+
+ private void setSourceEnd(AutoconfElement block, Token close) {
+ int offset = close.getOffset() + close.getLength();
+ if (block.getDocument() != null && block.getDocument() != close.getDocument())
+ throw new IllegalStateException();
+ block.setDocument(close.getDocument());
+ block.setEndOffset(offset);
+ }
+
+ private void setSourceEndBefore(AutoconfElement block, Token close) {
+ int offset = close.getOffset();
+ if (block.getDocument() != null && block.getDocument() != close.getDocument())
+ throw new IllegalStateException();
+ block.setDocument(close.getDocument());
+ block.setEndOffset(offset);
+ }
+
+ /**
+ * Parse a single statement (macro call or a shell construct).
+ * This can recursively invoke parseBlock() or parseStatement() to populate the tree.
+ * Whenever a token terminates a block, we check its validity and then throw BlockEndCondition.
+ * @param parent the parent into which to add statements. The type of this element is used
+ * to validate the legality of block closing tokens.
+ */
+ protected void parseStatement(AutoconfElement parent) throws BlockEndCondition {
+
+ boolean atStart = true;
+
+ while (true) {
+ Token token = tokenizer.readToken();
+
+ switch (token.getType()) {
+ // 0. Check EOF
+ case ITokenConstants.EOF:
+ AutoconfElement element = parent;
+ while (element != null && !(element instanceof AutoconfRootElement)) {
+ handleError(element, token, AutoconfEditorMessages.getFormattedString(UNTERMINATED_CONSTRUCT, element.getName()));
+ element = element.getParent();
+ }
+ throw new BlockEndCondition(token);
+
+
+ // 1. Check for end of statement
+ case ITokenConstants.EOL:
+ case ITokenConstants.SEMI:
+ return;
+
+
+ // 2. Check macro expansions
+ case ITokenConstants.WORD:
+ checkMacro(parent, token);
+ atStart = false;
+ break;
+
+ // Check for shell constructs. These should appear at the start of a line
+ // or after a semicolon. If they don't, just report an error and continue,
+ // to be tolerant of our own lax parsing.
+
+ // 3.a) Check dollar variables
+ case ITokenConstants.SH_DOLLAR:
+ // skip the next token
+ atStart = false;
+ token = tokenizer.readToken();
+ continue;
+
+ // 3.b) Look for if/else/elif/fi constructs,
+ // being tolerant of nesting problems by allowing
+ // stranded else/elif nodes but reporting errors.
+ case ITokenConstants.SH_IF:
+ checkLineStart(parent, token, atStart);
+ parseBlock(parent, token, new AutoconfIfElement());
+ break;
+
+ case ITokenConstants.SH_ELIF:
+ checkLineStart(parent, token, atStart);
+ checkBlockValidity(
+ parent, token,
+ new Class[] { AutoconfIfElement.class, AutoconfElifElement.class },
+ INVALID_ELIF);
+ parseBlock(parent, token, new AutoconfElifElement());
+ token = tokenizer.peekToken();
+ throw new BlockEndCondition(token);
+
+ case ITokenConstants.SH_ELSE:
+ checkLineStart(parent, token, atStart);
+ checkBlockValidity(
+ parent, token,
+ new Class[] { AutoconfIfElement.class, AutoconfElifElement.class },
+ INVALID_ELSE);
+ parseBlock(parent, token, new AutoconfElseElement());
+ token = tokenizer.peekToken();
+ throw new BlockEndCondition(token);
+
+ case ITokenConstants.SH_FI:
+ checkLineStart(parent, token, atStart);
+ checkBlockValidity(
+ parent, token,
+ new Class[] { AutoconfIfElement.class, AutoconfElifElement.class, AutoconfElseElement.class },
+ INVALID_FI);
+ throw new BlockEndCondition(token);
+
+
+ // 4. Look for for/while loops
+ case ITokenConstants.SH_FOR:
+ checkLineStart(parent, token, atStart);
+ parseBlock(parent, token, new AutoconfForElement());
+ break;
+
+ case ITokenConstants.SH_WHILE:
+ checkLineStart(parent, token, atStart);
+ parseBlock(parent, token, new AutoconfWhileElement());
+ break;
+
+ case ITokenConstants.SH_UNTIL:
+ checkLineStart(parent, token, atStart);
+ parseBlock(parent, token, new AutoconfUntilElement());
+ break;
+
+ case ITokenConstants.SH_SELECT:
+ checkLineStart(parent, token, atStart);
+ parseBlock(parent, token, new AutoconfSelectElement());
+ break;
+
+ case ITokenConstants.SH_DONE:
+ checkLineStart(parent, token, atStart);
+ checkBlockValidity(
+ parent, token,
+ new Class[] { AutoconfForElement.class, AutoconfWhileElement.class,
+ AutoconfUntilElement.class, AutoconfSelectElement.class },
+ INVALID_DONE);
+ throw new BlockEndCondition(token);
+
+ // 5. Look for case statements
+ case ITokenConstants.SH_CASE:
+ checkLineStart(parent, token, atStart);
+ parseCaseBlock(parent, token, new AutoconfCaseElement());
+ break;
+
+ case ITokenConstants.SH_CASE_CONDITION_END:
+ checkBlockValidity(
+ parent, token,
+ new Class[] { AutoconfCaseConditionElement.class },
+ IMPROPER_CASE_CONDITION);
+ throw new BlockEndCondition(token);
+
+ case ITokenConstants.SH_ESAC:
+ checkLineStart(parent, token, atStart);
+ checkBlockValidity(
+ parent, token,
+ // note: we don't strictly recurse here, so accept either parent
+ new Class[] { AutoconfCaseElement.class, AutoconfCaseConditionElement.class },
+ INVALID_ESAC);
+ throw new BlockEndCondition(token);
+
+
+ // 6. Check for HERE documents
+ case ITokenConstants.SH_HERE:
+ case ITokenConstants.SH_HERE_DASH:
+
+ parseHERE(parent, token);
+ break;
+ }
+ }
+ }
+
+ private void checkLineStart(AutoconfElement parent, Token token, boolean atStart) {
+ if (!atStart) {
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(INVALID_TERMINATION, token.getText()));
+ }
+ }
+
+ /**
+ * Parse the Here document, whose control token is provided (SH_HERE or SH_HERE_DASH).
+ * Contents are thrown away except for any macro calls.
+ * @param parent
+ * @param controlToken
+ */
+ private void parseHERE(AutoconfElement parent, Token controlToken) {
+ Token token = tokenizer.readToken();
+ if (token.getType() == ITokenConstants.EOL || token.getType() == ITokenConstants.EOF) {
+ handleError(parent, token,
+ AutoconfEditorMessages.getString(INCOMPLETE_INLINE_MARKER));
+
+ } else {
+ String hereTag = token.getText();
+
+ boolean atEOL = false;
+ while (true) {
+ token = tokenizer.readToken();
+ if (token.getType() == ITokenConstants.EOF) {
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(UNTERMINATED_CONSTRUCT, parent.getName()));
+ break;
+ } else if (token.getType() == ITokenConstants.EOL) {
+ atEOL = true;
+ } else {
+ if (atEOL && token.getText().equals(hereTag)) {
+ // only the end if it is also followed by EOL without any whitespace
+ Token eol = tokenizer.readToken();
+ if (eol.getType() == ITokenConstants.EOL && eol.getOffset() == token.getOffset() + token.getLength()) {
+ break;
+ }
+ }
+ if (token.getType() == ITokenConstants.WORD) {
+ checkMacro(parent, token);
+ }
+ atEOL = false;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parse through a single expression up to a semicolon or newline.
+ * Add a macro call to the element or just return upon finding the desired token.
+ * Whenever a token terminates the expression, we check its validity and return the final token
+ * Throw {@link BlockEndCondition} if an unexpected token was found.
+ * @param parent the parent into which to add statements. The type of this element is used
+ * to validate the legality of block closing tokens.
+ */
+ protected Token parseExpression(AutoconfElement parent) throws BlockEndCondition {
+
+ while (true) {
+ Token token = tokenizer.readToken();
+
+ // 0. Ignore comments (tokenizer skipped them!)
+
+ switch (token.getType()) {
+ // 1. Check EOF
+ case ITokenConstants.EOF:
+ throw new BlockEndCondition(token);
+
+ // 2. Check macro expansions
+ case ITokenConstants.WORD:
+ token = checkMacro(parent, token);
+ break;
+
+ // 3. Check expression terminators
+ case ITokenConstants.SEMI:
+ case ITokenConstants.EOL:
+ return token;
+
+ // 4. Handle variables
+ case ITokenConstants.SH_DOLLAR:
+ token = tokenizer.readToken();
+ break;
+
+ case ITokenConstants.SH_IN:
+ // in 'for' or 'select, an 'in' may occur before 'do'
+ if (!(parent instanceof AutoconfForElement)
+ && !(parent instanceof AutoconfSelectElement))
+ return token;
+ // fall through
+
+ // 5. Abort on unexpected tokens
+ case ITokenConstants.SH_DO:
+ case ITokenConstants.SH_THEN:
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(INVALID_SPECIFIER, token.getText()));
+ tokenizer.unreadToken(token);
+ // close enough...
+ return token;
+
+ case ITokenConstants.SH_ESAC:
+ case ITokenConstants.SH_CASE:
+ case ITokenConstants.SH_CASE_CONDITION_END:
+ case ITokenConstants.SH_FOR:
+ case ITokenConstants.SH_IF:
+ case ITokenConstants.SH_ELIF:
+ case ITokenConstants.SH_ELSE:
+ case ITokenConstants.SH_FI:
+ case ITokenConstants.SH_DONE:
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(UNTERMINATED_CONSTRUCT, parent.getName()));
+ tokenizer.unreadToken(token);
+ throw new BlockEndCondition(token);
+ }
+ }
+ }
+
+ /**
+ * Parse through a single expression up to 'do'.
+ * Add a macro call to the element or just return upon finding the desired token.
+ * Whenever a token terminates the expression, we check its validity and then throw ExprEndCondition.
+ * Throw {@link BlockEndCondition} if an unexpected token was found.
+ * @param parent the parent into which to add statements. The type of this element is used
+ * to validate the legality of block closing tokens.
+ */
+ protected Token parseForExpression(AutoconfElement parent) throws BlockEndCondition {
+ while (true) {
+ Token token = tokenizer.readToken();
+
+ // 0. Ignore comments (tokenizer skipped them!)
+
+ // 1. Check EOF
+ if (token.getType() == ITokenConstants.EOF) {
+ throw new BlockEndCondition(token);
+ }
+
+ // 2. Check macro expansions
+ else if (token.getType() == ITokenConstants.WORD) {
+ token = checkMacro(parent, token);
+ }
+
+ // 3. Check expression terminators -- not ';' here, but 'do'
+ else if (token.getType() == ITokenConstants.SH_DO) {
+ tokenizer.unreadToken(token);
+ return tokenizer.peekToken();
+ }
+
+ // 4. Abort on unexpected tokens
+ else switch (token.getType()) {
+ case ITokenConstants.SH_THEN:
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(INVALID_SPECIFIER, token.getText()));
+ tokenizer.unreadToken(token);
+ // close enough...
+ //throw new ExprEndCondition(token);
+ return token;
+
+ case ITokenConstants.SH_ESAC:
+ case ITokenConstants.SH_CASE:
+ case ITokenConstants.SH_CASE_CONDITION_END:
+ case ITokenConstants.SH_FOR:
+ case ITokenConstants.SH_IF:
+ case ITokenConstants.SH_ELIF:
+ case ITokenConstants.SH_ELSE:
+ case ITokenConstants.SH_FI:
+ case ITokenConstants.SH_DONE:
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(UNTERMINATED_CONSTRUCT, parent.getName()));
+ tokenizer.unreadToken(token);
+ throw new BlockEndCondition(token);
+ }
+ }
+ }
+
+ /**
+ * Parse through a single expression up to 'in'.
+ * Add a macro call to the element or just return upon finding the desired token.
+ * Whenever a token terminates the expression, we check its validity and then throw ExprEndCondition.
+ * Throw {@link BlockEndCondition} if an unexpected token was found.
+ * @param parent the parent into which to add statements. The type of this element is used
+ * to validate the legality of block closing tokens.
+ */
+ protected Token parseCaseExpression(AutoconfElement parent) throws BlockEndCondition {
+ while (true) {
+ Token token = tokenizer.readToken();
+
+ // 0. Ignore comments (tokenizer skipped them!)
+
+ // 1. Check EOF
+ if (token.getType() == ITokenConstants.EOF) {
+ throw new BlockEndCondition(token);
+ }
+
+ // 2. Check macro expansions
+ else if (token.getType() == ITokenConstants.WORD) {
+ token = checkMacro(parent, token);
+ }
+
+ // 3. Check expression terminators
+ else if (parent instanceof AutoconfCaseElement && token.getType() == ITokenConstants.SH_IN) {
+ return token;
+ }
+ else if (parent instanceof AutoconfCaseConditionElement && token.getType() == ITokenConstants.RPAREN) {
+ return token;
+ }
+
+ // 4. Abort on unexpected tokens
+ else switch (token.getType()) {
+ case ITokenConstants.SEMI:
+ case ITokenConstants.SH_IN:
+ case ITokenConstants.RPAREN:
+ case ITokenConstants.SH_DO:
+ case ITokenConstants.SH_THEN:
+ if (parent instanceof AutoconfCaseElement)
+ handleError(parent, token, AutoconfEditorMessages.getString(INVALID_IN));
+ else
+ handleError(parent, token, AutoconfEditorMessages.getString(IMPROPER_CASE_CONDITION));
+ // close enough...
+ return token;
+
+ case ITokenConstants.SH_ESAC:
+ case ITokenConstants.SH_CASE:
+ case ITokenConstants.SH_CASE_CONDITION_END:
+ case ITokenConstants.SH_FOR:
+ case ITokenConstants.SH_IF:
+ case ITokenConstants.SH_ELIF:
+ case ITokenConstants.SH_ELSE:
+ case ITokenConstants.SH_FI:
+ case ITokenConstants.SH_DONE:
+ handleError(parent, token, AutoconfEditorMessages.getFormattedString(UNTERMINATED_CONSTRUCT, parent.getName()));
+ tokenizer.unreadToken(token);
+ throw new BlockEndCondition(token);
+ }
+ }
+ }
+
+ /**
+ * Check a given close block token against the current parent by checking that
+ * the parent's class is one of classes, If a match happens,
+ * optionally push back the token if it will be used to parse new statements in the parent.
+ * Report an error if the parent is not one of the expected kinds.
+ * @param parent
+ * @param token
+ * @param classes
+ */
+ private void checkBlockValidity(
+ AutoconfElement parent,
+ Token token,
+ Class<?>[] classes,
+ String errorMessage) {
+ for (int i = 0; i < classes.length; i++) {
+ if (classes[i].isInstance(parent)) {
+ return;
+ }
+ }
+
+ // not a match
+ handleError(parent, token,
+ AutoconfEditorMessages.getFormattedString(errorMessage, parent.getName(), token.getText()));
+ }
+
+ /**
+ * Check whether the given token is part of a macro, and parse it as such
+ * if necessary.
+ * @param parent
+ * @param token
+ * @return Token last read for the macro call
+ */
+ private Token checkMacro(AutoconfElement parent, Token token) {
+ String name = token.getText();
+
+ boolean hasArguments = tokenizer.peekToken().getType() == ITokenConstants.LPAREN;
+ if (macroDetector != null && macroDetector.isMacroIdentifier(name)) {
+ // ok
+ } else if (m4builtins.contains(name)) {
+ // all of these except dnl take arguments
+ if (!name.equals("dnl") && !hasArguments)
+ return token;
+ } else {
+ return token;
+ }
+
+ AutoconfMacroElement macro = new AutoconfMacroElement(name);
+ token = parseMacro(macro, token);
+
+ // handle special macros here
+ if ("dnl".equals(name)) {
+ // consume to EOL
+ while (true) {
+ token = tokenizer.readToken();
+ if (token.getType() == ITokenConstants.EOF || token.getType() == ITokenConstants.EOL)
+ break;
+ }
+
+ // ignore macro entirely
+ macro = null;
+ } else if ("changequote".equals(name)) {
+ // change quote delimiters
+ validateMacroParameterCount(macro, token, 2);
+
+ // GNU behavior for invalid argument count
+ String parm0 = "`";
+ String parm1 = "'";
+ if (macro.getParameterCount() >= 1)
+ parm0 = macro.getParameter(0);
+ if (macro.getParameterCount() >= 2)
+ parm1 = macro.getParameter(1);
+
+ tokenizer.setM4Quote(parm0, parm1);
+ } else if ("changecom".equals(name)) {
+ // change comment delimiters
+ validateMacroParameterCount(macro, token, 2);
+
+ // GNU behavior for invalid argument count
+ String parm0 = "#";
+ String parm1 = "\n";
+ if (macro.getParameterCount() >= 1)
+ parm0 = macro.getParameter(0);
+ if (macro.getParameterCount() >= 2)
+ parm1 = macro.getParameter(1);
+
+ tokenizer.setM4Comment(parm0, parm1);
+ }
+
+ if (macro != null) {
+ parent.addChild(macro);
+ }
+
+ // now validate that the macro is properly terminated
+ if (!(parent instanceof AutoconfMacroArgumentElement)
+ && !(parent instanceof AutoconfMacroElement)
+ && !(parent instanceof AutoconfForElement)) {
+ Token peek = tokenizer.peekToken();
+ if (peek.getType() == ITokenConstants.RPAREN) {
+ handleError(macro, peek, AutoconfEditorMessages.getString(UNMATCHED_RIGHT_PARENTHESIS));
+ }
+ }
+
+ return token;
+ }
+
+ private void validateMacroParameterCount(AutoconfMacroElement macro, Token token, int count) {
+ if (macro.getParameterCount() < count) {
+ handleError(macro, token, AutoconfEditorMessages.getFormattedString("M4MacroArgsTooFew", macro.getName(), new Integer(2)));
+ } else if (macro.getParameterCount() > count) {
+ handleError(macro, token, AutoconfEditorMessages.getFormattedString("M4MacroArgsTooMany", macro.getName(), new Integer(2)));
+ }
+ }
+
+ /**
+ * Start parsing a macro call at a suspected macro expansion location.
+ * @param macro
+ * @param line the line containing the start of the
+ * @param parent
+ * @return last token parsed
+ */
+ protected Token parseMacro(AutoconfMacroElement macro, Token macroName) {
+ setSourceStart(macro, macroName);
+
+ // parse any arguments
+ tokenizer.setM4Context(true);
+
+ Token token = tokenizer.readToken();
+ if (token.getType() == ITokenConstants.LPAREN) {
+ token = parseMacroArguments(macro, token);
+ setSourceEnd(macro, token);
+ } else {
+ tokenizer.unreadToken(token);
+ setSourceEnd(macro, macroName);
+ }
+
+ tokenizer.setM4Context(false);
+
+ // validate macro arguments?
+ if (macroValidator != null) {
+ try {
+ macroValidator.validateMacroCall(macro);
+ } catch (ParseException e) {
+ errorHandler.handleError(e);
+ }
+ }
+
+ return token;
+ }
+
+ /**
+ * Parse the arguments for the given macro. These are not interpreted as shell
+ * constructs but just as text with possibly more macro expansions inside.
+ * @param macro
+ * @return final token (')')
+ */
+ protected Token parseMacroArguments(AutoconfMacroElement macro, Token lparen) {
+ Token argStart = null;
+ Token argEnd = null;
+ Token token;
+
+ // When parsing, we want to ignore the whitespace around the arguments.
+ // So, instead of taking the source range "between" a parenthesis and a comma,
+ // track the exact tokens forming the start and end of an argument, defaulting
+ // to the borders of the parentheses and commas if no text is included.
+
+ StringBuffer argBuffer = new StringBuffer();
+ AutoconfMacroArgumentElement arg = new AutoconfMacroArgumentElement();
+
+ while (true) {
+ token = tokenizer.readToken();
+
+ if (token.getType() == ITokenConstants.EOL) {
+ if (argBuffer.length() > 0)
+ argBuffer.append(token.getText());
+ continue;
+ }
+
+ if (token.getType() == ITokenConstants.COMMA
+ || token.getType() == ITokenConstants.RPAREN
+ || token.getType() == ITokenConstants.EOF) {
+
+ arg.setName(argBuffer.toString());
+ argBuffer.setLength(0);
+
+ if (argStart != null && argEnd != null) {
+ setSourceStart(arg, argStart);
+ setSourceEnd(arg, argEnd);
+ } else if (argEnd != null) {
+ setSourceStart(arg, argStart);
+ setSourceEndBefore(arg, token);
+ } else {
+ // empty argument
+ setSourceStart(arg, token);
+ setSourceEndBefore(arg, token);
+ }
+
+ macro.addChild(arg);
+
+ if (token.getType() != ITokenConstants.COMMA)
+ break;
+
+ argStart = null;
+ argEnd = null;
+
+ arg = new AutoconfMacroArgumentElement();
+
+ } else {
+ if (argStart == null) {
+ argStart = token;
+ }
+ argEnd = token;
+
+ if (argBuffer.length() > 0 && token.followsSpace())
+ argBuffer.append(' ');
+ argBuffer.append(token.getText());
+
+ // handle nested macro calls in arguments
+ if (token.getType() == ITokenConstants.WORD) {
+ argEnd = checkMacro(arg, token);
+ }
+ }
+ }
+
+ if (token.getType() != ITokenConstants.RPAREN) {
+ handleError(macro, token, AutoconfEditorMessages.getString(UNMATCHED_LEFT_PARENTHESIS));
+ }
+
+ // note: moved 15-char truncation to AutoconfLabelProvider
+ AutoconfElement[] children = macro.getChildren();
+ if (children.length > 0)
+ macro.setVar(children[0].getVar());
+
+ return token;
+ }
+
+
+
+ protected void handleError(AutoconfElement element, Token token, String message) {
+ handleMessage(element, token, message, IMarker.SEVERITY_ERROR);
+ }
+ protected void handleWarning(AutoconfElement element, Token token, String message) {
+ handleMessage(element, token, message, IMarker.SEVERITY_WARNING);
+ }
+ protected void handleMessage(AutoconfElement element, Token token, String message, int severity) {
+ if (errorHandler != null) {
+ int lineNumber = 0;
+ int startColumn = 0;
+ int endColumn = 0;
+ try {
+ lineNumber = token.getDocument().getLineOfOffset(token.getOffset());
+ int lineOffs = token.getDocument().getLineOffset(lineNumber);
+ startColumn = token.getOffset() - lineOffs;
+ endColumn = startColumn + token.getLength();
+ } catch (BadLocationException e) {
+ // Don't care if we blow up trying to issue marker
+ }
+ errorHandler.handleError(new ParseException(
+ message,
+ token.getOffset(),
+ token.getOffset() + token.getLength(),
+ lineNumber,
+ startColumn, endColumn,
+ severity));
+ }
+ }
+
+ public IAutoconfErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+}
+
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfRootElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfRootElement.java
new file mode 100644
index 0000000000..105d00b88d
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfRootElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfRootElement extends AutoconfElement {
+
+ public AutoconfRootElement() {
+ super(""); //$NON-NLS-1$
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java
new file mode 100644
index 0000000000..aded97c871
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfSelectElement extends AutoconfElement {
+
+ public AutoconfSelectElement() {
+ super("select");
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java
new file mode 100644
index 0000000000..a34cbb2448
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java
@@ -0,0 +1,434 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * This tokenizer traverses autotools-style text (m4 or configure.ac) to support the
+ * autoconf parser. It tracks the current context (m4 macro call or shell commands)
+ * to detect appropriate tokens, and tracks the m4 current quote style as well.
+ * <p>
+ * In m4 mode, its primary purpose is to find word boundaries, detect comments and quoted
+ * strings, and to find the macro punctuation tokens. It will not interpret anything
+ * (e.g. '$1' inside a macro) -- this is up to the parser.
+ * <p>
+ * In shell script mode, its primary purpose is to identify enough
+ * tokens to get a general picture of the structure of source for use by the autoconf
+ * parser. This isn't intended to be used for full shell script parsing. In fact,
+ * aside from the known tokens and identifiers, only individual characters will be returned.
+ * <p>
+ * Both modes know about "words" or identifiers and use the same syntax to detect these.
+ * It's expected that the parser will detect a word as a macro or possible macro and
+ * switch the mode of the tokenizer to fit. The parser should invoke "setM4Context(...)"
+ * (and "unreadToken" if necessary) to switch modes.
+ * @author eswartz
+ *
+ */
+public class AutoconfTokenizer {
+
+ private static final String UNTERMINATED_STRING = "UnterminatedString"; //$NON-NLS-1$
+ public static final String UNMATCHED_RIGHT_QUOTE = "UnmatchedRightQuote"; //$NON-NLS-1$
+ public static final String UNMATCHED_LEFT_QUOTE = "UnmatchedLeftQuote"; //$NON-NLS-1$
+ public static final String UNMATCHED_CLOSE_COMMENT = "UnmatchedCloseComment"; //$NON-NLS-1$
+
+ private IDocument document;
+ private int offset;
+ private String m4OpenQuote;
+ private String m4CloseQuote;
+ private String m4OpenComment;
+ private String m4CloseComment;
+ private char[] chars;
+ private int startOffset;
+ private boolean isM4Context;
+ private Token eofToken;
+ private IAutoconfErrorHandler errorHandler;
+
+ /** Create a tokenizer for a document. */
+ public AutoconfTokenizer(IDocument document, IAutoconfErrorHandler errorHandler) {
+ if (document == null /* || macroDetector == null*/)
+ throw new IllegalArgumentException();
+ this.document = document;
+ this.errorHandler = errorHandler;
+
+ this.chars = document.get().toCharArray();
+ this.offset = 0;
+
+ this.eofToken = new Token(ITokenConstants.EOF, "", document, chars.length, 0);
+
+ this.m4OpenQuote = "`";
+ this.m4CloseQuote = "'";
+ this.m4OpenComment = "#";
+ this.m4CloseComment = "\n";
+ }
+
+ /**
+ * Tell whether the tokenizer considers itself to be in an m4 context.
+ * This determines what kinds of tokens it returns.
+ * @return
+ */
+ public boolean isM4Context() {
+ return isM4Context;
+ }
+
+ /**
+ * Switch the tokenizer into or out of m4 context.
+ * @return
+ */
+ public void setM4Context(boolean flag) {
+ isM4Context = flag;
+ }
+
+ /**
+ * Set the m4 quote delimiters
+ */
+ public void setM4Quote(String open, String close) {
+ this.m4OpenQuote = open;
+ this.m4CloseQuote = close;
+ }
+
+ /**
+ * Set the m4 comment delimiters
+ */
+ public void setM4Comment(String open, String close) {
+ this.m4OpenComment = open;
+ this.m4CloseComment = close;
+ }
+
+ /** Push back the given token. This allows the tokenizer to restart from its start position,
+ * potentially in a different context. */
+ public void unreadToken(Token token) {
+ if (token.getLength() > 0 && offset == token.getOffset())
+ throw new IllegalStateException();
+ offset = token.getOffset();
+ }
+
+ /** Read the next token. Returns an EOF token at EOF. */
+ public Token readToken() {
+ if (offset >= chars.length)
+ return eofToken;
+
+ char ch = chars[offset];
+
+ // skip whitespace (but not EOL)
+ while (isWhitespace(ch)) {
+ offset++;
+ if (offset >= chars.length)
+ return eofToken;
+ ch = chars[offset];
+ }
+
+ // in shell mode, strip comments up to eol
+ if (!isM4Context && ch == '#') {
+ while (offset < chars.length) {
+ ch = chars[offset];
+ if (ch == '\n')
+ break;
+ offset++;
+ }
+
+ // keep inside doc if we didn't find that EOL
+ if (offset >= chars.length)
+ offset--;
+ }
+
+ startOffset = offset;
+ StringBuffer buffer = new StringBuffer();
+
+ // check EOL
+ if (ch == '\r' || ch == '\n') {
+ buffer.append(ch);
+ offset++;
+ if (ch == '\r' && offset < chars.length && chars[offset] == '\n') {
+ buffer.append(chars[offset++]);
+ }
+ return makeToken(ITokenConstants.EOL, buffer.toString());
+ }
+
+ // TODO: this parser always uses fixed logic for identifier reading, ignoring m4's "changeword"
+ if (isLeadIdentifierChar(ch)) {
+ return parseWord(ch);
+ }
+
+ // check comments and quotes
+ if (isM4Context) {
+ if (lookAhead(m4OpenComment)) {
+ boolean found = false;
+ // keep reading until the close comment (these are NOT nested)
+ while (offset < chars.length) {
+ if (lookAhead(m4CloseComment)) {
+ found = true;
+ break;
+ }
+ offset++;
+ }
+ if (!found) {
+ handleError(startOffset, offset, AutoconfEditorMessages.getFormattedString(UNMATCHED_CLOSE_COMMENT,
+ m4CloseComment.equals("\n") ? "newline" : m4CloseComment)); //$NON-NLS-1$
+ }
+ return makeToken(ITokenConstants.M4_COMMENT);
+ }
+
+ if (lookAhead(m4OpenQuote)) {
+ return parseQuote();
+ }
+ }
+
+ // check shell punctuation
+ if (!isM4Context) {
+ if (ch == ';' && offset + 1 < chars.length && chars[offset + 1] == ';') {
+ offset += 2;
+ return makeToken(ITokenConstants.SH_CASE_CONDITION_END);
+ }
+ if (ch == '<' && offset + 1 < chars.length && chars[offset + 1] == '<') {
+ offset += 2;
+ if (offset < chars.length && chars[offset] == '-') {
+ offset++;
+ return makeToken(ITokenConstants.SH_HERE_DASH);
+ } else {
+ return makeToken(ITokenConstants.SH_HERE);
+ }
+ }
+ switch (ch) {
+ case '$':
+ offset++;
+ return makeToken(ITokenConstants.SH_DOLLAR);
+ case '[':
+ offset++;
+ return makeToken(ITokenConstants.SH_LBRACKET);
+ case ']':
+ offset++;
+ return makeToken(ITokenConstants.SH_RBRACKET);
+ case '{':
+ offset++;
+ return makeToken(ITokenConstants.SH_LBRACE);
+ case '}':
+ offset++;
+ return makeToken(ITokenConstants.SH_RBRACE);
+ case '\'':
+ return parseString(ITokenConstants.SH_STRING_SINGLE, ch);
+ case '\"':
+ return parseString(ITokenConstants.SH_STRING_DOUBLE, ch);
+ case '`':
+ return parseString(ITokenConstants.SH_STRING_BACKTICK, ch);
+ }
+ }
+
+ // check common punctuation
+ if (ch == ';') {
+ offset++;
+ return makeToken(ITokenConstants.SEMI);
+ }
+ if (ch == ',') {
+ offset++;
+ return makeToken(ITokenConstants.COMMA);
+ }
+ if (ch == '(') {
+ offset++;
+ return makeToken(ITokenConstants.LPAREN);
+ }
+ if (ch == ')') {
+ offset++;
+ return makeToken(ITokenConstants.RPAREN);
+ }
+
+ // unknown text
+ offset++;
+ return makeToken(ITokenConstants.TEXT);
+ }
+
+ private Token parseWord(char ch) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(ch);
+ offset++;
+ do {
+ if (offset >= chars.length)
+ break;
+ ch = chars[offset];
+ if (!isIdentifierChar(ch))
+ break;
+ buffer.append(ch);
+ offset++;
+ } while (true);
+
+ String text = buffer.toString();
+
+ if (!isM4Context) {
+ // detect sh tokens
+ if ("case".equals(text))
+ return makeToken(ITokenConstants.SH_CASE, text);
+ if ("in".equals(text))
+ return makeToken(ITokenConstants.SH_IN, text);
+ if ("esac".equals(text))
+ return makeToken(ITokenConstants.SH_ESAC, text);
+ if ("while".equals(text))
+ return makeToken(ITokenConstants.SH_WHILE, text);
+ if ("select".equals(text))
+ return makeToken(ITokenConstants.SH_SELECT, text);
+ if ("until".equals(text))
+ return makeToken(ITokenConstants.SH_UNTIL, text);
+ if ("for".equals(text))
+ return makeToken(ITokenConstants.SH_FOR, text);
+ if ("do".equals(text))
+ return makeToken(ITokenConstants.SH_DO, text);
+ if ("done".equals(text))
+ return makeToken(ITokenConstants.SH_DONE, text);
+ if ("if".equals(text))
+ return makeToken(ITokenConstants.SH_IF, text);
+ if ("then".equals(text))
+ return makeToken(ITokenConstants.SH_THEN, text);
+ if ("else".equals(text))
+ return makeToken(ITokenConstants.SH_ELSE, text);
+ if ("elif".equals(text))
+ return makeToken(ITokenConstants.SH_ELIF, text);
+ if ("fi".equals(text))
+ return makeToken(ITokenConstants.SH_FI, text);
+ }
+
+ // other identifier-looking word
+ return makeToken(ITokenConstants.WORD, text);
+ }
+
+ private Token parseQuote() {
+ // read text, honoring nested quotes, but don't put the outermost quotes in the token
+
+ StringBuffer buffer = new StringBuffer();
+
+ int quoteLevel = 1;
+ // keep reading until the close quote
+ while (offset < chars.length) {
+ if (lookAhead(m4CloseQuote)) {
+ quoteLevel--;
+ if (quoteLevel == 0)
+ break;
+ buffer.append(m4CloseQuote);
+ } else if (lookAhead(m4OpenQuote)) {
+ buffer.append(m4OpenQuote);
+ quoteLevel++;
+ } else {
+ buffer.append(chars[offset]);
+ offset++;
+ }
+ }
+
+ if (quoteLevel > 0) {
+ handleError(startOffset, offset, AutoconfEditorMessages.getFormattedString(UNMATCHED_LEFT_QUOTE, m4CloseQuote));
+ } else if (quoteLevel < 0) {
+ handleError(startOffset, offset, AutoconfEditorMessages.getFormattedString(UNMATCHED_RIGHT_QUOTE, m4OpenQuote));
+ }
+
+ return makeToken(ITokenConstants.M4_STRING, buffer.toString());
+ }
+
+ private Token parseString(int type, char terminal) {
+ startOffset = offset;
+ offset++;
+
+ StringBuffer buffer = new StringBuffer();
+
+ char ch = 0;
+ while (offset < chars.length) {
+ ch = chars[offset++];
+ if (ch == '\\') {
+ if (offset < chars.length)
+ buffer.append(chars[offset++]);
+ else
+ buffer.append(ch);
+ } else if (ch == terminal) {
+ break;
+ } else {
+ buffer.append(ch);
+ }
+ }
+
+ if (ch != terminal) {
+ handleError(startOffset, offset, AutoconfEditorMessages.getFormattedString(UNTERMINATED_STRING, "" + ch));
+ }
+
+ return makeToken(type, buffer.toString());
+ }
+
+ private void handleError(int start, int end,
+ String message) {
+ if (errorHandler != null) {
+ int lineNumber = 0;
+ int startColumn = 0;
+ int endColumn = 0;
+ try {
+ lineNumber = document.getLineOfOffset(start);
+ int lineOffs = document.getLineOffset(lineNumber);
+ startColumn = start - lineOffs;
+ endColumn = end - lineOffs;
+ } catch (BadLocationException e) {
+ // Don't care if we blow up trying to issue marker
+ }
+ errorHandler.handleError(new ParseException(
+ message,
+ start, end,
+ lineNumber,
+ startColumn, endColumn,
+ IMarker.SEVERITY_ERROR));
+ }
+ }
+
+ /**
+ * Look ahead for the given string. If found, return true, and have
+ * offset updated. Otherwise, return false with offset unchanged.
+ * @param keyword
+ * @param text
+ * @return
+ */
+ private boolean lookAhead(String keyword) {
+ int length = keyword.length();
+ if (offset + length > chars.length) {
+ return false;
+ }
+ for (int idx = 0; idx < length; idx++) {
+ if (chars[offset + idx] != keyword.charAt(idx))
+ return false;
+ }
+ offset += length;
+ return true;
+ }
+
+ private boolean isWhitespace(char ch) {
+ return ch == ' ' || ch == '\t' || ch == '\f';
+ }
+
+ private Token makeToken(int type) {
+ return new Token(type,
+ new String(chars, startOffset, offset - startOffset),
+ document, startOffset, offset - startOffset);
+ }
+
+ private Token makeToken(int type, String text) {
+ return new Token(type, text, document, startOffset, offset - startOffset);
+ }
+
+ private boolean isIdentifierChar(char ch) {
+ return isLeadIdentifierChar(ch) || (ch >= '0' && ch <= '9');
+ }
+
+ private boolean isLeadIdentifierChar(char ch) {
+ return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_';
+ }
+
+ public Token peekToken() {
+ Token token = readToken();
+ unreadToken(token);
+ return token;
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java
new file mode 100644
index 0000000000..bf6eb597eb
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfUntilElement extends AutoconfElement {
+
+ public AutoconfUntilElement() {
+ super("until");
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java
new file mode 100644
index 0000000000..8d247f73d3
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class AutoconfWhileElement extends AutoconfElement {
+
+ public AutoconfWhileElement() {
+ super("while");
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfErrorHandler.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfErrorHandler.java
new file mode 100644
index 0000000000..1363240bbc
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfErrorHandler.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+
+/**
+ * Clients implement this interface to handle errors encountered while parsing.
+ * @author eswartz
+ *
+ */
+public interface IAutoconfErrorHandler {
+
+ /**
+ * Handle an exception associated with the given element
+ * @param exception the exception to handle; has a line number
+ * at the time of call
+ */
+ void handleError(ParseException exception);
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroDetector.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroDetector.java
new file mode 100644
index 0000000000..e4387316e5
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroDetector.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+
+/**
+ * Clients implement this interface to identify what identifiers represent
+ * macros for the autoconf tree.
+ * @author eswartz
+ *
+ */
+public interface IAutoconfMacroDetector {
+
+ /**
+ * Tell if this identifier should be treated as an m4 macro call.
+ * The identifier has already been judged to be a valid candidate
+ * (i.e. it's not quoted).
+ * @param name the string to check
+ */
+ boolean isMacroIdentifier(String name);
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroValidator.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroValidator.java
new file mode 100644
index 0000000000..2a54ee4773
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IAutoconfMacroValidator.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+
+/**
+ * Clients implement this interface to validate macro calls.
+ * @author eswartz
+ *
+ */
+public interface IAutoconfMacroValidator {
+
+ /**
+ * Validate the given macro call.
+ * @param element macro call, never <code>null</code>
+ * @throws ParseException if the call doesn't match the expected number of elements
+ */
+ void validateMacroCall(AutoconfMacroElement element) throws ParseException;
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IMacroDetector.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IMacroDetector.java
new file mode 100644
index 0000000000..b225942cfe
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/IMacroDetector.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+/**
+ * Clients implement this interface to detect whether a given identifier
+ * represents a known or potential macro in m4 or configure.ac text.
+ * @author eswartz
+ *
+ */
+public interface IMacroDetector {
+ boolean isMacro(String identifier);
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ITokenConstants.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ITokenConstants.java
new file mode 100644
index 0000000000..b665115f8d
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ITokenConstants.java
@@ -0,0 +1,87 @@
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public interface ITokenConstants {
+
+ /** end of file */
+ public static final int EOF = 0;
+ /** end of line */
+ public static final int EOL = 1;
+
+ /** an open parenthesis */
+ public static final int LPAREN = 2;
+ /** a close parenthesis */
+ public static final int RPAREN = 3;
+ /** a comma */
+ public static final int COMMA = 4;
+ /** a semicolon */
+ public static final int SEMI = 5;
+
+ /** a word (either m4 word or shell identifier-looking word) */
+ public static final int WORD = 6;
+
+ /** other text (usually punctuation or number, one char at a time) */
+ public static final int TEXT = 7;
+
+ /** an m4 string (the text does not contain the outermost quotes) */
+ public static final int M4_STRING = 21;
+ /** an m4 comment (as determined by changecomment, NOT dnl) */
+ public static final int M4_COMMENT = 22;
+
+ /** the sh 'if' token */
+ public static final int SH_IF = 40;
+ /** the sh 'then' token */
+ public static final int SH_THEN = 41;
+ /** the sh 'else' token */
+ public static final int SH_ELSE = 42;
+ /** the sh 'elif' token */
+ public static final int SH_ELIF = 43;
+ /** the sh 'fi' token */
+ public static final int SH_FI = 44;
+
+ /** the sh 'while' token */
+ public static final int SH_WHILE = 45;
+ /** the sh 'for' token */
+ public static final int SH_FOR = 46;
+ /** the sh 'select' token */
+ public static final int SH_SELECT = 47;
+ /** the sh 'until' token */
+ public static final int SH_UNTIL = 48;
+ /** the sh 'do' token */
+ public static final int SH_DO = 49;
+ /** the sh 'done' token */
+ public static final int SH_DONE = 50;
+ /** the sh 'case' token */
+
+ public static final int SH_CASE = 51;
+ /** the sh 'in' token */
+ public static final int SH_IN = 52;
+ /** the sh ';;' token */
+ public static final int SH_CASE_CONDITION_END = 53;
+ /** the sh 'esac' token */
+ public static final int SH_ESAC = 54;
+
+ /** the sh '$' token */
+ public static final int SH_DOLLAR = 60;
+
+ /** the sh '{' token */
+ public static final int SH_LBRACE = 61;
+ /** the sh '}' token */
+ public static final int SH_RBRACE = 62;
+ /** the sh '[' token */
+ public static final int SH_LBRACKET = 63;
+ /** the sh ']' token */
+ public static final int SH_RBRACKET = 64;
+
+ /** the sh '<<' token */
+ public static final int SH_HERE = 65;
+ /** the sh '<<-' token */
+ public static final int SH_HERE_DASH = 66;
+ /** an sh double-quoted string */
+ public static final int SH_STRING_DOUBLE = 67;
+ /** an sh single-quoted string */
+ public static final int SH_STRING_SINGLE = 68;
+ /** an sh backtick-quoted string */
+ public static final int SH_STRING_BACKTICK = 69;
+
+
+} \ No newline at end of file
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ParseException.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ParseException.java
new file mode 100644
index 0000000000..f0bc442469
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/ParseException.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * 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:
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+public class ParseException extends Exception {
+
+ static final long serialVersionUID = 1;
+ String message;
+ int severity;
+ int lineNumber;
+ int startColumn;
+ int endColumn;
+ private int startOffset;
+ private int endOffset;
+ public int getEndColumn() {
+ return endColumn;
+ }
+ public void setEndColumn(int endColumn) {
+ this.endColumn = endColumn;
+ }
+ public int getLineNumber() {
+ return lineNumber;
+ }
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+ public String getMessage() {
+ return message;
+ }
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ public int getStartColumn() {
+ return startColumn;
+ }
+ public void setStartColumn(int startColumn) {
+ this.startColumn = startColumn;
+ }
+ public ParseException(String message,
+ int startOffset, int endOffset,
+ int lineNumber, int startColumn, int endColumn, int severity) {
+ super();
+ this.message = message;
+ this.startOffset = startOffset;
+ this.endOffset = endOffset;
+ this.lineNumber = lineNumber;
+ this.startColumn = startColumn;
+ this.endColumn = endColumn;
+ this.severity = severity;
+ }
+ public int getSeverity() {
+ return severity;
+ }
+ public void setSeverity(int severity) {
+ this.severity = severity;
+ }
+ public int getStartOffset() {
+ return startOffset;
+ }
+ public int getEndOffset() {
+ return endOffset;
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/Token.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/Token.java
new file mode 100644
index 0000000000..9690363b4b
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/editors/parser/Token.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * 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:
+ * Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.editors.parser;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * A single token parsed from an autotools-style file. This represents m4 and sh
+ * tokens. Punctuation characters shared by both are not in a namespace.
+ *
+ * @author eswartz
+ *
+ */
+public class Token implements ITokenConstants {
+ /** Type:
+ * @see ITokenConstants
+ */
+ final int type;
+ /**
+ * Text of token, possibly interpreted or reduced from original characters
+ */
+ final String text;
+ /**
+ * Offset of token before interpretation
+ */
+ final int offset;
+ /**
+ * Length of token before interpretation
+ */
+ final int length;
+ /**
+ * The document providing the text
+ */
+ final IDocument document;
+
+ public Token(int type, String text, IDocument document, int offset, int length) {
+ this.type = type;
+ this.text = text;
+ this.document = document;
+ this.offset = offset;
+ this.length = length;
+ }
+
+ public String toString() {
+ return text;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public IDocument getDocument() {
+ return document;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public boolean followsSpace() {
+ char[] text = document.get().toCharArray();
+ if (offset == 0)
+ return false;
+ return (" \t\r\n\f".indexOf(text[offset - 1]) >= 0);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsBuildPropertyPage.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsBuildPropertyPage.java
new file mode 100644
index 0000000000..8bc173fe35
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsBuildPropertyPage.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.managedbuilder.ui.properties.AbstractCBuildPropertyTab;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsMakefileBuilder;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+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.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+
+public class AutotoolsBuildPropertyPage extends AbstractCBuildPropertyTab {
+
+ private String TRUE = "true"; // $NON-NLS-1$
+ private String FALSE = "false"; // $NON-NLS-1$
+ private String SCANNERMAKEW_LABEL = "ScannerMakeW.label"; // $NON-NLS-1$
+ private String SCANNERMAKEW_TOOLTIP = "ScannerMakeW.tooltip"; // $NON-NLS-1$
+
+ protected Button fCleanDelete;
+ protected Button fCleanMake;
+ protected Text fCleanMakeTarget;
+ protected Button fScannerMakeW;
+
+ private IProject getProject() {
+ return (IProject)getCfg().getManagedProject().getOwner();
+ }
+
+ public boolean canBeVisible() {
+ return AutotoolsMakefileBuilder.hasTargetBuilder(getProject());
+ }
+
+ public void createControls(Composite parent) {
+ super.createControls(parent);
+ Composite composite= usercomp;
+ // assume parent page uses griddata
+ GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL | GridData.FILL_HORIZONTAL);
+ composite.setLayoutData(gd);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ //PixelConverter pc= new PixelConverter(composite);
+ //layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
+ composite.setLayout(layout);
+
+ Group g = new Group(composite, SWT.SHADOW_ETCHED_IN);
+ g.setText(AutotoolsPropertyMessages.getString("CleanBehavior.title"));
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ g.setLayoutData(gd);
+ layout= new GridLayout();
+ layout.numColumns= 2;
+ g.setLayout(layout);
+
+ fCleanDelete = new Button(g, SWT.RADIO);
+ fCleanDelete.setText(AutotoolsPropertyMessages.getString("CleanDelete.label"));
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ gd.horizontalSpan = 2;
+ fCleanDelete.setLayoutData(gd);
+ fCleanMake = new Button(g, SWT.RADIO);
+ fCleanMake.setText(AutotoolsPropertyMessages.getString("CleanMake.label"));
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ gd.horizontalSpan = 2;
+ fCleanMake.setLayoutData(gd);
+
+ Label label = new Label(g, SWT.LEFT);
+ label.setText(AutotoolsPropertyMessages.getString("CleanMakeTarget.label"));
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label.setLayoutData(gd);
+
+ fCleanMakeTarget = new Text(g, SWT.SINGLE | SWT.BORDER);
+ fCleanMakeTarget.setText(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET_DEFAULT);
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fCleanMakeTarget.setLayoutData(gd);
+
+ fCleanDelete.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ fCleanMake.setSelection(false);
+ fCleanDelete.setSelection(true);
+ fCleanMakeTarget.setEnabled(false);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // do nothing
+ }
+ });
+
+ fCleanMake.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ fCleanDelete.setSelection(false);
+ fCleanMake.setSelection(true);
+ fCleanMakeTarget.setEnabled(true);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // do nothing
+ }
+ });
+
+ fCleanMakeTarget.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ if (fCleanMakeTarget.getText().equals("")) { // $NON-NLS-1$
+ // FIXME: should probably issue warning here, but how?
+ }
+ }
+ });
+
+ fScannerMakeW = new Button(composite, SWT.LEFT | SWT.CHECK);
+ fScannerMakeW.setText(AutotoolsPropertyMessages.getString(SCANNERMAKEW_LABEL));
+ fScannerMakeW.setToolTipText(AutotoolsPropertyMessages.getString(SCANNERMAKEW_TOOLTIP));
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+ fScannerMakeW.setLayoutData(gd);
+
+ initialize();
+ }
+
+ protected void performOK() {
+ IProject project = getProject();
+ if (fCleanDelete.getSelection()) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE, TRUE);
+ } catch (CoreException ce) {
+ // FIXME: what can we do here?
+ }
+ } else {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE, FALSE);
+ } catch (CoreException ce) {
+ // FIXME: what can we do here?
+ }
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET, fCleanMakeTarget.getText());
+ } catch (CoreException ce) {
+ // FIXME: what can we do here?
+ }
+ }
+ boolean setScannerInfoDirty = false;
+ try {
+ // Get old scanner method setting to see if it has changed.
+ String oldScannerMakeW = project.getPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W);
+ if (fScannerMakeW.getSelection()) {
+ project.setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, TRUE);
+ if (oldScannerMakeW == null || !oldScannerMakeW.equals(TRUE))
+ setScannerInfoDirty = true;
+ } else {
+ project.setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, null);
+ if (oldScannerMakeW != null && oldScannerMakeW.equals(TRUE))
+ setScannerInfoDirty = true;
+ }
+ } catch (CoreException ce) {
+ ce.printStackTrace(); // FIXME: what can we do here?
+ }
+ // If the scanner info method changes, we must mark the current data as
+ // dirty so it will be recalculated.
+ if (setScannerInfoDirty) {
+ try {
+ project.setSessionProperty(AutotoolsPropertyConstants.SCANNER_INFO_DIRTY, Boolean.TRUE);
+ } catch (CoreException ce2) {
+ // FIXME: what can we do here?
+ }
+ }
+ }
+
+ protected void performApply(ICResourceDescription src, ICResourceDescription dst) {
+ performOK();
+ }
+
+ protected void performDefaults() {
+ fCleanDelete.setSelection(false);
+ fCleanMake.setSelection(true);
+ fCleanMakeTarget.setText(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET_DEFAULT);
+ fCleanMakeTarget.setEnabled(true);
+ fScannerMakeW.setSelection(true);
+ }
+
+ public void updateData(ICResourceDescription cfgd) {
+ // what to do here?
+ }
+
+ public void updateButtons() {
+ // what to do here?
+ }
+
+ public void setVisible (boolean b) {
+ super.setVisible(b);
+ }
+
+ private void initialize() {
+ IProject project = getProject();
+ String cleanDelete = null;
+ String cleanMakeTarget = null;
+ String scannerMakeW = null;
+ try {
+ cleanDelete = project.getPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE);
+ cleanMakeTarget = project.getPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET);
+ scannerMakeW = project.getPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ if (cleanMakeTarget == null) {
+ cleanMakeTarget = AutotoolsPropertyConstants.CLEAN_MAKE_TARGET_DEFAULT;
+ }
+ fCleanMakeTarget.setText(cleanMakeTarget);
+
+ if (cleanDelete == null || cleanDelete.equals(FALSE)) {
+ fCleanDelete.setSelection(false);
+ fCleanMake.setSelection(true);
+ fCleanMakeTarget.setEnabled(true);
+ } else {
+ fCleanDelete.setSelection(true);
+ fCleanMake.setSelection(false);
+ fCleanMakeTarget.setEnabled(false);
+ }
+
+ if (scannerMakeW == null || !scannerMakeW.equals(TRUE)) {
+ fScannerMakeW.setSelection(false);
+ } else
+ fScannerMakeW.setSelection(true);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsEditorPropertyPage.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsEditorPropertyPage.java
new file mode 100644
index 0000000000..9ee6a4bf7a
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsEditorPropertyPage.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsPlugin;
+import org.eclipse.linuxtools.internal.cdt.autotools.ui.preferences.AutotoolsEditorPreferenceConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+
+public class AutotoolsEditorPropertyPage extends AbstractCPropertyTab {
+
+ protected Combo fACVersionCombo;
+ protected Combo fAMVersionCombo;
+ IProject project;
+
+// private class ACVersionSelectionListener implements SelectionListener {
+// ICPropertyProvider p;
+// public ACVersionSelectionListener(ICPropertyProvider p) {
+// this.p = p;
+// }
+//
+// public void widgetSelected(SelectionEvent e) {
+// int index = fACVersionCombo.getSelectionIndex();
+// try {
+// AutotoolsEditorPropertyPage.getProject(p).setPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION, fACVersionCombo.getItem(index));
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+// // do nothing
+// }
+// }
+//
+// private class AMVersionSelectionListener implements SelectionListener {
+// ICPropertyProvider p;
+// public AMVersionSelectionListener(ICPropertyProvider p) {
+// this.p = p;
+// }
+//
+// public void widgetSelected(SelectionEvent e) {
+// int index = fAMVersionCombo.getSelectionIndex();
+// try {
+// AutotoolsEditorPropertyPage.getProject(p).setPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION, fAMVersionCombo.getItem(index));
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+// // do nothing
+// }
+// }
+
+ private IProject getProject() {
+ IConfiguration c = ManagedBuildManager.getConfigurationForDescription(getResDesc().getConfiguration());
+ return (IProject)c.getManagedProject().getOwner();
+ }
+
+ public boolean canBeVisible() {
+ return true;
+ }
+
+ public void createControls(Composite parent) {
+ // TODO Auto-generated method stub
+ super.createControls(parent);
+ Composite composite= usercomp;
+
+ // assume parent page uses griddata
+ GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
+ composite.setLayoutData(gd);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ //PixelConverter pc= new PixelConverter(composite);
+ //layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
+ composite.setLayout(layout);
+
+ project = getProject();
+
+ /* check box for new editors */
+ fACVersionCombo= new Combo(composite, SWT.CHECK | SWT.DROP_DOWN | SWT.READ_ONLY);
+ fACVersionCombo.setItems(AutotoolsPropertyConstants.fACVersions);
+ fACVersionCombo.select(AutotoolsPropertyConstants.fACVersions.length - 1);
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+ fACVersionCombo.setLayoutData(gd);
+
+ Label label= new Label(composite, SWT.LEFT);
+ label.setText(AutotoolsPropertyMessages.getString("ACEditor.autoconfVersion")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label.setLayoutData(gd);
+
+ /* check box for new editors */
+ fAMVersionCombo= new Combo(composite, SWT.CHECK | SWT.DROP_DOWN | SWT.READ_ONLY);
+ fAMVersionCombo.setItems(AutotoolsPropertyConstants.fAMVersions);
+ fAMVersionCombo.select(AutotoolsPropertyConstants.fAMVersions.length - 1);
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+ fAMVersionCombo.setLayoutData(gd);
+
+ Label label2= new Label(composite, SWT.LEFT);
+ label2.setText(AutotoolsPropertyMessages.getString("ACEditor.automakeVersion")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label2.setLayoutData(gd);
+
+ initialize();
+ }
+
+ public void performOK() {
+ String acVer = null;
+ String amVer = null;
+ boolean changed = false;
+ try {
+ acVer = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION);
+ amVer = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION);
+ } catch (CoreException e) {
+ acVer = "";
+ amVer = "";
+ }
+ int index = fACVersionCombo.getSelectionIndex();
+ String acVerSelected = fACVersionCombo.getItem(index);
+ if (!acVerSelected.equals(acVer)) {
+ changed = true;
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION, fACVersionCombo.getItem(index));
+ } catch (CoreException ce) {
+ // Not much we can do at this point
+ }
+ }
+
+ index = fAMVersionCombo.getSelectionIndex();
+ String amVerSelected = fAMVersionCombo.getItem(index);
+ if (!amVerSelected.equals(amVer)) {
+ changed = true;
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION, fAMVersionCombo.getItem(index));
+ } catch (CoreException ce) {
+ // Not much we can do here either
+ }
+ }
+
+ // Notify any Autoconf editors that are open for this project that macro versioning
+ // has changed.
+ if (changed)
+ AutotoolsPropertyManager.getDefault().notifyPropertyListeners(project, AutotoolsPropertyConstants.AUTOCONF_MACRO_VERSIONING);
+ }
+
+ protected void performApply(ICResourceDescription src, ICResourceDescription dst) {
+ performOK();
+ }
+
+ public void performDefaults() {
+ // For default Autoconf and Automake versions, use the setting from the
+ // Autotools preference dialog.
+ String version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION);
+ String[] items = fACVersionCombo.getItems();
+ // Try and find which list item matches the current preference stored and
+ // select it in the list.
+ int i;
+ for (i = 0; i < items.length; ++i) {
+ if (items[i].equals(version))
+ break;
+ }
+ if (i >= items.length)
+ i = items.length - 1;
+ fACVersionCombo.select(i);
+
+ version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION);
+ items = fAMVersionCombo.getItems();
+ // Try and find which list item matches the current preference stored and
+ // select it in the list
+ for (i = 0; i < items.length; ++i) {
+ if (items[i].equals(version))
+ break;
+ }
+ if (i >= items.length)
+ i = items.length - 1;
+ fAMVersionCombo.select(i);
+ }
+
+ public void updateData(ICResourceDescription cfgd) {
+ // what to do here?
+ }
+
+ public void updateButtons() {
+ // what to do here?
+ }
+
+ public void setVisible (boolean b) {
+ super.setVisible(b);
+ }
+
+// private IProject getProject(ICPropertyProvider provider) {
+// Object element = provider.getElement();
+// if (element != null) {
+// if (element instanceof IFile ||
+// element instanceof IProject ||
+// element instanceof IFolder)
+// {
+// IResource f = (IResource) element;
+// return f.getProject();
+// }
+// else if (element instanceof ICProject)
+// return ((ICProject)element).getProject();
+// }
+// return null;
+// }
+
+ private void initialize() {
+ initializeACVersion();
+ initializeAMVersion();
+ }
+
+ void initializeACVersion() {
+ String version = "";
+ try {
+ version = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION);
+ if (version == null)
+ version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION);
+ } catch (CoreException e) {
+ // do nothing
+ }
+ String[] items = fACVersionCombo.getItems();
+ // Try and find which list item matches the current preference stored and
+ // select it in the list.
+ int i;
+ for (i = 0; i < items.length; ++i) {
+ if (items[i].equals(version))
+ break;
+ }
+ if (i >= items.length)
+ i = items.length - 1;
+ fACVersionCombo.select(i);
+ }
+
+ void initializeAMVersion() {
+ String version = "";
+ try {
+ version = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION);
+ if (version == null)
+ version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION);
+ } catch (CoreException e) {
+ // do nothing
+ }
+ String[] items = fAMVersionCombo.getItems();
+ // Try and find which list item matches the current preference stored and
+ // select it in the list.
+ int i;
+ for (i = 0; i < items.length; ++i) {
+ if (items[i].equals(version))
+ break;
+ }
+ if (i >= items.length)
+ i = items.length - 1;
+ fAMVersionCombo.select(i);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyConstants.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyConstants.java
new file mode 100644
index 0000000000..f020ce0252
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyConstants.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsPlugin;
+
+
+public class AutotoolsPropertyConstants {
+
+ static final String PREFIX = AutotoolsPlugin.getUniqueIdentifier() + "."; // $NON-NLS-1$
+ public static final String AUTOMAKE_VERSION_STRING = "AutoconfEditorAutomakeVersion"; // $NON-NLS-1$
+ public static final QualifiedName AUTOMAKE_VERSION = new QualifiedName(PREFIX, AUTOMAKE_VERSION_STRING);
+ public static final String AUTOCONF_VERSION_STRING = "AutoconfEditorAutoconfVersion"; // $NON-NLS-1$
+ public static final QualifiedName AUTOCONF_VERSION = new QualifiedName(PREFIX, AUTOCONF_VERSION_STRING);
+ public static final String AUTOCONF_MACRO_VERSIONING = "AutoconfEditorMacroVersioning"; // $NON-NLS-1$
+ public static final QualifiedName AUTOCONF_TOOL = new QualifiedName(PREFIX, "AutoconfToolPath"); // $NON-NLS-1$
+ public static final QualifiedName AUTOMAKE_TOOL = new QualifiedName(PREFIX, "AutomakeToolPath"); // $NON-NLS-1$
+ public static final QualifiedName ACLOCAL_TOOL = new QualifiedName(PREFIX, "AclocalToolPath"); // $NON-NLS-1$
+ public static final QualifiedName AUTOHEADER_TOOL = new QualifiedName(PREFIX, "AutoheaderToolPath"); // $NON-NLS-1$
+ public static final QualifiedName AUTORECONF_TOOL = new QualifiedName(PREFIX, "AutoreconfToolPath"); // $NON-NLS-1$
+ public static final QualifiedName LIBTOOLIZE_TOOL = new QualifiedName(PREFIX, "LibtoolizePath"); // $NON-NLS-1$
+ public static final QualifiedName CLEAN_DELETE = new QualifiedName(PREFIX, "CleanDelete"); // $NON-NLS-1$
+ public static final QualifiedName CLEAN_MAKE_TARGET = new QualifiedName(PREFIX, "CleanMakeTarget"); // $NON-NLS-1$
+ public static final QualifiedName SCANNER_USE_MAKE_W = new QualifiedName(PREFIX, "ScannerUseMakeW");
+ public static final QualifiedName OPEN_INCLUDE = new QualifiedName(PREFIX, "IncludeResourceMapping"); // $NON-NLS-1$
+ public static final QualifiedName OPEN_INCLUDE_P = new QualifiedName(PREFIX, "PersistentIncludeResourceMapping"); //$NON-NLS-1$
+ public static final QualifiedName SCANNER_INFO_DIRTY = new QualifiedName(PREFIX, "ScannerInfoDirty"); // $NON-NLSp-1$
+
+ static String[] fACVersions = {"2.13", "2.59", "2.61"}; // $NON-NLS-1$
+ static final String LATEST_AC_VERSION = fACVersions[fACVersions.length - 1];
+
+ static String[] fAMVersions = {"1.4-p6", "1.9.5", "1.9.6"}; // $NON-NLS-1$
+ static final String LATEST_AM_VERSION = fAMVersions[fAMVersions.length - 1];
+
+ public static final String CLEAN_MAKE_TARGET_DEFAULT = "distclean"; // $NON-NLS-1$
+ public static final String TRUE = "true"; // $NON-NLS-1$
+ public static final String FALSE = "false"; // $NON-NLS-1$
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyManager.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyManager.java
new file mode 100644
index 0000000000..1bdcca5ac1
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyManager.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.ListenerList;
+
+public class AutotoolsPropertyManager implements IPropertyChangeManager {
+
+ private static AutotoolsPropertyManager fInstance;
+ private Map<IProject, ListenerList> projectList;
+
+ private AutotoolsPropertyManager() {
+ projectList = new HashMap<IProject, ListenerList>();
+ }
+
+ public static AutotoolsPropertyManager getDefault() {
+ if (fInstance == null)
+ fInstance = new AutotoolsPropertyManager();
+ return fInstance;
+ }
+
+ public synchronized void addProjectPropertyListener(IProject project,
+ IProjectPropertyListener listener) {
+ ListenerList list = (ListenerList)projectList.get(project);
+ if (list == null) {
+ list = new ListenerList();
+ projectList.put(project, list);
+ }
+ list.add(listener);
+ }
+
+ public synchronized void notifyPropertyListeners(IProject project, String property) {
+ ListenerList list = (ListenerList)projectList.get(project);
+ if (list != null) {
+ Object[] listeners = list.getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ ((IProjectPropertyListener)listeners[i]).handleProjectPropertyChanged(project, property);
+ }
+ }
+ }
+
+ public synchronized void removeProjectPropertyListener(IProject project,
+ IProjectPropertyListener listener) {
+ ListenerList list = (ListenerList)projectList.get(project);
+ if (list != null)
+ list.remove(listener);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.java
new file mode 100644
index 0000000000..8fb1becc62
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * MakefilePreferencesMessages
+ */
+public class AutotoolsPropertyMessages {
+
+ /**
+ *
+ */
+ private AutotoolsPropertyMessages() {
+ }
+
+ private static final String BUNDLE_NAME = AutotoolsPropertyMessages.class.getName();
+
+ public static String getString(String key) {
+ try {
+ return ResourceBundle.getBundle(BUNDLE_NAME).getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ } catch (NullPointerException e) {
+ return '#' + key + '#';
+ }
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.properties b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.properties
new file mode 100644
index 0000000000..d729559cc6
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyMessages.properties
@@ -0,0 +1,41 @@
+###############################################################################
+# Copyright (c) 2007 Red Hat Inc. 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:
+# Red Hat Inc. - initial API and implementation
+###############################################################################
+
+Edit.name=Editors
+Build.name=Build
+
+Autotools.aclocalPath=aclocal
+Autotools.aclocalPath.tooltip=Specify desired aclocal to use for project
+Autotools.automakePath=automake
+Autotools.automakePath.tooltip=Specify desired automake to use for project
+Autotools.autoconfPath=autoconf
+Autotools.autoconfPath.tooltip=Specify desired autoconf to use for project
+Autotools.autoheaderPath=autoheader
+Autotools.autoheaderPath.tooltip=Specify desired autoheader to use for project
+Autotools.autoreconfPath=autoreconf
+Autotools.autoreconfPath.tooltip=Specify desired autoreconf to use for project
+Autotools.libtoolizePath=libtoolize
+Autotools.libtoolizePath.tooltip=Specify desired libtoolize to use for project
+
+ACEditor.version=&Version
+ACEditor.autoconfVersion=Version of Autoconf to use for syntax checking
+ACEditor.automakeVersion=Version of Automake to use for syntax checking
+
+ScannerMakeW.label=Use make -n -w per file to generate scanner info
+ScannerMakeW.tooltip=Use this option only if necessary to get correct include path
+
+CleanBehavior.title=Clean Build Behavior
+
+CleanDelete.label=Delete build directory on "clean" operation
+CleanMake.label=Use make target to clean
+CleanMakeTarget.label=Make target:
+CleanMakeTarget.default=distclean
+CleanMakeTarget.tooltip=Specify a top-level make target to clean build directory
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyPage.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyPage.java
new file mode 100644
index 0000000000..95fb589c95
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsPropertyPage.java
@@ -0,0 +1,376 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc. 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.cdt.ui.newui.AbstractPage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public class AutotoolsPropertyPage extends AbstractPage {
+
+ public AutotoolsPropertyPage() {
+ super();
+ }
+
+ protected boolean isSingle() {
+ return false;
+ }
+
+ protected Control createContents(Composite parent) {
+ return super.createContents(parent);
+ }
+
+ protected boolean showsConfig() {
+ return false;
+ }
+
+// protected Combo fACVersionCombo;
+// protected Combo fAMVersionCombo;
+//
+// protected Button fCleanDelete;
+// protected Button fCleanMake;
+// protected Combo fCleanMakeTarget;
+// protected Button fScannerMakeW;
+//
+//
+// public boolean isApplicable() {
+// IProject project = getProject();
+// if (project != null && !AutotoolsMakefileBuilder.hasTargetBuilder(project))
+// return false;
+// else
+// return super.isApplicable();
+// }
+//
+// protected Control createContents(Composite parent) {
+//
+// TabFolder folder= new TabFolder(parent, SWT.NONE);
+// folder.setLayout(new TabFolderLayout());
+// folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+//
+// // Allow end-user to select which version of autoconf to use for hover help
+// // and syntax checking of macros.
+// TabItem item= new TabItem(folder, SWT.NONE);
+// item.setText(AutotoolsPropertyMessages.getString("Edit.name")); //$NON-NLS-1$
+// item.setControl(createEditTabContent(folder));
+//
+// // Build options.
+// item= new TabItem(folder, SWT.NONE);
+// item.setText(AutotoolsPropertyMessages.getString("Build.name")); //$NON-NLS-1$
+// item.setControl(createBuildTabContent(folder));
+//
+// initialize();
+//
+// applyDialogFont(folder);
+// return folder;
+// }
+//
+// private Composite createEditTabContent(TabFolder folder) {
+// Composite composite= new Composite(folder, SWT.NULL);
+// // assume parent page uses griddata
+// GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
+// composite.setLayoutData(gd);
+// GridLayout layout= new GridLayout();
+// layout.numColumns= 2;
+// //PixelConverter pc= new PixelConverter(composite);
+// //layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
+// composite.setLayout(layout);
+//
+//
+// /* check box for new editors */
+// fACVersionCombo= new Combo(composite, SWT.CHECK | SWT.DROP_DOWN | SWT.READ_ONLY);
+// fACVersionCombo.setItems(AutotoolsPropertyConstants.fACVersions);
+// fACVersionCombo.select(AutotoolsPropertyConstants.fACVersions.length - 1);
+// gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+// fACVersionCombo.setLayoutData(gd);
+// fACVersionCombo.addSelectionListener(new SelectionListener() {
+// public void widgetSelected(SelectionEvent e) {
+// int index = fACVersionCombo.getSelectionIndex();
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION, fACVersionCombo.getItem(index));
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+// String version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION);
+// String[] items = fACVersionCombo.getItems();
+// // Try and find which list item matches the current preference stored and
+// // select it in the list.
+// int i;
+// for (i = 0; i < items.length; ++i) {
+// if (items[i].equals(version))
+// break;
+// }
+// if (i >= items.length)
+// i = items.length - 1;
+// fACVersionCombo.select(i);
+// }
+// });
+//
+// Label label= new Label(composite, SWT.LEFT);
+// label.setText(AutotoolsPropertyMessages.getString("ACEditor.autoconfVersion")); //$NON-NLS-1$
+// gd= new GridData();
+// gd.horizontalAlignment= GridData.BEGINNING;
+// label.setLayoutData(gd);
+//
+// /* check box for new editors */
+// fAMVersionCombo= new Combo(composite, SWT.CHECK | SWT.DROP_DOWN | SWT.READ_ONLY);
+// fAMVersionCombo.setItems(AutotoolsPropertyConstants.fAMVersions);
+// fAMVersionCombo.select(AutotoolsPropertyConstants.fAMVersions.length - 1);
+// gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+// fAMVersionCombo.setLayoutData(gd);
+// fAMVersionCombo.addSelectionListener(new SelectionListener() {
+// public void widgetSelected(SelectionEvent e) {
+// int index = fAMVersionCombo.getSelectionIndex();
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION, fAMVersionCombo.getItem(index));
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+// String version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION);
+// String[] items = fAMVersionCombo.getItems();
+// // Try and find which list item matches the current preference stored and
+// // select it in the list.
+// int i;
+// for (i = 0; i < items.length; ++i) {
+// if (items[i].equals(version))
+// break;
+// }
+// if (i >= items.length)
+// i = items.length - 1;
+// fAMVersionCombo.select(i);
+// }
+// });
+//
+// Label label2= new Label(composite, SWT.LEFT);
+// label2.setText(AutotoolsPropertyMessages.getString("ACEditor.automakeVersion")); //$NON-NLS-1$
+// gd= new GridData();
+// gd.horizontalAlignment= GridData.BEGINNING;
+// label2.setLayoutData(gd);
+//
+// return composite;
+// }
+//
+// private Composite createBuildTabContent(TabFolder folder) {
+// Composite composite= new Composite(folder, SWT.NULL);
+// // assume parent page uses griddata
+// GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
+// composite.setLayoutData(gd);
+// GridLayout layout= new GridLayout();
+// layout.numColumns= 2;
+// //PixelConverter pc= new PixelConverter(composite);
+// //layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
+// composite.setLayout(layout);
+//
+//
+// Group g = new Group(composite, SWT.SHADOW_ETCHED_IN);
+// g.setText(AutotoolsPropertyMessages.getString("CleanBehavior.title"));
+// gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+// gd.horizontalSpan = 2;
+// g.setLayoutData(gd);
+// layout= new GridLayout();
+// layout.numColumns= 2;
+// g.setLayout(layout);
+//
+// fCleanDelete = new Button(g, SWT.RADIO);
+// fCleanDelete.setText(AutotoolsPropertyMessages.getString("CleanDelete.label"));
+// gd= new GridData();
+// gd.horizontalAlignment= GridData.BEGINNING;
+// gd.horizontalSpan = 2;
+// fCleanDelete.setLayoutData(gd);
+// fCleanMake = new Button(g, SWT.RADIO);
+// fCleanMake.setText(AutotoolsPropertyMessages.getString("CleanMake.label"));
+// gd= new GridData();
+// gd.horizontalAlignment= GridData.BEGINNING;
+// gd.horizontalSpan = 2;
+// fCleanMake.setLayoutData(gd);
+//
+// Label label = new Label(g, SWT.LEFT);
+// label.setText(AutotoolsPropertyMessages.getString("CleanMakeTarget.label"));
+// gd= new GridData();
+// gd.horizontalAlignment= GridData.BEGINNING;
+// label.setLayoutData(gd);
+//
+// fCleanMakeTarget = new Combo(g, SWT.SIMPLE);
+// fCleanMakeTarget.setText(AutotoolsPropertyMessages.getString("CleanMakeTarget.default"));
+// fCleanMakeTarget.setTextLimit(40);
+// fCleanMakeTarget.setVisibleItemCount(0);
+// gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+// fCleanMakeTarget.setLayoutData(gd);
+//
+// fCleanDelete.addSelectionListener(new SelectionListener() {
+// public void widgetSelected(SelectionEvent e) {
+// fCleanMake.setSelection(false);
+// fCleanDelete.setSelection(true);
+// fCleanMakeTarget.setEnabled(false);
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE, "true");
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+// fCleanDelete.setSelection(false);
+// fCleanMake.setSelection(true);
+// fCleanMakeTarget.setEnabled(true);
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE, "false");
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET, "distclean");
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+// });
+//
+// fCleanMake.addSelectionListener(new SelectionListener() {
+// public void widgetSelected(SelectionEvent e) {
+// fCleanDelete.setSelection(false);
+// fCleanMake.setSelection(true);
+// fCleanMakeTarget.setEnabled(true);
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE, "false");
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+//// fCleanDelete.setSelection(false);
+//// fCleanMake.setSelection(true);
+//// try {
+//// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE, "false");
+//// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET, "distclean");
+//// } catch (CoreException ce) {
+//// // FIXME: what can we do here?
+//// }
+// }
+// });
+//
+// fCleanMakeTarget.addModifyListener(new ModifyListener() {
+// public void modifyText(ModifyEvent e) {
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET, fCleanMakeTarget.getText());
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+// });
+//
+// fScannerMakeW = new Button(composite, SWT.LEFT | SWT.CHECK);
+// fScannerMakeW.setText(AutotoolsPropertyMessages.getString("ScannerMakeW.label"));
+// fScannerMakeW.setToolTipText(AutotoolsPropertyMessages.getString("ScannerMakeW.tooltip"));
+// gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+// fScannerMakeW.setLayoutData(gd);
+// fScannerMakeW.addSelectionListener(new SelectionListener() {
+// public void widgetSelected(SelectionEvent e) {
+// try {
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, "true");
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+//
+// public void widgetDefaultSelected(SelectionEvent e) {
+// fScannerMakeW.setSelection(false);
+// try {
+// // This is only a temporary work-around so we remove the property rather than set it false.
+// getProject().setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, null);
+// } catch (CoreException ce) {
+// // FIXME: what can we do here?
+// }
+// }
+// });
+//
+// return composite;
+// }
+//
+// void initializeACVersion() {
+// String version = "";
+// try {
+// version = getProject().getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION);
+// if (version == null)
+// version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION);
+// } catch (CoreException e) {
+// // do nothing
+// }
+// String[] items = fACVersionCombo.getItems();
+// // Try and find which list item matches the current preference stored and
+// // select it in the list.
+// int i;
+// for (i = 0; i < items.length; ++i) {
+// if (items[i].equals(version))
+// break;
+// }
+// if (i >= items.length)
+// i = items.length - 1;
+// fACVersionCombo.select(i);
+// }
+//
+// void initializeAMVersion() {
+// String version = "";
+// try {
+// version = getProject().getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION);
+// if (version == null)
+// version = AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION);
+// } catch (CoreException e) {
+// // do nothing
+// }
+// String[] items = fAMVersionCombo.getItems();
+// // Try and find which list item matches the current preference stored and
+// // select it in the list.
+// int i;
+// for (i = 0; i < items.length; ++i) {
+// if (items[i].equals(version))
+// break;
+// }
+// if (i >= items.length)
+// i = items.length - 1;
+// fAMVersionCombo.select(i);
+// }
+//
+// void initializeBuild() {
+// String cleanDelete = null;
+// String cleanMakeTarget = null;
+// try {
+// cleanDelete = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE);
+// cleanMakeTarget = getProject().getPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET);
+// } catch (CoreException e) {
+// // do nothing
+// }
+//
+// if (cleanMakeTarget == null) {
+// cleanMakeTarget = AutotoolsPropertyMessages.getString("CleanMakeTarget.default"); // $NON-NLS-1$
+// fCleanMakeTarget.setText(cleanMakeTarget);
+// }
+//
+// if (cleanDelete == null || cleanDelete.equals("false")) {
+// fCleanDelete.setSelection(false);
+// fCleanMake.setSelection(true);
+// fCleanMakeTarget.setEnabled(true);
+// } else {
+// fCleanDelete.setSelection(true);
+// fCleanMake.setSelection(false);
+// fCleanMakeTarget.setEnabled(false);
+// }
+// }
+//
+// private void initialize() {
+// initializeACVersion();
+// initializeAMVersion();
+// initializeBuild();
+// }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsToolsPropertyPage.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsToolsPropertyPage.java
new file mode 100644
index 0000000000..7b56c2b213
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/AutotoolsToolsPropertyPage.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class AutotoolsToolsPropertyPage extends AbstractCPropertyTab {
+
+ public static final String DEFAULT_ACLOCAL = "aclocal"; // $NON-NLS-1$
+ public static final String DEFAULT_AUTOMAKE = "automake"; // $NON-NLS-1$
+ public static final String DEFAULT_AUTOCONF = "autoconf"; // $NON-NLS-1$
+ public static final String DEFAULT_AUTOHEADER = "autoheader"; // $NON-NLS-1$
+ public static final String DEFAULT_AUTORECONF = "autoreconf"; // $NON-NLS-1$
+ public static final String DEFAULT_LIBTOOLIZE = "libtoolize"; // $NON-NLS-1$
+
+ protected Text fAclocalPath;
+ protected Text fAutoheaderPath;
+ protected Text fAutomakePath;
+ protected Text fAutoreconfPath;
+ protected Text fAutoconfPath;
+ protected Text fLibtoolizePath;
+ private IProject project;
+
+
+ private IProject getProject() {
+ IConfiguration c = ManagedBuildManager.getConfigurationForDescription(getResDesc().getConfiguration());
+ return (IProject)c.getManagedProject().getOwner();
+ }
+
+ public boolean canBeVisible() {
+ return true;
+ }
+
+ public void createControls(Composite parent) {
+ // TODO Auto-generated method stub
+ super.createControls(parent);
+ Composite composite= usercomp;
+
+ // assume parent page uses griddata
+ GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL | GridData.FILL_HORIZONTAL);
+ composite.setLayoutData(gd);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ //PixelConverter pc= new PixelConverter(composite);
+ //layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
+ composite.setLayout(layout);
+
+ project = getProject();
+
+ Label label= new Label(composite, SWT.LEFT);
+ label.setText(AutotoolsPropertyMessages.getString("Autotools.aclocalPath")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label.setLayoutData(gd);
+
+ /* text window for aclocal path */
+ fAclocalPath = new Text(composite, SWT.BORDER | SWT.SINGLE);
+ fAclocalPath.setToolTipText(AutotoolsPropertyMessages.getString("Autotools.aclocalPath.tooltip")); // $NON-NLS-1$
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fAclocalPath.setLayoutData(gd);
+
+ Label label2= new Label(composite, SWT.LEFT);
+ label2.setText(AutotoolsPropertyMessages.getString("Autotools.automakePath")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label2.setLayoutData(gd);
+
+ /* text window for automake path */
+ fAutomakePath = new Text(composite, SWT.BORDER | SWT.SINGLE);
+ fAutomakePath.setToolTipText(AutotoolsPropertyMessages.getString("Autotools.automakePath.tooltip")); // $NON-NLS-1#
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fAutomakePath.setLayoutData(gd);
+
+ Label label3 = new Label(composite, SWT.LEFT);
+ label3.setText(AutotoolsPropertyMessages.getString("Autotools.autoconfPath")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label3.setLayoutData(gd);
+
+ /* text window for autoconf path */
+ fAutoconfPath = new Text(composite, SWT.BORDER | SWT.SINGLE);
+ fAutoconfPath.setToolTipText(AutotoolsPropertyMessages.getString("Autotools.autoconfPath.tooltip")); // $NON-NLS-1$
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fAutoconfPath.setLayoutData(gd);
+
+ Label label4= new Label(composite, SWT.LEFT);
+ label4.setText(AutotoolsPropertyMessages.getString("Autotools.autoheaderPath")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label4.setLayoutData(gd);
+
+ /* text window for aclocal path */
+ fAutoheaderPath = new Text(composite, SWT.BORDER | SWT.SINGLE);
+ fAutoheaderPath.setToolTipText(AutotoolsPropertyMessages.getString("Autotools.autoheaderPath.tooltip")); // $NON-NLS-1$
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fAutoheaderPath.setLayoutData(gd);
+
+ Label label5= new Label(composite, SWT.LEFT);
+ label5.setText(AutotoolsPropertyMessages.getString("Autotools.autoreconfPath")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label5.setLayoutData(gd);
+
+ /* text window for aclocal path */
+ fAutoreconfPath = new Text(composite, SWT.BORDER | SWT.SINGLE);
+ fAutoreconfPath.setToolTipText(AutotoolsPropertyMessages.getString("Autotools.autoreconfPath.tooltip")); // $NON-NLS-1$
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fAutoreconfPath.setLayoutData(gd);
+
+ Label label6= new Label(composite, SWT.LEFT);
+ label6.setText(AutotoolsPropertyMessages.getString("Autotools.libtoolizePath")); //$NON-NLS-1$
+ gd= new GridData();
+ gd.horizontalAlignment= GridData.BEGINNING;
+ label6.setLayoutData(gd);
+
+ /* text window for aclocal path */
+ fLibtoolizePath = new Text(composite, SWT.BORDER | SWT.SINGLE);
+ fLibtoolizePath.setToolTipText(AutotoolsPropertyMessages.getString("Autotools.libtoolizePath.tooltip")); // $NON-NLS-1$
+ gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+ fLibtoolizePath.setLayoutData(gd);
+
+ initialize();
+ }
+
+ public void performOK() {
+ String aclocalPath = null;
+ String automakePath = null;
+ String autoconfPath = null;
+ String autoheaderPath = null;
+ String autoreconfPath = null;
+ String libtoolizePath = null;
+ try {
+ aclocalPath = project.getPersistentProperty(AutotoolsPropertyConstants.ACLOCAL_TOOL);
+ } catch (CoreException e1) {
+ aclocalPath = DEFAULT_ACLOCAL;
+ }
+
+ String newAclocalPath = fAclocalPath.getText().trim();
+ if (aclocalPath == null || !newAclocalPath.equals(aclocalPath)) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.ACLOCAL_TOOL, newAclocalPath);
+ } catch (CoreException e1) {
+ // Not much we can do at this point
+ }
+ }
+
+ try {
+ automakePath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_TOOL);
+ } catch (CoreException e1) {
+ automakePath = DEFAULT_AUTOMAKE;
+ }
+
+ String newAutomakePath = fAutomakePath.getText().trim();
+ if (automakePath == null || !newAutomakePath.equals(automakePath)) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_TOOL, newAutomakePath);
+ } catch (CoreException e2) {
+ // Not much we can do at this point
+ }
+ }
+
+ try {
+ autoconfPath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_TOOL);
+ } catch (CoreException e1) {
+ autoconfPath = DEFAULT_AUTOCONF;
+ }
+
+ String newAutoconfPath = fAutoconfPath.getText().trim();
+ if (autoconfPath == null || !newAutoconfPath.equals(autoconfPath)) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_TOOL, newAutoconfPath);
+ } catch (CoreException e2) {
+ // Not much we can do at this point
+ }
+ }
+
+ try {
+ autoheaderPath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOHEADER_TOOL);
+ } catch (CoreException e1) {
+ autoheaderPath = DEFAULT_AUTOHEADER;
+ }
+
+ String newAutoheaderPath = fAutoheaderPath.getText().trim();
+ if (autoheaderPath == null || !newAutoheaderPath.equals(autoheaderPath)) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.AUTOHEADER_TOOL, newAutoheaderPath);
+ } catch (CoreException e2) {
+ // Not much we can do at this point
+ }
+ }
+
+ try {
+ autoreconfPath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTORECONF_TOOL);
+ } catch (CoreException e1) {
+ autoreconfPath = DEFAULT_AUTORECONF;
+ }
+
+ String newAutoreconfPath = fAutoreconfPath.getText().trim();
+ if (autoreconfPath == null || !newAutoreconfPath.equals(autoreconfPath)) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.AUTORECONF_TOOL, newAutoreconfPath);
+ } catch (CoreException e2) {
+ // Not much we can do at this point
+ }
+ }
+
+ try {
+ libtoolizePath = project.getPersistentProperty(AutotoolsPropertyConstants.LIBTOOLIZE_TOOL);
+ } catch (CoreException e1) {
+ libtoolizePath = DEFAULT_LIBTOOLIZE;
+ }
+
+ String newLibtoolizePath = fLibtoolizePath.getText().trim();
+ if (libtoolizePath == null || !newLibtoolizePath.equals(libtoolizePath)) {
+ try {
+ project.setPersistentProperty(AutotoolsPropertyConstants.LIBTOOLIZE_TOOL, newLibtoolizePath);
+ } catch (CoreException e2) {
+ // Not much we can do at this point
+ }
+ }
+ }
+
+ protected void performApply(ICResourceDescription src, ICResourceDescription dst) {
+ performOK();
+ }
+
+ public void performDefaults() {
+ // For default tool settings, simply default the base tool names
+ fAclocalPath.setText(DEFAULT_ACLOCAL);
+ fAutomakePath.setText(DEFAULT_AUTOMAKE);
+ fAutoconfPath.setText(DEFAULT_AUTOCONF);
+ fAutoheaderPath.setText(DEFAULT_AUTOHEADER);
+ fAutoreconfPath.setText(DEFAULT_AUTORECONF);
+ fLibtoolizePath.setText(DEFAULT_LIBTOOLIZE);
+ }
+
+ public void updateData(ICResourceDescription cfgd) {
+ // what to do here?
+ }
+
+ public void updateButtons() {
+ // what to do here?
+ }
+
+ public void setVisible (boolean b) {
+ super.setVisible(b);
+ }
+
+ private void initialize() {
+ String aclocalPath = null;
+ String automakePath = null;
+ String autoconfPath = null;
+ String autoheaderPath = null;
+ String autoreconfPath = null;
+ String libtoolizePath = null;
+
+ try {
+ aclocalPath = project.getPersistentProperty(AutotoolsPropertyConstants.ACLOCAL_TOOL);
+ } catch (CoreException e1) {
+ // do nothing
+ }
+
+ if (aclocalPath == null)
+ aclocalPath = DEFAULT_ACLOCAL;
+
+ fAclocalPath.setText(aclocalPath);
+
+ try {
+ automakePath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_TOOL);
+ } catch (CoreException e1) {
+ // do nothing
+ }
+
+ if (automakePath == null)
+ automakePath = DEFAULT_AUTOMAKE;
+
+ fAutomakePath.setText(automakePath);
+
+ try {
+ autoconfPath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_TOOL);
+ } catch (CoreException e1) {
+ // do nothing
+ }
+
+ if (autoconfPath == null)
+ autoconfPath = DEFAULT_AUTOCONF;
+
+ fAutoconfPath.setText(autoconfPath);
+
+ try {
+ autoheaderPath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOHEADER_TOOL);
+ } catch (CoreException e1) {
+ // do nothing
+ }
+
+ if (autoheaderPath == null)
+ autoheaderPath = DEFAULT_AUTOHEADER;
+
+ fAutoheaderPath.setText(autoheaderPath);
+
+ try {
+ autoreconfPath = project.getPersistentProperty(AutotoolsPropertyConstants.AUTORECONF_TOOL);
+ } catch (CoreException e1) {
+ // do nothing
+ }
+
+ if (autoreconfPath == null)
+ autoreconfPath = DEFAULT_AUTORECONF;
+
+ fAutoreconfPath.setText(autoreconfPath);
+
+ try {
+ libtoolizePath = project.getPersistentProperty(AutotoolsPropertyConstants.LIBTOOLIZE_TOOL);
+ } catch (CoreException e1) {
+ // do nothing
+ }
+
+ if (libtoolizePath == null)
+ libtoolizePath = DEFAULT_LIBTOOLIZE;
+
+ fLibtoolizePath.setText(libtoolizePath);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IProjectPropertyListener.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IProjectPropertyListener.java
new file mode 100644
index 0000000000..f9752307fb
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IProjectPropertyListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.core.resources.IProject;
+
+public interface IProjectPropertyListener {
+
+ /**
+ * Handler for property changes
+ *
+ * @param project the project to which the property changed
+ * @param property the name of the property changed
+ */
+ void handleProjectPropertyChanged(IProject project, String property);
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IPropertyChangeManager.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IPropertyChangeManager.java
new file mode 100644
index 0000000000..65b4fada2d
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/cdt/autotools/ui/properties/IPropertyChangeManager.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.cdt.autotools.ui.properties;
+
+import org.eclipse.core.resources.IProject;
+
+public interface IPropertyChangeManager {
+
+ /**
+ * Add a project property listener for given project.
+ *
+ * @param project the project to which the listener is interested
+ * @param listener the listener to notify
+ */
+ void addProjectPropertyListener(IProject project, IProjectPropertyListener listener);
+
+ /**
+ * Remove a project property listener.
+ *
+ * @param listener the listener to remove
+ */
+ void removeProjectPropertyListener(IProject project, IProjectPropertyListener listener);
+
+ /**
+ * Notify all listeners of project that a property has changed.
+ *
+ * @param project the project for which the property has changed
+ * @param property the property that has changed
+ */
+ void notifyPropertyListeners(IProject project, String property);
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/MarkerGenerator.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/MarkerGenerator.java
new file mode 100644
index 0000000000..c43f040b21
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/MarkerGenerator.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+import org.eclipse.cdt.core.model.ICModelMarker;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+
+public abstract class MarkerGenerator implements IMarkerGenerator {
+
+ /**
+ * Constructor for MarkerGenerator
+ */
+ public MarkerGenerator() {
+ super();
+ }
+
+ /*
+ * callback from Output Parser
+ */
+ public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) {
+
+ try {
+ IMarker[] cur = file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE);
+ /*
+ * Try to find matching markers and don't put in duplicates
+ */
+ if ((cur != null) && (cur.length > 0)) {
+ for (int i = 0; i < cur.length; i++) {
+ int line = ((Integer) cur[i].getAttribute(IMarker.LOCATION)).intValue();
+ int sev = ((Integer) cur[i].getAttribute(IMarker.SEVERITY)).intValue();
+ String mesg = (String) cur[i].getAttribute(IMarker.MESSAGE);
+ if (line == lineNumber && sev == mapMarkerSeverity(severity) && mesg.equals(errorDesc)) {
+ return;
+ }
+ }
+ }
+
+ IMarker marker = file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.LOCATION, lineNumber);
+ marker.setAttribute(IMarker.MESSAGE, errorDesc);
+ marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(severity));
+ marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
+ marker.setAttribute(IMarker.CHAR_START, -1);
+ marker.setAttribute(IMarker.CHAR_END, -1);
+ if (errorVar != null) {
+ marker.setAttribute(ICModelMarker.C_MODEL_MARKER_VARIABLE, errorVar);
+ }
+ }
+ catch (CoreException e) {
+ CCorePlugin.log(e.getStatus());
+ }
+
+ }
+
+ public abstract IProject getProject();
+
+ /*
+ * callback from Output Parser
+ */
+ public void addMarker(ProblemMarkerInfo problemMarkerInfo) {
+ try {
+ IResource markerResource = problemMarkerInfo.file ;
+ if (markerResource==null) {
+ markerResource = getProject();
+ }
+ IMarker[] cur = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ONE);
+ /*
+ * Try to find matching markers and don't put in duplicates
+ */
+ if ((cur != null) && (cur.length > 0)) {
+ for (int i = 0; i < cur.length; i++) {
+ int line = ((Integer) cur[i].getAttribute(IMarker.LOCATION)).intValue();
+ int sev = ((Integer) cur[i].getAttribute(IMarker.SEVERITY)).intValue();
+ String mesg = (String) cur[i].getAttribute(IMarker.MESSAGE);
+ if (line == problemMarkerInfo.lineNumber && sev == mapMarkerSeverity(problemMarkerInfo.severity) && mesg.equals(problemMarkerInfo.description)) {
+ return;
+ }
+ }
+ }
+
+ IMarker marker = markerResource.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER);
+ marker.setAttribute(IMarker.LOCATION, problemMarkerInfo.lineNumber);
+ marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description);
+ marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity));
+ marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber);
+ marker.setAttribute(IMarker.CHAR_START, -1);
+ marker.setAttribute(IMarker.CHAR_END, -1);
+ if (problemMarkerInfo.variableName != null) {
+ marker.setAttribute(ICModelMarker.C_MODEL_MARKER_VARIABLE, problemMarkerInfo.variableName);
+ }
+ if (problemMarkerInfo.externalPath != null) {
+ marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, problemMarkerInfo.externalPath.toOSString());
+ }
+ }
+ catch (CoreException e) {
+ CCorePlugin.log(e.getStatus());
+ }
+ }
+
+ private int mapMarkerSeverity(int severity) {
+ switch (severity) {
+ case SEVERITY_ERROR_BUILD :
+ case SEVERITY_ERROR_RESOURCE :
+ return IMarker.SEVERITY_ERROR;
+ case SEVERITY_INFO :
+ return IMarker.SEVERITY_INFO;
+ case SEVERITY_WARNING :
+ return IMarker.SEVERITY_WARNING;
+ }
+ return IMarker.SEVERITY_ERROR;
+ }
+
+ /* (non-Javadoc)
+ * Removes the IMarkers for the project specified in the argument if the
+ * project exists, and is open.
+ *
+ * @param project
+ */
+ public 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/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/AutotoolsConsole.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/AutotoolsConsole.java
new file mode 100644
index 0000000000..982764a120
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/AutotoolsConsole.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2004, 2009 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ * Red Hat Inc - Adapted for Autotools usage
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import org.eclipse.cdt.ui.IBuildConsoleManager;
+import org.eclipse.core.resources.IProject;
+
+public class AutotoolsConsole extends Console {
+ IProject project;
+ IBuildConsoleManager fConsoleManager;
+
+ private static final String CONTEXT_MENU_ID = "CAutotoolsConsole"; //$NON-NLS-1$
+ private static final String CONSOLE_NAME = ConsoleMessages.getString("AutotoolsConsole.name"); //$NON-NLS-1$
+
+ public AutotoolsConsole() {
+ super(CONSOLE_NAME, CONTEXT_MENU_ID);
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CBuildStepsConsole.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CBuildStepsConsole.java
new file mode 100644
index 0000000000..5ba325974f
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CBuildStepsConsole.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2004, 2009 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ * Red Hat Inc - Adapted for Autotools usage
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import org.eclipse.cdt.ui.IBuildConsoleManager;
+import org.eclipse.core.resources.IProject;
+
+public class CBuildStepsConsole extends Console {
+ IProject project;
+ IBuildConsoleManager fConsoleManager;
+
+ private static final String CONTEXT_MENU_ID = "CAutotoolsBuildStepsConsole"; //$NON-NLS-1$
+ private static final String CONSOLE_NAME = ConsoleMessages.getString("BuildStepsConsole.name"); //$NON-NLS-1$
+
+ public CBuildStepsConsole() {
+ super(CONSOLE_NAME, CONTEXT_MENU_ID);
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CConfigureConsole.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CConfigureConsole.java
new file mode 100644
index 0000000000..1925fcd7c2
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CConfigureConsole.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2004, 2009 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import org.eclipse.cdt.ui.IBuildConsoleManager;
+import org.eclipse.core.resources.IProject;
+
+public class CConfigureConsole extends Console {
+ IProject project;
+ IBuildConsoleManager fConsoleManager;
+
+ private static final String CONTEXT_MENU_ID = "CAutotoolsConfigureConsole"; //$NON-NLS-1$
+ private static final String CONSOLE_NAME = ConsoleMessages.getString("ConfigureConsole.name"); //$NON-NLS-1$
+
+ public CConfigureConsole() {
+ super(CONSOLE_NAME, CONTEXT_MENU_ID);
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CWordFinder.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CWordFinder.java
new file mode 100644
index 0000000000..cc28694b10
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/CWordFinder.java
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+
+/**
+ * This is a helper class for the text editor to be able to determine, given a
+ * particular offset in a document, various candidates segments for things like
+ * context help, proposals and hovering.
+ */
+public class CWordFinder {
+
+ private static final char CBRACE_L = '{';
+ private static final char CBRACE_R = '}';
+ private static final char BRACE_R = ')';
+
+ /**
+ * This method determines for a given offset into a given document what the
+ * region is which defines the current word. A word is defined as the set of
+ * non "C" identifiers. So assuming that ! indicated the current cursor
+ * postion: !afunction(int a, int b) --> word = length 0 afunc!tion(int a,
+ * int b) --> word = afunction afunction!(int a, int b) --> word = afunction
+ * afunction(!int a, int b) --> word = length 0 afunction(int a,! int b) -->
+ * word = length 0 afunction(!) --> word = length 0
+ *
+ * @param document
+ * The document to be examined
+ * @param offset
+ * The offset into the document where a word should be
+ * idendified.
+ * @return The region defining the current word, which may be a region of
+ * length 0 if the offset is not in a word, or null if there is an
+ * error accessing the docment data.
+ */
+ public static IRegion findWord(IDocument document, int offset) {
+ int start = -1;
+ int end = -1;
+
+ try {
+ int pos = offset;
+ char c;
+
+ while (pos >= 0) {
+ c = document.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ --pos;
+ }
+
+ start = pos + 1;
+
+ pos = offset;
+ int length = document.getLength();
+
+ while (pos < length) {
+ c = document.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ ++pos;
+ }
+
+ end = pos;
+
+ } catch (BadLocationException x) {
+ }
+
+ if (start > -1 && end > -1) {
+ if (start >= offset && end == offset)
+ return new Region(offset, 0);
+ else
+ return new Region(start, end - start);
+ }
+
+ return null;
+ }
+
+ /**
+ * This method will determine the region for the name of the function within
+ * which the current offset is contained.
+ *
+ * @param document
+ * The document to be examined
+ * @param offset
+ * The offset into the document where a word should be
+ * idendified.
+ * @return The region defining the current word, which may be a region of
+ * length 0 if the offset is not in a function, or null if there is
+ * an error accessing the docment data.
+ */
+ public static IRegion findFunction(IDocument document, int offset) {
+ int leftbracket = -1;
+ int leftbracketcount = 0;
+ int rightbracket = -1;
+ int rightbracketcount = 0;
+ int functionstart = -1;
+ int functionend = -1;
+
+ try {
+ int length = document.getLength();
+ int pos;
+ char c;
+
+ //Find most relevant right bracket from our position
+ pos = offset;
+ rightbracketcount = leftbracketcount = 0;
+ while (pos < length) {
+ c = document.getChar(pos);
+
+ if (c == ')') {
+ rightbracketcount++;
+ if (rightbracketcount >= leftbracketcount) {
+ rightbracket = pos;
+ break;
+ }
+ }
+
+ if (c == '(') {
+ leftbracketcount++;
+ }
+
+ if (c == ';') {
+ break;
+ }
+
+ pos++;
+ }
+
+ if (rightbracket == -1) {
+ return new Region(offset, 0);
+ }
+
+ //Now backtrack our way from the rightbracket to the left
+ pos = rightbracket;
+ rightbracketcount = leftbracketcount = 0;
+ while (pos >= 0) {
+ c = document.getChar(pos);
+
+ if (c == ')') {
+ rightbracketcount++;
+ }
+
+ if (c == '(') {
+ leftbracketcount++;
+ if (leftbracketcount >= rightbracketcount) {
+ leftbracket = pos;
+ break;
+ }
+ }
+
+ if (c == ';') {
+ break;
+ }
+
+ pos--;
+ }
+
+ if (leftbracket == -1) {
+ return new Region(offset, 0);
+ }
+
+ //Now work our way to the function name
+ pos = leftbracket - 1;
+ while (pos >= 0) {
+ c = document.getChar(pos);
+ if (functionend == -1 && c == ' ') {
+ pos--;
+ continue;
+ }
+
+ if (!Character.isJavaIdentifierPart(c)) {
+ break;
+ }
+
+ functionstart = pos;
+ if (functionend == -1) {
+ functionend = pos;
+ }
+
+ pos--;
+ }
+ } catch (BadLocationException x) {
+ /* Ignore */
+ }
+
+ if (functionstart > -1 && functionend > -1) {
+ return new Region(functionstart, functionend - functionstart + 1);
+ }
+
+ return null;
+ }
+
+ /**
+ * This method will determine whether current offset is contained
+ * in any function's body or it's outside it.
+ *
+ * @param document
+ * The document to be examined
+ * @param offset
+ * The offset into the document
+ * @return
+ * <code>true</code> if there is no function body around offset
+ * <code>false</code> otherwise
+ */
+ public static boolean isGlobal(IDocument document, int offset) {
+ try {
+ int pos = offset;
+ int bracketcount = 0;
+ char c;
+
+ //Find left curled bracket from our position
+ while (pos > 0) {
+ c = document.getChar(pos--);
+
+ if (c == CBRACE_R) {
+ bracketcount++; // take into account nested blocks
+ } else if (c == CBRACE_L) {
+ if (bracketcount-- == 0) {
+ do {
+ c = document.getChar(pos--);
+ if (c == BRACE_R) return false;
+ } while (Character.isWhitespace(c));
+ // container block seems to be not a function or statement body
+ pos++; // step back one symbol
+ bracketcount = 0; // let's search for upper block
+ }
+ }
+ }
+
+ } catch (BadLocationException x) { /* Ignore */ }
+ // return true in case of unknown result or exception
+ return true;
+ }
+
+ /**
+ * Searches for line feed symbols in string.
+ * First met '\r' or '\n' is treated as LF symbol
+ *
+ * @param s
+ * string to search in.
+ * @return number of LFs met.
+ */
+ public static int countLFs (String s) {
+ int counter = 0;
+ char lf = 0;
+ char c;
+ for (int i=0; i<s.length(); i++) {
+ c = s.charAt(i);
+ if (lf == 0) {
+ if (c == '\n' || c == '\r') {
+ lf = c;
+ counter++;
+ }
+ } else if (lf == c) counter++;
+ }
+ return counter;
+ }
+
+ /**
+ * Checks whether the string contains any C-block delimiters ( { } )
+ *
+ * @param s
+ * text to check
+ * @return true if curled brace found.
+ */
+ public static boolean hasCBraces (String s) {
+ if (s.indexOf(CBRACE_L) > -1 || s.indexOf(CBRACE_R) > -1) return true;
+ else return false;
+ }
+}
+
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/Console.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/Console.java
new file mode 100644
index 0000000000..695e489a1b
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/Console.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.core.resources.IConsole;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.IBuildConsoleManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+
+public class Console implements IConsole {
+ IProject project;
+ IBuildConsoleManager fConsoleManager;
+
+ public Console(String consoleName, String contextId) {
+ fConsoleManager = CUIPlugin.getDefault().getConsoleManager(consoleName,
+ contextId);
+ }
+
+// /**
+// * Constructor for ConfigureConsole.
+// */
+// public CConfigureConsole() {
+// fConsoleManager = AutotoolsPlugin.getDefault().getConsoleManager();
+// }
+//
+
+ public void start(IProject project ) {
+ this.project = project;
+ fConsoleManager.getConsole(project).start(project);
+ }
+
+ /**
+ * @throws CoreException
+ * @see org.eclipse.cdt.core.resources.IConsole#getOutputStream()
+ */
+ public ConsoleOutputStream getOutputStream() throws CoreException {
+ return fConsoleManager.getConsole(project).getOutputStream();
+ }
+
+ public ConsoleOutputStream getInfoStream() throws CoreException {
+ return fConsoleManager.getConsole(project).getInfoStream();
+ }
+
+ public ConsoleOutputStream getErrorStream() throws CoreException {
+ return fConsoleManager.getConsole(project).getErrorStream();
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.java
new file mode 100644
index 0000000000..a9b3d21ef0
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class ConsoleMessages {
+
+ public static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.cdt.autotools.ui.ConsoleMessages";//$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private ConsoleMessages() {
+
+ }
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.properties b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.properties
new file mode 100644
index 0000000000..7c4510df87
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/ConsoleMessages.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2003, 2004 QNX Software Systems and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# QNX Software Systems - Initial API and implementation
+###############################################################################
+ConfigureConsole.name=Configure
+BuildStepsConsole.name=Build Steps
+AutotoolsConsole.name=Autotools
+
+find_replace_action.label=&Find/Replace...@Ctrl+F
+find_replace_action.tooltip=Find/Replace
+find_replace_action.image=
+find_replace_action.description=Find/Replace
+
+ConfigureConsolePage.&Copy@Ctrl+C_6=&Copy@Ctrl+C
+ConfigureConsolePage.Copy_7=Copy
+ConfigureConsolePage.Select_&All@Ctrl+A_12=Select &All@Ctrl+A
+ConfigureConsolePage.Select_All=Select All
+
+ScrollLockAction.Scroll_Lock_1=Scroll Lock
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/HTMLPrinter.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/HTMLPrinter.java
new file mode 100644
index 0000000000..a9de7d1159
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/HTMLPrinter.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000 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 Corporation - initial API and implementation
+ * QNX Software System
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import java.io.IOException;
+import java.io.Reader;
+
+
+/**
+ * Provides a set of convenience methods for creating HTML pages.
+ */
+public class HTMLPrinter {
+
+ private HTMLPrinter() {
+ }
+
+ private static String replace(String text, char c, String s) {
+
+ int previous= 0;
+ int current= text.indexOf(c, previous);
+
+ if (current == -1)
+ return text;
+
+ StringBuffer buffer= new StringBuffer();
+ while (current > -1) {
+ buffer.append(text.substring(previous, current));
+ buffer.append(s);
+ previous= current + 1;
+ current= text.indexOf(c, previous);
+ }
+ buffer.append(text.substring(previous));
+
+ return buffer.toString();
+ }
+
+ public static String convertToHTMLContent(String content) {
+ content= replace(content, '<', "&lt;"); //$NON-NLS-1$
+ return replace(content, '>', "&gt;"); //$NON-NLS-1$
+ }
+
+ public static String read(Reader rd) {
+
+ StringBuffer buffer= new StringBuffer();
+ char[] readBuffer= new char[2048];
+
+ try {
+ int n= rd.read(readBuffer);
+ while (n > 0) {
+ buffer.append(readBuffer, 0, n);
+ n= rd.read(readBuffer);
+ }
+ return buffer.toString();
+ } catch (IOException x) {
+ }
+
+ return null;
+ }
+
+ public static void insertPageProlog(StringBuffer buffer, int position) {
+ buffer.insert(position, "<html><body text=\"#000000\" bgcolor=\"#FFFF88\"><font size=-1>"); //$NON-NLS-1$
+ }
+
+ public static void addPageProlog(StringBuffer buffer) {
+ insertPageProlog(buffer, buffer.length());
+ }
+
+ public static void addPageEpilog(StringBuffer buffer) {
+ buffer.append("</font></body></html>"); //$NON-NLS-1$
+ }
+
+ public static void startBulletList(StringBuffer buffer) {
+ buffer.append("<ul>"); //$NON-NLS-1$
+ }
+
+ public static void endBulletList(StringBuffer buffer) {
+ buffer.append("</ul>"); //$NON-NLS-1$
+ }
+
+ public static void addBullet(StringBuffer buffer, String bullet) {
+ if (bullet != null) {
+ buffer.append("<li>"); //$NON-NLS-1$
+ buffer.append(bullet);
+ buffer.append("</li>"); //$NON-NLS-1$
+ }
+ }
+
+ public static void addSmallHeader(StringBuffer buffer, String header) {
+ if (header != null) {
+ buffer.append("<h5>"); //$NON-NLS-1$
+ buffer.append(header);
+ buffer.append("</h5>"); //$NON-NLS-1$
+ }
+ }
+
+ public static void addParagraph(StringBuffer buffer, String paragraph) {
+ if (paragraph != null) {
+ buffer.append("<p>"); //$NON-NLS-1$
+ buffer.append(paragraph);
+ }
+ }
+
+ public static void addParagraph(StringBuffer buffer, Reader paragraphReader) {
+ if (paragraphReader != null)
+ addParagraph(buffer, read(paragraphReader));
+ }
+} \ No newline at end of file
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/LineBreakingReader.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/LineBreakingReader.java
new file mode 100644
index 0000000000..52fb3e31e5
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/LineBreakingReader.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000 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 Corporation - initial API and implementation
+ * QNX Software System
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import java.text.BreakIterator;
+import org.eclipse.swt.graphics.GC;
+
+/*
+ * Not a real reader. Could change if requested
+ */
+public class LineBreakingReader {
+
+ private BufferedReader fReader;
+ private GC fGC;
+ private int fMaxWidth;
+
+ private String fLine;
+ private int fOffset;
+
+ private BreakIterator fLineBreakIterator;
+ private int findNextBreakOffset(int currOffset) {
+ int currWidth= 0;
+ int nextOffset= fLineBreakIterator.following(currOffset);
+ while (nextOffset != BreakIterator.DONE) {
+ String word= fLine.substring(currOffset, nextOffset);
+ int wordWidth= fGC.textExtent(word).x;
+ int nextWidth= wordWidth + currWidth;
+ if (nextWidth > fMaxWidth) {
+ if (currWidth > 0) {
+ return currOffset;
+ }
+ return nextOffset;
+ }
+ currWidth= nextWidth;
+ currOffset= nextOffset;
+ nextOffset= fLineBreakIterator.next();
+ }
+ return nextOffset;
+ }
+ private int findWordBegin(int idx) {
+ while (idx < fLine.length() && Character.isWhitespace(fLine.charAt(idx))) {
+ idx++;
+ }
+ return idx;
+ }
+ /**
+ * Creates a reader that breaks an input text to fit in a given width.
+ * @param reader Reader of the input text
+ * @param gc The graphic context that defines the currently used font sizes
+ * @param maxLineWidth The max width (pixes) where the text has to fit in
+ */
+ public LineBreakingReader(Reader reader, GC gc, int maxLineWidth) {
+ fReader= new BufferedReader(reader);
+ fGC= gc;
+ fMaxWidth= maxLineWidth;
+ fOffset= 0;
+ fLine= null;
+ fLineBreakIterator= BreakIterator.getLineInstance();
+ }
+
+ public boolean isFormattedLine() {
+ return fLine != null;
+ }
+
+ /**
+ * Reads the next line. The lengths of the line will not exceed the gived maximum
+ * width.
+ */
+ public String readLine() throws IOException {
+ if (fLine == null) {
+ String line= fReader.readLine();
+ if (line == null) {
+ return null;
+ }
+
+ int lineLen= fGC.textExtent(line).x;
+ if (lineLen < fMaxWidth) {
+ return line;
+ }
+ fLine= line;
+ fLineBreakIterator.setText(line);
+ fOffset= 0;
+ }
+ int breakOffset= findNextBreakOffset(fOffset);
+ String res;
+ if (breakOffset != BreakIterator.DONE) {
+ res= fLine.substring(fOffset, breakOffset);
+ fOffset= findWordBegin(breakOffset);
+ if (fOffset == fLine.length()) {
+ fLine= null;
+ }
+ } else {
+ res= fLine.substring(fOffset);
+ fLine= null;
+ }
+ return res;
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SingleCharReader.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SingleCharReader.java
new file mode 100644
index 0000000000..1d48fcc21b
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SingleCharReader.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000 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 Corporation - initial API and implementation
+ * QNX Software System
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+import java.io.IOException;
+import java.io.Reader;
+
+
+public abstract class SingleCharReader extends Reader {
+
+ /**
+ * @see Reader#read(char)
+ */
+ public abstract int read() throws IOException;
+
+
+ /**
+ * @see Reader#read(char[],int,int)
+ */
+ public int read(char cbuf[], int off, int len) throws IOException {
+ int end= off + len;
+ for (int i= off; i < end; i++) {
+ int ch= read();
+ if (ch == -1) {
+ if (i == off) {
+ return -1;
+ }
+ return i - off;
+ }
+ cbuf[i]= (char)ch;
+ }
+ return len;
+ }
+
+ /**
+ * @see Reader#ready()
+ */
+ public boolean ready() throws IOException {
+ return true;
+ }
+
+ /**
+ * Gets the content as a String
+ */
+ public String getString() throws IOException {
+ StringBuffer buf= new StringBuffer();
+ int ch;
+ while ((ch= read()) != -1) {
+ buf.append((char)ch);
+ }
+ return buf.toString();
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SubstitutionTextReader.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SubstitutionTextReader.java
new file mode 100644
index 0000000000..16d8400b98
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/SubstitutionTextReader.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000 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 Corporation - initial API and implementation
+ * QNX Software System
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.autotools.ui;
+
+
+import java.io.IOException;
+import java.io.Reader;
+
+
+/**
+ * Reads the text contents from a reader and computes for each character
+ * a potential substitution. The substitution may eat more characters than
+ * only the one passed into the computation routine.
+ */
+public abstract class SubstitutionTextReader extends SingleCharReader {
+
+ protected static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private Reader fReader;
+ private boolean fWasWhiteSpace;
+ private int fCharAfterWhiteSpace;
+
+ private boolean fReadFromBuffer;
+ private StringBuffer fBuffer;
+ private int fIndex;
+
+
+ protected SubstitutionTextReader(Reader reader) {
+ fReader= reader;
+ fBuffer= new StringBuffer();
+ fIndex= 0;
+ fReadFromBuffer= false;
+ fCharAfterWhiteSpace= -1;
+ fWasWhiteSpace= true;
+ }
+
+ /**
+ * Implement to compute the substitution for the given character and
+ * if necessary subsequent characters. Use <code>nextChar</code>
+ * to read subsequent characters.
+ */
+ protected abstract String computeSubstitution(int c) throws IOException;
+
+ /**
+ * Returns the internal reader.
+ */
+ protected Reader getReader() {
+ return fReader;
+ }
+
+ /**
+ * Returns the next character.
+ */
+ protected int nextChar() throws IOException {
+ fReadFromBuffer= (fBuffer.length() > 0);
+ if (fReadFromBuffer) {
+ char ch= fBuffer.charAt(fIndex++);
+ if (fIndex >= fBuffer.length()) {
+ fBuffer.setLength(0);
+ fIndex= 0;
+ }
+ return ch;
+ }
+ int ch= fCharAfterWhiteSpace;
+ if (ch == -1) {
+ ch= fReader.read();
+ }
+ if (Character.isWhitespace((char)ch)) {
+ do {
+ ch= fReader.read();
+ } while (Character.isWhitespace((char)ch));
+ if (ch != -1) {
+ fCharAfterWhiteSpace= ch;
+ return ' ';
+ }
+ } else {
+ fCharAfterWhiteSpace= -1;
+ }
+ return ch;
+ }
+
+ /**
+ * @see Reader#read()
+ */
+ public int read() throws IOException {
+ int c;
+ do {
+
+ c= nextChar();
+ while (!fReadFromBuffer) {
+ String s= computeSubstitution(c);
+ if (s == null)
+ break;
+ if (s.length() > 0)
+ fBuffer.insert(0, s);
+ c= nextChar();
+ }
+
+ } while (fWasWhiteSpace && (c == ' '));
+
+ fWasWhiteSpace= (c == ' ' || c == '\r' || c == '\n');
+ return c;
+ }
+
+ /**
+ * @see Reader#ready()
+ */
+ public boolean ready() throws IOException {
+ return fReader.ready();
+ }
+
+ /**
+ * @see Reader#close()
+ */
+ public void close() throws IOException {
+ fReader.close();
+ }
+
+ /**
+ * @see Reader#reset()
+ */
+ public void reset() throws IOException {
+ fReader.reset();
+ fWasWhiteSpace= true;
+ fCharAfterWhiteSpace= -1;
+ fBuffer.setLength(0);
+ fIndex= 0;
+ }
+} \ No newline at end of file
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java
new file mode 100644
index 0000000000..5fbd71076a
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005, 2007, 2009 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ * Red Hat Inc. - rename to use with Autotools editors
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.cdt.autotools.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * MakefileEditorPreferenceConstants
+ */
+public class AutotoolsEditorPreferenceConstants {
+
+ /**
+ *
+ */
+ private AutotoolsEditorPreferenceConstants() {
+ }
+
+ /**
+ * The symbolic names for colors for displaying code assist proposals
+ * @see org.eclipse.jface.resource.ColorRegistry
+ */
+ public static final String CURRENT_LINE_COLOR = "org.eclipse.linuxtools.cdt.autotools.automake.ui.currentLineHightlightColor"; //$NON-NLS-1$
+ public static final String LINE_NUMBER_RULER_COLOR = "org.eclipse.linuxtools.cdt.autotools.automake.ui.lineNumberForegroundColor"; //$NON-NLS-1$
+ public static final String PRINT_MARGIN_COLOR = "org.eclipse.linuxtools.cdt.autotools.automake.ui.printMarginColor"; //$NON-NLS-1$
+
+ /**
+ * Preference key suffix for bold text style preference keys.
+ *
+ */
+ public static final String EDITOR_BOLD_SUFFIX= "_bold"; //$NON-NLS-1$
+
+ /**
+ * Preference key suffix for italic text style preference keys.
+ */
+ public static final String EDITOR_ITALIC_SUFFIX= "_italic"; //$NON-NLS-1$
+
+
+ public static final String EDITOR_FOLDING_MACRODEF = "editor_folding_default_macrodef"; //$NON-NLS-1$
+
+ public static final String EDITOR_FOLDING_RULE = "editor_folding_default_rule"; //$NON-NLS-1$
+
+ public static final String EDITOR_FOLDING_CASE = "editor_folding_default_case"; //$NON-NLS-1$
+
+ public static final String EDITOR_FOLDING_CONDITIONAL = "editor_folding_default_conditional"; //$NON-NLS-1$
+
+ public static final String EDITOR_FOLDING_LOOP = "editor_folding_default_loop"; //$NON-NLS-1$
+
+ public static final String EDITOR_FOLDING_ENABLED = "editor_folding_enabled"; //$NON-NLS-1$
+
+ public static final String AUTOCONF_VERSION = "autoconf_version"; //$NON-NLS-1$
+
+ public static final String AUTOMAKE_VERSION = "automake_version"; //$NON-NLS-1$
+
+ public static final String LATEST_AC_VERSION = "2.61"; //$NON-NLS-1$
+
+ public static final String LATEST_AM_VERSION = "1.9.6"; //$NON-NLS-1$
+
+ public static void initializeDefaultValues(IPreferenceStore store) {
+
+ store.setDefault(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_ENABLED, false);
+ store.setDefault(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_MACRODEF, false);
+ store.setDefault(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_RULE, true);
+ store.setDefault(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_CASE, true);
+ store.setDefault(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_CONDITIONAL, true);
+ store.setDefault(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_LOOP, true);
+ store.setDefault(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION, LATEST_AC_VERSION);
+ store.setDefault(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION, LATEST_AM_VERSION);
+ }
+
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/OverlayPreferenceStore.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/OverlayPreferenceStore.java
new file mode 100644
index 0000000000..3c6a672572
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/OverlayPreferenceStore.java
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.cdt.autotools.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * OverlayPreferenceStore
+ */
+/**
+ * An overlaying preference store.
+ */
+class OverlayPreferenceStore implements IPreferenceStore {
+
+
+ public static final class TypeDescriptor {
+ TypeDescriptor() {
+ }
+ }
+
+ public static final TypeDescriptor BOOLEAN= new TypeDescriptor();
+ public static final TypeDescriptor DOUBLE= new TypeDescriptor();
+ public static final TypeDescriptor FLOAT= new TypeDescriptor();
+ public static final TypeDescriptor INT= new TypeDescriptor();
+ public static final TypeDescriptor LONG= new TypeDescriptor();
+ public static final TypeDescriptor STRING= new TypeDescriptor();
+
+ public static class OverlayKey {
+
+ TypeDescriptor fDescriptor;
+ String fKey;
+
+ public OverlayKey(TypeDescriptor descriptor, String key) {
+ fDescriptor= descriptor;
+ fKey= key;
+ }
+ }
+
+ private class PropertyListener implements IPropertyChangeListener {
+
+ /*
+ * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ OverlayKey key= findOverlayKey(event.getProperty());
+ if (key != null)
+ propagateProperty(fParent, key, fStore);
+ }
+ }
+
+
+ IPreferenceStore fParent;
+ IPreferenceStore fStore;
+ private OverlayKey[] fOverlayKeys;
+
+ private PropertyListener fPropertyListener;
+
+
+ public OverlayPreferenceStore(IPreferenceStore parent, OverlayKey[] overlayKeys) {
+ fParent= parent;
+ fOverlayKeys= overlayKeys;
+ fStore= new PreferenceStore();
+ }
+
+ OverlayKey findOverlayKey(String key) {
+ for (int i= 0; i < fOverlayKeys.length; i++) {
+ if (fOverlayKeys[i].fKey.equals(key))
+ return fOverlayKeys[i];
+ }
+ return null;
+ }
+
+ private boolean covers(String key) {
+ return (findOverlayKey(key) != null);
+ }
+
+ void propagateProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target) {
+
+ if (orgin.isDefault(key.fKey)) {
+ if (!target.isDefault(key.fKey))
+ target.setToDefault(key.fKey);
+ return;
+ }
+
+ TypeDescriptor d= key.fDescriptor;
+ if (BOOLEAN == d) {
+
+ boolean originValue= orgin.getBoolean(key.fKey);
+ boolean targetValue= target.getBoolean(key.fKey);
+ if (targetValue != originValue)
+ target.setValue(key.fKey, originValue);
+
+ } else if (DOUBLE == d) {
+
+ double originValue= orgin.getDouble(key.fKey);
+ double targetValue= target.getDouble(key.fKey);
+ if (targetValue != originValue)
+ target.setValue(key.fKey, originValue);
+
+ } else if (FLOAT == d) {
+
+ float originValue= orgin.getFloat(key.fKey);
+ float targetValue= target.getFloat(key.fKey);
+ if (targetValue != originValue)
+ target.setValue(key.fKey, originValue);
+
+ } else if (INT == d) {
+
+ int originValue= orgin.getInt(key.fKey);
+ int targetValue= target.getInt(key.fKey);
+ if (targetValue != originValue)
+ target.setValue(key.fKey, originValue);
+
+ } else if (LONG == d) {
+
+ long originValue= orgin.getLong(key.fKey);
+ long targetValue= target.getLong(key.fKey);
+ if (targetValue != originValue)
+ target.setValue(key.fKey, originValue);
+
+ } else if (STRING == d) {
+
+ String originValue= orgin.getString(key.fKey);
+ String targetValue= target.getString(key.fKey);
+ if (targetValue != null && originValue != null && !targetValue.equals(originValue))
+ target.setValue(key.fKey, originValue);
+
+ }
+ }
+
+ public void propagate() {
+ for (int i= 0; i < fOverlayKeys.length; i++)
+ propagateProperty(fStore, fOverlayKeys[i], fParent);
+ }
+
+ private void loadProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target, boolean forceInitialization) {
+ TypeDescriptor d= key.fDescriptor;
+ if (BOOLEAN == d) {
+
+ if (forceInitialization)
+ target.setValue(key.fKey, true);
+ target.setValue(key.fKey, orgin.getBoolean(key.fKey));
+ target.setDefault(key.fKey, orgin.getDefaultBoolean(key.fKey));
+
+ } else if (DOUBLE == d) {
+
+ if (forceInitialization)
+ target.setValue(key.fKey, 1.0D);
+ target.setValue(key.fKey, orgin.getDouble(key.fKey));
+ target.setDefault(key.fKey, orgin.getDefaultDouble(key.fKey));
+
+ } else if (FLOAT == d) {
+
+ if (forceInitialization)
+ target.setValue(key.fKey, 1.0F);
+ target.setValue(key.fKey, orgin.getFloat(key.fKey));
+ target.setDefault(key.fKey, orgin.getDefaultFloat(key.fKey));
+
+ } else if (INT == d) {
+
+ if (forceInitialization)
+ target.setValue(key.fKey, 1);
+ target.setValue(key.fKey, orgin.getInt(key.fKey));
+ target.setDefault(key.fKey, orgin.getDefaultInt(key.fKey));
+
+ } else if (LONG == d) {
+
+ if (forceInitialization)
+ target.setValue(key.fKey, 1L);
+ target.setValue(key.fKey, orgin.getLong(key.fKey));
+ target.setDefault(key.fKey, orgin.getDefaultLong(key.fKey));
+
+ } else if (STRING == d) {
+
+ if (forceInitialization)
+ target.setValue(key.fKey, "1"); //$NON-NLS-1$
+ target.setValue(key.fKey, orgin.getString(key.fKey));
+ target.setDefault(key.fKey, orgin.getDefaultString(key.fKey));
+
+ }
+ }
+
+ public void load() {
+ for (int i= 0; i < fOverlayKeys.length; i++)
+ loadProperty(fParent, fOverlayKeys[i], fStore, true);
+ }
+
+ public void loadDefaults() {
+ for (int i= 0; i < fOverlayKeys.length; i++)
+ setToDefault(fOverlayKeys[i].fKey);
+ }
+
+ public void start() {
+ if (fPropertyListener == null) {
+ fPropertyListener= new PropertyListener();
+ fParent.addPropertyChangeListener(fPropertyListener);
+ }
+ }
+
+ public void stop() {
+ if (fPropertyListener != null) {
+ fParent.removePropertyChangeListener(fPropertyListener);
+ fPropertyListener= null;
+ }
+ }
+
+ /*
+ * @see IPreferenceStore#addPropertyChangeListener(IPropertyChangeListener)
+ */
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ fStore.addPropertyChangeListener(listener);
+ }
+
+ /*
+ * @see IPreferenceStore#removePropertyChangeListener(IPropertyChangeListener)
+ */
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ fStore.removePropertyChangeListener(listener);
+ }
+
+ /*
+ * @see IPreferenceStore#firePropertyChangeEvent(String, Object, Object)
+ */
+ public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
+ fStore.firePropertyChangeEvent(name, oldValue, newValue);
+ }
+
+ /*
+ * @see IPreferenceStore#contains(String)
+ */
+ public boolean contains(String name) {
+ return fStore.contains(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getBoolean(String)
+ */
+ public boolean getBoolean(String name) {
+ return fStore.getBoolean(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDefaultBoolean(String)
+ */
+ public boolean getDefaultBoolean(String name) {
+ return fStore.getDefaultBoolean(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDefaultDouble(String)
+ */
+ public double getDefaultDouble(String name) {
+ return fStore.getDefaultDouble(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDefaultFloat(String)
+ */
+ public float getDefaultFloat(String name) {
+ return fStore.getDefaultFloat(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDefaultInt(String)
+ */
+ public int getDefaultInt(String name) {
+ return fStore.getDefaultInt(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDefaultLong(String)
+ */
+ public long getDefaultLong(String name) {
+ return fStore.getDefaultLong(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDefaultString(String)
+ */
+ public String getDefaultString(String name) {
+ return fStore.getDefaultString(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getDouble(String)
+ */
+ public double getDouble(String name) {
+ return fStore.getDouble(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getFloat(String)
+ */
+ public float getFloat(String name) {
+ return fStore.getFloat(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getInt(String)
+ */
+ public int getInt(String name) {
+ return fStore.getInt(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getLong(String)
+ */
+ public long getLong(String name) {
+ return fStore.getLong(name);
+ }
+
+ /*
+ * @see IPreferenceStore#getString(String)
+ */
+ public String getString(String name) {
+ return fStore.getString(name);
+ }
+
+ /*
+ * @see IPreferenceStore#isDefault(String)
+ */
+ public boolean isDefault(String name) {
+ return fStore.isDefault(name);
+ }
+
+ /*
+ * @see IPreferenceStore#needsSaving()
+ */
+ public boolean needsSaving() {
+ return fStore.needsSaving();
+ }
+
+ /*
+ * @see IPreferenceStore#putValue(String, String)
+ */
+ public void putValue(String name, String value) {
+ if (covers(name))
+ fStore.putValue(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setDefault(String, double)
+ */
+ public void setDefault(String name, double value) {
+ if (covers(name))
+ fStore.setDefault(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setDefault(String, float)
+ */
+ public void setDefault(String name, float value) {
+ if (covers(name))
+ fStore.setDefault(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setDefault(String, int)
+ */
+ public void setDefault(String name, int value) {
+ if (covers(name))
+ fStore.setDefault(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setDefault(String, long)
+ */
+ public void setDefault(String name, long value) {
+ if (covers(name))
+ fStore.setDefault(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setDefault(String, String)
+ */
+ public void setDefault(String name, String value) {
+ if (covers(name))
+ fStore.setDefault(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setDefault(String, boolean)
+ */
+ public void setDefault(String name, boolean value) {
+ if (covers(name))
+ fStore.setDefault(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setToDefault(String)
+ */
+ public void setToDefault(String name) {
+ fStore.setToDefault(name);
+ }
+
+ /*
+ * @see IPreferenceStore#setValue(String, double)
+ */
+ public void setValue(String name, double value) {
+ if (covers(name))
+ fStore.setValue(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setValue(String, float)
+ */
+ public void setValue(String name, float value) {
+ if (covers(name))
+ fStore.setValue(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setValue(String, int)
+ */
+ public void setValue(String name, int value) {
+ if (covers(name))
+ fStore.setValue(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setValue(String, long)
+ */
+ public void setValue(String name, long value) {
+ if (covers(name))
+ fStore.setValue(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setValue(String, String)
+ */
+ public void setValue(String name, String value) {
+ if (covers(name))
+ fStore.setValue(name, value);
+ }
+
+ /*
+ * @see IPreferenceStore#setValue(String, boolean)
+ */
+ public void setValue(String name, boolean value) {
+ if (covers(name))
+ fStore.setValue(name, value);
+ }
+}
diff --git a/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/StatusInfo.java b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/StatusInfo.java
new file mode 100644
index 0000000000..3ae395a617
--- /dev/null
+++ b/autotools/org.eclipse.linuxtools.cdt.autotools/src/org/eclipse/linuxtools/internal/cdt/autotools/ui/preferences/StatusInfo.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.cdt.autotools.ui.preferences;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.linuxtools.cdt.autotools.AutotoolsPlugin;
+
+
+/**
+ * A settable IStatus.
+ * Can be an error, warning, info or ok. For error, info and warning states,
+ * a message describes the problem.
+ */
+public class StatusInfo implements IStatus {
+
+ private String fStatusMessage;
+ private int fSeverity;
+
+ /**
+ * Creates a status set to OK (no message)
+ */
+ public StatusInfo() {
+ this(OK, null);
+ }
+
+ /**
+ * Creates a status .
+ * @param severity The status severity: ERROR, WARNING, INFO and OK.
+ * @param message The message of the status. Applies only for ERROR,
+ * WARNING and INFO.
+ */
+ public StatusInfo(int severity, String message) {
+ fStatusMessage= message;
+ fSeverity= severity;
+ }
+
+ /**
+ * Returns if the status' severity is OK.
+ */
+ public boolean isOK() {
+ return fSeverity == IStatus.OK;
+ }
+
+ /**
+ * Returns if the status' severity is WARNING.
+ */
+ public boolean isWarning() {
+ return fSeverity == IStatus.WARNING;
+ }
+
+ /**
+ * Returns if the status' severity is INFO.
+ */
+ public boolean isInfo() {
+ return fSeverity == IStatus.INFO;
+ }
+
+ /**
+ * Returns if the status' severity is ERROR.
+ */
+ public boolean isError() {
+ return fSeverity == IStatus.ERROR;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IStatus#getMessage()
+ */
+ public String getMessage() {
+ return fStatusMessage;
+ }
+
+ /**
+ * Sets the status to ERROR.
+ * @param errorMessage The error message (can be empty, but not null)
+ */
+ public void setError(String errorMessage) {
+ Assert.isNotNull(errorMessage);
+ fStatusMessage= errorMessage;
+ fSeverity= IStatus.ERROR;
+ }
+
+ /**
+ * Sets the status to WARNING.
+ * @param warningMessage The warning message (can be empty, but not null)
+ */
+ public void setWarning(String warningMessage) {
+ Assert.isNotNull(warningMessage);
+ fStatusMessage= warningMessage;
+ fSeverity= IStatus.WARNING;
+ }
+
+ /**
+ * Sets the status to INFO.
+ * @param infoMessage The info message (can be empty, but not null)
+ */
+ public void setInfo(String infoMessage) {
+ Assert.isNotNull(infoMessage);
+ fStatusMessage= infoMessage;
+ fSeverity= IStatus.INFO;
+ }
+
+ /**
+ * Sets the status to OK.
+ */
+ public void setOK() {
+ fStatusMessage= null;
+ fSeverity= IStatus.OK;
+ }
+
+ /*
+ * @see IStatus#matches(int)
+ */
+ public boolean matches(int severityMask) {
+ return (fSeverity & severityMask) != 0;
+ }
+
+ /**
+ * Returns always <code>false</code>.
+ * @see IStatus#isMultiStatus()
+ */
+ public boolean isMultiStatus() {
+ return false;
+ }
+
+ /*
+ * @see IStatus#getSeverity()
+ */
+ public int getSeverity() {
+ return fSeverity;
+ }
+
+ /*
+ * @see IStatus#getPlugin()
+ */
+ public String getPlugin() {
+ return AutotoolsPlugin.getPluginId();
+ }
+
+ /**
+ * Returns always <code>null</code>.
+ * @see IStatus#getException()
+ */
+ public Throwable getException() {
+ return null;
+ }
+
+ /**
+ * Returns always the error severity.
+ * @see IStatus#getCode()
+ */
+ public int getCode() {
+ return fSeverity;
+ }
+
+ /**
+ * Returns always <code>null</code>.
+ * @see IStatus#getChildren()
+ */
+ public IStatus[] getChildren() {
+ return new IStatus[0];
+ }
+
+}

Back to the top