diff options
Diffstat (limited to 'build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt')
326 files changed, 35548 insertions, 0 deletions
diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/AutotoolsUIPlugin.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/AutotoolsUIPlugin.java new file mode 100644 index 00000000000..d542037ec74 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/AutotoolsUIPlugin.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.autotools.ui; + +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +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 activator class controls the plug-in life cycle + */ +public class AutotoolsUIPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.autotools.ui"; //$NON-NLS-1$ + + // The shared instance + private static AutotoolsUIPlugin plugin; + + private ResourceBundle resourceBundle; + + /** + * The constructor. + */ + public AutotoolsUIPlugin() { + Assert.isTrue(plugin == null); + plugin = this; + try { + resourceBundle = ResourceBundle.getBundle(PLUGIN_ID + ".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(); + } + + /** + * 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 AutotoolsUIPlugin 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 = AutotoolsUIPlugin.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; + } + + /** + * 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(PLUGIN_ID, 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, AutotoolsUIPlugin.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/Resources.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/Resources.properties new file mode 100644 index 00000000000..84ce7c0bf69 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/Resources.properties @@ -0,0 +1,105 @@ +################################################################################# +# 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 +# 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.message.stopped=Build stopped +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.make.message=Invoking {0} for project {1} +MakeGenerator.config.error=Error {0} occurred while running {1} +MakeGenerator.createdir.error=Error creating build directory: {0} +MakeGenerator.run.config.status=Running config.status in build directory: {0} +MakeGenerator.makefile.cvs=Invoking Makefile.cvs in build directory: {0} +MakeGenerator.autogen.sh=Invoking autogen.sh in build directory: {0} +MakeGenerator.autoreconf=Invoking autoreconf in directory: {0} +MakeGenerator.gen.makefile=Generating Makefile in build directory: {0} +MakeGenerator.clean.builddir=Cleaning build directory: {0} +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 + +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 C/C++ Autotools Project +WizardAutotoolsProjectConversion.description=Convert an existing Project to a 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=C/C++ Autotools Conversion +WizardAutotoolsConversion.windowTitle=Conversion to a 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 + +WizardAutotoolsNewCProjectV2.title=Autotools C Project V2 +WizardAutotoolsNewCProjectV2.description=Create a new C Autotools project +WizardAutotoolsNewCProjectV2.monitor.creatingProject=Creating Project... +WizardAutotoolsNewCProjectV2.windowTitle=GNU Autotools C Project V2 +WizardAutotoolsNewCProjectV2.config.title=Select a configuration +WizardAutotoolsNewCProjectV2.config.desc=Select the configuration you wish to deploy on +WizardAutotoolsNewCProjectV2.options.title=Additional Project Settings +WizardAutotoolsNewCProjectV2.options.desc=Define the inter-project dependencies, if any. +WizardAutotoolsNewCProjectV2.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AcInitElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AcInitElement.java new file mode 100644 index 00000000000..179c6807209 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AcInitElement.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 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.cdt.autotools.ui.editors; + +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroElement; +import org.eclipse.cdt.autotools.ui.editors.parser.InvalidMacroException; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.core.VersionComparator; + +public class AcInitElement extends AutoconfMacroElement { + + private static final String BAD_VERSION_NUMBER = "AC_INIT_badVersionNumber"; + + public AcInitElement(String name) { + super(name); + } + + @Override + public void validate(String version) throws InvalidMacroException { + super.validate(version); + + if (this.getChildren().length == 0) + return; + + if (VersionComparator.compare(version, + AutotoolsPropertyConstants.AC_VERSION_2_59) >= 0){ + if (this.getChildren().length < 2) + return; + + this.validateMultipleArguments(); + } + + return; + } + + private void validateMultipleArguments () throws InvalidMacroException{ + + // There are no restrictions on the first argument. + + // Validate second argument (version number). + AutoconfElement argument = this.getChildren()[1]; + // match a digit followed by a dot zero or more times + // but always end with a digit + if (!argument.getName().matches("(\\d*\\.)*((\\d+))")){ + throw new InvalidMacroException(AutoconfEditorMessages.getString(BAD_VERSION_NUMBER), argument); + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfAnnotationHover.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfAnnotationHover.java new file mode 100644 index 00000000000..9d3ae315baa --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfAnnotationHover.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2000 2005 2010 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.cdt.autotools.ui.editors; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.internal.autotools.ui.HTMLPrinter; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationHoverExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ILineRange; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.LineRange; +import org.eclipse.swt.widgets.Shell; + + +public class AutoconfAnnotationHover implements IAnnotationHover, IAnnotationHoverExtension { + + /** + * Returns the distance to the ruler line. + */ + protected int compareRulerLine(Position position, IDocument document, int line) { + + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + int markerLine= document.getLineOfOffset(position.getOffset()); + if (line == markerLine) + return 1; + if (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())) + return 2; + } catch (BadLocationException x) { + } + } + + return 0; + } + + /** + * Selects a set of markers from the two lists. By default, it just returns + * the set of exact matches. + */ + protected List<Annotation> select(List<Annotation> exactMatch, List<Annotation> including) { + return exactMatch; + } + + /** + * Returns one marker which includes the ruler's line of activity. + */ + protected List<Annotation> getAnnotationsForLine(ISourceViewer viewer, int line) { + + IDocument document= viewer.getDocument(); + IAnnotationModel model= viewer.getAnnotationModel(); + + if (model == null) + return null; + + List<Annotation> exact= new ArrayList<Annotation>(); + List<Annotation> including= new ArrayList<Annotation>(); + + @SuppressWarnings("unchecked") + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Object o= e.next(); + if (o instanceof Annotation) { + Annotation a= (Annotation) o; + switch (compareRulerLine(model.getPosition(a), document, line)) { + case 1: + exact.add(a); + break; + case 2: + including.add(a); + break; + } + } + } + + return select(exact, including); + } + + /* + * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + List<Annotation> annotations = getAnnotationsForLine(sourceViewer, lineNumber); + if (annotations != null && annotations.size() > 0) { + + if (annotations.size() == 1) { + + // optimization + Annotation annotation = (Annotation) annotations.get(0); + String message= annotation.getText(); + if (message != null && message.trim().length() > 0) + return formatSingleMessage(message); + + } else { + + List<String> messages= new ArrayList<String>(); + + Iterator<Annotation> e= annotations.iterator(); + while (e.hasNext()) { + Annotation annotation = (Annotation) e.next(); + String message= annotation.getText(); + if (message != null && message.trim().length() > 0) + messages.add(message.trim()); + } + + if (messages.size() == 1) + return formatSingleMessage((String) messages.get(0)); + + if (messages.size() > 1) + return formatMultipleMessages(messages); + } + } + + return null; + } + + +// private int getHoverWidth(Display display) { +// Rectangle displayBounds= display.getBounds(); +// int hoverWidth= displayBounds.width - (display.getCursorLocation().x - displayBounds.x); +// hoverWidth-= 12; // XXX: Add some space to the border, Revisit +// if (hoverWidth < 200) { +// hoverWidth= 200; +// } +// return hoverWidth; +// } + + /* + * Formats a message as HTML text. + */ + private String formatSingleMessage(String message) { + StringBuffer buffer= new StringBuffer(); + HTMLPrinter.addPageProlog(buffer); + HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message)); + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + /* + * Formats several message as HTML text. + */ + private String formatMultipleMessages(List<String> messages) { + StringBuffer buffer= new StringBuffer(); + HTMLPrinter.addPageProlog(buffer); + HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(AutoconfEditorMessages.getString("AutoconfAnnotationHover.multipleMarkers"))); //$NON-NLS-1$ + + HTMLPrinter.startBulletList(buffer); + Iterator<String> e= messages.iterator(); + while (e.hasNext()) + HTMLPrinter.addBullet(buffer, HTMLPrinter.convertToHTMLContent((String) e.next())); + HTMLPrinter.endBulletList(buffer); + + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + // IAnnotationHoverExtension members + // We need to use the extension to get a Hover Control Creator which + // handles html. + + + public IInformationControlCreator getHoverControlCreator() { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, false); + } + }; + } + + public boolean canHandleMouseCursor() { + return false; + } + + public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { + return new LineRange(lineNumber, 1); + } + + public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines) { + return getHoverInfo(sourceViewer, lineRange.getStartLine()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfCodeScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfCodeScanner.java new file mode 100644 index 00000000000..728c3d9ba81 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfCodeScanner.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + * Ed Swartz (NOKIA) - updates + *******************************************************************************/ +package org.eclipse.cdt.autotools.ui.editors; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.EndOfLineRule; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; +import org.eclipse.jface.text.rules.WordRule; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; + + +public class AutoconfCodeScanner extends RuleBasedScanner { + + private Map<String, IToken> fTokenMap= new HashMap<String, IToken>(); + private String[] fPropertyNamesColor; + + /** + * Preference keys for boolean preferences which are <code>true</code>, + * iff the corresponding token should be rendered bold. + */ + private String[] fPropertyNamesBold; + /** + * Preference keys for boolean preferences which are <code>true</code>, + * iff the corresponding token should be rendered italic. + */ + private String[] fPropertyNamesItalic; + + private static String[] keywords = { + "case", "do", "done", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "esac", "if", "elif", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "else", "fi", "for", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "in", "then" }; //$NON-NLS-1$ //$NON-NLS-2$ + + static final String[] fTokenProperties = new String[] { + ColorManager.AUTOCONF_COMMENT_COLOR, + ColorManager.AUTOCONF_KEYWORD_COLOR, + ColorManager.AUTOCONF_ACMACRO_COLOR, + ColorManager.AUTOCONF_AMMACRO_COLOR, + ColorManager.AUTOCONF_VAR_REF_COLOR, + ColorManager.AUTOCONF_VAR_SET_COLOR, + ColorManager.AUTOCONF_CODESEQ_COLOR, + ColorManager.AUTOCONF_DEFAULT_COLOR, + }; + + public AutoconfCodeScanner() { + + initialize(); + + IToken other= getToken(ColorManager.AUTOCONF_DEFAULT_COLOR); + IToken keyword = getToken(ColorManager.AUTOCONF_KEYWORD_COLOR); + IToken comment= getToken(ColorManager.AUTOCONF_COMMENT_COLOR); + IToken string = getToken(ColorManager.AUTOCONF_DEFAULT_COLOR); + IToken varRef = getToken(ColorManager.AUTOCONF_VAR_REF_COLOR); + IToken acmacro = getToken(ColorManager.AUTOCONF_ACMACRO_COLOR); + IToken ammacro = getToken(ColorManager.AUTOCONF_AMMACRO_COLOR); + IToken code = getToken(ColorManager.AUTOCONF_CODESEQ_COLOR); + + List<IRule> rules= new ArrayList<IRule>(); + + // Add rule for single line comments. + rules.add(new EndOfLineRule("dnl", comment)); //$NON-NLS-1$ + rules.add(new EndOfLineRule("#", comment, '\\')); //$NON-NLS-1$ + + // Add special recursive rule for strings which allows variable + // references to be internally tokenized. + RecursiveSingleLineRule stringRule = + new RecursiveSingleLineRule("\"", "\"", string, '\\'); //$NON-NLS-1$ //$NON-NLS-2$ + stringRule.addRule(new SingleLineRule("${", "}", varRef)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(stringRule); + + // Add rule for variable references + rules.add(new SingleLineRule("${", "}", varRef)); //$NON-NLS-1$ //$NON-NLS-2$ + // Add rule for strings + rules.add(new SingleLineRule("\"", "\"", string, '\\')); //$NON-NLS-1$ //$NON-NLS-2$ + + // Add rule for PKG_ macros + rules.add(new AutoconfMacroRule("PKG_", new AutoconfPKGWordDetector(), acmacro)); //$NON-NLS-1$ + + // Add rule for AC_ macros + rules.add(new AutoconfMacroRule("AC_", new AutoconfMacroWordDetector(), acmacro)); //$NON-NLS-1$ + + // Add rule for AM_ macros + rules.add(new AutoconfMacroRule("AM_", new AutoconfMacroWordDetector(), ammacro)); //$NON-NLS-1$ + + // Add rule for m4_ macros + rules.add(new AutoconfMacroRule("m4_", new AutoconfM4WordDetector(), acmacro)); //$NON-NLS-1$ + + // Add rule for code sequences starting with <<EOF and ending with EOF + rules.add(new InlineDataRule(code)); + + // Add word rule for keywords. + WordRule wordRule= new WordRule(new AutoconfWordDetector(), Token.UNDEFINED); + for (int i= 0; i < keywords.length; i++) + wordRule.addWord(keywords[i], keyword); + rules.add(wordRule); + + // Add word rule for identifier. + rules.add(new AutoconfIdentifierRule(other)); + + // Make sure we don't treat "\#" as comment start. + rules.add(new SingleLineRule("\\#", null, Token.UNDEFINED)); + + rules.add(new WhitespaceRule(new AutoconfWhitespaceDetector())); + + setDefaultReturnToken(other); + + IRule[] result= new IRule[rules.size()]; + rules.toArray(result); + setRules(result); + } + + protected Token getToken(String key) { + return (Token) fTokenMap.get(key); + } + + private void addToken(String colorKey, String boldKey, String italicKey) { + fTokenMap.put(colorKey, new Token(createTextAttribute(colorKey, boldKey, italicKey))); + } + + protected String[] getTokenProperties() { + return fTokenProperties; + } + + private int indexOf(String property) { + if (property != null) { + int length= fPropertyNamesColor.length; + for (int i= 0; i < length; i++) { + if (property.equals(fPropertyNamesColor[i]) || property.equals(fPropertyNamesBold[i]) || property.equals(fPropertyNamesItalic[i])) + return i; + } + } + return -1; + } + + /* + * @see ITokenScanner#nextToken() + */ + public IToken nextToken() { + return super.nextToken(); + } + + public boolean affectsBehavior(PropertyChangeEvent event) { + return indexOf(event.getProperty()) >= 0; + } + + public void adaptToPreferenceChange(PropertyChangeEvent event) { + String p= event.getProperty(); + int index= indexOf(p); + Token token= getToken(fPropertyNamesColor[index]); + if (fPropertyNamesColor[index].equals(p)) + adaptToColorChange(event, token); + else if (fPropertyNamesBold[index].equals(p)) + adaptToStyleChange(event, token, SWT.BOLD); + else if (fPropertyNamesItalic[index].equals(p)) + adaptToStyleChange(event, token, SWT.ITALIC); + } + + protected void adaptToColorChange(PropertyChangeEvent event, Token token) { + RGB rgb= null; + Object value= event.getNewValue(); + if (value instanceof RGB) { + rgb= (RGB) value; + } else if (value instanceof String) { + rgb= StringConverter.asRGB((String) value); + } + + if (rgb != null) { + TextAttribute attr= (TextAttribute) token.getData(); + token.setData(new TextAttribute(ColorManager.getDefault().getColor(rgb), attr.getBackground(), attr.getStyle())); + } + } + + protected void adaptToStyleChange(PropertyChangeEvent event, Token token, int styleAttribute) { + if (token == null) { + return; + } + boolean eventValue= false; + Object value= event.getNewValue(); + if (value instanceof Boolean) { + eventValue= ((Boolean) value).booleanValue(); + } else if (IPreferenceStore.TRUE.equals(value)) { + eventValue= true; + } + + TextAttribute attr= (TextAttribute) token.getData(); + boolean activeValue= (attr.getStyle() & styleAttribute) == styleAttribute; + if (activeValue != eventValue) { + token.setData(new TextAttribute(attr.getForeground(), attr.getBackground(), eventValue ? attr.getStyle() | styleAttribute : attr.getStyle() & ~styleAttribute)); + } + } + + protected TextAttribute createTextAttribute(String colorID, String boldKey, String italicKey) { + Color color= null; + if (colorID != null) { + color= AutoconfEditor.getPreferenceColor(colorID); + } + IPreferenceStore store= AutotoolsPlugin.getDefault().getPreferenceStore(); + int style= store.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL; + if (store.getBoolean(italicKey)) { + style |= SWT.ITALIC; + } + return new TextAttribute(color, null, style); + } + + /** + * Must be called after the constructor has been called. + */ + public final void initialize() { + + fPropertyNamesColor= getTokenProperties(); + int length= fPropertyNamesColor.length; + fPropertyNamesBold= new String[length]; + fPropertyNamesItalic= new String[length]; + + for (int i= 0; i < length; i++) { + fPropertyNamesBold[i]= fPropertyNamesColor[i] + AutotoolsEditorPreferenceConstants.EDITOR_BOLD_SUFFIX; + fPropertyNamesItalic[i]= fPropertyNamesColor[i] + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX; + addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i]); + } + } + + /* + * @see ICharacterScanner#unread() + */ + public void unread() { + --fOffset; + fColumn = UNDEFINED; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfDocumentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfDocumentProvider.java new file mode 100644 index 00000000000..a519fc151f1 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfDocumentProvider.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import java.util.Iterator; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ui.editors.text.TextFileDocumentProvider; + +public class AutoconfDocumentProvider extends TextFileDocumentProvider { + + public void shutdown() { + @SuppressWarnings("unchecked") + Iterator e= getConnectedElementsIterator(); + while (e.hasNext()) + disconnect(e.next()); + } + + public void connect(Object element) throws CoreException { + super.connect(element); + // Remove all error markers for file as we will parse + // from scratch. +// AutoconfErrorHandler h = new AutoconfErrorHandler(getDocument(element)); +// h.removeAllExistingMarkers(); + } + + public IDocument getDocument(Object element) { + FileInfo info= (FileInfo) getFileInfo(element); + if (info != null) + return info.fTextFileBuffer.getDocument(); + return getParentProvider().getDocument(element); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfDocumentSetupParticipant.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfDocumentSetupParticipant.java new file mode 100644 index 00000000000..1c7dda224ce --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfDocumentSetupParticipant.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import org.eclipse.core.filebuffers.IDocumentSetupParticipant; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IDocumentListener; + +public class AutoconfDocumentSetupParticipant implements + IDocumentSetupParticipant, IDocumentListener { + + public void setup(IDocument document) { + AutoconfPartitioner partitioner = + new AutoconfPartitioner( + new AutoconfPartitionScanner(), + AutoconfPartitionScanner.AUTOCONF_PARTITION_TYPES); + partitioner.connect(document, 1); + if (document instanceof IDocumentExtension3) { + IDocumentExtension3 extension3= (IDocumentExtension3) document; + extension3.setDocumentPartitioner(AutoconfEditor.AUTOCONF_PARTITIONING, partitioner); + } else { + document.setDocumentPartitioner(partitioner); + } +// document.addDocumentListener(this); + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + + public void documentAboutToBeChanged(DocumentEvent e) { + // do nothing + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent e) { + // do nothing + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditor.java new file mode 100644 index 00000000000..9e9a4f13ea5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditor.java @@ -0,0 +1,764 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import java.util.ResourceBundle; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.autotools.ui.editors.outline.AutoconfContentOutlinePage; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroDetector; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfParser; +import org.eclipse.cdt.autotools.ui.editors.parser.IAutoconfMacroValidator; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.ui.editors.autoconf.ProjectionFileUpdater; +import org.eclipse.cdt.internal.autotools.ui.editors.automake.IReconcilingParticipant; +import org.eclipse.cdt.internal.autotools.ui.editors.automake.MakefileEditorPreferenceConstants; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutoconfEditorPreferencePage; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.cdt.internal.autotools.ui.properties.AutotoolsPropertyManager; +import org.eclipse.cdt.internal.autotools.ui.properties.IProjectPropertyListener; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.text.AbstractInformationControlManager; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.ITextViewerExtension2; +import org.eclipse.jface.text.ITextViewerExtension4; +import org.eclipse.jface.text.ITextViewerExtension5; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextUtilities; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.IInformationProviderExtension; +import org.eclipse.jface.text.information.IInformationProviderExtension2; +import org.eclipse.jface.text.information.InformationPresenter; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationHoverExtension; +import org.eclipse.jface.text.source.ILineRange; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.ISourceViewerExtension3; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionSupport; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.ChainedPreferenceStore; +import org.eclipse.ui.texteditor.ContentAssistAction; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.ResourceAction; +import org.eclipse.ui.texteditor.TextEditorAction; +import org.eclipse.ui.texteditor.TextOperationAction; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + + +public class AutoconfEditor extends TextEditor implements IAutotoolsEditor, IProjectPropertyListener { + + public final static String AUTOCONF_PARTITIONING= "autoconf_partitioning"; //$NON-NLS-1$ + + + private AutoconfPartitionScanner fPartitionScanner; + private RuleBasedScanner fCodeScanner; + private RuleBasedScanner fMacroCodeScanner; + private static volatile AutoconfDocumentProvider fDocumentProvider; + private AutoconfElement rootElement; + private AutoconfContentOutlinePage outlinePage; + private AutoconfParser fParser; + private IEditorInput input; + private IProject fProject; + + /** The information provider used to present focusable information shells. */ + private InformationPresenter fInformationPresenter; + /** + * This editor's projection support + */ + + ProjectionSupport fProjectionSupport; + ProjectionFileUpdater fProjectionFileUpdater; + + /** + * Reconciling listeners + */ + private ListenerList fReconcilingListeners= new ListenerList(ListenerList.IDENTITY); + + + public AutoconfEditor() { + super(); + } + + protected void initializeEditor() { + super.initializeEditor(); + setDocumentProvider(getAutoconfDocumentProvider()); + IPreferenceStore[] stores = new IPreferenceStore[2]; + stores[0] = AutotoolsPlugin.getDefault().getPreferenceStore(); + stores[1] = EditorsUI.getPreferenceStore(); + ChainedPreferenceStore chainedStore = new ChainedPreferenceStore(stores); + setPreferenceStore(chainedStore); + setSourceViewerConfiguration(new AutoconfSourceViewerConfiguration(chainedStore, this)); + AutotoolsEditorPreferenceConstants.initializeDefaultValues(stores[0]); + AutoconfEditorPreferencePage.initDefaults(stores[0]); + } + + public static AutoconfDocumentProvider getAutoconfDocumentProvider() { + if (fDocumentProvider == null) + fDocumentProvider= new AutoconfDocumentProvider(); + return fDocumentProvider; + } + + public AutoconfElement getRootElement() { + return rootElement; + } + + public void setRootElement(AutoconfElement element) { + rootElement = element; + } + + public ISourceViewer getViewer() { + return getSourceViewer(); + } + + protected IDocument getInputDocument() + { + IDocument document = getDocumentProvider().getDocument(input); + return document; + } + + protected void doSetInput(IEditorInput newInput) throws CoreException + { + // If this editor is for a project file, remove this editor as a property + // change listener. + if (fProject != null) + AutotoolsPropertyManager.getDefault().removeProjectPropertyListener(fProject, this); + this.fProject = null; + super.doSetInput(newInput); + this.input = newInput; + + if (input instanceof IFileEditorInput) { + IFile f = ((IFileEditorInput)input).getFile(); + fProject = f.getProject(); + // This is a project file. We want to be notified if the Autoconf editor + // properties are changed such that the macro versions are changed. + AutotoolsPropertyManager.getDefault().addProjectPropertyListener(fProject, this); + } + getOutlinePage().setInput(input); + try + { + IDocument document = getInputDocument(); + + setRootElement(reparseDocument(document, newInput)); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @SuppressWarnings({ "unchecked" }) + public Object getAdapter(Class required) { + if (ProjectionAnnotationModel.class.equals(required)) { + if (fProjectionSupport != null) { + Object result = fProjectionSupport.getAdapter(getSourceViewer(), required); + if (result != null) { + return result; + } + } + } else if (IContentOutlinePage.class.equals(required)) { + return getOutlinePage(); + } + return super.getAdapter(required); + } + + + public AutoconfContentOutlinePage getOutlinePage() { + if (outlinePage == null) { + outlinePage= new AutoconfContentOutlinePage(this); + if (getEditorInput() != null) + outlinePage.setInput(getEditorInput()); + } + return outlinePage; + } + + /** + * Return a scanner for creating Autoconf partitions. + * + * @return a scanner for creating Autoconf partitions + */ + public AutoconfParser getAutoconfParser() { + if (fParser == null) { + AutoconfErrorHandler errorHandler = new AutoconfErrorHandler(input); + IAutoconfMacroValidator macroValidator = new AutoconfEditorMacroValidator(this); + fParser = new AutoconfParser(errorHandler, new AutoconfMacroDetector(), macroValidator); + } + return fParser; + } + + /** + * Return a scanner for creating Autoconf partitions. + * + * @return a scanner for creating Autoconf partitions + */ + public AutoconfPartitionScanner getAutoconfPartitionScanner() { + if (fPartitionScanner == null) + fPartitionScanner= new AutoconfPartitionScanner(); + return fPartitionScanner; + } + + /** + * Returns the Autoconf code scanner. + * + * @return the Autoconf code scanner + */ + public RuleBasedScanner getAutoconfCodeScanner() { + if (fCodeScanner == null) + fCodeScanner= new AutoconfCodeScanner(); + return fCodeScanner; + } + + /** + * Returns the Autoconf code scanner. + * + * @return the Autoconf code scanner + */ + public RuleBasedScanner getAutoconfMacroCodeScanner() { + if (fMacroCodeScanner == null) + fMacroCodeScanner= new AutoconfMacroCodeScanner(); + return fMacroCodeScanner; + } + + /** + * Returns the preference color, identified by the given preference. + */ + public static Color getPreferenceColor(String key) { + return ColorManager.getDefault().getColor(PreferenceConverter.getColor(AutotoolsPlugin.getDefault().getPreferenceStore(), key)); + } + + public void handleProjectPropertyChanged(IProject project, String property) { + if (property.equals(AutotoolsPropertyConstants.AUTOCONF_MACRO_VERSIONING)) { + ISourceViewer sourceViewer= getSourceViewer(); + if (sourceViewer == null) + return; + handleVersionChange(sourceViewer); + } + } + + /** + * Handle the case whereby the Autoconf or Automake macro versions to use + * for this project are changed in which case we want to invalidate and reparse + * the document. + * + * @param sourceViewer + */ + protected void handleVersionChange(ISourceViewer sourceViewer) { + sourceViewer.invalidateTextPresentation(); + try { + IDocument document = getInputDocument(); + + setRootElement(reparseDocument(document, getEditorInput())); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private AutoconfElement reparseDocument(IDocument document, + IEditorInput editorInput) { + AutoconfParser parser = getAutoconfParser(); + ((AutoconfErrorHandler)parser.getErrorHandler()).removeAllExistingMarkers(); + + return parser.parse(document); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent) + */ + protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { + ISourceViewer sourceViewer= getSourceViewer(); + if (sourceViewer == null) + return; + + String property = event.getProperty(); + + AutoconfCodeScanner scanner = (AutoconfCodeScanner)getAutoconfCodeScanner(); + if (scanner != null) { + if (scanner.affectsBehavior(event)) { + scanner.adaptToPreferenceChange(event); + sourceViewer.invalidateTextPresentation(); + } + } + + if (AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION.equals(property) || + AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION.equals(property)) { + handleVersionChange(sourceViewer); + } else if (AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_ENABLED.equals(property)) { + if (sourceViewer instanceof ProjectionViewer) { + ProjectionViewer projectionViewer= (ProjectionViewer) sourceViewer; + if (fProjectionFileUpdater != null) + fProjectionFileUpdater.uninstall(); + // either freshly enabled or provider changed + fProjectionFileUpdater= new ProjectionFileUpdater(); + if (fProjectionFileUpdater != null) { + fProjectionFileUpdater.install(this, projectionViewer); + } + } + return; + } + + super.handlePreferenceStoreChanged(event); + } + + /** + * Information provider used to present focusable information shells. + * + * @since 3.1.1 + */ + private static final class InformationProvider implements IInformationProvider, IInformationProviderExtension, IInformationProviderExtension2 { + + private IRegion fHoverRegion; + private Object fHoverInfo; + private IInformationControlCreator fControlCreator; + + InformationProvider(IRegion hoverRegion, Object hoverInfo, IInformationControlCreator controlCreator) { + fHoverRegion= hoverRegion; + fHoverInfo= hoverInfo; + fControlCreator= controlCreator; + } + /* + * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getSubject(ITextViewer textViewer, int invocationOffset) { + return fHoverRegion; + } + /* + * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + */ + public String getInformation(ITextViewer textViewer, IRegion subject) { + return fHoverInfo.toString(); + } + + /* + * @see org.eclipse.jface.text.information.IInformationProviderExtension#getInformation2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + * @since 3.2 + */ + public Object getInformation2(ITextViewer textViewer, IRegion subject) { + return fHoverInfo; + } + /* + * @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator() + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return fControlCreator; + } + } + + /** + * This action behaves in two different ways: If there is no current text + * hover, the tooltip is displayed using information presenter. If there is + * a current text hover, it is converted into a information presenter in + * order to make it sticky. + * @since 3.1.1 + */ + class InformationDispatchAction extends TextEditorAction { + + /** The wrapped text operation action. */ + private final TextOperationAction fTextOperationAction; + + /** + * Creates a dispatch action. + * + * @param resourceBundle the resource bundle + * @param prefix the prefix + * @param textOperationAction the text operation action + */ + public InformationDispatchAction(ResourceBundle resourceBundle, String prefix, final TextOperationAction textOperationAction) { + super(resourceBundle, prefix, AutoconfEditor.this); + if (textOperationAction == null) + throw new IllegalArgumentException(); + fTextOperationAction= textOperationAction; + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + + ISourceViewer sourceViewer= getSourceViewer(); + if (sourceViewer == null) { + fTextOperationAction.run(); + return; + } + + if (sourceViewer instanceof ITextViewerExtension4) { + ITextViewerExtension4 extension4= (ITextViewerExtension4) sourceViewer; + if (extension4.moveFocusToWidgetToken()) + return; + } + + if (sourceViewer instanceof ITextViewerExtension2) { + // does a text hover exist? + ITextHover textHover= ((ITextViewerExtension2) sourceViewer).getCurrentTextHover(); + if (textHover != null && makeTextHoverFocusable(sourceViewer, textHover)) + return; + } + + if (sourceViewer instanceof ISourceViewerExtension3) { + // does an annotation hover exist? + IAnnotationHover annotationHover= ((ISourceViewerExtension3) sourceViewer).getCurrentAnnotationHover(); + if (annotationHover != null && makeAnnotationHoverFocusable(sourceViewer, annotationHover)) + return; + } + + // otherwise, just display the tooltip + //fTextOperationAction.run(); + } + + /** + * Tries to make a text hover focusable (or "sticky"). + * + * @param sourceViewer the source viewer to display the hover over + * @param textHover the hover to make focusable + * @return <code>true</code> if successful, <code>false</code> otherwise + */ + @SuppressWarnings("deprecation") + private boolean makeTextHoverFocusable(ISourceViewer sourceViewer, ITextHover textHover) { + Point hoverEventLocation= ((ITextViewerExtension2) sourceViewer).getHoverEventLocation(); + int offset= computeOffsetAtLocation(sourceViewer, hoverEventLocation.x, hoverEventLocation.y); + if (offset == -1) + return false; + + try { + IRegion hoverRegion= textHover.getHoverRegion(sourceViewer, offset); + if (hoverRegion == null) + return false; + + String hoverInfo= textHover.getHoverInfo(sourceViewer, hoverRegion); + + IInformationControlCreator controlCreator= null; + if (textHover instanceof IInformationProviderExtension2) + controlCreator= ((IInformationProviderExtension2)textHover).getInformationPresenterControlCreator(); + + IInformationProvider informationProvider= new InformationProvider(hoverRegion, hoverInfo, controlCreator); + + fInformationPresenter.setOffset(offset); + fInformationPresenter.setAnchor(AbstractInformationControlManager.ANCHOR_BOTTOM); + fInformationPresenter.setMargins(6, 6); // default values from AbstractInformationControlManager + String contentType= TextUtilities.getContentType(sourceViewer.getDocument(), AutoconfPartitionScanner.AUTOCONF_MACRO, offset, true); + fInformationPresenter.setInformationProvider(informationProvider, contentType); + fInformationPresenter.showInformation(); + + return true; + + } catch (BadLocationException e) { + return false; + } + } + + /** + * Tries to make an annotation hover focusable (or "sticky"). + * + * @param sourceViewer the source viewer to display the hover over + * @param annotationHover the hover to make focusable + * @return <code>true</code> if successful, <code>false</code> otherwise + */ + private boolean makeAnnotationHoverFocusable(ISourceViewer sourceViewer, IAnnotationHover annotationHover) { + IVerticalRulerInfo info= getVerticalRuler(); + int line= info.getLineOfLastMouseButtonActivity(); + if (line == -1) + return false; + + try { + + // compute the hover information + Object hoverInfo; + if (annotationHover instanceof IAnnotationHoverExtension) { + IAnnotationHoverExtension extension= (IAnnotationHoverExtension) annotationHover; + ILineRange hoverLineRange= extension.getHoverLineRange(sourceViewer, line); + if (hoverLineRange == null) + return false; + final int maxVisibleLines= Integer.MAX_VALUE; // allow any number of lines being displayed, as we support scrolling + hoverInfo= extension.getHoverInfo(sourceViewer, hoverLineRange, maxVisibleLines); + } else { + hoverInfo= annotationHover.getHoverInfo(sourceViewer, line); + } + + // hover region: the beginning of the concerned line to place the control right over the line + IDocument document= sourceViewer.getDocument(); + int offset= document.getLineOffset(line); + String contentType= TextUtilities.getContentType(document, AutoconfPartitionScanner.AUTOCONF_MACRO, offset, true); + + IInformationControlCreator controlCreator= null; + +// /* +// * XXX: This is a hack to avoid API changes at the end of 3.2, +// * and should be fixed for 3.3, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=137967 +// */ +// if ("org.eclipse.jface.text.source.projection.ProjectionAnnotationHover".equals(annotationHover.getClass().getName())) { //$NON-NLS-1$ +// controlCreator= new IInformationControlCreator() { +// public IInformationControl createInformationControl(Shell shell) { +// int shellStyle= SWT.RESIZE | SWT.TOOL | getOrientation(); +// int style= SWT.V_SCROLL | SWT.H_SCROLL; +// return new SourceViewerInformationControl(shell, shellStyle, style); +// } +// }; +// +// } else { + if (annotationHover instanceof IInformationProviderExtension2) + controlCreator= ((IInformationProviderExtension2) annotationHover).getInformationPresenterControlCreator(); + else if (annotationHover instanceof IAnnotationHoverExtension) + controlCreator= ((IAnnotationHoverExtension) annotationHover).getHoverControlCreator(); +// } + + IInformationProvider informationProvider= new InformationProvider(new Region(offset, 0), hoverInfo, controlCreator); + + fInformationPresenter.setOffset(offset); + fInformationPresenter.setAnchor(AbstractInformationControlManager.ANCHOR_RIGHT); + fInformationPresenter.setMargins(4, 0); // AnnotationBarHoverManager sets (5,0), minus SourceViewer.GAP_SIZE_1 + fInformationPresenter.setInformationProvider(informationProvider, contentType); + fInformationPresenter.showInformation(); + + return true; + + } catch (BadLocationException e) { + return false; + } + } + + // modified version from TextViewer + private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) { + + StyledText styledText= textViewer.getTextWidget(); + IDocument document= textViewer.getDocument(); + + if (document == null) + return -1; + + try { + int widgetOffset= styledText.getOffsetAtLocation(new Point(x, y)); + Point p= styledText.getLocationAtOffset(widgetOffset); + if (p.x > x) + widgetOffset--; + + if (textViewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension= (ITextViewerExtension5) textViewer; + return extension.widgetOffset2ModelOffset(widgetOffset); + } else { + IRegion visibleRegion= textViewer.getVisibleRegion(); + return widgetOffset + visibleRegion.getOffset(); + } + } catch (IllegalArgumentException e) { + return -1; + } + + } + } + + /** + * Adds the given listener. + * Has no effect if an identical listener was not already registered. + * + * @param listener The reconcile listener to be added + */ + public final void addReconcilingParticipant(IReconcilingParticipant listener) { + synchronized (fReconcilingListeners) { + fReconcilingListeners.add(listener); + } + } + + /** + * Removes the given listener. + * Has no effect if an identical listener was not already registered. + * + * @param listener the reconcile listener to be removed + */ + final void removeReconcilingParticipant(IReconcilingParticipant listener) { + synchronized (fReconcilingListeners) { + fReconcilingListeners.remove(listener); + } + } + + /* + */ + public void reconciled() { + // Notify listeners + Object[] listeners = fReconcilingListeners.getListeners(); + for (int i = 0, length= listeners.length; i < length; ++i) { + ((IReconcilingParticipant)listeners[i]).reconciled(); + } + } + + /** + * Determines is folding enabled. + * @return <code>true</code> if folding is enabled, <code>false</code> otherwise. + */ + boolean isFoldingEnabled() { + return AutotoolsPlugin.getDefault().getPreferenceStore().getBoolean(MakefileEditorPreferenceConstants.EDITOR_FOLDING_ENABLED); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes() + */ + protected void initializeKeyBindingScopes() { + setKeyBindingScopes(new String [] { AutotoolsUIPlugin.getUniqueIdentifier() + ".editor.scope" } ); //$NON-NLS-1$ + } + + + /** + * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions() + */ + protected void createActions() { + super.createActions(); + // TODO: Figure out how to do this later. +// fFoldingGroup= new FoldingActionGroup(this, getSourceViewer()); + + // Sticky hover support + ResourceAction resAction= new TextOperationAction(AutoconfEditorMessages.getResourceBundle(), "ShowToolTip.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$ + resAction= new InformationDispatchAction(AutoconfEditorMessages.getResourceBundle(), "ShowToolTip.", (TextOperationAction) resAction); //$NON-NLS-1$ + resAction.setActionDefinitionId(IAutotoolEditorActionDefinitionIds.SHOW_TOOLTIP); + setAction("ShowToolTip", resAction); //$NON-NLS-1$ + PlatformUI.getWorkbench().getHelpSystem().setHelp(resAction, IAutotoolHelpContextIds.SHOW_TOOLTIP_ACTION); + + // Content assist + Action action = new ContentAssistAction(AutoconfEditorMessages.getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$ + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); + setAction("ContentAssistProposal", action); //$NON-NLS-1$ + markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$ + PlatformUI.getWorkbench().getHelpSystem().setHelp(action, IAutotoolHelpContextIds.CONTENT_ASSIST); + } + + /** + * The <code>AbstractTextEditor</code> implementation of this + * <code>IWorkbenchPart</code> method creates the vertical ruler and + * source viewer. Subclasses may extend. + * + * We attach our own mouseDown listener on the menu bar, + * and our own listener for cursor/key/selection events to update cursor position in + * status bar. + + * @param parent Parent composite of the control. + */ + public void createPartControl(Composite parent) { + super.createPartControl(parent); + + // Sticky hover support + IInformationControlCreator informationControlCreator= new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell shell) { + return new DefaultInformationControl(shell, true); + } + }; + + fInformationPresenter= new InformationPresenter(informationControlCreator); + fInformationPresenter.setSizeConstraints(60, 10, true, true); + fInformationPresenter.install(getSourceViewer()); + fInformationPresenter.setDocumentPartitioning(AutoconfPartitionScanner.AUTOCONF_MACRO); + + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); + + fProjectionSupport= new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); + fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$ + fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$ + fProjectionSupport.install(); + + if (isFoldingEnabled()) + projectionViewer.doOperation(ProjectionViewer.TOGGLE); + + fProjectionFileUpdater= new ProjectionFileUpdater(); + if (fProjectionFileUpdater != null) { + fProjectionFileUpdater.install(this, projectionViewer); + fProjectionFileUpdater.initialize(); + } + + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IAutotoolHelpContextIds.AC_EDITOR_VIEW); + + // TODO: Do we need the following two lines? +// fEditorSelectionChangedListener= new EditorSelectionChangedListener(); +// fEditorSelectionChangedListener.install(getSelectionProvider()); + } + + protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { + ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles); + + // ensure decoration support has been created and configured. + getSourceViewerDecorationSupport(viewer); + + return viewer; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + public void dispose() { + if (fProjectionFileUpdater != null) { + fProjectionFileUpdater.uninstall(); + fProjectionFileUpdater= null; + } + if (fProject != null) { + AutotoolsPropertyManager.getDefault().removeProjectPropertyListener(fProject, this); + } + super.dispose(); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert() + */ + protected void performRevert() { + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); + projectionViewer.setRedraw(false); + try { + + boolean projectionMode= projectionViewer.isProjectionMode(); + if (projectionMode) { + projectionViewer.disableProjection(); + if (fProjectionFileUpdater != null) + fProjectionFileUpdater.uninstall(); + } + + super.performRevert(); + + if (projectionMode) { + if (fProjectionFileUpdater != null) + fProjectionFileUpdater.install(this, projectionViewer); + projectionViewer.enableProjection(); + } + + } finally { + projectionViewer.setRedraw(true); + } + } + + public IProject getProject() { + return this.fProject; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMacroValidator.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMacroValidator.java new file mode 100644 index 00000000000..efb7f5b1428 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMacroValidator.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2007 Red Hat Corporation, (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.cdt.autotools.ui.editors; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroElement; +import org.eclipse.cdt.autotools.ui.editors.parser.IAutoconfMacroValidator; +import org.eclipse.cdt.autotools.ui.editors.parser.InvalidMacroException; +import org.eclipse.cdt.autotools.ui.editors.parser.ParseException; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.cdt.internal.autotools.ui.text.hover.AutoconfPrototype; +import org.eclipse.cdt.internal.autotools.ui.text.hover.AutoconfTextHover; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.BadLocationException; + + +/** + * Validate a macro call by checking against the stored macro prototypes + */ +public class AutoconfEditorMacroValidator implements IAutoconfMacroValidator { + public final String AUTOCONF_MACRO_ARGS_TOO_FEW = "AutoconfMacroArgsTooFew"; //$NON-NLS-1$ + public final String AUTOCONF_MACRO_ARGS_TOO_MANY = "AutoconfMacroArgsTooMany"; //$NON-NLS-1$ + + private AutoconfEditor fEditor; + + public AutoconfEditorMacroValidator(AutoconfEditor autoconfEditor) { + fEditor = autoconfEditor; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.autotools.ui.editors.parser.IAutoconfMacroValidator#validateMacroCall(org.eclipse.cdt.autotools.core.ui.editors.parser.AutoconfMacroElement) + */ + public void validateMacroCall(AutoconfMacroElement macro) + throws ParseException, InvalidMacroException { + AutoconfPrototype p = AutoconfTextHover.getPrototype(macro.getName(), fEditor); + if (p != null) { + boolean tooFew = false; + boolean tooMany = false; + boolean justRight = false; + int parms = macro.getParameterCount(); + int numPrototypes = p.getNumPrototypes(); + int minParms = 0; + int maxParms = 0; + for (int i = 0; i < numPrototypes; ++i) { + if (parms < p.getMinParms(i)) { + tooFew = true; + minParms = p.getMinParms(i); + } else if (parms > p.getMaxParms(i)) { + tooMany = true; + maxParms = p.getMaxParms(i); + } else { + justRight = true; + break; + } + } + + int length = macro.getEndOffset() - macro.getStartOffset(); + int start = macro.getStartOffset(); + int end = macro.getEndOffset(); + int lineNumber = 0; + try { + lineNumber = macro.getDocument().getLineOfOffset(start); + } catch (BadLocationException e) { + + } + + if (!justRight) { + if (tooFew) { + String formatString = AutoconfEditorMessages.getFormattedString(AUTOCONF_MACRO_ARGS_TOO_FEW, + AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION), + p.getName(), Integer.toString(minParms)); + throw new ParseException( + formatString, + start, end, + lineNumber, 0, length, + IMarker.SEVERITY_WARNING); + } else if (tooMany) { + String formatString = AutoconfEditorMessages.getFormattedString(AUTOCONF_MACRO_ARGS_TOO_MANY, + AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION), + p.getName(), Integer.toString(maxParms)); + throw new ParseException( + formatString, + start, end, + lineNumber, 0, length, + IMarker.SEVERITY_WARNING); + } + } + + IProject project = fEditor.getProject(); + String acDocVer = AutoconfTextHover.getDefaultAutoconfMacrosVer(); + try { + String acVer = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION); + if (acVer != null) + acDocVer = acVer; + else { // look for compat project properties + acVer = project.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION_COMPAT); + if (acVer != null) + acDocVer = acVer; + } + } catch (CoreException ce1) { + // do nothing + } + + macro.validate(acDocVer); + + } + + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMessages.java new file mode 100644 index 00000000000..18c8c1cdcda --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/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.cdt.autotools.ui.editors; + +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[] { Boolean.valueOf(arg) }); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMessages.properties new file mode 100644 index 00000000000..f4b8547fdb8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfEditorMessages.properties @@ -0,0 +1,49 @@ +################################################################################# +# 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 + +AC_INIT_badVersionNumber =The second argument of AC_INIT must be a version number + +ShowToolTip.label=Show T&ooltip Description +ContentAssistProposal.label=Co&ntent Assist +ContentAssistProposal.tooltip=Content Assist +ContentAssistProposal.description=Content Assist + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfErrorHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfErrorHandler.java new file mode 100644 index 00000000000..5daefac831e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfErrorHandler.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.autotools.ui.editors; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.autotools.ui.editors.parser.IAutoconfErrorHandler; +import org.eclipse.cdt.autotools.ui.editors.parser.ParseException; +import org.eclipse.core.runtime.AssertionFailedException; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.quickassist.IQuickFixableAnnotation; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.ui.IEditorInput; + + +public class AutoconfErrorHandler implements IAutoconfErrorHandler { + + public static final String CDT_ANNOTATION_INFO = "org.eclipse.cdt.ui.info"; //$NON-NLS-1$ + public static final String CDT_ANNOTATION_WARNING = "org.eclipse.cdt.ui.warning"; //$NON-NLS-1$ + public static final String CDT_ANNOTATION_ERROR = "org.eclipse.cdt.ui.error"; //$NON-NLS-1$ + + private int CDT_WARNING = 1; + private int CDT_ERROR = 2; + + private Map<Position, Annotation> annotations = new HashMap<Position, Annotation>(); + private AnnotationModel fAnnotationModel; + + public AutoconfErrorHandler(IEditorInput input) { + this.fAnnotationModel = (AnnotationModel)AutoconfEditor.getAutoconfDocumentProvider().getAnnotationModel(input); + } + + // TODO: no quickfixes yet implemented, but maybe in the future + private static class AutoconfAnnotation extends Annotation implements IQuickFixableAnnotation { + public AutoconfAnnotation(String annotationType, boolean persist, String message) { + super(annotationType, persist, message); + } + + public void setQuickFixable(boolean state) { + // do nothing + } + + public boolean isQuickFixableStateSet() { + return true; + } + + public boolean isQuickFixable() throws AssertionFailedException { + return false; + } + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.autotools.ui.editors.IAutoconfErrorHandler#handleError(org.eclipse.cdt.autotools.core.ui.editors.parser.ParseException) + */ + public void handleError(ParseException e) { + Integer charStart = Integer.valueOf(e.getStartOffset()); + Integer charEnd = Integer.valueOf(e.getEndOffset()); + + String annotationType = CDT_ANNOTATION_INFO; + if (e.getSeverity() == CDT_ERROR) + annotationType = CDT_ANNOTATION_ERROR; + else if (e.getSeverity() == CDT_WARNING) + annotationType = CDT_ANNOTATION_WARNING; + Annotation annotation = new AutoconfAnnotation(annotationType, true, e.getLocalizedMessage()); + Position p = new Position(charStart.intValue(),charEnd.intValue() - charStart.intValue()); + fAnnotationModel.addAnnotation(annotation, p); + annotations.put(p, annotation); + } + + public void removeAllExistingMarkers() + { + fAnnotationModel.removeAllAnnotations(); + annotations.clear(); + } + + public void removeExistingMarkers(int offset, int length) + { + @SuppressWarnings("unchecked") + Iterator i = fAnnotationModel.getAnnotationIterator(); + while (i.hasNext()) { + Annotation annotation = (Annotation)i.next(); + Position p = fAnnotationModel.getPosition(annotation); + int pStart = p.getOffset(); + if (pStart >= offset && pStart < (offset + length)) { + // Remove directly from model instead of using + // iterator so position will be removed from document. + fAnnotationModel.removeAnnotation(annotation); + } + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfIdentifierRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfIdentifierRule.java new file mode 100644 index 00000000000..3a1bfbe6669 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfIdentifierRule.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2007, 20009 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.cdt.autotools.ui.editors; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +public class AutoconfIdentifierRule implements IPredicateRule { + + private IToken fToken; + private String fExtraChars = "_${@"; //$NON-NLS-1$ + + public AutoconfIdentifierRule(IToken token) { + Assert.isNotNull(token); + fToken = token; + } + + public IToken getSuccessToken() { + return fToken; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + + /* + * @see IPredicateRule#evaluate(ICharacterScanner, resume) + */ + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + int c = scanner.read(); + if (Character.isLetterOrDigit((char)c) || fExtraChars.indexOf((char)c) >= 0) { + do { + c = scanner.read(); + } while (Character.isLetterOrDigit((char)c) || fExtraChars.indexOf((char)c) >= 0); + scanner.unread(); + return fToken; + } + scanner.unread(); + return Token.UNDEFINED; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfKeywordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfKeywordDetector.java new file mode 100644 index 00000000000..d82f01092ab --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfKeywordDetector.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class AutoconfKeywordDetector implements IWordDetector { + + /** + * @see IWordDetector#isWordPart(character) + */ + public boolean isWordPart(char character) { + return (Character.isLetter(character) && Character.isLowerCase(character)); + } + + /** + * @see IWordDetector#isWordStart(char) + */ + public boolean isWordStart(char character) { + return (Character.isLetter(character) && Character.isLowerCase(character)); + } + +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfM4WordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfM4WordDetector.java new file mode 100644 index 00000000000..86569e164f6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfM4WordDetector.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class AutoconfM4WordDetector implements IWordDetector { + + public boolean isWordPart(char c) { + // TODO Auto-generated method stub + return (Character.isLetter(c) || + Character.isDigit(c) || c == '_'); + } + + public boolean isWordStart(char c) { + // TODO Auto-generated method stub + return (c == 'm'); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacro.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacro.java new file mode 100644 index 00000000000..6775b5a8379 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacro.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.autotools.ui.editors; + +public class AutoconfMacro implements Comparable<Object> { + + protected String name; + protected String parms; + + public AutoconfMacro(String name, String parms) { + this.name = name; + this.parms = parms; + } + + public String getName() { + return name; + } + + public String getTemplate() { + return name + (hasParms() ? "()" : ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String getParms() { + return parms; + } + + public boolean hasParms() { + return (parms.length() > 0); + } + + public int compareTo(Object x) { + AutoconfMacro y = (AutoconfMacro) x; + return getName().compareTo(y.getName()); + } + + public boolean equals(Object x) { + AutoconfMacro y = (AutoconfMacro)x; + return getName().equals(y.getName()); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroCodeScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroCodeScanner.java new file mode 100644 index 00000000000..6f2a07da536 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroCodeScanner.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; +import org.eclipse.jface.text.rules.WordRule; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; + + +public class AutoconfMacroCodeScanner extends RuleBasedScanner { + + private Map<String, IToken> fTokenMap= new HashMap<String, IToken>(); + private String[] fPropertyNamesColor; + + private int quoteLevel; + + /** + * Preference keys for boolean preferences which are <code>true</code>, + * iff the corresponding token should be rendered bold. + */ + private String[] fPropertyNamesBold; + /** + * Preference keys for boolean preferences which are <code>true</code>, + * iff the corresponding token should be rendered italic. + */ + private String[] fPropertyNamesItalic; + + private static String[] keywords = { + "case", "do", "done", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "esac", "if", "elif", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "else", "fi", "for", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "in", "then" }; //$NON-NLS-1$ //$NON-NLS-2$ + + static final String[] fTokenProperties = new String[] { + ColorManager.AUTOCONF_COMMENT_COLOR, + ColorManager.AUTOCONF_KEYWORD_COLOR, + ColorManager.AUTOCONF_ACMACRO_COLOR, + ColorManager.AUTOCONF_AMMACRO_COLOR, + ColorManager.AUTOCONF_VAR_REF_COLOR, + ColorManager.AUTOCONF_VAR_SET_COLOR, + ColorManager.AUTOCONF_CODESEQ_COLOR, + ColorManager.AUTOCONF_DEFAULT_COLOR, + }; + + public AutoconfMacroCodeScanner() { + + initialize(); + + IToken other= getToken(ColorManager.AUTOCONF_DEFAULT_COLOR); + IToken keyword = getToken(ColorManager.AUTOCONF_KEYWORD_COLOR); + IToken comment= getToken(ColorManager.AUTOCONF_COMMENT_COLOR); + IToken string = getToken(ColorManager.AUTOCONF_DEFAULT_COLOR); + IToken varRef = getToken(ColorManager.AUTOCONF_VAR_REF_COLOR); + IToken acmacro = getToken(ColorManager.AUTOCONF_ACMACRO_COLOR); + IToken ammacro = getToken(ColorManager.AUTOCONF_AMMACRO_COLOR); + IToken code = getToken(ColorManager.AUTOCONF_CODESEQ_COLOR); + + List<IRule> rules= new ArrayList<IRule>(); + + // Add rule for single line comments. + rules.add(new RestrictedEndOfLineRule("dnl", "[]", comment)); //$NON-NLS-1$ + rules.add(new RestrictedEndOfLineRule("#", "[]", comment, '\\')); //$NON-NLS-1$ + + // Add special recursive rule for strings which allows variable + // references to be internally tokenized. + RecursiveSingleLineRule stringRule = + new RecursiveSingleLineRule("\"", "\"", string, '\\'); //$NON-NLS-1$ //$NON-NLS-2$ + stringRule.addRule(new SingleLineRule("${", "}", varRef)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(stringRule); + + // Add rule for variable references + rules.add(new SingleLineRule("${", "}", varRef)); //$NON-NLS-1$ //$NON-NLS-2$ + // Add rule for strings + rules.add(new SingleLineRule("\"", "\"", string, '\\')); //$NON-NLS-1$ //$NON-NLS-2$ + + // Add rule for AC_ macros + rules.add(new AutoconfMacroRule("AC_", new AutoconfMacroWordDetector(), acmacro)); //$NON-NLS-1$ + + // Add rule for AM_ macros + rules.add(new AutoconfMacroRule("AM_", new AutoconfMacroWordDetector(), ammacro)); //$NON-NLS-1$ + + // Add rule for m4_ macros + rules.add(new AutoconfMacroRule("m4_", new AutoconfM4WordDetector(), acmacro)); //$NON-NLS-1$ + + // Add rule for code sequences starting with <<EOF and ending with EOF + rules.add(new InlineDataRule(code)); + + // Add word rule for keywords. + WordRule wordRule= new WordRule(new AutoconfWordDetector(), other); + for (int i= 0; i < keywords.length; i++) + wordRule.addWord(keywords[i], keyword); + rules.add(wordRule); + + // Add word rule for identifier. + rules.add(new AutoconfIdentifierRule(other)); + + // Make sure we don't treat "\#" as comment start. + rules.add(new SingleLineRule("\\#", null, Token.UNDEFINED)); + + rules.add(new WhitespaceRule(new AutoconfWhitespaceDetector())); + + IRule[] result= new IRule[rules.size()]; + rules.toArray(result); + setRules(result); + } + + /* + * @see ITokenScanner#nextToken() + */ + public IToken nextToken() { + int ch = read(); + if (ch == '[') { + incQuoteLevel(); + return getToken(ColorManager.AUTOCONF_DEFAULT_COLOR); + } else if (ch == ']') { + decQuoteLevel(); + return getToken(ColorManager.AUTOCONF_DEFAULT_COLOR); + } + unread(); + return super.nextToken(); + } + + protected Token getToken(String key) { + return (Token) fTokenMap.get(key); + } + + private void addToken(String colorKey, String boldKey, String italicKey) { + fTokenMap.put(colorKey, new Token(createTextAttribute(colorKey, boldKey, italicKey))); + } + + protected String[] getTokenProperties() { + return fTokenProperties; + } + + private int indexOf(String property) { + if (property != null) { + int length= fPropertyNamesColor.length; + for (int i= 0; i < length; i++) { + if (property.equals(fPropertyNamesColor[i]) || property.equals(fPropertyNamesBold[i]) || property.equals(fPropertyNamesItalic[i])) + return i; + } + } + return -1; + } + + public void incQuoteLevel() { + ++quoteLevel; + } + + public void decQuoteLevel() { + --quoteLevel; + } + + public void resetQuoteLevel() { + quoteLevel = 0; + } + + public int getQuoteLevel() { + return quoteLevel; + } + + public boolean affectsBehavior(PropertyChangeEvent event) { + return indexOf(event.getProperty()) >= 0; + } + + public void adaptToPreferenceChange(PropertyChangeEvent event) { + String p= event.getProperty(); + int index= indexOf(p); + Token token= getToken(fPropertyNamesColor[index]); + if (fPropertyNamesColor[index].equals(p)) + adaptToColorChange(event, token); + else if (fPropertyNamesBold[index].equals(p)) + adaptToStyleChange(event, token, SWT.BOLD); + else if (fPropertyNamesItalic[index].equals(p)) + adaptToStyleChange(event, token, SWT.ITALIC); + } + + protected void adaptToColorChange(PropertyChangeEvent event, Token token) { + RGB rgb= null; + Object value= event.getNewValue(); + if (value instanceof RGB) { + rgb= (RGB) value; + } else if (value instanceof String) { + rgb= StringConverter.asRGB((String) value); + } + + if (rgb != null) { + TextAttribute attr= (TextAttribute) token.getData(); + token.setData(new TextAttribute(ColorManager.getDefault().getColor(rgb), attr.getBackground(), attr.getStyle())); + } + } + + protected void adaptToStyleChange(PropertyChangeEvent event, Token token, int styleAttribute) { + if (token == null) { + return; + } + boolean eventValue= false; + Object value= event.getNewValue(); + if (value instanceof Boolean) { + eventValue= ((Boolean) value).booleanValue(); + } else if (IPreferenceStore.TRUE.equals(value)) { + eventValue= true; + } + + TextAttribute attr= (TextAttribute) token.getData(); + boolean activeValue= (attr.getStyle() & styleAttribute) == styleAttribute; + if (activeValue != eventValue) { + token.setData(new TextAttribute(attr.getForeground(), attr.getBackground(), eventValue ? attr.getStyle() | styleAttribute : attr.getStyle() & ~styleAttribute)); + } + } + + protected TextAttribute createTextAttribute(String colorID, String boldKey, String italicKey) { + Color color= null; + if (colorID != null) { + color= AutoconfEditor.getPreferenceColor(colorID); + } + IPreferenceStore store= AutotoolsPlugin.getDefault().getPreferenceStore(); + int style= store.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL; + if (store.getBoolean(italicKey)) { + style |= SWT.ITALIC; + } + return new TextAttribute(color, null, style); + } + + /** + * Must be called after the constructor has been called. + */ + public final void initialize() { + + resetQuoteLevel(); + fPropertyNamesColor= getTokenProperties(); + int length= fPropertyNamesColor.length; + fPropertyNamesBold= new String[length]; + fPropertyNamesItalic= new String[length]; + + for (int i= 0; i < length; i++) { + fPropertyNamesBold[i]= fPropertyNamesColor[i] + AutotoolsEditorPreferenceConstants.EDITOR_BOLD_SUFFIX; + fPropertyNamesItalic[i]= fPropertyNamesColor[i] + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX; + addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i]); + } + } + + /* + * @see ICharacterScanner#unread() + */ + public void unread() { + --fOffset; + fColumn = UNDEFINED; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroContentAssistProcessor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroContentAssistProcessor.java new file mode 100644 index 00000000000..83fb60ce555 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroContentAssistProcessor.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2006, 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.cdt.autotools.ui.editors; + +import java.util.ArrayList; + +import org.eclipse.cdt.internal.autotools.ui.text.hover.AutoconfTextHover; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; +import org.eclipse.jface.text.rules.ICharacterScanner; + + +public class AutoconfMacroContentAssistProcessor implements + IContentAssistProcessor { + + protected ICharacterScanner scanner; + protected AutoconfEditor editor; + + public AutoconfMacroContentAssistProcessor(ICharacterScanner scanner, AutoconfEditor editor) { + this.scanner = scanner; + this.editor = editor; + } + + private int computeMacroStart(IDocument document, int offset) { + try { + while (Character.isJavaIdentifierPart(document.getChar(offset - 1))) { + --offset; + } + } catch (BadLocationException e) { + // Do nothing + } + return offset; + } + + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, + int offset) { + + IDocument document = viewer.getDocument(); + String prefix = ""; //$NON-NLS-1$ + AutoconfMacro[] macros = AutoconfTextHover.getMacroList(editor); + try { + int macroStart = computeMacroStart(document, offset); + if (macroStart < offset) { + prefix = prefix + document.get(macroStart, offset - macroStart); + } + } catch (BadLocationException e) { + // Do nothing. Leave prefix empty. + } + ICompletionProposal[] result = null; + if (macros != null) { + ArrayList<ICompletionProposal> validList = new ArrayList<ICompletionProposal>(); + for (int i = 0; i < macros.length; ++i) { + String name = macros[i].getName(); + if (name.length() >= prefix.length()) { + if (name.startsWith(prefix)) { + String template = macros[i].getTemplate(); + int cursorPos = template.length(); + int prefixLen = prefix.length(); + if (template.charAt(template.length() - 1) == ')') + cursorPos -= 1; + AutoconfMacroProposalContextInformation ci = null; + if (macros[i].hasParms()) { + // Provide parameter info as context information that + // is tied to the completion proposal. + ci = new AutoconfMacroProposalContextInformation(macros[i].getParms(), macros[i].getParms()); + ci.setContextInformationPosition(offset - prefixLen + cursorPos - 1); + } + ICompletionProposal cp = new CompletionProposal(template, offset - prefixLen, prefixLen, cursorPos, null, + name, ci, AutoconfTextHover.getIndexedInfo(name, editor)); + validList.add(cp); + } + } + } + result = new ICompletionProposal[validList.size()]; + result = (ICompletionProposal[])validList.toArray(result); + } + return result; + } + + public IContextInformation[] computeContextInformation(ITextViewer viewer, + int offset) { + // TODO Auto-generated method stub + return null; + } + + public char[] getCompletionProposalAutoActivationCharacters() { + // TODO Auto-generated method stub + return null; + } + + public char[] getContextInformationAutoActivationCharacters() { + // TODO Auto-generated method stub + return null; + } + + public IContextInformationValidator getContextInformationValidator() { + // TODO Auto-generated method stub + return new AutoconfMacroParameterListValidator(); + } + + public String getErrorMessage() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroDamagerRepairer.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroDamagerRepairer.java new file mode 100644 index 00000000000..e86c6e27b29 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroDamagerRepairer.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.ITokenScanner; + +public class AutoconfMacroDamagerRepairer extends DefaultDamagerRepairer { + + public final static String UNMATCHED_RIGHT_PARENTHESIS = "UnmatchedRightParenthesis"; //$NON-NLS-1$ + public final static String UNMATCHED_LEFT_PARENTHESIS = "UnmatchedLeftParenthesis"; //$NON-NLS-1$ + public final static String UNMATCHED_RIGHT_QUOTE = "UnmatchedRightQuote"; //$NON-NLS-1$ + public final static String UNMATCHED_LEFT_QUOTE = "UnmatchedLeftQuote"; //$NON-NLS-1$ + + /** + * Creates a damager/repairer that uses the given scanner. The scanner may not be <code>null</code> + * and is assumed to return only token that carry text attributes. + * + * @param scanner the token scanner to be used, may not be <code>null</code> + */ + public AutoconfMacroDamagerRepairer(ITokenScanner scanner) { + super(scanner); + } + + /* + * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean) + */ + public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) { + // In the case of a partition with multiline rules, we will punt to + // reparse the entire partition because we don't know if the line being + // edited is in the middle of an area covered by a multiline rule. In + // such a case, we need to back up and find the start sequence of the + // rule. It is easiest to just reparse the whole partition. + return partition; + } + + /* + * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion) + */ + public void createPresentation(TextPresentation presentation, ITypedRegion region) { + +// int offset = region.getOffset(); +// int length = region.getLength(); + + super.createPresentation(presentation, region); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroParameterListValidator.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroParameterListValidator.java new file mode 100644 index 00000000000..42f412e407b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroParameterListValidator.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.autotools.ui.editors; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationPresenter; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; + +/** + * This class provides the macro call parameter parsing for the Autoconf Editor hover + * It is modified from the CDT class CParameterListValidator + * + * @author jjohnstn + * + */ +public class AutoconfMacroParameterListValidator implements IContextInformationValidator, IContextInformationPresenter { + private int fPosition; + private ITextViewer fViewer; + private IContextInformation fInformation; + + private int fCurrentParameter; + + public AutoconfMacroParameterListValidator() { + } + + /** + * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int) + * @see IContextInformationPresenter#install(IContextInformation, ITextViewer, int) + */ + public void install(IContextInformation info, ITextViewer viewer, int documentPosition) { + + fPosition= documentPosition; + fViewer= viewer; + fInformation= info; + + fCurrentParameter= -1; + } + + private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException { + while (pos < end) { + char curr= d.getChar(pos); + pos++; + if (curr == '\\') { + // ignore escaped characters + pos++; + } else if (curr == ch) { + return pos; + } + } + return end; + } + + private int getCharCount(IDocument document, int start, int end, + char increment, char decrement, boolean considerNesting) throws BadLocationException { + + Assert.isTrue((increment != 0 || decrement != 0) && increment != decrement); + + // There are two nesting levels to worry about. Arguments can be + // quoted with [] which means to treat the contents as one arg. + // As well, macro calls can be nested within macro calls so we + // have to handle parentheses. + int macroQuotingLevel = 0; // Pertaining to '[' and ']' quoted args. + int macroNestingLevel = -1; // Set to -1 to take into account first ( for function call + int charCount = 0; + while (start < end) { + char curr = document.getChar(start++); + switch (curr) { + case 'd': + if (start < end - 2) { + char next= document.getChar(start); + if (next == 'n') { + // a comment starts, advance to the comment end + next = document.getChar(start + 1); + if (next == 'l') + // dnl-comment: nothing to do anymore on this line + start= end; + } + } + break; + case '"': + case '\'': + start= getStringEnd(document, start, end, curr); + break; + default: + if ('[' == curr) + ++ macroQuotingLevel; + else if (']' == curr) + -- macroQuotingLevel; + if (macroQuotingLevel != 0) + break; + if (considerNesting) { + if ('(' == curr) + ++ macroNestingLevel; + else if (')' == curr) { + -- macroNestingLevel; + } + if (macroNestingLevel != 0) + break; + } + if (increment != 0) { + if (curr == increment) { + ++charCount; + } + } + + if (decrement != 0) { + if (curr == decrement) { + -- charCount; + } + } + } + } + + return charCount; + } + + /** + * @see IContextInformationValidator#isContextInformationValid(int) + */ + public boolean isContextInformationValid(int position) { + + try { + if (position < fPosition) + return false; + + IDocument document= fViewer.getDocument(); + IRegion line= document.getLineInformationOfOffset(fPosition); + + if (position > line.getOffset() + line.getLength()) + return false; + + return (getCharCount(document, fPosition, position, '(', ')', false) >= 0); + + } catch (BadLocationException x) { + return false; + } + } + + /** + * @see IContextInformationPresenter#updatePresentation(int, TextPresentation) + */ + public boolean updatePresentation(int position, TextPresentation presentation) { + + int currentParameter= -1; + try { + currentParameter= getCharCount(fViewer.getDocument(), fPosition, position, ',', (char) 0, true); + } catch (BadLocationException x) { + return false; + } + + if (fCurrentParameter != -1) { + if (currentParameter == fCurrentParameter) + return false; + } + + presentation.clear(); + fCurrentParameter= currentParameter; + + //Don't presume what has been done to the string, rather use as is + String s= fInformation.getInformationDisplayString(); + + //@@@ This is obviously going to have problems with functions such + //int myfunction(int (*function_argument)(void * extra, int param), void * extra) + //int myfunction(/*A comment, indeed */int a); + int start= 0; + int occurrences= 0; + while (occurrences < fCurrentParameter) { + int found= s.indexOf(',', start); + if (found == -1) + break; + start= found + 1; + ++ occurrences; + } + + if (occurrences < fCurrentParameter) { + presentation.addStyleRange(new StyleRange(0, s.length(), null, null, SWT.NORMAL)); + return true; + } + + if (start == -1) + start= 0; + + int end= s.indexOf(',', start); + if (end == -1) + end= s.length(); + + if (start > 0) + presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL)); + + if (end > start) + presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD)); + + if (end < s.length()) + presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL)); + + return true; + } +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroPartitionRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroPartitionRule.java new file mode 100644 index 00000000000..fb47b158ed2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroPartitionRule.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; + + +public class AutoconfMacroPartitionRule implements IPredicateRule { + /** + * The default token to be returned on success and if nothing else has been + * specified. + */ + protected IToken token; + + private IWordDetector generalMacroWordDetector; + private IWordDetector m4MacroWordDetector; + protected IWordDetector fDetector; + protected IWhitespaceDetector fWsDetector = new AutoconfWhitespaceDetector(); + + /** The column constraint */ + protected int fColumn = UNDEFINED; + + /** Internal setting for the un-initialized column constraint */ + protected static final int UNDEFINED = -1; + + /** Buffer used for pattern detection */ + private StringBuffer fBuffer = new StringBuffer(); + + public AutoconfMacroPartitionRule(IToken inToken) { + token = inToken; + generalMacroWordDetector = new AutoconfMacroWordDetector(); + m4MacroWordDetector = new AutoconfM4WordDetector(); + } + + public IToken getSuccessToken() { + return token; + } + + protected void matchParentheses(ICharacterScanner scanner) { + boolean finished = false; + int depth = 1; + int quoteDepth = 0; + int c = scanner.read(); + while (!finished && c != ICharacterScanner.EOF) { + if (c == '[') { + ++quoteDepth; + } + else if (c == ']') { + --quoteDepth; + if (quoteDepth < 0) + finished = true; + } + if (quoteDepth == 0) { + if (c == ')') { + --depth; + if (depth <= 0) + finished = true; + } + else if (c == '(') { + ++depth; + } + } + c = scanner.read(); + } + } + + public IToken evaluate(ICharacterScanner scanner, boolean resume) { +// if (resume) +// return Token.UNDEFINED; + return evaluate(scanner); + } + + public IToken evaluate(ICharacterScanner scanner) { + int c = scanner.read(); + fBuffer.setLength(0); + + fBuffer.append((char)c); + if (c == 'A') { + c = scanner.read(); + fBuffer.append((char)c); + if (c != 'C' && c != 'H' && c != 'M') { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + fDetector = generalMacroWordDetector; + } else if (c == 'm') { + c = scanner.read(); + fBuffer.append((char)c); + if (c != 4) { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + fDetector = m4MacroWordDetector; + } else { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + + c = scanner.read(); + while (c != ICharacterScanner.EOF + && fDetector.isWordPart((char) c)) { + fBuffer.append((char) c); + c = scanner.read(); + } + + if (c != ICharacterScanner.EOF) { + if (c == ';' || fWsDetector.isWhitespace((char)c)) { + // We are done + } + else if (c == '(') { + matchParentheses(scanner); + } + else { + scanner.unread(); + unreadBuffer(scanner); + return Token.UNDEFINED; + } + } + + scanner.unread(); + return token; + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner + * the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i = fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroProposalContextInformation.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroProposalContextInformation.java new file mode 100644 index 00000000000..01cec3d4140 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroProposalContextInformation.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + *******************************************************************************/ +/* + * Created on May 6, 2004 + */ +package org.eclipse.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationExtension; +import org.eclipse.swt.graphics.Image; + +/** + * @author aniefer + */ +public class AutoconfMacroProposalContextInformation implements IContextInformation, IContextInformationExtension { + /** The name of the context */ + private String fContextDisplayString; + /** The information to be displayed */ + private String fInformationDisplayString; + /** The position to display the information */ + private int fInformationPosition; + /** The image to be displayed */ + private Image fImage; + + /** + * Creates a new context information without an image. + * + * @param contextDisplayString the string to be used when presenting the context + * @param informationDisplayString the string to be displayed when presenting the context information + */ + public AutoconfMacroProposalContextInformation(String contextDisplayString, String informationDisplayString) { + this(null, contextDisplayString, informationDisplayString); + } + + /** + * Creates a new context information with an image. + * + * @param image the image to display when presenting the context information + * @param contextDisplayString the string to be used when presenting the context + * @param informationDisplayString the string to be displayed when presenting the context information, + * may not be <code>null</code> + */ + public AutoconfMacroProposalContextInformation(Image image, String contextDisplayString, String informationDisplayString) { + //Assert.isNotNull(informationDisplayString); + fImage= image; + fContextDisplayString= contextDisplayString; + fInformationDisplayString= informationDisplayString; + } + + /* + * @see IContextInformation#equals(Object) + */ + public boolean equals(Object object) { + if (object instanceof IContextInformation) { + IContextInformation contextInformation= (IContextInformation) object; + boolean equals= fInformationDisplayString.equalsIgnoreCase(contextInformation.getInformationDisplayString()); + if (fContextDisplayString != null) + equals= equals && fContextDisplayString.equalsIgnoreCase(contextInformation.getContextDisplayString()); + return equals; + } + return false; + } + + public int hashCode() { + String combined = fInformationDisplayString.toLowerCase().concat(fContextDisplayString.toLowerCase()); + return combined.hashCode(); + } + + /* + * @see IContextInformation#getInformationDisplayString() + */ + public String getInformationDisplayString() { + return fInformationDisplayString; + } + + /* + * @see IContextInformation#getImage() + */ + public Image getImage() { + return fImage; + } + + /* + * @see IContextInformation#getContextDisplayString() + */ + public String getContextDisplayString() { + if (fContextDisplayString != null) + return fContextDisplayString; + return fInformationDisplayString; + } + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContextInformationExtension#getContextInformationPosition() + */ + public int getContextInformationPosition() { + return fInformationPosition; + } + + public void setContextInformationPosition( int pos ){ + fInformationPosition = pos; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroRule.java new file mode 100644 index 00000000000..66f3b361d43 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroRule.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; + +public class AutoconfMacroRule implements IRule { + /** + * The default token to be returned on success and if nothing else has been + * specified. + */ + protected IToken token; + + protected IWordDetector fDetector; + protected IWhitespaceDetector fWsDetector = new AutoconfWhitespaceDetector(); + + /** The column constraint */ + protected int fColumn = UNDEFINED; + + /** Internal setting for the un-initialized column constraint */ + protected static final int UNDEFINED = -1; + + /** Buffer used for pattern detection */ + private StringBuffer fBuffer = new StringBuffer(); + + private String fStartingSequence; + + public AutoconfMacroRule(String startingSequence, + IWordDetector detector, IToken inToken) { + token = inToken; + fDetector = detector; + fStartingSequence = startingSequence; + } + + public IToken evaluate(ICharacterScanner scanner) { + int c = scanner.read(); + fBuffer.setLength(0); + + for (int i = 0; i < fStartingSequence.length(); i++) { + fBuffer.append((char) c); + if (fStartingSequence.charAt(i) != c) { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + c = scanner.read(); + } + + while (c != ICharacterScanner.EOF + && fDetector.isWordPart((char) c)) { + fBuffer.append((char) c); + c = scanner.read(); + } + + if (c != ICharacterScanner.EOF && c != '(' && c != ';' + && !fWsDetector.isWhitespace((char)c)) { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + + scanner.unread(); + return token; + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner + * the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i = fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroWordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroWordDetector.java new file mode 100644 index 00000000000..4ec3b2c95a4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfMacroWordDetector.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class AutoconfMacroWordDetector implements IWordDetector { + + public boolean isWordPart(char c) { + return ((Character.isLetter(c) && Character.isUpperCase(c)) || + Character.isDigit(c) || c == '_'); + } + + public boolean isWordStart(char c) { + return (c == 'A'); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPKGWordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPKGWordDetector.java new file mode 100644 index 00000000000..2d5145a802e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPKGWordDetector.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (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: + * Ed Swartz (Nokia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class AutoconfPKGWordDetector implements IWordDetector { + + public boolean isWordPart(char c) { + return ((Character.isLetter(c) && Character.isUpperCase(c)) || + Character.isDigit(c) || c == '_'); + } + + public boolean isWordStart(char c) { + return (c == 'P'); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPartitionScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPartitionScanner.java new file mode 100644 index 00000000000..2082170eff4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPartitionScanner.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.rules.EndOfLineRule; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; + +public class AutoconfPartitionScanner extends RuleBasedPartitionScanner { + + public final static String AUTOCONF_MACRO = "autoconf_macro"; //$NON-NLS-1$ + public final static String AUTOCONF_COMMENT = "autoconf_comment"; //$NON-NLS-1$ + final static String[] AUTOCONF_PARTITION_TYPES= + new String[] { AUTOCONF_MACRO, AUTOCONF_COMMENT }; + + /** + * Creates the partitioner and sets up the appropriate rules. + */ + public AutoconfPartitionScanner() { + super(); + + List<IRule> rules= new ArrayList<IRule>(); + Token macro = new Token(AUTOCONF_MACRO); + Token comment = new Token(AUTOCONF_COMMENT); + + // Add rule for target bodies. + rules.add(new AutoconfMacroPartitionRule(macro)); + + + rules.add(new EndOfLineRule("dnl", comment)); //$NON-NLS-1$ + rules.add(new SingleLineRule("\\#", null, Token.UNDEFINED)); + rules.add(new EndOfLineRule("#", comment, '\\')); //$NON-NLS-1$ + + // We want to process identifiers that might have macro + // names inside them. + rules.add(new AutoconfIdentifierRule(Token.UNDEFINED)); + + IPredicateRule[] result= new IPredicateRule[rules.size()]; + rules.toArray(result); + setPredicateRules(result); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPartitioner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPartitioner.java new file mode 100644 index 00000000000..f1b64c70505 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfPartitioner.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2006, 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.rules.FastPartitioner; +import org.eclipse.jface.text.rules.IPartitionTokenScanner; + +public class AutoconfPartitioner extends FastPartitioner { + + public AutoconfPartitioner(IPartitionTokenScanner scanner, String[] legalContentTypes) { + // TODO Auto-generated constructor stub + super(scanner, legalContentTypes); + } + + public void connect(IDocument document, int blah) { + super.connect(document); + } + + // To optionally show partitions, we must do so by overriding the computePartitioning + // method. We cannot do it at connect time because the document may be zero length + // at the time and we will end up getting default partitioning from then on. + public ITypedRegion[] computePartitioning(int offset, int length, + boolean includeZeroLength) { + ITypedRegion[] regions = super.computePartitioning(offset, length, includeZeroLength); + // Uncomment the following line to see partitioning. +// printPartitions(regions); + return regions; + } + + public void printPartitions(ITypedRegion[] partitions) + { + StringBuffer buffer = new StringBuffer(); + + for (int i = 0; i < partitions.length; i++) + { + try + { + buffer.append("Partition type: " + partitions[i].getType() //$NON-NLS-1$ + + ", offset: " + partitions[i].getOffset() //$NON-NLS-1$ + + ", length: " + partitions[i].getLength()); //$NON-NLS-1$ + buffer.append("\n"); //$NON-NLS-1$ + buffer.append("Text:\n"); //$NON-NLS-1$ + buffer.append(super.fDocument.get(partitions[i].getOffset(), partitions[i].getLength())); + buffer.append("\n---------------------------\n\n\n"); //$NON-NLS-1$ + } + catch (BadLocationException e) + { + e.printStackTrace(); + } + } + System.out.print(buffer); + } +}
\ No newline at end of file diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfReconcilingStrategy.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfReconcilingStrategy.java new file mode 100644 index 00000000000..118c19dcd18 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfReconcilingStrategy.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import org.eclipse.cdt.autotools.ui.editors.outline.AutoconfContentOutlinePage; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfParser; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.ui.texteditor.IDocumentProvider; + + +public class AutoconfReconcilingStrategy implements IReconcilingStrategy { + + AutoconfContentOutlinePage outline; +// int lastRegionOffset; + AutoconfEditor editor; + IDocumentProvider documentProvider; + + public AutoconfReconcilingStrategy(AutoconfEditor editor) { + outline= editor.getOutlinePage(); +// lastRegionOffset = Integer.MAX_VALUE; + this.editor = editor; + documentProvider = editor.getDocumentProvider(); + } + + public void reconcile(IRegion partition) { + try { + AutoconfParser parser = editor.getAutoconfParser(); + ((AutoconfErrorHandler)parser.getErrorHandler()).removeAllExistingMarkers(); + + editor.setRootElement(parser.parse(documentProvider.getDocument(editor.getEditorInput()))); + outline.update(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + // TODO Auto-generated method stub + + } + + public void setDocument(IDocument document) { + // TODO Auto-generated method stub + + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfSourceViewerConfiguration.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfSourceViewerConfiguration.java new file mode 100644 index 00000000000..97ac3e234a7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfSourceViewerConfiguration.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import org.eclipse.cdt.internal.autotools.ui.text.hover.AutoconfTextHover; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.reconciler.MonoReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; + + +public class AutoconfSourceViewerConfiguration extends + TextSourceViewerConfiguration { + + private ITextHover acHover; + private IAnnotationHover aaHover; + private AutoconfEditor fEditor; + + public AutoconfSourceViewerConfiguration(IPreferenceStore prefs, AutoconfEditor editor) { + super(prefs); + fEditor = editor; + } + + /* + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer) + */ + public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) { + return AutoconfEditor.AUTOCONF_PARTITIONING; + } + + /* + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer) + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + ContentAssistant assistant = new ContentAssistant(); + + IContentAssistProcessor macroContentAssistProcessor = + new AutoconfMacroContentAssistProcessor(new AutoconfMacroCodeScanner(), fEditor); + assistant.setContentAssistProcessor(macroContentAssistProcessor, AutoconfPartitionScanner.AUTOCONF_MACRO); + assistant.setContentAssistProcessor(macroContentAssistProcessor, IDocument.DEFAULT_CONTENT_TYPE); + assistant.enableAutoActivation(true); + assistant.setAutoActivationDelay(500); + assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY); + assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE); + assistant.setInformationControlCreator(AutoconfTextHover.getInformationControlCreator()); + + return assistant; + } + + /* (non-Javadoc) + * Method declared on SourceViewerConfiguration + */ + public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { + return new String[] { IDocument.DEFAULT_CONTENT_TYPE, + AutoconfPartitionScanner.AUTOCONF_MACRO, + AutoconfPartitionScanner.AUTOCONF_COMMENT}; + } + + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + if (acHover == null) + acHover = new AutoconfTextHover(fEditor); + return acHover; + } + + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + if (aaHover == null) + aaHover = new AutoconfAnnotationHover(); + return aaHover; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer) + */ + public IReconciler getReconciler(ISourceViewer sourceViewer) { + MonoReconciler reconciler= new MonoReconciler(new AutoconfReconcilingStrategy(fEditor), false); + reconciler.setDelay(1000); + reconciler.setProgressMonitor(new NullProgressMonitor()); + return reconciler; + } + /* (non-Javadoc) + * Method declared on SourceViewerConfiguration + */ + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + + DefaultDamagerRepairer dr= new AutoconfMacroDamagerRepairer(new AutoconfMacroCodeScanner()); + reconciler.setDamager(dr, AutoconfPartitionScanner.AUTOCONF_MACRO); + reconciler.setRepairer(dr, AutoconfPartitionScanner.AUTOCONF_MACRO); + + dr= new DefaultDamagerRepairer(new AutoconfCodeScanner()); + reconciler.setDamager(dr, AutoconfPartitionScanner.AUTOCONF_COMMENT); + reconciler.setRepairer(dr, AutoconfPartitionScanner.AUTOCONF_COMMENT); + + dr= new MultilineRuleDamagerRepairer(new AutoconfCodeScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + + return reconciler; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfWhitespaceDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfWhitespaceDetector.java new file mode 100644 index 00000000000..d89807999e4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfWhitespaceDetector.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.IWhitespaceDetector; + +public class AutoconfWhitespaceDetector implements IWhitespaceDetector { + + public boolean isWhitespace(char c) { + return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfWordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfWordDetector.java new file mode 100644 index 00000000000..1ae4a70f1be --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/AutoconfWordDetector.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class AutoconfWordDetector implements IWordDetector { + + private static final String correctStartSpecChars = "%*().><"; //$NON-NLS-1$ + private static final String correctSpecChars = "@$/\\><"; //$NON-NLS-1$ + + /** + * @see IWordDetector#isWordPart(character) + */ + public boolean isWordPart(char character) { + return Character.isLetterOrDigit(character) || (correctSpecChars.indexOf(character) >= 0); + } + + /** + * @see IWordDetector#isWordStart(char) + */ + public boolean isWordStart(char character) { + return Character.isLetterOrDigit(character) || (correctStartSpecChars.indexOf(character) >= 0); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolEditorActionDefinitionIds.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolEditorActionDefinitionIds.java new file mode 100644 index 00000000000..c45d8a5b342 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolEditorActionDefinitionIds.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2006, 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.cdt.autotools.ui.editors; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; + +public interface IAutotoolEditorActionDefinitionIds { + public static final String SHOW_TOOLTIP = AutotoolsUIPlugin.getUniqueIdentifier() + ".editors.text.show.tooltip"; //$NON-NLS-1$ +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolHelpContextIds.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolHelpContextIds.java new file mode 100644 index 00000000000..92a8c462dc6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolHelpContextIds.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2006, 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.cdt.autotools.ui.editors; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; + +public interface IAutotoolHelpContextIds { + public static final String PREFIX = AutotoolsUIPlugin.getUniqueIdentifier(); + public static final String AC_EDITOR_VIEW = PREFIX + "autoconf_editor"; //$NON-NLS-1$ + public static final String SHOW_TOOLTIP_ACTION = PREFIX + "show_tooltip_action"; //$NON-NLS-1$ + public static final String CONTENT_ASSIST = PREFIX + "content_assist"; //$NON-NLS-1$ +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolsEditor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolsEditor.java new file mode 100644 index 00000000000..d71a4c638e0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/IAutotoolsEditor.java @@ -0,0 +1,16 @@ +package org.eclipse.cdt.autotools.ui.editors; + +import org.eclipse.cdt.internal.autotools.ui.editors.automake.IReconcilingParticipant; +import org.eclipse.ui.texteditor.ITextEditor; + + +public interface IAutotoolsEditor extends ITextEditor { + + /** + * Adds the given listener. + * Has no effect if an identical listener was not already registered. + * + * @param listener The reconcile listener to be added + */ + public void addReconcilingParticipant(IReconcilingParticipant listener); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/InlineDataRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/InlineDataRule.java new file mode 100644 index 00000000000..449a611a447 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/InlineDataRule.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; + +public class InlineDataRule implements IRule { + /** + * The default token to be returned on success and if nothing else has been + * specified. + */ + protected IToken token; + + protected IWordDetector fDetector; + protected IWhitespaceDetector fWsDetector = new AutoconfWhitespaceDetector(); + + /** The column constraint */ + protected int fColumn = UNDEFINED; + + /** Internal setting for the un-initialized column constraint */ + protected static final int UNDEFINED = -1; + + /** Buffer used for pattern detection */ + private StringBuffer fBuffer = new StringBuffer(); + + private String fStartingSequence = "<<"; + + public InlineDataRule(IToken inToken) { + token = inToken; + } + + // Confirm an EOL delimeter after already matching first delimeter character. + protected boolean confirmDelimeter(ICharacterScanner scanner, char[] delimeter) { + int c = scanner.read(); + StringBuffer buffer = new StringBuffer(); + buffer.append((char)c); + for (int i = 1; i < delimeter.length; ++i) { + if (c == delimeter[i]) { + c = scanner.read(); + buffer.append((char)c); + } else { + for (int j = buffer.length() - 1; j >= 0; j--) + scanner.unread(); + return false; + } + } + scanner.unread(); + return true; + } + public IToken evaluate(ICharacterScanner scanner) { + int c = scanner.read(); + fBuffer.setLength(0); + + // Looking for <<WORD or <<-WORD or <<'WORD' at end of line. + for (int i = 0; i < fStartingSequence.length(); i++) { + fBuffer.append((char) c); + if (fStartingSequence.charAt(i) != c) { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + c = scanner.read(); + } + + char[][] lineDelimeters = scanner.getLegalLineDelimiters(); + StringBuffer endMarkerBuffer = new StringBuffer(); + if (c == '-') { + fBuffer.append((char)c); + c = scanner.read(); + } else if (c == '\'') { + fBuffer.append((char)c); + c = scanner.read(); + } + + while (c != ICharacterScanner.EOF && + Character.isJavaIdentifierPart((char)c) && + c != '\'') { + fBuffer.append((char)c); + endMarkerBuffer.append((char)c); + c = scanner.read(); + } + + if (c == '\'') { + fBuffer.append((char)c); + c = scanner.read(); + } + + if (endMarkerBuffer.length() == 0) { + unreadBuffer(scanner); + return Token.UNDEFINED; + } + + // At this point we read until we find id by itself on its own line + boolean eol = false; + boolean finished = false; + boolean foundMarker = false; + String endMarker = endMarkerBuffer.toString(); + while (!finished && c != ICharacterScanner.EOF) { + for (int i = 0; i < lineDelimeters.length; ++i) { + if (c == lineDelimeters[i][0]) { + if (confirmDelimeter(scanner, lineDelimeters[i])) { + c = scanner.read(); + eol = true; + break; + } + } + } + if (eol) { + eol = false; + if (foundMarker) { + // We get here if we have found the marker by itself + // on the line + finished = true; + } else { + foundMarker = false; + int j = 0; + while (j < endMarker.length()) { + if (c == endMarker.charAt(j)) { + c = scanner.read(); + ++j; + } else { + break; + } + } + if (j == endMarker.length()) { + foundMarker = true; + } + } + } else { + // otherwise ignore all other characters + eol = false; + foundMarker = false; + c = scanner.read(); + } + } + + // unread last character + scanner.unread(); + return token; + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner + * the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i = fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/MultilineRuleDamagerRepairer.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/MultilineRuleDamagerRepairer.java new file mode 100644 index 00000000000..ba68d044bf7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/MultilineRuleDamagerRepairer.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.ITokenScanner; + +public class MultilineRuleDamagerRepairer extends DefaultDamagerRepairer { + + + /** + * Creates a damager/repairer that uses the given scanner. The scanner may not be <code>null</code> + * and is assumed to return only token that carry text attributes. + * + * @param scanner the token scanner to be used, may not be <code>null</code> + */ + public MultilineRuleDamagerRepairer(ITokenScanner scanner) { + super(scanner); + } + + /* + * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean) + */ + public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) { + // In the case of a partition with multiline rules, we will punt to + // reparse the entire partition because we don't know if the line being + // edited is in the middle of an area covered by a multiline rule. In + // such a case, we need to back up and find the start sequence of the + // rule. It is easiest to just reparse the whole partition. + return partition; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/ParseException.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/ParseException.java new file mode 100644 index 00000000000..5cd632099c1 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/ParseException.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +public class ParseException extends Exception { + + static final long serialVersionUID = 1; + String message; + int severity; + int lineNumber; + int startColumn; + int endColumn; + 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 lineNumber, int startColumn, int endColumn, int severity) { + super(); + this.message = message; + 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; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/RecursiveSingleLineRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/RecursiveSingleLineRule.java new file mode 100644 index 00000000000..356972c058b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/RecursiveSingleLineRule.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2006 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.cdt.autotools.ui.editors; + +import java.util.ArrayList; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; + +public class RecursiveSingleLineRule extends SingleLineRule { + + private ArrayList<IRule> rules; + private int evalIndex; + private int startIndex; + private int endIndex; + private int endBoundary; + private String startSequence; + private String endSequence; + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + */ + public RecursiveSingleLineRule(String startSequence, String endSequence, IToken token) { + this(startSequence, endSequence, token, (char) 0); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public RecursiveSingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) { + this(startSequence, endSequence, token, escapeCharacter, false); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @since 2.1 + */ + public RecursiveSingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF) { + super(startSequence, endSequence, token, escapeCharacter, breaksOnEOF); + this.startSequence = startSequence; + this.endSequence = endSequence; + rules = new ArrayList<IRule>(); + startIndex = 0; + endIndex = 0; + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. In addition, an escape character immediately before an + * end of line can be set to continue the line. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @param escapeContinuesLine indicates whether the specified escape character is used for line + * continuation, so that an end of line immediately after the escape character does not + * terminate the line, even if <code>breakOnEOL</code> is true + * @since 3.0 + */ + public RecursiveSingleLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOF, boolean escapeContinuesLine) { + super(startSequence, endSequence, token, escapeCharacter, breaksOnEOF, escapeContinuesLine); + this.startSequence = startSequence; + this.endSequence = endSequence; + rules = new ArrayList<IRule>(); + startIndex = 0; + endIndex = 0; + } + + public void addRule(SingleLineRule rule) { + rules.add(rule); + } + + public IToken getSuccessToken() { + // We need to be aware of what success token we are referring to. + // The current internal rule index will help us determine which + // one. + if (evalIndex < rules.size()) { + SingleLineRule x = (SingleLineRule)rules.get(evalIndex); + return x.getSuccessToken(); + } + return super.getSuccessToken(); + } + + protected void backupScanner(ICharacterScanner scanner, int position) { + int count = scanner.getColumn() - position; + while (count-- > 0) + scanner.unread(); + } + + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + int column = scanner.getColumn(); + // Check if we are at EOF, in which case rules don't hold + if (column < 0) + return Token.UNDEFINED; + if (!resume) { + evalIndex = 0; + // Check if we are within outer rule boundaries. + if (column >= endIndex || column < startIndex) { + // If not, then we should evaluate to see if the + // outer rule is true starting at the current position. + startIndex = scanner.getColumn(); + if (super.evaluate(scanner, false) != Token.UNDEFINED) { + // Outer rule is true for a section. Now we can + // set the boundaries for the internal rules. + // End boundary for internal rules is the start of + // the end sequence. + endIndex = scanner.getColumn(); + endBoundary = endIndex - endSequence.length(); + // Back up scanner to just after start sequence. + backupScanner(scanner, startIndex + startSequence.length()); + return super.getSuccessToken(); + } + else + // Outer rule doesn't hold. + return Token.UNDEFINED; + } + } + + // At this point, we want to subdivide up the area covered by the + // outer rule into success tokens for internal areas separated by + // areas of the outer rule. + + int start = scanner.getColumn(); + column = start; + while (column < endBoundary) { + while (evalIndex < rules.size()) { + SingleLineRule x = (SingleLineRule)rules.get(evalIndex); + IToken token = x.evaluate(scanner, false); + if (!token.isUndefined()) { + // Found internal token. If we had to read to get + // to the start of the internal token, then back up + // the scanner to the start of the internal token and + // return the initial read area as part of an outer token. + // Otherwise, return the internal token. + if (column == start) { + evalIndex = 0; + return token; + } else { + backupScanner(scanner, column); + return super.getSuccessToken(); + } + } + ++evalIndex; + } + evalIndex = 0; + scanner.read(); + ++column; + } + + // Outside internal area. Read until end of outer area and return + // outer token. + while (column++ < endIndex) + scanner.read(); + startIndex = 0; + endIndex = 0; + return super.getSuccessToken(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/RestrictedEndOfLineRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/RestrictedEndOfLineRule.java new file mode 100644 index 00000000000..826b89afeab --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/RestrictedEndOfLineRule.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors; + +import java.util.ArrayList; + +import org.eclipse.jface.text.rules.EndOfLineRule; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; + +public class RestrictedEndOfLineRule extends EndOfLineRule { + + private ArrayList<IRule> rules; + private int startIndex; + private int endIndex; + private String startSequence; + private String restrictedChars; + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param restrictedChars chars that stop the sequence + * @param token the token to be returned on success + */ + public RestrictedEndOfLineRule(String startSequence, String restrictedChars, IToken token) { + this(startSequence, restrictedChars, token, (char) 0); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param restrictedChars chars that stop the sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public RestrictedEndOfLineRule(String startSequence, String restrictedChars, IToken token, char escapeCharacter) { + this(startSequence, restrictedChars, token, escapeCharacter, false); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param restrictedChars chars that stop the sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @since 2.1 + */ + public RestrictedEndOfLineRule(String startSequence, String restrictedChars, IToken token, char escapeCharacter, boolean breaksOnEOF) { + super(startSequence, token, escapeCharacter, breaksOnEOF); + this.startSequence = startSequence; + this.restrictedChars = restrictedChars; + rules = new ArrayList<IRule>(); + startIndex = 0; + endIndex = 0; + } + + + public void addRule(SingleLineRule rule) { + rules.add(rule); + } + + + protected void backupScanner(ICharacterScanner scanner, int position) { + int count = scanner.getColumn() - position; + while (count-- > 0) + scanner.unread(); + } + + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + int column = scanner.getColumn(); + // Check if we are at EOF, in which case rules don't hold + if (column < 0) + return Token.UNDEFINED; + if (!resume) { + startIndex = scanner.getColumn(); + if (super.evaluate(scanner, false) != Token.UNDEFINED) { + // Outer rule is true for a section. Now we can + // set the boundaries for the internal rules. + // End boundary for internal rules is the start of + // the end sequence. + endIndex = scanner.getColumn(); + // Back up scanner to just after start sequence. + backupScanner(scanner, startIndex + startSequence.length()); + } + else + // Base rule doesn't hold. + return Token.UNDEFINED; + } + + // At this point, we want to check for restricted chars in the + // token. If we find them, we stop there. + + int start = scanner.getColumn(); + column = start; + while (column < endIndex) { + int ch = scanner.read(); + if (ch == ICharacterScanner.EOF + || restrictedChars.indexOf(ch) >= 0) { + scanner.unread(); + return getSuccessToken(); + } + ++column; + } + startIndex = 0; + endIndex = 0; + return getSuccessToken(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfContentOutlinePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfContentOutlinePage.java new file mode 100644 index 00000000000..5fc7417b6bd --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfContentOutlinePage.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors.outline; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditor; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElement; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; + + +public class AutoconfContentOutlinePage extends ContentOutlinePage { + + private ITextEditor editor; + private IEditorInput input; + + public AutoconfContentOutlinePage(AutoconfEditor editor) { + super(); + this.editor = editor; + } + + public void setInput(IEditorInput editorInput) { + this.input = editorInput; + update(); + } + + protected ISelection updateSelection(ISelection sel) { + ArrayList<AutoconfElement> newSelection= new ArrayList<AutoconfElement>(); + if (sel instanceof IStructuredSelection) { + @SuppressWarnings("unchecked") + Iterator iter= ((IStructuredSelection)sel).iterator(); + for (;iter.hasNext();) { + //ICElement elem= fInput.findEqualMember((ICElement)iter.next()); + Object o = iter.next(); + if (o instanceof AutoconfElement) { + newSelection.add((AutoconfElement)o); + } + } + } + return new StructuredSelection(newSelection); + } + + public void update() { + //set the input so that the outlines parse can be called + //update the tree viewer state + final TreeViewer viewer = getTreeViewer(); + + if (viewer != null) + { + final Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) + { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!control.isDisposed()) { +// control.setRedraw(false); +// if (input != null) +// viewer.setInput(input); +// viewer.expandAll(); +// control.setRedraw(true); + ISelection sel= viewer.getSelection(); + viewer.setSelection(updateSelection(sel)); + viewer.refresh(); + } + } + }); + } + } + } + + public void createControl(Composite parent) { + + super.createControl(parent); + + TreeViewer viewer= getTreeViewer(); + viewer.setContentProvider(new AutoconfContentProvider(editor)); + viewer.setLabelProvider(new AutoconfLabelProvider()); + viewer.addSelectionChangedListener(this); + + if (input != null) + viewer.setInput(input); + } + + /* + * Change in selection + */ + public void selectionChanged(SelectionChangedEvent event) + { + super.selectionChanged(event); + + //find out which item in tree viewer we have selected, and set highlight range accordingly + ISelection selection = event.getSelection(); + if (selection.isEmpty()) { + editor.resetHighlightRange(); + } else { + AutoconfElement element = (AutoconfElement) ((IStructuredSelection) selection) + .getFirstElement(); + + try { + int offset = element.getStartOffset(); + int length = element.getEndOffset() - offset; + editor.setHighlightRange(offset, length, true); + editor.selectAndReveal(offset, length); + } catch (IllegalArgumentException x) { + editor.resetHighlightRange(); + } + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfContentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfContentProvider.java new file mode 100644 index 00000000000..5e898545d94 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfContentProvider.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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.cdt.autotools.ui.editors.outline; + +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditor; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElement; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IPositionUpdater; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + + +public class AutoconfContentProvider implements ITreeContentProvider { + + private IDocumentProvider documentProvider; + private AutoconfEditor editor; + protected final static String SECTION_POSITIONS = "section_positions"; + protected IPositionUpdater positionUpdater = new DefaultPositionUpdater(SECTION_POSITIONS); + + public AutoconfContentProvider(ITextEditor editor) { + if (editor instanceof AutoconfEditor) { + this.editor = (AutoconfEditor) editor; + } + this.documentProvider = editor.getDocumentProvider(); + } + + public void dispose() { + // TODO Auto-generated method stub + + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (oldInput != null) + { + IDocument document = documentProvider.getDocument(oldInput); + if (document != null) + { + try + { + document.removePositionCategory(SECTION_POSITIONS); + } + catch (BadPositionCategoryException x) + { + } + document.removePositionUpdater(positionUpdater); + } + } + + if (newInput != null) + { + IDocument document = documentProvider.getDocument(newInput); + if (document != null) + { + document.addPositionCategory(SECTION_POSITIONS); + document.addPositionUpdater(positionUpdater); + } + } + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof AutoconfElement) { + AutoconfElement element = (AutoconfElement)parentElement; + return element.getChildren(); + } + return new Object[0]; + } + + public Object getParent(Object element) { + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof AutoconfElement) { + return ((AutoconfElement)element).hasChildren(); + } + return false; + } + + public Object[] getElements(Object inputElement) { + return this.getChildren(editor.getRootElement()); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfLabelProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfLabelProvider.java new file mode 100644 index 00000000000..8795ad929cd --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/outline/AutoconfLabelProvider.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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 + * Ed Swartz (NOKIA) - refactoring + *******************************************************************************/ +package org.eclipse.cdt.autotools.ui.editors.outline; + +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfCaseConditionElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfCaseElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElifElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElseElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfForElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfIfElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroArgumentElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfSelectElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfUntilElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfWhileElement; +import org.eclipse.cdt.internal.autotools.ui.AutotoolsUIPluginImages; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; + + +public class AutoconfLabelProvider implements ILabelProvider { + + public AutoconfLabelProvider() { + super(); + } + + public void addListener(ILabelProviderListener listener) { + } + + public void dispose() { + } + + public boolean isLabelProperty(Object element, String property) { + return false; + } + + public void removeListener(ILabelProviderListener listener) { + } + + public Image getImage(Object element) { + if (element instanceof AutoconfIfElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_IF); + else if (element instanceof AutoconfElseElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_ELSE); + else if (element instanceof AutoconfElifElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_ELIF); + else if (element instanceof AutoconfCaseElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_CASE); + else if (element instanceof AutoconfCaseConditionElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_CONDITION); + else if (element instanceof AutoconfForElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_FOR); + else if (element instanceof AutoconfWhileElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_WHILE); + else if (element instanceof AutoconfUntilElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_WHILE); // TODO + else if (element instanceof AutoconfSelectElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_WHILE); // TODO + else if (element instanceof AutoconfMacroElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_ACMACRO); + else if (element instanceof AutoconfMacroArgumentElement) + return AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_OBJS_ACMACRO_ARG); // TODO + return null; + } + + public String getText(Object element) { + if (element instanceof AutoconfElement) { + AutoconfElement e = (AutoconfElement)element; + String result; + String name = e.getName(); + if (name.length() > 31) + name = name.substring(0, 31) + "..."; + String var = e.getVar(); + if (var != null) { + if (var.length() > 15) + var = var.substring(0, 15) + "..."; + var = " " + var; //$NON-NLS-1$ + } else { + var = ""; + } + result = (name + var).replaceAll("(\r|\n| |\t|\f)+", " "); + return result; + } else if (element instanceof String) { + return (String) element; + } + return ""; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfCaseConditionElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfCaseConditionElement.java new file mode 100644 index 00000000000..f417933fce3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfCaseConditionElement extends AutoconfElement { + + public AutoconfCaseConditionElement() { + super(""); + } + + public AutoconfCaseConditionElement(String name) { + super(name); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfCaseElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfCaseElement.java new file mode 100644 index 00000000000..6a2fe255abd --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfCaseElement extends AutoconfElement { + + public AutoconfCaseElement() { + super("case"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElement.java new file mode 100644 index 00000000000..8976969d6e8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElement.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 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.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(","); //$NON-NLS-1$ + } + source = kids.toString(); + } + return getClass().getSimpleName() + ": '" + source + "'"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + 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; + } + + /** + * Return the length of this element. + * @return the length of this element. + */ + public int getLength() { + return endOffset - startOffset; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElifElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElifElement.java new file mode 100644 index 00000000000..da9834ceea7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfElifElement extends AutoconfElement { + + public AutoconfElifElement() { + super("elif"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElseElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfElseElement.java new file mode 100644 index 00000000000..c151f626f09 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfElseElement extends AutoconfElement { + + public AutoconfElseElement() { + super("else"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfForElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfForElement.java new file mode 100644 index 00000000000..69c57bd7afc --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfForElement extends AutoconfElement { + + public AutoconfForElement() { + super("for"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfIfElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfIfElement.java new file mode 100644 index 00000000000..21d8953016e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfIfElement extends AutoconfElement { + + public AutoconfIfElement() { + super("if"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java new file mode 100644 index 00000000000..73718984bc2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroArgumentElement.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 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.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); + } + public String getVar() { + return super.getVar(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroDetector.java new file mode 100644 index 00000000000..598e57db8da --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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.cdt.autotools.core.ui.editors.parser.IAutoconfMacroDetector#isMacroIdentifier(java.lang.String) + */ + public boolean isMacroIdentifier(String name) { + return AUTOCONF_MACRO_PATTERN.matcher(name).matches(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java new file mode 100644 index 00000000000..a2edefc368e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfMacroElement.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * 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.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(); + } + + /** + * Check the most recently added child and make sure it is valid. + * Children of his class should overwrite this and perform proper + * validation. + * @param verions Autoconf to be used to validate this macro. + * @throws InvalidMacroException + */ + public void validate (String version) throws InvalidMacroException {} + + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java new file mode 100644 index 00000000000..e3ca4d234f3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfOutlineErrorHandler.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.autotools.ui.editors.parser; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +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.ui.IStorageEditorInput; +import org.eclipse.ui.texteditor.MarkerUtilities; + + +public class AutoconfOutlineErrorHandler { + + public static final String PARSE_ERROR_MARKER_ID = AutotoolsUIPlugin.PLUGIN_ID + + ".outlineparsefileerror"; //$NON-NLS-1$ + + 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("../"); //$NON-NLS-1$ + } + 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, Integer.valueOf(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 Integer.valueOf(document.getLineOffset(lineNumber) + columnNumber); + } catch (BadLocationException e) { + e.printStackTrace(); + return null; + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfParser.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfParser.java new file mode 100644 index 00000000000..36d43815245 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfParser.java @@ -0,0 +1,1087 @@ +/******************************************************************************* + * Copyright (c) 2007, 2009 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.cdt.autotools.ui.editors.parser; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.autotools.ui.editors.AcInitElement; +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditorMessages; +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 " + //$NON-NLS-1$ + "dumpdef traceon traceoff debugmode debugfile dnl changequote changecom changeword " + //$NON-NLS-1$ + "m4wrap " + //$NON-NLS-1$ + "include sinclude divert undivert divnum len index regexp substr translit patsubst " + //$NON-NLS-1$ + "format incr decr eval syscmd esyscmd sysval mkstemp maketemp errprint m4exit " + //$NON-NLS-1$ + "__file__ __line__ __program__ "; //$NON-NLS-1$ + + private static List<String> m4builtins = new ArrayList<String>(); + static { + m4builtins.addAll(Arrays.asList(M4_BUILTINS.split(" "))); //$NON-NLS-1$ + } + + /** + * 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 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("[", "]"); //$NON-NLS-1$ //$NON-NLS-2$ + + 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())); + } + + /** + * Creates the appropriate macro type object depending on the + * macro name. + * + * @return + */ + private AutoconfMacroElement createMacroElement (String name){ + if (name.equals("AC_INIT")){ //$NON-NLS-1$ + return new AcInitElement(name); + } + return new AutoconfMacroElement(name); + } + + /** + * 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) //$NON-NLS-1$ + return token; + } else { + return token; + } + + AutoconfMacroElement macro = createMacroElement(name); + token = parseMacro(macro, token); + + // handle special macros here + if ("dnl".equals(name)) { //$NON-NLS-1$ + // 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)) { //$NON-NLS-1$ + // change quote delimiters + validateMacroParameterCount(macro, token, 2); + + // GNU behavior for invalid argument count + String parm0 = "`"; //$NON-NLS-1$ + String parm1 = "'"; //$NON-NLS-1$ + 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)) { //$NON-NLS-1$ + // change comment delimiters + validateMacroParameterCount(macro, token, 2); + + // GNU behavior for invalid argument count + String parm0 = "#"; //$NON-NLS-1$ + String parm1 = "\n"; //$NON-NLS-1$ + 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(), Integer.valueOf(2))); //$NON-NLS-1$ + } else if (macro.getParameterCount() > count) { + handleError(macro, token, AutoconfEditorMessages.getFormattedString("M4MacroArgsTooMany", + macro.getName(), Integer.valueOf(2))); //$NON-NLS-1$ + } + } + + /** + * 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); + } catch (InvalidMacroException e) { + 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)); + } + } + + /** + * Figure out the error location and create a marker and message for it. + * @param exception + */ + protected void handleError (InvalidMacroException exception) { + AutoconfElement element = exception.getBadElement(); + + if (errorHandler != null) { + int lineNumber = 0; + int startColumn = 0; + int endColumn = 0; + try { + lineNumber = element.getDocument().getLineOfOffset(element.getStartOffset()); + int lineOffs = element.getDocument().getLineOffset(lineNumber); + startColumn = element.getStartOffset() - lineOffs; + endColumn = startColumn + element.getLength(); + } catch (BadLocationException e) { + // Don't care if we blow up trying to issue marker + } + errorHandler.handleError(new ParseException( + exception.getMessage(), + element.getStartOffset(), + element.getEndOffset(), + lineNumber, + startColumn, endColumn, + IMarker.SEVERITY_ERROR)); + } + } + + public IAutoconfErrorHandler getErrorHandler() { + return errorHandler; + } +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfRootElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfRootElement.java new file mode 100644 index 00000000000..7daabe6669b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.cdt.autotools.ui.editors.parser; + +public class AutoconfRootElement extends AutoconfElement { + + public AutoconfRootElement() { + super(""); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java new file mode 100644 index 00000000000..3a0392cdeef --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfSelectElement.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.autotools.ui.editors.parser; + +public class AutoconfSelectElement extends AutoconfElement { + + public AutoconfSelectElement() { + super("select"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java new file mode 100644 index 00000000000..36bfdef00de --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfTokenizer.java @@ -0,0 +1,435 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 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.cdt.autotools.ui.editors.parser; + +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditorMessages; +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 = "`"; //$NON-NLS-1$ + this.m4CloseQuote = "'"; //$NON-NLS-1$ + this.m4OpenComment = "#"; //$NON-NLS-1$ + this.m4CloseComment = "\n"; //$NON-NLS-1$ + } + + /** + * 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java new file mode 100644 index 00000000000..f6d1d92c08a --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfUntilElement.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.autotools.ui.editors.parser; + +public class AutoconfUntilElement extends AutoconfElement { + + public AutoconfUntilElement() { + super("until"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java new file mode 100644 index 00000000000..e4d9cddacd8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/AutoconfWhileElement.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.autotools.ui.editors.parser; + +public class AutoconfWhileElement extends AutoconfElement { + + public AutoconfWhileElement() { + super("while"); //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IAutoconfErrorHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IAutoconfErrorHandler.java new file mode 100644 index 00000000000..18940e5a1d8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IAutoconfMacroDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IAutoconfMacroDetector.java new file mode 100644 index 00000000000..cc72b8045d3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IAutoconfMacroValidator.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IAutoconfMacroValidator.java new file mode 100644 index 00000000000..f0ba1cff5a4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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, InvalidMacroException; +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IMacroDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/IMacroDetector.java new file mode 100644 index 00000000000..97d505320b8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/ITokenConstants.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/ITokenConstants.java new file mode 100644 index 00000000000..53c616d2e15 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/ITokenConstants.java @@ -0,0 +1,87 @@ +package org.eclipse.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/InvalidMacroArgumentException.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/InvalidMacroArgumentException.java new file mode 100644 index 00000000000..17f1209cef5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/InvalidMacroArgumentException.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2011 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.cdt.autotools.ui.editors.parser; + +public class InvalidMacroArgumentException extends Exception { + + public InvalidMacroArgumentException(String message) { + super(message); + } + + private static final long serialVersionUID = 1L; + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/InvalidMacroException.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/InvalidMacroException.java new file mode 100644 index 00000000000..2b99b003b58 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/InvalidMacroException.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2011 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.cdt.autotools.ui.editors.parser; + +public class InvalidMacroException extends Exception { + + private static final long serialVersionUID = 1L; + private AutoconfElement badElement; + + public InvalidMacroException(String message, AutoconfElement badElement) { + super(message); + this.badElement = badElement; + } + + public AutoconfElement getBadElement() { + return this.badElement; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/ParseException.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/ParseException.java new file mode 100644 index 00000000000..5e0342c6799 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/Token.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/autotools/ui/editors/parser/Token.java new file mode 100644 index 00000000000..a1fede4ded9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AbstractAutotoolsCPropertyTab.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AbstractAutotoolsCPropertyTab.java new file mode 100644 index 00000000000..364ea5e67e3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AbstractAutotoolsCPropertyTab.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + +import org.eclipse.cdt.managedbuilder.ui.properties.AbstractCBuildPropertyTab; + +public abstract class AbstractAutotoolsCPropertyTab extends + AbstractCBuildPropertyTab { + + public boolean isIndexerAffected() { + return false; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AutotoolsConsole.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AutotoolsConsole.java new file mode 100644 index 00000000000..c90a12bc18d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AutotoolsConsole.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + +public class AutotoolsConsole extends Console { + 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AutotoolsUIPluginImages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AutotoolsUIPluginImages.java new file mode 100644 index 00000000000..4f5272ed66d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/AutotoolsUIPluginImages.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007, 2009 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 + * Red Hat Inc. - completely modified for Autotools usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + + +/** + * Bundle of all images used by the C plugin. + */ +public class AutotoolsUIPluginImages { + + // The plugin registry + private static ImageRegistry imageRegistry = new ImageRegistry(CUIPlugin.getStandardDisplay()); + + // Subdirectory (under the package containing this class) where 16 color images are + private static URL fgIconBaseURL; + + static { + try { + fgIconBaseURL= new URL(AutotoolsUIPlugin.getDefault().getBundle().getEntry("/"), "icons/" ); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (MalformedURLException e) { + CUIPlugin.log(e); + } + } + private static final String NAME_PREFIX= AutotoolsUIPlugin.PLUGIN_ID + '.'; + private static final int NAME_PREFIX_LENGTH= NAME_PREFIX.length(); + + public static final String T_OBJ= "ac16/"; //$NON-NLS-1$ + public static final String T_BUILD= "elcl16/"; //$NON-NLS-1$ + + public static final String IMG_OBJS_IF= NAME_PREFIX + "if_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ELSE= NAME_PREFIX + "else_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ELIF= NAME_PREFIX + "elif_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CASE= NAME_PREFIX + "case_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CONDITION= NAME_PREFIX + "condition_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FOR= NAME_PREFIX + "for_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_WHILE= NAME_PREFIX + "while_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ACMACRO= NAME_PREFIX + "acmacro_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_AMMACRO= NAME_PREFIX + "ammacro_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_ACMACRO_ARG = NAME_PREFIX + "acmacro_arg_obj.gif"; // $NON-NLS-1$ + public static final String IMG_BUILD_CONFIG = NAME_PREFIX + "build_configs.gif"; //$NON-NLS-1$ + public static final String IMG_CFG_CATEGORY = NAME_PREFIX + "config_category.gif"; //$NON-NLS-1$ + public static final String IMG_CFG_TOOL = NAME_PREFIX + "config_tool.gif"; //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_IF= createManaged(T_OBJ, IMG_OBJS_IF); + public static final ImageDescriptor DESC_OBJS_ELSE= createManaged(T_OBJ, IMG_OBJS_ELSE); + public static final ImageDescriptor DESC_OBJS_ELIF= createManaged(T_OBJ, IMG_OBJS_ELIF); + public static final ImageDescriptor DESC_OBJS_CASE= createManaged(T_OBJ, IMG_OBJS_CASE); + public static final ImageDescriptor DESC_OBJS_CONDITION = createManaged(T_OBJ, IMG_OBJS_CONDITION); + public static final ImageDescriptor DESC_OBJS_FOR= createManaged(T_OBJ, IMG_OBJS_FOR); + public static final ImageDescriptor DESC_OBJS_WHILE= createManaged(T_OBJ, IMG_OBJS_WHILE); + public static final ImageDescriptor DESC_OBJS_ACMACRO= createManaged(T_OBJ, IMG_OBJS_ACMACRO); + public static final ImageDescriptor DESC_OBJS_AMMACRO= createManaged(T_OBJ, IMG_OBJS_AMMACRO); + public static final ImageDescriptor DESC_OBJS_ACMACRO_ARG= createManaged(T_OBJ, IMG_OBJS_ACMACRO_ARG); + public static final ImageDescriptor DESC_BUILD_CONFIG = createManaged(T_BUILD, IMG_BUILD_CONFIG); + public static final ImageDescriptor DESC_CFG_CATEGORY = createManaged(T_BUILD, IMG_CFG_CATEGORY); + public static final ImageDescriptor DESC_CFG_TOOL = createManaged(T_BUILD, IMG_CFG_TOOL); + + private static ImageDescriptor createManaged(String prefix, String name) { + return createManaged(imageRegistry, prefix, name); + } + + private static ImageDescriptor createManaged(ImageRegistry registry, String prefix, String name) { + ImageDescriptor result= ImageDescriptor.createFromURL(makeIconFileURL(prefix, name.substring(NAME_PREFIX_LENGTH))); + registry.put(name, result); + return result; + } + + public static Image get(String key) { + return imageRegistry.get(key); + } + + private static ImageDescriptor create(String prefix, String name) { + return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name)); + } + + private static URL makeIconFileURL(String prefix, String name) { + StringBuffer buffer= new StringBuffer(prefix); + buffer.append(name); + try { + return new URL(fgIconBaseURL, buffer.toString()); + } catch (MalformedURLException e) { + CUIPlugin.log(e); + return null; + } + } + + /** + * Sets all available image descriptors for the given action. + */ + public static void setImageDescriptors(IAction action, String type, String relPath) { + if (relPath.startsWith(NAME_PREFIX)) + relPath= relPath.substring(NAME_PREFIX_LENGTH); + action.setDisabledImageDescriptor(create("d" + type, relPath)); //$NON-NLS-1$ +// action.setHoverImageDescriptor(create("c" + type, relPath)); //$NON-NLS-1$ + action.setImageDescriptor(create("e" + type, relPath)); //$NON-NLS-1$ + + // We are still not sure about this, let see TF results first. + // Use the managed version so that we ensure that there is no resource handle leaks + // Let the widget itself manage the disabled/hover attribution. This was a huge leak + //ImageDescriptor desc = getImageRegistry().getDescriptor(relPath); + //if(desc == null) { + // desc = createManaged(T + "c" + type, relPath); + //} + //action.setImageDescriptor(desc); + } + + /** + * Helper method to access the image registry from the CUIPlugin class. + */ + static ImageRegistry getImageRegistry() { + return imageRegistry; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CBuildStepsConsole.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CBuildStepsConsole.java new file mode 100644 index 00000000000..3789214badf --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CBuildStepsConsole.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + + +public class CBuildStepsConsole extends Console { + 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CConfigureConsole.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CConfigureConsole.java new file mode 100644 index 00000000000..39b004d89d3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CConfigureConsole.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + + +public class CConfigureConsole extends Console { + 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CWordFinder.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/CWordFinder.java new file mode 100644 index 00000000000..089017ac7fb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/Console.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/Console.java new file mode 100644 index 00000000000..da7401aed35 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ConsoleMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ConsoleMessages.java new file mode 100644 index 00000000000..405e5ad42e3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.autotools.ui; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class ConsoleMessages { + + public static final String BUNDLE_NAME = "org.eclipse.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ConsoleMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ConsoleMessages.properties new file mode 100644 index 00000000000..7c4510df873 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ErrorParserBlock.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ErrorParserBlock.java new file mode 100644 index 00000000000..cbd054b0cdb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ErrorParserBlock.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + +import org.eclipse.cdt.make.core.IMakeBuilderInfo; +import org.eclipse.cdt.make.core.MakeBuilder; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.ui.dialogs.AbstractErrorParserBlock; +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.cdt.utils.ui.controls.ControlFactory; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.swt.widgets.Composite; + +@SuppressWarnings("deprecation") +public class ErrorParserBlock extends AbstractErrorParserBlock { + + // make builder enabled + IMakeBuilderInfo fBuildInfo; + boolean useBuildInfo = false; + Preferences fPrefs; + + public ErrorParserBlock(Preferences preferences) { + super(); + fPrefs = preferences; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + + if (useBuildInfo == true && fBuildInfo == null) { + Composite composite = ControlFactory.createComposite(parent, 1); + setControl(composite); + ControlFactory.createEmptySpace(composite); + ControlFactory.createLabel(composite, MakeUIMessages.getResourceString("ErrorParserBlock.label.missingBuilderInformation")); //$NON-NLS-1$ + return; + } + super.createControl(parent); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.ui.dialogs.ErrorParserBlock#getErrorParserIDs(org.eclipse.core.resources.IProject) + */ + protected String[] getErrorParserIDs(IProject project) { + if (getContainer().getProject() != null && fBuildInfo == null) { + try { + fBuildInfo = MakeCorePlugin.createBuildInfo(getContainer().getProject(), MakeBuilder.BUILDER_ID); + } catch (CoreException e) { + } + } + if (fBuildInfo != null) { + return fBuildInfo.getErrorParsers(); + } + return new String[0]; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.ui.dialogs.ErrorParserBlock#saveErrorParsers(org.eclipse.core.resources.IProject, + * java.lang.String[]) + */ + public void saveErrorParsers(IProject project, String[] parserIDs) throws CoreException { + if (getContainer().getProject() != null) { + try { + fBuildInfo = MakeCorePlugin.createBuildInfo(getContainer().getProject(), MakeBuilder.BUILDER_ID); + } catch (CoreException e) { + } + } + if (fBuildInfo != null) { + fBuildInfo.setErrorParsers(parserIDs); + } + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.AbstractErrorParserBlock#saveErrorParsers(java.lang.String[]) + */ + protected void saveErrorParsers(String[] parserIDs) throws CoreException { + fBuildInfo = MakeCorePlugin.createBuildInfo(fPrefs, MakeBuilder.BUILDER_ID, false); + fBuildInfo.setErrorParsers(parserIDs); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.AbstractErrorParserBlock#getErrorParserIDs(boolean) + */ + protected String[] getErrorParserIDs(boolean defaults) { + fBuildInfo = MakeCorePlugin.createBuildInfo(fPrefs, MakeBuilder.BUILDER_ID, defaults); + return fBuildInfo.getErrorParsers(); + } + + public void setContainer(ICOptionContainer container) { + super.setContainer(container); + if (getContainer().getProject() != null) { + try { + fBuildInfo = MakeCorePlugin.createBuildInfo(getContainer().getProject(), MakeBuilder.BUILDER_ID); + } catch (CoreException e) { + } + useBuildInfo = true; + } else { + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/FileRelevance.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/FileRelevance.java new file mode 100644 index 00000000000..c7e65ad58d9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/FileRelevance.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2008 Broadcom 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: + * James Blackburn (Broadcom) - Initial API and implementation + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourceAttributes; + +/** + * This class computes a relevance for files in case we have to select + * from multiple files for the same file-system location. + */ +public class FileRelevance { + private static final int PREFERRED_PROJECT = 0x40; + private static final int CDT_PROJECT = 0x20; + private static final int ON_SOURCE_ROOT = 0x10; + + // Penalty for undesirable attributes + private static final int LINK_PENALTY = 1; + private static final int INACCESSIBLE_SHIFT = 4; + + /** + * Compute a relevance for the given file. The higher the score the more relevant the + * file. It is determined by the following criteria: <br> + * - file belongs to preferred project <br> + * - file belongs to a cdt-project <br> + * - file belongs to a source folder of a cdt-project <br> + * - file is accessible + * - file is not a link + * @param f the file to compute the relevance for + * @return integer representing file relevance. Larger numbers are more relevant + */ + public static int getRelevance(IFile f, IProject preferredProject) { + int result= 0; + IProject p= f.getProject(); + if (p.equals(preferredProject)) + result+= PREFERRED_PROJECT; + + if (CoreModel.hasCNature(p)) { + result+= CDT_PROJECT; + ICProject cproject= CoreModel.getDefault().create(p); + if (cproject.isOnSourceRoot(f)) + result+= ON_SOURCE_ROOT; + } + + if (!f.isAccessible()) + result >>= INACCESSIBLE_SHIFT; + else { + ResourceAttributes ra = f.getResourceAttributes(); + if (f.isLinked() || (ra != null && ra.isSymbolicLink())) + result -= LINK_PENALTY; + } + + return result; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTML2TextReader.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTML2TextReader.java new file mode 100644 index 00000000000..b1a507309c9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTML2TextReader.java @@ -0,0 +1,260 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + + +import java.io.IOException; +import java.io.PushbackReader; +import java.io.Reader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; + + +/** + * Reads the text contents from a reader of HTML contents and translates + * the tags or cut them out. + */ +public class HTML2TextReader extends SubstitutionTextReader { + + + private static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + private static final Map<String, String> fgEntityLookup; + private static final Set<String> fgTags; + + static { + + fgTags= new HashSet<String>(); + fgTags.add("b"); //$NON-NLS-1$ + fgTags.add("br"); //$NON-NLS-1$ + fgTags.add("h5"); //$NON-NLS-1$ + fgTags.add("p"); //$NON-NLS-1$ + fgTags.add("dl"); //$NON-NLS-1$ + fgTags.add("dt"); //$NON-NLS-1$ + fgTags.add("dd"); //$NON-NLS-1$ + fgTags.add("li"); //$NON-NLS-1$ + fgTags.add("ul"); //$NON-NLS-1$ + + fgEntityLookup= new HashMap<String, String>(7); + fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$ + fgEntityLookup.put("quot", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private int fCounter= 0; + private TextPresentation fTextPresentation; + private int fBold= 0; + private int fStartOffset= -1; + private boolean fInParagraph= false; + + /** + * Transforms the html text from the reader to formatted text. + * @param presentation If not <code>null</code>, formattings will be applied to + * the presentation. + */ + public HTML2TextReader(Reader reader, TextPresentation presentation) { + super(new PushbackReader(reader)); + fTextPresentation= presentation; + } + + public int read() throws IOException { + int c= super.read(); + if (c != -1) + ++ fCounter; + return c; + } + + protected void startBold() { + if (fBold == 0) + fStartOffset= fCounter; + ++ fBold; + } + + protected void stopBold() { + -- fBold; + if (fBold == 0) { + if (fTextPresentation != null) { + fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.BOLD)); + } + fStartOffset= -1; + } + } + + /** + * @see SubstitutionTextReader#computeSubstitution(char) + */ + protected String computeSubstitution(int c) throws IOException { + if (c == '<') + return processHTMLTag(); + else if (c == '&') + return processEntity(); + + return null; + } + + private String html2Text(String html) { + + String tag= html; + if ('/' == tag.charAt(0)) + tag= tag.substring(1); + + if (!fgTags.contains(tag)) + return ""; //$NON-NLS-1$ + + if ("b".equals(html)) { //$NON-NLS-1$ + startBold(); + return ""; //$NON-NLS-1$ + } + + if ("h5".equals(html) || "dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$ + startBold(); + return ""; //$NON-NLS-1$ + } + + if ("dl".equals(html)) //$NON-NLS-1$ + return LINE_DELIM; + + if ("dd".equals(html)) //$NON-NLS-1$ + return "\t"; //$NON-NLS-1$ + + if ("li".equals(html)) //$NON-NLS-1$ + return LINE_DELIM + "\t" + "-"; //$NON-NLS-1$ //$NON-NLS-2$ + + if ("/b".equals(html)) { //$NON-NLS-1$ + stopBold(); + return ""; //$NON-NLS-1$ + } + + if ("p".equals(html)) { //$NON-NLS-1$ + fInParagraph= true; + return LINE_DELIM; + } + + if ("br".equals(html)) //$NON-NLS-1$ + return LINE_DELIM; + + if ("/p".equals(html)) { //$NON-NLS-1$ + boolean inParagraph= fInParagraph; + fInParagraph= false; + return inParagraph ? "" : LINE_DELIM; //$NON-NLS-1$ + } + + if ("/h5".equals(html) || "/dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$ + stopBold(); + return LINE_DELIM; + } + + if ("/dd".equals(html)) //$NON-NLS-1$ + return LINE_DELIM; + + return ""; //$NON-NLS-1$ + } + + /* + * A '<' has been read. Process a html tag + */ + private String processHTMLTag() throws IOException { + + StringBuffer buf= new StringBuffer(); + int ch; + do { + + ch= nextChar(); + + while (ch != -1 && ch != '>') { + buf.append(Character.toLowerCase((char) ch)); + ch= nextChar(); + if (ch == '"'){ + buf.append(Character.toLowerCase((char) ch)); + ch= nextChar(); + while (ch != -1 && ch != '"'){ + buf.append(Character.toLowerCase((char) ch)); + ch= nextChar(); + } + } + if (ch == '<'){ + unread(ch); + return '<' + buf.toString(); + } + } + + if (ch == -1) + return null; + + int tagLen= buf.length(); + // needs special treatment for comments + if ((tagLen >= 3 && "!--".equals(buf.substring(0, 3))) //$NON-NLS-1$ + && !(tagLen >= 5 && "--!".equals(buf.substring(tagLen - 3)))) { //$NON-NLS-1$ + // unfinished comment + buf.append(ch); + } else { + break; + } + } while (true); + + return html2Text(buf.toString()); + } + + private void unread(int ch) throws IOException { + ((PushbackReader) getReader()).unread(ch); + } + + protected String entity2Text(String symbol) { + if (symbol.length() > 1 && symbol.charAt(0) == '#') { + int ch; + try { + if (symbol.charAt(1) == 'x') { + ch= Integer.parseInt(symbol.substring(2), 16); + } else { + ch= Integer.parseInt(symbol.substring(1), 10); + } + return "" + (char)ch; //$NON-NLS-1$ + } catch (NumberFormatException e) { + } + } else { + String str= (String) fgEntityLookup.get(symbol); + if (str != null) { + return str; + } + } + return "&" + symbol; // not found //$NON-NLS-1$ + } + + /* + * A '&' has been read. Process a entity + */ + private String processEntity() throws IOException { + StringBuffer buf= new StringBuffer(); + int ch= nextChar(); + while (Character.isLetterOrDigit((char)ch) || ch == '#') { + buf.append((char) ch); + ch= nextChar(); + } + + if (ch == ';') + return entity2Text(buf.toString()); + + buf.insert(0, '&'); + if (ch != -1) + buf.append((char) ch); + return buf.toString(); + } +}
\ No newline at end of file diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTMLPrinter.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTMLPrinter.java new file mode 100644 index 00000000000..52e37f8dda1 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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, '<', "<"); //$NON-NLS-1$ + return replace(content, '>', ">"); //$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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTMLTextPresenter.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTMLTextPresenter.java new file mode 100644 index 00000000000..b1d27d56365 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/HTMLTextPresenter.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.Iterator; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Display; + + +public class HTMLTextPresenter implements DefaultInformationControl.IInformationPresenter { + + private static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + + private int fCounter; + private boolean fEnforceUpperLineLimit; + + public HTMLTextPresenter(boolean enforceUpperLineLimit) { + super(); + fEnforceUpperLineLimit= enforceUpperLineLimit; + } + + public HTMLTextPresenter() { + this(true); + } + + protected Reader createReader(String hoverInfo, TextPresentation presentation) { + return new HTML2TextReader(new StringReader(hoverInfo), presentation); + } + + protected void adaptTextPresentation(TextPresentation presentation, int offset, int insertLength) { + + int yoursStart= offset; + + @SuppressWarnings("unchecked") + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) { + + StyleRange range= (StyleRange) e.next(); + + int myStart= range.start; + int myEnd= range.start + range.length -1; + myEnd= Math.max(myStart, myEnd); + + if (myEnd < yoursStart) + continue; + + if (myStart < yoursStart) + range.length += insertLength; + else + range.start += insertLength; + } + } + + private void append(StringBuffer buffer, String string, TextPresentation presentation) { + + int length= string.length(); + buffer.append(string); + + if (presentation != null) + adaptTextPresentation(presentation, fCounter, length); + + fCounter += length; + } + + private String getIndent(String line) { + int length= line.length(); + + int i= 0; + while (i < length && Character.isWhitespace(line.charAt(i))) ++i; + + return (i == length ? line : line.substring(0, i)) + " "; //$NON-NLS-1$ + } + + /* + * @see IHoverInformationPresenter#updatePresentation(Display display, String, TextPresentation, int, int) + */ + public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) { + + if (hoverInfo == null) + return null; + + GC gc= new GC(display); + try { + + StringBuffer buffer= new StringBuffer(); + int maxNumberOfLines= Math.round((float)maxHeight / gc.getFontMetrics().getHeight()); + + fCounter= 0; + LineBreakingReader reader= new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth); + + boolean lastLineFormatted= false; + String lastLineIndent= null; + + String line=reader.readLine(); + boolean lineFormatted= reader.isFormattedLine(); + boolean firstLineProcessed= false; + + while (line != null) { + + if (fEnforceUpperLineLimit && maxNumberOfLines <= 0) + break; + + if (firstLineProcessed) { + if (!lastLineFormatted) + append(buffer, LINE_DELIM, null); + else { + append(buffer, LINE_DELIM, presentation); + if (lastLineIndent != null) + append(buffer, lastLineIndent, presentation); + } + } + + append(buffer, line, null); + firstLineProcessed= true; + + lastLineFormatted= lineFormatted; + if (!lineFormatted) + lastLineIndent= null; + else if (lastLineIndent == null) + lastLineIndent= getIndent(line); + + line= reader.readLine(); + lineFormatted= reader.isFormattedLine(); + + maxNumberOfLines--; + } + + if (line != null) { + append(buffer, LINE_DELIM, lineFormatted ? presentation : null); + append(buffer, (""), presentation); //$NON-NLS-1$ + } + + return trim(buffer, presentation); + + } catch (IOException e) { + + AutotoolsUIPlugin.log(e); + return null; + + } finally { + gc.dispose(); + } + } + + private String trim(StringBuffer buffer, TextPresentation presentation) { + + int length= buffer.length(); + + int end= length -1; + while (end >= 0 && Character.isWhitespace(buffer.charAt(end))) + -- end; + + if (end == -1) + return ""; //$NON-NLS-1$ + + if (end < length -1) + buffer.delete(end + 1, length); + else + end= length; + + int start= 0; + while (start < end && Character.isWhitespace(buffer.charAt(start))) + ++ start; + + buffer.delete(0, start); + presentation.setResultWindow(new Region(start, buffer.length())); + return buffer.toString(); + } +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/LineBreakingReader.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/LineBreakingReader.java new file mode 100644 index 00000000000..8c6146ad664 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/LocationAdapter.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/LocationAdapter.java new file mode 100644 index 00000000000..a2c767fd362 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/LocationAdapter.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import java.io.File; +import java.io.IOException; +import java.net.URI; + +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; + +/** + * Provides common functionality for URI and IPath + */ +abstract class LocationAdapter<T> { + + public abstract String extractName(T location); + public abstract IFile[] platformsFindFilesForLocation(T location); + public abstract String getCanonicalPath(T location); + public abstract T getLocation(IFile file); + + public static final LocationAdapter<IPath> PATH = new LocationAdapter<IPath>() { + @Override + public String extractName(IPath location) { + String name = location.lastSegment(); + if (name != null) + return name; + return location.toString(); + } + + @Override + public IFile[] platformsFindFilesForLocation(IPath location) { + final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + return root.findFilesForLocationURI(URIUtil.toURI(location.makeAbsolute())); + } + + @Override + public String getCanonicalPath(IPath location) { + final File file= location.toFile(); + try { + return file.getCanonicalPath(); + } catch (IOException e) { + // use non-canonical version + return file.getAbsolutePath(); + } + } + + @Override + public IPath getLocation(IFile file) { + return file.getLocation(); + } + }; + + public static final LocationAdapter<URI> URI = new LocationAdapter<URI>() { + @Override + public String extractName(URI location) { + String path= location.getPath(); + int idx= path.lastIndexOf('/'); + return path.substring(idx+1); + } + + @Override + public IFile[] platformsFindFilesForLocation(URI location) { + return ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(location); + } + + @Override + public String getCanonicalPath(URI location) { + if (!"file".equals(location.getScheme())) //$NON-NLS-1$ + return null; + + String path= location.getPath(); + try { + return new File(path).getCanonicalPath(); + } catch (IOException e) { + // use non-canonical version + return path; + } + } + + @Override + public URI getLocation(IFile file) { + return file.getLocationURI(); + } + }; +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIImages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIImages.java new file mode 100644 index 00000000000..0d149f04c07 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIImages.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005, 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.cdt.internal.autotools.ui; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + + + +public class MakeUIImages { + + /** + * Bundle of all images used by the Make plugin. + */ + // The plugin registry + private static ImageRegistry imageRegistry = new ImageRegistry(); + + // Subdirectory (under the package containing this class) where 16 color images are + private static URL fgIconBaseURL; + static { + try { + fgIconBaseURL = new URL(AutotoolsUIPlugin.getDefault().getBundle().getEntry("/"), "icons/"); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (MalformedURLException e) { + AutotoolsUIPlugin.log(e); + } + } + private static final String NAME_PREFIX = AutotoolsUIPlugin.getUniqueIdentifier() + '.'; + private static final int NAME_PREFIX_LENGTH = NAME_PREFIX.length(); + + public static final String OBJ = "obj16/"; //$NON-NLS-1$ + public static final String T_TOOL= "tool16/"; //$NON-NLS-1$ + public static final String T_LCL = "lcl16/"; //$NON-NLS-1$ + + // For the build image + public static final String IMG_OBJS_BUILD_TARGET = NAME_PREFIX + "target_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_BUILD_TARGET = createManaged(OBJ, IMG_OBJS_BUILD_TARGET); + + public static final String IMG_OBJS_ERROR = NAME_PREFIX + "error_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJ_ERROR = createManaged(OBJ, IMG_OBJS_ERROR); + public static final String IMG_OBJS_WARNING = NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJ_WARNING = createManaged(OBJ, IMG_OBJS_WARNING); + + public static final String IMG_TOOLS_MAKE_TARGET_BUILD = NAME_PREFIX + "target_build.gif"; //$NON-NLS-1$ + public static final String IMG_TOOLS_MAKE_TARGET_ADD = NAME_PREFIX + "target_add.gif"; //$NON-NLS-1$ + public static final String IMG_TOOLS_MAKE_TARGET_DELETE = NAME_PREFIX + "target_delete.gif"; //$NON-NLS-1$ + public static final String IMG_TOOLS_MAKE_TARGET_EDIT = NAME_PREFIX + "target_edit.gif"; //$NON-NLS-1$ + public static final String IMG_TOOLS_MAKE_TARGET_FILTER = NAME_PREFIX + "target_filter.gif"; //$NON-NLS-1$ + + public static final String IMG_OBJS_MAKEFILE_MACRO = NAME_PREFIX + "macro_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_MACRO = createManaged(OBJ, IMG_OBJS_MAKEFILE_MACRO); + + public static final String IMG_OBJS_MAKEFILE_ACMACRO = NAME_PREFIX + "acmacro_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_ACMACRO = createManaged(OBJ, IMG_OBJS_MAKEFILE_ACMACRO); + + public static final String IMG_OBJS_MAKEFILE_TARGET_RULE = NAME_PREFIX + "trule_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_TARGET_RULE = createManaged(OBJ, IMG_OBJS_MAKEFILE_TARGET_RULE); + + public static final String IMG_OBJS_MAKEFILE_INFERENCE_RULE = NAME_PREFIX + "irule_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_INFERENCE_RULE = createManaged(OBJ, IMG_OBJS_MAKEFILE_INFERENCE_RULE); + + public static final String IMG_OBJS_MAKEFILE_RELATION = NAME_PREFIX + "relation_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_RELATION = createManaged(OBJ, IMG_OBJS_MAKEFILE_RELATION); + + public static final String IMG_OBJS_MAKEFILE_COMMAND = NAME_PREFIX + "command_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_COMMAND = createManaged(OBJ, IMG_OBJS_MAKEFILE_COMMAND); + + public static final String IMG_OBJS_MAKEFILE_INCLUDE = NAME_PREFIX + "include_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_MAKEFILE_INCLUDE = createManaged(OBJ, IMG_OBJS_MAKEFILE_INCLUDE); + + public static final String IMG_OBJS_ENVIRONMNET = NAME_PREFIX + "environment_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_ENVIRONMENT = createManaged(OBJ, IMG_OBJS_ENVIRONMNET); + + public static final String IMG_OBJS_ENV_VAR = NAME_PREFIX + "envvar_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_ENV_VAR = createManaged(OBJ, IMG_OBJS_ENV_VAR); + + public static final String IMG_TOOLS_ALPHA_SORTING= NAME_PREFIX + "alphab_sort_co.gif"; //$NON-NLS-1$ + public static final String IMG_TOOLS_MAKEFILE_SEGMENT_EDIT= NAME_PREFIX + "segment_edit.gif"; //$NON-NLS-1$ + + public static final String IMG_MENU_OPEN_INCLUDE= NAME_PREFIX + "open_include.gif"; //$NON-NLS-1$ + + private static ImageDescriptor createManaged(String prefix, String name) { + return createManaged(imageRegistry, prefix, name); + } + + private static ImageDescriptor createManaged(ImageRegistry registry, String prefix, String name) { + ImageDescriptor result = ImageDescriptor.createFromURL(makeIconFileURL(prefix, name.substring(NAME_PREFIX_LENGTH))); + registry.put(name, result); + return result; + } + + public static Image getImage(String key) { + return imageRegistry.get(key); + } + + private static ImageDescriptor create(String prefix, String name) { + return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name)); + } + + private static URL makeIconFileURL(String prefix, String name) { + StringBuffer buffer = new StringBuffer(prefix); + buffer.append(name); + try { + return new URL(fgIconBaseURL, buffer.toString()); + } catch (MalformedURLException e) { + AutotoolsUIPlugin.log(e); + return null; + } + } + + /** + * Sets all available image descriptors for the given action. + */ + public static void setImageDescriptors(IAction action, String type, String relPath) { + relPath = relPath.substring(NAME_PREFIX_LENGTH); + action.setDisabledImageDescriptor(create("d" + type + "/", relPath)); //$NON-NLS-1$ //$NON-NLS-2$ +// action.setHoverImageDescriptor(create("e" + type + "/", relPath)); //$NON-NLS-1$ //$NON-NLS-2$ + action.setImageDescriptor(create("e" + type + "/", relPath)); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Helper method to access the image registry from the JavaPlugin class. + */ + static ImageRegistry getImageRegistry() { + return imageRegistry; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIMessages.java new file mode 100644 index 00000000000..ee5f755aa84 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIMessages.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class MakeUIMessages { + + public static final String BUNDLE_NAME = MakeUIMessages.class.getName(); + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + private MakeUIMessages() { + + } + public static String getResourceString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + /** + * Returns the plugin's resource bundle, + */ + public static ResourceBundle getResourceBundle() { + return RESOURCE_BUNDLE; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIMessages.properties new file mode 100644 index 00000000000..4f49ba8d572 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MakeUIMessages.properties @@ -0,0 +1,283 @@ +############################################################################### +# Copyright (c) 2003, 2005, 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 +# Wind River Systems - fix for bugzilla 135150 +# Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136) +############################################################################### + +MakeCWizard.title=C/Make Project +MakeCWizard.description=Create a New C Project using 'make' to build it +MakeEnvironmentBlock.10=&Remove +MakeEnvironmentBlock.11=New Environment Variable +MakeEnvironmentBlock.12=Overwrite variable? +MakeEnvironmentBlock.13=A variable named {0} already exists. Overwrite? +MakeEnvironmentBlock.14=Select &environment variables to add: +MakeEnvironmentBlock.15=Select Environment Variables +MakeEnvironmentBlock.16=Edit Environment Variable +MakeEnvironmentBlock.17=&Append environment to native environment +MakeEnvironmentBlock.18=Re&place native environment with specified environment +MakeCWizard.task_name=Creating C project with Make builder... + +MakeCCWizard.title=C++/Make Project +MakeCCWizard.description=Create a New C++ Project using 'make' to build it +MakeCCWizard.task_name=Creating C++ project with Make builder... +MakeEnvironmentBlock.0=Variable +MakeEnvironmentBlock.1=Value +MakeEnvironmentBlock.2=&Name: +MakeEnvironmentBlock.3=&Value: +MakeEnvironmentBlock.4=Environment +MakeEnvironmentBlock.5=Environment used for make builder +MakeEnvironmentBlock.6=Environment variables to set +MakeEnvironmentBlock.7=N&ew... +MakeEnvironmentBlock.8=Se&lect... +MakeEnvironmentBlock.9=E&dit... + +MakeCWizardSettings.title=C/Make Project Settings +MakeCWizardSettings.description=Define the project and 'make' builder settings + +MakeCCWizardSettings.title=C++/Make Project Settings +MakeCCWizardSettings.description=Define the project and 'make' builder settings + +WizardMakeProjectConversion.title=Convert to C/C++ Make project +WizardMakeProjectConversion.description=Convert a project to a C/C++ project which uses 'make' to build it. +WizardMakeProjectConversion.monitor.convertingToMakeProject=Converting to Make Project... + +MakeWizardUpdate.window_title=Make Project Migration +MakeWizardUpdatePage.title=Make Project Migration +MakeWizardUpdatePage.description=Migrate older make projects to new make builder. +MakeWizardUpdatePage.projectList=Project list +MakeWizardUpdatePage.status.noProjectsToUpdate=No projects to update +MakeWizardUpdatePage.status.noProjectsSelected=No projects selected + +WizardCheckboxTablePart.WizardCheckboxTablePart.selectAll=Select All +WizardCheckboxTablePart.WizardCheckboxTablePart.deselectAll=Deselect All +WizardCheckboxTablePart.WizardCheckboxTablePart.counter={0} of {1} Selected + +SettingsBlock.label=Make Builder +SettingsBlock.message=Make builder settings. +SettingsBlock.makeSetting.group_label=Build Setting +SettingsBlock.makeSetting.stopOnError=Stop on first build error. +SettingsBlock.makeSetting.runAllBuilders=Run all project builders. +SettingsBlock.makeCmd.group_label=Build command +SettingsBlock.makeCmd.use_default=Use default +SettingsBlock.makeCmd.label=Build command: +SettingsBlock.makeLoc.group_label=Build Location +SettingsBlock.makeDir.label=Build directory: +SettingsBlock.makeDir.browseWorkspace=Workspace... +SettingsBlock.makeDir.browseFilesystem=Filesystem... +SettingsBlock.makeWorkbench.group_label=Workbench Build Behavior +SettingsBlock.makeWorkbench.type=Workbench build type: +SettingsBlock.makeWorkbench.target=Make build target: +SettingsBlock.makeWorkbench.auto=Build on resource save (Auto Build) +SettingsBlock.makeWorkbench.note=Note: +SettingsBlock.makeWorkbench.autobuildMessage=See Workbench automatic build preference. +SettingsBlock.makeWorkbench.incremental=Build (Incremental Build) +SettingsBlock.makeWorkbench.clean=Clean +SettingsBlock.makeWorkbench.autoBuildTarget=Auto Build Target +SettingsBlock.makeWorkbench.incrementalBuildTarget=Incremental Build Target +SettingsBlock.makeWorkbench.cleanTarget=Clean Target +SettingsBlock.variables=Variables... +TargetBlock.target.group_label=Target +TargetBlock.target.label=Target Name: + +ErrorParserBlock.label.missingBuilderInformation=Builder is missing or disabled on project. + +BuildTarget.target.group_label=Make Target +BuildTarget.target.label=Make Target: + +MakeTargetsPreferencePage.buildTargetInBackground.label=Build make targets in background. + +MakeDocumentProvider.exception.createElementInfo=Error creating element. + +AddBuildTargetAction.title=Add make Target +AddBuildTargetAction.description=Add make Target +AddBuildTargetAction.tooltip= Add make Target +AddBuildTargetAction.exception.internal=Internal Error + +OpenIncludeAction.title=Open include directive +OpenIncludeAction.description=Open an include directive +OpenIncludeAction.tooltip= Include Directive +OpenIncludeAction.exception.internal=Internal Error + +TargetBuild.execption.message=Target Build Error +TargetBuild.monitor.beginTask=Building Targets... +TargetBuild.backgroundTask.name=Building Targets. + +TargetListViewer.button.add=Add... +TargetListViewer.button.remove=Remove +TargetListViewer.button.edit=Edit... +TargetListViewer.lable.target=Target +TargetListViewer.lable.location=Location +TargetListViewer.exception.error=Error +TargetListViewer.exception.message=An error occurred performing the selected action + +UpdateMakeProjectAction.exception.error=Error +UpdateMakeProjectAction.eception.message=Error updating Make Projects +UpdateMakeProjectAction.monitor.convert=Converting Make Targets... +UpdateMakeProjectAction.monitor.update=Updating make Projects... + +BuildPathInfoBlock.button.browse=Browse... +BuildPathInfoBlock.description=Set the include paths and preprocessor symbols for this project +BuildPathInfoBlock.monitor.settingScannerInfo=Setting Scanner Info + +BuildTargetDialog.title.buildTarget=Make Targets +BuildTargetDialog.button.build=Build +BuildTargetDialog.title.makeTargetsFor=Make Targets for: + +MakeTargetDialog.exception.noTargetBuilderOnProject=Not target builders on the project +MakeTargetDialog.title.createMakeTarget=Create a new Make target +MakeTargetDialog.title.modifyMakeTarget=Modify a Make target +MakeTargetDialog.message.mustSpecifyName=Must specify a target name. +MakeTargetDialog.message.targetWithNameExists=Target with that name already exits. +MakeTargetDialog.message.mustSpecifyBuildCommand=Must specify a build command +MakeTargetDialog.button.update=Update +MakeTargetDialog.button.create=Create +MakeTargetDialog.exception.makeTargetError=Make Target Error +MakeTargetDialog.exception.errorAddingTarget=Error adding target + +SettingsBlock.title.selectLocationToBuildFrom=Selection Location to build from. +SettingsBlock.label.missingBuilderInformation=Builder is missing or disabled on project. +SettingsBlock.monitor.applyingSettings=Applying Settings... +SettingsBlock.message.mustEnterBuildCommand=Must enter a build command + +DeleteTargetAction.label=Delete Make Target +DeleteTargetAction.tooltip=Delete Make Target +DeleteTargetAction.title.confirmDeletion=Confirm Target Deletion +DeleteTargetAction.message.confirmDeleteion=Are you sure you want to delete ''{0}''? +DeleteTargetAction.title.confirmMultipleDeletion=Confirm Multiple Target Deletion +DeleteTargetAction.message.confirmMultipleDeletion=Are you sure you want to delete these {0} targets? +DeleteTargetAction.exception.removeError=Make Target Remove Error +DeleteTargetAction.exception.errorDeletingBuildTarget=Error deleting Make target + +BuildTargetAction.label=Build Make Target +BuildTargetAction.tooltip=Build Make Target + +EditTargetAction.label=Edit Make Target +EditTargetAction.tooltip=Edit Make Target +EditTargetAction.exception.internalError=Internal Error +EditTargetAction.exception.errorEditingTarget=Error editing target. + +AddTargetAction.label=Add Make Target +AddTargetAction.tooltip=Add Make Target +AddTargetAction.exception.internalError=Internal Error +AddTargetAction.=Internal Error + +FilterEmptyFolderAction.label=Hide Empty Folders +FilterEmptyFolderAction.tooltip=Hide Empty Folders + +# Startup messages +MakeUIPlugin.update_project=Update make projects +MakeUIPlugin.update_project_message=Older \'make\' projects have been detected in your workspace. \n These projects are no longer supported, would you like to convert these now? + +# Prefernece Page +MakePreferencePage.description=Specify the settings used as defaults by the New Standard Make Project creation wizard. +MakeTargetPreferencePage.buildTargetInBackground.label=Build Make target in the background. + +#Property Page +MakeProjectPropertyPage.closedproject=Project Closed +MakeProjectPropertyPage.internalError=An Internal error has occur please check error log. + +#-------------- Makefile Editor messages +ContentAssistProposal.label=Content Assist@Ctrl+SPACE +ContentAssistProposal.tooltip=Content Assist +ContentAssistProposal.image= +ContentAssistProposal.description=Content Assist + +ContentAssistTip.label=Content Tip@Ctrl+SHIFT+SPACE +ContentAssistTip.tooltip=Content Tip +ContentAssistTip.image= +ContentAssistTip.description=Content Tip + +TogglePresentation.label=Show Source of Selected Element Only +TogglePresentation.tooltip=Show Source of Selected Element Only +TogglePresentation.description=Enable/Disable Segmented Source Viewer + +Comment.label=&Comment +Comment.tooltip=Comment the Selected Lines +Comment.description=Turn the selected lines into # style comments + +Uncomment.label=Uncommen&t +Uncomment.tooltip=Uncomment the Selected # comment Lines +Uncomment.description=Uncomment the selected # comment lines + +OpenDeclarationAction.label=&Open Declaration@F3 +OpenDeclarationAction.description=Open an editor on the referenced element +OpenDeclarationAction.tooltip=Open an editor on the referenced element + +# ------- LexicalSortingAction------------ + +LexicalSortingAction.label=Sort +LexicalSortingAction.description=Sorts the elements in the outliner +LexicalSortingAction.tooltip=Sort +LexicalSortingAction.tooltip.on=Do Not Sort +LexicalSortingAction.tooltip.off=Sort + +# --- ManageIncludePathsDialog dialog --- +ManageIncludePathsDialog.title=Manage include paths +ManageIncludePathsDialog.userGroup.title=User specified include paths +ManageIncludePathsDialog.discoveredGroup.title=Discovered include paths + +ManageScannerConfigDialogCommon.discoveredGroup.selected.label=Selected: +ManageScannerConfigDialogCommon.discoveredGroup.removed.label=Removed: +ManageScannerConfigDialogCommon.discoveredGroup.buttons.up.label=Up +ManageScannerConfigDialogCommon.discoveredGroup.buttons.down.label=Down +ManageScannerConfigDialogCommon.discoveredGroup.buttons.disable.label=Disable +ManageScannerConfigDialogCommon.discoveredGroup.buttons.enable.label=Enable +ManageScannerConfigDialogCommon.discoveredGroup.buttons.delete.label=Delete +ManageScannerConfigDialogCommon.discoveredGroup.buttons.deleteAll.label=Delete all +ManageScannerConfigDialogCommon.discoveredGroup.annotation.disabled=disabled + +# --- ManageDefinedSymbolsDialog dialog --- +ManageDefinedSymbolsDialog.title=Manage defined symbols +ManageDefinedSymbolsDialog.userGroup.title=User specified symbol definitions +ManageDefinedSymbolsDialog.discoveredGroup.title=Discovered symbol definitions + +# --- ScannerConfigOptionsDialog --- +ScannerConfigOptionsDialog.title=Discovery Options +ScannerConfigOptionsDialog.description=Set the scanner configuration discovery options for this project +ScannerConfigOptionsDialog.scGroup.label=Automated discovery of paths and symbols +ScannerConfigOptionsDialog.scGroup.enabled.button=Automate discovery of paths and symbols +ScannerConfigOptionsDialog.scGroup.problemReporting.enabled.button=Report path detection problems +ScannerConfigOptionsDialog.scGroup.selectedProfile.combo=Discovery profile: +ScannerConfigOptionsDialog.profile.group.label=Discovery profile options +ScannerConfigOptionsDialog.boProvider.parser.enabled.button=Enable build output scanner info discovery +ScannerConfigOptionsDialog.boProvider.open.label=Load build output from file +ScannerConfigOptionsDialog.boProvider.browse.button=Browse... +ScannerConfigOptionsDialog.boProvider.browse.openFileDialog=Build output file: +ScannerConfigOptionsDialog.boProvider.load.button=Load +ScannerConfigOptionsDialog.siProvider.parser.enabled.button=Enable generate scanner info command +ScannerConfigOptionsDialog.siProvider.command.label=Compiler invocation command +ScannerConfigOptionsDialog.siProvider.browse.button=Browse... +ScannerConfigOptionsDialog.siProvider.browse.runCommandDialog='gcc' command: +ScannerConfigOptionsDialog.siProvider.command.errorMessage=Must enter compiler invocation command +ScannerConfigOptionsDialog.apply.progressMessage=Setting scanner configuration discovery options... +ScannerConfigOptionsDialog.common.variables.button=Variables... + +ScannerConfigOptionsDialog.unsavedchanges.title=Setting C/C++ Make Project Discovery Options +ScannerConfigOptionsDialog.unsavedchanges.message=The C/C++ Make Project Discovery Options property page contains unsaved modifications. Do you want to save changes so that other discovery related settings can be updated? +ScannerConfigOptionsDialog.unsavedchanges.button.save=Apply +ScannerConfigOptionsDialog.unsavedchanges.button.cancel=Cancel + +ScannerConfigOptionsDialog.error.title=Error Setting Project Discovery options +ScannerConfigOptionsDialog.error.message=An error occurred while setting the project discovery options + +# --- DiscoveredScannerConfigurationContainerPage --- +DiscoveredScannerConfigurationContainerPage.title=Edit container +DiscoveredScannerConfigurationContainerPage.description=Manage discovered scanner configuration +DiscoveredScannerConfigurationContainerPage.list.title=Discovered include paths and symbol definitions +DiscoveredScannerConfigurationContainerPage.initialization.error.message=Error initializing Discovered paths container + +CopyDiscoveredPathAction.title=Copy +CopyDiscoveredPathAction.description=Copy as text +CopyDiscoveredPathAction.tooltip=Copy as text +MultipleInputDialog.0=&Browse... +MultipleInputDialog.1=Select a file: +MultipleInputDialog.2=Varia&bles... + +OptionalMessageDialog_dontShowAgain= Do not show this &message again diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MessageLine.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MessageLine.java new file mode 100644 index 00000000000..bcf346c8a6e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/MessageLine.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import org.eclipse.jface.resource.JFaceColors; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; + + +/** + * A message line. It distinguishes between "normal" messages and errors. + * Setting an error message hides a currently displayed message until + * <code>clearErrorMessage</code> is called. + */ +public class MessageLine { + + private String fMessage; + + private Color fNormalMsgAreaBackground; + + private boolean hasErrorMessage; + + private CLabel clabel; + + /** + * Creates a new message line as a child of the given parent. + */ + public MessageLine(Composite parent) { + this(parent, SWT.LEFT); + } + + /** + * Creates a new message line as a child of the parent and with the given SWT stylebits. + */ + public MessageLine(Composite parent, int style) { + clabel = new CLabel(parent, style); + fNormalMsgAreaBackground= clabel.getBackground(); + } + + + /** + * Display the given error message. A currently displayed message + * is saved and will be redisplayed when the error message is cleared. + */ + public void setErrorMessage(String message) { + if (message != null && message.length() > 0) { + hasErrorMessage = true; + clabel.setText(message); + clabel.setImage(MakeUIImages.getImage(MakeUIImages.IMG_OBJS_ERROR)); + clabel.setBackground(JFaceColors.getErrorBackground(clabel.getDisplay())); + return; + } + hasErrorMessage = false; + clabel.setText(fMessage); + clabel.setImage(null); + clabel.setBackground(fNormalMsgAreaBackground); + } + + public void setMessage(String message) { + fMessage = message; + clabel.setText(message); + } + + public boolean hasErrorMessage() { + return hasErrorMessage; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/OptionalMessageDialog.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/OptionalMessageDialog.java new file mode 100644 index 00000000000..86c77434436 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/OptionalMessageDialog.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2000, 2009 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 + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +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.Control; +import org.eclipse.swt.widgets.Shell; + +/** + * This is a <code>MessageDialog</code> which allows the user + * to choose that the dialog isn't shown again the next time. + */ +public class OptionalMessageDialog extends MessageDialog { + // String constants for widgets + private static final String CHECKBOX_TEXT= MakeUIMessages.getResourceString("OptionalMessageDialog_dontShowAgain"); // $NON-NLS-1$ + + // Dialog store id constants + private static final String STORE_ID= "OptionalMessageDialog.hide."; //$NON-NLS-1$ + private static final String KEY_DETAIL = ".detail"; //$NON-NLS-1$ + + public static final int NOT_SHOWN= IDialogConstants.CLIENT_ID + 1; + public static final int NO_DETAIL= -1; + + private Button fHideDialogCheckBox; + private String fId; + + /** + * Opens the dialog but only if the user hasn't choosen to hide it. + * Returns <code>NOT_SHOWN</code> if the dialog was not shown. + */ + public static int open(String id, Shell parent, String title, Image titleImage, String message, int dialogType, String[] buttonLabels, int defaultButtonIndex) { + if (!isDialogEnabled(id)) + return OptionalMessageDialog.NOT_SHOWN; + + MessageDialog dialog= new OptionalMessageDialog(id, parent, title, titleImage, message, dialogType, buttonLabels, defaultButtonIndex); + return dialog.open(); + } + + protected OptionalMessageDialog(String id, Shell parent, String title, Image titleImage, String message, int dialogType, String[] buttonLabels, int defaultButtonIndex) { + super(parent, title, titleImage, message, dialogType, buttonLabels, defaultButtonIndex); + fId= id; + } + + @Override + protected Control createCustomArea(Composite parent) { + Composite composite= new Composite(parent, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); + layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + layout.horizontalSpacing= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + fHideDialogCheckBox= new Button(composite, SWT.CHECK | SWT.LEFT); + fHideDialogCheckBox.setText(CHECKBOX_TEXT); + fHideDialogCheckBox.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setDialogEnabled(fId, !((Button)e.widget).getSelection()); + } + }); + applyDialogFont(fHideDialogCheckBox); + return fHideDialogCheckBox; + } + + //--------------- Configuration handling -------------- + + /** + * Returns this dialog + * + * @return the settings to be used + */ + private static IDialogSettings getDialogSettings() { + IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings(); + settings= settings.getSection(STORE_ID); + if (settings == null) + settings= CUIPlugin.getDefault().getDialogSettings().addNewSection(STORE_ID); + return settings; + } + + /** + * Answers whether the optional dialog is enabled and should be shown. + */ + public static boolean isDialogEnabled(String key) { + IDialogSettings settings= getDialogSettings(); + return !settings.getBoolean(key); + } + + /** + * Sets a detail for the dialog. + */ + public static void setDialogDetail(String key, int detail) { + IDialogSettings settings= getDialogSettings(); + settings.put(key+KEY_DETAIL, detail); + } + + /** + * Returns the detail for this dialog, or NO_DETAIL, if none. + */ + public static int getDialogDetail(String key) { + IDialogSettings settings= getDialogSettings(); + try { + return settings.getInt(key+KEY_DETAIL); + } catch (NumberFormatException e) { + return NO_DETAIL; + } + } + + /** + * Sets whether the optional dialog is enabled and should be shown. + */ + public static void setDialogEnabled(String key, boolean isEnabled) { + IDialogSettings settings= getDialogSettings(); + settings.put(key, !isEnabled); + } + + /** + * Clears all remembered information about hidden dialogs + */ + public static void clearAllRememberedStates() { + IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings(); + settings.addNewSection(STORE_ID); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ResourceLookup.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ResourceLookup.java new file mode 100644 index 00000000000..2583f5f06ae --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ResourceLookup.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; + +/** + * Allows for looking up resources by location or name. + */ +public class ResourceLookup { + private static ResourceLookupTree lookupTree= new ResourceLookupTree(); + + public static void startup() { + lookupTree.startup(); + } + + public static void shutdown() { + lookupTree.shutdown(); + } + + /** + * Searches for files with the given location suffix. + * + * At this point the method works for sources and headers (no other content types), only. + * This is done to use less memory and can be changed if necessary. + * For linked resource files, the name of the link target is relevant. + * + * @param locationSuffix the suffix to match, always used as relative path. + * @param projects the projects to search + * @param ignoreCase whether or not to ignore case when comparing the suffix. + */ + public static IFile[] findFilesByName(IPath locationSuffix, IProject[] projects, boolean ignoreCase) { + return lookupTree.findFilesByName(locationSuffix, projects, ignoreCase); + } + + /** + * Uses a lookup-tree that finds resources for locations using the canonical representation + * of the path. + */ + public static IFile[] findFilesForLocationURI(URI location) { + return lookupTree.findFilesForLocationURI(location); + } + + /** + * Uses a lookup-tree that finds resources for locations using the canonical representation + * of the path. The method does not work for files where the name (last segment) of the + * resources differs from the name of the location. + */ + public static IFile[] findFilesForLocation(IPath location) { + return lookupTree.findFilesForLocation(location); + } + + /** + * Uses {@link #findFilesForLocationURI(URI)} and selects the most relevant file + * from the result. Files form the first project, from cdt-projects and those on source + * roots are preferred, see {@link FileRelevance}. + * @param location an URI for the location of the files to search for. + * @param preferredProject a project to be preferred over others, or <code>null</code>. + * @return a file for the location in one of the given projects, or <code>null</code>. + * NB the returned IFile may not exist + */ + public static IFile selectFileForLocationURI(URI location, IProject preferredProject) { + return selectFile(findFilesForLocationURI(location), preferredProject); + } + + /** + * Uses {@link #findFilesForLocation(IPath)} and selects the most relevant file + * from the result. Files form the preferred project, from cdt-projects and those on source + * roots are preferred, see {@link FileRelevance}. + * @param location a path for the location of the files to search for. + * @param preferredProject a project to be preferred over others, or <code>null</code>. + * @return a file for the location or <code>null</code>. + * NB the returned IFile may not exist + */ + public static IFile selectFileForLocation(IPath location, IProject preferredProject) { + return selectFile(findFilesForLocation(location), preferredProject); + } + + private static IFile selectFile(IFile[] files, IProject preferredProject) { + if (files.length == 0) + return null; + + if (files.length == 1) + return files[0]; + + IFile best= null; + int bestRelevance= -1; + + for (int i = 0; i < files.length; i++) { + IFile file = files[i]; + int relevance= FileRelevance.getRelevance(file, preferredProject); + if (best == null || relevance > bestRelevance || + (relevance == bestRelevance && + best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) { + bestRelevance= relevance; + best= file; + } + } + return best; + } + + /** + * Sorts files by relevance for CDT, by the criteria listed below. The most relevant files + * is listed first. + * <br> Accessible files + * <br> Files of preferred project + * <br> Files of CDT projects + * <br> Files on a source root of a CDT project + */ + public static void sortFilesByRelevance(IFile[] filesToSort, final IProject preferredProject) { + Collections.sort(Arrays.asList(filesToSort), new Comparator<IFile>() { + public int compare(IFile f1, IFile f2) { + int r1= FileRelevance.getRelevance(f1, preferredProject); + int r2= FileRelevance.getRelevance(f2, preferredProject); + + if (r1 > r2) + return -1; + if (r1 < r2) + return 1; + + return f1.getFullPath().toString().compareTo(f2.getFullPath().toString()); + } + }); + } + + /** + * For testing, only. + */ + public static void dump() { + lookupTree.dump(); + } + /** + * For testing, only. + */ + public static void unrefNodeMap() { + lookupTree.unrefNodeMap(); + } + /** + * For testing, only. + */ + public static void simulateNodeMapCollection() { + lookupTree.simulateNodeMapCollection(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ResourceLookupTree.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ResourceLookupTree.java new file mode 100644 index 00000000000..55e75c5df14 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/ResourceLookupTree.java @@ -0,0 +1,861 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui; + +import java.lang.ref.SoftReference; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.core.runtime.content.IContentTypeManager; +import org.eclipse.core.runtime.jobs.Job; + +/** + * Allows for looking up resources by location or name. When using this class 100 bytes per resource + * are needed. Therefore the support is limited to header-files int non-cdt projects and all files + * except non-cdt-files in CDT projects. + * + * The information for a project is initialized when first requested and then it is kept up to date + * using a resource change listener. No memory is used, as long as the class is not used. + * When information is not used for more than 10 minutes, the data-structures will be held via a weak + * reference, only and are subject to garbage collection. + * + * The node map stores a map from hash-code of file-names to nodes. + * A node contains the name of a file plus a link to the parent resource. From that we can compute + * the resource path and obtain further information via the resource. + */ +class ResourceLookupTree implements IResourceChangeListener, IResourceDeltaVisitor, IResourceProxyVisitor { + private static final int UNREF_DELAY = 10 * 60000; // 10 min + + private static final boolean VISIT_CHILDREN = true; + private static final boolean SKIP_CHILDREN = false; + private static final IFile[] NO_FILES = new IFile[0]; + private static final int TRIGGER_RECALC= + IResourceDelta.TYPE | IResourceDelta.REPLACED | + IResourceDelta.LOCAL_CHANGED | IResourceDelta.OPEN; + + private static class Extensions { + private final boolean fInvert; + private final Set<String> fExtensions; + Extensions(Set<String> extensions, boolean invert) { + fInvert= invert; + fExtensions= extensions; + } + boolean isRelevant(String filename) { + // accept all files without extension + final int idx= filename.lastIndexOf('.'); + if (idx < 0) + return true; + + return fExtensions.contains(filename.substring(idx+1).toUpperCase()) != fInvert; + } + } + + private static class Node { + final Node fParent; + final char[] fResourceName; + final boolean fHasFileLocationName; + final boolean fIsFileLinkTarget; + + boolean fDeleted; + boolean fHasChildren; + int fCanonicHash; + + Node(Node parent, char[] name, boolean hasFileLocationName, boolean isFileLinkTarget) { + fParent= parent; + fResourceName= name; + fHasFileLocationName= hasFileLocationName; + fIsFileLinkTarget= isFileLinkTarget; + if (parent != null) + parent.fHasChildren= true; + } + } + + private final Object fLock= new Object(); + private final Job fUnrefJob; + private SoftReference<Map<Integer, Object>> fNodeMapRef; + private Map<Integer, Object> fNodeMap; + private final Map<String, Extensions> fFileExtensions; + private Extensions fCDTProjectExtensions; + private Extensions fDefaultExtensions; + private Extensions fCurrentExtensions; + private Node fRootNode; + private boolean fNeedCleanup; + private Node fLastFolderNode; + + public ResourceLookupTree() { + fRootNode= new Node(null, CharArrayUtils.EMPTY, false, false) {}; + fFileExtensions= new HashMap<String, Extensions>(); + fUnrefJob= new Job("Timer") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + unrefNodeMap(); + return Status.OK_STATUS; + } + }; + fUnrefJob.setSystem(true); + } + + public void startup() { + final IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace.addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); + } + + public void shutdown() { + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); + synchronized (fLock) { + fNodeMap= null; + fNodeMapRef= null; + fFileExtensions.clear(); + } + } + + /** + * Handle resource change notifications. + */ + public void resourceChanged(IResourceChangeEvent event) { + IResourceDelta delta= event.getDelta(); + synchronized (fLock) { + if (fNodeMapRef == null) + return; + boolean unsetMap= false; + if (fNodeMap == null) { + fNodeMap= fNodeMapRef.get(); + if (fNodeMap == null) + return; + unsetMap= true; + } + try { + delta.accept(this); + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + } finally { + if (fNeedCleanup) + cleanup(); + fCurrentExtensions= null; + fNeedCleanup= false; + if (unsetMap) + fNodeMap= null; + } + } + } + + /** + * Handles resource change notifications by visiting the delta. + */ + public boolean visit(IResourceDelta delta) throws CoreException { + assert Thread.holdsLock(fLock); + + final IResource res= delta.getResource(); + if (res instanceof IWorkspaceRoot) + return VISIT_CHILDREN; + + if (res instanceof IProject) { + // project not yet handled + final String name = res.getName(); + final Extensions exts= fFileExtensions.get(name); + if (exts == null) + return SKIP_CHILDREN; + + switch (delta.getKind()) { + case IResourceDelta.ADDED: // new projects should not yet be part of the tree + case IResourceDelta.REMOVED: + fFileExtensions.remove(name); + remove(res); + return SKIP_CHILDREN; + + case IResourceDelta.CHANGED: + if ((delta.getFlags() & (TRIGGER_RECALC | IResourceDelta.DESCRIPTION)) != 0) { + fFileExtensions.remove(name); + remove(res); + return SKIP_CHILDREN; + } + break; + } + fCurrentExtensions= exts; + return VISIT_CHILDREN; + } + + // file or folder + switch (delta.getKind()) { + case IResourceDelta.ADDED: + add(res); + return SKIP_CHILDREN; + + case IResourceDelta.CHANGED: + if ((delta.getFlags() & TRIGGER_RECALC) != 0) { + remove(res); + add(res); + return SKIP_CHILDREN; + } + return VISIT_CHILDREN; + + case IResourceDelta.REMOVED: + + remove(res); + return SKIP_CHILDREN; + } + return VISIT_CHILDREN; + } + + + /** + * Add a resource to the tree. + */ + private void add(IResource res) { + assert Thread.holdsLock(fLock); + + if (res instanceof IFile) { + final String resName = res.getName(); + String linkedName= null; + if (res.isLinked()) { + URI uri= res.getLocationURI(); + if (uri != null) { + linkedName= LocationAdapter.URI.extractName(uri); + if (linkedName.length() > 0 && fCurrentExtensions.isRelevant(linkedName)) { + if (linkedName.equals(resName)) { + createFileNode(res.getFullPath(), null); + } else { + createFileNode(res.getFullPath(), linkedName); + } + } + } + } else if (fCurrentExtensions.isRelevant(resName)) { + createFileNode(res.getFullPath(), null); + } + } else { + try { + res.accept(this, 0); + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + } + } + } + + /** + * Add a resource tree by using a resource proxy visitor. + */ + public boolean visit(IResourceProxy proxy) throws CoreException { + if (proxy.getType() == IResource.FILE) { + if (fCurrentExtensions.isRelevant(proxy.getName())) { + if (proxy.isLinked()) { + IResource res= proxy.requestResource(); + if (res instanceof IFile) { + add(res); + } + return true; + } + createFileNode(proxy.requestFullPath(), null); + } + } + return true; + } + + + public void unrefNodeMap() { + synchronized (fLock) { + fNodeMap= null; + } + } + + public void simulateNodeMapCollection() { + synchronized (fLock) { + fNodeMap= null; + fNodeMapRef= new SoftReference<Map<Integer, Object>>(null); + } + } + + /** + * Initializes nodes for the given projects. Also creates the node map if it was collected. + */ + private void initializeProjects(IProject[] projects) { + assert Thread.holdsLock(fLock); + + if (fNodeMap == null) { + if (fNodeMapRef != null) { + fNodeMap= fNodeMapRef.get(); + } + + if (fNodeMap == null) { + fFileExtensions.clear(); + fNodeMap= new HashMap<Integer, Object>(); + fNodeMapRef= new SoftReference<Map<Integer, Object>>(fNodeMap); + } + } + fUnrefJob.cancel(); + fUnrefJob.schedule(UNREF_DELAY); + + for (IProject project : projects) { + if (project.isOpen() && !fFileExtensions.containsKey(project.getName())) { + Extensions ext= fDefaultExtensions; + try { + if (project.hasNature(CProjectNature.C_NATURE_ID)) { + ext= fCDTProjectExtensions; + } + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + // treat as non-cdt project + } + fCurrentExtensions= ext; + add(project); + fFileExtensions.put(project.getName(), ext); + fCurrentExtensions= null; + } + } + } + + /** + * Initializes file-extensions and node map + */ + private void initFileExtensions() { + + if (fDefaultExtensions == null) { + HashSet<String> cdtContentTypes= new HashSet<String>(); + String[] registeredContentTypes= CoreModel.getRegistedContentTypeIds(); + cdtContentTypes.addAll(Arrays.asList(registeredContentTypes)); + + final IContentTypeManager ctm= Platform.getContentTypeManager(); + final IContentType[] ctts= ctm.getAllContentTypes(); + Set<String> result= new HashSet<String>(); + outer: for (IContentType ctt : ctts) { + IContentType basedOn= ctt; + while (basedOn != null) { + if (cdtContentTypes.contains(basedOn.getId())) + continue outer; + basedOn= basedOn.getBaseType(); + } + // this is a non-cdt content type + addFileSpecs(ctt, result); + } + fCDTProjectExtensions= new Extensions(result, true); + + result= new HashSet<String>(); + for (IContentType ctt : ctts) { + IContentType basedOn= ctt; + while (basedOn != null) { + if (cdtContentTypes.contains(basedOn.getId())) { + addFileSpecs(ctt, result); + break; + } + basedOn= basedOn.getBaseType(); + } + } + fDefaultExtensions= new Extensions(result, false); + } + } + + private void addFileSpecs(IContentType ctt, Set<String> result) { + String[] fspecs= ctt.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + for (String fspec : fspecs) { + result.add(fspec.toUpperCase()); + } + } + + /** + * Inserts a node for the given path. + */ + private void createFileNode(IPath fullPath, String fileLink) { + final String[] segments= fullPath.segments(); + final boolean isFileLinkTarget= fileLink != null; + final char[][] charArraySegments = toCharArrayArray(segments, fileLink); + createNode(charArraySegments, charArraySegments.length, true, isFileLinkTarget); + } + + private char[][] toCharArrayArray(String[] segments, String fileLink) { + final int segmentLen = segments.length; + char[][] chsegs; + if (fileLink != null) { + chsegs= new char[segmentLen+1][]; + chsegs[segmentLen]= fileLink.toCharArray(); + } else { + chsegs= new char[segmentLen][]; + } + for (int i = 0; i < segmentLen; i++) { + chsegs[i]= segments[i].toCharArray(); + } + return chsegs; + } + + /** + * Inserts a node for the given path. + */ + private Node createNode(char[][] segments, int segmentCount, boolean hasFileLocationName, boolean isFileLinkTarget) { + assert Thread.holdsLock(fLock); + + if (segmentCount == 0) + return fRootNode; + + if (!hasFileLocationName && fLastFolderNode != null) { + if (isNodeForSegments(fLastFolderNode, segments, segmentCount, isFileLinkTarget)) + return fLastFolderNode; + } + + final char[] name= segments[segmentCount-1]; + final int hash= hashCode(name); + + // search for existing node + Object obj= fNodeMap.get(hash); + + Node[] nodes= null; + int len= 0; + if (obj != null) { + if (obj instanceof Node) { + Node node= (Node) obj; + if (isNodeForSegments(node, segments, segmentCount, isFileLinkTarget)) { + if (!hasFileLocationName) + fLastFolderNode= node; + return node; + } + nodes= new Node[]{node, null}; + fNodeMap.put(hash, nodes); + len= 1; + } else { + nodes= (Node[]) obj; + for (len=0; len < nodes.length; len++) { + Node node = nodes[len]; + if (node == null) + break; + if (isNodeForSegments(node, segments, segmentCount, isFileLinkTarget)) { + if (!hasFileLocationName) + fLastFolderNode= node; + return node; + } + } + } + } + final Node parent= createNode(segments, segmentCount-1, false, false); + Node node= new Node(parent, name, hasFileLocationName, isFileLinkTarget); + if (nodes == null) { + fNodeMap.put(hash, node); + } else { + if (len == nodes.length) { + Node[] newNodes= new Node[len+2]; + System.arraycopy(nodes, 0, newNodes, 0, len); + nodes= newNodes; + fNodeMap.put(hash, nodes); + } + nodes[len]= node; + } + + if (!hasFileLocationName) + fLastFolderNode= node; + return node; + } + + /** + * Checks whether the given node matches the given segments. + */ + private boolean isNodeForSegments(Node node, char[][] segments, int segmentLength, boolean isFileLinkTarget) { + assert Thread.holdsLock(fLock); + + if (node.fIsFileLinkTarget != isFileLinkTarget) + return false; + + while(segmentLength > 0 && node != null) { + if (!CharArrayUtils.equals(segments[--segmentLength], node.fResourceName)) + return false; + node= node.fParent; + } + return node == fRootNode; + } + + /** + * Remove a resource from the tree + */ + private void remove(IResource res) { + assert Thread.holdsLock(fLock); + + final char[] name= res.getName().toCharArray(); + final int hash= hashCode(name); + + Object obj= fNodeMap.get(hash); + if (obj == null) + return; + + final IPath fullPath= res.getFullPath(); + final int segmentCount= fullPath.segmentCount(); + if (segmentCount == 0) + return; + + final char[][]segments= toCharArrayArray(fullPath.segments(), null); + if (obj instanceof Node) { + final Node node= (Node) obj; + if (!node.fDeleted && isNodeForSegments(node, segments, segmentCount, false)) { + node.fDeleted= true; + if (node.fHasChildren) + fNeedCleanup= true; + fNodeMap.remove(hash); + } + } else { + final Node[] nodes= (Node[]) obj; + for (int i= 0; i < nodes.length; i++) { + Node node = nodes[i]; + if (node == null) + return; + if (!node.fDeleted && isNodeForSegments(node, segments, segmentCount, false)) { + remove(nodes, i); + + if (nodes[0] == null) + fNodeMap.remove(hash); + + node.fDeleted= true; + if (node.fHasChildren) + fNeedCleanup= true; + + return; + } + } + } + } + + private void remove(Node[] nodes, int i) { + int idx= lastValid(nodes, i); + if (idx > 0) { + nodes[i]= nodes[idx]; + nodes[idx]= null; + } + } + + private int lastValid(Node[] nodes, int left) { + int right= nodes.length-1; + while (left < right) { + int mid= (left+right+1)/2; // ==> mid > left + if (nodes[mid] == null) + right= mid-1; + else + left= mid; + } + return right; + } + + private void cleanup() { + assert Thread.holdsLock(fLock); + fLastFolderNode= null; + + for (Iterator<Object> iterator = fNodeMap.values().iterator(); iterator.hasNext();) { + Object obj= iterator.next(); + if (obj instanceof Node) { + if (isDeleted((Node) obj)) { + iterator.remove(); + } + } else { + Node[] nodes= (Node[]) obj; + int j= 0; + for (int i = 0; i < nodes.length; i++) { + final Node node = nodes[i]; + if (node == null) { + if (j==0) { + iterator.remove(); + } + break; + } + if (!isDeleted(node)) { + if (i != j) { + nodes[j]= node; + nodes[i]= null; + } + j++; + } else { + nodes[i]= null; + } + } + } + } + } + + private boolean isDeleted(Node node) { + while(node != null) { + if (node.fDeleted) + return true; + node= node.fParent; + } + return false; + } + + /** + * Computes a case insensitive hash-code for file names. + */ + private int hashCode(char[] name) { + int h= 0; + final int len = name.length; + for (int i = 0; i < len; i++) { + h = 31*h + Character.toUpperCase(name[i]); + } + return h; + } + + /** + * Searches for all files with the given location. In case the name of the location is + * a cdt-content type the lookup tree is consulted, otherwise as a fallback the platform's + * method is called. + */ + public IFile[] findFilesForLocationURI(URI location) { + return findFilesForLocation(location, LocationAdapter.URI); + } + + /** + * Searches for all files with the given location. In case the name of the location is + * a cdt-content type the lookup tree is consulted, otherwise as a fallback the platform's + * method is called. + */ + public IFile[] findFilesForLocation(IPath location) { + return findFilesForLocation(location, LocationAdapter.PATH); + } + + /** + * Searches for all files with the given location. In case the name of the location is + * a cdt-content type the lookup tree is consulted, otherwise as a fallback the platform's + * method is called. + */ + public <T> IFile[] findFilesForLocation(T location, LocationAdapter<T> adapter) { + initFileExtensions(); + String name= adapter.extractName(location); + Node[] candidates= null; + synchronized (fLock) { + initializeProjects(ResourcesPlugin.getWorkspace().getRoot().getProjects()); + Object obj= fNodeMap.get(hashCode(name.toCharArray())); + if (obj != null) { + candidates= convert(obj); + IFile[] result= extractMatchesForLocation(candidates, location, adapter); + if (result.length > 0) + return result; + } + } + + // fall back to platform functionality + return adapter.platformsFindFilesForLocation(location); + } + + private Node[] convert(Object obj) { + if (obj instanceof Node) + return new Node[] {(Node) obj}; + + final Node[] nodes= (Node[]) obj; + final int len= lastValid(nodes, -1)+1; + final Node[] result= new Node[len]; + System.arraycopy(nodes, 0, result, 0, len); + return result; + } + + /** + * Returns an array of files for the given name. Search is limited to the supplied projects. + */ + public IFile[] findFilesByName(IPath relativeLocation, IProject[] projects, boolean ignoreCase) { + final int segCount= relativeLocation.segmentCount(); + if (segCount < 1) + return NO_FILES; + + final String name= relativeLocation.lastSegment(); + Node[] candidates; + + initFileExtensions(); + synchronized (fLock) { + initializeProjects(projects); + Object obj= fNodeMap.get(hashCode(name.toCharArray())); + if (obj == null) { + return NO_FILES; + } + candidates= convert(obj); + } + String suffix= relativeLocation.toString(); + while(suffix.startsWith("../")) { //$NON-NLS-1$ + suffix= suffix.substring(3); + } + Set<String> prjset= new HashSet<String>(); + for (IProject prj : projects) { + prjset.add(prj.getName()); + } + return extractMatchesForName(candidates, name, suffix, ignoreCase, prjset); + } + + /** + * Selects the actual matches for the list of candidate nodes. + */ + private IFile[] extractMatchesForName(Node[] candidates, String name, String suffix, boolean ignoreCase, Set<String> prjSet) { + final char[] n1= name.toCharArray(); + final int namelen = n1.length; + int resultIdx= 0; + + if (ignoreCase) { + for (int j = 0; j < namelen; j++) { + n1[j]= Character.toUpperCase(n1[j]); + } + } + final int suffixLen= suffix.length(); + final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); + IFile[] result= null; + outer: for (int i = 0; i < candidates.length; i++) { + final Node node = candidates[i]; + if (node.fHasFileLocationName && checkProject(node, prjSet)) { + final char[] n2= node.fResourceName; + if (namelen == n2.length) { + for (int j = 0; j < n2.length; j++) { + final char c= ignoreCase ? Character.toUpperCase(n2[j]) : n2[j]; + if (c != n1[j]) + continue outer; + } + final IFile file= root.getFile(createPath(node)); + final URI loc= file.getLocationURI(); + if (loc != null) { + String path= loc.getPath(); + final int len= path.length(); + if (len >= suffixLen && + suffix.regionMatches(ignoreCase, 0, path, len-suffixLen, suffixLen)) { + if (result == null) + result= new IFile[candidates.length-i]; + result[resultIdx++]= root.getFile(createPath(node)); + } + } + } + } + } + if (result==null) + return NO_FILES; + + if (resultIdx < result.length) { + IFile[] copy= new IFile[resultIdx]; + System.arraycopy(result, 0, copy, 0, resultIdx); + return copy; + } + return result; + } + + private boolean checkProject(Node node, Set<String> prjSet) { + while(true) { + final Node n= node.fParent; + if (n == fRootNode) + break; + if (n == null) + return false; + node= n; + } + return prjSet.contains(new String(node.fResourceName)); + } + + private IPath createPath(Node node) { + if (node == fRootNode) + return Path.ROOT; + + if (node.fIsFileLinkTarget) + return createPath(node.fParent); + + return createPath(node.fParent).append(new String(node.fResourceName)); + } + + /** + * Selects the actual matches from the list of candidates + */ + private <T> IFile[] extractMatchesForLocation(Node[] candidates, T location, LocationAdapter<T> adapter) { + final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); + final String searchPath= adapter.getCanonicalPath(location); + IFile[] result= null; + int resultIdx= 0; + for (int i = 0; i < candidates.length; i++) { + final Node node = candidates[i]; + if (node.fHasFileLocationName) { + final IFile file= root.getFile(createPath(node)); + final T loc= adapter.getLocation(file); + if (loc != null) { + if (!loc.equals(location)) { + if (searchPath == null) + continue; + + if (node.fCanonicHash != 0 && node.fCanonicHash != searchPath.hashCode()) + continue; + + final String candPath= adapter.getCanonicalPath(loc); + if (candPath == null) + continue; + + node.fCanonicHash= candPath.hashCode(); + if (!candPath.equals(searchPath)) + continue; + } + if (result == null) + result= new IFile[candidates.length-i]; + result[resultIdx++]= root.getFile(createPath(node)); + } + } + } + if (result==null) + return NO_FILES; + + if (resultIdx < result.length) { + IFile[] copy= new IFile[resultIdx]; + System.arraycopy(result, 0, copy, 0, resultIdx); + return copy; + } + return result; + } + + @SuppressWarnings("nls") + public void dump() { + List<String> lines= new ArrayList<String>(); + synchronized (fLock) { + for (Iterator<Object> iterator = fNodeMap.values().iterator(); iterator.hasNext();) { + Node[] nodes= convert(iterator.next()); + for (int i = 0; i < nodes.length; i++) { + final Node node = nodes[i]; + if (node == null) { + break; + } + lines.add(toString(node)); + } + } + } + Collections.sort(lines); + System.out.println("Dumping files:"); + for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) { + String line = iterator.next(); + System.out.println(line); + } + System.out.flush(); + } + + @SuppressWarnings("nls") + private String toString(Node node) { + if (node == fRootNode) + return ""; + + return toString(node.fParent) + "/" + new String(node.fResourceName); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/SingleCharReader.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/SingleCharReader.java new file mode 100644 index 00000000000..b58f8288bab --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/SubstitutionTextReader.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/SubstitutionTextReader.java new file mode 100644 index 00000000000..797b903ce12 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AbstractAutotoolsHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AbstractAutotoolsHandler.java new file mode 100644 index 00000000000..de7ceb1b3e5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AbstractAutotoolsHandler.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.cdt.internal.autotools.ui.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.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +public abstract class AbstractAutotoolsHandler extends AbstractHandler { + + protected Object execute(ExecutionEvent event, InvokeAction a) throws ExecutionException { + ISelection k = HandlerUtil.getCurrentSelection(event); + if (!k.isEmpty() && k instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection)k).getFirstElement(); + IContainer container = getContainer(obj); + if (container != null) { + a.setSelectedContainer(container); + a.run(null); + } + } + return null; + } + + @SuppressWarnings("unchecked") + protected IContainer getContainer(Object obj) { + IContainer fContainer = null; + + 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AbstractTargetAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AbstractTargetAction.java new file mode 100644 index 00000000000..5b7f53e132b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AbstractTargetAction.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +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.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 && AutotoolsPlugin.hasTargetBuilder(fContainer.getProject())) { + enabled = true; + } + } + action.setEnabled(enabled); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AclocalHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AclocalHandler.java new file mode 100644 index 00000000000..9ef6e1140ef --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AclocalHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2008, 2011 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** + * @author Jeff Johnston + * + */ +public class AclocalHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new InvokeAclocalAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoconfHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoconfHandler.java new file mode 100644 index 00000000000..7ad41ebca2c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoconfHandler.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class AutoconfHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new InvokeAutoconfAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoheaderHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoheaderHandler.java new file mode 100644 index 00000000000..e0f93c782b4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoheaderHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** + * @author Jeff Johnston + * + */ +public class AutoheaderHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new InvokeAutoheaderAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutomakeHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutomakeHandler.java new file mode 100644 index 00000000000..24776f9b6c7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutomakeHandler.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009,2011 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class AutomakeHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new InvokeAutomakeAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoreconfHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoreconfHandler.java new file mode 100644 index 00000000000..867bef3071a --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/AutoreconfHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** + * @author Jeff Johnston + * + */ +public class AutoreconfHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new InvokeAutoreconfAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAclocalAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAclocalAction.java new file mode 100644 index 00000000000..24de790370f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAction.java new file mode 100644 index 00000000000..2e2cd1ac802 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAction.java @@ -0,0 +1,474 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.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.autotools.ui.AutotoolsUIPlugin; +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.internal.autotools.core.AutotoolsNewMakeGenerator; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.ui.CUIPlugin; +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.Platform; +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.swt.widgets.Shell; + +public abstract class InvokeAction extends AbstractTargetAction { + + public final String SHELL_COMMAND = "sh"; //$NON-NLS-1$ + + 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$ + StringBuffer tmpTarget = new StringBuffer(); + while (!currentWord.endsWith("'")) { //$NON-NLS-1$ + tmpTarget.append(currentWord + " "); //$NON-NLS-1$ + if (!st.hasMoreTokens()) { + // quote not closed properly, so return null + return null; + } + currentWord = st.nextToken().trim(); + } + + tmpTarget.append(currentWord); + targetList.add(tmpTarget.toString()); + continue; + } + + if (currentWord.startsWith("\"")) { //$NON-NLS-1$ + StringBuffer tmpTarget = new StringBuffer(); + while (!currentWord.endsWith("\"")) { //$NON-NLS-1$ + tmpTarget.append(currentWord + " "); //$NON-NLS-1$ + if (!st.hasMoreTokens()) { + // double quote not closed properly, so return null + return null; + } + currentWord = st.nextToken().trim(); + } + + tmpTarget.append(currentWord); + targetList.add(tmpTarget.toString()); + 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 static 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$ + AutotoolsUIPlugin.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.cdt.autotools.ui.autotoolsConsole"); //$NON-NLS-1$ + console.start(project); + CUIPlugin.getDefault().startGlobalConsole(); + 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 = AutotoolsNewMakeGenerator.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()]); + } + + String[] newArgumentList; + + // Fix for bug #343905 + // For Windows and Mac, we cannot run a script directly (in this case, the + // autotools are scripts). We need to run "sh -c command args where command + // plus args is represented in a single string. + if (Platform.getOS().equals(Platform.OS_WIN32) + || Platform.getOS().equals(Platform.OS_MACOSX)) { + // Neither Mac or Windows support calling scripts directly. + StringBuffer command = new StringBuffer(strippedCommand); + for (String arg : argumentList) { + command.append(" " + arg); + } + newArgumentList = new String[] { "-c", command.toString() }; + } else { + // Otherwise, we don't need the -c argument and can present the command + // name and arguments as individual arguments + if (argumentList == null) + newArgumentList = new String[1]; + else + newArgumentList = new String[argumentList.length + 1]; + newArgumentList[0] = strippedCommand; + if (argumentList != null) + System.arraycopy(argumentList, 0, newArgumentList, 1, argumentList.length); + } + + OutputStream stdout = consoleOutStream; + OutputStream stderr = consoleOutStream; + + launcher.showCommand(true); + // Run the shell script via shell command. + Process proc = launcher.execute(new Path(SHELL_COMMAND), newArgumentList, 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(AutotoolsUIPlugin.getResourceString("MakeGenerator.refresh")); //$NON-NLS-1$ + try { + project.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + monitor.subTask(AutotoolsUIPlugin + .getResourceString("MakeGenerator.refresh.error")); //$NON-NLS-1$ + } + } else { + errMsg = launcher.getErrorMessage(); + } + + if (errMsg != null) + AutotoolsUIPlugin.logErrorMessage(errMsg); + + } catch (IOException e) { + AutotoolsUIPlugin.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutoconfAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutoconfAction.java new file mode 100644 index 00000000000..d679055eb78 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +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; + + +/** + * 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutoheaderAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutoheaderAction.java new file mode 100644 index 00000000000..21ef02258a9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutomakeAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutomakeAction.java new file mode 100644 index 00000000000..5e643261aa6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutoreconfAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeAutoreconfAction.java new file mode 100644 index 00000000000..0d61a9c8a07 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +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.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeLibtoolizeAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeLibtoolizeAction.java new file mode 100644 index 00000000000..6d6c6721624 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +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.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.LIBTOOLIZE_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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeMessages.java new file mode 100644 index 00000000000..dae5f1d055b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/InvokeMessages.properties new file mode 100644 index 00000000000..b2da117fef0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/LibtoolizeHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/LibtoolizeHandler.java new file mode 100644 index 00000000000..cb665f6c72b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/LibtoolizeHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** + * @author Jeff Johnston + * + */ +public class LibtoolizeHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new InvokeLibtoolizeAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/ReconfigureAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/ReconfigureAction.java new file mode 100644 index 00000000000..4dbbf0d397f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/ReconfigureAction.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.cdt.internal.autotools.ui.actions; + +import org.eclipse.cdt.internal.autotools.core.AutotoolsNewMakeGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.ui.CUIPlugin; +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; + + +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(); + AutotoolsNewMakeGenerator m = new AutotoolsNewMakeGenerator(); + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + CUIPlugin.getDefault().startGlobalConsole(); + m.initialize(project, info, monitor); + try { + m.reconfigure(); + } 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/ReconfigureHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/ReconfigureHandler.java new file mode 100644 index 00000000000..d83d02be425 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/ReconfigureHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +/** + * @author Jeff Johnston + * + */ +public class ReconfigureHandler extends AbstractAutotoolsHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + return execute(event, new ReconfigureAction()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/SingleInputDialog.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/SingleInputDialog.java new file mode 100644 index 00000000000..6161630f142 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/TwoInputDialog.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/actions/TwoInputDialog.java new file mode 100644 index 00000000000..82610b84258 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/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.cdt.internal.autotools.ui.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/autoconf/ProjectionFileUpdater.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/autoconf/ProjectionFileUpdater.java new file mode 100644 index 00000000000..475a084a06c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/autoconf/ProjectionFileUpdater.java @@ -0,0 +1,424 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 2007 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. - convert to use with Autoconf Editor + * Ed Swartz (NOKIA) - refactoring + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.autoconf; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditor; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfCaseElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElifElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfElseElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfForElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfIfElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroArgumentElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfMacroElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfRootElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfSelectElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfUntilElement; +import org.eclipse.cdt.autotools.ui.editors.parser.AutoconfWhileElement; +import org.eclipse.cdt.internal.autotools.ui.editors.automake.IReconcilingParticipant; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.projection.IProjectionListener; +import org.eclipse.jface.text.source.projection.ProjectionAnnotation; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.ui.texteditor.IDocumentProvider; + + +/** + * ProjectionMakefileUpdater + */ +public class ProjectionFileUpdater implements IProjectionListener { + + private static class AutoconfProjectionAnnotation extends ProjectionAnnotation { + + private AutoconfElement fElement; + private boolean fIsComment; + + public AutoconfProjectionAnnotation(AutoconfElement element, boolean isCollapsed, boolean isComment) { + super(isCollapsed); + fElement = element; + fIsComment = isComment; + } + + public AutoconfElement getElement() { + return fElement; + } + + public void setElement(AutoconfElement element) { + fElement = element; + } + + public boolean isComment() { + return fIsComment; + } + + } + + + public void install(AutoconfEditor editor, ProjectionViewer viewer) { + fEditor= editor; + fViewer= viewer; + fViewer.addProjectionListener(this); + } + + public void uninstall() { + if (isInstalled()) { + projectionDisabled(); + fViewer.removeProjectionListener(this); + fViewer= null; + fEditor= null; + } + } + + protected boolean isInstalled() { + return fEditor != null; + } + + private class ReconcilerParticipant implements IReconcilingParticipant { + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.IReconcilingParticipant#reconciled() + */ + public void reconciled() { + processReconcile(); + } + } + + private IDocument fCachedDocument; + private AutoconfEditor fEditor; + private ProjectionViewer fViewer; + private IReconcilingParticipant fParticipant; + + private boolean fAllowCollapsing = false; + private boolean fCollapseMacroDef = false; + private boolean fCollapseCase = false; + private boolean fCollapseConditional = false; + private boolean fCollapseLoop = false; + + /* + * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled() + */ + public void projectionEnabled() { + // http://home.ott.oti.com/teams/wswb/anon/out/vms/index.html + // projectionEnabled messages are not always paired with projectionDisabled + // i.e. multiple enabled messages may be sent out. + // we have to make sure that we disable first when getting an enable + // message. + projectionDisabled(); + + initialize(); + fParticipant= new ReconcilerParticipant(); + fEditor.addReconcilingParticipant(fParticipant); + } + + /* + * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled() + */ + public void projectionDisabled() { + fCachedDocument= null; + if (fParticipant != null) { + fEditor.addReconcilingParticipant(fParticipant); + fParticipant= null; + } + } + + public void initialize() { + + if (!isInstalled()) + return; + + initializePreferences(); + + try { + + IDocumentProvider provider= fEditor.getDocumentProvider(); + fCachedDocument= provider.getDocument(fEditor.getEditorInput()); + fAllowCollapsing= true; + +// IWorkingCopyManager manager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + AutoconfElement fInput= fEditor.getRootElement(); + + if (fInput != null) { + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model != null) { + Map<AutoconfProjectionAnnotation, Position> additions= computeAdditions(fInput); + model.removeAllAnnotations(); + model.replaceAnnotations(null, additions); + } + } + + } finally { + fCachedDocument= null; + fAllowCollapsing= false; + } + } + + private void initializePreferences() { + //FIXME: what to do with Makefile editor preferences + IPreferenceStore store = AutotoolsPlugin.getDefault().getPreferenceStore(); + fCollapseMacroDef = store.getBoolean(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_MACRODEF); + fCollapseCase = store.getBoolean(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_CASE); + fCollapseConditional = store.getBoolean(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_CONDITIONAL); + fCollapseLoop = store.getBoolean(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_LOOP); + } + + private Map<AutoconfProjectionAnnotation, Position> computeAdditions(AutoconfElement root) { + Map<AutoconfProjectionAnnotation, Position> map= new HashMap<AutoconfProjectionAnnotation, Position>(); + if (root instanceof AutoconfRootElement) + computeAdditions(root.getChildren(), map); + return map; + } + + private void computeAdditions(Object[] elements, Map<AutoconfProjectionAnnotation, Position> map) { + for (int i= 0; i < elements.length; i++) { + AutoconfElement element= (AutoconfElement)elements[i]; + + computeAdditions(element, map); + + if (element.hasChildren()) { + computeAdditions(element.getChildren(), map); + } + } + } + + private void computeAdditions(AutoconfElement element, Map<AutoconfProjectionAnnotation, Position> map) { + + boolean createProjection= false; + + @SuppressWarnings("unused") + boolean collapse= false; + + if (element instanceof AutoconfIfElement || + element instanceof AutoconfElseElement || + element instanceof AutoconfElifElement) { + collapse= fAllowCollapsing && fCollapseConditional; + createProjection= true; + } else if (element instanceof AutoconfMacroElement) { + collapse= fAllowCollapsing && fCollapseMacroDef; + createProjection= true; + } else if (element instanceof AutoconfMacroArgumentElement) { + collapse= fAllowCollapsing && fCollapseMacroDef; + createProjection= true; + } else if (element instanceof AutoconfCaseElement) { + collapse= fAllowCollapsing && fCollapseCase; + createProjection= true; + } else if (element instanceof AutoconfForElement || + element instanceof AutoconfWhileElement || + element instanceof AutoconfUntilElement || + element instanceof AutoconfSelectElement) { + collapse = fAllowCollapsing && fCollapseLoop; + createProjection = true; + } + + if (createProjection) { + Position position= createProjectionPosition(element); + if (position != null) { + map.put(new AutoconfProjectionAnnotation(element, fAllowCollapsing, true), position); + } + } + } + + private Position createProjectionPosition(AutoconfElement element) { + if (fCachedDocument == null) + return null; + int offset = 0; + try { + int startLine = 0; + int endLine = 0; + startLine = fCachedDocument.getLineOfOffset(element.getStartOffset()); + endLine = fCachedDocument.getLineOfOffset(element.getEndOffset()); + + if (startLine != endLine) { + offset= fCachedDocument.getLineOffset(startLine); + int endOffset = fCachedDocument.getLineOffset(endLine) + fCachedDocument.getLineLength(endLine); + return new Position(offset, endOffset - offset); + } + } catch (BadLocationException x) { + // We should only get here if we try and read the line past EOF + return new Position(offset, fCachedDocument.getLength() - 1); + } + return null; + } + + public void processReconcile() { + if (!isInstalled()) + return; + + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model == null) + return; + + try { + IDocumentProvider provider= fEditor.getDocumentProvider(); + fCachedDocument= provider.getDocument(fEditor.getEditorInput()); + fAllowCollapsing= false; + + Map<AutoconfProjectionAnnotation, Position> additions= new HashMap<AutoconfProjectionAnnotation, Position>(); + List<AutoconfProjectionAnnotation> deletions= new ArrayList<AutoconfProjectionAnnotation>(); + List<AutoconfProjectionAnnotation> updates = new ArrayList<AutoconfProjectionAnnotation>(); + + Map<AutoconfProjectionAnnotation, Position> updated= computeAdditions(fEditor.getRootElement()); + + Map<AutoconfElement, List<AutoconfProjectionAnnotation>> previous= createAnnotationMap(model); + + + Iterator<AutoconfProjectionAnnotation> e= updated.keySet().iterator(); + while (e.hasNext()) { + AutoconfProjectionAnnotation annotation= (AutoconfProjectionAnnotation) e.next(); + AutoconfElement element= annotation.getElement(); + Position position= (Position) updated.get(annotation); + + List<AutoconfProjectionAnnotation> annotations= previous.get(element); + if (annotations == null) { + additions.put(annotation, position); + } else { + Iterator<AutoconfProjectionAnnotation> x= annotations.iterator(); + while (x.hasNext()) { + AutoconfProjectionAnnotation a= (AutoconfProjectionAnnotation) x.next(); + if (annotation.isComment() == a.isComment()) { + Position p= model.getPosition(a); + if (p != null && !position.equals(p)) { + p.setOffset(position.getOffset()); + p.setLength(position.getLength()); + updates.add(a); + } + x.remove(); + break; + } + } + + if (annotations.isEmpty()) + previous.remove(element); + } + } + + Iterator<List<AutoconfProjectionAnnotation>> e2 = previous.values().iterator(); + while (e2.hasNext()) { + List<AutoconfProjectionAnnotation> list= e2.next(); + int size= list.size(); + for (int i= 0; i < size; i++) + deletions.add(list.get(i)); + } + + match(model, deletions, additions, updates); + + Annotation[] removals= new Annotation[deletions.size()]; + deletions.toArray(removals); + Annotation[] changes= new Annotation[updates.size()]; + updates.toArray(changes); + model.modifyAnnotations(removals, additions, changes); + + } finally { + fCachedDocument= null; + fAllowCollapsing= true; + } + } + + private void match(ProjectionAnnotationModel model, List<AutoconfProjectionAnnotation> deletions, Map<AutoconfProjectionAnnotation, Position> additions, List<AutoconfProjectionAnnotation> changes) { + if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty())) + return; + + List<AutoconfProjectionAnnotation> newDeletions= new ArrayList<AutoconfProjectionAnnotation>(); + List<AutoconfProjectionAnnotation> newChanges= new ArrayList<AutoconfProjectionAnnotation>(); + + Iterator<AutoconfProjectionAnnotation> deletionIterator= deletions.iterator(); + outer: while (deletionIterator.hasNext()) { + AutoconfProjectionAnnotation deleted= (AutoconfProjectionAnnotation) deletionIterator.next(); + Position deletedPosition= model.getPosition(deleted); + if (deletedPosition == null) + continue; + + Iterator<AutoconfProjectionAnnotation> changesIterator= changes.iterator(); + while (changesIterator.hasNext()) { + AutoconfProjectionAnnotation changed= (AutoconfProjectionAnnotation) changesIterator.next(); + if (deleted.isComment() == changed.isComment()) { + Position changedPosition= model.getPosition(changed); + if (changedPosition == null) + continue; + + if (deletedPosition.getOffset() == changedPosition.getOffset()) { + + deletedPosition.setLength(changedPosition.getLength()); + deleted.setElement(changed.getElement()); + + deletionIterator.remove(); + newChanges.add(deleted); + + changesIterator.remove(); + newDeletions.add(changed); + + continue outer; + } + } + } + + Iterator<AutoconfProjectionAnnotation> additionsIterator= additions.keySet().iterator(); + while (additionsIterator.hasNext()) { + AutoconfProjectionAnnotation added= (AutoconfProjectionAnnotation) additionsIterator.next(); + if (deleted.isComment() == added.isComment()) { + Position addedPosition= (Position) additions.get(added); + + if (deletedPosition.getOffset() == addedPosition.getOffset()) { + + deletedPosition.setLength(addedPosition.getLength()); + deleted.setElement(added.getElement()); + + deletionIterator.remove(); + newChanges.add(deleted); + + additionsIterator.remove(); + + break; + } + } + } + } + + deletions.addAll(newDeletions); + changes.addAll(newChanges); + } + + private Map<AutoconfElement, List<AutoconfProjectionAnnotation>> createAnnotationMap(IAnnotationModel model) { + Map<AutoconfElement, List<AutoconfProjectionAnnotation>> map= new HashMap<AutoconfElement, List<AutoconfProjectionAnnotation>>(); + @SuppressWarnings("unchecked") + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Object annotation= e.next(); + if (annotation instanceof AutoconfProjectionAnnotation) { + AutoconfProjectionAnnotation directive= (AutoconfProjectionAnnotation) annotation; + List<AutoconfProjectionAnnotation> list= map.get(directive.getElement()); + if (list == null) { + list= new ArrayList<AutoconfProjectionAnnotation>(2); + map.put(directive.getElement(), list); + } + list.add(directive); + } + } + return map; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractElementListSelectionDialog.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractElementListSelectionDialog.java new file mode 100644 index 00000000000..b557d224946 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractElementListSelectionDialog.java @@ -0,0 +1,283 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +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.jface.viewers.ILabelProvider; + +/** + * A class to select one or more elements out of an indexed property + */ +public abstract class AbstractElementListSelectionDialog extends SelectionStatusDialog { + + private ILabelProvider fRenderer; + private boolean fIgnoreCase; + private boolean fIsMultipleSelection; + + private SelectionList fSelectionList; + private Label fMessage; + private ISelectionValidator fValidator; + + private String fMessageText; + private String fEmptyListMessage; + private String fNothingSelectedMessage; + + private StatusInfo fCurrStatus; + + /* + * @private + */ + protected void access$superOpen() { + super.open(); + } + /* + * @private + * @see Dialog#cancelPressed + */ + protected void cancelPressed() { + setResult(null); + super.cancelPressed(); + } + protected Point computeInitialSize() { + return new Point(convertWidthInCharsToPixels(60), convertHeightInCharsToPixels(18)); + } + /* + * @private + * @see Window#createDialogArea(Composite) + */ + protected Control createDialogArea(Composite parent) { + Composite contents= (Composite)super.createDialogArea(parent); + + fMessage= createMessage(contents); + + int flags= fIsMultipleSelection ? SWT.MULTI : SWT.SINGLE; + fSelectionList= new SelectionList(contents, flags | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, + fRenderer, fIgnoreCase); + + fSelectionList.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + handleDoubleClick(); + } + public void widgetSelected(SelectionEvent e) { + verifyCurrentSelection(); + } + }); + + GridData spec= new GridData(); + Point initialSize= computeInitialSize(); + spec.widthHint= initialSize.x; + spec.heightHint= initialSize.y; + spec.grabExcessVerticalSpace= true; + spec.grabExcessHorizontalSpace= true; + spec.horizontalAlignment= GridData.FILL; + spec.verticalAlignment= GridData.FILL; + fSelectionList.setLayoutData(spec); + + return contents; + } + /** + * Creates the message text widget and sets layout data. + */ + protected Label createMessage(Composite parent) { + Label text= new Label(parent, SWT.NULL); + text.setText(fMessageText); + GridData spec= new GridData(); + spec.grabExcessVerticalSpace= false; + spec.grabExcessHorizontalSpace= true; + spec.horizontalAlignment= GridData.FILL; + spec.verticalAlignment= GridData.BEGINNING; + text.setLayoutData(spec); + return text; + } + /* + * @private + * @see Window#create(Shell) + */ + public void create() { + super.create(); + if (isEmptyList()) { + fMessage.setEnabled(false); + fSelectionList.setEnabled(false); + } else { + verifyCurrentSelection(); + fSelectionList.selectFilterText(); + fSelectionList.setFocus(); + } + } + /** + * Returns the currently used filter text. + */ + protected String getFilter() { + return fSelectionList.getFilter(); + } + /** + * Returns the selection indices. + */ + protected int[] getSelectionIndices() { + return fSelectionList.getSelectionIndices(); + } + /** + * Returns the widget selection. Returns empty list when the widget is not + * usable. + */ + protected List<Object> getWidgetSelection() { + if (fSelectionList == null || fSelectionList.isDisposed()) + return new ArrayList<Object>(0); + return fSelectionList.getSelection(); + } + /** + * An element as been selected in the list by double clicking on it. + * Emulate a OK button pressed to close the dialog. + */ + protected abstract void handleDoubleClick(); + /** + * Checks whether the list of elements is empty or not. + */ + protected boolean isEmptyList() { + if (fSelectionList == null) + return true; + return fSelectionList.isEmptyList(); + } + /** + * Constructs a list selection dialog. + * @param renderer The label renderer used + * @param ignoreCase Decides if the match string ignores lower/upppr case + * @param multipleSelection Allow multiple selection + */ + protected AbstractElementListSelectionDialog(Shell parent, String title, Image image, ILabelProvider renderer, boolean ignoreCase, boolean multipleSelection) { + super(parent); + setTitle(title); + setImage(image); + fRenderer= renderer; + fIgnoreCase= ignoreCase; + fIsMultipleSelection= multipleSelection; + + fMessageText= ""; //$NON-NLS-1$ + + fCurrStatus= new StatusInfo(); + + fValidator= null; + fEmptyListMessage= ""; //$NON-NLS-1$ + fNothingSelectedMessage= ""; //$NON-NLS-1$ + } + /** + * Constructs a list selection dialog. + * @param renderer The label renderer used + * @param ignoreCase Decides if the match string ignores lower/upppr case + * @param multipleSelection Allow multiple selection + */ + protected AbstractElementListSelectionDialog(Shell parent, ILabelProvider renderer, boolean ignoreCase, boolean multipleSelection) { + this(parent, "", null, renderer, ignoreCase, multipleSelection); //$NON-NLS-1$ + } + /* + * @private + */ + public int open() { + BusyIndicator.showWhile(null, new Runnable() { + public void run() { + access$superOpen(); + } + }); + return getReturnCode() ; + } + /** + * Refilters the current list according to the filter entered into the + * text edit field. + */ + protected void refilter() { + fSelectionList.filter(true); + } + /** + * If a empty-list message is set, a error message is shown + * Must be set before widget creation + */ + public void setEmptyListMessage(String message) { + fEmptyListMessage= message; + } + /** + * Sets the filter text to the given value. + */ + protected void setFilter(String text, boolean refilter) { + fSelectionList.setFilter(text, refilter); + } + /** + * Sets the message to be shown above the match text field. + * Must be set before widget creation + */ + public void setMessage(String message) { + fMessageText= message; + } + /** + * If the selection is empty, this message is shown + */ + public void setNothingSelectedMessage(String message) { + fNothingSelectedMessage= message; + } + /** + * Selects the elements in the list determined by the given + * selection indices. + */ + protected void setSelection(int[] selection) { + fSelectionList.setSelection(selection); + } + /** + * Initializes the selection list widget with the given list of + * elements. + */ + protected void setSelectionListElements(List<Object> elements, boolean refilter) { + fSelectionList.setElements(elements, refilter); + } + /** + * A validator can be set to check if the current selection + * is valid + */ + public void setValidator(ISelectionValidator validator) { + fValidator= validator; + } + /** + * Verifies the current selection and updates the status line + * accordingly. + */ + protected boolean verifyCurrentSelection() { + List<Object> sel= getWidgetSelection(); + int length= sel.size(); + if (length > 0) { + if (fValidator != null) { + fValidator.isValid(sel.toArray(), fCurrStatus); + } else { + fCurrStatus.setOK(); + } + } else { + if (isEmptyList()) { + fCurrStatus.setError(fEmptyListMessage); + } else { + fCurrStatus.setError(fNothingSelectedMessage); + } + } + updateStatus(fCurrStatus); + return fCurrStatus.isOK(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractMakefile.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractMakefile.java new file mode 100644 index 00000000000..6affd8923bc --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractMakefile.java @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +/** + * Makefile : ( statement ) * + * statement : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule + * inference_rule : target ':' <nl> ( <tab> command <nl> ) + + * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl> + [ ( command ) * ] + * macro_definition : string '=' (string)* + * comments : ('#' (string) <nl>) * + * empty : <nl> + * command : <tab> prefix_command string <nl> + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" + */ + +public abstract class AbstractMakefile extends Parent implements IMakefile { + + private URI filename; + + public AbstractMakefile(Directive parent) { + super(parent); + } + + public abstract IDirective[] getBuiltins(); + + public IRule[] getRules() { + IDirective[] stmts = getDirectives(true); + List<IRule> array = new ArrayList<IRule>(stmts.length); + for (int i = 0; i < stmts.length; i++) { + if (stmts[i] instanceof IRule) { + array.add((IRule)stmts[i]); + } + } + return (IRule[]) array.toArray(new IRule[0]); + } + + public IRule[] getRules(String target) { + IRule[] rules = getRules(); + List<IRule> array = new ArrayList<IRule>(rules.length); + for (int i = 0; i < rules.length; i++) { + if (rules[i].getTarget().toString().equals(target)) { + array.add(rules[i]); + } + } + return (IRule[]) array.toArray(new IRule[0]); + } + + public IInferenceRule[] getInferenceRules() { + IRule[] rules = getRules(); + List<IInferenceRule> array = new ArrayList<IInferenceRule>(rules.length); + for (int i = 0; i < rules.length; i++) { + if (rules[i] instanceof IInferenceRule) { + array.add((IInferenceRule)rules[i]); + } + } + return (IInferenceRule[]) array.toArray(new IInferenceRule[0]); + } + + public IInferenceRule[] getInferenceRules(String target) { + IInferenceRule[] irules = getInferenceRules(); + List<IInferenceRule> array = new ArrayList<IInferenceRule>(irules.length); + for (int i = 0; i < irules.length; i++) { + if (irules[i].getTarget().toString().equals(target)) { + array.add(irules[i]); + } + } + return (IInferenceRule[]) array.toArray(new IInferenceRule[0]); + } + + public ITargetRule[] getTargetRules() { + IRule[] trules = getRules(); + List<ITargetRule> array = new ArrayList<ITargetRule>(trules.length); + for (int i = 0; i < trules.length; i++) { + if (trules[i] instanceof ITargetRule) { + array.add((ITargetRule)trules[i]); + } + } + return (ITargetRule[]) array.toArray(new ITargetRule[0]); + } + + public ITargetRule[] getTargetRules(String target) { + ITargetRule[] trules = getTargetRules(); + List<ITargetRule> array = new ArrayList<ITargetRule>(trules.length); + for (int i = 0; i < trules.length; i++) { + if (trules[i].getTarget().toString().equals(target)) { + array.add(trules[i]); + } + } + return (ITargetRule[]) array.toArray(new ITargetRule[0]); + } + + public IMacroDefinition[] getMacroDefinitions() { + IDirective[] stmts = getDirectives(true); + List<IMacroDefinition> array = new ArrayList<IMacroDefinition>(stmts.length); + for (int i = 0; i < stmts.length; i++) { + if (stmts[i] instanceof IMacroDefinition) { + array.add((IMacroDefinition)stmts[i]); + } + } + return (IMacroDefinition[]) array.toArray(new IMacroDefinition[0]); + } + + public IMacroDefinition[] getMacroDefinitions(String name) { + IMacroDefinition[] variables = getMacroDefinitions(); + List<IMacroDefinition> array = new ArrayList<IMacroDefinition>(variables.length); + for (int i = 0; i < variables.length; i++) { + if (variables[i].getName().equals(name)) { + array.add(variables[i]); + } + } + return (IMacroDefinition[]) array.toArray(new IMacroDefinition[0]); + } + + public IMacroDefinition[] getBuiltinMacroDefinitions() { + IDirective[] stmts = getBuiltins(); + List<IMacroDefinition> array = new ArrayList<IMacroDefinition>(stmts.length); + for (int i = 0; i < stmts.length; i++) { + if (stmts[i] instanceof IMacroDefinition) { + array.add((IMacroDefinition)stmts[i]); + } + } + return (IMacroDefinition[]) array.toArray(new IMacroDefinition[0]); + } + + public IMacroDefinition[] getBuiltinMacroDefinitions(String name) { + IMacroDefinition[] variables = getBuiltinMacroDefinitions(); + List<IMacroDefinition> array = new ArrayList<IMacroDefinition>(variables.length); + for (int i = 0; i < variables.length; i++) { + if (variables[i].getName().equals(name)) { + array.add(variables[i]); + } + } + return (IMacroDefinition[]) array.toArray(new IMacroDefinition[0]); + } + + public IInferenceRule[] getBuiltinInferenceRules() { + IDirective[] stmts = getBuiltins(); + List<IInferenceRule> array = new ArrayList<IInferenceRule>(stmts.length); + for (int i = 0; i < stmts.length; i++) { + if (stmts[i] instanceof IInferenceRule) { + array.add((IInferenceRule)stmts[i]); + } + } + return (IInferenceRule[]) array.toArray(new IInferenceRule[0]); + } + + public IInferenceRule[] getBuiltinInferenceRules(String target) { + IInferenceRule[] irules = getBuiltinInferenceRules(); + List<IInferenceRule> array = new ArrayList<IInferenceRule>(irules.length); + for (int i = 0; i < irules.length; i++) { + if (irules[i].getTarget().toString().equals(target)) { + array.add(irules[i]); + } + } + return (IInferenceRule[]) array.toArray(new IInferenceRule[0]); + } + + public String expandString(String line) { + return expandString(line, false); + } + + public String expandString(String line, boolean recursive) { + int len = line.length(); + boolean foundDollar = false; + boolean inMacro = false; + StringBuffer buffer = new StringBuffer(); + StringBuffer macroName = new StringBuffer(); + for (int i = 0; i < len; i++) { + char c = line.charAt(i); + switch(c) { + case '$': + // '$$' --> '$' + if (foundDollar) { + buffer.append(c); + foundDollar = false; + } else { + foundDollar = true; + } + break; + case '(': + case '{': + if (foundDollar) { + inMacro = true; + } else { + buffer.append(c); + } + break; + case ')': + case '}': + if (inMacro) { + String name = macroName.toString(); + if (name.length() > 0) { + IMacroDefinition[] defs = getMacroDefinitions(name); + if (defs.length == 0) { + defs = getBuiltinMacroDefinitions(name); + } + if (defs.length > 0) { + String result = defs[0].getValue().toString(); + if (result.indexOf('$') != -1 && recursive) { + result = expandString(result, recursive); + } + buffer.append(result); + } else { // Do not expand + buffer.append('$').append('(').append(name).append(')'); + } + } + macroName.setLength(0); + inMacro = false; + } else { + buffer.append(c); + } + break; + default: + if (inMacro) { + macroName.append(c); + } else if (foundDollar) { + String name = String.valueOf(c); + IMacroDefinition[] defs = getMacroDefinitions(name); + if (defs.length == 0) { + defs = getBuiltinMacroDefinitions(name); + } + if (defs.length > 0) { + String result = defs[0].getValue().toString(); + if (result.indexOf('$') != -1 && recursive) { + result = expandString(result, recursive); + } + buffer.append(result); + } else { + // nothing found + buffer.append('$').append(c); + } + inMacro = false; + } else { + buffer.append(c); + } + foundDollar = false; + break; + } + } + return buffer.toString(); + } + + public URI getFileURI() { + return filename; + } + + public void setFileURI(URI filename) { + this.filename = filename; + } + + + public IMakefile getMakefile() { + return this; + } + + public IMakefileReaderProvider getMakefileReaderProvider() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMakefile#parse(java.net.URI, org.eclipse.cdt.make.core.makefile.IMakefileReaderProvider) + */ + public void parse(URI fileURI, + IMakefileReaderProvider makefileReaderProvider) throws IOException { + // not used + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractMakefileCodeScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractMakefileCodeScanner.java new file mode 100644 index 00000000000..7066798f204 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AbstractMakefileCodeScanner.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; + + +/** + * AbstractMakefileEditorScanner + */ +public abstract class AbstractMakefileCodeScanner extends RuleBasedScanner { + + private Map<String, Token> fTokenMap= new HashMap<String, Token>(); + private String[] fPropertyNamesColor; + /** + * Preference keys for boolean preferences which are <code>true</code>, + * iff the corresponding token should be rendered bold. + */ + private String[] fPropertyNamesBold; + /** + * Preference keys for boolean preferences which are <code>true</code>, + * iff the corresponding token should be rendered italic. + */ + private String[] fPropertyNamesItalic; + + + /** + * Returns the list of preference keys which define the tokens + * used in the rules of this scanner. + */ + abstract protected String[] getTokenProperties(); + + /** + * Creates the list of rules controlling this scanner. + */ + abstract protected List<IRule> createRules(); + + /** + * Must be called after the constructor has been called. + */ + public final void initialize() { + + fPropertyNamesColor= getTokenProperties(); + int length= fPropertyNamesColor.length; + fPropertyNamesBold= new String[length]; + fPropertyNamesItalic= new String[length]; + + for (int i= 0; i < length; i++) { + fPropertyNamesBold[i]= fPropertyNamesColor[i] + MakefileEditorPreferenceConstants.EDITOR_BOLD_SUFFIX; + fPropertyNamesItalic[i]= fPropertyNamesColor[i] + MakefileEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX; + addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i]); + } + + initializeRules(); + } + + private void initializeRules() { + List<IRule> rules= createRules(); + if (rules != null) { + IRule[] result= new IRule[rules.size()]; + rules.toArray(result); + setRules(result); + } + } + + protected Token getToken(String key) { + return (Token) fTokenMap.get(key); + } + + private void addToken(String colorKey, String boldKey, String italicKey) { + fTokenMap.put(colorKey, new Token(createTextAttribute(colorKey, boldKey, italicKey))); + } + + private int indexOf(String property) { + if (property != null) { + int length= fPropertyNamesColor.length; + for (int i= 0; i < length; i++) { + if (property.equals(fPropertyNamesColor[i]) || property.equals(fPropertyNamesBold[i]) || property.equals(fPropertyNamesItalic[i])) + return i; + } + } + return -1; + } + + public boolean affectsBehavior(PropertyChangeEvent event) { + return indexOf(event.getProperty()) >= 0; + } + + public void adaptToPreferenceChange(PropertyChangeEvent event) { + String p= event.getProperty(); + int index= indexOf(p); + Token token= getToken(fPropertyNamesColor[index]); + if (fPropertyNamesColor[index].equals(p)) + adaptToColorChange(event, token); + else if (fPropertyNamesBold[index].equals(p)) + adaptToStyleChange(event, token, SWT.BOLD); + else if (fPropertyNamesItalic[index].equals(p)) + adaptToStyleChange(event, token, SWT.ITALIC); + } + + protected void adaptToColorChange(PropertyChangeEvent event, Token token) { + RGB rgb= null; + Object value= event.getNewValue(); + if (value instanceof RGB) { + rgb= (RGB) value; + } else if (value instanceof String) { + rgb= StringConverter.asRGB((String) value); + } + + if (rgb != null) { + TextAttribute attr= (TextAttribute) token.getData(); + token.setData(new TextAttribute(ColorManager.getDefault().getColor(rgb), attr.getBackground(), attr.getStyle())); + } + } + + protected void adaptToStyleChange(PropertyChangeEvent event, Token token, int styleAttribute) { + if (token == null) { + return; + } + boolean eventValue= false; + Object value= event.getNewValue(); + if (value instanceof Boolean) { + eventValue= ((Boolean) value).booleanValue(); + } else if (IPreferenceStore.TRUE.equals(value)) { + eventValue= true; + } + + TextAttribute attr= (TextAttribute) token.getData(); + boolean activeValue= (attr.getStyle() & styleAttribute) == styleAttribute; + if (activeValue != eventValue) { + token.setData(new TextAttribute(attr.getForeground(), attr.getBackground(), eventValue ? attr.getStyle() | styleAttribute : attr.getStyle() & ~styleAttribute)); + } + } + + protected TextAttribute createTextAttribute(String colorID, String boldKey, String italicKey) { + Color color= null; + if (colorID != null) { + color= AutomakeEditorFactory.getPreferenceColor(colorID); + } + IPreferenceStore store= AutotoolsPlugin.getDefault().getPreferenceStore(); + int style= store.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL; + if (store.getBoolean(italicKey)) { + style |= SWT.ITALIC; + } + return new TextAttribute(color, null, style); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ArchiveTarget.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ArchiveTarget.java new file mode 100644 index 00000000000..66f52d50241 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ArchiveTarget.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * IArchiveTarget + */ +public class ArchiveTarget extends Target { + + String member; + + public ArchiveTarget(String lib, String obj) { + super(lib); + member = obj; + } + + public String getMember() { + return member; + } + + public String getLibaryName() { + return toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutoconfSubstRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutoconfSubstRule.java new file mode 100644 index 00000000000..9af2123a547 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutoconfSubstRule.java @@ -0,0 +1,92 @@ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +public class AutoconfSubstRule implements IPredicateRule { + + private IToken token; + private char[][] fLineDelimiters; + private char[][] fSortedLineDelimiters; + + private static class DecreasingCharArrayLengthComparator implements Comparator<Object> { + public int compare(Object o1, Object o2) { + return ((char[]) o2).length - ((char[]) o1).length; + } + } + + private Comparator<Object> fLineDelimiterComparator= new DecreasingCharArrayLengthComparator(); + + public AutoconfSubstRule(IToken token) { + this.token = token; + } + + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + char[][] originalDelimiters= scanner.getLegalLineDelimiters(); + int count= originalDelimiters.length; + if (fLineDelimiters == null || originalDelimiters.length != count) { + fSortedLineDelimiters= new char[count][]; + } else { + while (count > 0 && fLineDelimiters[count-1] == originalDelimiters[count-1]) + count--; + } + if (count != 0) { + fLineDelimiters= originalDelimiters; + System.arraycopy(fLineDelimiters, 0, fSortedLineDelimiters, 0, fLineDelimiters.length); + Arrays.sort(fSortedLineDelimiters, fLineDelimiterComparator); + } + + int c; + boolean okToScan = resume; + int charCount = 0; + + if (!resume) { + // Not resuming. Verify first char is '@'. + c = scanner.read(); + ++charCount; + if (c == '@') { + okToScan = true; + } + } + + if (okToScan) { + // We want to make sure we have a valid id (not @@) or (@_@). When + // we resume, we have no choice but to assume it is valid so far. + boolean isId = resume; + ++charCount; + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') { + // A valid id has some alphabetic character in it. + isId = true; + } + else if (c >= '0' && c <= '9' || c == '_') { + ; // continue + } + else if (c == '@' && isId) + return getSuccessToken(); + else + break; + ++charCount; + } + } + + for (int i = 0; i < charCount; ++i) + scanner.unread(); + + return Token.UNDEFINED; + } + + public IToken getSuccessToken() { + return token; + } + + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeCompletionProcessor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeCompletionProcessor.java new file mode 100644 index 00000000000..cba9d060d11 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeCompletionProcessor.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * Mostly copied from makefileCompletionProcessor which has the following + * copyright notice: + * + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ContextInformation; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationPresenter; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IEditorPart; + + +public class AutomakeCompletionProcessor implements IContentAssistProcessor { + + /** + * Simple content assist tip closer. The tip is valid in a range + * of 5 characters around its popup location. + */ + protected static class Validator implements IContextInformationValidator, IContextInformationPresenter { + + protected int fInstallOffset; + + /* + * @see IContextInformationValidator#isContextInformationValid(int) + */ + public boolean isContextInformationValid(int offset) { + return Math.abs(fInstallOffset - offset) < 5; + } + + /* + * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int) + */ + public void install(IContextInformation info, ITextViewer viewer, int offset) { + fInstallOffset = offset; + } + + /* + * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int, TextPresentation) + */ + public boolean updatePresentation(int documentPosition, TextPresentation presentation) { + return false; + } + } + + public static class DirectiveComparator implements Comparator<Object> { + + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) { + String name1; + String name2; + + if (o1 instanceof IMacroDefinition) { + name1 = ((IMacroDefinition)o1).getName(); + } else if (o1 instanceof IRule) { + name1 = ((IRule)o1).getTarget().toString(); + } else { + name1 =""; //$NON-NLS-1$ + } + + if (o2 instanceof IMacroDefinition) { + name2 = ((IMacroDefinition)o1).getName(); + } else if (o2 instanceof IRule) { + name2 = ((IRule)o1).getTarget().toString(); + } else { + name2 =""; //$NON-NLS-1$ + } + + //return String.CASE_INSENSITIVE_ORDER.compare(name1, name2); + return name1.compareToIgnoreCase(name2); + } + + } + protected IContextInformationValidator fValidator = new Validator(); + protected Image imageMacro = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_MACRO); + protected Image imageTarget = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_TARGET_RULE); + + protected CompletionProposalComparator comparator = new CompletionProposalComparator(); + protected IEditorPart fEditor; + protected IWorkingCopyManager fManager; + + public AutomakeCompletionProcessor(IEditorPart editor) { + fEditor = editor; + fManager = AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { + WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset); + boolean macro = WordPartDetector.inMacro(viewer, documentOffset); + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + IDirective[] statements = null; + if (macro) { + IDirective[] m1 = makefile.getMacroDefinitions(); + IDirective[] m2 = makefile.getBuiltinMacroDefinitions(); + statements = new IDirective[m1.length + m2.length]; + System.arraycopy(m1, 0, statements, 0, m1.length); + System.arraycopy(m2, 0, statements, m1.length, m2.length); + } else { + statements = makefile.getTargetRules(); + } + + ArrayList<ICompletionProposal> proposalList = new ArrayList<ICompletionProposal>(statements.length); + + // iterate over all the different categories + for (int i = 0; i < statements.length; i++) { + String name = null; + Image image = null; + String infoString = "";//getContentInfoString(name); //$NON-NLS-1$ + if (statements[i] instanceof IMacroDefinition) { + name = ((IMacroDefinition) statements[i]).getName(); + image = imageMacro; + infoString = ((IMacroDefinition)statements[i]).getValue().toString(); + } else if (statements[i] instanceof IRule) { + name = ((IRule) statements[i]).getTarget().toString(); + image = imageTarget; + infoString = name; + } + if (name != null && name.startsWith(wordPart.toString())) { + IContextInformation info = new ContextInformation(name, infoString); + String displayString = (name.equals(infoString) ? name : name + " - " + infoString); //$NON-NLS-1$ + ICompletionProposal result = + new CompletionProposal( + name, + wordPart.getOffset(), + wordPart.toString().length(), + name.length(), + image, + displayString, + info, + infoString); + proposalList.add(result); + } + } + ICompletionProposal[] proposals = (ICompletionProposal[]) proposalList.toArray(new ICompletionProposal[0]); + Arrays.sort(proposals, comparator); + return proposals; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { + WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset); + boolean macro = WordPartDetector.inMacro(viewer, documentOffset); + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + ArrayList<String> contextList = new ArrayList<String>(); + if (macro) { + IDirective[] statements = makefile.getMacroDefinitions(); + for (int i = 0; i < statements.length; i++) { + if (statements[i] instanceof IMacroDefinition) { + String name = ((IMacroDefinition) statements[i]).getName(); + if (name != null && name.equals(wordPart.toString())) { + String value = ((IMacroDefinition) statements[i]).getValue().toString(); + if (value != null && value.length() > 0) { + contextList.add(value); + } + } + } + } + statements = makefile.getBuiltinMacroDefinitions(); + for (int i = 0; i < statements.length; i++) { + if (statements[i] != null) { + String name = ((IMacroDefinition) statements[i]).getName(); + if (name != null && name.equals(wordPart.toString())) { + String value = ((IMacroDefinition) statements[i]).getValue().toString(); + if (value != null && value.length() > 0) { + contextList.add(value); + } + } + } + } + } + + IContextInformation[] result = new IContextInformation[contextList.size()]; + for (int i = 0; i < result.length; i++) { + String context = (String)contextList.get(i); + result[i] = new ContextInformation(imageMacro, wordPart.toString(), context); + } + return result; + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return fValidator; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeConfigMacro.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeConfigMacro.java new file mode 100644 index 00000000000..bfaf671c9de --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeConfigMacro.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + + + +public class AutomakeConfigMacro extends Directive { + String name; + + public AutomakeConfigMacro(Directive parent, String name) { + super(parent); + this.name = name; + } + + public String getName() { + return name; + } + + public String toString() { + return name + "\n"; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeDocumentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeDocumentProvider.java new file mode 100644 index 00000000000..7b9b6da9e57 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeDocumentProvider.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MakefileDocumentProvider for Automake + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.util.Iterator; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IURIEditorInput; +import org.eclipse.ui.editors.text.TextFileDocumentProvider; + + +public class AutomakeDocumentProvider extends TextFileDocumentProvider implements IMakefileDocumentProvider { + + /** + * Remembers a IMakefile for each element. + */ + protected class AutomakefileFileInfo extends FileInfo { + public IMakefile fCopy; + } + + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createEmptyFileInfo() + */ + protected FileInfo createEmptyFileInfo() { + return new AutomakefileFileInfo(); + } + + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createFileInfo(java.lang.Object) + */ + protected FileInfo createFileInfo(Object element) throws CoreException { + IMakefile original = null; + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + if (input.getFile().exists()) + original= createMakefile(input.getFile().getLocation().toOSString()); + } else if (element instanceof IURIEditorInput) { + IURIEditorInput input = (IURIEditorInput)element; + original = createMakefile(input.getURI().getPath().toString()); + } + if (original == null) + return null; + + FileInfo info= super.createFileInfo(element); + if (!(info instanceof AutomakefileFileInfo)) { + return null; + } + + AutomakefileFileInfo makefileInfo= (AutomakefileFileInfo) info; + setUpSynchronization(makefileInfo); + + makefileInfo.fCopy = original; + + return makefileInfo; + } + + /** + */ + private IMakefile createMakefile(String fileName) { + IMakefile makefile = null; + Automakefile automakefile = new Automakefile(); + try { + automakefile.parse(fileName); + } catch (IOException e) { + } + makefile = automakefile; + return makefile; + } + + /* + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.IMakefileDocumentProvider#getWorkingCopy(java.lang.Object) + */ + public IMakefile getWorkingCopy(Object element) { + FileInfo fileInfo= getFileInfo(element); + if (fileInfo instanceof AutomakefileFileInfo) { + AutomakefileFileInfo info= (AutomakefileFileInfo) fileInfo; + return info.fCopy; + } + return null; + } + + /* + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.IMakefileDocumentProvider#shutdown() + */ + public void shutdown() { + @SuppressWarnings("unchecked") + Iterator e= getConnectedElementsIterator(); + while (e.hasNext()) + disconnect(e.next()); + } + + public void connect(Object element) throws CoreException { + super.connect(element); + IMakefile makefile = getWorkingCopy(element); + IDocument document = getDocument(element); + AutomakeErrorHandler errorHandler = new AutomakeErrorHandler(document); + errorHandler.update(makefile); + } + + public IDocument getDocument(Object element) { + FileInfo info= (FileInfo) getFileInfo(element); + if (info != null) + return info.fTextFileBuffer.getDocument(); + return getParentProvider().getDocument(element); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeEditor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeEditor.java new file mode 100644 index 00000000000..f033e31b65b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeEditor.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MakefileEditor to support Automake files + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutomakeEditorPreferencePage; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.texteditor.ChainedPreferenceStore; +import org.eclipse.ui.texteditor.DefaultRangeIndicator; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + + +public class AutomakeEditor extends MakefileEditor { + + protected AutomakefileContentOutlinePage ampage; + private AutomakefileSourceConfiguration sourceViewerConfiguration; + private static AutomakeEditor fgInstance; + private IEditorInput input; + + public AutomakeEditor() { + super(); + fgInstance = this; + } + + /** + * Returns the default editor instance. + * + * @return the default editor instance + */ + public static AutomakeEditor getDefault() { + return fgInstance; + } + + protected void doSetInput(IEditorInput newInput) throws CoreException + { + super.doSetInput(newInput); + this.input = newInput; + + getOutlinePage().setInput(input); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor() + */ + protected void initializeEditor() { + setRangeIndicator(new DefaultRangeIndicator()); + setEditorContextMenuId("#MakefileEditorContext"); //$NON-NLS-1$ + setRulerContextMenuId("#MakefileRulerContext"); //$NON-NLS-1$ + setDocumentProvider(AutomakeEditorFactory.getDefault().getAutomakefileDocumentProvider()); + IPreferenceStore[] stores = new IPreferenceStore[2]; + stores[0] = AutotoolsPlugin.getDefault().getPreferenceStore(); + stores[1] = EditorsUI.getPreferenceStore(); + ChainedPreferenceStore chainedStore = new ChainedPreferenceStore(stores); + setPreferenceStore(chainedStore); + sourceViewerConfiguration = new AutomakefileSourceConfiguration(chainedStore, this); + setSourceViewerConfiguration(sourceViewerConfiguration); + AutotoolsEditorPreferenceConstants.initializeDefaultValues(stores[0]); + AutomakeEditorPreferencePage.initDefaults(stores[0]); + configureInsertMode(SMART_INSERT, false); + setInsertMode(INSERT); + } + + public AutomakeDocumentProvider getAutomakefileDocumentProvider() { + return (AutomakeDocumentProvider) AutomakeEditorFactory.getDefault().getAutomakefileDocumentProvider(); + } + + public AutomakefileContentOutlinePage getAutomakeOutlinePage() { + if (ampage == null) { + ampage = new AutomakefileContentOutlinePage(this); + ampage.addSelectionChangedListener(this); + ampage.setInput(getEditorInput()); + } + return ampage; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + public void createPartControl(Composite parent) { + super.createPartControl(parent); + } + + /* (non-Javadoc) + * Method declared on IAdaptable + */ + public Object getAdapter(@SuppressWarnings("unchecked") Class key) { + if (key.equals(IContentOutlinePage.class)) { + return getAutomakeOutlinePage(); + } + return super.getAdapter(key); + } + + public AutomakefileSourceConfiguration getAutomakeSourceViewerConfiguration() { + return sourceViewerConfiguration; + } + + protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { + super.handlePreferenceStoreChanged(event); + } + + public IMakefile getMakefile() { + return getAutomakefileDocumentProvider().getWorkingCopy(this.getEditorInput()); + } + + public ISourceViewer getAutomakeSourceViewer() { + return getSourceViewer(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeEditorFactory.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeEditorFactory.java new file mode 100644 index 00000000000..e799ccaca3d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeEditorFactory.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.swt.graphics.Color; + + +public class AutomakeEditorFactory { + private IWorkingCopyManager workingCopyManager; + private IMakefileDocumentProvider automakeFileDocumentProvider; + private static volatile AutomakeEditorFactory factory; + + /** + * The constructor. + */ + private AutomakeEditorFactory() { + factory = this; + } + + public synchronized IMakefileDocumentProvider getAutomakefileDocumentProvider() { + if (automakeFileDocumentProvider == null) { + automakeFileDocumentProvider= new AutomakeDocumentProvider(); + } + return automakeFileDocumentProvider; + } + + public synchronized IWorkingCopyManager getWorkingCopyManager() { + if (workingCopyManager == null) { + IMakefileDocumentProvider provider= getAutomakefileDocumentProvider(); + workingCopyManager= new WorkingCopyManager(provider); + } + return workingCopyManager; + } + + /** + * Returns the preference color, identified by the given preference. + */ + public static Color getPreferenceColor(String key) { + //FIXME: what do we do with Makefile editor preferences? + return ColorManager.getDefault().getColor(PreferenceConverter.getColor(AutotoolsPlugin.getDefault().getPreferenceStore(), key)); + } + + public static AutomakeEditorFactory getDefault() { + if (factory == null) + factory = new AutomakeEditorFactory(); + return factory; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeErrorHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeErrorHandler.java new file mode 100644 index 00000000000..d6ea5f8ca28 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeErrorHandler.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.core.runtime.AssertionFailedException; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.quickassist.IQuickFixableAnnotation; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.ui.IEditorInput; + + +public class AutomakeErrorHandler { + public static final String AUTOMAKE_ERROR_MARKER_ID = AutotoolsUIPlugin.PLUGIN_ID + + ".parsefileerror"; + + private IDocument document; + private AnnotationModel fAnnotationModel; + + public static final String CDT_ANNOTATION_INFO = "org.eclipse.cdt.ui.info"; + public static final String CDT_ANNOTATION_WARNING = "org.eclipse.cdt.ui.warning"; + public static final String CDT_ANNOTATION_ERROR = "org.eclipse.cdt.ui.error"; + + // TODO: no quickfixes yet implemented, but maybe in the future + private static class AutomakeAnnotation extends Annotation implements IQuickFixableAnnotation { + public AutomakeAnnotation(String annotationType, boolean persist, String message) { + super(annotationType, persist, message); + } + + public void setQuickFixable(boolean state) { + // do nothing + } + + public boolean isQuickFixableStateSet() { + return true; + } + + public boolean isQuickFixable() throws AssertionFailedException { + return false; + } + + } + + public AutomakeErrorHandler(IDocument document) { + this.document = document; + IEditorInput input = AutomakeEditor.getDefault().getEditorInput(); + this.fAnnotationModel = (AnnotationModel)AutomakeEditorFactory.getDefault().getAutomakefileDocumentProvider().getAnnotationModel(input); + } + + + public void update(IMakefile makefile) { + removeExistingMarkers(); + + // Recursively process all the directives in the Makefile + checkChildren(makefile); + } + + private void checkChildren(IParent parent) { + IDirective[] directives = parent.getDirectives(); + for (int i = 0; i < directives.length; i++) { + IDirective directive = directives[i]; + if (directive instanceof IParent) { + checkChildren((IParent)directive); + } else if (directive instanceof BadDirective) { + int lineNumber = directive.getStartLine(); + Integer charStart = getCharOffset(lineNumber - 1, 0); + Integer charEnd = Integer.valueOf(getCharOffset(directive.getEndLine() - 1, -1).intValue()); + + String annotationType = CDT_ANNOTATION_ERROR; + Annotation annotation = new AutomakeAnnotation(annotationType, true, "Bad directive"); //$NON-NLS-1$ + Position p = new Position(charStart.intValue(),charEnd.intValue() - charStart.intValue()); + fAnnotationModel.addAnnotation(annotation, p); + } + } + return; + } + + public void removeExistingMarkers() + { + fAnnotationModel.removeAllAnnotations(); + } + + + private Integer getCharOffset(int lineNumber, int columnNumber) + { + try + { + if (columnNumber >= 0) + return Integer.valueOf(document.getLineOffset(lineNumber) + columnNumber); + return Integer.valueOf(document.getLineOffset(lineNumber) + document.getLineLength(lineNumber)); + } + catch (BadLocationException e) + { + e.printStackTrace(); + return null; + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeIfElse.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeIfElse.java new file mode 100644 index 00000000000..0a2f44dd4d2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeIfElse.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + + + +public class AutomakeIfElse extends Parent { + String condition; + String type; + public AutomakeIfElse(Directive parent, String type, String condition) { + super(parent); + this.type = type; + this.condition = condition; + } + public String getCondition() { + return condition; + } + public void setCondition(String condition) { + this.condition = condition; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeMacroDefinitionRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeMacroDefinitionRule.java new file mode 100644 index 00000000000..61206404b46 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeMacroDefinitionRule.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MacroDefinitionRule to support Automake files + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +class AutomakeMacroDefinitionRule implements IPredicateRule { + private static final int INIT_STATE = 0; + private static final int VAR_STATE = 1; + private static final int END_VAR_STATE = 2; + private static final int EQUAL_STATE = 3; + private static final int FINISH_STATE = 4; + private static final int ERROR_STATE = 5; + + private IToken token; + private StringBuffer buffer = new StringBuffer(); + protected IToken defaultToken; + + public AutomakeMacroDefinitionRule(IToken token, IToken defaultToken) { + this.token = token; + this.defaultToken = defaultToken; + } + + public IToken getSuccessToken() { + return token; + } + + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + buffer.setLength(0); + int c; + int state = INIT_STATE; + + if (resume) + scanToBeginOfLine(scanner); + + for (c = scanner.read(); c != ICharacterScanner.EOF; c = scanner.read()) { + switch (state) { + case INIT_STATE : + if (c != '\n' && Character.isWhitespace((char) c)) { + break; + } + if (isValidCharacter(c)) { + state = VAR_STATE; + } else { + state = ERROR_STATE; + } + break; + case VAR_STATE : + if (isValidCharacter(c)) { + break; + } + case END_VAR_STATE : + if (Character.isWhitespace((char) c)) { + state = END_VAR_STATE; + } else if (c == ':' || c == '+') { + state = EQUAL_STATE; + } else if (c == '=') { + state = FINISH_STATE; + } else { +// if (state == END_VAR_STATE) { +// scanner.unread(); // Return back to the space +// } + state = ERROR_STATE; + } + break; + case EQUAL_STATE : + if (c == '=') { + state = FINISH_STATE; + } else { + state = ERROR_STATE; + } + break; + case FINISH_STATE : + break; + default : + break; + } + if (state >= FINISH_STATE) { + break; + } + buffer.append((char) c); + } + + if (state == FINISH_STATE) { + scanToEndOfLine(scanner); + return token; + } + + boolean debug = true; + if (debug) { +// System.out.println("This should be a 'c': " + peek(scanner)); +// System.out.println("This is what's in the **REST OF** the buffer:"); +// int count = 0; +// for (int c = scanner.read(); c != ICharacterScanner.EOF; c = scanner.read()) { +// System.out.println((char) c); +// count++; +// } +// // Unread what we just displayed +// for (int i = 0; i < count; i++) { +// scanner.unread(); +// } + } + + if (defaultToken.isUndefined()) { + // If c is EOF, we've read it and broken out of the for loop above, + // but we need to unread it since it got read but not put into the + // buffer + if (state == ERROR_STATE || c == ICharacterScanner.EOF) + scanner.unread(); + unreadBuffer(scanner); + debug = true; + if (debug) { +// System.out.println("This should be an 'i': " + peek(scanner)); +// System.out.println("We've supposedly just unread the entire buffer. Here it is:"); +// int count = 0; +// for (int c = scanner.read(); c != ICharacterScanner.EOF; c = scanner.read()) { +// System.out.println((char) c); +// count++; +// } +// // Unread what we just displayed +// for (int i = 0; i < count + 1; i++) { +// scanner.unread(); +// } +// System.out.println("... just to be safe, here's the first character: " + peek(scanner)); + } + + } + + return Token.UNDEFINED; + } + + public char peek(ICharacterScanner scanner) { + char c = (char) scanner.read(); + scanner.unread(); + return c; + } + + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i = buffer.length() - 1; i >= 0; i--) + scanner.unread(); + } + + private void scanToEndOfLine(ICharacterScanner scanner) { + int c; + char[][] delimiters = scanner.getLegalLineDelimiters(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + // Check for end of line since it can be used to terminate the pattern. + for (int i = 0; i < delimiters.length; i++) { + if (c == delimiters[i][0] && sequenceDetected(scanner, delimiters[i])) { + return; + } + } + } + } + + private void scanToBeginOfLine(ICharacterScanner scanner) { + while(scanner.getColumn() != 0) { + scanner.unread(); + } + } + + private boolean sequenceDetected(ICharacterScanner scanner, char[] sequence) { + for (int i = 1; i < sequence.length; i++) { + int c = scanner.read(); + if (c == ICharacterScanner.EOF) { + return true; + } else if (c != sequence[i]) { + // Non-matching character detected, rewind the scanner back to the start. + for (; i > 0; i--) { + scanner.unread(); + } + return false; + } + } + + return true; + } + protected boolean isValidCharacter(int c) { + char c0 = (char) c; + return Character.isLetterOrDigit(c0) || (c0 == '_') || (c0 == '-') || + (c0 == '@') || (c0 == '+') || (c0 == '$') || (c0 == '(') || (c0 == ')'); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeMacroReferenceRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeMacroReferenceRule.java new file mode 100644 index 00000000000..785ffaa64c5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeMacroReferenceRule.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2006, Red Hat, Inc. + * Based on MacroReferenceRule which has the following copyright notice + * + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.PatternRule; + +public class AutomakeMacroReferenceRule extends PatternRule { + + int nOfBrackets; + int fBracket; + +// public MacroReferenceRule(IToken token) { +// super("$(", ")", token, (char) 0, true); //$NON-NLS-1$ //$NON-NLS-2$ +// } + + public AutomakeMacroReferenceRule(IToken token, String startSeq, String endSeq) { + super(startSeq, endSeq, token, (char)0, true); + if (endSeq.length() > 0 && endSeq.charAt(0) == '}') { + fBracket = '{'; + } else { + fBracket = '('; + } + } + + protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) { + nOfBrackets = 1; + return super.doEvaluate(scanner, resume); + } + + protected boolean endSequenceDetected(ICharacterScanner scanner) { + int c; + char[][] delimiters = scanner.getLegalLineDelimiters(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (fBracket == c) { + ++nOfBrackets; + } + if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) { + if (0 == --nOfBrackets) { + return true; + } + } + } else if (fBreaksOnEOL) { + // Check for end of line since it can be used to terminate the pattern. + for (int i = 0; i < delimiters.length; i++) { + if (c == delimiters[i][0] && sequenceDetected(scanner, delimiters[i], false)) { + return true; + } + } + } + } + scanner.unread(); + return false; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeTextHover.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeTextHover.java new file mode 100644 index 00000000000..4a8a9ad5265 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeTextHover.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextHoverExtension; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.swt.graphics.Point; + + +public class AutomakeTextHover implements ITextHover, ITextHoverExtension { + + AutomakeEditor editor; + + public AutomakeTextHover(AutomakeEditor editor) { + this.editor = editor; + } + + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + TargetRule target = null; + String[] preReqs = null; + + if (hoverRegion == null || hoverRegion.getLength() == 0) + return null; + Automakefile makefile = (Automakefile) editor.getMakefile(); + if (makefile == null) + return null; + + String hoverText; + int hoverLine; + try { + hoverText = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength()); + hoverLine = textViewer.getDocument().getLineOfOffset(hoverRegion.getOffset()); + } catch (BadLocationException e) { + return null; + } + + // Automatic variables + if (hoverText.startsWith("$")) { + IDirective containingDirective = makefile.getDirectiveContainingLine(hoverLine); + if (containingDirective instanceof TargetRule) { + target = (TargetRule) containingDirective; + } + if (target == null) + return ""; + switch (hoverText.charAt(1)) { + case '@': + return target.getTarget().toString(); + case '<': + preReqs = target.getPrerequisites(); + if (preReqs != null && preReqs.length > 0) + return preReqs[0]; + break; + // FIXME: implement $* ? +// case '*': +// break; + case '?': + preReqs = target.getPrerequisites(); + if (preReqs != null && preReqs.length > 0) { + StringBuffer toReturn = new StringBuffer(); + toReturn.append(preReqs[0]); + for (int i = 1; i < preReqs.length; i++) { + toReturn.append(" " + preReqs[i]); + } + return toReturn.toString(); + } + break; + case '%': +// if (target instanceOf ArchiveTarget) { +// return target.getMember(); +// } else { +// error; +// } +// break; + default: + break; + } + } else { + // Macros + IMacroDefinition[] macroDefinitions = makefile.getMacroDefinitions(hoverText); + for (int i = 0; i < macroDefinitions.length; i++) { + IMacroDefinition definition = macroDefinitions[i]; + if (definition.getName().equals(hoverText)) + return definition.getValue().toString(); + } + } + +// IRule[] rules = makefile.getRules(); +// for (int i = 0; i < rules.length; i++) { +// rule = rules[i]; +// System.out.println("rule: " + rule); +// System.out.println("target: " + rule.getTarget()); +// ICommand[] commands = rule.getCommands(); +// for (int j = 0; j < commands.length; j++) { +// ICommand command = commands[j]; +// System.out.println("command: " + command); +// } +// } + return ""; + } + + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + + if (textViewer != null) { + /* + * If the hover offset falls within the selection range return the + * region for the whole selection. + */ + Point selectedRange = textViewer.getSelectedRange(); + if (selectedRange.x >= 0 && selectedRange.y > 0 + && offset >= selectedRange.x + && offset <= selectedRange.x + selectedRange.y) + return new Region(selectedRange.x, selectedRange.y); + else { + return findWord(textViewer.getDocument(), offset); + } + } + return null; + } + + private 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) && + (c != '@') && (c != '<') && (c != '*') && (c != '?') && (c != '%')) + break; + --pos; + } + + start = pos; + + pos = offset; + int length = document.getLength(); + + while (pos < length) { + c = document.getChar(pos); + if (!Character.isJavaIdentifierPart(c) && + (c != '@') && (c != '<') && (c != '*') && (c != '?') && (c != '%')) + break; + ++pos; + } + + end = pos; + + } catch (BadLocationException x) { + } + + if (start > -1 && end > -1) { + if (start == offset && end == offset) + return new Region(offset, 0); + else if (start == offset) + return new Region(start, end - start); + else + return new Region(start + 1, end - start - 1); + } + + return null; + } + + public IInformationControlCreator getHoverControlCreator() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeWordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeWordDetector.java new file mode 100644 index 00000000000..7836e48621c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakeWordDetector.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class AutomakeWordDetector implements IWordDetector { + + private static final String correctStartSpecChars = "$%*().><"; //$NON-NLS-1$ + private static final String correctSpecChars = "?@$/\\<*%"; //$NON-NLS-1$ + + public boolean isWordStart(char character) { + return Character.isLetterOrDigit(character) || (correctStartSpecChars.indexOf(character) >= 0); + } + + public boolean isWordPart(char character) { + return Character.isLetterOrDigit(character) || (correctSpecChars.indexOf(character) >= 0); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Automakefile.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Automakefile.java new file mode 100644 index 00000000000..c3234f36fda --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Automakefile.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from PosixMakeFile to support Automake files + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; + +public class Automakefile extends GNUAutomakefile { + + public Automakefile() { + super(); + } + + protected IDirective getDirectiveContainingLine(int line) { + int startLine, endLine; + IDirective[] directives = this.getDirectives(); + for (int i = 0; i < directives.length; i++) { + IDirective directive = directives[i]; + startLine = directive.getStartLine(); + endLine = directive.getEndLine(); + if (startLine <= line && endLine >= line) + return directive; + } + return null; + } + + public static void main(String[] args) { + try { + String filename = "Makefile.am"; //$NON-NLS-1$ + if (args.length == 1) { + filename = args[0]; + } + Automakefile makefile = new Automakefile(); + makefile.parse(filename); + IDirective[] directives = makefile.getDirectives(); + //IDirective[] directives = makefile.getBuiltins(); + for (int i = 0; i < directives.length; i++) { + //System.out.println("Rule[" + i +"]"); + System.out.print(directives[i]); + } + } catch (IOException e) { + System.out.println(e); + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileCodeScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileCodeScanner.java new file mode 100644 index 00000000000..7bd06f99170 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileCodeScanner.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MakefileCodeScanner to support Automake files + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.autotools.ui.editors.AutoconfIdentifierRule; +import org.eclipse.cdt.autotools.ui.editors.AutoconfWhitespaceDetector; +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.jface.text.rules.EndOfLineRule; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.SingleLineRule; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; +import org.eclipse.jface.text.rules.WordRule; + + +public class AutomakefileCodeScanner extends AbstractMakefileCodeScanner { + + + private final static String[] keywords = { "define", "endef", "ifdef", "ifndef", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "ifeq", "ifneq", "else", "endif", "include", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + "-include", "sinclude", "override", "endef", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "export", "unexport", "vpath", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "if", "@if", "@endif" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + private final static String[] functions = { "subst", "patsubst", "strip", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "findstring", "filter", "sort", "dir", "notdir", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + "suffix", "basename", "addsuffix", "addprefix", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "join", "word", "words", "wordlist", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "firstword", "wildcard", "error", "warning", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "shell", "origin", "foreach", "call" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + }; + + private final static String[] automaticVariables = { "$<" , "$*" , "$@" , "$?" , "$%" + }; + + static final String[] fTokenProperties = new String[] { + ColorManager.MAKE_COMMENT_COLOR, + ColorManager.MAKE_KEYWORD_COLOR, + ColorManager.MAKE_FUNCTION_COLOR, + ColorManager.MAKE_MACRO_REF_COLOR, + ColorManager.MAKE_MACRO_DEF_COLOR, + ColorManager.MAKE_DEFAULT_COLOR + }; + + /** + * Constructor for AutomakefileCodeScanner + */ + public AutomakefileCodeScanner() { + super(); + initialize(); + } + + protected List<IRule> createRules() { + IToken keyword = getToken(ColorManager.MAKE_KEYWORD_COLOR); + IToken function = getToken(ColorManager.MAKE_FUNCTION_COLOR); + IToken comment = getToken(ColorManager.MAKE_COMMENT_COLOR); + IToken macroRef = getToken(ColorManager.MAKE_MACRO_REF_COLOR); + IToken macroDef = getToken(ColorManager.MAKE_MACRO_DEF_COLOR); + IToken other = getToken(ColorManager.MAKE_DEFAULT_COLOR); + + List<IRule> rules = new ArrayList<IRule>(); + + // Add rule for single line comments. + rules.add(new EndOfLineRule("#", comment, '\\', true)); //$NON-NLS-1$ + + // Add generic whitespace rule. + rules.add(new WhitespaceRule(new IWhitespaceDetector() { + public boolean isWhitespace(char character) { + return Character.isWhitespace(character); + } + })); + + // Put before the the word rules + MultiLineRule defineRule = new MultiLineRule("define", "endef", macroDef); //$NON-NLS-1$ //$NON-NLS-2$ + defineRule.setColumnConstraint(0); + rules.add(defineRule); + + rules.add(new AutomakeMacroDefinitionRule(macroDef, Token.UNDEFINED)); + + // @AC_SUBST_VAR@ + IPredicateRule substVarRule = new AutoconfSubstRule(macroRef); + rules.add(substVarRule); + + // Add word rule for keywords, types, and constants. + // We restring the detection of the keywords to be the first column to be valid. + WordRule keyWordRule = new WordRule(new MakefileWordDetector(), Token.UNDEFINED); + for (int i = 0; i < keywords.length; i++) { + keyWordRule.addWord(keywords[i], keyword); + } + keyWordRule.setColumnConstraint(0); + rules.add(keyWordRule); + + + WordRule functionRule = new WordRule(new MakefileWordDetector(), Token.UNDEFINED); + for (int i = 0; i < functions.length; i++) + functionRule.addWord(functions[i], function); + rules.add(functionRule); + + WordRule automaticVarRule = new WordRule(new AutomakeWordDetector(), Token.UNDEFINED); + for (int i = 0; i < automaticVariables.length; i++) + automaticVarRule.addWord(automaticVariables[i], keyword); + rules.add(automaticVarRule); + +// rules.add(new SingleLineRule("$(", ")", macroRef)); //$NON-NLS-1$ //$NON-NLS-2$ +// rules.add(new SingleLineRule("${", "}", macroRef)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new AutomakeMacroReferenceRule(macroRef, "$(", ")")); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new AutomakeMacroReferenceRule(macroRef, "${", "}")); //$NON-NLS-1$ //$NON-NLS-2$ + // Add word rule for identifier. + + rules.add(new AutoconfIdentifierRule(other)); + + // Make sure we don't treat "\#" as comment start. + rules.add(new SingleLineRule("\\#", null, Token.UNDEFINED)); + + rules.add(new WhitespaceRule(new AutoconfWhitespaceDetector())); + + setDefaultReturnToken(other); + + return rules; + } + + public IToken nextToken() { + return super.nextToken(); + } + + /* + * @see AbstractMakefileCodeScanner#getTokenProperties() + */ + protected String[] getTokenProperties() { + return fTokenProperties; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileContentOutlinePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileContentOutlinePage.java new file mode 100644 index 00000000000..ab39af95b27 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileContentOutlinePage.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MakefileContentOutlinePage for Automake files + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; + + +public class AutomakefileContentOutlinePage extends ContentOutlinePage { + + protected IMakefile makefile; + protected IMakefile nullMakefile = new NullMakefile(); + + private class AutomakefileContentProvider implements ITreeContentProvider { + + protected boolean showMacroDefinition = true; + protected boolean showTargetRule = true; + protected boolean showInferenceRule = true; + protected boolean showIncludeChildren = false; + + protected IMakefile makefile; + protected IMakefile nullMakefile = new NullMakefile(); + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) { + if (element == fInput) { + return getElements(makefile); + } else if (element instanceof IDirective) { + return getElements(element); + } + return new Object[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element instanceof IMakefile) { + return fInput; + } else if (element instanceof IDirective) { + return ((IDirective)element).getParent(); + } + return fInput; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element == fInput) { + return true; + } else if (element instanceof IParent) { + // Do not drill down in includes. + if (element instanceof IInclude && !showIncludeChildren) { + return false; + } + return true; + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + IDirective[] directives; + if (inputElement == fInput) { + directives = makefile.getDirectives(); + } else if (inputElement instanceof IRule) { + directives = ((IRule)inputElement).getCommands(); + } else if (inputElement instanceof IParent) { + if (inputElement instanceof IInclude && !showIncludeChildren) { + directives = new IDirective[0]; + } else { + directives = ((IParent)inputElement).getDirectives(); + } + } else { + directives = new IDirective[0]; + } + List<IDirective> list = new ArrayList<IDirective>(directives.length); + for (int i = 0; i < directives.length; i++) { + if (showMacroDefinition && directives[i] instanceof IMacroDefinition) { + list.add(directives[i]); + } else if (showInferenceRule && directives[i] instanceof IInferenceRule) { + list.add(directives[i]); + } else if (showTargetRule && directives[i] instanceof ITargetRule) { + list.add(directives[i]); + } else if (showTargetRule && directives[i] instanceof AutomakeIfElse) { + list.add(directives[i]); + } else { + boolean irrelevant = (directives[i] instanceof IComment || + directives[i] instanceof IEmptyLine || + directives[i] instanceof ITerminal); + if (!irrelevant) { + list.add(directives[i]); + } + } + } + return list.toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (oldInput != null) { + makefile = nullMakefile; + } + + if (newInput != null) { + IWorkingCopyManager manager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + makefile = manager.getWorkingCopy((IEditorInput) newInput); + if (makefile == null) { + makefile = nullMakefile; + } + } + } + } + + private class AutomakefileLabelProvider extends LabelProvider implements ILabelProvider { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + public Image getImage(Object element) { + if (element instanceof ITargetRule) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_TARGET_RULE); + } else if (element instanceof IInferenceRule) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_INFERENCE_RULE); + } else if (element instanceof IMacroDefinition) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_MACRO); + } else if (element instanceof IAutomakeConditional) { + // Must process this before ICommand because if/else are also ICommands + return super.getImage(element); + } else if (element instanceof ICommand) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_COMMAND); + } else if (element instanceof IInclude) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_INCLUDE); + } else if (element instanceof IBadDirective) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_ERROR); + } else if (element instanceof AutomakeConfigMacro) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_ACMACRO); + } + + return super.getImage(element); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + String name; + if (element instanceof IRule) { + name = ((IRule) element).getTarget().toString().trim(); + } else if (element instanceof IMacroDefinition) { + name = ((IMacroDefinition) element).getName().trim(); + } else if (element instanceof AutomakeIfElse) { + AutomakeIfElse ifelse = (AutomakeIfElse) element; + // FIXME: make this not a string comparison + if (ifelse.getType().equals("if")) { + name = "if " + ifelse.getCondition(); + } else + name = "else"; + } else if (element instanceof AutomakeConfigMacro) { + AutomakeConfigMacro macro = (AutomakeConfigMacro)element; + name = macro.getName(); + } else { + name = super.getText(element); + } + if (name != null) { + name = name.trim(); + if (name.length() > 25) { + name = name.substring(0, 25) + " ..."; //$NON-NLS-1$ + } + } + return name; + } + + } + + protected AutomakeEditor fEditor; + protected Object fInput; + + public AutomakefileContentOutlinePage(AutomakeEditor editor) { + super(); + fEditor = editor; + } + + /** + * Sets the input of the outline page + */ + public void setInput(Object input) { + fInput = input; + update(); + } + + /** + * Updates the outline page. + */ + public void update() { + final TreeViewer viewer = getTreeViewer(); + + if (viewer != null) { + final Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!control.isDisposed()) { + control.setRedraw(false); + viewer.setInput(fInput); + viewer.expandAll(); + control.setRedraw(true); + } + } + }); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + super.createControl(parent); + TreeViewer viewer = getTreeViewer(); + viewer.setContentProvider(new AutomakefileContentProvider()); + viewer.setLabelProvider(new AutomakefileLabelProvider()); + if (fInput != null) { + viewer.setInput(fInput); + } + +// MenuManager manager= new MenuManager("#MakefileOutlinerContext"); //$NON-NLS-1$ +// manager.setRemoveAllWhenShown(true); +// manager.addMenuListener(new IMenuListener() { +// public void menuAboutToShow(IMenuManager m) { +// contextMenuAboutToShow(m); +// } +// }); +// Control tree = viewer.getControl(); +// Menu menu = manager.createContextMenu(tree); +// tree.setMenu(menu); +// +// viewer.addDoubleClickListener(new IDoubleClickListener() { +// /* (non-Javadoc) +// * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) +// */ +// public void doubleClick(DoubleClickEvent event) { +// if (fOpenIncludeAction != null) { +// fOpenIncludeAction.run(); +// } +// } +// }); +// +// IPageSite site= getSite(); +// site.registerContextMenu(MakeUIPlugin.getPluginId() + ".outline", manager, viewer); //$NON-NLS-1$ +// site.setSelectionProvider(viewer); + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (oldInput != null) { + makefile = nullMakefile; + } + + if (newInput != null) { + IWorkingCopyManager manager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + makefile = manager.getWorkingCopy((IEditorInput)newInput); + if (makefile == null) { + makefile = nullMakefile; + } + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileReconcilingStrategy.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileReconcilingStrategy.java new file mode 100644 index 00000000000..5b867dde764 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileReconcilingStrategy.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MakefileReconcilingStrategy for Automake files + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.io.StringReader; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + + +public class AutomakefileReconcilingStrategy implements IReconcilingStrategy { + + private int fLastRegionOffset; + private ITextEditor fEditor; + private IWorkingCopyManager fManager; + private IDocumentProvider fDocumentProvider; + private AutomakefileContentOutlinePage fOutliner; + private IReconcilingParticipant fMakefileReconcilingParticipant; + private AutomakeErrorHandler fErrorHandler; + private IEditorInput input; + + public AutomakefileReconcilingStrategy(AutomakeEditor editor) { + fOutliner= editor.getAutomakeOutlinePage(); + fLastRegionOffset = Integer.MAX_VALUE; + fEditor= editor; + input = (IEditorInput) fEditor.getEditorInput(); + fManager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + fDocumentProvider= AutomakeEditorFactory.getDefault().getAutomakefileDocumentProvider(); + fErrorHandler= new AutomakeErrorHandler(fDocumentProvider.getDocument(input)); + fMakefileReconcilingParticipant= (IReconcilingParticipant)fEditor; + } + + /** + * @see IReconcilingStrategy#reconcile(document) + */ + public void setDocument(IDocument document) { + } + + + /** + * @see IReconcilingStrategy#reconcile(region) + */ + public void reconcile(IRegion region) { + // We use a trick to avoid running the reconciler multiple times + // on a file when it gets changed. This is because this gets called + // multiple times with different regions of the file, we do a + // complete parse on the first region. + if(region.getOffset() <= fLastRegionOffset) { + reconcile(); + } + fLastRegionOffset = region.getOffset(); + } + + /** + * @see IReconcilingStrategy#reconcile(dirtyRegion, region) + */ + public void reconcile(DirtyRegion dirtyRegion, IRegion region) { + // FIXME: This seems to generate too much flashing in + // the contentoutline viewer. + //reconcile(); + } + + private void reconcile() { + try { + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + if (makefile != null) { + String content = fDocumentProvider.getDocument(input).get(); + StringReader reader = new StringReader(content); + try { + makefile.parse(makefile.getFileURI(), reader); + } catch (IOException e) { + } + + fOutliner.update(); + fErrorHandler.update(makefile); + } + } finally { + try { + if (fMakefileReconcilingParticipant != null) { + fMakefileReconcilingParticipant.reconciled(); + } + } finally { + // + } + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileSourceConfiguration.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileSourceConfiguration.java new file mode 100644 index 00000000000..bef5111da0f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileSourceConfiguration.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified from MakefileSourceConfiguration to support Automake + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.reconciler.MonoReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.util.PropertyChangeEvent; + + +public class AutomakefileSourceConfiguration extends + MakefileSourceConfiguration { + + AutomakeEditor editor; + AutomakefileCodeScanner codeScanner; + AutomakeTextHover amHover; + + /** + * Constructor for MakeConfiguration + */ + public AutomakefileSourceConfiguration(IPreferenceStore preferenceStore) { + super(preferenceStore, null); + } + + public AutomakefileSourceConfiguration(IPreferenceStore preferenceStore, AutomakeEditor editor) { + super(preferenceStore, editor); + this.editor = editor; + } + + public AutomakefileCodeScanner getAutomakeCodeScanner() { + if (null == codeScanner) + codeScanner = new AutomakefileCodeScanner(); + return codeScanner; + + } + + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + if (amHover == null) + amHover = new AutomakeTextHover(editor); + return amHover; + } + + /** + * @param event + */ + public void adaptToPreferenceChange(PropertyChangeEvent event) { + AutomakefileCodeScanner scanner = getAutomakeCodeScanner(); + scanner.adaptToPreferenceChange(event); + } + + /** + * @param event + * @return + */ + public boolean affectsBehavior(PropertyChangeEvent event) { + AutomakefileCodeScanner scanner = getAutomakeCodeScanner(); + return scanner.affectsBehavior(event); + } + + public IPresentationReconciler getPresentationReconciler(ISourceViewer v) { + + PresentationReconciler reconciler = new PresentationReconciler(); + + DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + + dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION); + + dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + + dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION); + + dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION); + + dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION); + + dr = new DefaultDamagerRepairer(getAutomakeCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_OTHER_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_OTHER_PARTITION); + return reconciler; + } + + + /** + * @see SourceViewerConfiguration#getReconciler(ISourceViewer) + */ + public IReconciler getReconciler(ISourceViewer sourceViewer) { + if (editor != null && editor.isEditable()) { + MonoReconciler reconciler= new MonoReconciler(new AutomakefileReconcilingStrategy(editor), false); + reconciler.setDelay(1000); + reconciler.setProgressMonitor(new NullProgressMonitor()); + return reconciler; + } + return null; + } + + /** + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(ISourceViewer) + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + ContentAssistant assistant = new ContentAssistant(); + assistant.setContentAssistProcessor(new AutomakeCompletionProcessor(editor), IDocument.DEFAULT_CONTENT_TYPE); + assistant.setContentAssistProcessor(new AutomakeCompletionProcessor(editor), MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION); + assistant.setContentAssistProcessor(new AutomakeCompletionProcessor(editor), MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION); + assistant.setContentAssistProcessor(new AutomakeCompletionProcessor(editor), MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION); + assistant.setContentAssistProcessor(new AutomakeCompletionProcessor(editor), MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION); + assistant.setContentAssistProcessor(new AutomakeCompletionProcessor(editor), MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + + assistant.enableAutoActivation(true); + assistant.setAutoActivationDelay(500); + + assistant.setProposalPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW); + assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW); + + return assistant; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileUtil.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileUtil.java new file mode 100644 index 00000000000..b15d00ac4d3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/AutomakefileUtil.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + + +public class AutomakefileUtil { + + // Look for Automake conditionals which optionally + // activate or disable a Makefile rule command. + public static boolean isAutomakeCommand(String line) { + return line.matches("^@[a-z_A-Z0-9]+@\\t.*$"); //$NON-NLS-1$ + } + + public static boolean isIfBlock(String line) { + return line.startsWith("if"); //$NON-NLS-1$ + } + + public static boolean isElseBlock(String line) { + return line.startsWith("else"); //$NON-NLS-1$ + } + + public static boolean isElseIfBlock(String line) { + return line.startsWith("else if"); //$NON-NLS-1$ + } + + public static boolean isEndifBlock(String line) { + return line.startsWith("endif"); //$NON-NLS-1$ + } + + public static boolean isConfigMacro(String line) { + return line.matches("\\s*@[a-z_A-Z0-9]+@"); //$NON-NLS-1$ + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/BadDirective.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/BadDirective.java new file mode 100644 index 00000000000..8bae9e0102f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/BadDirective.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class BadDirective extends Directive implements IBadDirective { + + String line; + + public BadDirective(Directive parent, String s) { + super(parent); + line = s; + } + + public String toString() { + return line; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Command.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Command.java new file mode 100644 index 00000000000..2436d19a587 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Command.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; +import java.io.IOException; + +/** + * Makefile : ( statement ) * + * statement : command | .. + * command : <tab> prefix_command string <nl> + * prefix_command : '-' | '@' | '+' + */ +public class Command extends Directive implements ICommand { + + final public static char NL = '\n'; + + String command = ""; //$NON-NLS-1$ + char prefix = '\0'; + + public Command(Directive parent, String cmd) { + super(parent); + parse(cmd); + } + + /** + * - If the command prefix contains a hyphen, or the -i option is + * present, or the special target .IGNORE has either the current + * target as a prerequisite or has no prerequisites, any error + * found while executing the command will be ignored. + */ + public boolean shouldIgnoreError() { + // Check for the prefix hyphen in the command. + if (getPrefix() == HYPHEN) { + return true; + } + return false; + } + + /** + * @ If the command prefix contains an at sign and the + * command-line -n option is not specified, or the -s option is + * present, or the special target .SILENT has either the current + * target as a prerequisite or has no prerequisites, the command + * will not be written to standard output before it is executed. + */ + public boolean shouldBeSilent() { + // Check for the prefix at sign + if (getPrefix() == AT) { + return true; + } + return false; + } + + /** + * + If the command prefix contains a plus sign, this indicates a + * command line that will be executed even if -n, -q or -t is + * specified. + */ + public boolean shouldExecute() { + // Check for the prefix at sign + if (getPrefix() == PLUS) { + return true; + } + return false; + } + + public String toString() { + StringBuffer cmd = new StringBuffer(); + cmd.append( '\t'); + if (getPrefix() != 0) { + cmd.append(getPrefix()); + } + cmd.append(command).append('\n'); + return cmd.toString(); + } + + public boolean equals(Object cmd) { + if (cmd instanceof Command) + return cmd.toString().equals(toString()); + return false; + } + + public int hashCode() { + return toString().hashCode(); + } + + char getPrefix() { + return prefix; + } + + /** + * command : <tab> prefix_command string <nl> + */ + void parse(String cmd) { + command = cmd.trim(); + if (command.startsWith(HYPHEN_STRING) || command.startsWith(AT_STRING) || command.startsWith(PLUS_STRING)) { + prefix = command.charAt(0); + command = command.substring(1).trim(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.ICommand#execute(java.lang.String[], java.io.File) + */ + public Process execute(String shell, String[] envp, File dir) throws IOException { + String[] cmdArray = new String[] { shell, "-c", command}; //$NON-NLS-1$ + return Runtime.getRuntime().exec(cmdArray, envp, dir); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Comment.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Comment.java new file mode 100644 index 00000000000..0cfdf833221 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Comment.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class Comment extends Directive implements IComment { + + String comment; + + public Comment(Directive parent, String cmt) { + super(parent); + if (cmt.startsWith(POUND_STRING)) { + comment = cmt.substring(1); + } else { + comment = cmt; + } + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(POUND_STRING).append(comment).append('\n'); + return buffer.toString(); + } + + public boolean equals(Object cmt) { + if (cmt instanceof Comment) + return cmt.toString().equals(toString()); + return false; + } + + public int hashCode() { + return toString().hashCode(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/CompletionProposalComparator.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/CompletionProposalComparator.java new file mode 100644 index 00000000000..6e78eac1ded --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/CompletionProposalComparator.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +import java.io.Serializable; +import java.util.Comparator; + +import org.eclipse.jface.text.contentassist.ICompletionProposal; + +public class CompletionProposalComparator implements Comparator<ICompletionProposal>, Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor for CompletionProposalComparator. + */ + public CompletionProposalComparator() { + } + + /* (non-Javadoc) + * @see Comparator#compare(Object, Object) + */ + public int compare(ICompletionProposal o1, ICompletionProposal o2) { + ICompletionProposal c1= (ICompletionProposal) o1; + ICompletionProposal c2= (ICompletionProposal) o2; + return c1.getDisplayString().compareToIgnoreCase(c2.getDisplayString()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Conditional.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Conditional.java new file mode 100644 index 00000000000..ad2fefc369c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Conditional.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified for Automake editor usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public abstract class Conditional extends Parent implements IConditional { + + private static final String EMPTY = ""; //$NON-NLS-1$ + String cond; + String arg1; + String arg2; + + public Conditional(Directive parent, String conditional) { + super(parent); + cond = conditional; + parse(); + } + + public Conditional(Directive parent) { + this(parent, EMPTY, EMPTY, EMPTY); + } + + public Conditional(Directive parent, String conditional, String argument1, String argument2) { + super(parent); + arg1 = argument1; + arg2 = argument2; + cond = conditional; + } + + + public String getConditional() { + return cond; + } + + public String getArg1() { + return arg1; + } + + public String getArg2() { + return arg2; + } + + public boolean isIf() { + return false; + } + + public boolean isIfdef() { + return false; + } + + public boolean isIfndef() { + return false; + } + + public boolean isIfeq() { + return false; + } + + public boolean isIfneq() { + return false; + } + + public boolean isElse() { + return false; + } + + public boolean isEndif() { + return false; + } + + /** + * Formats of the conditional string. + * ifeq (ARG1, ARG2) + * ifeq 'ARG1' 'ARG2' + * ifeq "ARG1" "ARG2" + * ifeq "ARG1" 'ARG2' + * ifeq 'ARG1' "ARG2" + */ + protected void parse() { + String line = getConditional().trim(); + + char terminal = line.charAt(0) == '(' ? ',' : line.charAt(0); + + if (line.length() < 5 && terminal != ',' && terminal != '"' && terminal != '\'') { + arg1 = arg2 = EMPTY; + return; + } + + // Find the end of the first string. + int count = 0; + // For the (ARG1, ARG2) format. + + // get the first ARG1 + if (terminal == ',') { + int paren = 0; + for (count = 1; count < line.length(); count++) { + char ch = line.charAt(count); + if (ch == '(') { + paren++; + } else if (ch == ')') { + paren--; + } + if (ch == terminal && paren <= 0) { + break; + } + } + } else { + for (count = 1; count < line.length(); count++) { + if (line.charAt(count) == terminal) { + break; + } + } + } + + if (count >= line.length()) { + arg1 = arg2 = EMPTY; + return; + } + + arg1 = line.substring(1, count); + + /* Find the start of the second string. */ + line = line.substring(count + 1).trim(); + + terminal = terminal == ',' ? ')' : line.charAt(0); + if (terminal != ')' && terminal != '"' && terminal != '\'') { + arg2 = EMPTY; + return; + } + + count = 0; + /* Find the end of the second string. */ + if (terminal == ')') { + int paren = 0; + for (count = 0; count < line.length(); count++) { + char ch = line.charAt(count); + if (ch == '(') { + paren++; + } else if (ch == ')') { + paren--; + } + if (ch == terminal && paren <= 0) { + break; + } + } + } else { + for (count = 1; count < line.length(); count++) { + if (line.charAt(count) == terminal) { + break; + } + } + } + if (count > line.length()) { + arg2 = EMPTY; + } else { + arg2 = line.substring(0, count); + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DefaultRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DefaultRule.java new file mode 100644 index 00000000000..76d9880ec72 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DefaultRule.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .DEFAULT + * If the makefile uses this special target, the application shall ensure that it is + * specified with commands, but without prerequisites. + */ +public class DefaultRule extends SpecialRule implements IDefaultRule { + + public DefaultRule(Directive parent, Command[] cmds) { + super(parent, new Target(MakeFileConstants.RULE_DEFAULT), new String[0], cmds); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DefineVariable.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DefineVariable.java new file mode 100644 index 00000000000..511e740068b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DefineVariable.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class DefineVariable extends GNUVariableDef { + + public DefineVariable(Directive parent, String name, StringBuffer value) { + super(parent, name, value); + } + + public boolean isMultiLine() { + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.VARIABLE_DEFINE); + sb.append(getName()).append('\n'); + sb.append(getValue()); + sb.append(GNUMakefileConstants.TERMINAL_ENDEF); + return sb.toString(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DeleteOnErrorRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DeleteOnErrorRule.java new file mode 100644 index 00000000000..3f550161de0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/DeleteOnErrorRule.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .DELETE_ON_ERROR + * If `.DELETE_ON_ERROR' is mentioned as a target anywhere in the + * makefile, then `make' will delete the target of a rule if it has + * changed and its commands exit with a nonzero exit status, just as + * it does when it receives a signal. + */ +public class DeleteOnErrorRule extends SpecialRule implements IDeleteOnErrorRule { + + public DeleteOnErrorRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_DELETE_ON_ERROR), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Directive.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Directive.java new file mode 100644 index 00000000000..330243d3cba --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Directive.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public abstract class Directive implements IDirective { + + int endLine; + int startLine; + String filename; + IMakefile makefile; + Directive parent; + + public Directive(Directive owner) { + parent = owner; + } + + public Directive(int start, int end) { + setLines(start, end); + } + + public abstract String toString(); + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IDirective#getEndLine() + */ + public int getEndLine() { + return endLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IDirective#getStartLine() + */ + public int getStartLine() { + return startLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IDirective#getParent() + */ + public IDirective getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IDirective#getFileName() + */ + public String getFileName() { + if (filename == null) { + if (parent != null) { + filename = parent.getFileName(); + } + } + return filename; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IDirective#getMakefile() + */ + public IMakefile getMakefile() { + if (makefile == null) { + if (parent != null) { + makefile = parent.getMakefile(); + } + } + return makefile; + } + + public void setParent(Directive owner) { + parent = owner; + } + + public void setStartLine(int lineno) { + startLine = lineno; + } + + public void setEndLine(int lineno) { + endLine = lineno; + } + + public void setLines(int start, int end) { + setStartLine(start); + setEndLine(end); + } + + public void setFilename(String name) { + filename = name; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/EditorUtility.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/EditorUtility.java new file mode 100644 index 00000000000..31d9ad9d5ec --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/EditorUtility.java @@ -0,0 +1,561 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 + * Markus Schorn (Wind River Systems) + * Norbert Ploett (Siemens AG) + * Anton Leherbauer (Wind River Systems) + * Ed Swartz (Nokia) + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.text.MessageFormat; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.cdt.core.model.IBuffer; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IIncludeReference; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.core.resources.FileStorage; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.filebuffers.FileBuffers; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.jface.action.Action; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.part.FileEditorInput; + +public class EditorUtility { + + /** + * The ID of the default text editor + */ + public static final String DEFAULT_TEXT_EDITOR_ID = EditorsUI.DEFAULT_TEXT_EDITOR_ID; + + private EditorUtility () { + } + + /** + * Tests if a cu is currently shown in an editor + * @return the IEditorPart if shown, null if element is not open in an editor + */ + public static IEditorPart isOpenInEditor(Object inputElement) { + IEditorInput input = null; + + try { + input = getEditorInput(inputElement); + } catch (CModelException x) { + //CUIPlugin.log(x.getStatus()); + } + + if (input != null) { + IWorkbenchPage p= CUIPlugin.getActivePage(); + if (p != null) { + return p.findEditor(input); + } + } + + return null; + } + + /** + * Opens an editor for an element such as <code>ICElement</code>, + * <code>IFile</code>, or <code>IStorage</code>. + * The editor is activated by default. + * @return the IEditorPart or null if wrong element type or opening failed + */ + public static IEditorPart openInEditor(Object inputElement) throws CModelException, PartInitException { + return openInEditor(inputElement, true); + } + + /** + * Opens an editor for an element (ICElement, IFile, IStorage...) + * @return the IEditorPart or null if wrong element type or opening failed + */ + public static IEditorPart openInEditor(Object inputElement, boolean activate) throws CModelException, PartInitException { + + if (inputElement instanceof IFile) { + return openInEditor((IFile) inputElement, activate); + } + + IEditorInput input = getEditorInput(inputElement); + + if (input != null) { + return openInEditor(input, getEditorID(input, inputElement), activate); + } + + return null; + } + + // Following is not needed and drags in internal reference to CEditor. + +// /** +// * Selects a C Element in an editor +// */ +// public static void revealInEditor(IEditorPart part, ICElement element) { +// if (element != null && part instanceof CEditor) { +// ((CEditor) part).setSelection(element); +// } +// } + + private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException { + if (!file.getProject().isAccessible()){ + closedProject(file.getProject()); + return null; + } + + if (file != null) { + try { + if (!isLinked(file)) { + File tempFile = file.getRawLocation().toFile(); + + if (tempFile != null){ + String canonicalPath = null; + try { + canonicalPath = tempFile.getCanonicalPath(); + } catch (IOException e1) {} + + if (canonicalPath != null){ + IPath path = new Path(canonicalPath); + file = CUIPlugin.getWorkspace().getRoot().getFileForLocation(path); + } + } + } + + IEditorInput input = getEditorInput(file); + if (input != null) { + return openInEditor(input, getEditorID(input, file), activate); + } + } catch (CModelException e) {} + } + return null; + } + + @SuppressWarnings("deprecation") + public static boolean isLinked(IFile file) { + if (file.isLinked()) + return true; + + IPath path = file.getLocation(); + while (path.segmentCount() > 0) { + path = path.removeLastSegments(1); + IContainer[] containers = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocation(path); + + for(int i=0; i<containers.length; i++) { + if (containers[i] instanceof IFolder && ((IFolder)containers[i]).isLinked()) { + return true; + } + } + } + + return false; + } + + /** + * Open error dialog about closed project. + * @param project + */ + private static void closedProject(IProject project) { + MessageBox errorMsg = new MessageBox(CUIPlugin.getActiveWorkbenchShell(), SWT.ICON_ERROR | SWT.OK); + errorMsg.setText(CUIPlugin.getResourceString("EditorUtility.closedproject")); //$NON-NLS-1$ + String desc= CUIPlugin.getResourceString("Editorutility.closedproject.description"); //$NON-NLS-1$ + errorMsg.setMessage (MessageFormat.format(desc, new Object[]{project.getName()})); + errorMsg.open(); + + } + + private static IEditorPart openInEditor(IEditorInput input, String editorID, boolean activate) throws PartInitException { + if (input != null) { + IWorkbenchPage p= CUIPlugin.getActivePage(); + if (p != null) { + IEditorPart editorPart= p.openEditor(input, editorID, activate); + return editorPart; + } + } + return null; + } + + private static IEditorInput getEditorInput(ICElement element) throws CModelException { + while (element != null) { + if (element instanceof ISourceReference) { + ITranslationUnit tu = ((ISourceReference)element).getTranslationUnit(); + if (tu != null) { + element = tu; + } + } + if (element instanceof IWorkingCopy && ((IWorkingCopy) element).isWorkingCopy()) + element= ((IWorkingCopy) element).getOriginalElement(); + + if (element instanceof ITranslationUnit) { + ITranslationUnit unit= (ITranslationUnit) element; + IResource resource= unit.getResource(); + if (resource instanceof IFile) { + return new FileEditorInput((IFile) resource); + } + return new ExternalEditorInput(unit, new FileStorage(unit.getPath())); + } + + if (element instanceof IBinary) { + return new ExternalEditorInput(getStorage((IBinary)element), (IPath)null); + } + + element= element.getParent(); + } + + return null; + } + + public static IEditorInput getEditorInput(Object input) throws CModelException { + if (input instanceof ICElement) { + return getEditorInput((ICElement) input); + } + if (input instanceof IFile) { + return new FileEditorInput((IFile) input); + } + if (input instanceof IStorage) { + return new ExternalEditorInput((IStorage)input); + } + return null; + } + + /** + * Utility method to open an editor for the given file system location + * using {@link #getEditorInputForLocation(IPath, ICElement)} to create + * the editor input. + * + * @param location a file system location + * @param element an element related to the target file, may be <code>null</code> + * @throws PartInitException + */ + public static IEditorPart openInEditor(IPath location, ICElement element) throws PartInitException { + IEditorInput input= getEditorInputForLocation(location, element); + return EditorUtility.openInEditor(input, getEditorID(input, element), true); + } + + /** + * Utility method to get an editor input for the given file system location. + * If the location denotes a workspace file, a <code>FileEditorInput</code> + * is returned, otherwise, the input is an <code>IStorageEditorInput</code> + * assuming the location points to an existing file in the file system. + * The <code>ICElement</code> is used to determine the associated project + * in case the location can not be resolved to a workspace <code>IFile</code>. + * + * @param location a valid file system location + * @param context an element related to the target file, may be <code>null</code> + * @return an editor input + */ + public static IEditorInput getEditorInputForLocation(IPath location, ICElement context) { + IFile resource= getWorkspaceFileAtLocation(location, context); + if (resource != null) { + return new FileEditorInput(resource); + } + + if (context == null) { + // try to synthesize a context for a location appearing on a project's + // include paths + try { + ICProject[] projects = CCorePlugin.getDefault().getCoreModel().getCModel().getCProjects(); + outerFor: for (int i = 0; i < projects.length; i++) { + IIncludeReference[] includeReferences = projects[i].getIncludeReferences(); + for (int j = 0; j < includeReferences.length; j++) { + if (includeReferences[j].isOnIncludeEntry(location)) { + context = projects[i]; + break outerFor; + } + } + } + if (context == null && projects.length > 0) { + // last resort: just take any of them + context= projects[0]; + } + } catch (CModelException e) { + } + } + + if (context != null) { + // try to get a translation unit from the location and associated element + ICProject cproject= context.getCProject(); + if (cproject != null) { + ITranslationUnit unit = CoreModel.getDefault().createTranslationUnitFrom(cproject, location); + if (unit != null) { + return new ExternalEditorInput(unit, new FileStorage(location)); + } + // no translation unit - still try to get a sensible marker resource + // from the associated element + IResource markerResource= cproject.getProject(); + return new ExternalEditorInput(new FileStorage(location), markerResource); + } + } + return new ExternalEditorInput(new FileStorage(location)); + } + + + /** + * Utility method to resolve a file system location to a workspace resource. + * If a context element is given and there are multiple matches in the workspace, + * a resource with the same project of the context element are preferred. + * + * @param location a valid file system location + * @param context an element related to the target file, may be <code>null</code> + * @return an <code>IFile</code> or <code>null</code> + */ + private static IFile getWorkspaceFileAtLocation(IPath location, ICElement context) { + IFile file= FileBuffers.getWorkspaceFileAtLocation(location); + if (file == null) { + // try to find a linked resource + IProject project= null; + if (context != null) { + ICProject cProject= context.getCProject(); + if (cProject != null) { + project= cProject.getProject(); + } + } + IFile bestMatch= null; + IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); + IFile[] files= root.findFilesForLocationURI(URIUtil.toURI(location)); + for (int i= 0; i < files.length; i++) { + file= files[i]; + if (file.isAccessible()) { + if (project != null && file.getProject() == project) { + bestMatch= file; + break; + } + if (bestMatch == null) { + bestMatch= file; + if (project == null) { + break; + } + } + } + } + return bestMatch; + } + return file; + } + + /** + * If the current active editor edits a c element return it, else + * return null + */ + public static ICElement getActiveEditorCInput() { + IWorkbenchPage page= CUIPlugin.getActivePage(); + if (page != null) { + IEditorPart part= page.getActiveEditor(); + if (part != null) { + IEditorInput editorInput= part.getEditorInput(); + if (editorInput != null) { + return (ICElement)editorInput.getAdapter(ICElement.class); + } + } + } + return null; + } + + /** + * Gets the working copy of an compilation unit opened in an editor + * + * @param cu the original compilation unit (or another working copy) + * @return the working copy of the compilation unit, or null if not found + */ + public static ITranslationUnit getWorkingCopy(ITranslationUnit cu) { + if (cu == null) + return null; + if (cu.isWorkingCopy()) + return cu; + + return cu.findSharedWorkingCopy(); + } + + /** + * Determine the editor id from the given file name using + * the workspace-wide content-type definitions. + * + * @param name the file name + * @return a valid editor id, never <code>null</code> + */ + public static String getEditorID(String name) { + IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); + if (registry != null) { + IEditorDescriptor descriptor = registry.getDefaultEditor(name); + if (descriptor != null) { + return descriptor.getId(); + } + } + return DEFAULT_TEXT_EDITOR_ID; + } + + /** + * Determine the editor id from the given editor input and optional input object. + * When a translation unit can be obtained, the project-specific content-type + * mechanism is used to determine the correct editor id. + * If that fails, the editor id is determined by file name and extension using + * the workspace-wide content-type definitions. + * + * @param input the editor input + * @param inputObject the input object (used to create the editor input) or <code>null</code> + * @return a valid editor id, never <code>null</code> + */ + public static String getEditorID(IEditorInput input, Object inputObject) { + + ITranslationUnit tunit = null; + if (inputObject instanceof ITranslationUnit) { + tunit= (ITranslationUnit)inputObject; + } else if (input instanceof IFileEditorInput) { + IFileEditorInput editorInput = (IFileEditorInput)input; + IFile file = editorInput.getFile(); + ICElement celement = CoreModel.getDefault().create(file); + if (celement instanceof ITranslationUnit) { + tunit = (ITranslationUnit)celement; + } + } else if (input instanceof ITranslationUnitEditorInput) { + ITranslationUnitEditorInput editorInput = (ITranslationUnitEditorInput)input; + tunit = editorInput.getTranslationUnit(); + } + + if (tunit != null) { + // Choose an editor based on the content type + String contentTypeId= tunit.getContentTypeId(); + if (contentTypeId != null) { + IContentType contentType= Platform.getContentTypeManager().getContentType(contentTypeId); + IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); + IEditorDescriptor desc= registry.getDefaultEditor(input.getName(), contentType); + if (desc != null) { + return desc.getId(); + } + } + // Choose an editor based on the language (obsolete?) + if (tunit.isCLanguage()) { + return CUIPlugin.EDITOR_ID; + } else if (tunit.isCXXLanguage()) { + return CUIPlugin.EDITOR_ID; + } else if (tunit.isASMLanguage()) { + return "org.eclipse.cdt.ui.editor.asm.AsmEditor"; //$NON-NLS-1$ + } + } + + // Choose an editor based on filename/extension + String editorId = getEditorID(input.getName()); + + return editorId; + } + + /** + * Maps the localized modifier name to a code in the same + * manner as #findModifier. + * + * @return the SWT modifier bit, or <code>0</code> if no match was found + */ + public static int findLocalizedModifier(String token) { + if (token == null) + return 0; + + if (token.equalsIgnoreCase(Action.findModifierString(SWT.CTRL))) + return SWT.CTRL; + if (token.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT))) + return SWT.SHIFT; + if (token.equalsIgnoreCase(Action.findModifierString(SWT.ALT))) + return SWT.ALT; + if (token.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND))) + return SWT.COMMAND; + + return 0; + } + + /** + * Returns the modifier string for the given SWT modifier + * modifier bits. + * + * @param stateMask the SWT modifier bits + * @return the modifier string + * @since 2.1.1 + */ + public static String getModifierString(int stateMask) { + String modifierString= ""; //$NON-NLS-1$ + if ((stateMask & SWT.CTRL) == SWT.CTRL) + modifierString= appendModifierString(modifierString, SWT.CTRL); + if ((stateMask & SWT.ALT) == SWT.ALT) + modifierString= appendModifierString(modifierString, SWT.ALT); + if ((stateMask & SWT.SHIFT) == SWT.SHIFT) + modifierString= appendModifierString(modifierString, SWT.SHIFT); + if ((stateMask & SWT.COMMAND) == SWT.COMMAND) + modifierString= appendModifierString(modifierString, SWT.COMMAND); + + return modifierString; + } + + /** + * Appends to modifier string of the given SWT modifier bit + * to the given modifierString. + * + * @param modifierString the modifier string + * @param modifier an int with SWT modifier bit + * @return the concatenated modifier string + * @since 2.1.1 + */ + private static String appendModifierString(String modifierString, int modifier) { + if (modifierString == null) + modifierString= ""; //$NON-NLS-1$ + String newModifierString= Action.findModifierString(modifier); + if (modifierString.length() == 0) + return newModifierString; + return MakefileMessages.getFormattedString("EditorUtility.concatModifierStrings", new String[] {modifierString, newModifierString}); //$NON-NLS-1$ + } + + public static IStorage getStorage(IBinary bin) { + IStorage store = null; + try { + IBuffer buffer = bin.getBuffer(); + if (buffer != null) { + store = new FileStorage (new ByteArrayInputStream(buffer.getContents().getBytes()), bin.getPath()); + } + } catch (CModelException e) { + // nothing; + } + return store; + } + + public static IStorage getStorage(ITranslationUnit tu) { + IStorage store = null; + try { + store = new FileStorage (new ByteArrayInputStream(tu.getBuffer().getContents().getBytes()), tu.getPath()); + } catch (CModelException e) { + // nothing; + } + return store; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ElementListSelectionDialog.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ElementListSelectionDialog.java new file mode 100644 index 00000000000..3b55792ffa8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ElementListSelectionDialog.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ILabelProvider; + +/** + * A class to select one or more elements out of an indexed property + */ +public class ElementListSelectionDialog extends AbstractElementListSelectionDialog { + + private List<Object> fElements; + + /* + * @private + */ + protected void computeResult() { + setResult(getWidgetSelection()); + } + /* + * @private + */ + protected Control createDialogArea(Composite parent) { + Control result= super.createDialogArea(parent); + + setSelectionListElements(fElements, false); + //a little trick to make the window come up faster + String initialFilter= null; + if (getPrimaryInitialSelection() instanceof String) + initialFilter= (String)getPrimaryInitialSelection(); + if (initialFilter != null) + setFilter(initialFilter, true); + else + refilter(); + + return result; + } + public Object getSelectedElement() { + return getPrimaryResult(); + } + public Object[] getSelectedElements() { + return getResult(); + } + /* + * @private + */ + protected void handleDoubleClick() { + if (verifyCurrentSelection()) { + buttonPressed(IDialogConstants.OK_ID); + } + } + /** + * Constructs a list selection dialog. + * @param renderer The label renderer used + * @param ignoreCase Decides if the match string ignores lower/upper case + * @param multipleSelection Allow multiple selection + */ + public ElementListSelectionDialog(Shell parent, String title, Image image, ILabelProvider renderer, boolean ignoreCase, boolean multipleSelection) { + super (parent, title, image, renderer, ignoreCase, multipleSelection); + } + /** + * Constructs a list selection dialog. + * @param renderer The label renderer used + * @param ignoreCase Decides if the match string ignores lower/upppr case + * @param multipleSelection Allow multiple selection + */ + public ElementListSelectionDialog(Shell parent, ILabelProvider renderer, boolean ignoreCase, boolean multipleSelection) { + this(parent, "", null, renderer, ignoreCase, multipleSelection); //$NON-NLS-1$ + } + public int open(Object[] elements) { + return open(Arrays.asList(elements)); + } + public int open(Object[] elements, String initialSelection) { + return open(Arrays.asList(elements), initialSelection); + } + /** + * Open the dialog. + * @param elements The elements to show in the list + * @return Returns OK or CANCEL + */ + public int open(List<Object> elements) { + setElements(elements); + return open(); + } + /** + * Open the dialog. + * @param elements The elements to show in the list + * @param initialSelection The initial content of the match text box. + * @return Returns OK or CANCEL + */ + public int open(List<Object> elements, String initialSelection) { + setElements(elements); + setInitialSelection(initialSelection); + return open(); + } + /** + * Sets the elements presented by this dialog. + */ + public void setElements(List<Object> elements) { + fElements= elements; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Else.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Else.java new file mode 100644 index 00000000000..d261779cae7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Else.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified for Automake editor usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; +import java.io.IOException; + +public class Else extends Conditional implements IAutomakeConditional, ICommand { + + private boolean isAutomake; + private Rule[] rules; + + public Else(Directive parent) { + super(parent); + } + + public boolean isAutomake() { + return isAutomake; + } + + public Rule[] getRules() { + if (rules != null) + return rules.clone(); + return rules; + } + + public void setRules(Rule[] rules) { + if (rules != null) + this.rules = rules.clone(); + else + this.rules = rules; + } + + public void setAutomake(boolean value) { + isAutomake = value; + } + + public boolean isElse() { + return true; + } + + public String toString() { + return GNUMakefileConstants.CONDITIONAL_ELSE; + } + + // ICommand methods so Automake else can be a child of an IRule + public Process execute(String shell, String[] envp, File dir) + throws IOException { + return null; + } + + public boolean shouldBeSilent() { + return false; + } + + public boolean shouldIgnoreError() { + return false; + } + + public boolean shouldExecute() { + return false; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/EmptyLine.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/EmptyLine.java new file mode 100644 index 00000000000..016efd8afec --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/EmptyLine.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class EmptyLine extends Directive implements IEmptyLine { + + final public static char NL = '\n'; + final public static String NL_STRING = "\n"; //$NON-NLS-1$ + + public EmptyLine(Directive parent) { + super(parent); + } + + public String toString() { + return NL_STRING; + } + + public boolean equals(IEmptyLine stmt) { + return true; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Endef.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Endef.java new file mode 100644 index 00000000000..0a67166d6d5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Endef.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class Endef extends Terminal { + + + public Endef(Directive parent) { + super(parent); + } + + public boolean isEndef() { + return true; + } + + public String toString() { + return GNUMakefileConstants.TERMINAL_ENDEF; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Endif.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Endif.java new file mode 100644 index 00000000000..a812ba4e0e1 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Endif.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class Endif extends Terminal { + + public Endif(Directive parent) { + super(parent); + } + + public boolean isEndif() { + return true; + } + + public String toString() { + return GNUMakefileConstants.TERMINAL_ENDIF; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExportAllVariablesRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExportAllVariablesRule.java new file mode 100644 index 00000000000..4fcb3b60ee3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExportAllVariablesRule.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .EXPORT_ALL_VARIABLES + * Simply by being mentioned as a target, this tells `make' to export + * all variables to child processes by default. + */ +public class ExportAllVariablesRule extends SpecialRule implements IExportAllVariablesRule { + + public ExportAllVariablesRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_EXPORT_ALL_VARIABLES), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExportVariable.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExportVariable.java new file mode 100644 index 00000000000..e0d455406e6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExportVariable.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified for Automake usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class ExportVariable extends GNUVariableDef { + + public ExportVariable(Directive parent, String name, StringBuffer value, int type) { + super(parent, name, value, type); + } + + public boolean isExport() { + return true; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExternalEditorInput.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExternalEditorInput.java new file mode 100644 index 00000000000..f59b44a45b6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExternalEditorInput.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; +import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.ILocationProvider; + + +/** + * An EditorInput for an external (non-workspace) file. + */ +public class ExternalEditorInput implements ITranslationUnitEditorInput, IPersistableElement { + + private IStorage externalFile; + private IResource markerResource; + private ITranslationUnit unit; + private IPath location; + + /* + */ + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof IStorageEditorInput)) + return false; + IStorageEditorInput other = (IStorageEditorInput)obj; + try { + return externalFile.equals(other.getStorage()); + } catch (CoreException exc) { + return false; + } + } + + public int hashCode() { + return externalFile.hashCode(); + } + + /* + * @see IEditorInput#exists() + */ + public boolean exists() { + // External file can not be deleted + return true; + } + + /* + * @see IAdaptable#getAdapter(Class) + */ + @SuppressWarnings({ "unchecked" }) + public Object getAdapter(Class adapter) { + if (ILocationProvider.class.equals(adapter)) { + return this; + } + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + /* + * @see IEditorInput#getImageDescriptor() + */ + public ImageDescriptor getImageDescriptor() { + IEditorRegistry registry= PlatformUI.getWorkbench().getEditorRegistry(); + return registry.getImageDescriptor(externalFile.getFullPath().getFileExtension()); + } + + /* + * @see IEditorInput#getName() + */ + public String getName() { + return externalFile.getName(); + } + + /* + * @see IEditorInput#getPersistable() + */ + public IPersistableElement getPersistable() { + return this; + } + + /* + * see IStorageEditorInput#getStorage() + */ + public IStorage getStorage() { + return externalFile; + } + + /* + * @see IEditorInput#getToolTipText() + */ + public String getToolTipText() { + return externalFile.getFullPath().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.ITranslationUnitEditorInput#getTranslationUnit() + */ + public ITranslationUnit getTranslationUnit() { + return unit; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.editors.text.ILocationProvider#getPath(java.lang.Object) + */ + public IPath getPath(Object element) { + return location; + } + + public ExternalEditorInput(ITranslationUnit unit, IStorage exFile) { + this(exFile, exFile.getFullPath()); + this.unit = unit; + markerResource= unit.getCProject().getProject(); + } + + public ExternalEditorInput(IStorage exFile) { + this(exFile, exFile.getFullPath()); + } + + public ExternalEditorInput(IStorage exFile, IPath location) { + externalFile = exFile; + this.location = location; + } + + /** + * This constructor accepts the storage for the editor + * and a reference to a resource which holds the markers for the external file. + */ + public ExternalEditorInput(IStorage exFile, IResource markerResource) { + this(exFile, exFile.getFullPath()); + this.markerResource = markerResource ; + } + + /** + * Return the resource where markers for this external editor input are stored + */ + public IResource getMarkerResource() { + return markerResource; + } + + /* + * @see org.eclipse.ui.IPersistableElement#getFactoryId() + */ + public String getFactoryId() { + return ExternalEditorInputFactory.ID; + } + + /* + * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento) + */ + public void saveState(IMemento memento) { + ExternalEditorInputFactory.saveState(memento, this); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExternalEditorInputFactory.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExternalEditorInputFactory.java new file mode 100644 index 00000000000..e4a86c885a2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ExternalEditorInputFactory.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems, 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; + +/** + * The ExternalEditorInputFactory is used to save and recreate an ExternalEditorInput object. + * As such, it implements the IPersistableElement interface for storage + * and the IElementFactory interface for recreation. + * + * @see IMemento + * @see IPersistableElement + * @see IElementFactory + * + * @since 4.0 + */ +public class ExternalEditorInputFactory implements IElementFactory { + + public static final String ID = "org.eclipse.cdt.ui.ExternalEditorInputFactory"; //$NON-NLS-1$ + + private static final String TAG_PATH = "path";//$NON-NLS-1$ + private static final String TAG_PROJECT = "project";//$NON-NLS-1$ + + /* + * @see org.eclipse.ui.IElementFactory#createElement(org.eclipse.ui.IMemento) + */ + public IAdaptable createElement(IMemento memento) { + // Get the file name. + String fileName = memento.getString(TAG_PATH); + if (fileName == null) { + return null; + } + + IPath location= new Path(fileName); + ICProject cProject= null; + + String projectName= memento.getString(TAG_PROJECT); + if (projectName != null) { + IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + if (project.isAccessible() && CoreModel.hasCNature(project)) { + cProject= CoreModel.getDefault().create(project); + } + } + return EditorUtility.getEditorInputForLocation(location, cProject); + } + + /** + * Save the element state. + * + * @param memento the storage + * @param input the element + */ + static void saveState(IMemento memento, ExternalEditorInput input) { + IPath location= input.getPath(input); + if (location != null) { + memento.putString(TAG_PATH, location.toOSString()); + } + IProject project= null; + ITranslationUnit unit= input.getTranslationUnit(); + if (unit != null) { + project= unit.getCProject().getProject(); + } + if (project == null && input.getMarkerResource() instanceof IProject) { + project= (IProject)input.getMarkerResource(); + } + if (project != null) { + memento.putString(TAG_PROJECT, project.getName()); + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUAutomakefile.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUAutomakefile.java new file mode 100644 index 00000000000..cc8730de6d6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUAutomakefile.java @@ -0,0 +1,987 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified for Automake editor usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Stack; +import java.util.StringTokenizer; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileInfo; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; + + +/** + * Makefile : ( statement ) * + * statement : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule + * inference_rule : target ':' <nl> ( <tab> command <nl> ) + + * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl> + [ ( command ) * ] + * macro_definition : string '=' (string)* + * comments : ('#' (string) <nl>) * + * empty : <nl> + * command : <tab> prefix_command string <nl> + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" + */ + +public class GNUAutomakefile extends AbstractMakefile implements IGNUMakefile { + + public static final String PATH_SEPARATOR = System.getProperty("path.separator", ":"); //$NON-NLS-1$ //$NON-NLS-2$ + public static final String FILE_SEPARATOR = System.getProperty("file.separator", "/"); //$NON-NLS-1$ //$NON-NLS-2$ + + String[] includeDirectories = new String[0]; + IDirective[] builtins = null; + + public GNUAutomakefile() { + super(null); + } + + public void parse(String name) throws IOException { + FileReader stream = new FileReader(name); + try { + parse(name, stream); + } finally { + if (stream != null) { + stream.close(); + } + } + } + + public void parse(String filePath, Reader reader) throws IOException { + parse(URIUtil.toURI(filePath), new MakefileReader(reader)); + } + + public void parse(URI fileURI, Reader reader) throws IOException { + parse(fileURI, new MakefileReader(reader)); + } + + + protected void parse(URI fileURI, MakefileReader reader) throws IOException { + String line; + Rule[] rules = null; + Stack<IDirective> conditions = new Stack<IDirective>(); + Stack<GNUVariableDef> defines = new Stack<GNUVariableDef>(); + int startLine = 0; + int endLine = 0; + + // Clear any old directives. + clearDirectives(); + + setFileURI(fileURI); + + while ((line = reader.readLine()) != null) { + startLine = endLine + 1; + endLine = reader.getLineNumber(); + + // Check if we enter in "define" + if (GNUMakefileUtil.isEndef(line)) { + // We should have a "define" for a "endef". + if (!defines.empty()) { + GNUVariableDef def = (GNUVariableDef) defines.pop(); + def.setEndLine(endLine); + } + Endef endef = new Endef((Directive)this); + endef.setLines(startLine, endLine); + addDirective(conditions, endef); + continue; + } else if (GNUMakefileUtil.isDefine(line)) { + GNUVariableDef def = parseGNUVariableDef(line); + def.setLines(startLine, endLine); + addDirective(conditions, def); + defines.push(def); + continue; + } else if (GNUMakefileUtil.isOverrideDefine(line)) { + GNUVariableDef oDef = parseGNUVariableDef(line); + oDef.setLines(startLine, endLine); + addDirective(conditions, oDef); + defines.push(oDef); + continue; + } + + // We still in a define. + if (!defines.empty()) { + GNUVariableDef def = (GNUVariableDef) defines.peek(); + StringBuffer sb = def.getValue(); + if (sb.length() > 0) { + sb.append('\n'); + } + sb.append(line); + continue; + } + + // 1- Try command first, since we can not strip '#' in command line + if (PosixMakefileUtil.isCommand(line) || + AutomakefileUtil.isAutomakeCommand(line)) { + Command cmd = new Command(this, line); + cmd.setLines(startLine, endLine); + if (rules != null) { + // The command is added to the rules + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(cmd); + rules[i].setEndLine(endLine); + } + continue; + } + if (!conditions.isEmpty()) { + addDirective(conditions, cmd); + continue; + } + // If we have no rules/condition for the command, + // give the other directives a chance by falling through + } + + // 2- Strip away any comments. + int pound = Util.indexOfComment(line); + if (pound != -1) { + Comment cmt = new Comment(this, line.substring(pound + 1)); + cmt.setLines(startLine, endLine); + if (rules != null) { + // The comment is added to the rules. + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(cmt); + rules[i].setEndLine(endLine); + } + } else { + addDirective(conditions, cmt); + } + line = line.substring(0, pound); + // If all we have left are spaces continue + if (Util.isEmptyLine(line)) { + continue; + } + // The rest of the line maybe a valid directives. + // keep on trying by falling through. + } + + // 3- Empty lines ? + if (Util.isEmptyLine(line)) { + Directive empty = new EmptyLine(this); + empty.setLines(startLine, endLine); + if (rules != null) { + // The EmptyLine is added to the rules. + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(empty); + rules[i].setEndLine(endLine); + } + } else { + addDirective(conditions, empty); + } + continue; + } + + // 3b - look for if statement which is an Automake directive. + // These will be processed at configure time and all statements + // in-between are modified with a prefix. We will treat these as + // standard conditionals even though they can affect the behavior + // of lines that follow the construct. For + // example, an automake-if could start in the middle of a rule + // and the else might be outside a target. + if (GNUMakefileUtil.isIf(line)) { + // We cache the rules that were in effect at entry to the + // if/else block. We treat the endif as restoring the + // state of the rules at this point. It is possible for + // commands to follow the if/else that belong to different + // rules that start inside the if/else, but we are not + // prepared to handle that in an outline view and it is + // pretty bad Automake coding. + If ifDirective = parseIf(line, rules); + ifDirective.setLines(startLine, endLine); + if (rules != null) { + // The if statement is added to the rules. + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(ifDirective); + rules[i].setEndLine(endLine); + } + } else { + addDirective(conditions, ifDirective); + } + conditions.push(ifDirective); + rules = null; + continue; + } + + // 3c - Check for else or endif + + if (GNUMakefileUtil.isElse(line)) { + Else elseDirective = (Else)parseConditional(line); + elseDirective.setLines(startLine, endLine); + Conditional cond = null; + // FIXME: Are we missing a if condition ? + if (!conditions.empty()) { + cond = (Conditional) conditions.pop(); + cond.setEndLine(endLine - 1); + } + if (cond != null && cond.isIf()) { + // See 3b above for description on automake if/else handling. + elseDirective.setAutomake(true); + rules = ((If)cond).getRules(); + // We cache the rules at the time of entry into the if/else block. + elseDirective.setRules(rules); + if (rules != null) { + // The else is added to the rules. + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(elseDirective); + rules[i].setEndLine(endLine); + } + } else { + addDirective(conditions, elseDirective); + } + rules = null; + } else { + addDirective(conditions, elseDirective); + } + conditions.push(elseDirective); + continue; + } else if (GNUMakefileUtil.isEndif(line)) { + Endif endif = new Endif(this); + endif.setLines(startLine, endLine); + Conditional cond = null; + // FIXME: Are we missing a if/else condition ? + if (!conditions.empty()) { + cond = (Conditional) conditions.pop(); + cond.setEndLine(endLine); + } + if (cond != null && cond instanceof IAutomakeConditional) { + rules = ((IAutomakeConditional)cond).getRules(); + } + if (rules != null) { + // The endif is added to the rules. + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(endif); + rules[i].setEndLine(endLine); + } + } else { + addDirective(conditions, endif); + } + continue; + } + + // 4 - reset rules to null + // The first non empty line that does not begin with a <TAB> or '#' + // shall begin a new entry. + rules = null; + + // 5- Check for the conditionals. + Directive directive = processConditions(line); + if (directive != null) { + directive.setLines(startLine, endLine); + addDirective(conditions, directive); + conditions.push(directive); + continue; + } + + // 6- Check for other special gnu directives. + directive = processGNUDirectives(line); + if (directive != null) { + directive.setLines(startLine, endLine); + addDirective(conditions, directive); + continue; + } + + // 7- Check for GNU special rules. + SpecialRule special = processSpecialRules(line); + if (special != null) { + rules = new Rule[] { special }; + special.setLines(startLine, endLine); + addDirective(conditions, special); + continue; + } + + // - Check for inference rule. + if (PosixMakefileUtil.isInferenceRule(line)) { + InferenceRule irule = parseInferenceRule(line); + irule.setLines(startLine, endLine); + addDirective(conditions, irule); + rules = new Rule[] { irule }; + continue; + } + + // - Variable Definiton ? + if (GNUMakefileUtil.isVariableDefinition(line)) { + GNUVariableDef vd = parseGNUVariableDef(line); + vd.setLines(startLine, endLine); + addDirective(conditions, vd); + if (!vd.isTargetSpecific()) { + continue; + } + } + + // - GNU Static Target rule ? + if (GNUMakefileUtil.isStaticTargetRule(line)) { + StaticTargetRule[] srules = parseStaticTargetRule(line); + for (int i = 0; i < srules.length; i++) { + srules[i].setLines(startLine, endLine); + addDirective(conditions, srules[i]); + } + rules = srules; + continue; + } + + // - Target Rule ? + if (GNUMakefileUtil.isGNUTargetRule(line)) { + GNUTargetRule[] trules = parseGNUTargetRules(line); + for (int i = 0; i < trules.length; i++) { + trules[i].setLines(startLine, endLine); + addDirective(conditions, trules[i]); + } + rules = trules; + continue; + } + + // - Configure macro (@xxxx@) + if (AutomakefileUtil.isConfigMacro(line)) { + AutomakeConfigMacro macro = parseConfigMacro(line); + if (macro != null) { + macro.setLines(startLine, endLine); + addDirective(macro); + continue; + } + } + + // XXX ?? Should not be here. + BadDirective stmt = new BadDirective(this, line); + stmt.setLines(startLine, endLine); + addDirective(conditions, stmt); + + } + setLines(1, endLine); + // TEST please remove. + //GNUMakefileValidator validator = new GNUMakefileValidator(); + //validator.validateDirectives(null, getDirectives()); + } + + private void addDirective(Stack<IDirective> conditions, Directive directive) { + if (conditions.empty()) { + addDirective(directive); + } else { + Conditional cond = (Conditional) conditions.peek(); + cond.addDirective(directive); + cond.setEndLine(directive.getEndLine()); + } + } + + protected Conditional processConditions(String line) { + Conditional stmt = null; + if (GNUMakefileUtil.isIfdef(line)) { + stmt = parseConditional(line); + } else if (GNUMakefileUtil.isIfndef(line)) { + stmt = parseConditional(line); + } else if (GNUMakefileUtil.isIfeq(line)) { + stmt = parseConditional(line); + } else if (GNUMakefileUtil.isIfneq(line)) { + stmt = parseConditional(line); + } + return stmt; + } + + protected Directive processGNUDirectives(String line) { + Directive stmt = null; + if (GNUMakefileUtil.isUnExport(line)) { + stmt = parseUnExport(line); + } else if (GNUMakefileUtil.isVPath(line)) { + stmt = parseVPath(line); + } else if (GNUMakefileUtil.isInclude(line)) { + stmt = parseInclude(line); + } + return stmt; + } + + protected SpecialRule processSpecialRules(String line) { + SpecialRule stmt = null; + if (PosixMakefileUtil.isIgnoreRule(line)) { + stmt = parseSpecialRule(line); + } else if (PosixMakefileUtil.isPosixRule(line)) { + stmt = parseSpecialRule(line); + } else if (PosixMakefileUtil.isPreciousRule(line)) { + stmt = parseSpecialRule(line); + } else if (PosixMakefileUtil.isSilentRule(line)) { + stmt = parseSpecialRule(line); + } else if (PosixMakefileUtil.isSuffixesRule(line)) { + stmt = parseSpecialRule(line); + } else if (PosixMakefileUtil.isDefaultRule(line)) { + stmt = parseSpecialRule(line); + } else if (PosixMakefileUtil.isSccsGetRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isPhonyRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isIntermediateRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isSecondaryRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isDeleteOnErrorRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isLowResolutionTimeRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isExportAllVariablesRule(line)) { + stmt = parseSpecialRule(line); + } else if (GNUMakefileUtil.isNotParallelRule(line)) { + stmt = parseSpecialRule(line); + } + return stmt; + } + + /** + * @param line + * @return + */ + protected SpecialRule parseSpecialRule(String line) { + line = line.trim(); + String keyword = null; + String[] reqs = null; + SpecialRule special = null; + int index = Util.indexOf(line, ':'); + if (index != -1) { + keyword = line.substring(0, index).trim(); + String req = line.substring(index + 1); + reqs = PosixMakefileUtil.findPrerequisites(req); + } else { + keyword = line; + reqs = new String[0]; + } + if (keyword.equals(MakeFileConstants.RULE_IGNORE)) { + special = new IgnoreRule(this, reqs); + } else if (keyword.equals(MakeFileConstants.RULE_POSIX)) { + special = new PosixRule(this); + } else if (keyword.equals(MakeFileConstants.RULE_PRECIOUS)) { + special = new PreciousRule(this, reqs); + } else if (keyword.equals(MakeFileConstants.RULE_SILENT)) { + special = new SilentRule(this, reqs); + } else if (keyword.equals(MakeFileConstants.RULE_SUFFIXES)) { + special = new SuffixesRule(this, reqs); + } else if (keyword.equals(MakeFileConstants.RULE_DEFAULT)) { + special = new DefaultRule(this, new Command[0]); + } else if (keyword.equals(MakeFileConstants.RULE_SCCS_GET)) { + special = new SccsGetRule(this, new Command[0]); + } else if (keyword.equals(GNUMakefileConstants.RULE_PHONY)) { + special = new PhonyRule(this, reqs); + } else if (keyword.equals(GNUMakefileConstants.RULE_INTERMEDIATE)) { + special = new IntermediateRule(this, reqs); + } else if (keyword.equals(GNUMakefileConstants.RULE_SECONDARY)) { + special = new SecondaryRule(this, reqs); + } else if (keyword.equals(GNUMakefileConstants.RULE_DELETE_ON_ERROR)) { + special = new DeleteOnErrorRule(this, reqs); + } else if (keyword.equals(GNUMakefileConstants.RULE_LOW_RESOLUTION_TIME)) { + special = new LowResolutionTimeRule(this, reqs); + } else if (keyword.equals(GNUMakefileConstants.RULE_EXPORT_ALL_VARIABLES)) { + special = new ExportAllVariablesRule(this, reqs); + } else if (keyword.equals(GNUMakefileConstants.RULE_NOT_PARALLEL)) { + special = new NotParallelRule(this, reqs); + } + return special; + } + + /** + * if CONDITIONAL + * + * @param line + * @return + */ + protected If parseIf(String line, Rule[] rules) { + line = line.trim(); + String keyword = null; + // Move pass the keyword + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + keyword = line.substring(0, i); + line = line.substring(i).trim(); + break; + } + } + if (keyword == null) { + keyword = line; + } + if (keyword.equals(GNUMakefileConstants.CONDITIONAL_IF) || + keyword.equals(GNUMakefileConstants.AT_CONDITIONAL_IF)) { + return new If(this, rules, line); + } + return null; + } + + /** + * + * ifdef CONDITIONAL + * ifeq CONDITIONAL + * ifneq CONDITIONAL + * else + * + * @param line + * @return + */ + protected Conditional parseConditional(String line) { + Conditional condition = null; + line = line.trim(); + String keyword = null; + // Move pass the keyword + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + keyword = line.substring(0, i); + line = line.substring(i).trim(); + break; + } + } + if (keyword == null) { + keyword = line; + } + if (keyword.equals(GNUMakefileConstants.CONDITIONAL_IFDEF)) { + condition = new Ifdef(this, line); + } else if (keyword.equals(GNUMakefileConstants.CONDITIONAL_IFNDEF)) { + condition = new Ifndef(this, line); + } else if (keyword.equals(GNUMakefileConstants.CONDITIONAL_IFEQ)) { + condition = new Ifeq(this, line); + } else if (keyword.equals(GNUMakefileConstants.CONDITIONAL_IFNEQ)) { + condition = new Ifneq(this, line); + } else if (keyword.equals(GNUMakefileConstants.CONDITIONAL_ELSE)) { + condition = new Else(this); + } + return condition; + } + + /** + * An Autoconf directive of the form @xxx@ + */ + protected AutomakeConfigMacro parseConfigMacro(String line) { + String extraChars = "_-"; + char[] ch = line.toCharArray(); + int i = 1; + while (Character.isLetterOrDigit(ch[i]) || + extraChars.indexOf(ch[i]) >= 0) { + ++i; + } + if (i > 1 && ch[i] == '@') + return new AutomakeConfigMacro(this, line.substring(0, i+1)); + return null; + } + /** + * Format of the include directive: + * include filename1 filename2 ... + */ + protected Include parseInclude(String line) { + String[] filenames; + StringTokenizer st = new StringTokenizer(line); + int count = st.countTokens(); + if (count > 0) { + filenames = new String[count - 1]; + for (int i = 0; i < count; i++) { + if (i == 0) { + st.nextToken(); + // ignore the "include" keyword. + continue; + } + filenames[i - 1] = st.nextToken(); + } + } else { + filenames = new String[0]; + } + return new Include(this, filenames, getIncludeDirectories()); + } + + /** + * There are three forms of the "vpath" directive: + * "vpath PATTERN DIRECTORIES" + * Specify the search path DIRECTORIES for file names that match PATTERN. + * + * The search path, DIRECTORIES, is a list of directories to be + * searched, separated by colons (semi-colons on MS-DOS and + * MS-Windows) or blanks, just like the search path used in the `VPATH' variable. + * + * "vpath PATTERN" + * Clear out the search path associated with PATTERN. + * + * "vpath" + * Clear all search paths previously specified with `vpath' directives. + */ + protected VPath parseVPath(String line) { + String pattern = null; + String[] directories; + StringTokenizer st = new StringTokenizer(line); + int count = st.countTokens(); + List<String> dirs = new ArrayList<String>(count); + if (count > 0) { + for (int i = 0; i < count; i++) { + if (count == 0) { + // ignore the "vpath" directive + st.nextToken(); + } else if (count == 1) { + pattern = st.nextToken(); + } else if (count == 3) { + String delim = " \t\n\r\f" + GNUAutomakefile.PATH_SEPARATOR; //$NON-NLS-1$ + dirs.add(st.nextToken(delim)); + } else { + dirs.add(st.nextToken()); + } + } + } + directories = (String[]) dirs.toArray(new String[0]); + if (pattern == null) { + pattern = ""; + } + return new VPath(this, pattern, directories); + } + + /** + * @param line + * @return + */ + protected UnExport parseUnExport(String line) { + // Pass over "unexport" + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + return new UnExport(this, line); + } + + protected GNUTargetRule[] parseGNUTargetRules(String line) { + String[] targetNames; + String[] normalReqs; + String[] orderReqs; + String cmd = null; + boolean doubleColon = false; + int index = Util.indexOf(line, ':'); + if (index != -1) { + // Break the targets + String target = line.substring(0, index); + targetNames = PosixMakefileUtil.findTargets(target.trim()); + + // Some TargetRule have "::" for separator + String req = line.substring(index + 1); + doubleColon = req.startsWith(":"); //$NON-NLS-1$ + if (doubleColon) { + // move pass the second ':' + req = req.substring(1); + } + + // Check for command + int semicolon = Util.indexOf(req, ';'); + if (semicolon != -1) { + cmd = req.substring(semicolon + 1); + req = req.substring(0, semicolon); + } + + // Check for Normal and order prerequisites + String normalReq = null; + String orderReq = null; + int pipe = Util.indexOf(req, '|'); + if (pipe != -1) { + normalReq = req.substring(0, pipe); + orderReq = req.substring(pipe + 1); + } else { + normalReq = req; + orderReq = ""; //$NON-NLS-1$ + } + + normalReqs = PosixMakefileUtil.findPrerequisites(normalReq.trim()); + orderReqs = PosixMakefileUtil.findPrerequisites(orderReq.trim()); + } else { + targetNames = PosixMakefileUtil.findTargets(line); + normalReqs = new String[0]; + orderReqs = new String[0]; + } + + GNUTargetRule[] rules = new GNUTargetRule[targetNames.length]; + for (int i = 0; i < targetNames.length; i++) { + rules[i] = new GNUTargetRule(this, new Target(targetNames[i]), doubleColon, normalReqs, orderReqs, new Command[0]); + if (cmd != null) { + rules[i].addDirective(new Command(this, cmd)); + } + } + return rules; + } + + protected GNUVariableDef parseGNUVariableDef(String line) { + line = line.trim(); + GNUVariableDef vd; + + // the default type. + int type = GNUVariableDef.TYPE_RECURSIVE_EXPAND; + boolean isDefine = false; + boolean isOverride = false; + boolean isTargetVariable = false; + boolean isExport = false; + String targetName = ""; //$NON-NLS-1$ + + String name; + StringBuffer value = new StringBuffer(); + + // Check for Target: Variable-assignment + isTargetVariable = GNUMakefileUtil.isTargetVariable(line); + if (isTargetVariable) { + // move to the first ':' + int colon = Util.indexOf(line, ':'); + if (colon != -1) { + targetName = line.substring(0, colon).trim(); + line = line.substring(colon + 1).trim(); + } else { + targetName = ""; //$NON-NLS-1$ + } + } + + // Check for Override condition. + if (GNUMakefileUtil.isOverride(line)) { + isOverride = true; + // Move pass the keyword override. + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + } + + // Check for "define" + if (GNUMakefileUtil.isDefine(line)) { + isDefine = true; + // Move pass the keyword define. + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + } + + // Check for Override condition. + if (GNUMakefileUtil.isExport(line)) { + isExport = true; + // Move pass the keyword export. + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + } + + // Check for Target-variable + + int index = line.indexOf('='); + if (index != -1) { + int separator = index; + // Check for "+=", ":=", "?=" + if (index > 0) { + type = line.charAt(index - 1); + if (type == GNUVariableDef.TYPE_SIMPLE_EXPAND + || type == GNUVariableDef.TYPE_APPEND + || type == GNUVariableDef.TYPE_CONDITIONAL) { + separator = index - 1; + } else { + type = GNUVariableDef.TYPE_RECURSIVE_EXPAND; + } + } + name = line.substring(0, separator).trim(); + value.append(line.substring(index + 1).trim()); + } else { + name = line; + } + + if (isTargetVariable) { + vd = new TargetVariable(this, targetName, name, value, isOverride, type); + } else if (isOverride && isDefine) { + vd = new OverrideDefine(this, name, value); + } else if (isDefine) { + vd = new DefineVariable(this, name, value); + } else if (isOverride) { + vd = new OverrideVariable(this, name, value, type); + } else if (isExport) { + vd = new ExportVariable(this, name, value, type); + } else { + vd = new GNUVariableDef(this, name, value, type); + } + return vd; + } + + protected StaticTargetRule[] parseStaticTargetRule(String line) { + // first colon: the Targets + String targetPattern; + String[] prereqPatterns; + String[] targets; + int colon = Util.indexOf(line, ':'); + if (colon > 1) { + String targetLine = line.substring(0, colon).trim(); + targets = PosixMakefileUtil.findTargets(targetLine); + // second colon: Target-Pattern + line = line.substring(colon + 1); + colon = Util.indexOf(line, ':'); + if (colon != -1) { + targetPattern = line.substring(0, colon).trim(); + line = line.substring(colon + 1); + StringTokenizer st = new StringTokenizer(line); + int count = st.countTokens(); + prereqPatterns = new String[count]; + for (int i = 0; i < count; i++) { + prereqPatterns[i] = st.nextToken(); + } + } else { + targetPattern = ""; //$NON-NLS-1$ + prereqPatterns = new String[0]; + } + } else { + targets = new String[0]; + targetPattern = ""; //$NON-NLS-1$ + prereqPatterns = new String[0]; + } + + StaticTargetRule[] staticRules = new StaticTargetRule[targets.length]; + for (int i = 0; i < targets.length; i++) { + staticRules[i] = new StaticTargetRule(this, new Target(targets[i]), targetPattern, prereqPatterns, new Command[0]); + } + return staticRules; + } + + /** + * @param line + * @return + */ + protected InferenceRule parseInferenceRule(String line) { + String tgt; + int index = Util.indexOf(line, ':'); + if (index != -1) { + tgt = line.substring(0, index); + } else { + tgt = line; + } + return new InferenceRule(this, new Target(tgt)); + } + + public IDirective[] getDirectives(boolean expand) { + if (!expand) { + return getDirectives(); + } + IDirective[] dirs = getDirectives(); + ArrayList<IDirective> list = new ArrayList<IDirective>(Arrays.asList(dirs)); + for (int i = 0; i < dirs.length; ++i) { + if (dirs[i] instanceof Include) { + Include include = (Include)dirs[i]; + IDirective[] includedMakefiles = include.getDirectives(); + for (int j = 0; j < includedMakefiles.length; ++j) { + IMakefile includedMakefile = (IMakefile)includedMakefiles[j]; + list.addAll(Arrays.asList(includedMakefile.getDirectives())); + } + } + } + return (IDirective[]) list.toArray(new IDirective[list.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.AbstractMakefile#getBuiltins() + */ + public IDirective[] getBuiltins() { + if (builtins == null) { + String location = "builtin" + File.separator + "gnu.mk"; //$NON-NLS-1$ //$NON-NLS-2$ + try { + InputStream stream = FileLocator.openStream(MakeCorePlugin.getDefault().getBundle(), new Path(location), false); + GNUAutomakefile gnu = new GNUAutomakefile(); + URL url = FileLocator.find(MakeCorePlugin.getDefault().getBundle(), new Path(location), null); + url = FileLocator.resolve(url); + location = url.getFile(); + gnu.parse(location, new InputStreamReader(stream)); + builtins = gnu.getDirectives(); + for (int i = 0; i < builtins.length; i++) { + if (builtins[i] instanceof MacroDefinition) { + ((MacroDefinition)builtins[i]).setFromDefault(true); + } + } + } catch (Exception e) { + //e.printStackTrace(); + } + if (builtins == null) { + builtins = new IDirective[0]; + } + } + return builtins.clone(); + } + + public void setIncludeDirectories(String[] dirs) { + includeDirectories = dirs.clone(); + } + + public String[] getIncludeDirectories() { + return includeDirectories.clone(); + } + + /** + * Create an IMakefile using the given IMakefileReaderProvider to fetch + * contents by name. + * + * @param fileURI URI of main file + * @param makefileReaderProvider may be <code>null</code> for EFS IFileStore reading + */ + public static IMakefile createMakefile(IFile file) throws CoreException { + URI fileURI = file.getLocationURI(); + IMakefile makefile = null; + GNUAutomakefile gnu = new GNUAutomakefile(); + ArrayList<String> includeList = new ArrayList<String>(); + includeList.add(new Path(fileURI.getPath()).removeLastSegments(1).toString()); + includeList.addAll(Arrays.asList(gnu.getIncludeDirectories())); + String[] includes = includeList.toArray(new String[includeList.size()]); + gnu.setIncludeDirectories(includes); + try { + final IFileStore store = EFS.getStore(fileURI); + final IFileInfo info = store.fetchInfo(); + if (!info.exists() || info.isDirectory()) + throw new IOException(); + + MakefileReader reader = new MakefileReader(new InputStreamReader( + store.openInputStream(EFS.NONE, null))); + gnu.parse(fileURI, reader); + } catch (IOException e) { + AutotoolsUIPlugin.log(e); + Status status = new Status(IStatus.ERROR, AutotoolsUIPlugin.PLUGIN_ID, e.getLocalizedMessage()); + throw new CoreException(status); + } + makefile = gnu; + return makefile; + } + + public static void main(String[] args) { + try { + String filename = "Makefile"; //$NON-NLS-1$ + if (args.length == 1) { + filename = args[0]; + } + GNUAutomakefile makefile = new GNUAutomakefile(); + makefile.parse(filename); + IDirective[] directive = makefile.getDirectives(); + for (int i = 0; i < directive.length; i++) { + //System.out.println("Rule[" + i +"]"); + System.out.print(directive[i]); + } + } catch (IOException e) { + System.out.println(e); + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUMakefileConstants.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUMakefileConstants.java new file mode 100644 index 00000000000..4cea7c72a9d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUMakefileConstants.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified for Automake editor usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class GNUMakefileConstants extends MakeFileConstants { + static final String CONDITIONAL_ELSE = "else"; //$NON-NLS-1$ + static final String CONDITIONAL_IF = "if"; //$NON-NLS-1$ + static final String AT_CONDITIONAL_IF = "@if"; //$NON-NLS-1$ + static final String CONDITIONAL_IFNEQ = "ifneq"; //$NON-NLS-1$ + static final String CONDITIONAL_IFNDEF = "ifndef"; //$NON-NLS-1$ + static final String CONDITIONAL_IFEQ = "ifeq"; //$NON-NLS-1$ + static final String CONDITIONAL_IFDEF = "ifdef"; //$NON-NLS-1$ + + static final String TERMINAL_ENDEF = "endef"; //$NON-NLS-1$ + static final String TERMINAL_ENDIF = "endif"; //$NON-NLS-1$ + static final String AT_TERMINAL_ENDIF = "@endif"; //$NON-NLS-1$ + + static final String DIRECTIVE_VPATH = "vpath"; //$NON-NLS-1$ + static final String DIRECTIVE_UNEXPORT = "unexport"; //$NON-NLS-1$ + + static final String VARIABLE_DEFINE = "define"; //$NON-NLS-1$ + static final String VARIABLE_EXPORT = "export"; //$NON-NLS-1$ + static final String VARIABLE_OVERRIDE = "override"; //$NON-NLS-1$ + + static final String DIRECTIVE_INCLUDE = "include"; //$NON-NLS-1$ + + static final String RULE_DELETE_ON_ERROR = ".DELETE_ON_ERROR"; //$NON-NLS-1$ + static final String RULE_PHONY = ".PHONY"; //$NON-NLS-1$ + static final String RULE_SECONDARY = ".SECONDARY"; //$NON-NLS-1$ + static final String RULE_LOW_RESOLUTION_TIME = ".LOW_RESOLUTION_TIME"; //$NON-NLS-1$ + static final String RULE_NOT_PARALLEL = ".NOTPARALLEL"; //$NON-NLS-1$ + static final String RULE_EXPORT_ALL_VARIABLES = ".EXPORT_ALL_VARIABLES"; //$NON-NLS-1$ + static final String RULE_INTERMEDIATE = ".INTERMEDIATE"; //$NON-NLS-1$ +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUMakefileUtil.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUMakefileUtil.java new file mode 100644 index 00000000000..0f1383b61a9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUMakefileUtil.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified for Automake editor usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +/** + * GNUMakefile + */ +public class GNUMakefileUtil extends PosixMakefileUtil { + + public static boolean isInclude(String line) { + line = line.trim(); + boolean isInclude = line.startsWith(GNUMakefileConstants.DIRECTIVE_INCLUDE) && line.length() > 7 && Character.isWhitespace(line.charAt(7)); + boolean isDashInclude = line.startsWith("-" + GNUMakefileConstants.DIRECTIVE_INCLUDE) && line.length() > 8 && Character.isWhitespace(line.charAt(8)); //$NON-NLS-1$ + boolean isSInclude = line.startsWith("s" + GNUMakefileConstants.DIRECTIVE_INCLUDE) && line.length() > 8 && Character.isWhitespace(line.charAt(8)); //$NON-NLS-1$ + return isInclude || isDashInclude || isSInclude; + } + + public static boolean isVPath(String line) { + line = line.trim(); + return line.equals(GNUMakefileConstants.DIRECTIVE_VPATH) || line.startsWith(GNUMakefileConstants.DIRECTIVE_VPATH) && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + } + + public static boolean isExport(String line) { + line = line.trim(); + return line.equals(GNUMakefileConstants.VARIABLE_EXPORT) || line.startsWith(GNUMakefileConstants.VARIABLE_EXPORT) && line.length() > 6 && Character.isWhitespace(line.charAt(6)); + } + + public static boolean isUnExport(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.DIRECTIVE_UNEXPORT) && line.length() > 8 && Character.isWhitespace(line.charAt(8)); + } + + public static boolean isDefine(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.VARIABLE_DEFINE) && line.length() > 6 && Character.isWhitespace(line.charAt(6)); + } + + public static boolean isEndef(String line) { + return line.trim().equals(GNUMakefileConstants.TERMINAL_ENDEF); + } + + public static boolean isOverride(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.VARIABLE_OVERRIDE) && line.length() > 8 && Character.isWhitespace(line.charAt(8)); + } + + public static boolean isIf(String line) { + line = line.trim(); + return (line.startsWith(GNUMakefileConstants.CONDITIONAL_IF) && line.length() > 2 && Character.isWhitespace(line.charAt(2))) || + (line.startsWith(GNUMakefileConstants.AT_CONDITIONAL_IF) && line.length() > 3 && Character.isWhitespace(line.charAt(3))); + } + + public static boolean isIfeq(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.CONDITIONAL_IFEQ) && line.length() > 4 && Character.isWhitespace(line.charAt(4)); + } + + public static boolean isIfneq(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.CONDITIONAL_IFNEQ) && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + } + + public static boolean isIfdef(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.CONDITIONAL_IFDEF) && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + } + + public static boolean isIfndef(String line) { + line = line.trim(); + return line.startsWith(GNUMakefileConstants.CONDITIONAL_IFNDEF) && line.length() > 6 && Character.isWhitespace(line.charAt(6)); + } + + public static boolean isElse(String line) { + return line.trim().equals(GNUMakefileConstants.CONDITIONAL_ELSE); + } + + public static boolean isEndif(String line) { + return line.trim().equals(GNUMakefileConstants.TERMINAL_ENDIF) || + line.trim().startsWith(GNUMakefileConstants.AT_TERMINAL_ENDIF); + } + + public static boolean isOverrideDefine(String line) { + line = line.trim(); + if (line.startsWith(GNUMakefileConstants.VARIABLE_OVERRIDE)) { + int i = 8; + while(i < line.length() && Character.isWhitespace(line.charAt(i))) { + i++; + } + if (line.startsWith(GNUMakefileConstants.VARIABLE_DEFINE, i)) { + return true; + } + } + return false; + } + + public static boolean isTargetVariable(String line) { + line = line.trim(); + int index = Util.indexOf(line, ':'); + if (index > 1) { + line = line.substring(index + 1).trim(); + int equal = Util.indexOf(line, '='); + if (equal > 1) { + return true; + } + } + return false; + } + + public static boolean isVariableDefinition(String line) { + return isOverrideDefine(line) + || isTargetVariable(line) + || isDefine(line) + || isOverride(line) + || isExport(line) + || isMacroDefinition(line); + } + + /** + * @param line + * @return + */ + public static boolean isStaticTargetRule(String line) { + line = line.trim(); + int colon1 = Util.indexOf(line, ':'); + if (colon1 > 0) { + // move pass colon1 + line = line.substring(colon1 + 1); + int colon2 = Util.indexOf(line, ':'); + // Catch operator "::" not a static pattern rule + return (colon2 > 0); + } + return false; + } + + /** + * @param line + * @return + */ + public static boolean isGNUTargetRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + colon++; + // Catch VariableDefiniton with operator ":=" + if (colon < line.length()) { + return line.charAt(colon) != '='; + } + return true; + } + return false; + } + + public static boolean isPhonyRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_PHONY); + } + return false; + } + + public static boolean isIntermediateRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_INTERMEDIATE); + } + return false; + } + + public static boolean isSecondaryRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_SECONDARY); + } + return false; + } + + public static boolean isDeleteOnErrorRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_DELETE_ON_ERROR); + } + return false; + } + + public static boolean isLowResolutionTimeRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_LOW_RESOLUTION_TIME); + } + return false; + } + + public static boolean isExportAllVariablesRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_EXPORT_ALL_VARIABLES); + } + return false; + } + + public static boolean isNotParallelRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(GNUMakefileConstants.RULE_NOT_PARALLEL); + } + return false; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUTargetRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUTargetRule.java new file mode 100644 index 00000000000..1f41ae8912e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUTargetRule.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + */ +public class GNUTargetRule extends TargetRule { + + String[] orderOnlyPrerequisites; + boolean doubleColon; + + public GNUTargetRule(Directive parent, Target target, boolean double_colon, String[] normal_prereqs, String[] order_prereqs, Command[] commands) { + super(parent, target, normal_prereqs, commands); + orderOnlyPrerequisites = order_prereqs.clone(); + doubleColon = double_colon; + } + + public boolean isDoubleColon() { + return doubleColon; + } + + public String[] getNormalPrerequisites() { + return getPrerequisites(); + } + + public String[] getOrderOnlyPrerequisites() { + return orderOnlyPrerequisites.clone(); + } + + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getTarget().toString()); + buffer.append(':'); + String[] reqs = getNormalPrerequisites(); + for (int i = 0; i < reqs.length; i++) { + buffer.append(' ').append(reqs[i]); + } + reqs = getOrderOnlyPrerequisites(); + if (reqs.length > 0) { + buffer.append(" |"); //$NON-NLS-1$ + for (int i = 0; i < reqs.length; i++) { + buffer.append(' ').append(reqs[i]); + } + } + buffer.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); + } + return buffer.toString(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUVariableDef.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUVariableDef.java new file mode 100644 index 00000000000..93831f0d64d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/GNUVariableDef.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Refactor name + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + */ +public class GNUVariableDef extends MacroDefinition implements IVariableDefinition { + + /** + * ? is Conditional + * : is Simply-expanded + * + is append + * 0 is recursively-expanded. + */ + final static int TYPE_RECURSIVE_EXPAND = 0; + final static int TYPE_SIMPLE_EXPAND = ':'; + final static int TYPE_CONDITIONAL = '?'; + final static int TYPE_APPEND = '+'; + int type; + String varTarget; + + public GNUVariableDef(Directive parent, String name, StringBuffer value) { + this(parent, name, value, TYPE_RECURSIVE_EXPAND); + } + + public GNUVariableDef(Directive parent, String name, StringBuffer value, int type) { + this(parent, "", name, value, type); //$NON-NLS-1$ + } + + public GNUVariableDef(Directive parent, String target, String name, StringBuffer value, int type) { + super(parent, name, value); + varTarget = target; + this.type = type; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + if (isTargetSpecific()) { + sb.append(getTarget()).append(": "); //$NON-NLS-1$ + } + if (isOverride()) { + sb.append(GNUMakefileConstants.VARIABLE_OVERRIDE); + } + if (isMultiLine()) { + sb.append(GNUMakefileConstants.VARIABLE_DEFINE); + sb.append(' '); + sb.append(getName()).append('\n'); + sb.append(getValue()).append('\n'); + sb.append(GNUMakefileConstants.TERMINAL_ENDEF); + sb.append('\n'); + } else { + if (isExport()) { + sb.append(GNUMakefileConstants.VARIABLE_EXPORT); + sb.append(' '); + } + sb.append(getName()); + if (isRecursivelyExpanded()) { + sb.append(" = "); //$NON-NLS-1$ + } else if (isSimplyExpanded()) { + sb.append(" := "); //$NON-NLS-1$ + } else if (isConditional()) { + sb.append(" ?= "); //$NON-NLS-1$ + } else if (isAppend()) { + sb.append(" += "); //$NON-NLS-1$ + } + sb.append(getValue()).append('\n'); + } + return sb.toString(); + } + + public boolean isRecursivelyExpanded() { + return type == TYPE_RECURSIVE_EXPAND; + } + + public boolean isSimplyExpanded() { + return type == TYPE_SIMPLE_EXPAND; + } + + public boolean isConditional() { + return type == TYPE_CONDITIONAL; + } + + public boolean isAppend() { + return type == TYPE_APPEND; + } + + public boolean isTargetSpecific() { + String t = getTarget(); + return t != null && t.length() > 0; + } + + public boolean isExport() { + return false; + } + + public boolean isMultiLine() { + return false; + } + + /** + * Variable from an `override' directive. + */ + public boolean isOverride() { + return false; + } + + /** + * Automatic variable -- cannot be set. + */ + public boolean isAutomatic() { + return false; + } + + public String getTarget() { + return varTarget; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IArchiveTarget.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IArchiveTarget.java new file mode 100644 index 00000000000..9a2b555e967 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IArchiveTarget.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * IArchiveTarget + * Archive files, are files maintained by the program "ar". + * They contain objects, the members of the Archive. + * For example: + * foolib(hack.o) : hack.o + * ar cr foolib hack.o + * ArchiveTarget(member) -- foolib(hack.o); + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IArchiveTarget extends ITarget { + + /** + * Returns the members the point by archive target. + * @return String + */ + String[] getMembers(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IAutomakeConditional.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IAutomakeConditional.java new file mode 100644 index 00000000000..f9ecac051aa --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IAutomakeConditional.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * 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 Incorporated - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public interface IAutomakeConditional { + + public boolean isAutomake(); + public void setAutomake(boolean value); + public Rule[] getRules(); + public void setRules(Rule[] rules); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IBadDirective.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IBadDirective.java new file mode 100644 index 00000000000..c7c5b914346 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IBadDirective.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Represent an error in the makefile syntax + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IBadDirective { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ICommand.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ICommand.java new file mode 100644 index 00000000000..2f9750b7549 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ICommand.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; +import java.io.IOException; + + +/** + * ICommand + * Commands are associated with a rule and executed by + * the make program when building a target. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICommand extends IDirective { + + final public static char HYPHEN = '-'; + + final public static String HYPHEN_STRING = "-"; //$NON-NLS-1$ + + final public static char AT = '@'; + + final public static String AT_STRING = "@"; //$NON-NLS-1$ + + final public static char PLUS = '+'; + + final public static String PLUS_STRING = "+"; //$NON-NLS-1$ + + final public static char TAB = '\t'; + + /** + * - If the command prefix contains a hyphen, or the -i option is + * present, or the special target .IGNORE has either the current + * target as a prerequisite or has no prerequisites, any error + * found while executing the command will be ignored. + */ + boolean shouldIgnoreError(); + + /** + * @ If the command prefix contains an at sign and the + * command-line -n option is not specified, or the -s option is + * present, or the special target .SILENT has either the current + * target as a prerequisite or has no prerequisites, the command + * will not be written to standard output before it is executed. + */ + boolean shouldBeSilent(); + + /** + * + If the command prefix contains a plus sign, this indicates a + * command line that will be executed even if -n, -q or -t is + * specified. + */ + boolean shouldExecute(); + + + /** + * Executes the command in a separate process with the + * specified environment and working directory. + * + */ + Process execute(String shell, String[] envp, File dir) throws IOException; +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IComment.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IComment.java new file mode 100644 index 00000000000..2c3ecd55472 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IComment.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Comments start with '#' and until the end of the line. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IComment extends IDirective { + + final public static char POUND = '#'; + + final public static String POUND_STRING = "#"; //$NON-NLS-1$ + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IConditional.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IConditional.java new file mode 100644 index 00000000000..f1be19b3676 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IConditional.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IConditional extends IDirective { + + String getConditional(); + + String getArg1(); + + String getArg2(); + + boolean isIfdef(); + + boolean isIfndef(); + + boolean isIfeq(); + + boolean isIfneq(); + + boolean isElse(); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDefaultRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDefaultRule.java new file mode 100644 index 00000000000..f44c04c7589 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDefaultRule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .DEFAULT + * If the makefile uses this special target, the application shall ensure that it is + * specified with commands, but without prerequisites. + * The commands shall be used by make if there are no other rules available to build a target. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IDefaultRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDeleteOnErrorRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDeleteOnErrorRule.java new file mode 100644 index 00000000000..09ee9daf9b5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDeleteOnErrorRule.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .DELETE_ON_ERROR' + * If `.DELETE_ON_ERROR' is mentioned as a target anywhere in the + * makefile, then `make' will delete the target of a rule if it has + * changed and its commands exit with a nonzero exit status, just as + * it does when it receives a signal. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IDeleteOnErrorRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDirective.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDirective.java new file mode 100644 index 00000000000..6b699d4d4cf --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IDirective.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * A Makefile can contain rules, macro definitons and comments. + * They are call directives. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IDirective { + + /** + * @return the parent of this directive, null if none. + */ + IDirective getParent(); + + /** + * @return the starting line number of this directive. + * The numbering starts at 1 .i.e the first line is not 0 + */ + int getStartLine(); + + /** + * @return the ending line number of this directive. + * The numbering starts at 1 .i.e the first line is not 0 + */ + int getEndLine(); + + /** + * Returns the makefile where the directive was found. + * + * @return <code>IMakefile</code> + */ + IMakefile getMakefile(); + + String toString(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IEmptyLine.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IEmptyLine.java new file mode 100644 index 00000000000..ea7e67df764 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IEmptyLine.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * IEmptyLine + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IEmptyLine extends IDirective { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IExportAllVariablesRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IExportAllVariablesRule.java new file mode 100644 index 00000000000..681b82d8823 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IExportAllVariablesRule.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .EXPORT_ALL_VARIABLES + * Simply by being mentioned as a target, this tells `make' to export + * all variables to child processes by default. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IExportAllVariablesRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IGNUMakefile.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IGNUMakefile.java new file mode 100644 index 00000000000..505710cd254 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IGNUMakefile.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IGNUMakefile extends IMakefile { + + /** + * Set the search include directories for the + * "include" directive + */ + void setIncludeDirectories(String[] paths); + + /** + * @return the include directories search paths. + */ + String[] getIncludeDirectories(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IIgnoreRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IIgnoreRule.java new file mode 100644 index 00000000000..a367a321a9d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IIgnoreRule.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .IGNORE + * Prerequisites of this special target are targets themselves; this shall cause errors + * from commands associated with them to be ignored in the same manner as specified by the -i option. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IIgnoreRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IInclude.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IInclude.java new file mode 100644 index 00000000000..adf50b70f19 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IInclude.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IInclude extends IParent { + String[] getFilenames(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IInferenceRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IInferenceRule.java new file mode 100644 index 00000000000..54163f56299 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IInferenceRule.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * IInferenceRules are formated as follows: + * target: + * <tab>command + * [<tab>command] + * + * The target is of the form .s2 or .s1.s2 + * There are no prerequisites. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IInferenceRule extends IRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IIntermediateRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IIntermediateRule.java new file mode 100644 index 00000000000..b0c6d21564a --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IIntermediateRule.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .INTERMEDIATE + * The targets which `.INTERMEDIATE' depends on are treated as intermediate files. + * `.INTERMEDIATE' with no prerequisites has no effect. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IIntermediateRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ILowResolutionTimeRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ILowResolutionTimeRule.java new file mode 100644 index 00000000000..836e09287c9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ILowResolutionTimeRule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .LOW_RESOLUTION_TIME + * If you specify prerequisites for `.LOW_RESOLUTION_TIME', `make' + * assumes that these files are created by commands that generate low + * resolution time stamps. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ILowResolutionTimeRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMacroDefinition.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMacroDefinition.java new file mode 100644 index 00000000000..f4a99738efa --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMacroDefinition.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * IMacroDefinitions are in the form: + * string1 = [string2] + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IMacroDefinition extends IDirective { + + /** + * @return the name of the macro + */ + String getName(); + + /** + * @return the value of the macro + */ + StringBuffer getValue(); + + /** + * @return the macro is a built-in + */ + boolean isFromDefault(); + + /** + * @return the macro was found in a Makefile. + * + */ + boolean isFromMakefile(); + + /** + * @return the macro came from the environment. + */ + boolean isFromEnviroment(); + + /** + * The macro came from the make command option -e + */ + boolean isFromEnvironmentOverride(); + + /** + * @return the macro was pass from an option to make. + */ + boolean isFromCommand(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefile.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefile.java new file mode 100644 index 00000000000..585aea80085 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefile.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.io.Reader; +import java.net.URI; + + +/** + * IMakefile: + * + * Makefile : ( directive ) * + * directive : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule | special_rule + * inference_rule : target ':' [ ';' command ] <nl> + * [ ( command ) * ] + * target_rule : [ ( target ) + ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl> + * [ ( command ) * ] + * macro_definition : string '=' ( string )* + * comments : ('#' ( string ) <nl>) * + * empty : <nl> + * command : <tab> prefix_command string <nl> + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IMakefile extends IParent { + + /** + * ITargetRule | IInferenceRule | ISpecialRule + */ + IRule[] getRules(); + + /** + * @return the IRule for target. + */ + IRule[] getRules(String target); + + /** + * @return IInferenceRule + * + */ + IInferenceRule[] getInferenceRules(); + + /** + * @return the IInferenceRules for target. + */ + IInferenceRule[] getInferenceRules(String target); + + /** + * @return ITargetRule + */ + ITargetRule[] getTargetRules(); + + /** + * @return the ITargetRules for name. + */ + ITargetRule[] getTargetRules(String target); + + /** + * @return the IMacroDefinitions. + */ + IMacroDefinition[] getMacroDefinitions(); + + /** + * @return the IMacroDefinitions for name. + */ + IMacroDefinition[] getMacroDefinitions(String name); + + /** + * @return all the built-in directives. + */ + IDirective[] getBuiltins(); + + /** + * @return all the built-in MacroDefintions + */ + IMacroDefinition[] getBuiltinMacroDefinitions(); + + /** + * @return the built-in macro definition for name. + */ + IMacroDefinition[] getBuiltinMacroDefinitions(String name); + + /** + * @return line after expanding any macros. + */ + String expandString(String line); + + /** + * @return line after expanding any macros. + * + * @param line - line to expand + * @param recursive - if true recursively expand. + */ + String expandString(String line, boolean recursive); + + /** + * @return the makefile Reader provider used to create this makefile or <code>null</code> + */ + IMakefileReaderProvider getMakefileReaderProvider(); + + /** + * Clear all statements and (re)parse the Makefile + */ + void parse(String filePath, Reader makefile) throws IOException; + + /** + * Clear all statements and (re)parse the Makefile + */ + void parse(URI fileURI, Reader makefile) throws IOException; + + /** + * Clear the all statements and (re)parse the Makefile + * using the given makefile Reader provider + * + * @param makefileReaderProvider provider, or <code>null</code> to use a FileReader + */ + void parse(URI fileURI, IMakefileReaderProvider makefileReaderProvider) throws IOException; + + + /** + * @return the <code>URI</code> of this makefile + */ + URI getFileURI(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileDocumentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileDocumentProvider.java new file mode 100644 index 00000000000..4b204c475fb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileDocumentProvider.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +/* + */ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.ui.texteditor.IDocumentProvider; + +/** + */ +public interface IMakefileDocumentProvider extends IDocumentProvider { + + /** + * Shuts down this provider. + */ + void shutdown(); + + /** + * Returns the working copy for the given element. + * + * @param element the element + * @return the working copy for the given element + */ + IMakefile getWorkingCopy(Object element); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileEditorActionDefinitionIds.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileEditorActionDefinitionIds.java new file mode 100644 index 00000000000..be8a98ce622 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileEditorActionDefinitionIds.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +/** + */ +public interface IMakefileEditorActionDefinitionIds { + + final String UNCOMMENT = "org.eclipse.cdt.make.ui.edit.text.makefile.uncomment"; //$NON-NLS-1$ + + final String COMMENT = "org.eclipse.cdt.make.ui.edit.text.makefile.comment"; //$NON-NLS-1$ + + final String OPEN_DECLARATION = "org.eclipse.cdt.make.ui.edit.text.makefile.opendcl"; //$NON-NLS-1$ + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileReaderProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileReaderProvider.java new file mode 100644 index 00000000000..9d4626104bb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileReaderProvider.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 Nokia 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: + * Nokia (Ed Swartz) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.io.Reader; +import java.net.URI; + +/** + * Provide an abstraction to loading the contents of a makefile + * @author eswartz + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IMakefileReaderProvider { + /** + * Get a reader for the contents of the file at filename. + * @param fileURI the file to read. It's up to the implementation how to read + * it, but usually EFS.getFileStore(fileURI).getInputStream(...) is the best bet. + * @return Reader a reader for the contents of the existing file + * @throws IOException if the file cannot be found according to the implementation + */ + Reader getReader(URI fileURI) throws IOException; +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileValidator.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileValidator.java new file mode 100644 index 00000000000..3603db3f569 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IMakefileValidator.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * @author alain + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IMakefileValidator { + public abstract void setMarkerGenerator(IMarkerGenerator errorHandler); + public abstract void checkFile(IFile file, IProgressMonitor monitor); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/INotParallelRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/INotParallelRule.java new file mode 100644 index 00000000000..0ca249712b1 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/INotParallelRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .NOTPARALLEL + * If `.NOTPARALLEL' is mentioned as a target, then this invocation of + * `make' will be run serially, even if the `-j' option is given. + * Any recursively invoked `make' command will still be run in + * parallel (unless its makefile contains this target). Any + * prerequisites on this target are ignored. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface INotParallelRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IParent.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IParent.java new file mode 100644 index 00000000000..9182adb5964 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IParent.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IParent extends IDirective { + IDirective[] getDirectives(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPhonyRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPhonyRule.java new file mode 100644 index 00000000000..b11f5484692 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPhonyRule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .PHONY + * The prerequisites of the special target `.PHONY' are considered to be phony targets. + * When it is time to consider such a target, `make' will run its commands unconditionally, regardless of + * whether a file with that name exists or what its last-modification time is. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IPhonyRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPosixRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPosixRule.java new file mode 100644 index 00000000000..404498a0a1b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPosixRule.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .POSIX + * The application shall ensure that this special target is specified without + * prerequisites or commands. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IPosixRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPreciousRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPreciousRule.java new file mode 100644 index 00000000000..ef0fa1a1aa8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IPreciousRule.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .PRECIOUS + * Prerequisites of this special target shall not be removed if make recieves an + * asynchronous events. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IPreciousRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IReconcilingParticipant.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IReconcilingParticipant.java new file mode 100644 index 00000000000..bb03de8f62d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IReconcilingParticipant.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +/** + * IReconcilingParticipant + * Interface of an object participating in reconciling. + */ +public interface IReconcilingParticipant { + + /** + * Called after reconciling has been finished. + */ + void reconciled(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IRule.java new file mode 100644 index 00000000000..ed300035952 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IRule.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * There are several kinds of rules: Inference rules, target rules + * Some make provides special rules for example: + * .DEFAULT, .IGNORE etc ... + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IRule extends IParent { + /** + * @return Array of command for the rule. + */ + ICommand[] getCommands(); + + /** + * @return The rule target name. + * + */ + ITarget getTarget(); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISccsGetRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISccsGetRule.java new file mode 100644 index 00000000000..647d5801ef4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISccsGetRule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SCCS_GET + * The application shall ensure that this special target is specified without prerequesites. + * The commands specified with this target shall replace the default + * commands associated with this special target. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ISccsGetRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISecondaryRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISecondaryRule.java new file mode 100644 index 00000000000..59c8f6abb97 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISecondaryRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SECONDARY + * The targets which `.SECONDARY' depends on are treated as + * intermediate files, except that they are never automatically deleted. + * + * `.SECONDARY' with no prerequisites causes all targets to be treated + * as secondary (i.e., no target is removed because it is considered intermediate). + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ISecondaryRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISelectionValidator.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISelectionValidator.java new file mode 100644 index 00000000000..8e98d308036 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISelectionValidator.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +public interface ISelectionValidator { + void isValid(Object[] selection, StatusInfo res); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISilentRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISilentRule.java new file mode 100644 index 00000000000..de830bb9ba2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISilentRule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SILENT + * Prerequisites of this special target are targets themselves; this shall case + * commands associated with them not to be written to the standard output before + * they are executed. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ISilentRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISpecialRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISpecialRule.java new file mode 100644 index 00000000000..4ec637b442b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISpecialRule.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Target rule that have special meaning for Make. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ISpecialRule extends IRule { + + /** + * The meaning of the prerequistes are specific to + * each rules. + */ + String[] getPrerequisites(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISuffixesRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISuffixesRule.java new file mode 100644 index 00000000000..3e9c822a900 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ISuffixesRule.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SUFFIXES + * Prerequesites of .SUFFIXES shall be appended to the list of known suffixes and are + * used in conjunction with the inference rules. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ISuffixesRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITarget.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITarget.java new file mode 100644 index 00000000000..c014c22c401 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITarget.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ITarget { + + String toString(); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITargetRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITargetRule.java new file mode 100644 index 00000000000..ff803b1a873 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITargetRule.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ITargetRule extends IRule { + + String[] getPrerequisites(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITerminal.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITerminal.java new file mode 100644 index 00000000000..38625a517c5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITerminal.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * ITerminal finish a block. + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ITerminal extends IDirective { + + boolean isEndef(); + + boolean isEndif(); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITranslationUnitEditorInput.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITranslationUnitEditorInput.java new file mode 100644 index 00000000000..bf955c7d3b0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ITranslationUnitEditorInput.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.editors.text.ILocationProvider; + +/** + * ITranslationUnitEditorInput + */ +public interface ITranslationUnitEditorInput extends IStorageEditorInput, ILocationProvider { + + ITranslationUnit getTranslationUnit(); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IUnExport.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IUnExport.java new file mode 100644 index 00000000000..bfae468441c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IUnExport.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IUnExport extends IDirective { + + String getVariable(); +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IVPath.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IVPath.java new file mode 100644 index 00000000000..ebb6c0e2777 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IVPath.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IVPath extends IDirective { + + String[] getDirectories(); + + String getPattern(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IVariableDefinition.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IVariableDefinition.java new file mode 100644 index 00000000000..0a36672db10 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IVariableDefinition.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + */ +/** + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IVariableDefinition extends IMacroDefinition { + + boolean isRecursivelyExpanded(); + + boolean isSimplyExpanded(); + + boolean isConditional(); + + boolean isAppend(); + + boolean isTargetSpecific(); + + boolean isExport(); + + boolean isMultiLine(); + + /** + * Variable from an `override' directive. + */ + boolean isOverride(); + + /** + * Automatic variable -- cannot be set. + */ + boolean isAutomatic(); + String getTarget(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IWorkingCopyManager.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IWorkingCopyManager.java new file mode 100644 index 00000000000..a17c1605318 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IWorkingCopyManager.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.ui.IEditorInput; + +/** + * Interface for accessing working copies of <code>IMakefile</code> + * objects. The original unit is only given indirectly by means + * of an <code>IEditorInput</code>. The life cycle is as follows: + * <ul> + * <li> <code>connect</code> creates and remembers a working copy of the + * unit which is encoded in the given editor input</li> + * <li> <code>getWorkingCopy</code> returns the working copy remembered on + * <code>connect</code></li> + * <li> <code>disconnect</code> destroys the working copy remembered on + * <code>connect</code></li> + * </ul> + * <p> + * This interface is not intended to be implemented by clients. + * </p> + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IWorkingCopyManager { + + /** + * Connects the given editor input to this manager. After calling + * this method, a working copy will be available for the compilation unit encoded + * in the given editor input (does nothing if there is no encoded compilation unit). + * + * @param input the editor input + * @exception CoreException if the working copy cannot be created for the + * unit + */ + void connect(IEditorInput input) throws CoreException; + + /** + * Disconnects the given editor input from this manager. After calling + * this method, a working copy for the compilation unit encoded + * in the given editor input will no longer be available. Does nothing if there + * is no encoded compilation unit, or if there is no remembered working copy for + * the compilation unit. + * + * @param input the editor input + */ + void disconnect(IEditorInput input); + + /** + * Returns the working copy remembered for the compilation unit encoded in the + * given editor input. + * + * @param input the editor input + * @return the working copy of the compilation unit, or <code>null</code> if the + * input does not encode an editor input, or if there is no remembered working + * copy for this compilation unit + */ + IMakefile getWorkingCopy(IEditorInput input); + + /** + * Shuts down this working copy manager. All working copies still remembered + * by this manager are destroyed. + */ + void shutdown(); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IWorkingCopyManagerExtension.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IWorkingCopyManagerExtension.java new file mode 100644 index 00000000000..21b03b562b7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IWorkingCopyManagerExtension.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 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 + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.ui.IEditorInput; + +/** + * Extension interface for <code>IWorkingCopyManager</code>. + * @since 2.1 + * + * @noextend This class is not intended to be subclassed by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IWorkingCopyManagerExtension { + + /** + * Sets the given working copy for the given editor input. If the given editor input + * is not connected to this working copy manager, this call has no effect. <p> + * This working copy manager does not assume the ownership of this working copy, i.e., + * the given working copy is not automatically be freed when this manager is shut down. + * + * @param input the editor input + * @param workingCopy the working copy + */ + void setWorkingCopy(IEditorInput input, IMakefile workingCopy); + + /** + * Removes the working copy set for the given editor input. If there is no + * working copy set for this input or this input is not connected to this + * working copy manager, this call has no effect. + * + * @param input the editor input + */ + void removeWorkingCopy(IEditorInput input); +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/If.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/If.java new file mode 100644 index 00000000000..5ca21d0ef84 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/If.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified to be If class + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; +import java.io.IOException; + +public class If extends Conditional implements IAutomakeConditional, ICommand { + private static final String EMPTY = ""; //$NON-NLS-1$ + private Rule rules[] = null; + + public If(Directive parent, Rule[] rules, String var) { + super(parent, var, EMPTY, EMPTY); + if (rules != null) { + this.rules = new Rule[rules.length]; + System.arraycopy(rules, 0, this.rules, 0, rules.length); + } + } + + public Rule[] getRules() { + if (rules != null) + return rules.clone(); + return null; + } + + public void setRules(Rule[] rules) { + if (rules != null) + this.rules = rules.clone(); + else + this.rules = rules; + } + + public boolean isIf() { + return true; + } + + public boolean isAutomake() { + return true; + } + + public void setAutomake(boolean value) { + // ignore value + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.CONDITIONAL_IF); + sb.append(' ').append(getVariable()); + return sb.toString(); + } + + public String getVariable() { + return getConditional(); + } + + // ICommand methods so Automake if can be a child of an IRule + public Process execute(String shell, String[] envp, File dir) + throws IOException { + return null; + } + + public boolean shouldBeSilent() { + return false; + } + + public boolean shouldIgnoreError() { + return false; + } + + public boolean shouldExecute() { + return false; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifdef.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifdef.java new file mode 100644 index 00000000000..52f47fd44cb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifdef.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class Ifdef extends Conditional { + private static final String EMPTY = ""; //$NON-NLS-1$ + + public Ifdef(Directive parent, String var) { + super(parent, var, EMPTY, EMPTY); + } + + public boolean isIfdef() { + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.CONDITIONAL_IFDEF); + sb.append(' ').append(getVariable()); + return sb.toString(); + } + + public String getVariable() { + return getConditional(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifeq.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifeq.java new file mode 100644 index 00000000000..5bb35dfd21f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifeq.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class Ifeq extends Conditional { + + public Ifeq(Directive parent, String cond) { + super(parent, cond); + } + + public boolean isIfeq() { + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.CONDITIONAL_IFEQ); + sb.append(' ').append(getConditional()); + return sb.toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifndef.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifndef.java new file mode 100644 index 00000000000..09e51105c10 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifndef.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class Ifndef extends Conditional { + + private static final String EMPTY = ""; //$NON-NLS-1$ + public Ifndef(Directive parent, String var) { + super(parent, var, EMPTY, EMPTY); + } + + public boolean isIfndef() { + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.CONDITIONAL_IFNDEF); + sb.append(' ').append(getVariable()); + return sb.toString(); + } + + public String getVariable() { + return getConditional(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifneq.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifneq.java new file mode 100644 index 00000000000..f222da2cca6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Ifneq.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class Ifneq extends Conditional { + + public Ifneq(Directive parent, String cond) { + super(parent, cond); + } + + public boolean isIfneq() { + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.CONDITIONAL_IFNEQ); + sb.append(' ').append(getConditional()); + return sb.toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IgnoreRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IgnoreRule.java new file mode 100644 index 00000000000..8739dc76d1b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IgnoreRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .IGNORE + * Prerequisites of this special target are targets themselves; this shall cause errors + * from commands associated with them to be ignored in the same manner as + * specified by the -i option. + */ +public class IgnoreRule extends SpecialRule implements IIgnoreRule { + + public IgnoreRule(Directive parent, String[] reqs) { + super(parent, new Target(MakeFileConstants.RULE_IGNORE), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Include.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Include.java new file mode 100644 index 00000000000..ab9fe9d28eb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Include.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; + +public class Include extends Parent implements IInclude { + + String[] filenames; + String[] dirs; + + public Include(Directive parent, String[] files, String[] directories) { + super(parent); + filenames = files.clone(); + dirs = directories.clone(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.DIRECTIVE_INCLUDE); + for (int i = 0; i < filenames.length; i++) { + sb.append(' ').append(filenames[i]); + } + return sb.toString(); + } + + public String[] getFilenames() { + return filenames.clone(); + } + + public IDirective[] getDirectives() { + clearDirectives(); + for (int i = 0; i < filenames.length; i++) { + // Try the current directory. + GNUAutomakefile gnu = new GNUAutomakefile(); + try { + gnu.parse(filenames[i]); + addDirective(gnu); + continue; + } catch (IOException e) { + } + if (!filenames[i].startsWith(GNUAutomakefile.FILE_SEPARATOR) && dirs != null) { + for (int j = 0; j < dirs.length; j++) { + try { + String filename = dirs[j] + GNUAutomakefile.FILE_SEPARATOR + filenames[i]; + gnu = new GNUAutomakefile(); + gnu.parse(filename); + addDirective(gnu); + break; + } catch (IOException e) { + } + } + } + } + return super.getDirectives(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/InferenceRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/InferenceRule.java new file mode 100644 index 00000000000..1d68cad880f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/InferenceRule.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class InferenceRule extends Rule { + + public InferenceRule(Directive parent, Target target) { + this(parent, target, new Command[0]); + } + + public InferenceRule(Directive parent, String tgt, Command[] cmds) { + this(parent, new Target(tgt), cmds); + } + + public InferenceRule(Directive parent, Target target, Command[] cmds) { + super(parent, target, cmds); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getTarget().toString()).append(":\n"); //$NON-NLS-1$ + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); + } + return buffer.toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IntermediateRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IntermediateRule.java new file mode 100644 index 00000000000..0d7d5acedc0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/IntermediateRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +/** + * .INTERMEDIATE + * The targets which `.INTERMEDIATE' depends on are treated as intermediate files. + * `.INTERMEDIATE' with no prerequisites has no effect. + */ +public class IntermediateRule extends SpecialRule implements IIntermediateRule { + + public IntermediateRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_INTERMEDIATE), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/LexicalSortingAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/LexicalSortingAction.java new file mode 100644 index 00000000000..da6a916582b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/LexicalSortingAction.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + * QNX Software System + * Red Hat Inc. - convert to use with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.ViewerSorter; + + + +public class LexicalSortingAction extends Action { + + private static final String ACTION_NAME= "LexicalSortingAction"; //$NON-NLS-1$ + private static final String DIALOG_STORE_KEY= ACTION_NAME + ".sort"; //$NON-NLS-1$ + + private LexicalCSorter fSorter; + private TreeViewer fTreeViewer; + + public LexicalSortingAction(TreeViewer treeViewer) { + super(CUIPlugin.getResourceString(ACTION_NAME + ".label")); //$NON-NLS-1$ + + setDescription(CUIPlugin.getResourceString(ACTION_NAME + ".description")); //$NON-NLS-1$ + setToolTipText(CUIPlugin.getResourceString(ACTION_NAME + ".tooltip")); //$NON-NLS-1$ + + MakeUIImages.setImageDescriptors(this, MakeUIImages.T_TOOL, MakeUIImages.IMG_TOOLS_ALPHA_SORTING); + + fTreeViewer= treeViewer; + fSorter= new LexicalCSorter(); + + boolean checked= CUIPlugin.getDefault().getDialogSettings().getBoolean(DIALOG_STORE_KEY); + valueChanged(checked, false); + } + + public void run() { + valueChanged(isChecked(), true); + } + + private void valueChanged(boolean on, boolean store) { + setChecked(on); + fTreeViewer.setSorter(on ? fSorter : null); + + String key= ACTION_NAME + ".tooltip" + (on ? ".on" : ".off"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + setToolTipText(CUIPlugin.getResourceString(key)); + + if (store) { + CUIPlugin.getDefault().getDialogSettings().put(DIALOG_STORE_KEY, on); + } + } + + private static class LexicalCSorter extends ViewerSorter { + @SuppressWarnings("unused") + public boolean isSorterProperty(Object element, Object property) { + return true; + } + + public int category(Object obj) { + if (obj instanceof ICElement) { + ICElement elem= (ICElement)obj; + switch (elem.getElementType()) { + case ICElement.C_MACRO: return 1; + case ICElement.C_INCLUDE: return 2; + + case ICElement.C_CLASS: return 3; + case ICElement.C_STRUCT: return 4; + case ICElement.C_UNION: return 5; + + case ICElement.C_FIELD: return 6; + case ICElement.C_FUNCTION: return 7; + } + + } + return 0; + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/LowResolutionTimeRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/LowResolutionTimeRule.java new file mode 100644 index 00000000000..d425208b113 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/LowResolutionTimeRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .LOW_RESOLUTION_TIME' + * If you specify prerequisites for `.LOW_RESOLUTION_TIME', `make' + * assumes that these files are created by commands that generate low + * resolution time stamps. + */ +public class LowResolutionTimeRule extends SpecialRule implements ILowResolutionTimeRule { + + public LowResolutionTimeRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_LOW_RESOLUTION_TIME), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroDefinition.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroDefinition.java new file mode 100644 index 00000000000..733a255229b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroDefinition.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + */ +public class MacroDefinition extends Directive implements IMacroDefinition { + String name; + StringBuffer value; + boolean fromCommand; + boolean fromDefault; + boolean fromMakefile; + boolean fromEnvironment; + boolean fromEnvironmentOverride; + + public MacroDefinition(Directive parent, String n, StringBuffer v) { + super(parent); + name = n; + value = v; + } + + public String getName() { + return name; + } + + public void setName(String n) { + name = (n == null) ? "" : n.trim() ; //$NON-NLS-1$ + } + + public StringBuffer getValue() { + return value; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getName()).append(" = ").append(getValue()).append('\n'); //$NON-NLS-1$ + return buffer.toString(); + } + + public boolean equals(Object v) { + if (v instanceof MacroDefinition) + return ((MacroDefinition)v).getName().equals(getName()); + return false; + } + + public int hashCode() { + return getName().hashCode(); + } + + public void setFromCommand(boolean from) { + fromCommand = from; + } + + public void setFromDefault(boolean from) { + fromDefault = from; + } + + public void setFromEnviroment(boolean from) { + fromEnvironment = from; + } + + public void setFromEnviromentOverride(boolean from) { + fromEnvironmentOverride = from; + } + + public void setFromMakefile(boolean from) { + fromMakefile = from; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromCommand() + */ + public boolean isFromCommand() { + return fromCommand; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromDefault() + */ + public boolean isFromDefault() { + return fromDefault; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromEnviroment() + */ + public boolean isFromEnviroment() { + return fromEnvironment; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromEnviroment() + */ + public boolean isFromEnvironmentOverride() { + return fromEnvironmentOverride; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromMakefile() + */ + public boolean isFromMakefile() { + return fromMakefile; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroDefinitionRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroDefinitionRule.java new file mode 100644 index 00000000000..09e4fe8133f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroDefinitionRule.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +class MacroDefinitionRule implements IPredicateRule { + private static final int INIT_STATE = 0; + private static final int VAR_STATE = 1; + private static final int END_VAR_STATE = 2; + private static final int EQUAL_STATE = 3; + private static final int FINISH_STATE = 4; + private static final int ERROR_STATE = 5; + + private IToken token; + private StringBuffer buffer = new StringBuffer(); + protected IToken defaultToken; + + public MacroDefinitionRule(IToken token, IToken defaultToken) { + this.token = token; + this.defaultToken = defaultToken; + } + + public IToken getSuccessToken() { + return token; + } + + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + buffer.setLength(0); + int state = INIT_STATE; + + if (resume) + scanToBeginOfLine(scanner); + + for (int c = scanner.read(); c != ICharacterScanner.EOF; c = scanner.read()) { + switch (state) { + case INIT_STATE : + if (c != '\n' && Character.isWhitespace((char) c)) { + break; + } + if (isValidCharacter(c)) { + state = VAR_STATE; + } else { + state = ERROR_STATE; + } + break; + case VAR_STATE : + if (isValidCharacter(c)) { + break; + } + case END_VAR_STATE : + if (c != '\n' && Character.isWhitespace((char) c)) { + state = END_VAR_STATE; + } else if (c == ':' || c == '+') { + state = EQUAL_STATE; + } else if (c == '=') { + state = FINISH_STATE; + } else { + if (state == END_VAR_STATE) { + scanner.unread(); // Return back to the space + } + state = ERROR_STATE; + } + break; + case EQUAL_STATE : + if (c == '=') { + state = FINISH_STATE; + } else { + state = ERROR_STATE; + } + break; + case FINISH_STATE : + break; + default : + break; + } + if (state >= FINISH_STATE) { + break; + } + buffer.append((char) c); + } + + scanner.unread(); + + if (state == FINISH_STATE) { + scanToEndOfLine(scanner); + return token; + } + + if (defaultToken.isUndefined()) + unreadBuffer(scanner); + + return Token.UNDEFINED; + + } + + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i = buffer.length() - 1; i >= 0; i--) { + scanner.unread(); + } + } + + private void scanToEndOfLine(ICharacterScanner scanner) { + int c; + char[][] delimiters = scanner.getLegalLineDelimiters(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + // Check for end of line since it can be used to terminate the pattern. + for (int i = 0; i < delimiters.length; i++) { + if (c == delimiters[i][0] && sequenceDetected(scanner, delimiters[i])) { + return; + } + } + } + } + + private void scanToBeginOfLine(ICharacterScanner scanner) { + while(scanner.getColumn() != 0) { + scanner.unread(); + } + } + + private boolean sequenceDetected(ICharacterScanner scanner, char[] sequence) { + for (int i = 1; i < sequence.length; i++) { + int c = scanner.read(); + if (c == ICharacterScanner.EOF) { + return true; + } else if (c != sequence[i]) { + // Non-matching character detected, rewind the scanner back to the start. + for (; i > 0; i--) { + scanner.unread(); + } + return false; + } + } + + return true; + } + protected boolean isValidCharacter(int c) { + char c0 = (char) c; + return Character.isLetterOrDigit(c0) || (c0 == '_'); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroReferenceRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroReferenceRule.java new file mode 100644 index 00000000000..f8bc830cc97 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MacroReferenceRule.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.PatternRule; + +public class MacroReferenceRule extends PatternRule { + + int nOfBrackets; + int fBracket; + +// public MacroReferenceRule(IToken token) { +// super("$(", ")", token, (char) 0, true); //$NON-NLS-1$ //$NON-NLS-2$ +// } + + public MacroReferenceRule(IToken token, String startSeq, String endSeq) { + super(startSeq, endSeq, token, (char)0, true); + if (endSeq.length() > 0 && endSeq.charAt(0) == '}') { + fBracket = '{'; + } else { + fBracket = '('; + } + } + + protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) { + nOfBrackets = 1; + return super.doEvaluate(scanner, resume); + } + + protected boolean endSequenceDetected(ICharacterScanner scanner) { + int c; + char[][] delimiters = scanner.getLegalLineDelimiters(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (fBracket == c) { + ++nOfBrackets; + } + if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) { + if (0 == --nOfBrackets) { + return true; + } + } + } else if (fBreaksOnEOL) { + // Check for end of line since it can be used to terminate the pattern. + for (int i = 0; i < delimiters.length; i++) { + if (c == delimiters[i][0] && sequenceDetected(scanner, delimiters[i], false)) { + return true; + } + } + } + } + scanner.unread(); + return true; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakeFileConstants.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakeFileConstants.java new file mode 100644 index 00000000000..1e0c3a770b0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakeFileConstants.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class MakeFileConstants { + + public static final String RULE_DEFAULT = ".DEFAULT"; //$NON-NLS-1$ + public static final String RULE_IGNORE =".IGNORE"; //$NON-NLS-1$ + public static final String RULE_POSIX = ".POSIX"; //$NON-NLS-1$ + public static final String RULE_PRECIOUS = ".PRECIOUS"; //$NON-NLS-1$ + public static final String RULE_SCCS_GET = ".SCCS_GET"; //$NON-NLS-1$ + public static final String RULE_SILENT = ".SILENT"; //$NON-NLS-1$ + public static final String RULE_SUFFIXES = ".SUFFIXES"; //$NON-NLS-1$ + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakeFileMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakeFileMessages.properties new file mode 100644 index 00000000000..b61ee7c8e25 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakeFileMessages.properties @@ -0,0 +1,27 @@ +############################################################################### +# Copyright (c) 2003, 2006, 2007, 2010 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. - convert to use with Automake editor +############################################################################### +MakefileValidator.errorBuild=Error Build +MakefileValidator.errorResource=Error resource +MakefileValidator.warningInfo=Warning info +MakefileValidator.warning=Warning +MakefileValidator.unknown=unknown +MakefileValidator.checkingFile=Checking file : +MakefileValidator.fileChecked=File checked +MakefileValidator.error.elseMissingIfCondition=else missing if condition +MakefileValidator.error.endifMissingIfElseCondition=Endif missing if/else condition +MakefileValidator.error.endefMissingOverrideDefine=endef missing [override] define +MakefileValidator.error.unknownDirective=unknow directive +MakefileValidator.error.noMatchingEndifForCondition=No matching endif for condition +MakefileValidator.error.noMatchingEndefForOverrideDefine=No matching endef for [override] define + +MakefileErrorMessage=Invalid directive +EditorUtility.concatModifierStrings= {0} + {1}
\ No newline at end of file diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileAnnotationHover.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileAnnotationHover.java new file mode 100644 index 00000000000..164a2f62103 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileAnnotationHover.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditorMessages; +import org.eclipse.cdt.internal.autotools.ui.HTMLPrinter; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationHoverExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ILineRange; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.LineRange; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; + + +/** + * MakefileAnnotationHover + * + */ +public class MakefileAnnotationHover implements IAnnotationHover, IAnnotationHoverExtension { + + @SuppressWarnings("unused") + private IEditorPart fEditor; + + /** + * + */ + public MakefileAnnotationHover(IEditorPart editor) { + fEditor = editor; + } + + /** + * Returns the distance to the ruler line. + */ + protected int compareRulerLine(Position position, IDocument document, int line) { + + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + int markerLine= document.getLineOfOffset(position.getOffset()); + if (line == markerLine) + return 1; + if (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())) + return 2; + } catch (BadLocationException x) { + } + } + + return 0; + } + + /** + * Selects a set of markers from the two lists. By default, it just returns + * the set of exact matches. + */ + protected List<Annotation> select(List<Annotation> exactMatch, List<Annotation> including) { + return exactMatch; + } + + /** + * Returns one marker which includes the ruler's line of activity. + */ + protected List<Annotation> getAnnotationsForLine(ISourceViewer viewer, int line) { + + IDocument document= viewer.getDocument(); + IAnnotationModel model= viewer.getAnnotationModel(); + + if (model == null) + return null; + + List<Annotation> exact= new ArrayList<Annotation>(); + List<Annotation> including= new ArrayList<Annotation>(); + + @SuppressWarnings("unchecked") + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Object o= e.next(); + if (o instanceof Annotation) { + Annotation a= (Annotation) o; + switch (compareRulerLine(model.getPosition(a), document, line)) { + case 1: + exact.add(a); + break; + case 2: + including.add(a); + break; + } + } + } + + return select(exact, including); + } + + /* + * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + List<Annotation> annotations = getAnnotationsForLine(sourceViewer, lineNumber); + if (annotations != null && annotations.size() > 0) { + + if (annotations.size() == 1) { + + // optimization + Annotation annotation = (Annotation) annotations.get(0); + String message= annotation.getText(); + if (message != null && message.trim().length() > 0) + return formatSingleMessage(message); + + } else { + + List<String> messages= new ArrayList<String>(); + + Iterator<Annotation> e= annotations.iterator(); + while (e.hasNext()) { + Annotation annotation = (Annotation) e.next(); + String message= annotation.getText(); + if (message != null && message.trim().length() > 0) + messages.add(message.trim()); + } + + if (messages.size() == 1) + return formatSingleMessage((String) messages.get(0)); + + if (messages.size() > 1) + return formatMultipleMessages(messages); + } + } + + return null; + } + + /* + * Formats a message as HTML text. + */ + private String formatSingleMessage(String message) { + StringBuffer buffer= new StringBuffer(); + HTMLPrinter.addPageProlog(buffer); + HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message)); + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + /* + * Formats several message as HTML text. + */ + private String formatMultipleMessages(List<String> messages) { + StringBuffer buffer= new StringBuffer(); + HTMLPrinter.addPageProlog(buffer); + HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(AutoconfEditorMessages.getString("AutoconfAnnotationHover.multipleMarkers"))); //$NON-NLS-1$ + + HTMLPrinter.startBulletList(buffer); + Iterator<String> e= messages.iterator(); + while (e.hasNext()) + HTMLPrinter.addBullet(buffer, HTMLPrinter.convertToHTMLContent((String) e.next())); + HTMLPrinter.endBulletList(buffer); + + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + // IAnnotationHoverExtension members + // We need to use the extension to get a Hover Control Creator which + // handles html. + + + public IInformationControlCreator getHoverControlCreator() { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, false); + } + }; + } + + public boolean canHandleMouseCursor() { + return false; + } + + public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { + return new LineRange(lineNumber, 1); + } + + public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines) { + return getHoverInfo(sourceViewer, lineRange.getStartLine()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileCodeScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileCodeScanner.java new file mode 100644 index 00000000000..1abb345d2c4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileCodeScanner.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.jface.text.rules.EndOfLineRule; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.WhitespaceRule; +import org.eclipse.jface.text.rules.WordRule; + + +public class MakefileCodeScanner extends AbstractMakefileCodeScanner { + + private final static String[] keywords = { "define", "endef", "ifdef", "ifndef", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "ifeq", "ifneq", "else", "endif", "include", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + "-include", "sinclude", "override", "endef", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "export", "unexport", "vpath" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + }; + + private final static String[] functions = { "subst", "patsubst", "strip", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "findstring", "filter", "sort", "dir", "notdir", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + "suffix", "basename", "addsuffix", "addprefix", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "join", "word", "words", "wordlist", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "firstword", "wildcard", "error", "warning", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "shell", "origin", "foreach", "call" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + }; + + static final String[] fTokenProperties = new String[] { + ColorManager.MAKE_COMMENT_COLOR, + ColorManager.MAKE_KEYWORD_COLOR, + ColorManager.MAKE_FUNCTION_COLOR, + ColorManager.MAKE_MACRO_REF_COLOR, + ColorManager.MAKE_MACRO_DEF_COLOR, + ColorManager.MAKE_DEFAULT_COLOR + }; + + /** + * Constructor for MakefileCodeScanner + */ + public MakefileCodeScanner() { + super(); + initialize(); + } + + protected List<IRule> createRules() { + IToken keyword = getToken(ColorManager.MAKE_KEYWORD_COLOR); + IToken function = getToken(ColorManager.MAKE_FUNCTION_COLOR); + IToken comment = getToken(ColorManager.MAKE_COMMENT_COLOR); + IToken macroRef = getToken(ColorManager.MAKE_MACRO_REF_COLOR); + IToken macroDef = getToken(ColorManager.MAKE_MACRO_DEF_COLOR); + IToken other = getToken(ColorManager.MAKE_DEFAULT_COLOR); + + List<IRule> rules = new ArrayList<IRule>(); + + // Add rule for single line comments. + rules.add(new EndOfLineRule("#", comment, '\\', true)); //$NON-NLS-1$ + + // Add generic whitespace rule. + rules.add(new WhitespaceRule(new IWhitespaceDetector() { + public boolean isWhitespace(char character) { + return Character.isWhitespace(character); + } + })); + + // Put before the the word rules + MultiLineRule defineRule = new MultiLineRule("define", "endef", macroDef); //$NON-NLS-1$ //$NON-NLS-2$ + defineRule.setColumnConstraint(0); + rules.add(defineRule); + rules.add(new MacroDefinitionRule(macroDef, other)); + + // Add word rule for keywords, types, and constants. + // We restring the detection of the keywords to be the first column to be valid. + WordRule keyWordRule = new WordRule(new MakefileWordDetector(), other); + for (int i = 0; i < keywords.length; i++) { + keyWordRule.addWord(keywords[i], keyword); + } + keyWordRule.setColumnConstraint(0); + rules.add(keyWordRule); + + WordRule functionRule = new WordRule(new MakefileWordDetector(), other); + for (int i = 0; i < functions.length; i++) + functionRule.addWord(functions[i], function); + rules.add(functionRule); + + rules.add(new MacroReferenceRule(macroRef, "$(", ")")); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new MacroReferenceRule(macroRef, "${", "}")); //$NON-NLS-1$ //$NON-NLS-2$ + + setDefaultReturnToken(other); + + return rules; + } + + /* + * @see AbstractMakefileCodeScanner#getTokenProperties() + */ + protected String[] getTokenProperties() { + return fTokenProperties; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileCompletionProcessor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileCompletionProcessor.java new file mode 100644 index 00000000000..f62ae6a0bf5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileCompletionProcessor.java @@ -0,0 +1,235 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ContextInformation; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationPresenter; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IEditorPart; + + +/** + * MakefileCompletionProcessor + */ +public class MakefileCompletionProcessor implements IContentAssistProcessor { + + /** + * Simple content assist tip closer. The tip is valid in a range + * of 5 characters around its popup location. + */ + protected static class Validator implements IContextInformationValidator, IContextInformationPresenter { + + protected int fInstallOffset; + + /* + * @see IContextInformationValidator#isContextInformationValid(int) + */ + public boolean isContextInformationValid(int offset) { + return Math.abs(fInstallOffset - offset) < 5; + } + + /* + * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int) + */ + public void install(IContextInformation info, ITextViewer viewer, int offset) { + fInstallOffset = offset; + } + + /* + * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int, TextPresentation) + */ + public boolean updatePresentation(int documentPosition, TextPresentation presentation) { + return false; + } + } + + public static class DirectiveComparator implements Comparator<Object>{ + + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) { + String name1; + String name2; + + if (o1 instanceof IMacroDefinition) { + name1 = ((IMacroDefinition)o1).getName(); + } else if (o1 instanceof IRule) { + name1 = ((IRule)o1).getTarget().toString(); + } else { + name1 =""; //$NON-NLS-1$ + } + + if (o2 instanceof IMacroDefinition) { + name2 = ((IMacroDefinition)o1).getName(); + } else if (o2 instanceof IRule) { + name2 = ((IRule)o1).getTarget().toString(); + } else { + name2 =""; //$NON-NLS-1$ + } + + //return String.CASE_INSENSITIVE_ORDER.compare(name1, name2); + return name1.compareToIgnoreCase(name2); + } + + } + protected IContextInformationValidator fValidator = new Validator(); + protected Image imageMacro = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_MACRO); + protected Image imageTarget = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_TARGET_RULE); + + protected CompletionProposalComparator comparator = new CompletionProposalComparator(); + protected IEditorPart fEditor; + protected IWorkingCopyManager fManager; + + public MakefileCompletionProcessor(IEditorPart editor) { + fEditor = editor; + fManager = AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { + WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset); + boolean macro = WordPartDetector.inMacro(viewer, documentOffset); + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + IDirective[] statements = null; + if (macro) { + IDirective[] m1 = makefile.getMacroDefinitions(); + IDirective[] m2 = makefile.getBuiltinMacroDefinitions(); + statements = new IDirective[m1.length + m2.length]; + System.arraycopy(m1, 0, statements, 0, m1.length); + System.arraycopy(m2, 0, statements, m1.length, m2.length); + } else { + statements = makefile.getTargetRules(); + } + + ArrayList<ICompletionProposal> proposalList = new ArrayList<ICompletionProposal>(statements.length); + + // iterate over all the different categories + for (int i = 0; i < statements.length; i++) { + String name = null; + Image image = null; + String infoString = "";//getContentInfoString(name); //$NON-NLS-1$ + if (statements[i] instanceof IMacroDefinition) { + name = ((IMacroDefinition) statements[i]).getName(); + image = imageMacro; + infoString = ((IMacroDefinition)statements[i]).getValue().toString(); + } else if (statements[i] instanceof IRule) { + name = ((IRule) statements[i]).getTarget().toString(); + image = imageTarget; + infoString = name; + } + if (name != null && name.startsWith(wordPart.toString())) { + IContextInformation info = new ContextInformation(name, infoString); + String displayString = (name.equals(infoString) ? name : name + " - " + infoString); //$NON-NLS-1$ + ICompletionProposal result = + new CompletionProposal( + name, + wordPart.getOffset(), + wordPart.toString().length(), + name.length(), + image, + displayString, + info, + infoString); + proposalList.add(result); + } + } + ICompletionProposal[] proposals = (ICompletionProposal[]) proposalList.toArray(new ICompletionProposal[0]); + Arrays.sort(proposals, comparator); + return proposals; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { + WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset); + boolean macro = WordPartDetector.inMacro(viewer, documentOffset); + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + ArrayList<String> contextList = new ArrayList<String>(); + if (macro) { + IDirective[] statements = makefile.getMacroDefinitions(); + for (int i = 0; i < statements.length; i++) { + if (statements[i] instanceof IMacroDefinition) { + String name = ((IMacroDefinition) statements[i]).getName(); + if (name != null && name.equals(wordPart.toString())) { + String value = ((IMacroDefinition) statements[i]).getValue().toString(); + if (value != null && value.length() > 0) { + contextList.add(value); + } + } + } + } + statements = makefile.getBuiltinMacroDefinitions(); + for (int i = 0; i < statements.length; i++) { + String name = ((IMacroDefinition) statements[i]).getName(); + if (name != null && name.equals(wordPart.toString())) { + String value = ((IMacroDefinition) statements[i]).getValue().toString(); + if (value != null && value.length() > 0) { + contextList.add(value); + } + } + } + } + + IContextInformation[] result = new IContextInformation[contextList.size()]; + for (int i = 0; i < result.length; i++) { + String context = (String)contextList.get(i); + result[i] = new ContextInformation(imageMacro, wordPart.toString(), context); + } + return result; + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return fValidator; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileContentOutlinePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileContentOutlinePage.java new file mode 100644 index 00000000000..419e2a8e1db --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileContentOutlinePage.java @@ -0,0 +1,317 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + + +/** + * MakefileContentOutlinePage + */ +public class MakefileContentOutlinePage extends ContentOutlinePage implements IContentOutlinePage { + + private class MakefileContentProvider implements ITreeContentProvider { + + protected boolean showMacroDefinition = true; + protected boolean showTargetRule = true; + protected boolean showInferenceRule = true; + protected boolean showIncludeChildren = false; + + protected IMakefile makefile; + protected IMakefile nullMakefile = new NullMakefile(); + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) { + if (element == fInput) { + return getElements(makefile); + } else if (element instanceof IDirective) { + return getElements(element); + } + return new Object[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element instanceof IMakefile) { + return fInput; + } else if (element instanceof IDirective) { + return ((IDirective)element).getParent(); + } + return fInput; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element == fInput) { + return true; + } else if (element instanceof IParent) { + // Do not drill down in includes. + if (element instanceof IInclude && !showIncludeChildren) { + return false; + } + return true; + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + IDirective[] directives; + if (inputElement == fInput) { + directives = makefile.getDirectives(); + } else if (inputElement instanceof IRule) { + directives = ((IRule)inputElement).getCommands(); + } else if (inputElement instanceof IParent) { + if (inputElement instanceof IInclude && !showIncludeChildren) { + directives = new IDirective[0]; + } else { + directives = ((IParent)inputElement).getDirectives(); + } + } else { + directives = new IDirective[0]; + } + List<Object> list = new ArrayList<Object>(directives.length); + for (int i = 0; i < directives.length; i++) { + if (showMacroDefinition && directives[i] instanceof IMacroDefinition) { + list.add(directives[i]); + } else if (showInferenceRule && directives[i] instanceof IInferenceRule) { + list.add(directives[i]); + } else if (showTargetRule && directives[i] instanceof ITargetRule) { + list.add(directives[i]); + } else { + boolean irrelevant = (directives[i] instanceof IComment || + directives[i] instanceof IEmptyLine || + directives[i] instanceof ITerminal); + if (!irrelevant) { + list.add(directives[i]); + } + } + } + return list.toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (oldInput != null) { + makefile = nullMakefile; + } + + if (newInput != null) { + IWorkingCopyManager manager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + makefile = manager.getWorkingCopy((IEditorInput)newInput); + if (makefile == null) { + makefile = nullMakefile; + } + } + } + + } + + private static class MakefileLabelProvider extends LabelProvider implements ILabelProvider { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + public Image getImage(Object element) { + if (element instanceof ITargetRule) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_TARGET_RULE); + } else if (element instanceof IInferenceRule) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_INFERENCE_RULE); + } else if (element instanceof IMacroDefinition) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_MACRO); + } else if (element instanceof ICommand) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_COMMAND); + } else if (element instanceof IInclude) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_INCLUDE); + } else if (element instanceof IBadDirective) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_ERROR); + } else if (element instanceof IParent) { + return MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_RELATION); + } + return super.getImage(element); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + String name; + if (element instanceof IRule) { + name = ((IRule) element).getTarget().toString().trim(); + } else if (element instanceof IMacroDefinition) { + name = ((IMacroDefinition) element).getName().trim(); + } else { + name = super.getText(element); + } + if (name != null) { + name = name.trim(); + if (name.length() > 25) { + name = name.substring(0, 25) + " ..."; //$NON-NLS-1$ + } + } + return name; + } + + } + + protected MakefileEditor fEditor; + protected Object fInput; + protected OpenIncludeAction fOpenIncludeAction; + + public MakefileContentOutlinePage(MakefileEditor editor) { + super(); + fEditor = editor; + fOpenIncludeAction = new OpenIncludeAction(this); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + super.createControl(parent); + TreeViewer viewer = getTreeViewer(); + viewer.setContentProvider(new MakefileContentProvider()); + viewer.setLabelProvider(new MakefileLabelProvider()); + if (fInput != null) { + viewer.setInput(fInput); + } + + MenuManager manager= new MenuManager("#MakefileOutlinerContext"); //$NON-NLS-1$ + manager.setRemoveAllWhenShown(true); + manager.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager m) { + contextMenuAboutToShow(m); + } + }); + Control tree = viewer.getControl(); + Menu menu = manager.createContextMenu(tree); + tree.setMenu(menu); + + viewer.addDoubleClickListener(new IDoubleClickListener() { + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) + */ + public void doubleClick(DoubleClickEvent event) { + if (fOpenIncludeAction != null) { + fOpenIncludeAction.run(); + } + } + }); + + IPageSite site= getSite(); + //FIXME: should pluginid below be MakeUIPlugin id? + site.registerContextMenu(AutotoolsUIPlugin.getPluginId() + ".outline", manager, viewer); //$NON-NLS-1$ + site.setSelectionProvider(viewer); + + } + + /** + * called to create the context menu of the outline + */ + protected void contextMenuAboutToShow(IMenuManager menu) { + if (OpenIncludeAction.canActionBeAdded(getSelection())) { + menu.add(fOpenIncludeAction); + } + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS+"-end"));//$NON-NLS-1$ + } + + /** + * Sets the input of the outline page + */ + public void setInput(Object input) { + fInput = input; + update(); + } + + public Object getInput() { + return fInput; + } + + /** + * Updates the outline page. + */ + public void update() { + final TreeViewer viewer = getTreeViewer(); + + if (viewer != null) { + final Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!control.isDisposed()) { + control.setRedraw(false); + viewer.setInput(fInput); + viewer.expandAll(); + control.setRedraw(true); + } + } + }); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#setActionBars(org.eclipse.ui.IActionBars) + */ + public void setActionBars(IActionBars actionBars) { + super.setActionBars(actionBars); + IToolBarManager toolBarManager= actionBars.getToolBarManager(); + + LexicalSortingAction action= new LexicalSortingAction(getTreeViewer()); + toolBarManager.add(action); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileDocumentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileDocumentProvider.java new file mode 100644 index 00000000000..b831341bfae --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileDocumentProvider.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * 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 + * Anton Leherbauer (Wind River Systems) - Fixed bug 141295 + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.Iterator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.editors.text.ForwardingDocumentProvider; +import org.eclipse.ui.editors.text.TextFileDocumentProvider; +import org.eclipse.ui.texteditor.IDocumentProvider; + +public class MakefileDocumentProvider extends TextFileDocumentProvider implements IMakefileDocumentProvider { + + IMakefile fMakefile; + + protected class MakefileAnnotationModel extends AnnotationModel /*implements IProblemRequestor */{ + /** + * @param resource + */ + public MakefileAnnotationModel(IResource resource) { + super(); + } + + /** + * @param makefile + */ + public void setMakefile(IMakefile makefile) { + fMakefile = makefile; + } + } + + /** + * Remembers a IMakefile for each element. + */ + protected class MakefileFileInfo extends FileInfo { + public IMakefile fCopy; + } + + public MakefileDocumentProvider() { + IDocumentProvider provider= new TextFileDocumentProvider(new MakefileStorageDocumentProvider()); + provider= new ForwardingDocumentProvider(MakefileDocumentSetupParticipant.MAKEFILE_PARTITIONING, new MakefileDocumentSetupParticipant(), provider); + setParentDocumentProvider(provider); + } + + /** + */ + private IMakefile createMakefile(IFile file) throws CoreException { + if (file.exists()) { + return GNUAutomakefile.createMakefile(file); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createAnnotationModel(org.eclipse.core.resources.IFile) + */ + protected IAnnotationModel createAnnotationModel(IFile file) { + return new MakefileAnnotationModel(file); + } + + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createFileInfo(java.lang.Object) + */ + protected FileInfo createFileInfo(Object element) throws CoreException { + if (!(element instanceof IFileEditorInput)) + return null; + + IFileEditorInput input= (IFileEditorInput) element; + IMakefile original= createMakefile(input.getFile()); + if (original == null) + return null; + + FileInfo info= super.createFileInfo(element); + if (!(info instanceof MakefileFileInfo)) { + return null; + } + + MakefileFileInfo makefileInfo= (MakefileFileInfo) info; + setUpSynchronization(makefileInfo); + + makefileInfo.fCopy = original; + + if (makefileInfo.fModel instanceof MakefileAnnotationModel) { + MakefileAnnotationModel model= (MakefileAnnotationModel) makefileInfo.fModel; + model.setMakefile(makefileInfo.fCopy); + } + return makefileInfo; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#disposeFileInfo(java.lang.Object, org.eclipse.ui.editors.text.TextFileDocumentProvider.FileInfo) + */ + protected void disposeFileInfo(Object element, FileInfo info) { + if (info instanceof MakefileFileInfo) { + MakefileFileInfo makefileInfo= (MakefileFileInfo) info; + if (makefileInfo.fCopy != null) { + makefileInfo.fCopy = null; + } + } + super.disposeFileInfo(element, info); + } + + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createEmptyFileInfo() + */ + protected FileInfo createEmptyFileInfo() { + return new MakefileFileInfo(); + } + + /* + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.IMakefileDocumentProvider#getWorkingCopy(java.lang.Object) + */ + public IMakefile getWorkingCopy(Object element) { + FileInfo fileInfo= getFileInfo(element); + if (fileInfo instanceof MakefileFileInfo) { + MakefileFileInfo info= (MakefileFileInfo) fileInfo; + return info.fCopy; + } + return null; + } + + /* + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.MakefileDocumentProvider#shutdown() + */ + public void shutdown() { + @SuppressWarnings("unchecked") + Iterator e= getConnectedElementsIterator(); + while (e.hasNext()) + disconnect(e.next()); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileDocumentSetupParticipant.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileDocumentSetupParticipant.java new file mode 100644 index 00000000000..75553c2d944 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileDocumentSetupParticipant.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.filebuffers.IDocumentSetupParticipant; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.rules.FastPartitioner; + +/** + * MakefileDocumentSetupParticipant + * The document setup participant for Ant. + */ +public class MakefileDocumentSetupParticipant implements IDocumentSetupParticipant { + + /** + * The name of the Makefile partitioning. + */ + public final static String MAKEFILE_PARTITIONING= "___makefile_partitioning"; //$NON-NLS-1$ + + public MakefileDocumentSetupParticipant() { + } + + /* + * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument) + */ + public void setup(IDocument document) { + if (document instanceof IDocumentExtension3) { + IDocumentExtension3 extension3= (IDocumentExtension3) document; + IDocumentPartitioner partitioner = createDocumentPartitioner(); + extension3.setDocumentPartitioner(MAKEFILE_PARTITIONING, partitioner); + partitioner.connect(document); + } + } + + private IDocumentPartitioner createDocumentPartitioner() { + return new FastPartitioner( + new MakefilePartitionScanner(), MakefilePartitionScanner.MAKE_PARTITIONS); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditor.java new file mode 100644 index 00000000000..d609a614ccf --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditor.java @@ -0,0 +1,432 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 + * Anton Leherbauer, Wind River Systems, Inc. + * Red Hat Inc. - convert to use with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ResourceBundle; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.internal.autotools.ui.MakeUIMessages; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.FindReplaceDocumentAdapter; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionSupport; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IPartService; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.ChainedPreferenceStore; +import org.eclipse.ui.texteditor.DefaultRangeIndicator; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.TextOperationAction; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + + +public class MakefileEditor extends TextEditor implements ISelectionChangedListener, IReconcilingParticipant { + + /** + * The page that shows the outline. + */ + protected MakefileContentOutlinePage page; + ProjectionSupport projectionSupport; + ProjectionMakefileUpdater fProjectionMakefileUpdater; + private FindReplaceDocumentAdapter fFindReplaceDocumentAdapter; + + /** + * Reconciling listeners. + * @since 3.0 + */ + private ListenerList fReconcilingListeners= new ListenerList(ListenerList.IDENTITY); + + + MakefileSourceConfiguration getMakefileSourceConfiguration() { + SourceViewerConfiguration configuration = getSourceViewerConfiguration(); + if (configuration instanceof MakefileSourceConfiguration) { + return (MakefileSourceConfiguration)configuration; + } + return null; + } + + public MakefileContentOutlinePage getOutlinePage() { + if (page == null) { + page = new MakefileContentOutlinePage(this); + page.addSelectionChangedListener(this); + page.setInput(getEditorInput()); + } + return page; + } + + public MakefileEditor() { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor() + */ + protected void initializeEditor() { + setRangeIndicator(new DefaultRangeIndicator()); + setEditorContextMenuId("#MakefileEditorContext"); //$NON-NLS-1$ + setRulerContextMenuId("#MakefileRulerContext"); //$NON-NLS-1$ + setDocumentProvider(AutomakeEditorFactory.getDefault().getAutomakefileDocumentProvider()); + IPreferenceStore[] stores = new IPreferenceStore[2]; + stores[0] = AutotoolsPlugin.getDefault().getPreferenceStore(); + stores[1] = EditorsUI.getPreferenceStore(); + ChainedPreferenceStore chainedStore = new ChainedPreferenceStore(stores); + setPreferenceStore(chainedStore); + setSourceViewerConfiguration(new MakefileSourceConfiguration(chainedStore, this)); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + public void dispose() { + if (fProjectionMakefileUpdater != null) { + fProjectionMakefileUpdater.uninstall(); + fProjectionMakefileUpdater= null; + } + super.dispose(); + } + + boolean isFoldingEnabled() { + return AutotoolsPlugin.getDefault().getPreferenceStore().getBoolean(MakefileEditorPreferenceConstants.EDITOR_FOLDING_ENABLED); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isTabsToSpacesConversionEnabled() + */ + protected boolean isTabsToSpacesConversionEnabled() { + // always false for Makefiles + // see http://bugs.eclipse.org/186106 + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + public void createPartControl(Composite parent) { + super.createPartControl(parent); + ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); + projectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); + projectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$ + projectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$ + projectionSupport.install(); + + if (isFoldingEnabled()) { + projectionViewer.doOperation(ProjectionViewer.TOGGLE); + } + +// ProjectionAnnotationModel model= (ProjectionAnnotationModel) getAdapter(ProjectionAnnotationModel.class); + + fProjectionMakefileUpdater= new ProjectionMakefileUpdater(); + if (fProjectionMakefileUpdater != null) { + fProjectionMakefileUpdater.install(this, projectionViewer); + fProjectionMakefileUpdater.initialize(); + } + } + + protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { + ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles); + + // ensure decoration support has been created and configured. + getSourceViewerDecorationSupport(viewer); + + return viewer; + } + + /* (non-Javadoc) + * Method declared on IAdaptable + */ + public Object getAdapter(@SuppressWarnings("unchecked") Class key) { + if (ProjectionAnnotationModel.class.equals(key)) { + if (projectionSupport != null) { + Object result = projectionSupport.getAdapter(getSourceViewer(), key); + if (result != null) { + return result; + } + } + } else if (key.equals(IContentOutlinePage.class)) { + return getOutlinePage(); + } + return super.getAdapter(key); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) + */ + public void doSave(IProgressMonitor monitor) { + super.doSave(monitor); + if (page != null) { + page.update(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions() + */ + protected void createActions() { + super.createActions(); + + ResourceBundle bundle = MakeUIMessages.getResourceBundle(); + + IAction a = new TextOperationAction(bundle, "ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); //$NON-NLS-1$ + a.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); + setAction("ContentAssistProposal", a); //$NON-NLS-1$ + + a = new TextOperationAction(bundle, "ContentAssistTip.", this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); //$NON-NLS-1$ + a.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION); + setAction("ContentAssistTip", a); //$NON-NLS-1$ + + a = new TextOperationAction(bundle, "Comment.", this, ITextOperationTarget.PREFIX); //$NON-NLS-1$ + a.setActionDefinitionId(IMakefileEditorActionDefinitionIds.COMMENT); + setAction("Comment", a); //$NON-NLS-1$ + markAsStateDependentAction("Comment", true); //$NON-NLS-1$ + + a = new TextOperationAction(bundle, "Uncomment.", this, ITextOperationTarget.STRIP_PREFIX); //$NON-NLS-1$ + a.setActionDefinitionId(IMakefileEditorActionDefinitionIds.UNCOMMENT); + setAction("Uncomment", a); //$NON-NLS-1$ + markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$ + + a = new OpenDeclarationAction(this); + a.setActionDefinitionId(IMakefileEditorActionDefinitionIds.OPEN_DECLARATION); + setAction("OpenDeclarationAction", a); //$NON-NLS-1$ + markAsStateDependentAction("OpenDeclarationAction", true); //$NON-NLS-1$ + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection.isEmpty()) { + resetHighlightRange(); + } else if (selection instanceof IStructuredSelection){ + if (!isActivePart() && AutotoolsPlugin.getActivePage() != null) { + AutotoolsPlugin.getActivePage().bringToTop(this); + } + Object element = ((IStructuredSelection) selection).getFirstElement(); + if (element instanceof IDirective) { + IDirective statement = (IDirective)element; + setSelection(statement, !isActivePart()); + } + } + } + + /** + * Returns whether the editor is active. + */ + private boolean isActivePart() { + IWorkbenchWindow window= getSite().getWorkbenchWindow(); + IPartService service= window.getPartService(); + IWorkbenchPart part= service.getActivePart(); + return part != null && part.equals(this); + } + + /** + * Returns the find/replace document adapter. + * + * @return the find/replace document adapter. + */ + private FindReplaceDocumentAdapter getFindRepalceDocumentAdapter() { + if (fFindReplaceDocumentAdapter == null) { + IDocument doc = getDocumentProvider().getDocument(getEditorInput()); + fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(doc); + } + return fFindReplaceDocumentAdapter; + } + + public void setSelection(IDirective directive, boolean moveCursor) { + int startLine = directive.getStartLine() - 1; + int endLine = directive.getEndLine() - 1; + try { + IDocument doc = getDocumentProvider().getDocument(getEditorInput()); + int start = doc.getLineOffset(startLine); + int len = doc.getLineLength(endLine) - 1; + int length = (doc.getLineOffset(endLine) + len) - start; + setHighlightRange(start, length, true); + if (moveCursor) { + // Let see if we can move the cursor at the position also + String var = directive.toString().trim(); + IWordDetector detector = new MakefileWordDetector(); + for (len = 0; len < var.length(); len++) { + char c = var.charAt(len); + //if (! (Character.isLetterOrDigit(c) || c == '.' || c == '_')) { + if (!(detector.isWordPart(c) || detector.isWordStart(c) || c == '-' || c == '_')) { + break; + } + } + if (len > 0) { + var = var.substring(0, len); + } + IRegion region = getFindRepalceDocumentAdapter().find(start, var, true, true, true, false); + + if (region != null) { + len = region.getOffset(); + length = region.getLength(); + getSourceViewer().revealRange(len, length); + // Selected region begins one index after offset + getSourceViewer().setSelectedRange(len, length); + } + + } + } catch (IllegalArgumentException x) { + resetHighlightRange(); + } catch (BadLocationException e) { + resetHighlightRange(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager) + */ + protected void editorContextMenuAboutToShow(IMenuManager menu) { + super.editorContextMenuAboutToShow(menu); + addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Comment"); //$NON-NLS-1$ + addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Uncomment"); //$NON-NLS-1$ + //addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "OpenDeclarationAction"); //$NON-NLS-1$ + } + + /** + * Adds the given listener. + * Has no effect if an identical listener was not already registered. + * + * @param listener The reconcile listener to be added + * @since 3.0 + */ + final void addReconcilingParticipant(IReconcilingParticipant listener) { + synchronized (fReconcilingListeners) { + fReconcilingListeners.add(listener); + } + } + + /** + * Removes the given listener. + * Has no effect if an identical listener was not already registered. + * + * @param listener the reconcile listener to be removed + * @since 3.0 + */ + final void removeReconcilingParticipant(IReconcilingParticipant listener) { + synchronized (fReconcilingListeners) { + fReconcilingListeners.remove(listener); + } + } + + /* + */ + public void reconciled() { + // Notify listeners + Object[] listeners = fReconcilingListeners.getListeners(); + for (int i = 0, length= listeners.length; i < length; ++i) { + ((IReconcilingParticipant)listeners[i]).reconciled(); + } + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert() + */ + protected void performRevert() { + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); + projectionViewer.setRedraw(false); + try { + + boolean projectionMode= projectionViewer.isProjectionMode(); + if (projectionMode) { + projectionViewer.disableProjection(); + if (fProjectionMakefileUpdater != null) + fProjectionMakefileUpdater.uninstall(); + } + + super.performRevert(); + + if (projectionMode) { + if (fProjectionMakefileUpdater != null) + fProjectionMakefileUpdater.install(this, projectionViewer); + projectionViewer.enableProjection(); + } + + } finally { + projectionViewer.setRedraw(true); + } + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent) + */ + protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { + ISourceViewer sourceViewer= getSourceViewer(); + if (sourceViewer == null) + return; + + String property = event.getProperty(); + + MakefileSourceConfiguration makeConf = getMakefileSourceConfiguration(); + if (makeConf != null) { + if (makeConf.affectsBehavior(event)) { + makeConf.adaptToPreferenceChange(event); + sourceViewer.invalidateTextPresentation(); + } + } + + if (MakefileEditorPreferenceConstants.EDITOR_FOLDING_ENABLED.equals(property)) { + if (sourceViewer instanceof ProjectionViewer) { + ProjectionViewer projectionViewer= (ProjectionViewer) sourceViewer; + if (fProjectionMakefileUpdater != null) + fProjectionMakefileUpdater.uninstall(); + // either freshly enabled or provider changed + fProjectionMakefileUpdater= new ProjectionMakefileUpdater(); + if (fProjectionMakefileUpdater != null) { + fProjectionMakefileUpdater.install(this, projectionViewer); + } + } + return; + } + + super.handlePreferenceStoreChanged(event); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages() + */ + protected String[] collectContextMenuPreferencePages() { + // Add Makefile Editor relevant pages + String[] parentPrefPageIds = super.collectContextMenuPreferencePages(); + String[] prefPageIds = new String[parentPrefPageIds.length + 2]; + int nIds = 0; + prefPageIds[nIds++] = "org.eclipse.cdt.make.ui.preferences.MakeFileEditorPreferencePage"; //$NON-NLS-1$ + prefPageIds[nIds++] = "org.eclipse.cdt.make.ui.preferences.MakefileSettingPreferencePage"; //$NON-NLS-1$ + System.arraycopy(parentPrefPageIds, 0, prefPageIds, nIds, parentPrefPageIds.length); + return prefPageIds; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorActionContributor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorActionContributor.java new file mode 100644 index 00000000000..181e53c393e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorActionContributor.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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 + * Wind River Systems - fix for bugzilla 135150 + * Red Hat Inc. - modify for usage with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ResourceBundle; + +import org.eclipse.cdt.internal.autotools.ui.MakeUIMessages; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.texteditor.BasicTextEditorActionContributor; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.RetargetTextEditorAction; + + +/** + */ +public class MakefileEditorActionContributor extends BasicTextEditorActionContributor { + + private MakefileEditorTogglePresentationAction fTogglePresentation; + private OpenDeclarationAction fOpenDeclarationAction; + protected RetargetTextEditorAction fContentAssistProposal; + protected RetargetTextEditorAction fContentAssistTip; + + /** + * Constructor for MakefileEditorActionContributor. + */ + public MakefileEditorActionContributor() { + super(); + ResourceBundle bundle = MakeUIMessages.getResourceBundle(); + fContentAssistProposal = new RetargetTextEditorAction(bundle, "ContentAssistProposal."); //$NON-NLS-1$ + fContentAssistProposal.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); + fContentAssistTip = new RetargetTextEditorAction(bundle, "ContentAssistTip."); //$NON-NLS-1$ + fContentAssistTip.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION); + fTogglePresentation = new MakefileEditorTogglePresentationAction(); + fOpenDeclarationAction = new OpenDeclarationAction(); + + } + + /** + * @see org.eclipse.ui.IEditorActionBarContributor#setActiveEditor(IEditorPart) + */ + public void setActiveEditor(IEditorPart targetEditor) { + super.setActiveEditor(targetEditor); + doSetActiveEditor(targetEditor); + } + + private void doSetActiveEditor(IEditorPart part) { + super.setActiveEditor(part); + + ITextEditor editor = null; + if (part instanceof ITextEditor) { + editor = (ITextEditor) part; + } + + fContentAssistProposal.setAction(getAction(editor, "ContentAssistProposal")); //$NON-NLS-1$ + fContentAssistTip.setAction(getAction(editor, "ContentAssistTip")); //$NON-NLS-1$ + + fTogglePresentation.setEditor(editor); + fTogglePresentation.update(); + + fOpenDeclarationAction.setEditor(editor); + fOpenDeclarationAction.update(); + } + + /* + * @see IEditorActionBarContributor#dispose() + */ + public void dispose() { + doSetActiveEditor(null); + super.dispose(); + } + + /** + * @see org.eclipse.ui.part.EditorActionBarContributor#init(IActionBars) + */ + public void init(IActionBars bars) { + super.init(bars); + IMenuManager menuManager = bars.getMenuManager(); + IMenuManager editMenu = menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT); + if (editMenu != null) { + editMenu.add(new Separator()); + editMenu.add(fContentAssistProposal); + editMenu.add(fContentAssistTip); + editMenu.add(fOpenDeclarationAction); + } + + bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation); + // there is a global action in the toolbar, that is retargeted, + // there is no need to add another one. +// IToolBarManager toolBarManager = bars.getToolBarManager(); +// if (toolBarManager != null) { +// toolBarManager.add(new Separator()); +// toolBarManager.add(fTogglePresentation); +// } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorPreferenceConstants.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorPreferenceConstants.java new file mode 100644 index 00000000000..84ac61b086c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorPreferenceConstants.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.preference.IPreferenceStore; + +/** + * MakefileEditorPreferenceConstants + */ +public class MakefileEditorPreferenceConstants { + + /** + * + */ + private MakefileEditorPreferenceConstants() { + } + + /** + * 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.cdt.make.ui.currentLineHightlightColor"; //$NON-NLS-1$ + public static final String LINE_NUMBER_RULER_COLOR = "org.eclipse.cdt.make.ui.lineNumberForegroundColor"; //$NON-NLS-1$ + public static final String PRINT_MARGIN_COLOR = "org.eclipse.cdt.make.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_CONDITIONAL = "editor_folding_default_conditional"; //$NON-NLS-1$ + + public static final String EDITOR_FOLDING_ENABLED = "editor_folding_enabled"; //$NON-NLS-1$ + + public static void initializeDefaultValues(IPreferenceStore store) { + + store.setDefault(MakefileEditorPreferenceConstants.EDITOR_FOLDING_ENABLED, false); + store.setDefault(MakefileEditorPreferenceConstants.EDITOR_FOLDING_MACRODEF, false); + store.setDefault(MakefileEditorPreferenceConstants.EDITOR_FOLDING_RULE, true); + store.setDefault(MakefileEditorPreferenceConstants.EDITOR_FOLDING_CONDITIONAL, true); + + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorTogglePresentationAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorTogglePresentationAction.java new file mode 100644 index 00000000000..6a71db7bb61 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileEditorTogglePresentationAction.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified for Automake editor usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.cdt.internal.autotools.ui.MakeUIMessages; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.TextEditorAction; + + +/** + */ +public class MakefileEditorTogglePresentationAction extends TextEditorAction { + + /** + * Constructor for MakefileEditorTogglePresentationAction. + */ + public MakefileEditorTogglePresentationAction() { + super(MakeUIMessages.getResourceBundle(), "TogglePresentation.", null); //$NON-NLS-1$ + MakeUIImages.setImageDescriptors(this, MakeUIImages.T_TOOL, MakeUIImages.IMG_TOOLS_MAKEFILE_SEGMENT_EDIT); + update(); + } + + /** + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + ITextEditor editor= getTextEditor(); + editor.resetHighlightRange(); + boolean show = editor.showsHighlightRangeOnly(); + setChecked(!show); + editor.showHighlightRangeOnly(!show); + } + + /** + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + setChecked(getTextEditor() != null && getTextEditor().showsHighlightRangeOnly()); + setEnabled(true); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileMessages.java new file mode 100644 index 00000000000..b7cfb82a874 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileMessages.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2009 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.cdt.internal.autotools.ui.editors.automake; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class MakefileMessages { + + private static final String BUNDLE_NAME = MakefileMessages.class.getName(); + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private MakefileMessages() { + } + + public static ResourceBundle getResourceBundle() { + return RESOURCE_BUNDLE; + } + + /** + * 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 getString(String key) { + try { + return RESOURCE_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 substitution strings + * @return the resource bundle message + */ + public static String getFormattedString(String key, String[] args) { + return MessageFormat.format(getString(key), (Object[])args); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefilePartitionScanner.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefilePartitionScanner.java new file mode 100644 index 00000000000..a992172cba3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefilePartitionScanner.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.rules.EndOfLineRule; +import org.eclipse.jface.text.rules.IPredicateRule; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; +import org.eclipse.jface.text.rules.Token; + +public class MakefilePartitionScanner extends RuleBasedPartitionScanner { + // Partition types + public final static String MAKEFILE_COMMENT_PARTITION = "makefile_comment"; //$NON-NLS-1$ + public final static String MAKEFILE_MACRO_ASSIGNEMENT_PARTITION = "makefile_macro_assignement"; //$NON-NLS-1$ + public final static String MAKEFILE_INCLUDE_BLOCK_PARTITION = "makefile_include_block"; //$NON-NLS-1$ + public final static String MAKEFILE_IF_BLOCK_PARTITION = "makefile_if_block"; //$NON-NLS-1$ + public final static String MAKEFILE_DEF_BLOCK_PARTITION = "makefile_def_block"; //$NON-NLS-1$ + public final static String MAKEFILE_OTHER_PARTITION = "makefile_other"; //$NON-NLS-1$ + + final static String[] MAKE_PARTITIONS = + new String[] { + MAKEFILE_COMMENT_PARTITION, + MAKEFILE_MACRO_ASSIGNEMENT_PARTITION, + MAKEFILE_INCLUDE_BLOCK_PARTITION, + MAKEFILE_IF_BLOCK_PARTITION, + MAKEFILE_DEF_BLOCK_PARTITION, + MAKEFILE_OTHER_PARTITION, + }; + + /** The predefined delimiters of this tracker */ + private char[][] fModDelimiters = { { '\r', '\n' }, { '\r' }, { '\n' } }; + + /** + * Constructor for MakefilePartitionScanner + */ + public MakefilePartitionScanner() { + super(); + + IToken tComment = new Token(MAKEFILE_COMMENT_PARTITION); + IToken tMacro = new Token(MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + IToken tInclude = new Token(MAKEFILE_INCLUDE_BLOCK_PARTITION); + IToken tIf = new Token(MAKEFILE_IF_BLOCK_PARTITION); + IToken tDef = new Token(MAKEFILE_DEF_BLOCK_PARTITION); + IToken tOther = new Token(MAKEFILE_OTHER_PARTITION); + + List<IRule> rules = new ArrayList<IRule>(); + + // Add rule for single line comments. + + rules.add(new EndOfLineRule("#", tComment, '\\', true)); //$NON-NLS-1$ + + rules.add(new EndOfLineRule("include", tInclude)); //$NON-NLS-1$ + + rules.add(new EndOfLineRule("export", tDef)); //$NON-NLS-1$ + rules.add(new EndOfLineRule("unexport", tDef)); //$NON-NLS-1$ + rules.add(new EndOfLineRule("vpath", tDef)); //$NON-NLS-1$ + rules.add(new EndOfLineRule("override", tDef)); //$NON-NLS-1$ + rules.add(new MultiLineRule("define", "endef", tDef)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new MultiLineRule("override define", "endef", tDef)); //$NON-NLS-1$ //$NON-NLS-2$ + + // Add rules for multi-line comments and javadoc. + rules.add(new MultiLineRule("ifdef", "endif", tIf)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new MultiLineRule("ifndef", "endif", tIf)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new MultiLineRule("ifeq", "endif", tIf)); //$NON-NLS-1$ //$NON-NLS-2$ + rules.add(new MultiLineRule("ifnneq", "endif", tIf)); //$NON-NLS-1$ //$NON-NLS-2$ + + // Last rule must be supplied with default token! + rules.add(new MacroDefinitionRule(tMacro, tOther)); //$NON-NLS-1$ + + IPredicateRule[] result = new IPredicateRule[rules.size()]; + rules.toArray(result); + setPredicateRules(result); + + } + + /* + * @see ICharacterScanner#getLegalLineDelimiters + */ + public char[][] getLegalLineDelimiters() { + return fModDelimiters.clone(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileReader.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileReader.java new file mode 100644 index 00000000000..4b6c1cd89b2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileReader.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; + +/** + */ +public class MakefileReader extends LineNumberReader { + + + public MakefileReader(Reader reader) { + super(reader); + } + + public MakefileReader(Reader reader, int sz) { + super(reader, sz); + } + + + public String readLine() throws IOException { + boolean done = false; + StringBuffer buffer = new StringBuffer(); + boolean escapedLine = false; + boolean escapedCommand = false; + while (!done) { + String line = super.readLine(); + if (line == null) { + return null; + } + + if (escapedLine && line.length() > 0) { + // Eat the spaces at the beginning. + int i = 0; + while (i < line.length() && (Util.isSpace(line.charAt(i)))) { + i++ ; + } + line = line.substring(i); + } else if (escapedCommand && line.length() > 0) { + // Only eat the first tab + if (line.charAt(0) == '\t') { + line = line.substring(1); + } + } + + // According to POSIX rules: + // When an escaped <newline>(one preceded by a backslash) is found + // anywhere in the makefile except in a command line, it shall be replaced, + // along with any leading white space on the following line, with a single <space> + // + // When an escaped <newline> is found in a command line in a makefile, + // the command line shall contain the backslash, the <newline>, and the next line, + // except that the first character of the next line shall not be included if it is a <tab> + if (Util.isEscapedLine(line)) { + int index = line.lastIndexOf('\\'); + if (index > 0) { + if (!escapedLine && Util.isCommand(line)) { + escapedCommand = true; + buffer.append(line); + } else { + escapedLine = true; + buffer.append(line.substring(0, index)); + buffer.append(' '); + } + } + } else { + done = true; + escapedLine = false; + escapedCommand = false; + buffer.append(line); + } + } + return buffer.toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileReconcilingStrategy.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileReconcilingStrategy.java new file mode 100644 index 00000000000..7a9cc1a03ca --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileReconcilingStrategy.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.io.StringReader; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + + + +public class MakefileReconcilingStrategy implements IReconcilingStrategy { + + + private int fLastRegionOffset; + private ITextEditor fEditor; + private IWorkingCopyManager fManager; + private IDocumentProvider fDocumentProvider; + private MakefileContentOutlinePage fOutliner; + private IReconcilingParticipant fMakefileReconcilingParticipant; + + public MakefileReconcilingStrategy(MakefileEditor editor) { + fOutliner= editor.getOutlinePage(); + fLastRegionOffset = Integer.MAX_VALUE; + fEditor= editor; + fManager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + fDocumentProvider= AutomakeEditorFactory.getDefault().getAutomakefileDocumentProvider(); + fMakefileReconcilingParticipant= (IReconcilingParticipant)fEditor; + } + + /** + * @see IReconcilingStrategy#reconcile(document) + */ + public void setDocument(IDocument document) { + } + + + /** + * @see IReconcilingStrategy#reconcile(region) + */ + public void reconcile(IRegion region) { + // We use a trick to avoid running the reconciler multiple times + // on a file when it gets changed. This is because this gets called + // multiple times with different regions of the file, we do a + // complete parse on the first region. + if(region.getOffset() <= fLastRegionOffset) { + reconcile(); + } + fLastRegionOffset = region.getOffset(); + } + + /** + * @see IReconcilingStrategy#reconcile(dirtyRegion, region) + */ + public void reconcile(DirtyRegion dirtyRegion, IRegion region) { + // FIXME: This seems to generate to much flashing in + // the contentouline viewer. + //reconcile(); + } + + private void reconcile() { + try { + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + if (makefile != null) { + String content = fDocumentProvider.getDocument(fEditor.getEditorInput()).get(); + StringReader reader = new StringReader(content); + try { + makefile.parse(makefile.getFileURI(), reader); + } catch (IOException e) { + } + + fOutliner.update(); + } + } finally { + try { + if (fMakefileReconcilingParticipant != null) { + fMakefileReconcilingParticipant.reconciled(); + } + } finally { + // + } + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileSourceConfiguration.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileSourceConfiguration.java new file mode 100644 index 00000000000..b7a62b66115 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileSourceConfiguration.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.cdt.internal.autotools.ui.preferences.ColorManager; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.reconciler.MonoReconciler; +import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; + + +public class MakefileSourceConfiguration extends TextSourceViewerConfiguration { + + private ColorManager colorManager; + MakefileCodeScanner codeScanner; + private MakefileEditor fEditor; + + /** + * Single token scanner. + */ + static class SingleTokenScanner extends BufferedRuleBasedScanner { + public SingleTokenScanner(TextAttribute attribute) { + setDefaultReturnToken(new Token(attribute)); + } + } + + /** + * Constructor for MakeConfiguration + */ + public MakefileSourceConfiguration(IPreferenceStore preferenceStore, MakefileEditor editor) { + super(preferenceStore); + fEditor = editor; + colorManager = ColorManager.getDefault(); + } + + /** + * @see SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer) + */ + public String[] getConfiguredContentTypes(ISourceViewer v) { + return new String[] { + IDocument.DEFAULT_CONTENT_TYPE, + MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION, + MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION, + MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION, + MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION, + MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION, + }; + + } + + /** + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(ISourceViewer) + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + ContentAssistant assistant = new ContentAssistant(); + assistant.setContentAssistProcessor(new MakefileCompletionProcessor(fEditor), IDocument.DEFAULT_CONTENT_TYPE); + assistant.setContentAssistProcessor(new MakefileCompletionProcessor(fEditor), MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION); + assistant.setContentAssistProcessor(new MakefileCompletionProcessor(fEditor), MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION); + assistant.setContentAssistProcessor(new MakefileCompletionProcessor(fEditor), MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION); + assistant.setContentAssistProcessor(new MakefileCompletionProcessor(fEditor), MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION); + assistant.setContentAssistProcessor(new MakefileCompletionProcessor(fEditor), MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + + assistant.enableAutoActivation(true); + assistant.setAutoActivationDelay(500); + + assistant.setProposalPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW); + assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW); + //Set to Carolina blue + assistant.setContextInformationPopupBackground(colorManager.getColor(new RGB(0, 191, 255))); + + return assistant; + } + + protected MakefileCodeScanner getCodeScanner() { + if (null == codeScanner) + codeScanner = new MakefileCodeScanner(); + return codeScanner; + + } + + public IPresentationReconciler getPresentationReconciler(ISourceViewer v) { + + PresentationReconciler reconciler = new PresentationReconciler(); + + DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + + dr = new DefaultDamagerRepairer(getCodeScanner()); + dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_COMMENT_PARTITION); + + dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_MACRO_ASSIGNEMENT_PARTITION); + + dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_INCLUDE_BLOCK_PARTITION); + + dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_IF_BLOCK_PARTITION); + + dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_DEF_BLOCK_PARTITION); + + dr = new DefaultDamagerRepairer(getCodeScanner()); + reconciler.setDamager(dr, MakefilePartitionScanner.MAKEFILE_OTHER_PARTITION); + reconciler.setRepairer(dr, MakefilePartitionScanner.MAKEFILE_OTHER_PARTITION); + return reconciler; + } + + /** + * @see SourceViewerConfiguration#getReconciler(ISourceViewer) + */ + public IReconciler getReconciler(ISourceViewer sourceViewer) { + if (fEditor != null && fEditor.isEditable()) { + MonoReconciler reconciler= new MonoReconciler(new MakefileReconcilingStrategy(fEditor), false); + reconciler.setDelay(1000); + reconciler.setProgressMonitor(new NullProgressMonitor()); + return reconciler; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getDefaultPrefixes(org.eclipse.jface.text.source.ISourceViewer, java.lang.String) + */ + public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) { + return new String[]{"#"}; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String) + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return new MakefileTextHover(fEditor); + } + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer) + */ + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + return new MakefileAnnotationHover(fEditor); + } + + /** + * @param event + * @return + */ + public boolean affectsBehavior(PropertyChangeEvent event) { + MakefileCodeScanner scanner = getCodeScanner(); + return scanner.affectsBehavior(event); + } + + /** + * @param event + */ + public void adaptToPreferenceChange(PropertyChangeEvent event) { + MakefileCodeScanner scanner = getCodeScanner(); + scanner.adaptToPreferenceChange(event); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileStorageDocumentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileStorageDocumentProvider.java new file mode 100644 index 00000000000..20a96f929fa --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileStorageDocumentProvider.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.rules.FastPartitioner; +import org.eclipse.ui.editors.text.StorageDocumentProvider; + +/** + * MakefileStorageDocumentProvider + */ +public class MakefileStorageDocumentProvider extends StorageDocumentProvider { + + /* + * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setupDocument(java.lang.Object, + * org.eclipse.jface.text.IDocument) + */ + protected void setupDocument(Object element, IDocument document) { + if (document != null) { + IDocumentPartitioner partitioner= createDocumentPartitioner(); + if (document instanceof IDocumentExtension3) { + IDocumentExtension3 extension3= (IDocumentExtension3) document; + extension3.setDocumentPartitioner(MakefileDocumentSetupParticipant.MAKEFILE_PARTITIONING, partitioner); + } else { + document.setDocumentPartitioner(partitioner); + } + partitioner.connect(document); + } + } + + private IDocumentPartitioner createDocumentPartitioner() { + return new FastPartitioner( + new MakefilePartitionScanner(), MakefilePartitionScanner.MAKE_PARTITIONS); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileTextHover.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileTextHover.java new file mode 100644 index 00000000000..e25962feacb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileTextHover.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.IEditorPart; + + +/** + * MakefileTextHover + * + */ +public class MakefileTextHover implements ITextHover { + + private IEditorPart fEditor; + + /** + * + */ + public MakefileTextHover(IEditorPart editor) { + fEditor = editor; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, + * org.eclipse.jface.text.IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + if (hoverRegion != null) { + try { + int len = hoverRegion.getLength(); + int offset = hoverRegion.getOffset(); + textViewer.getDocument().get(offset, len); // check off/len validity + if (fEditor != null && len > -1) { + IWorkingCopyManager fManager = AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput()); + if (makefile != null) { + WordPartDetector wordPart = new WordPartDetector(textViewer, offset); + String name = wordPart.toString(); + IMacroDefinition[] statements = null; + if (WordPartDetector.inMacro(textViewer, offset)) { + statements = makefile.getMacroDefinitions(name); + if (statements == null || statements.length == 0) { + statements = makefile.getBuiltinMacroDefinitions(name); + } + } + + if (statements == null) { + statements = new IMacroDefinition[0]; + } + // iterate over all the different categories + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < statements.length; i++) { + if (i > 0) { + buffer.append("\n"); //$NON-NLS-1$ + } + String infoString = statements[i].getValue().toString(); + buffer.append(name); + buffer.append(" - "); //$NON-NLS-1$ + buffer.append(infoString); + } + return buffer.toString(); + } + } + } catch (BadLocationException e) { + } + } + return ""; //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, + * int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + Point selection = textViewer.getSelectedRange(); + if (selection.x <= offset && offset < selection.x + selection.y) { + return new Region(selection.x, selection.y); + } + return new Region(offset, 0); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileWordDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileWordDetector.java new file mode 100644 index 00000000000..a103b51f5de --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MakefileWordDetector.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.rules.IWordDetector; + +public class MakefileWordDetector implements IWordDetector { + + private static final String correctStartSpecChars = "%*().><"; //$NON-NLS-1$ + private static final String correctSpecChars = "@$/\\"; //$NON-NLS-1$ + + /** + * @see IWordDetector#isWordPart(character) + */ + public boolean isWordPart(char character) { + return Character.isLetterOrDigit(character) || (correctSpecChars.indexOf(character) >= 0); + } + + /** + * @see IWordDetector#isWordStart(char) + */ + public boolean isWordStart(char character) { + return Character.isLetterOrDigit(character) || (correctStartSpecChars.indexOf(character) >= 0); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MessageLine.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MessageLine.java new file mode 100644 index 00000000000..6419424a49c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/MessageLine.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; + +/** + * A message line. It distinguishs between "normal" messages and errors. + * Setting an error message hides a currently displayed message until + * <code>clearErrorMessage</code> is called. + */ +public class MessageLine { + + private String fMessageText; + private String fErrorText; + private CLabel clabel; + + private Color fDefaultColor; + private RGB fErrorRGB; + protected Color fErrorColor; + + private static RGB fgErrorRGB= new RGB(200, 0, 0); + + /** + * Clears the currently displayed error message and redisplayes + * the message which was active before the error message was set. + */ + public void clearErrorMessage() { + setErrorMessage(null); + } + /** + * Clears the currently displayed message. + */ + public void clearMessage() { + setMessage(null); + } + /** + * Get the currently displayed error text. + * @return The error message. If no error message is displayed <code>null</code> is returned. + */ + public String getErrorMessage() { + return fErrorText; + } + /** + * Get the currently displayed message. + * @return The message. If no message is displayed <code>null<code> is returned. + */ + public String getMessage() { + return fMessageText; + } + /** + * Creates a new message line as a child of the parent and with the given SWT stylebits. + * Error message will be shown with in the given rgb color. + */ + public MessageLine(Composite parent, int style, RGB errorRGB) { + clabel = new CLabel(parent, style); + fDefaultColor= clabel.getForeground(); + fErrorRGB= errorRGB; + } + /** + * Creates a new message line as a child of the parent and with the given SWT stylebits. + * Error message will be shown with in the rgb color 200,0,0. + */ + public MessageLine(Composite parent, int style) { + clabel = new CLabel(parent, style); + fDefaultColor= clabel.getForeground(); + fErrorRGB= fgErrorRGB; + } + /** + * Creates a new message line as a child of the given parent. + * Error message will be shown with in the rgb color 200,0,0. + */ + public MessageLine(Composite parent) { + this(parent, SWT.LEFT); + } + /** + * Sets the default error color used by all message lines. + * Note: a call to this method only affects newly created MessageLines not existing ones. + */ + public static void setErrorColor(RGB color) { + fgErrorRGB= color; + } + /** + * Display the given error message. A currently displayed message + * is saved and will be redisplayed when the error message is cleared. + */ + public void setErrorMessage(String message) { + fErrorText= message; + + if (message == null) { + setMessage(fMessageText); + } else { + if (fErrorColor == null) { + fErrorColor= new Color(clabel.getDisplay(), fErrorRGB); + clabel.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + fErrorColor.dispose(); + } + }); + } + clabel.setForeground(fErrorColor); + clabel.setText(message); + } + } + /** + * Set the message text. If the message line currently displays an error, + * the message is stored and will be shown after a call to clearErrorMessage + */ + public void setMessage(String message) { + fMessageText= message; + if (message == null) + message= ""; //$NON-NLS-1$ + if (fErrorText == null) { + clabel.setForeground(fDefaultColor); + clabel.setText(message); + } + } + + /** + * @see org.eclipse.swt.custom.CLabel#isDisposed() + */ + public boolean isDisposed() { + return clabel.isDisposed(); + } + + /** + * @see org.eclipse.swt.custom.CLabel#setAlignment(int) + */ + public void setAlignment(int left) { + clabel.setAlignment(left); + } + + /** + * @see org.eclipse.swt.widgets.Control#setLayoutData(Object) + */ + public void setLayoutData(GridData gridData) { + clabel.setLayoutData(gridData); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/NotParallelRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/NotParallelRule.java new file mode 100644 index 00000000000..54c77ccbcda --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/NotParallelRule.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +/** + * .NOTPARALLEL + * If `.NOTPARALLEL' is mentioned as a target, then this invocation of + * `make' will be run serially, even if the `-j' option is given. + * Any recursively invoked `make' command will still be run in + * parallel (unless its makefile contains this target). Any + * prerequisites on this target are ignored. + */ +public class NotParallelRule extends SpecialRule implements INotParallelRule { + + public NotParallelRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_NOT_PARALLEL), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/NullMakefile.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/NullMakefile.java new file mode 100644 index 00000000000..10f1027c669 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/NullMakefile.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.IOException; +import java.io.Reader; +import java.net.URI; + +/** + * Makefile : ( statement ) * + * statement : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule + * inference_rule : target ':' <nl> ( <tab> command <nl> ) + + * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl> + [ ( command ) * ] + * macro_definition : string '=' (string)* + * comments : ('#' (string) <nl>) * + * empty : <nl> + * command : <tab> prefix_command string <nl> + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" + */ + +public class NullMakefile extends AbstractMakefile { + + public final static IDirective[] EMPTY_DIRECTIVES = new IDirective[0]; + + public NullMakefile() { + super(null); + } + + public IDirective[] getDirectives() { + return EMPTY_DIRECTIVES; + } + + public IDirective[] getBuiltins() { + return EMPTY_DIRECTIVES; + } + + public void addDirective(IDirective directive) { + } + + public String toString() { + return ""; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMakefile#parse(java.io.Reader) + */ + public void parse(String name, Reader makefile) throws IOException { + } + + public void parse(URI fileURI, Reader reader) throws IOException { + } + + protected void parse(URI fileURI, MakefileReader reader) throws IOException { + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OpenDeclarationAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OpenDeclarationAction.java new file mode 100644 index 00000000000..d2b1bc0646e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OpenDeclarationAction.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 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 Corporation - initial API and implementation + * Red Hat Inc. - convert to use with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.net.URI; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.core.resources.FileStorage; +import org.eclipse.cdt.internal.autotools.ui.MakeUIMessages; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.TextEditorAction; + + +public class OpenDeclarationAction extends TextEditorAction { + + public OpenDeclarationAction() { + this(null); + } + + public OpenDeclarationAction(ITextEditor editor) { + super(MakeUIMessages.getResourceBundle(), "OpenDeclarationAction.", editor); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + ITextEditor editor = getTextEditor(); + if (editor == null) { + return; + } + ISelectionProvider provider = editor.getSelectionProvider(); + if (provider == null) { + return; + } + IDirective[] directives = null; + IWorkingCopyManager fManager = AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + IMakefile makefile = fManager.getWorkingCopy(editor.getEditorInput()); + if (makefile != null) { + IDocumentProvider prov = editor.getDocumentProvider(); + IDocument doc = prov.getDocument(editor.getEditorInput()); + try { + ITextSelection textSelection = (ITextSelection) provider.getSelection(); + int offset = textSelection.getOffset(); + WordPartDetector wordPart = new WordPartDetector(doc, textSelection.getOffset()); + String name = wordPart.toString(); + if (WordPartDetector.inMacro(doc, offset)) { + directives = makefile.getMacroDefinitions(name); + if (directives.length == 0) { + directives = makefile.getBuiltinMacroDefinitions(name); + } + } else { + directives = makefile.getTargetRules(name); + } + if (directives != null && directives.length > 0) { + openInEditor(directives[0]); + } + } catch (Exception x) { + // + } + } + } + + private static IEditorPart openInEditor(IDirective directive) throws PartInitException { + URI fileURI = directive.getMakefile().getFileURI(); + IPath path = URIUtil.toPath(fileURI); + IFile file = AutotoolsUIPlugin.getWorkspace().getRoot().getFileForLocation(path); + if (file != null) { + IWorkbenchPage p = AutotoolsUIPlugin.getActivePage(); + if (p != null) { + IEditorPart editorPart = IDE.openEditor(p, file, true); + if (editorPart instanceof MakefileEditor) { + ((MakefileEditor)editorPart).setSelection(directive, true); + } + return editorPart; + } + } else { + // External file + IStorage storage = new FileStorage(path); + IStorageEditorInput input = new ExternalEditorInput(storage); + IWorkbenchPage p = AutotoolsUIPlugin.getActivePage(); + if (p != null) { + String editorID = "org.eclipse.cdt.make.editor"; //$NON-NLS-1$ + IEditorPart editorPart = IDE.openEditor(p, input, editorID, true); + if (editorPart instanceof MakefileEditor) { + ((MakefileEditor)editorPart).setSelection(directive, true); + } + return editorPart; + } + + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.text.ITextSelection) + */ + //public void selectionChanged(ITextSelection selection) { + //setEnabled(fEditor != null); + //} +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OpenIncludeAction.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OpenIncludeAction.java new file mode 100644 index 00000000000..00e8ed0e0b4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OpenIncludeAction.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * Copyright (c) 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 Corporation - initial API and implementation + * QNX Software System + * Sergey Prigogin, Google - https://bugs.eclipse.org/bugs/show_bug.cgi?id=13221 + * Ed Swartz (Nokia) + * Anton Leherbauer (Wind River Systems) + * Red Hat Inc. - convert to use with Automake editor + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IInclude; +import org.eclipse.cdt.core.parser.ExtendedScannerInfo; +import org.eclipse.cdt.core.parser.IExtendedScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.internal.autotools.ui.MakeUIImages; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.utils.PathUtil; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; + + + +public class OpenIncludeAction extends Action { + + + private static final String PREFIX= "OpenIncludeAction."; //$NON-NLS-1$ + + private static final String DIALOG_TITLE= PREFIX + "dialog.title"; //$NON-NLS-1$ + private static final String DIALOG_MESSAGE= PREFIX + "dialog.message"; //$NON-NLS-1$ + + private ISelectionProvider fSelectionProvider; + + + public OpenIncludeAction(ISelectionProvider provider) { + super(CUIPlugin.getResourceString(PREFIX + "label")); //$NON-NLS-1$ + setDescription(CUIPlugin.getResourceString(PREFIX + "description")); //$NON-NLS-1$ + setToolTipText(CUIPlugin.getResourceString(PREFIX + "tooltip")); //$NON-NLS-1$ + + MakeUIImages.setImageDescriptors(this, MakeUIImages.T_LCL, MakeUIImages.IMG_MENU_OPEN_INCLUDE); + + fSelectionProvider= provider; + } + + public void run() { + IInclude include= getIncludeStatement(fSelectionProvider.getSelection()); + if (include == null) { + return; + } + + try { + IResource res = include.getUnderlyingResource(); + ArrayList<Object> filesFound = new ArrayList<Object>(4); + String fullFileName= include.getFullFileName(); + if (fullFileName != null) { + IPath fullPath= new Path(fullFileName); + if (fullPath.isAbsolute() && fullPath.toFile().exists()) { + filesFound.add(fullPath); + } + } + if (filesFound.isEmpty() && res != null) { + IProject proj = res.getProject(); + String includeName = include.getElementName(); + // Search in the scannerInfo information + IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(proj); + if (provider != null) { + IScannerInfo info = provider.getScannerInformation(res); + // XXXX this should fall back to project by itself + if (info == null) { + info = provider.getScannerInformation(proj); + } + if (info != null) { + IExtendedScannerInfo scanInfo = new ExtendedScannerInfo(info); + + boolean isSystemInclude = include.isStandard(); + + if (!isSystemInclude) { + // search in current directory + IPath location= include.getTranslationUnit().getLocation(); + if (location != null) { + String currentDir= location.removeLastSegments(1).toOSString(); + findFile(new String[] { currentDir }, includeName, filesFound); + } + if (filesFound.isEmpty()) { + // search in "..." include directories + String[] localIncludePaths = scanInfo.getLocalIncludePath(); + findFile(localIncludePaths, includeName, filesFound); + } + } + + if (filesFound.isEmpty()) { + // search in <...> include directories + String[] includePaths = scanInfo.getIncludePaths(); + findFile(includePaths, includeName, filesFound); + } + } + + if (filesFound.isEmpty()) { + // Fall back and search the project + findFile(proj, new Path(includeName), filesFound); + } + } + } + IPath fileToOpen; + int nElementsFound= filesFound.size(); + if (nElementsFound == 0) { + noElementsFound(); + fileToOpen= null; + } else if (nElementsFound == 1) { + fileToOpen= (IPath) filesFound.get(0); + } else { + fileToOpen= chooseFile(filesFound); + } + + if (fileToOpen != null) { + EditorUtility.openInEditor(fileToOpen, include); + } + } catch (CModelException e) { + CUIPlugin.log(e.getStatus()); + } catch (CoreException e) { + CUIPlugin.log(e.getStatus()); + } + } + + /** + * + */ + private void noElementsFound() { + MessageBox errorMsg = new MessageBox(CUIPlugin.getActiveWorkbenchShell(), SWT.ICON_ERROR | SWT.OK); + errorMsg.setText(CUIPlugin.getResourceString("OpenIncludeAction.error")); //$NON-NLS-1$ + errorMsg.setMessage (CUIPlugin.getResourceString("OpenIncludeAction.error.description")); //$NON-NLS-1$ + errorMsg.open(); + } + + private boolean isInProject(IPath path) { + return getWorkspaceRoot().getFileForLocation(path) != null; + } + + /** + * Returns the path as is, if it points to a workspace resource. If the path + * does not point to a workspace resource, but there are linked workspace + * resources pointing to it, returns the paths of these resources. + * Othervise, returns the path as is. + */ + private IPath[] resolveIncludeLink(IPath path) { + if (!isInProject(path)) { + IFile[] files = getWorkspaceRoot().findFilesForLocationURI(URIUtil.toURI(path)); + if (files.length > 0) { + IPath[] paths = new IPath[files.length]; + for (int i = 0; i < files.length; i++) { + paths[i] = files[i].getFullPath(); + } + return paths; + } + } + + return new IPath[] { path }; + } + + private IWorkspaceRoot getWorkspaceRoot() { + return ResourcesPlugin.getWorkspace().getRoot(); + } + + private void findFile(String[] includePaths, String name, ArrayList<Object> list) + throws CoreException { + // in case it is an absolute path + IPath includeFile= new Path(name); + if (includeFile.isAbsolute()) { + includeFile = PathUtil.getCanonicalPath(includeFile); + if (includeFile.toFile().exists()) { + list.add(includeFile); + return; + } + } + HashSet<IPath> foundSet = new HashSet<IPath>(); + for (int i = 0; i < includePaths.length; i++) { + IPath path = PathUtil.getCanonicalPath(new Path(includePaths[i]).append(includeFile)); + File file = path.toFile(); + if (file.exists()) { + IPath[] paths = resolveIncludeLink(path); + for (int j = 0; j < paths.length; j++) { + IPath p = paths[j]; + if (foundSet.add(p)) { + list.add(p); + } + } + } + } + } + + /** + * Recuse in the project. + * @param parent + * @param name + * @param list + * @throws CoreException + */ + private void findFile(IContainer parent, final IPath name, final ArrayList<Object> list) throws CoreException { + parent.accept(new IResourceProxyVisitor() { + + public boolean visit(IResourceProxy proxy) throws CoreException { + if (proxy.getType() == IResource.FILE && proxy.getName().equalsIgnoreCase(name.lastSegment())) { + IPath rPath = proxy.requestResource().getLocation(); + int numSegToRemove = rPath.segmentCount() - name.segmentCount(); + IPath sPath = rPath.removeFirstSegments(numSegToRemove); + sPath = sPath.setDevice(name.getDevice()); + if (Platform.getOS().equals(Platform.OS_WIN32) ? + sPath.toOSString().equalsIgnoreCase(name.toOSString()) : + sPath.equals(name)) { + list.add(rPath); + } + return false; + } + return true; + } + }, 0); + } + + + private IPath chooseFile(ArrayList<Object> filesFound) { + ILabelProvider renderer= new LabelProvider() { + public String getText(Object element) { + if (element instanceof IPath) { + IPath file= (IPath)element; + return file.lastSegment() + " - " + file.toString(); //$NON-NLS-1$ + } + return super.getText(element); + } + }; + + ElementListSelectionDialog dialog= new ElementListSelectionDialog(CUIPlugin.getActiveWorkbenchShell(), renderer, false, false); + dialog.setTitle(CUIPlugin.getResourceString(DIALOG_TITLE)); + dialog.setMessage(CUIPlugin.getResourceString(DIALOG_MESSAGE)); + dialog.setElements(filesFound); + + if (dialog.open() == Window.OK) { + return (IPath) dialog.getSelectedElement(); + } + return null; + } + + + private static IInclude getIncludeStatement(ISelection sel) { + if (!sel.isEmpty() && sel instanceof IStructuredSelection) { + @SuppressWarnings("unchecked") + List list= ((IStructuredSelection)sel).toList(); + if (list.size() == 1) { + Object element= list.get(0); + if (element instanceof IInclude) { + return (IInclude)element; + } + } + } + return null; + } + + public static boolean canActionBeAdded(ISelection selection) { + ICElement include = getIncludeStatement(selection); + if (include != null) { + IResource res = include.getUnderlyingResource(); + if (res != null) { + return true; + } + } + return false; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OverrideDefine.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OverrideDefine.java new file mode 100644 index 00000000000..64b4c46b4c0 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OverrideDefine.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +public class OverrideDefine extends DefineVariable { + + public OverrideDefine(Directive parent, String name, StringBuffer value) { + super(parent, name, value); + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.VARIABLE_OVERRIDE + " " + GNUMakefileConstants.VARIABLE_DEFINE); //$NON-NLS-1$ + sb.append(getName()).append('\n'); + sb.append(getValue()); + sb.append(GNUMakefileConstants.TERMINAL_ENDEF); + return sb.toString(); + } + + public boolean isOverride() { + return true; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OverrideVariable.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OverrideVariable.java new file mode 100644 index 00000000000..d757cff56c4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/OverrideVariable.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - Modified for Automake usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class OverrideVariable extends GNUVariableDef { + + public OverrideVariable(Directive parent, String name, StringBuffer value, int type) { + super(parent, name, value, type); + } + + public boolean isOverride() { + return true; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Parent.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Parent.java new file mode 100644 index 00000000000..da478d25c8d --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Parent.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * IParent + */ + +public abstract class Parent extends Directive implements IParent { + + ArrayList<IDirective> children = new ArrayList<IDirective>(); + + public Parent(Directive parent) { + super(parent); + } + + public IDirective[] getDirectives(boolean expand) { + return getDirectives(); + } + + public IDirective[] getDirectives() { + children.trimToSize(); + return (IDirective[]) children.toArray(new IDirective[0]); + } + + public void addDirective(Directive directive) { + children.add(directive); + // reparent + directive.setParent(this); + } + + public void addDirectives(Directive[] directives) { + children.addAll(Arrays.asList(directives)); + // reparent + for (int i = 0; i < directives.length; i++) { + directives[i].setParent(this); + } + } + + public void clearDirectives() { + children.clear(); + } + + public Directive[] getStatements() { + children.trimToSize(); + return (Directive[]) children.toArray(new Directive[0]); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + IDirective[] directives = getDirectives(); + for (int i = 0; i < directives.length; i++) { + sb.append(directives[i]); + } + return sb.toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PhonyRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PhonyRule.java new file mode 100644 index 00000000000..45f02ff08b7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PhonyRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .PHONY + * The prerequisites of the special target `.PHONY' are considered to be phony targets. + * When it is time to consider such a target, `make' will run its commands unconditionally, regardless of + * whether a file with that name exists or what its last-modification time is. + */ +public class PhonyRule extends SpecialRule implements IPhonyRule { + + public PhonyRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_PHONY), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PosixMakefileUtil.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PosixMakefileUtil.java new file mode 100644 index 00000000000..c757f4ec816 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PosixMakefileUtil.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + + +/** + */ +public class PosixMakefileUtil { + + public static String[] findPrerequisites(String line) { + return findTargets(line); + } + + public static String[] findTargets(String line) { + List<String> aList = new ArrayList<String>(); + int space; + // Trim away trailing and prepending spaces. + line = line.trim(); + while ((space = Util.indexOf(line, " \t")) != -1) { //$NON-NLS-1$ + aList.add(line.substring(0, space).trim()); + line = line.substring(space + 1).trim(); + } + // The last target. + if (line.length() > 0) { + aList.add(line); + } + return (String[]) aList.toArray(new String[0]); + } + + public static boolean isMacroDefinition(String line) { + return Util.indexOf(line, '=') != -1; + } + + public static boolean isTargetRule(String line) { + return Util.indexOf(line, ':') != -1; + } + + public static boolean isCommand(String line) { + return line.length() > 1 && line.charAt(0) == '\t'; + } + + public static boolean isEmptyLine(String line) { + return line.trim().length() == 0; + } + + public static boolean isInferenceRule(String line) { + line = line.trim(); + if (line.startsWith(".")) { //$NON-NLS-1$ + int index = Util.indexOf(line, ':'); + if (index > 1) { + line = line.substring(index + 1).trim(); + if (line.length() == 0 || line.equals(";")) { //$NON-NLS-1$ + return true; + } + } + } + return false; + } + + public static boolean isDefaultRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_DEFAULT); + } + return false; + } + + public static boolean isIgnoreRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_IGNORE); + } + return false; + } + + public static boolean isPosixRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_POSIX); + } + return false; + } + + public static boolean isPreciousRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_PRECIOUS); + } + return false; + } + + public static boolean isSccsGetRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_SCCS_GET); + } + return false; + } + + public static boolean isSilentRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_SILENT); + } + return false; + } + + public static boolean isSuffixesRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(MakeFileConstants.RULE_SUFFIXES); + } + return false; + } + + public static boolean isLibraryTarget(String line) { + char prev = 0; + int paren = 0; + + for (int i = 0; i < line.length(); i++) { + char ch = line.charAt(i); + if (ch == '(' && prev != '$' && prev != '\\') { + paren++; + } else if (ch == ')' && prev != '\\') { + if (paren > 0) { + return true; + } + } + prev = ch; + } + return false; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PosixRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PosixRule.java new file mode 100644 index 00000000000..803cc5b1cf6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PosixRule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .POSIX + * The appliation shall ensure that this special target is specified without + * prerequisites or commands. + */ +public class PosixRule extends SpecialRule implements IPosixRule { + + public PosixRule(Directive parent) { + super(parent, new Target(MakeFileConstants.RULE_POSIX), new String[0], new Command[0]); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PreciousRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PreciousRule.java new file mode 100644 index 00000000000..2e031a8b0d5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/PreciousRule.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .PRECIOUS + * Prerequisites of this special target shall not be removed if make recieves an + * asynchronous events. + */ +public class PreciousRule extends SpecialRule implements IPreciousRule { + + public PreciousRule(Directive parent, String[] reqs) { + super(parent, new Target(MakeFileConstants.RULE_PRECIOUS), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ProjectionMakefileUpdater.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ProjectionMakefileUpdater.java new file mode 100644 index 00000000000..fe45218a151 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ProjectionMakefileUpdater.java @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 2007 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. - convert to use with Automake editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.projection.IProjectionListener; +import org.eclipse.jface.text.source.projection.ProjectionAnnotation; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.ui.texteditor.IDocumentProvider; + + +/** + * ProjectionMakefileUpdater + */ +public class ProjectionMakefileUpdater implements IProjectionListener { + + private static class MakefileProjectionAnnotation extends ProjectionAnnotation { + + private IDirective fDirective; + private boolean fIsComment; + + public MakefileProjectionAnnotation(IDirective element, boolean isCollapsed, boolean isComment) { + super(isCollapsed); + fDirective = element; + fIsComment = isComment; + } + + public IDirective getElement() { + return fDirective; + } + + public void setElement(IDirective element) { + fDirective = element; + } + + public boolean isComment() { + return fIsComment; + } + } + + + public void install(MakefileEditor editor, ProjectionViewer viewer) { + fEditor= editor; + fViewer= viewer; + fViewer.addProjectionListener(this); + } + + public void uninstall() { + if (isInstalled()) { + projectionDisabled(); + fViewer.removeProjectionListener(this); + fViewer= null; + fEditor= null; + } + } + + protected boolean isInstalled() { + return fEditor != null; + } + + private class ReconcilerParticipant implements IReconcilingParticipant { + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.IReconcilingParticipant#reconciled() + */ + public void reconciled() { + processReconcile(); + } + } + + private IDocument fCachedDocument; + private MakefileEditor fEditor; + private IDirective fInput; + private ProjectionViewer fViewer; + private IReconcilingParticipant fParticipant; + + private boolean fAllowCollapsing = false; + @SuppressWarnings("unused") + private boolean fCollapseMacroDef = false; + @SuppressWarnings("unused") + private boolean fCollapseRule = false; + @SuppressWarnings("unused") + private boolean fCollapseConditional = false; + + /* + * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled() + */ + public void projectionEnabled() { + // http://home.ott.oti.com/teams/wswb/anon/out/vms/index.html + // projectionEnabled messages are not always paired with projectionDisabled + // i.e. multiple enabled messages may be sent out. + // we have to make sure that we disable first when getting an enable + // message. + projectionDisabled(); + + initialize(); + fParticipant= new ReconcilerParticipant(); + fEditor.addReconcilingParticipant(fParticipant); + } + + /* + * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled() + */ + public void projectionDisabled() { + fCachedDocument= null; + if (fParticipant != null) { + fEditor.addReconcilingParticipant(fParticipant); + fParticipant= null; + } + } + + public void initialize() { + + if (!isInstalled()) + return; + + initializePreferences(); + + try { + + IDocumentProvider provider= fEditor.getDocumentProvider(); + fCachedDocument= provider.getDocument(fEditor.getEditorInput()); + fAllowCollapsing= true; + + IWorkingCopyManager manager= AutomakeEditorFactory.getDefault().getWorkingCopyManager(); + fInput= manager.getWorkingCopy(fEditor.getEditorInput()); + + if (fInput != null) { + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model != null) { + @SuppressWarnings("unchecked") + Map additions= computeAdditions((IParent) fInput); + model.removeAllAnnotations(); + model.replaceAnnotations(null, additions); + } + } + + } finally { + fCachedDocument= null; + fAllowCollapsing= false; + } + } + + private void initializePreferences() { + //FIXME: what to do with Makefile editor preferences + IPreferenceStore store = AutotoolsPlugin.getDefault().getPreferenceStore(); + fCollapseMacroDef = store.getBoolean(MakefileEditorPreferenceConstants.EDITOR_FOLDING_MACRODEF); + fCollapseRule = store.getBoolean(MakefileEditorPreferenceConstants.EDITOR_FOLDING_RULE); + fCollapseConditional = store.getBoolean(MakefileEditorPreferenceConstants.EDITOR_FOLDING_CONDITIONAL); + } + + private Map<MakefileProjectionAnnotation, Position> computeAdditions(IParent parent) { + Map<MakefileProjectionAnnotation, Position> map= new HashMap<MakefileProjectionAnnotation, Position>(); + computeAdditions(parent.getDirectives(), map); + return map; + } + + private void computeAdditions(IDirective[] elements, Map<MakefileProjectionAnnotation, Position> map) { + for (int i= 0; i < elements.length; i++) { + IDirective element= elements[i]; + + computeAdditions(element, map); + + if (element instanceof IParent) { + IParent parent= (IParent) element; + computeAdditions(parent.getDirectives(), map); + } + } + } + + private void computeAdditions(IDirective element, Map<MakefileProjectionAnnotation, Position> map) { + + boolean createProjection= false; + + if (element instanceof IConditional) { + createProjection= true; + } else if (element instanceof IMacroDefinition) { + createProjection= true; + } else if (element instanceof IRule) { + createProjection= true; + } + + if (createProjection) { + Position position= createProjectionPosition(element); + if (position != null) { + map.put(new MakefileProjectionAnnotation(element, fAllowCollapsing, true), position); + } + } + } + + private Position createProjectionPosition(IDirective element) { + + if (fCachedDocument == null) + return null; + + try { + int startLine= element.getStartLine() - 1; + int endLine= element.getEndLine() - 1; + if (startLine != endLine) { + int offset= fCachedDocument.getLineOffset(startLine); + int endOffset= fCachedDocument.getLineOffset(endLine + 1); + return new Position(offset, endOffset - offset); + } + + } catch (BadLocationException x) { + } + + return null; + } + + public void processReconcile() { + if (!isInstalled()) + return; + + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model == null) + return; + + try { + IDocumentProvider provider= fEditor.getDocumentProvider(); + fCachedDocument= provider.getDocument(fEditor.getEditorInput()); + fAllowCollapsing= false; + + Map<MakefileProjectionAnnotation, Position> additions= new HashMap<MakefileProjectionAnnotation, Position>(); + List<MakefileProjectionAnnotation> deletions= new ArrayList<MakefileProjectionAnnotation>(); + List<MakefileProjectionAnnotation> updates= new ArrayList<MakefileProjectionAnnotation>(); + + Map<MakefileProjectionAnnotation, Position> updated= computeAdditions((IParent) fInput); + Map<IDirective, List<MakefileProjectionAnnotation>> previous= createAnnotationMap(model); + + + Iterator<MakefileProjectionAnnotation> e= updated.keySet().iterator(); + while (e.hasNext()) { + MakefileProjectionAnnotation annotation= (MakefileProjectionAnnotation) e.next(); + IDirective element= annotation.getElement(); + Position position= (Position) updated.get(annotation); + + List<MakefileProjectionAnnotation> annotations= previous.get(element); + if (annotations == null) { + additions.put(annotation, position); + } else { + Iterator<MakefileProjectionAnnotation> x= annotations.iterator(); + while (x.hasNext()) { + MakefileProjectionAnnotation a= (MakefileProjectionAnnotation) x.next(); + if (annotation.isComment() == a.isComment()) { + Position p= model.getPosition(a); + if (p != null && !position.equals(p)) { + p.setOffset(position.getOffset()); + p.setLength(position.getLength()); + updates.add(a); + } + x.remove(); + break; + } + } + + if (annotations.isEmpty()) + previous.remove(element); + } + } + + Iterator<List<MakefileProjectionAnnotation>> e2 = previous.values().iterator(); + while (e.hasNext()) { + List<MakefileProjectionAnnotation> list= e2.next(); + int size= list.size(); + for (int i= 0; i < size; i++) + deletions.add(list.get(i)); + } + + match(model, deletions, additions, updates); + + Annotation[] removals= new Annotation[deletions.size()]; + deletions.toArray(removals); + Annotation[] changes= new Annotation[updates.size()]; + updates.toArray(changes); + model.modifyAnnotations(removals, additions, changes); + + } finally { + fCachedDocument= null; + fAllowCollapsing= true; + } + } + + private void match(ProjectionAnnotationModel model, List<MakefileProjectionAnnotation> deletions, + Map<MakefileProjectionAnnotation, Position> additions, List<MakefileProjectionAnnotation> changes) { + if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty())) + return; + + List<MakefileProjectionAnnotation> newDeletions= new ArrayList<MakefileProjectionAnnotation>(); + List<MakefileProjectionAnnotation> newChanges= new ArrayList<MakefileProjectionAnnotation>(); + + Iterator<MakefileProjectionAnnotation> deletionIterator= deletions.iterator(); + outer: while (deletionIterator.hasNext()) { + MakefileProjectionAnnotation deleted= (MakefileProjectionAnnotation) deletionIterator.next(); + Position deletedPosition= model.getPosition(deleted); + if (deletedPosition == null) + continue; + + Iterator<MakefileProjectionAnnotation> changesIterator= changes.iterator(); + while (changesIterator.hasNext()) { + MakefileProjectionAnnotation changed= (MakefileProjectionAnnotation) changesIterator.next(); + if (deleted.isComment() == changed.isComment()) { + Position changedPosition= model.getPosition(changed); + if (changedPosition == null) + continue; + + if (deletedPosition.getOffset() == changedPosition.getOffset()) { + + deletedPosition.setLength(changedPosition.getLength()); + deleted.setElement(changed.getElement()); + + deletionIterator.remove(); + newChanges.add(deleted); + + changesIterator.remove(); + newDeletions.add(changed); + + continue outer; + } + } + } + + Iterator<MakefileProjectionAnnotation> additionsIterator= additions.keySet().iterator(); + while (additionsIterator.hasNext()) { + MakefileProjectionAnnotation added= (MakefileProjectionAnnotation) additionsIterator.next(); + if (deleted.isComment() == added.isComment()) { + Position addedPosition= (Position) additions.get(added); + + if (deletedPosition.getOffset() == addedPosition.getOffset()) { + + deletedPosition.setLength(addedPosition.getLength()); + deleted.setElement(added.getElement()); + + deletionIterator.remove(); + newChanges.add(deleted); + + additionsIterator.remove(); + + break; + } + } + } + } + + deletions.addAll(newDeletions); + changes.addAll(newChanges); + } + + private Map<IDirective, List<MakefileProjectionAnnotation>> createAnnotationMap(IAnnotationModel model) { + Map<IDirective, List<MakefileProjectionAnnotation>> map= new HashMap<IDirective, List<MakefileProjectionAnnotation>>(); + @SuppressWarnings("unchecked") + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Object annotation= e.next(); + if (annotation instanceof MakefileProjectionAnnotation) { + MakefileProjectionAnnotation directive= (MakefileProjectionAnnotation) annotation; + List<MakefileProjectionAnnotation> list= map.get(directive.getElement()); + if (list == null) { + list= new ArrayList<MakefileProjectionAnnotation>(2); + map.put(directive.getElement(), list); + } + list.add(directive); + } + } + return map; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ResourceMarkerAnnotationModel.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ResourceMarkerAnnotationModel.java new file mode 100644 index 00000000000..9f2513ccf5c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/ResourceMarkerAnnotationModel.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.HashSet; +import java.util.Iterator; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.Position; +import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel; +import org.eclipse.ui.texteditor.MarkerAnnotation; + +/** + * A marker annotation model whose underlying source of markers is + * a resource in the workspace. + * <p> + * This class may be instantiated; it is not intended to be subclassed.</p> + * + * @noextend This class is not intended to be subclassed by clients. + */ +public class ResourceMarkerAnnotationModel extends AbstractMarkerAnnotationModel { + + /** + * Internal resource change listener. + */ + class ResourceChangeListener implements IResourceChangeListener { + /* + * @see IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent e) { + IResourceDelta delta= e.getDelta(); + if (delta != null && fResource != null) { + IResourceDelta child= delta.findMember(fResource.getFullPath()); + if (child != null) + update(child.getMarkerDeltas()); + } + } + } + + /** The workspace. */ + private IWorkspace fWorkspace; + /** The resource. */ + private IResource fResource; + /** The resource change listener. */ + private IResourceChangeListener fResourceChangeListener= new ResourceChangeListener(); + + + /** + * Creates a marker annotation model with the given resource as the source + * of the markers. + * + * @param resource the resource + */ + public ResourceMarkerAnnotationModel(IResource resource) { + Assert.isNotNull(resource); + fResource= resource; + fWorkspace= resource.getWorkspace(); + } + + /* + * @see AbstractMarkerAnnotationModel#isAcceptable(IMarker) + */ + protected boolean isAcceptable(IMarker marker) { + return marker != null && fResource.equals(marker.getResource()); + } + + /** + * Updates this model to the given marker deltas. + * + * @param markerDeltas the array of marker deltas + */ + protected void update(IMarkerDelta[] markerDeltas) { + + if (markerDeltas.length == 0) + return; + + if (markerDeltas.length == 1) { + IMarkerDelta delta= markerDeltas[0]; + switch (delta.getKind()) { + case IResourceDelta.ADDED : + addMarkerAnnotation(delta.getMarker()); + break; + case IResourceDelta.REMOVED : + removeMarkerAnnotation(delta.getMarker()); + break; + case IResourceDelta.CHANGED : + modifyMarkerAnnotation(delta.getMarker()); + break; + } + } else + batchedUpdate(markerDeltas); + + fireModelChanged(); + } + + /** + * Updates this model to the given marker deltas. + * + * @param markerDeltas the array of marker deltas + */ + @SuppressWarnings("unchecked") + private void batchedUpdate(IMarkerDelta[] markerDeltas) { + HashSet removedMarkers= new HashSet(markerDeltas.length); + HashSet modifiedMarkers= new HashSet(markerDeltas.length); + + for (int i= 0; i < markerDeltas.length; i++) { + IMarkerDelta delta= markerDeltas[i]; + switch (delta.getKind()) { + case IResourceDelta.ADDED: + addMarkerAnnotation(delta.getMarker()); + break; + case IResourceDelta.REMOVED: + removedMarkers.add(delta.getMarker()); + break; + case IResourceDelta.CHANGED: + modifiedMarkers.add(delta.getMarker()); + break; + } + } + + if (modifiedMarkers.isEmpty() && removedMarkers.isEmpty()) + return; + + Iterator e= getAnnotationIterator(false); + while (e.hasNext()) { + Object o= e.next(); + if (o instanceof MarkerAnnotation) { + MarkerAnnotation a= (MarkerAnnotation)o; + IMarker marker= a.getMarker(); + + if (removedMarkers.remove(marker)) + removeAnnotation(a, false); + + if (modifiedMarkers.remove(marker)) { + Position p= createPositionFromMarker(marker); + if (p != null) { + a.update(); + modifyAnnotationPosition(a, p, false); + } + } + + if (modifiedMarkers.isEmpty() && removedMarkers.isEmpty()) + return; + + } + } + + Iterator iter= modifiedMarkers.iterator(); + while (iter.hasNext()) + addMarkerAnnotation((IMarker)iter.next()); + } + + /* + * @see AbstractMarkerAnnotationModel#listenToMarkerChanges(boolean) + */ + protected void listenToMarkerChanges(boolean listen) { + if (listen) + fWorkspace.addResourceChangeListener(fResourceChangeListener); + else + fWorkspace.removeResourceChangeListener(fResourceChangeListener); + } + + /* + * @see AbstractMarkerAnnotationModel#deleteMarkers(IMarker[]) + */ + protected void deleteMarkers(final IMarker[] markers) throws CoreException { + fWorkspace.run(new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + for (int i= 0; i < markers.length; ++i) { + markers[i].delete(); + } + } + }, null, IWorkspace.AVOID_UPDATE, null); + } + + /* + * @see AbstractMarkerAnnotationModel#retrieveMarkers() + */ + protected IMarker[] retrieveMarkers() throws CoreException { + return fResource.findMarkers(IMarker.MARKER, true, IResource.DEPTH_ZERO); + } + + /** + * Returns the resource serving as the source of markers for this annotation model. + * + * @return the resource serving as the source of markers for this annotation model + * @since 2.0 + */ + protected IResource getResource() { + return fResource; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Rule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Rule.java new file mode 100644 index 00000000000..5a22407a7d9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Rule.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; + +public abstract class Rule extends Parent implements IRule { + + Target target; + + public Rule(Directive parent, Target tgt) { + this(parent, tgt, new Command[0]); + } + + public Rule(Directive parent, Target tgt, Command[] cmds) { + super(parent); + target = tgt; + addDirectives(cmds); + } + + public ICommand[] getCommands() { + IDirective[] directives = getDirectives(); + ArrayList<IDirective> cmds = new ArrayList<IDirective>(directives.length); + for (int i = 0; i < directives.length; i++) { + if (directives[i] instanceof ICommand) { + cmds.add(directives[i]); + } + } + return (ICommand[])cmds.toArray(new ICommand[0]); + } + + public ITarget getTarget() { + return target; + } + + public void setTarget(Target tgt) { + target = tgt; + } + + public boolean equals(Object r) { + if (r instanceof Rule) + return ((Rule)r).getTarget().equals(getTarget()); + return false; + } + + public int hashCode() { + return getTarget().hashCode(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SccsGetRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SccsGetRule.java new file mode 100644 index 00000000000..465c4a2d0e2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SccsGetRule.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SCCS_GET + * The application shall ensure that this special target is specified without + * prerequesites. + * The commands specifeied with this target shall replace the default + * commands associated with this special target. + */ +public class SccsGetRule extends SpecialRule implements ISccsGetRule { + + public SccsGetRule(Directive parent, Command[] cmds) { + super(parent, new Target(MakeFileConstants.RULE_SCCS_GET), new String[0], cmds); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SecondaryRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SecondaryRule.java new file mode 100644 index 00000000000..af753c0f0d9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SecondaryRule.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SECONDARY + * The targets which `.SECONDARY' depends on are treated as + * intermediate files, except that they are never automatically deleted. + * + * `.SECONDARY' with no prerequisites causes all targets to be treated + * as secondary (i.e., no target is removed because it is considered intermediate). + */ +public class SecondaryRule extends SpecialRule implements ISecondaryRule { + + public SecondaryRule(Directive parent, String[] reqs) { + super(parent, new Target(GNUMakefileConstants.RULE_SECONDARY), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SelectionList.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SelectionList.java new file mode 100644 index 00000000000..a31b324d4dd --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SelectionList.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** + * A selection widget that consists of a list and a text entry field. The list + * of elements presented are limited to the pattern entered into the text entry + * field. + */ +public class SelectionList extends Composite { + + // State + private Object[] fElements; + protected ILabelProvider fRenderer; + private boolean fIgnoreCase; + + // Implementation details + private String[] fRenderedStrings; + private int[] fFilteredElements; + private String fRememberedMatchText; + + // SWT widgets + private Table fList; + private Text fText; + + /** + * Adds a selection change listener to this widget. + */ + public void addSelectionListener(SelectionListener listener) { + fList.addSelectionListener(listener); + } + private void createList(int style) { + fList= new Table(this, style); + fList.setLayoutData(new GridData(GridData.FILL_BOTH)); + fList.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + fRenderer.dispose(); + } + }); + } + private void createText() { + fText= new Text(this, SWT.BORDER); + GridData spec= new GridData(); + spec.grabExcessVerticalSpace= false; + spec.grabExcessHorizontalSpace= true; + spec.horizontalAlignment= GridData.FILL; + spec.verticalAlignment= GridData.BEGINNING; + fText.setLayoutData(spec); + Listener l= new Listener() { + public void handleEvent(Event evt) { + filter(false); + } + }; + fText.addListener(SWT.Modify, l); + } + /** + * Filters the list of elements according to the pattern entered + * into the text entry field. + */ + public void filter(boolean forceUpdate) { + int k= 0; + String text= fText.getText(); + if (!forceUpdate && text.equals(fRememberedMatchText)) + return; + fRememberedMatchText= text; + StringMatcher matcher= new StringMatcher(text+"*", fIgnoreCase, false); //$NON-NLS-1$ + for (int i= 0; i < fElements.length; i++) { + if (matcher.match(fRenderedStrings[i])) { + fFilteredElements[k]= i; + k++; + } + } + fFilteredElements[k]= -1; + updateListWidget(fFilteredElements, k); + } + /** + * Returns the currently used filter text. + */ + public String getFilter() { + return fText.getText(); + } + /** + * Returns the selection indices. + */ + public int[] getSelectionIndices() { + return fList.getSelectionIndices(); + } + /** + * Returns a list of selected elements. Note that the type of the elements + * returned in the list are the same as the ones passed to the selection list + * via <code>setElements</code>. The list doesn't contain the rendered strings. + */ + public List<Object> getSelection() { + if (fList == null || fList.isDisposed() || fList.getSelectionCount() == 0) + return new ArrayList<Object>(0); + int[] listSelection= fList.getSelectionIndices(); + List<Object> selected= new ArrayList<Object>(listSelection.length); + for (int i= 0; i < listSelection.length; i++) { + selected.add(fElements[fFilteredElements[listSelection[i]]]); + } + return selected; + } + /** + * Returns <code>true</code> when the list of elements is empty. + */ + public boolean isEmptyList() { + return fElements == null || fElements.length == 0; + } + /** + * Creates new instance of the widget. + */ + public SelectionList(Composite parent, int style, ILabelProvider renderer, boolean ignoreCase) { + super(parent, SWT.NONE); + fRenderer= renderer; + fIgnoreCase= ignoreCase; + GridLayout layout= new GridLayout(); + layout.marginHeight= 0; layout.marginWidth= 0; + //XXX: 1G9V58A: ITPUI:WIN2000 - Dialog.convert* methods should be static + setLayout(layout); + createText(); + createList(style); + } + /** + * Removes a selection change listener to this widget. + */ + public void removeSelectionListener(SelectionListener listener) { + fList.removeSelectionListener(listener); + } + private String[] renderStrings() { + String[] strings= new String[fElements.length]; + for (int i= 0; i < strings.length; i++) { + strings[i]= fRenderer.getText(fElements[i]); + } + TwoArrayQuickSort.sort(strings, fElements, fIgnoreCase); + return strings; + } + /** + * Select the pattern text. + */ + public void selectFilterText() { + fText.selectAll(); + } + /** + * Sets the list of elements presented in the widget. + */ + public void setElements(List<Object> elements, boolean refilter) { + // We copy the list since we sort it. + if (elements == null) + fElements= new Object[0]; + else + fElements= elements.toArray(); + fFilteredElements= new int[fElements.length+1]; + fRenderedStrings= renderStrings(); + if (refilter) + filter(true); + } + /* + * Non Java-doc + */ + public void setEnabled(boolean enable) { + super.setEnabled(enable); + fText.setEnabled(enable); + fList.setEnabled(enable); + } + /** + * Sets the filter pattern. Current only prefix filter pattern are supported. + */ + public void setFilter(String pattern, boolean refilter) { + fText.setText(pattern); + if (refilter) + filter(true); + } + /* + * Non Java-doc + */ + public boolean setFocus() { + return fText.setFocus(); + } + /* + * Non Java-doc + */ + public void setFont(Font font) { + super.setFont(font); + fText.setFont(font); + fList.setFont(font); + } + /** + * Selects the elements in the list determined by the given + * selection indices. + */ + protected void setSelection(int[] selection) { + fList.setSelection(selection); + } + private void updateListWidget(int[] indices, int size) { + if (fList == null || fList.isDisposed()) + return; + fList.setRedraw(false); + int itemCount= fList.getItemCount(); + if (size < itemCount) { + fList.remove(0, itemCount-size-1); + } + + TableItem[] items= fList.getItems(); + for (int i= 0; i < size; i++) { + TableItem ti= null; + if (i < itemCount) { + ti= items[i]; + } else { + ti= new TableItem(fList, i); + } + ti.setText(fRenderedStrings[indices[i]]); + Image img= fRenderer.getImage(fElements[indices[i]]); + if (img != null) + ti.setImage(img); + } + if (fList.getItemCount() > 0) { + fList.setSelection(0); + } + + fList.setRedraw(true); + Event event= new Event(); + fList.notifyListeners(SWT.Selection, event); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SelectionStatusDialog.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SelectionStatusDialog.java new file mode 100644 index 00000000000..af45a6a94fe --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SelectionStatusDialog.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +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.Control; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.ui.dialogs.SelectionDialog; + +import org.eclipse.core.runtime.IStatus; + +/** + * An abstract base class for dialogs with a status bar and ok/cancel buttons. + * The status message must be passed over as StatusInfo object and can be + * an error, warning or ok. The OK button is enabled / disabled depending + * on the status. + */ +public abstract class SelectionStatusDialog extends SelectionDialog { + + private MessageLine fStatusLine; + private IStatus fLastStatus; + private Image fImage; + private boolean fInitialSelectionSet; + private boolean fStatusLineAboveButtons= false; + + + /** + * Compute the result and return it. + */ + protected abstract void computeResult(); + /* (non-Javadoc) + * Method declared in Window. + */ + protected void configureShell(Shell shell) { + super.configureShell(shell); + if (fImage != null) + shell.setImage(fImage); + } + /* (non-Javadoc) + * Method declared in Dialog. + */ + protected Control createButtonBar(Composite parent) { + Composite composite= new Composite(parent, SWT.NULL); + GridLayout layout= new GridLayout(); + if (fStatusLineAboveButtons) { + layout.verticalSpacing= 0; + } else { + layout.numColumns= 2; + } + layout.marginHeight= 0; layout.marginWidth= 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + fStatusLine= new MessageLine(composite); + fStatusLine.setAlignment(SWT.LEFT); + fStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fStatusLine.setMessage(""); //$NON-NLS-1$ + + super.createButtonBar(composite); + return composite; + } + /* (non-Javadoc) + * Method declared in Dialog. + */ + public void create() { + super.create(); + if (fLastStatus != null) { + updateStatus(fLastStatus); + } + } + /** + * Returns the first element of the initial selection or <code>null<code> + * if there isn't any initial selection. + * @return the first element of the initial selection. + */ + @SuppressWarnings({ "unchecked" }) + protected Object getPrimaryInitialSelection() { + List result= getInitialElementSelections(); + if (result == null || result.size() == 0) + return null; + return result.get(0); + } + /** + * Returns the first element from the list of results. Returns <code>null</code> + * if no element has been selected. + * + * @return the first result element if one exists. Otherwise <code>null</code> is + * returned. + */ + public Object getPrimaryResult() { + Object[] result= getResult(); + if (result == null || result.length == 0) + return null; + return result[0]; + } + public SelectionStatusDialog(Shell parent) { + super(parent); + fInitialSelectionSet= false; + } + /* (non-Javadoc) + * Method declared in Dialog. + */ + protected void okPressed() { + computeResult(); + super.okPressed(); + } + /** + * Sets the image for this dialog. + * + * @param image the dialog's image + */ + public void setImage(Image image) { + fImage= image; + } + @SuppressWarnings({ "unchecked" }) + protected void setInitialSelection(int position, Object element) { + List l= getInitialElementSelections(); + l.set(position, element); + fInitialSelectionSet= true; + } + /** + * Sets the initial selection to the given element. + */ + public void setInitialSelection(Object element) { + // Allow clients to use set their own initial selection(s) + if (fInitialSelectionSet && element != null && element.equals("A")) //$NON-NLS-1$ + return; + + if (element != null) { + setInitialSelections(new Object[] { element }); + } else { + setInitialSelections(new Object[0]); + } + } + public void setInitialSelections(Object[] selectedElements) { + super.setInitialSelections(selectedElements); + fInitialSelectionSet= true; + } + /** + * Sets a result element at the given position. + */ + protected void setResult(int position, Object element) { + Object[] result= getResult(); + result[position]= element; + setResult(Arrays.asList(result)); + } + /** + * Controls whether status line appears to the left of the buttons (default) + * or above them. + * + * @param aboveButtons if <code>true</code> status line is placed above buttons; if + * <code>false</code> to the right + */ + public void setStatusLineAboveButtons(boolean aboveButtons) { + fStatusLineAboveButtons= aboveButtons; + } + /** + * Update the status of the ok button to reflect the given status. Subclasses + * may override this method to update additional buttons. + */ + protected void updateButtonsEnableState(IStatus status) { + Button okButton= getOkButton(); + if (okButton != null && !okButton.isDisposed()) + okButton.setEnabled(!status.matches(IStatus.ERROR)); + } + /** + * Update the dialog's status line to reflect the given status. It is safe to call + * this method before the dialog has been opened. + */ + protected void updateStatus(IStatus status) { + fLastStatus= status; + if (fStatusLine != null && !fStatusLine.isDisposed()) { + updateButtonsEnableState(status); + StatusTool.applyToStatusLine(fStatusLine, status); + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SilentRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SilentRule.java new file mode 100644 index 00000000000..c706e36899e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SilentRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SILENT + * Prerequisties of this special target are targets themselves; this shall cause + * commands associated with them not to be written to the standard output before + * they are executed. + */ +public class SilentRule extends SpecialRule implements ISilentRule { + + public SilentRule(Directive parent, String[] reqs) { + super(parent, new Target(MakeFileConstants.RULE_SILENT), reqs, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SpecialRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SpecialRule.java new file mode 100644 index 00000000000..2d19bb2d5ee --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SpecialRule.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Targets that have special meaning for Make. + */ +public abstract class SpecialRule extends Rule implements ISpecialRule { + + String[] prerequisites; + + public SpecialRule(Directive parent, Target target, String[] reqs, Command[] cmds) { + super(parent, target, cmds); + prerequisites = reqs.clone(); + } + + public String[] getPrerequisites() { + return prerequisites.clone(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(target).append(':'); + String[] reqs = getPrerequisites(); + for (int i = 0; i < reqs.length; i++) { + sb.append(' ').append(reqs[i]); + } + sb.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + sb.append(cmds[i]); + } + return sb.toString(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StaticTargetRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StaticTargetRule.java new file mode 100644 index 00000000000..c630122590b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StaticTargetRule.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Here is the syntax of a static pattern rule: + * + * TARGETS ...: TARGET-PATTERN: DEP-PATTERNS ... + * COMMANDS + * ... + */ +public class StaticTargetRule extends InferenceRule implements IInferenceRule { + + String targetPattern; + String[] prereqPatterns; + + public StaticTargetRule(Directive parent, Target target, String target_pattern, String[] prereq_patterns, Command[] commands) { + super(parent, target, commands); + targetPattern = target_pattern; + prereqPatterns = prereq_patterns.clone(); + } + + public String[] getPrerequisitePatterns() { + return prereqPatterns.clone(); + } + + public void setPrerequisitePatterns(String[] prereqs) { + prereqPatterns = prereqs.clone(); + } + + public String getTargetPattern() { + return targetPattern; + } + + public void setTargetPattern(String target_pattern) { + targetPattern = target_pattern; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getTarget()).append(':'); + String pattern = getTargetPattern(); + if (pattern != null && pattern.length() > 0) { + buffer.append(' ').append(targetPattern); + } + buffer.append(':'); + for (int i = 0; i < prereqPatterns.length; i++) { + buffer.append(' ').append(prereqPatterns[i]); + } + buffer.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); + } + return buffer.toString(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StatusInfo.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StatusInfo.java new file mode 100644 index 00000000000..fd6a842cdf4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StatusInfo.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.runtime.IStatus; + +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * 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 { + + public static final IStatus OK_STATUS= new StatusInfo(); + + 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; + } + + /** + * @see IStatus#getChildren() + */ + public IStatus[] getChildren() { + return new IStatus[0]; + } + /** + * @see IStatus#getCode() + */ + public int getCode() { + return fSeverity; + } + /** + * @see IStatus#getException() + */ + public Throwable getException() { + return null; + } + /** + * @see IStatus#getMessage + */ + public String getMessage() { + return fStatusMessage; + } + /** + * @see IStatus#getPlugin() + */ + public String getPlugin() { + return CUIPlugin.PLUGIN_ID; + } + /** + * @see IStatus#getSeverity() + */ + public int getSeverity() { + return fSeverity; + } + public boolean isError() { + return fSeverity == IStatus.ERROR; + } + public boolean isInfo() { + return fSeverity == IStatus.INFO; + } + /** + * @see IStatus#isMultiStatus() + */ + public boolean isMultiStatus() { + return false; + } + public boolean isOK() { + return fSeverity == IStatus.OK; + } + public boolean isWarning() { + return fSeverity == IStatus.WARNING; + } + /** + * @see IStatus#matches(int) + */ + public boolean matches(int severityMask) { + return (fSeverity & severityMask) != 0; + } + public void setError(String errorMessage) { + fStatusMessage= errorMessage; + fSeverity= IStatus.ERROR; + } + public void setInfo(String infoMessage) { + fStatusMessage= infoMessage; + fSeverity= IStatus.INFO; + } + public void setOK() { + fStatusMessage= null; + fSeverity= IStatus.OK; + } + public void setWarning(String warningMessage) { + fStatusMessage= warningMessage; + fSeverity= IStatus.WARNING; + } + + /** + * Returns a string representation of the status, suitable + * for debugging purposes only. + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("StatusInfo "); //$NON-NLS-1$ + if (fSeverity == OK) { + buf.append("OK"); //$NON-NLS-1$ + } else if (fSeverity == ERROR) { + buf.append("ERROR"); //$NON-NLS-1$ + } else if (fSeverity == WARNING) { + buf.append("WARNING"); //$NON-NLS-1$ + } else if (fSeverity == INFO) { + buf.append("INFO"); //$NON-NLS-1$ + } else { + buf.append("severity="); //$NON-NLS-1$ + buf.append(fSeverity); + } + buf.append(": "); //$NON-NLS-1$ + buf.append(fStatusMessage); + return buf.toString(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StatusTool.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StatusTool.java new file mode 100644 index 00000000000..c5e83569f3e --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StatusTool.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.runtime.IStatus; + +import org.eclipse.jface.dialogs.DialogPage; + +public class StatusTool { + + /** + * Applies the status to the status line of a dialog page + */ + public static void applyToStatusLine(MessageLine messageLine, IStatus status) { + String[] messages= getErrorMessages(status); + messageLine.setErrorMessage(messages[0]); + messageLine.setMessage(messages[1]); + } + /** + * Applies the status to the status line of a dialog page + */ + public static void applyToStatusLine(DialogPage page, IStatus status) { + String[] messages= getErrorMessages(status); + page.setErrorMessage(messages[0]); + page.setMessage(messages[1]); + } + /** + * Returns error-message / warning-message for a status + */ + public static String[] getErrorMessages(IStatus status) { + String message= status.getMessage(); + if (status.matches(IStatus.ERROR) && !"".equals(message)) { //$NON-NLS-1$ + return new String[] { message, null }; + } else if (status.matches(IStatus.WARNING | IStatus.INFO)) { + return new String[] { null, message }; + } else { + return new String[] { null, null }; + } + } + /** + * Compare two IStatus. The more severe is returned: + * An error is more severe than a warning, and a warning is more severe + * than ok. + */ + public static IStatus getMoreSevere(IStatus s1, IStatus s2) { + if (s1.getSeverity() > s2.getSeverity()) { + return s1; + } + return s2; + } + /** + * Finds the most severe status from a array of status + * An error is more severe than a warning, and a warning is more severe + * than ok. + */ + public static IStatus getMostSevere(IStatus[] status) { + IStatus max= null; + for (int i= 0; i < status.length; i++) { + IStatus curr= status[i]; + if (curr.matches(IStatus.ERROR)) { + return curr; + } + if (max == null || curr.getSeverity() > max.getSeverity()) { + max= curr; + } + } + return max; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StringMatcher.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StringMatcher.java new file mode 100644 index 00000000000..68d31a43948 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/StringMatcher.java @@ -0,0 +1,389 @@ +/******************************************************************************* + * Copyright (c) 2000, 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 Corporation - initial API and implementation + * QNX Software System + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.util.Vector; + +public class StringMatcher { + protected String fPattern; + protected int fLength; // pattern length + protected boolean fIgnoreWildCards; + protected boolean fIgnoreCase; + protected boolean fHasLeadingStar; + protected boolean fHasTrailingStar; + protected String fSegments[]; //the given pattern is split into * separated segments + + /* boundary value beyond which we don't need to search in the text */ + protected int fBound= 0; + + protected static final char fSingleWildCard= '\u0000'; + + public static class Position { + int start; //inclusive + int end; //exclusive + public Position(int start, int end) { + this.start= start; + this.end= end; + } + public int getStart() { + return start; + } + public int getEnd() { + return end; + } + } + + /** + * Find the first occurrence of the pattern between <code>start</code)(inclusive) + * and <code>end</code>(exclusive). + * @param text the String object to search in + * @param start the starting index of the search range, inclusive + * @param end the ending index of the search range, exclusive + * @return an <code>StringMatcher.Position</code> object that keeps the starting + * (inclusive) and ending positions (exclusive) of the first occurrence of the + * pattern in the specified range of the text; return null if not found or subtext + * is empty (start==end). A pair of zeros is returned if pattern is empty string + * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" + * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned + */ + + public StringMatcher.Position find(String text, int start, int end) { + if (fPattern == null || text == null) + throw new IllegalArgumentException(); + + int tlen= text.length(); + if (start < 0) + start= 0; + if (end > tlen) + end= tlen; + if (end < 0 || start >= end) + return null; + if (fLength == 0) + return new Position(start, start); + if (fIgnoreWildCards) { + int x= posIn(text, start, end); + if (x < 0) + return null; + return new Position(x, x + fLength); + } + + int segCount= fSegments.length; + if (segCount == 0) //pattern contains only '*'(s) + return new Position(start, end); + + int curPos= start; + int matchStart= -1; + for (int i= 0; i < segCount && curPos < end; ++i) { + String current= fSegments[i]; + int nextMatch= regExpPosIn(text, curPos, end, current); + if (nextMatch < 0) + return null; + if (i == 0) + matchStart= nextMatch; + curPos= nextMatch + current.length(); + } + return new Position(matchStart, curPos); + } + /** + * StringMatcher constructor takes in a String object that is a simple + * pattern which may contain * for 0 and many characters and + * ? for exactly one character. Also takes as parameter a boolean object + * specifying if case should be ignored + * @deprecated Use StringMatcher(pattern, ignoreCase, ignoreWildCards). + */ + public StringMatcher(String aPattern, boolean ignoreCase) { + this(aPattern, ignoreCase, false); + } + /** + * StringMatcher constructor takes in a String object that is a simple + * pattern which may contain * for 0 and many characters and + * ? for exactly one character. + * + * Literal '*' and '?' characters must be escaped in the pattern + * e.g., "\*" means literal "*", etc. + * + * Escaping any other character (including the escape character itself), + * just results in that character in the pattern. + * e.g., "\a" means "a" and "\\" means "\" + * + * If invoking the StringMatcher with string literals in Java, don't forget + * escape characters are represented by "\\". + * + * @param aPattern the pattern to match text against + * @param ignoreCase if true, case is ignored + * @param ignoreWildCards if true, wild cards and their escape sequences are ignored + * (everything is taken literally). + */ + public StringMatcher(String aPattern, boolean ignoreCase, boolean ignoreWildCards) { + fIgnoreCase= ignoreCase; + fIgnoreWildCards= ignoreWildCards; + fLength= aPattern.length(); + + /* convert case */ + if (fIgnoreCase) { + char[] chars= aPattern.toCharArray(); + for (int i = 0; i < chars.length; i++) { + chars[i]= Character.toUpperCase(chars[i]); + } + fPattern= new String(chars); + } else { + fPattern= aPattern; + } + + if (fIgnoreWildCards) { + parseNoWildCards(); + } else { + parseWildCards(); + } + } + /** + * Given the starting (inclusive) and the ending (exclusive) poisitions in the + * <code>text</code>, determine if the given substring matches with aPattern + * @return true if the specified portion of the text matches the pattern + * @param text a String object that contains the substring to match + * @param start marks the starting position (inclusive) of the substring + * @param end marks the ending index (exclusive) of the substring + */ + public boolean match(String text, int start, int end) { + if (null == fPattern || null == text) + throw new IllegalArgumentException(); + + if (start > end) + return false; + + if (fIgnoreWildCards) + return fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength); + int segCount= fSegments.length; + if (segCount == 0) //pattern contains only '*'(s) or empty pattern + return true; + if (start == end) + return fLength == 0; + if (fLength == 0) + return start == end; + + int tlen= text.length(); + if (start < 0) + start= 0; + if (end > tlen) + end= tlen; + + int tCurPos= start; + int bound= end - fBound; + if (bound < 0) + return false; + int i= 0; + String current= fSegments[i]; + int segLength= current.length(); + + /* process first segment */ + if (!fHasLeadingStar) { + if (!regExpRegionMatches(text, start, current, 0, segLength)) { + return false; + } + ++i; + tCurPos= tCurPos + segLength; + } + + /* process middle segments */ + for (; i < segCount && tCurPos <= bound; ++i) { + current= fSegments[i]; + int currentMatch; + int k= current.indexOf(fSingleWildCard); + if (k < 0) { + currentMatch= textPosIn(text, tCurPos, end, current); + if (currentMatch < 0) + return false; + } else { + currentMatch= regExpPosIn(text, tCurPos, end, current); + if (currentMatch < 0) + return false; + } + tCurPos= currentMatch + current.length(); + } + + /* process final segment */ + if (!fHasTrailingStar && tCurPos != end) { + int clen= current.length(); + return regExpRegionMatches(text, end - clen, current, 0, clen); + } + return i == segCount; + } + /** + * match the given <code>text</code> with the pattern + * @return true if matched eitherwise false + * @param text a String object + */ + public boolean match(String text) { + return match(text, 0, text.length()); + } + /** + * This method parses the given pattern into segments seperated by wildcard '*' characters. + * Since wildcards are not being used in this case, the pattern consists of a single segment. + */ + private void parseNoWildCards() { + fSegments= new String[1]; + fSegments[0]= fPattern; + fBound= fLength; + } + /** + * This method parses the given pattern into segments seperated by wildcard '*' characters. + */ + private void parseWildCards() { + if (fPattern.startsWith("*")) //$NON-NLS-1$ + fHasLeadingStar= true; + if (fPattern.endsWith("*")) { //$NON-NLS-1$ + /* make sure it's not an escaped wildcard */ + if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { + fHasTrailingStar= true; + } + } + + Vector<String> temp= new Vector<String>(); + + int pos= 0; + StringBuffer buf= new StringBuffer(); + while (pos < fLength) { + char c= fPattern.charAt(pos++); + switch (c) { + case '\\' : + if (pos >= fLength) { + buf.append(c); + } else { + char next= fPattern.charAt(pos++); + /* if it's an escape sequence */ + if (next == '*' || next == '?' || next == '\\') { + buf.append(next); + } else { + /* not an escape sequence, just insert literally */ + buf.append(c); + buf.append(next); + } + } + break; + case '*' : + if (buf.length() > 0) { + /* new segment */ + temp.addElement(buf.toString()); + fBound += buf.length(); + buf.setLength(0); + } + break; + case '?' : + /* append special character representing single match wildcard */ + buf.append(fSingleWildCard); + break; + default : + buf.append(c); + } + } + + /* add last buffer to segment list */ + if (buf.length() > 0) { + temp.addElement(buf.toString()); + fBound += buf.length(); + } + + fSegments= new String[temp.size()]; + temp.copyInto(fSegments); + } + /** + * @param text a string which contains no wildcard + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int posIn(String text, int start, int end) { //no wild card in pattern + int max= end - fLength; + + if (!fIgnoreCase) { + int i= text.indexOf(fPattern, start); + if (i == -1 || i > max) + return -1; + return i; + } + + for (int i= start; i <= max; ++i) { + if (text.regionMatches(true, i, fPattern, 0, fLength)) + return i; + } + + return -1; + } + /** + * @param text a simple regular expression that may only contain '?'(s) + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a simple regular expression that may contains '?' + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int regExpPosIn(String text, int start, int end, String p) { + int plen= p.length(); + + int max= end - plen; + for (int i= start; i <= max; ++i) { + if (regExpRegionMatches(text, i, p, 0, plen)) + return i; + } + return -1; + } + + protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) { + while (plen-- > 0) { + char tchar= text.charAt(tStart++); + char pchar= p.charAt(pStart++); + + /* process wild cards */ + if (!fIgnoreWildCards) { + /* skip single wild cards */ + if (pchar == fSingleWildCard) { + continue; + } + } + if (pchar == tchar) + continue; + if (fIgnoreCase) { + char tc= Character.toUpperCase(tchar); + if (tc == pchar) + continue; + } + return false; + } + return true; + } + /** + * @param text the string to match + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a string that has no wildcard + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int textPosIn(String text, int start, int end, String p) { + + int plen= p.length(); + int max= end - plen; + + if (!fIgnoreCase) { + int i= text.indexOf(p, start); + if (i == -1 || i > max) + return -1; + return i; + } + + for (int i= 0; i <= max; ++i) { + if (text.regionMatches(true, i, p, 0, plen)) + return i; + } + + return -1; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SuffixesRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SuffixesRule.java new file mode 100644 index 00000000000..f61990318fc --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/SuffixesRule.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * .SUFFIXES + * Prerequisites of .SUFFIXES shall be appended to the list of known suffixes and are + * used in conjunction with the inference rules. + * + */ +public class SuffixesRule extends SpecialRule implements ISuffixesRule { + + public SuffixesRule(Directive parent, String[] suffixes) { + super(parent, new Target(MakeFileConstants.RULE_SUFFIXES), suffixes, new Command[0]); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Target.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Target.java new file mode 100644 index 00000000000..236a02fd023 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Target.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import java.io.File; + +public class Target implements ITarget { + + String target; + + public Target(String t) { + target = t; + } + + public String toString() { + return target; + } + + public boolean exits() { + return new File(target).exists(); + } + + public long lastModified() { + return new File(target).lastModified(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TargetRule.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TargetRule.java new file mode 100644 index 00000000000..1bdea41fa41 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TargetRule.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Makefile : ( statement ) * + * statement : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule + * inference_rule : target ':' <nl> ( <tab> command <nl> ) + + * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl> + [ ( <tab> prefix_command command ) * ] + * macro_definition : string '=' (string)* + * comments : '#' (string) * + * empty : <nl> + * command : string <nl> + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" + */ + +public class TargetRule extends Rule implements ITargetRule { + + String[] prerequisites; + + public TargetRule(Directive parent, Target target) { + this(parent, target, new String[0], new Command[0]); + } + + public TargetRule(Directive parent, Target target, String[] deps) { + this(parent, target, deps, new Command[0]); + } + + public TargetRule(Directive parent, Target target, String[] reqs, Command[] commands) { + super(parent, target, commands); + prerequisites = reqs.clone(); + } + + public String[] getPrerequisites() { + return prerequisites.clone(); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getTarget().toString()); + buffer.append(':'); + String[] reqs = getPrerequisites(); + for (int i = 0; i < reqs.length; i++) { + buffer.append(' ').append(reqs[i]); + } + buffer.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); + } + return buffer.toString(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TargetVariable.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TargetVariable.java new file mode 100644 index 00000000000..558e2f08a7a --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TargetVariable.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 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. - modified for Automake usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Here is the syntax of a static pattern rule: + * + * TARGETS ...: VARIABLE-ASSIGNMENT + * TARGETS ...: override VARIABLE-ASSIGNMENT + */ +public class TargetVariable extends GNUVariableDef { + + boolean override; + + public TargetVariable(Directive parent, String target, String name, StringBuffer value, boolean override, int type) { + super(parent, target, name, value, type); + this.override = override; + } + + public boolean isOverride() { + return override; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Terminal.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Terminal.java new file mode 100644 index 00000000000..f57259d1163 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Terminal.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public abstract class Terminal extends Directive implements ITerminal { + + public Terminal(Directive parent) { + super(parent); + } + + public boolean isEndif() { + return false; + } + + public boolean isEndef() { + return false; + } + + public String toString() { + return "\n"; //$NON-NLS-1$ + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TwoArrayQuickSort.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TwoArrayQuickSort.java new file mode 100644 index 00000000000..a2d34655a87 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/TwoArrayQuickSort.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.core.runtime.Assert; + + +/** + * Quick sort to sort two arrays in parallel. + */ +public class TwoArrayQuickSort { + + private static void internalSort(String[] keys, Object[] values, int left, int right, boolean ignoreCase) { + + int original_left= left; + int original_right= right; + + String mid= keys[(left + right) >>> 1]; + do { + while (smaller(keys[left], mid, ignoreCase)) { + left++; + } + while (smaller(mid, keys[right], ignoreCase)) { + right--; + } + if (left <= right) { + String tmp= keys[left]; + keys[left]= keys[right]; + keys[right]= tmp; + + Object tmp2= values[left]; + values[left]= values[right]; + values[right]= tmp2; + + left++; + right--; + } + } while (left <= right); + + if (original_left < right) { + internalSort(keys , values, original_left, right, ignoreCase); + } + if (left < original_right) { + internalSort(keys, values, left, original_right, ignoreCase); + } + } + private static boolean smaller(String left, String right, boolean ignoreCase) { + if (ignoreCase) + return left.compareToIgnoreCase(right) < 0; + return left.compareTo(right) < 0; + } + /** + * Sorts keys and values in parallel. + */ + public static void sort(String[] keys, Object[] values, boolean ignoreCase) { + if (keys != null && values != null) { + Assert.isTrue(keys.length == values.length); + if (keys.length > 1) + internalSort(keys, values, 0, keys.length - 1, ignoreCase); + } else { + if (keys != null || values != null) + Assert.isTrue(false, "Either keys or values in null"); //$NON-NLS-1$ + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/UnExport.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/UnExport.java new file mode 100644 index 00000000000..6464c39f8ad --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/UnExport.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class UnExport extends Directive implements IUnExport { + + String variable; + + public UnExport(Directive parent, String var) { + super(parent); + variable = var; + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.DIRECTIVE_UNEXPORT); + sb.append(' ').append(variable); + return sb.toString(); + } + + public String getVariable() { + return variable; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Util.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Util.java new file mode 100644 index 00000000000..1455230a124 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/Util.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + * Utility methods. + */ +public class Util { + + private Util() { + } + + public static boolean isCommand(String line) { + return line.length() > 1 && line.startsWith("\t"); //$NON-NLS-1$ + } + + public static boolean isEscapedLine(String line) { + return (line.endsWith("\\") && !line.endsWith("\\\\")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static boolean isEmptyLine(String line) { + return line.trim().length() == 0; + } + + public static int indexOfComment(String line) { + boolean escaped = false; + for (int i = 0; i < line.length(); i++) { + if (line.charAt(i) == '#' && !escaped) { + return i; + } + escaped = line.charAt(i) == '\\'; + } + return -1; + } + + public static boolean isSpace(char c) { + return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); + } + + public static int indexOf(String line, char c) { + return indexOf(line, Character.valueOf(c).toString()); + } + + /** + * Special indexOf() method that makes sure that what we are searching + * is not between parentheses and brackets like a macro $(foo) ${bar} + */ + public static int indexOf(String line, String tokens) { + int paren = 0; + int bracket = 0; + char prev = 0; + char pprev = 0; + for (int i = 0; i < line.length(); i++) { + char ch = line.charAt(i); + if (ch == '(' && prev == '$' && pprev != '\\') { + paren++; + } else if (ch == '{' && prev == '$' && pprev != '\\') { + bracket++; + } else if (ch == ')' && prev != '\\') { + if (paren > 0) { + paren--; + } + } else if (ch == '}' && prev != '\\') { + if (bracket > 0) { + bracket--; + } + } else if (tokens.indexOf(ch) != -1) { + if (paren == 0 && bracket == 0) { + return i; + } + } + pprev = prev; + prev = ch; + } + return -1; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/VPath.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/VPath.java new file mode 100644 index 00000000000..965c3e3e874 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/VPath.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +public class VPath extends Directive implements IVPath { + + String pattern; + String[] directories; + + public VPath(Directive parent, String pat, String[] dirs) { + super(parent); + pattern = pat; + directories = dirs.clone(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(GNUMakefileConstants.DIRECTIVE_VPATH); + if (pattern != null && pattern.length() > 0) { + sb.append(' ').append(pattern); + } + for (int i = 0; i < directories.length; i++) { + sb.append(' ').append(directories[i]); + } + return sb.toString(); + } + + public String[] getDirectories() { + return directories.clone(); + } + + public String getPattern() { + return pattern; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/VariableDefinition.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/VariableDefinition.java new file mode 100644 index 00000000000..a43106e5861 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/VariableDefinition.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +/** + */ +public class VariableDefinition extends MacroDefinition implements IVariableDefinition { + + /** + * ? is Conditional + * : is Simply-expanded + * + is append + * 0 is recursively-expanded. + */ + final static int TYPE_RECURSIVE_EXPAND = 0; + final static int TYPE_SIMPLE_EXPAND = ':'; + final static int TYPE_CONDITIONAL = '?'; + final static int TYPE_APPEND = '+'; + int type; + String varTarget; + + public VariableDefinition(Directive parent, String name, StringBuffer value) { + this(parent, name, value, TYPE_RECURSIVE_EXPAND); + } + + public VariableDefinition(Directive parent, String name, StringBuffer value, int type) { + this(parent, "", name, value, type); //$NON-NLS-1$ + } + + public VariableDefinition(Directive parent, String target, String name, StringBuffer value, int type) { + super(parent, name, value); + varTarget = target; + this.type = type; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + if (isTargetSpecific()) { + sb.append(getTarget()).append(": "); //$NON-NLS-1$ + } + if (isOverride()) { + sb.append(GNUMakefileConstants.VARIABLE_OVERRIDE); + } + if (isMultiLine()) { + sb.append(GNUMakefileConstants.VARIABLE_DEFINE); + sb.append(' '); + sb.append(getName()).append('\n'); + sb.append(getValue()).append('\n'); + sb.append(GNUMakefileConstants.TERMINAL_ENDEF); + sb.append('\n'); + } else { + if (isExport()) { + sb.append(GNUMakefileConstants.VARIABLE_EXPORT); + sb.append(' '); + } + sb.append(getName()); + if (isRecursivelyExpanded()) { + sb.append(" = "); //$NON-NLS-1$ + } else if (isSimplyExpanded()) { + sb.append(" := "); //$NON-NLS-1$ + } else if (isConditional()) { + sb.append(" ?= "); //$NON-NLS-1$ + } else if (isAppend()) { + sb.append(" += "); //$NON-NLS-1$ + } + sb.append(getValue()).append('\n'); + } + return sb.toString(); + } + + public boolean isRecursivelyExpanded() { + return type == TYPE_RECURSIVE_EXPAND; + } + + public boolean isSimplyExpanded() { + return type == TYPE_SIMPLE_EXPAND; + } + + public boolean isConditional() { + return type == TYPE_CONDITIONAL; + } + + public boolean isAppend() { + return type == TYPE_APPEND; + } + + public boolean isTargetSpecific() { + String t = getTarget(); + return t != null && t.length() > 0; + } + + public boolean isExport() { + return false; + } + + public boolean isMultiLine() { + return false; + } + + /** + * Variable from an `override' directive. + */ + public boolean isOverride() { + return false; + } + + /** + * Automatic variable -- cannot be set. + */ + public boolean isAutomatic() { + return false; + } + + public String getTarget() { + return varTarget; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/WordPartDetector.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/WordPartDetector.java new file mode 100644 index 00000000000..156fc5e7fb9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/WordPartDetector.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; + +/** + * Used to scan and detect for SQL keywords + */ +public class WordPartDetector { + String wordPart = ""; //$NON-NLS-1$ + int offset; + + /** + * WordPartDetector. + * @param viewer is a text viewer + * @param documentOffset into the SQL document + */ + public WordPartDetector(ITextViewer viewer, int documentOffset) { + this(viewer.getDocument(), documentOffset); + } + + /** + * + * @param doc + * @param documentOffset + */ + public WordPartDetector(IDocument doc, int documentOffset) { + offset = documentOffset - 1; + int endOffset = documentOffset; + try { + IRegion region = doc.getLineInformationOfOffset(documentOffset); + int top = region.getOffset(); + int bottom = region.getLength() + top; + while (offset >= top && isMakefileLetter(doc.getChar(offset))) { + offset--; + } + while (endOffset < bottom && isMakefileLetter(doc.getChar(endOffset))) { + endOffset++; + } + //we've been one step too far : increase the offset + offset++; + wordPart = doc.get(offset, endOffset - offset); + } catch (BadLocationException e) { + // do nothing + } + } + + public static boolean inMacro(ITextViewer viewer, int offset) { + return inMacro(viewer.getDocument(), offset); + } + + public static boolean inMacro(IDocument document, int offset) { + boolean isMacro = false; + // Try to figure out if we are in a Macro. + try { + for (int index = offset - 1; index >= 0; index--) { + char c; + c = document.getChar(index); + if (c == '$') { + isMacro = true; + break; + } else if (Character.isWhitespace(c)) { + break; + } + } + } catch (BadLocationException e) { + } + return isMacro; + } + + + /** + * @return String + */ + public String toString() { + return wordPart; + } + + public int getOffset() { + return offset; + } + + boolean isMakefileLetter(char c) { + return Character.isLetterOrDigit(c) || c == '_' || c == '.'; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/WorkingCopyManager.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/WorkingCopyManager.java new file mode 100644 index 00000000000..8a0a11d4323 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/editors/automake/WorkingCopyManager.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.editors.automake; + + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.ui.IEditorInput; + + +/** + * This working copy manager works together with a given compilation unit document provider and + * additionally offers to "overwrite" the working copy provided by this document provider. + */ +public class WorkingCopyManager implements IWorkingCopyManager, IWorkingCopyManagerExtension { + + private IMakefileDocumentProvider fDocumentProvider; + private Map<IEditorInput, IMakefile> fMap; + private boolean fIsShuttingDown; + + /** + * Creates a new working copy manager that co-operates with the given + * compilation unit document provider. + * + * @param provider the provider + */ + public WorkingCopyManager(IMakefileDocumentProvider provider) { + Assert.isNotNull(provider); + fDocumentProvider= provider; + } + + /* + * @see org.eclipse.cdt.make.ui.IWorkingCopyManager#connect(org.eclipse.ui.IEditorInput) + */ + public void connect(IEditorInput input) throws CoreException { + fDocumentProvider.connect(input); + } + + /* + * @see org.eclipse.cdt.make.ui.IWorkingCopyManager#disconnect(org.eclipse.ui.IEditorInput) + */ + public void disconnect(IEditorInput input) { + fDocumentProvider.disconnect(input); + } + + /* + * @see org.eclipse.cdt.make.ui.IWorkingCopyManager#shutdown() + */ + public void shutdown() { + if (!fIsShuttingDown) { + fIsShuttingDown= true; + try { + if (fMap != null) { + fMap.clear(); + fMap= null; + } + fDocumentProvider.shutdown(); + } finally { + fIsShuttingDown= false; + } + } + } + + /* + * @see org.eclipse.cdt.make.ui.IWorkingCopyManager#getWorkingCopy(org.eclipse.ui.IEditorInput) + */ + public IMakefile getWorkingCopy(IEditorInput input) { + IMakefile unit= fMap == null ? null : (IMakefile) fMap.get(input); + return unit != null ? unit : fDocumentProvider.getWorkingCopy(input); + } + + /* + * @see org.eclipse.cdt.make.ui.IWorkingCopyManagerExtension#setWorkingCopy(org.eclipse.ui.IEditorInput, org.eclipse.cdt.make.core.makefile.IMakefile) + */ + public void setWorkingCopy(IEditorInput input, IMakefile workingCopy) { + if (fDocumentProvider.getDocument(input) != null) { + if (fMap == null) + fMap= new HashMap<IEditorInput, IMakefile>(); + fMap.put(input, workingCopy); + } + } + + /* + * @see org.eclipse.cdt.internal.autotools.ui.editors.automake.IWorkingCopyManagerExtension#removeWorkingCopy(org.eclipse.ui.IEditorInput) + */ + public void removeWorkingCopy(IEditorInput input) { + fMap.remove(input); + if (fMap.isEmpty()) + fMap= null; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AbstractEditorPreferencePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AbstractEditorPreferencePage.java new file mode 100644 index 00000000000..6a1de86d4a4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AbstractEditorPreferencePage.java @@ -0,0 +1,329 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.preferences; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.dialogs.DialogPage; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.preference.PreferencePage; +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.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.osgi.service.prefs.BackingStoreException; + + +/** + * AbstraceMakeEditorPreferencePage + */ +public abstract class AbstractEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + OverlayPreferenceStore fOverlayStore; + + Map<Button, String> fCheckBoxes= new HashMap<Button, String>(); + private SelectionListener fCheckBoxListener= new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + } + public void widgetSelected(SelectionEvent e) { + Button button= (Button) e.widget; + fOverlayStore.setValue((String) fCheckBoxes.get(button), button.getSelection()); + } + }; + + Map<Text, String> fTextFields= new HashMap<Text, String>(); + private ModifyListener fTextFieldListener= new ModifyListener() { + public void modifyText(ModifyEvent e) { + Text text= (Text) e.widget; + fOverlayStore.setValue((String) fTextFields.get(text), text.getText()); + } + }; + + private Map<Text, Object> fNumberFields= new HashMap<Text, Object>(); + private ModifyListener fNumberFieldListener= new ModifyListener() { + public void modifyText(ModifyEvent e) { + numberFieldChanged((Text) e.widget); + } + }; + + public AbstractEditorPreferencePage() { + super(); + setPreferenceStore(AutotoolsPlugin.getDefault().getPreferenceStore()); + fOverlayStore= createOverlayStore(); + } + + protected abstract OverlayPreferenceStore createOverlayStore(); + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + + protected void initializeFields() { + Map<Button, String> checkBoxes= getCheckBoxes(); + Map<Text, String> textFields= getTextFields(); + Iterator<Button> e= checkBoxes.keySet().iterator(); + while (e.hasNext()) { + Button b= (Button) e.next(); + String key= (String) checkBoxes.get(b); + b.setSelection(getOverlayStore().getBoolean(key)); + } + + Iterator<Text> e2 = textFields.keySet().iterator(); + while (e.hasNext()) { + Text t= (Text) e2.next(); + String key= (String) textFields.get(t); + t.setText(getOverlayStore().getString(key)); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferencePage#performOk() + */ + public boolean performOk() { + getOverlayStore().propagate(); + IScopeContext scope = InstanceScope.INSTANCE; + try { + scope.getNode(AutotoolsPlugin.PLUGIN_ID).flush(); + } catch (BackingStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return true; + } + + protected OverlayPreferenceStore getOverlayStore() { + return fOverlayStore; + } + + protected OverlayPreferenceStore setOverlayStore() { + return fOverlayStore; + } + + protected Map<Button, String> getCheckBoxes() { + return fCheckBoxes; + } + + protected Map<Text, String> getTextFields() { + return fTextFields; + } + + protected Map<Text, Object> getNumberFields() { + return fNumberFields; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performDefaults() + */ + protected void performDefaults() { + getOverlayStore().loadDefaults(); + initializeFields(); + handleDefaults(); + super.performDefaults(); + } + + protected abstract void handleDefaults(); + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#dispose() + */ + public void dispose() { + if (getOverlayStore() != null) { + getOverlayStore().stop(); + fOverlayStore= null; + } + super.dispose(); + } + + protected Button addCheckBox(Composite parent, String labelText, String key, int indentation) { + Button checkBox= new Button(parent, SWT.CHECK); + checkBox.setText(labelText); + checkBox.setFont(parent.getFont()); + + GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent= indentation; + gd.horizontalSpan= 2; + checkBox.setLayoutData(gd); + checkBox.addSelectionListener(fCheckBoxListener); + + getCheckBoxes().put(checkBox, key); + + return checkBox; + } + + protected Control addTextField(Composite composite, String labelText, String key, int textLimit, int indentation, String[] errorMessages) { + Font font= composite.getFont(); + + Label label= new Label(composite, SWT.NONE); + label.setText(labelText); + label.setFont(font); + GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent= indentation; + label.setLayoutData(gd); + + Text textControl= new Text(composite, SWT.BORDER | SWT.SINGLE); + textControl.setFont(font); + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.widthHint= convertWidthInCharsToPixels(textLimit + 1); + textControl.setLayoutData(gd); + textControl.setTextLimit(textLimit); + getTextFields().put(textControl, key); + if (errorMessages != null) { + getNumberFields().put(textControl, errorMessages); + textControl.addModifyListener(fNumberFieldListener); + } else { + textControl.addModifyListener(fTextFieldListener); + } + + return textControl; + } + + void numberFieldChanged(Text textControl) { + String number= textControl.getText(); + IStatus status= validatePositiveNumber(number, (String[])getNumberFields().get(textControl)); + if (!status.matches(IStatus.ERROR)) { + getOverlayStore().setValue((String) getTextFields().get(textControl), number); + } + updateStatus(status); + } + + private IStatus validatePositiveNumber(String number, String[] errorMessages) { + StatusInfo status= new StatusInfo(); + if (number.length() == 0) { + status.setError(errorMessages[0]); + } else { + try { + int value= Integer.parseInt(number); + if (value < 0) + status.setError(MessageFormat.format(errorMessages[1], new Object[]{number})); //$NON-NLS-1$ + } catch (NumberFormatException e) { + status.setError(MessageFormat.format(errorMessages[1], new Object[]{number})); //$NON-NLS-1$ + } + } + return status; + } + + private void updateStatus(IStatus status) { + if (!status.matches(IStatus.ERROR)) { + Set<Text> keys= getNumberFields().keySet(); + for (Iterator<Text> iter = keys.iterator(); iter.hasNext();) { + Text text = (Text) iter.next(); + IStatus s= validatePositiveNumber(text.getText(), (String[])getNumberFields().get(text)); + status= s.getSeverity() > status.getSeverity() ? s : status; + } + } + setValid(!status.matches(IStatus.ERROR)); + applyToStatusLine(this, status); + } + + /* + * Applies the status to the status line of a dialog page. + */ + private void applyToStatusLine(DialogPage page, IStatus status) { + String message= status.getMessage(); + switch (status.getSeverity()) { + case IStatus.OK: + page.setMessage(message, IMessageProvider.NONE); + page.setErrorMessage(null); + break; + case IStatus.WARNING: + page.setMessage(message, IMessageProvider.WARNING); + page.setErrorMessage(null); + break; + case IStatus.INFO: + page.setMessage(message, IMessageProvider.INFORMATION); + page.setErrorMessage(null); + break; + default: + if (message.length() == 0) { + message= null; + } + page.setMessage(null); + page.setErrorMessage(message); + break; + } + } + + /** + * Returns an array of size 2: + * - first element is of type <code>Label</code> + * - second element is of type <code>Text</code> + * Use <code>getLabelControl</code> and <code>getTextControl</code> to get the 2 controls. + */ + protected Control[] addLabelledTextField(Composite composite, String label, String key, int textLimit, int indentation, String[] errorMessages) { + Label labelControl= new Label(composite, SWT.NONE); + labelControl.setText(label); + labelControl.setFont(composite.getFont()); + GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent= indentation; + labelControl.setLayoutData(gd); + + Text textControl= new Text(composite, SWT.BORDER | SWT.SINGLE); + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.widthHint= convertWidthInCharsToPixels(textLimit + 1); + textControl.setLayoutData(gd); + textControl.setTextLimit(textLimit); + textControl.setFont(composite.getFont()); + fTextFields.put(textControl, key); + if (errorMessages != null) { + fNumberFields.put(textControl, errorMessages); + textControl.addModifyListener(fNumberFieldListener); + } else { + textControl.addModifyListener(fTextFieldListener); + } + + return new Control[]{labelControl, textControl}; + } + + protected String loadPreviewContentFromFile(String filename) { + String line; + String separator= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + StringBuffer buffer= new StringBuffer(512); + BufferedReader reader= null; + try { + reader= new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(filename))); + while ((line= reader.readLine()) != null) { + buffer.append(line); + buffer.append(separator); + } + } catch (IOException io) { + AutotoolsUIPlugin.log(io); + } finally { + if (reader != null) { + try { reader.close(); } catch (IOException e) {} + } + } + return buffer.toString(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutoconfEditorPreferencePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutoconfEditorPreferencePage.java new file mode 100644 index 00000000000..3fda416f901 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutoconfEditorPreferencePage.java @@ -0,0 +1,588 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 2007 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. - modification to use with Autoconf editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.preferences; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.make.ui.IMakeHelpContextIds; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.model.WorkbenchViewerComparator; + + + +/** + * MakeEditorPreferencePage + * The page for setting the editor options. + */ +public class AutoconfEditorPreferencePage extends AbstractEditorPreferencePage { + + private static String[] fACVersions = {"2.13", "2.59", "2.61", "2.68"}; + public static final String LATEST_AC_VERSION = fACVersions[fACVersions.length - 1]; + + private static String[] fAMVersions = {"1.4-p6", "1.9.5", "1.9.6", "1.11.1"}; + public static final String LATEST_AM_VERSION = fAMVersions[fAMVersions.length - 1]; + + /** The keys of the overlay store. */ + private String[][] fSyntaxColorListModel; + + private TableViewer fHighlightingColorListViewer; + private final List<HighlightingColorListItem> fHighlightingColorList= new ArrayList<HighlightingColorListItem>(5); + + ColorEditor fSyntaxForegroundColorEditor; + Button fBoldCheckBox; + Button fItalicCheckBox; + + // folding + protected Button fFoldingCheckbox; + + // version + protected Combo fACVersionCombo; + protected Combo fAMVersionCombo; + + /** + * Item in the highlighting color list. + * + * @since 3.0 + */ + private static class HighlightingColorListItem { + /** Display name */ + private String fDisplayName; + /** Color preference key */ + private String fColorKey; + /** Bold preference key */ + private String fBoldKey; + /** Italic preference key */ + private String fItalicKey; + /** Item color */ + private Color fItemColor; + + /** + * Initialize the item with the given values. + * + * @param displayName the display name + * @param colorKey the color preference key + * @param boldKey the bold preference key + * @param italicKey the italic preference key + * @param itemColor the item color + */ + public HighlightingColorListItem(String displayName, String colorKey, String boldKey, String italicKey, Color itemColor) { + fDisplayName= displayName; + fColorKey= colorKey; + fBoldKey= boldKey; + fItalicKey= italicKey; + fItemColor= itemColor; + } + + /** + * @return the bold preference key + */ + public String getBoldKey() { + return fBoldKey; + } + + /** + * @return the bold preference key + */ + public String getItalicKey() { + return fItalicKey; + } + + /** + * @return the color preference key + */ + public String getColorKey() { + return fColorKey; + } + + /** + * @return the display name + */ + public String getDisplayName() { + return fDisplayName; + } + + /** + * @return the item color + */ + public Color getItemColor() { + return fItemColor; + } + } + + /** + * Color list label provider. + * + * @since 3.0 + */ + private static class ColorListLabelProvider extends LabelProvider implements IColorProvider { + + /* + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + return ((HighlightingColorListItem)element).getDisplayName(); + } + + /* + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element) { + return ((HighlightingColorListItem)element).getItemColor(); + } + + /* + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element) { + return null; + } + } + + /** + * Color list content provider. + * + * @since 3.0 + */ + private static class ColorListContentProvider implements IStructuredContentProvider { + + /* + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + @SuppressWarnings("unchecked") + public Object[] getElements(Object inputElement) { + return ((List<Object>)inputElement).toArray(); + } + + /* + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + + + /** + * + */ + public AutoconfEditorPreferencePage() { + super(); + } + + protected OverlayPreferenceStore createOverlayStore() { + fSyntaxColorListModel= new String[][] { + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_comment"), ColorManager.AUTOCONF_COMMENT_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_acmacro"), ColorManager.AUTOCONF_ACMACRO_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_ammacro"), ColorManager.AUTOCONF_AMMACRO_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_code_seq"), ColorManager.AUTOCONF_CODESEQ_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_keyword"), ColorManager.AUTOCONF_KEYWORD_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_var_ref"), ColorManager.AUTOCONF_VAR_REF_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_var_set"), ColorManager.AUTOCONF_VAR_SET_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.autoconf_editor_default"), ColorManager.AUTOCONF_DEFAULT_COLOR, null}, //$NON-NLS-1$ + }; + ArrayList<OverlayPreferenceStore.OverlayKey> overlayKeys= new ArrayList<OverlayPreferenceStore.OverlayKey>(); + + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_ENABLED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_CONDITIONAL)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_MACRODEF)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_RULE)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION)); + + for (int i= 0; i < fSyntaxColorListModel.length; i++) { + String colorKey= fSyntaxColorListModel[i][1]; + addTextKeyToCover(overlayKeys, colorKey); + } + + OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; + overlayKeys.toArray(keys); + return new OverlayPreferenceStore(getPreferenceStore(), keys); + } + + private void addTextKeyToCover(ArrayList<OverlayPreferenceStore.OverlayKey> overlayKeys, String mainKey) { + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, mainKey)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, mainKey + AutotoolsEditorPreferenceConstants.EDITOR_BOLD_SUFFIX)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, mainKey + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + AutotoolsUIPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(getControl(), IMakeHelpContextIds.MAKE_EDITOR_PREFERENCE_PAGE); + getOverlayStore().load(); + getOverlayStore().start(); + + TabFolder folder= new TabFolder(parent, SWT.NONE); + folder.setLayout(new TabFolderLayout()); + folder.setLayoutData(new GridData(GridData.FILL_BOTH)); + + TabItem item= new TabItem(folder, SWT.NONE); + item.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.syntax")); //$NON-NLS-1$ + item.setControl(createSyntaxPage(folder)); + + item= new TabItem(folder, SWT.NONE); + item.setText(AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.folding")); //$NON-NLS-1$ + item.setControl(createFoldingTabContent(folder)); + + // Allow end-user to select which version of autoconf to use for hover help + // and syntax checking of macros. + item= new TabItem(folder, SWT.NONE); + item.setText(AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.version")); //$NON-NLS-1$ + item.setControl(createVersionTabContent(folder)); + + initialize(); + + applyDialogFont(folder); + return folder; + } + + private void initialize() { + + initializeFields(); + + for (int i= 0, n= fSyntaxColorListModel.length; i < n; i++) { + fHighlightingColorList.add( + new HighlightingColorListItem (fSyntaxColorListModel[i][0], fSyntaxColorListModel[i][1], + fSyntaxColorListModel[i][1] + AutotoolsEditorPreferenceConstants.EDITOR_BOLD_SUFFIX, + fSyntaxColorListModel[i][1] + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX, null)); + } + fHighlightingColorListViewer.setInput(fHighlightingColorList); + fHighlightingColorListViewer.setSelection(new StructuredSelection(fHighlightingColorListViewer.getElementAt(0))); + + for (int i=0, n= fACVersions.length; i < n; i++) { + fACVersionCombo.setItem(i, fACVersions[i]); + } + + initializeFolding(); + initializeACVersion(); + initializeAMVersion(); + } + + void initializeFolding() { + boolean enabled= getOverlayStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + fFoldingCheckbox.setSelection(enabled); + } + + void initializeACVersion() { + // FIXME: What do we do here? There is no PreferenceConstants value for this. + // Perhaps we should be using our own overlay store. + String version = getOverlayStore().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); + } + + void initializeAMVersion() { + // FIXME: What do we do here? There is no PreferenceConstants value for this. + // Perhaps we should be using our own overlay store. + String version = getOverlayStore().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); + } + + void initializeDefaultFolding() { + boolean enabled= getOverlayStore().getDefaultBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + fFoldingCheckbox.setSelection(enabled); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.autotools.ui.preferences.AbstractAutomakeEditorPreferencePage#handleDefaults() + */ + protected void handleDefaults() { + handleSyntaxColorListSelection(); + initializeDefaultFolding(); + } + + private Control createSyntaxPage(Composite parent) { + + Composite colorComposite= new Composite(parent, SWT.NONE); + colorComposite.setLayout(new GridLayout()); + + Label label= new Label(colorComposite, SWT.LEFT); + label.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.Foreground")); //$NON-NLS-1$ + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite editorComposite= new Composite(colorComposite, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + layout.marginHeight= 0; + layout.marginWidth= 0; + editorComposite.setLayout(layout); + GridData gd= new GridData(GridData.FILL_BOTH); + editorComposite.setLayoutData(gd); + + fHighlightingColorListViewer= new TableViewer(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); + fHighlightingColorListViewer.setLabelProvider(new ColorListLabelProvider()); + fHighlightingColorListViewer.setContentProvider(new ColorListContentProvider()); + fHighlightingColorListViewer.setComparator(new WorkbenchViewerComparator()); + gd= new GridData(GridData.FILL_BOTH); + gd.heightHint= convertHeightInCharsToPixels(5); + fHighlightingColorListViewer.getControl().setLayoutData(gd); + + Composite stylesComposite= new Composite(editorComposite, SWT.NONE); + layout= new GridLayout(); + layout.marginHeight= 0; + layout.marginWidth= 0; + layout.numColumns= 2; + stylesComposite.setLayout(layout); + stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + label= new Label(stylesComposite, SWT.LEFT); + label.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.color")); //$NON-NLS-1$ + gd= new GridData(); + gd.horizontalAlignment= GridData.BEGINNING; + label.setLayoutData(gd); + + fSyntaxForegroundColorEditor= new ColorEditor(stylesComposite); + Button foregroundColorButton= fSyntaxForegroundColorEditor.getButton(); + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment= GridData.BEGINNING; + foregroundColorButton.setLayoutData(gd); + + fBoldCheckBox= new Button(stylesComposite, SWT.CHECK); + fBoldCheckBox.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.bold")); //$NON-NLS-1$ + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment= GridData.BEGINNING; + gd.horizontalSpan= 2; + fBoldCheckBox.setLayoutData(gd); + + fItalicCheckBox= new Button(stylesComposite, SWT.CHECK); + fItalicCheckBox.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.italic")); //$NON-NLS-1$ + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment= GridData.BEGINNING; + gd.horizontalSpan= 2; + fItalicCheckBox.setLayoutData(gd); + + fHighlightingColorListViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + handleSyntaxColorListSelection(); + } + }); + + foregroundColorButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + HighlightingColorListItem item= getHighlightingColorListItem(); + PreferenceConverter.setValue(getOverlayStore(), item.getColorKey(), fSyntaxForegroundColorEditor.getColorValue()); + } + }); + + fBoldCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + HighlightingColorListItem item= getHighlightingColorListItem(); + getOverlayStore().setValue(item.getBoldKey(), fBoldCheckBox.getSelection()); + } + }); + + fItalicCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + HighlightingColorListItem item= getHighlightingColorListItem(); + getOverlayStore().setValue(item.getItalicKey(), fItalicCheckBox.getSelection()); + } + }); + + return colorComposite; + } + + + private Composite createFoldingTabContent(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 */ + fFoldingCheckbox= new Button(composite, SWT.CHECK); + fFoldingCheckbox.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.foldingenable")); //$NON-NLS-1$ + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); + fFoldingCheckbox.setLayoutData(gd); + fFoldingCheckbox.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + boolean enabled= fFoldingCheckbox.getSelection(); + getOverlayStore().setValue(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_ENABLED, enabled); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + return composite; + } + + private Composite createVersionTabContent(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(fACVersions); + fACVersionCombo.select(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(); + getOverlayStore().setValue(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION, fACVersionCombo.getItem(index)); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + Label label= new Label(composite, SWT.LEFT); + label.setText(AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.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(fAMVersions); + fAMVersionCombo.select(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(); + getOverlayStore().setValue(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION, fAMVersionCombo.getItem(index)); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + Label label2= new Label(composite, SWT.LEFT); + label2.setText(AutotoolsPreferencesMessages.getString("AutoconfEditorPreferencePage.automakeVersion")); //$NON-NLS-1$ + gd= new GridData(); + gd.horizontalAlignment= GridData.BEGINNING; + label2.setLayoutData(gd); + + return composite; + } + + void handleSyntaxColorListSelection() { + HighlightingColorListItem item= getHighlightingColorListItem(); + RGB rgb= PreferenceConverter.getColor(getOverlayStore(), item.getColorKey()); + fSyntaxForegroundColorEditor.setColorValue(rgb); + fBoldCheckBox.setSelection(getOverlayStore().getBoolean(item.getBoldKey())); + fItalicCheckBox.setSelection(getOverlayStore().getBoolean(item.getItalicKey())); + } + + /** + * Returns the current highlighting color list item. + * + * @return the current highlighting color list item + * @since 3.0 + */ + HighlightingColorListItem getHighlightingColorListItem() { + IStructuredSelection selection= (IStructuredSelection) fHighlightingColorListViewer.getSelection(); + return (HighlightingColorListItem) selection.getFirstElement(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferencePage#performOk() + */ + public boolean performOk() { + return super.performOk(); + } + + /** + * @param preferenceStore + */ + public static void initDefaults(IPreferenceStore prefs) { + // Makefile Editor color preferences + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_COMMENT_COLOR, ColorManager.AUTOCONF_COMMENT_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_DEFAULT_COLOR, ColorManager.AUTOCONF_DEFAULT_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_KEYWORD_COLOR, ColorManager.AUTOCONF_KEYWORD_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_VAR_REF_COLOR, ColorManager.AUTOCONF_VAR_REF_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_VAR_SET_COLOR, ColorManager.AUTOCONF_VAR_SET_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_ACMACRO_COLOR, ColorManager.AUTOCONF_ACMACRO_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_AMMACRO_COLOR, ColorManager.AUTOCONF_AMMACRO_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.AUTOCONF_CODESEQ_COLOR, ColorManager.AUTOCONF_CODESEQ_RGB); + prefs.setDefault(ColorManager.AUTOCONF_CODESEQ_COLOR + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX, true); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutomakeEditorPreferencePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutomakeEditorPreferencePage.java new file mode 100644 index 00000000000..bf08f7f0274 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutomakeEditorPreferencePage.java @@ -0,0 +1,465 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 2007 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. - modification to use with Automake editor + *******************************************************************************/ + +package org.eclipse.cdt.internal.autotools.ui.preferences; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.make.ui.IMakeHelpContextIds; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +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.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.model.WorkbenchViewerComparator; + + + +/** + * MakeEditorPreferencePage + * The page for setting the editor options. + */ +public class AutomakeEditorPreferencePage extends AbstractEditorPreferencePage { + + /** The keys of the overlay store. */ + private String[][] fSyntaxColorListModel; + + private TableViewer fHighlightingColorListViewer; + private final List<HighlightingColorListItem> fHighlightingColorList= new ArrayList<HighlightingColorListItem>(5); + + ColorEditor fSyntaxForegroundColorEditor; + Button fBoldCheckBox; + Button fItalicCheckBox; + + // folding + protected Button fFoldingCheckbox; + + /** + * Item in the highlighting color list. + * + * @since 3.0 + */ + private static class HighlightingColorListItem { + /** Display name */ + private String fDisplayName; + /** Color preference key */ + private String fColorKey; + /** Bold preference key */ + private String fBoldKey; + /** Italic preference key */ + private String fItalicKey; + /** Item color */ + private Color fItemColor; + + /** + * Initialize the item with the given values. + * + * @param displayName the display name + * @param colorKey the color preference key + * @param boldKey the bold preference key + * @param italicKey the italic preference key + * @param itemColor the item color + */ + public HighlightingColorListItem(String displayName, String colorKey, String boldKey, String italicKey, Color itemColor) { + fDisplayName= displayName; + fColorKey= colorKey; + fBoldKey= boldKey; + fItalicKey= italicKey; + fItemColor= itemColor; + } + + /** + * @return the bold preference key + */ + public String getBoldKey() { + return fBoldKey; + } + + /** + * @return the bold preference key + */ + public String getItalicKey() { + return fItalicKey; + } + + /** + * @return the color preference key + */ + public String getColorKey() { + return fColorKey; + } + + /** + * @return the display name + */ + public String getDisplayName() { + return fDisplayName; + } + + /** + * @return the item color + */ + public Color getItemColor() { + return fItemColor; + } + } + + /** + * Color list label provider. + * + * @since 3.0 + */ + private static class ColorListLabelProvider extends LabelProvider implements IColorProvider { + + /* + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + return ((HighlightingColorListItem)element).getDisplayName(); + } + + /* + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element) { + return ((HighlightingColorListItem)element).getItemColor(); + } + + /* + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element) { + return null; + } + } + + /** + * Color list content provider. + * + * @since 3.0 + */ + private static class ColorListContentProvider implements IStructuredContentProvider { + + /* + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + @SuppressWarnings("unchecked") + public Object[] getElements(Object inputElement) { + return ((List<Object>)inputElement).toArray(); + } + + /* + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + + + /** + * + */ + public AutomakeEditorPreferencePage() { + super(); + } + + protected OverlayPreferenceStore createOverlayStore() { + fSyntaxColorListModel= new String[][] { + {AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.makefile_editor_comment"), ColorManager.MAKE_COMMENT_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.makefile_editor_macro_ref"), ColorManager.MAKE_MACRO_REF_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.makefile_editor_macro_def"), ColorManager.MAKE_MACRO_DEF_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.makefile_editor_function"), ColorManager.MAKE_FUNCTION_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.makefile_editor_keyword"), ColorManager.MAKE_KEYWORD_COLOR, null}, //$NON-NLS-1$ + {AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.makefile_editor_default"), ColorManager.MAKE_DEFAULT_COLOR, null}, //$NON-NLS-1$ + }; + ArrayList<OverlayPreferenceStore.OverlayKey> overlayKeys= new ArrayList<OverlayPreferenceStore.OverlayKey>(); + + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_ENABLED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_CONDITIONAL)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_MACRODEF)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_RULE)); + + for (int i= 0; i < fSyntaxColorListModel.length; i++) { + String colorKey= fSyntaxColorListModel[i][1]; + addTextKeyToCover(overlayKeys, colorKey); + } + + OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; + overlayKeys.toArray(keys); + return new OverlayPreferenceStore(getPreferenceStore(), keys); + } + + private void addTextKeyToCover(ArrayList<OverlayPreferenceStore.OverlayKey> overlayKeys, String mainKey) { + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, mainKey)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, mainKey + AutotoolsEditorPreferenceConstants.EDITOR_BOLD_SUFFIX)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, mainKey + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + AutotoolsUIPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(getControl(), IMakeHelpContextIds.MAKE_EDITOR_PREFERENCE_PAGE); + getOverlayStore().load(); + getOverlayStore().start(); + + TabFolder folder= new TabFolder(parent, SWT.NONE); + folder.setLayout(new TabFolderLayout()); + folder.setLayoutData(new GridData(GridData.FILL_BOTH)); + + TabItem item= new TabItem(folder, SWT.NONE); + item.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.syntax")); //$NON-NLS-1$ + item.setControl(createSyntaxPage(folder)); + + item= new TabItem(folder, SWT.NONE); + item.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.folding")); //$NON-NLS-1$ + item.setControl(createFoldingTabContent(folder)); + + initialize(); + + applyDialogFont(folder); + return folder; + } + + private void initialize() { + + initializeFields(); + + for (int i= 0, n= fSyntaxColorListModel.length; i < n; i++) { + fHighlightingColorList.add( + new HighlightingColorListItem (fSyntaxColorListModel[i][0], fSyntaxColorListModel[i][1], + fSyntaxColorListModel[i][1] + AutotoolsEditorPreferenceConstants.EDITOR_BOLD_SUFFIX, + fSyntaxColorListModel[i][1] + AutotoolsEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX, null)); + } + fHighlightingColorListViewer.setInput(fHighlightingColorList); + fHighlightingColorListViewer.setSelection(new StructuredSelection(fHighlightingColorListViewer.getElementAt(0))); + + initializeFolding(); + } + + void initializeFolding() { + boolean enabled= getOverlayStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + fFoldingCheckbox.setSelection(enabled); + } + + void initializeDefaultFolding() { + boolean enabled= getOverlayStore().getDefaultBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + fFoldingCheckbox.setSelection(enabled); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.autotools.ui.preferences.AbstractAutomakeEditorPreferencePage#handleDefaults() + */ + protected void handleDefaults() { + handleSyntaxColorListSelection(); + initializeDefaultFolding(); + } + + private Control createSyntaxPage(Composite parent) { + + Composite colorComposite= new Composite(parent, SWT.NONE); + colorComposite.setLayout(new GridLayout()); + + Label label= new Label(colorComposite, SWT.LEFT); + label.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.Foreground")); //$NON-NLS-1$ + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite editorComposite= new Composite(colorComposite, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + layout.marginHeight= 0; + layout.marginWidth= 0; + editorComposite.setLayout(layout); + GridData gd= new GridData(GridData.FILL_BOTH); + editorComposite.setLayoutData(gd); + + fHighlightingColorListViewer= new TableViewer(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); + fHighlightingColorListViewer.setLabelProvider(new ColorListLabelProvider()); + fHighlightingColorListViewer.setContentProvider(new ColorListContentProvider()); + fHighlightingColorListViewer.setComparator(new WorkbenchViewerComparator()); + gd= new GridData(GridData.FILL_BOTH); + gd.heightHint= convertHeightInCharsToPixels(5); + fHighlightingColorListViewer.getControl().setLayoutData(gd); + + Composite stylesComposite= new Composite(editorComposite, SWT.NONE); + layout= new GridLayout(); + layout.marginHeight= 0; + layout.marginWidth= 0; + layout.numColumns= 2; + stylesComposite.setLayout(layout); + stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + label= new Label(stylesComposite, SWT.LEFT); + label.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.color")); //$NON-NLS-1$ + gd= new GridData(); + gd.horizontalAlignment= GridData.BEGINNING; + label.setLayoutData(gd); + + fSyntaxForegroundColorEditor= new ColorEditor(stylesComposite); + Button foregroundColorButton= fSyntaxForegroundColorEditor.getButton(); + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment= GridData.BEGINNING; + foregroundColorButton.setLayoutData(gd); + + fBoldCheckBox= new Button(stylesComposite, SWT.CHECK); + fBoldCheckBox.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.bold")); //$NON-NLS-1$ + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment= GridData.BEGINNING; + gd.horizontalSpan= 2; + fBoldCheckBox.setLayoutData(gd); + + fItalicCheckBox= new Button(stylesComposite, SWT.CHECK); + fItalicCheckBox.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.italic")); //$NON-NLS-1$ + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalAlignment= GridData.BEGINNING; + gd.horizontalSpan= 2; + fItalicCheckBox.setLayoutData(gd); + + fHighlightingColorListViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + handleSyntaxColorListSelection(); + } + }); + + foregroundColorButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + HighlightingColorListItem item= getHighlightingColorListItem(); + PreferenceConverter.setValue(getOverlayStore(), item.getColorKey(), fSyntaxForegroundColorEditor.getColorValue()); + } + }); + + fBoldCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + HighlightingColorListItem item= getHighlightingColorListItem(); + getOverlayStore().setValue(item.getBoldKey(), fBoldCheckBox.getSelection()); + } + }); + + fItalicCheckBox.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // do nothing + } + public void widgetSelected(SelectionEvent e) { + HighlightingColorListItem item= getHighlightingColorListItem(); + getOverlayStore().setValue(item.getItalicKey(), fItalicCheckBox.getSelection()); + } + }); + + return colorComposite; + } + + + private Composite createFoldingTabContent(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 */ + fFoldingCheckbox= new Button(composite, SWT.CHECK); + fFoldingCheckbox.setText(AutotoolsPreferencesMessages.getString("AutomakeEditorPreferencePage.foldingenable")); //$NON-NLS-1$ + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); + fFoldingCheckbox.setLayoutData(gd); + fFoldingCheckbox.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + boolean enabled= fFoldingCheckbox.getSelection(); + getOverlayStore().setValue(AutotoolsEditorPreferenceConstants.EDITOR_FOLDING_ENABLED, enabled); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + return composite; + } + + void handleSyntaxColorListSelection() { + HighlightingColorListItem item= getHighlightingColorListItem(); + RGB rgb= PreferenceConverter.getColor(getOverlayStore(), item.getColorKey()); + fSyntaxForegroundColorEditor.setColorValue(rgb); + fBoldCheckBox.setSelection(getOverlayStore().getBoolean(item.getBoldKey())); + fItalicCheckBox.setSelection(getOverlayStore().getBoolean(item.getItalicKey())); + } + + /** + * Returns the current highlighting color list item. + * + * @return the current highlighting color list item + * @since 3.0 + */ + HighlightingColorListItem getHighlightingColorListItem() { + IStructuredSelection selection= (IStructuredSelection) fHighlightingColorListViewer.getSelection(); + return (HighlightingColorListItem) selection.getFirstElement(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferencePage#performOk() + */ + public boolean performOk() { + return super.performOk(); + } + + /** + * @param preferenceStore + */ + public static void initDefaults(IPreferenceStore prefs) { + // Makefile Editor color preferences + PreferenceConverter.setDefault(prefs, ColorManager.MAKE_COMMENT_COLOR, ColorManager.MAKE_COMMENT_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.MAKE_DEFAULT_COLOR, ColorManager.MAKE_DEFAULT_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.MAKE_FUNCTION_COLOR, ColorManager.MAKE_FUNCTION_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.MAKE_KEYWORD_COLOR, ColorManager.MAKE_KEYWORD_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.MAKE_MACRO_DEF_COLOR, ColorManager.MAKE_MACRO_DEF_RGB); + PreferenceConverter.setDefault(prefs, ColorManager.MAKE_MACRO_REF_COLOR, ColorManager.MAKE_MACRO_REF_RGB); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java new file mode 100644 index 00000000000..751bf30dbf6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsEditorPreferenceConstants.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * 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.cdt.internal.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.cdt.autotools.ui.automake.currentLineHightlightColor"; //$NON-NLS-1$ + public static final String LINE_NUMBER_RULER_COLOR = "org.eclipse.cdt.autotools.ui.automake.lineNumberForegroundColor"; //$NON-NLS-1$ + public static final String PRINT_MARGIN_COLOR = "org.eclipse.cdt.autotools.ui.automake.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"; + + public static final String AUTOMAKE_VERSION = "automake_version"; + + 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, AutoconfEditorPreferencePage.LATEST_AC_VERSION); + store.setDefault(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION, AutoconfEditorPreferencePage.LATEST_AM_VERSION); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencePage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencePage.java new file mode 100644 index 00000000000..3300e00eb96 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencePage.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006, 2009 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.preferences; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + + +public class AutotoolsPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + private static final String PREF_BUILD_TARGET_IN_BACKGROUND = "MakeTargetPrefs.buildTargetInBackground"; //$NON-NLS-1$ + private static final String TARGET_BUILDS_IN_BACKGROUND = "MakeTargetPreferencePage.buildTargetInBackground.label"; //$NON-NLS-1$ + + public AutotoolsPreferencePage() { + super(GRID); + setPreferenceStore(AutotoolsPlugin.getDefault().getPreferenceStore()); + } + + /** + * @see FieldEditorPreferencePage#createControl(Composite) + */ + protected void createFieldEditors() { + Composite parent = getFieldEditorParent(); + + BooleanFieldEditor targetBackgroundEditor = new BooleanFieldEditor(PREF_BUILD_TARGET_IN_BACKGROUND, + AutotoolsUIPlugin.getResourceString(TARGET_BUILDS_IN_BACKGROUND), parent); + addField(targetBackgroundEditor); + } + + public static boolean isBuildTargetInBackground() { + return AutotoolsPlugin.getDefault().getPreferenceStore().getBoolean(PREF_BUILD_TARGET_IN_BACKGROUND); + } + + public static void setBuildTargetInBackground(boolean enable) { + AutotoolsPlugin.getDefault().getPreferenceStore().setValue(PREF_BUILD_TARGET_IN_BACKGROUND, enable); + } + + /** + * Initializes the default values of this page in the preference bundle. + */ + public static void initDefaults(IPreferenceStore prefs) { + prefs.setDefault(PREF_BUILD_TARGET_IN_BACKGROUND, true); + } + + public void init(IWorkbench workbench) { + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencesMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencesMessages.java new file mode 100644 index 00000000000..4bf5211d3a5 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencesMessages.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 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.cdt.internal.autotools.ui.preferences; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * MakefilePreferencesMessages + */ +public class AutotoolsPreferencesMessages { + + /** + * + */ + private AutotoolsPreferencesMessages() { + } + + private static final String BUNDLE_NAME = AutotoolsPreferencesMessages.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencesMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencesMessages.properties new file mode 100644 index 00000000000..40b53806839 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/AutotoolsPreferencesMessages.properties @@ -0,0 +1,108 @@ +############################################################################### +# Copyright (c) 2000, 2006, 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 Corporation - initial API and implementation +# Red Hat Inc. - convert for usage with Automake and Autoconf editors +############################################################################### + +AutomakeEditorPreferencePage.description=Automake Editor settings: +AutomakeEditorPreferencePage.invalid_input_print_margin= Invalid print margin column specified +AutomakeEditorPreferencePage.empty_input_print_margin= No print margin column specified +AutomakeEditorPreferencePage.appearance=Appeara&nce +AutomakeEditorPreferencePage.printMarginColumn=Print margin col&umn: +AutomakeEditorPreferencePage.showOverviewRuler=Show overview &ruler +AutomakeEditorPreferencePage.showLineNumbers=Show lin&e numbers +AutomakeEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line +AutomakeEditorPreferencePage.showPrintMargin=Sho&w print margin +AutomakeEditorPreferencePage.color=C&olor: +AutomakeEditorPreferencePage.appearanceOptions=Appearance co&lor options: +AutomakeEditorPreferencePage.lineNumberForegroundColor=Line number foreground +AutomakeEditorPreferencePage.currentLineHighlighColor=Current line highlight +AutomakeEditorPreferencePage.printMarginColor=Print margin +AutomakeEditorPreferencePage.Makefile_editor_text_1=Text +AutomakeEditorPreferencePage.Makefile_editor_processing_instuctions_2=Processing instructions +AutomakeEditorPreferencePage.Makefile_editor_constMakefile_strings_3=ConstMakefile strings +AutomakeEditorPreferencePage.Makefile_editor_tags_4=Tags +AutomakeEditorPreferencePage.Makefile_editor_comments_5=Comments +AutomakeEditorPreferencePage.tabwidth=Displayed &tab width: +AutomakeEditorPreferencePage.notabwidth=No tab width specified +AutomakeEditorPreferencePage.39=Invalid tab width specified +AutomakeEditorPreferencePage.systemdefault=System de&fault +AutomakeEditorPreferencePage.spacetabs=&Insert spaces for tabs when typing +AutomakeEditorPreferencePage.foreground= Selection foreground color +AutomakeEditorPreferencePage.background= Selection background color +AutomakeEditorPreferencePage.syntax=Synta&x +AutomakeEditorPreferencePage.backcolor=Background color +AutomakeEditorPreferencePage.custom=C&ustom: +AutomakeEditorPreferencePage.Foreground=Fore&ground: +AutomakeEditorPreferencePage.bold=&Bold +AutomakeEditorPreferencePage.italic=I&talic + +AutomakeEditorPreferencePage.folding= &Folding +AutomakeEditorPreferencePage.foldingenable= Enable folding when &opening a new editor + +AutomakeEditorPreferencePage.makefile_editor_comment=comment +AutomakeEditorPreferencePage.makefile_editor_macro_def=macro definition +AutomakeEditorPreferencePage.makefile_editor_macro_ref=macro reference +AutomakeEditorPreferencePage.makefile_editor_function=function +AutomakeEditorPreferencePage.makefile_editor_keyword=keyword +AutomakeEditorPreferencePage.makefile_editor_target=target +AutomakeEditorPreferencePage.makefile_editor_default=default + + +AutomakeSettingsPreferencePage.style=Style of Makefile +AutomakeSettingsPreferencePage.path.label=Makefile include directories +AutomakeSettingsPreferencePage.path.browse=directory + +AutoconfEditorPreferencePage.description=Autoconf Editor settings: +AutoconfEditorPreferencePage.invalid_input_print_margin= Invalid print margin column specified +AutoconfEditorPreferencePage.empty_input_print_margin= No print margin column specified +AutoconfEditorPreferencePage.appearance=Appeara&nce +AutoconfEditorPreferencePage.printMarginColumn=Print margin col&umn: +AutoconfEditorPreferencePage.showOverviewRuler=Show overview &ruler +AutoconfEditorPreferencePage.showLineNumbers=Show lin&e numbers +AutoconfEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line +AutoconfEditorPreferencePage.showPrintMargin=Sho&w print margin +AutoconfEditorPreferencePage.color=C&olor: +AutoconfEditorPreferencePage.appearanceOptions=Appearance co&lor options: +AutoconfEditorPreferencePage.lineNumberForegroundColor=Line number foreground +AutoconfEditorPreferencePage.currentLineHighlighColor=Current line highlight +AutoconfEditorPreferencePage.printMarginColor=Print margin +AutoconfEditorPreferencePage.Makefile_editor_text_1=Text +AutoconfEditorPreferencePage.Makefile_editor_processing_instuctions_2=Processing instructions +AutoconfEditorPreferencePage.Makefile_editor_constMakefile_strings_3=ConstMakefile strings +AutoconfEditorPreferencePage.Makefile_editor_tags_4=Tags +AutoconfEditorPreferencePage.Makefile_editor_comments_5=Comments +AutoconfEditorPreferencePage.tabwidth=Displayed &tab width: +AutoconfEditorPreferencePage.notabwidth=No tab width specified +AutoconfEditorPreferencePage.39=Invalid tab width specified +AutoconfEditorPreferencePage.systemdefault=System de&fault +AutoconfEditorPreferencePage.spacetabs=&Insert spaces for tabs when typing +AutoconfEditorPreferencePage.foreground= Selection foreground color +AutoconfEditorPreferencePage.background= Selection background color +AutoconfEditorPreferencePage.syntax=Synta&x +AutoconfEditorPreferencePage.backcolor=Background color +AutoconfEditorPreferencePage.custom=C&ustom: +AutoconfEditorPreferencePage.Foreground=Fore&ground: +AutoconfEditorPreferencePage.bold=&Bold +AutoconfEditorPreferencePage.italic=I&talic + +AutoconfEditorPreferencePage.folding= &Folding +AutoconfEditorPreferencePage.foldingenable= Enable folding when &opening a new editor + +AutoconfEditorPreferencePage.version= &Version +AutoconfEditorPreferencePage.autoconfVersion = Default version of Autoconf to use for syntax checking +AutoconfEditorPreferencePage.automakeVersion = Default version of Automake to use for syntax checking +AutoconfEditorPreferencePage.autoconf_editor_comment=comment +AutoconfEditorPreferencePage.autoconf_editor_acmacro=autoconf macro +AutoconfEditorPreferencePage.autoconf_editor_ammacro=automake macro +AutoconfEditorPreferencePage.autoconf_editor_var_ref=variable reference +AutoconfEditorPreferencePage.autoconf_editor_keyword=keyword +AutoconfEditorPreferencePage.autoconf_editor_var_set=variable set +AutoconfEditorPreferencePage.autoconf_editor_code_seq=inlined code sequence +AutoconfEditorPreferencePage.autoconf_editor_default=default
\ No newline at end of file diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/ColorEditor.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/ColorEditor.java new file mode 100644 index 00000000000..fbb1cd13084 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/ColorEditor.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.preferences; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; + +/** + * A "button" of a certain color determined by the color picker + */ +public class ColorEditor { + + private Point fExtent; + Image fImage; + RGB fColorValue; + Color fColor; + Button fButton; + + public ColorEditor(Composite parent) { + + fButton= new Button(parent, SWT.PUSH); + fExtent= computeImageSize(parent); + fImage= new Image(parent.getDisplay(), fExtent.x, fExtent.y); + + GC gc= new GC(fImage); + gc.setBackground(fButton.getBackground()); + gc.fillRectangle(0, 0, fExtent.x, fExtent.y); + gc.dispose(); + + fButton.setImage(fImage); + fButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + ColorDialog colorDialog= new ColorDialog(fButton.getShell()); + colorDialog.setRGB(fColorValue); + RGB newColor = colorDialog.open(); + if (newColor != null) { + fColorValue= newColor; + updateColorImage(); + } + } + }); + + fButton.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + if (fImage != null) { + fImage.dispose(); + fImage= null; + } + if (fColor != null) { + fColor.dispose(); + fColor= null; + } + } + }); + } + + public RGB getColorValue() { + return fColorValue; + } + + public void setColorValue(RGB rgb) { + fColorValue= rgb; + updateColorImage(); + } + + public Button getButton() { + return fButton; + } + + protected void updateColorImage() { + + Display display= fButton.getDisplay(); + + GC gc= new GC(fImage); + gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); + gc.drawRectangle(0, 2, fExtent.x - 1, fExtent.y - 4); + + if (fColor != null) + fColor.dispose(); + + fColor= new Color(display, fColorValue); + gc.setBackground(fColor); + gc.fillRectangle(1, 3, fExtent.x - 2, fExtent.y - 5); + gc.dispose(); + + fButton.setImage(fImage); + } + + protected Point computeImageSize(Control window) { + GC gc= new GC(window); + Font f= JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT); + gc.setFont(f); + int height= gc.getFontMetrics().getHeight(); + gc.dispose(); + Point p= new Point(height * 3 - 6, height); + return p; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/ColorManager.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/ColorManager.java new file mode 100644 index 00000000000..3f26bf03ddb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/ColorManager.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.preferences; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.jface.text.source.ISharedTextColors; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class ColorManager implements ISharedTextColors { + + public static final String MAKE_COMMENT_COLOR ="org.eclipse.cdt.autotools.ui.automake.editor.comment"; //$NON-NLS-1$ + public static final String MAKE_KEYWORD_COLOR = "org.eclipse.cdt.autotools.ui.automake.editor.keyword"; //$NON-NLS-1$ + public static final String MAKE_FUNCTION_COLOR = "org.eclipse.cdt.autotools.ui.automake.editor.function"; //$NON-NLS-1$ + public static final String MAKE_MACRO_REF_COLOR = "org.eclipse.cdt.autotools.ui.automake.editor.macro_ref"; //$NON-NLS-1$ + public static final String MAKE_MACRO_DEF_COLOR = "org.eclipse.cdt.autotools.ui.automake.editor.macro_def"; //$NON-NLS-1$ + public static final String MAKE_DEFAULT_COLOR = "org.eclipse.cdt.autotools.ui.automake.editor.default"; //$NON-NLS-1$ + + public static final String AUTOCONF_COMMENT_COLOR ="org.eclipse.cdt.autotools.ui.autoconf.editor.comment"; //$NON-NLS-1$ + public static final String AUTOCONF_KEYWORD_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.keyword"; //$NON-NLS-1$ + public static final String AUTOCONF_VAR_REF_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.var_ref"; //$NON-NLS-1$ + public static final String AUTOCONF_VAR_SET_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.var_set"; //$NON-NLS-1$ + public static final String AUTOCONF_ACMACRO_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.acmacro"; //$NON-NLS-1$ + public static final String AUTOCONF_AMMACRO_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.ammacro"; //$NON-NLS-1$ + public static final String AUTOCONF_CODESEQ_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.codeseq"; //$NON-NLS-1$ + public static final String AUTOCONF_DEFAULT_COLOR = "org.eclipse.cdt.autotools.ui.autoconf.editor.default"; //$NON-NLS-1$ + + public static final RGB MAKE_COMMENT_RGB = new RGB(128, 0, 0); + public static final RGB MAKE_KEYWORD_RGB = new RGB(128, 255, 0); + public static final RGB MAKE_FUNCTION_RGB = new RGB(128, 0, 128); + public static final RGB MAKE_MACRO_DEF_RGB = new RGB(0, 0, 128); + public static final RGB MAKE_MACRO_REF_RGB = new RGB(0, 128, 0); + public static final RGB MAKE_DEFAULT_RGB = new RGB(0, 0, 0); + + public static final RGB AUTOCONF_COMMENT_RGB = new RGB(63, 95, 191); + public static final RGB AUTOCONF_KEYWORD_RGB = new RGB(127, 0, 85); + public static final RGB AUTOCONF_VAR_REF_RGB = new RGB(128, 0, 0); + public static final RGB AUTOCONF_VAR_SET_RGB = new RGB(255, 101, 52); + public static final RGB AUTOCONF_ACMACRO_RGB = new RGB(0, 0, 128); + public static final RGB AUTOCONF_AMMACRO_RGB = new RGB(0, 128, 0); + public static final RGB AUTOCONF_CODESEQ_RGB = new RGB(0, 100, 0); + public static final RGB AUTOCONF_DEFAULT_RGB = new RGB(0, 0, 0); + + private static ColorManager fgColorManager; + + private ColorManager() { + } + + public static ColorManager getDefault() { + if (fgColorManager == null) { + fgColorManager= new ColorManager(); + } + return fgColorManager; + } + + protected Map<RGB, Color> fColorTable = new HashMap<RGB, Color>(10); + + /** + * @see IMakefileColorManager#dispose() + */ + public void dispose() { + Iterator<Color> e = fColorTable.values().iterator(); + while (e.hasNext()) + ((Color) e.next()).dispose(); + } + + /** + * @see IMakefileColorManager#getColor(RGB) + */ + public Color getColor(RGB rgb) { + Color color = (Color) fColorTable.get(rgb); + if (color == null) { + color = new Color(Display.getCurrent(), rgb); + fColorTable.put(rgb, color); + } + return color; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/OverlayPreferenceStore.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/OverlayPreferenceStore.java new file mode 100644 index 00000000000..0f85ee41030 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/StatusInfo.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/StatusInfo.java new file mode 100644 index 00000000000..745e7796998 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/StatusInfo.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 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.cdt.internal.autotools.ui.preferences; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; + + +/** + * 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 AutotoolsUIPlugin.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]; + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/TabFolderLayout.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/TabFolderLayout.java new file mode 100644 index 00000000000..ad70f80d5e9 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/preferences/TabFolderLayout.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.preferences; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; + +public class TabFolderLayout extends Layout { + + protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) { + if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) + return new Point(wHint, hHint); + + Control [] children = composite.getChildren (); + int count = children.length; + int maxWidth = 0, maxHeight = 0; + for (int i=0; i<count; i++) { + Control child = children [i]; + Point pt = child.computeSize (SWT.DEFAULT, SWT.DEFAULT, flushCache); + maxWidth = Math.max (maxWidth, pt.x); + maxHeight = Math.max (maxHeight, pt.y); + } + + if (wHint != SWT.DEFAULT) + maxWidth= wHint; + if (hHint != SWT.DEFAULT) + maxHeight= hHint; + + return new Point(maxWidth, maxHeight); + + } + + protected void layout (Composite composite, boolean flushCache) { + Rectangle rect= composite.getClientArea(); + + Control[] children = composite.getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].setBounds(rect); + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AbstractConfigurePropertyOptionsPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AbstractConfigurePropertyOptionsPage.java new file mode 100644 index 00000000000..a36f502b78f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AbstractConfigurePropertyOptionsPage.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.PropertyChangeEvent; + +public abstract class AbstractConfigurePropertyOptionsPage extends + FieldEditorPreferencePage { + + private boolean dirty = false; + private String name; + + protected AbstractConfigurePropertyOptionsPage(String name) { + this(GRID); + this.name = name; + } + + protected String getName() { + return name; + } + + protected AbstractConfigurePropertyOptionsPage(int style) { + super(style); + noDefaultAndApplyButton(); + } + + @Override + protected void createFieldEditors() { + // Get the preference store for the build settings + IPreferenceStore settings = getConfigurePrefStore(); + setPreferenceStore(settings); + } + + /** + * Return the tool settings preference store + */ + protected AutotoolsConfigurePrefStore getConfigurePrefStore() { + return AutotoolsConfigurePrefStore.getInstance(); + } + + /** + * Method called when the value of a dialog field changes + */ + public void propertyChange(PropertyChangeEvent event) { + super.propertyChange(event); + if (event.getProperty().equals(FieldEditor.VALUE)) { + setDirty(true); + } + } + + public void setDirty(boolean b) { dirty = b; } + public boolean isDirty() { return dirty; } + public void storeSettings() { super.performOk(); } + + public abstract void updateFields(); + public abstract void setValues(); + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsBuildPropertyPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsBuildPropertyPage.java new file mode 100644 index 00000000000..16ee860a488 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsBuildPropertyPage.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.core.settings.model.ICResourceDescription; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.managedbuilder.ui.properties.AbstractCBuildPropertyTab; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +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 CLEAN_DELETE_LABEL = "CleanDelete.label"; // $NON-NLS-1$ + private String CLEAN_MAKE_LABEL = "CleanMake.label"; // $NON-NLS-1$ + private String CLEAN_MAKETARGET_LABEL = "CleanMakeTarget.label"; // $NON-NLS-1$ + private String CLEAN_MAKETARGET_TOOLTIP = "CleanMakeTarget.tooltip"; // $NON-NLS-1$ + private String AUTO_BUILDNAME_LABEL = "AutoBuildName.label"; // $NON-NLS-1$ + private String AUTO_BUILDNAME_TOOLTIP = "AutoBuildName.tooltip"; // $NON-NLS-1$ + + protected Button fCleanDelete; + protected Button fCleanMake; + protected Button fAutoName; + protected Text fCleanMakeTarget; + + private IProject getProject() { + return (IProject)getCfg().getManagedProject().getOwner(); + } + + public boolean canBeVisible() { + return AutotoolsPlugin.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(CLEAN_DELETE_LABEL)); + gd= new GridData(); + gd.horizontalAlignment= GridData.BEGINNING; + gd.horizontalSpan = 2; + fCleanDelete.setLayoutData(gd); + fCleanMake = new Button(g, SWT.RADIO); + fCleanMake.setText(AutotoolsPropertyMessages.getString(CLEAN_MAKE_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(CLEAN_MAKETARGET_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); + fCleanMakeTarget.setToolTipText(AutotoolsPropertyMessages.getString(CLEAN_MAKETARGET_TOOLTIP)); + 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? + } + } + }); + + fAutoName = new Button(composite, SWT.LEFT | SWT.CHECK); + fAutoName.setText(AutotoolsPropertyMessages.getString(AUTO_BUILDNAME_LABEL)); + fAutoName.setToolTipText(AutotoolsPropertyMessages.getString(AUTO_BUILDNAME_TOOLTIP)); + gd= new GridData(); + gd.horizontalAlignment= GridData.BEGINNING; + gd.horizontalSpan = 2; + fAutoName.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? + } + } + + if (fAutoName.getSelection()) { + try { + project.setPersistentProperty(AutotoolsPropertyConstants.AUTO_BUILD_NAME, TRUE); + } catch (CoreException ce) { + // FIXME: what can we do here? + } + } else { + try { + project.setPersistentProperty(AutotoolsPropertyConstants.AUTO_BUILD_NAME, FALSE); + } catch (CoreException ce) { + // 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); + fAutoName.setEnabled(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 autoName = null; + String cleanMakeTarget = null; + try { + cleanDelete = project.getPersistentProperty(AutotoolsPropertyConstants.CLEAN_DELETE); + cleanMakeTarget = project.getPersistentProperty(AutotoolsPropertyConstants.CLEAN_MAKE_TARGET); + autoName = project.getPersistentProperty(AutotoolsPropertyConstants.AUTO_BUILD_NAME); + } 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 (autoName == null || autoName.equals(TRUE)) + fAutoName.setSelection(true); + else + fAutoName.setSelection(false); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsCategoryPropertyOptionPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsCategoryPropertyOptionPage.java new file mode 100644 index 00000000000..0746923dab2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsCategoryPropertyOptionPage.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.cdt.internal.autotools.ui.properties; + +import java.util.ArrayList; + +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +public class AutotoolsCategoryPropertyOptionPage extends + AbstractConfigurePropertyOptionsPage { + + private String catName = ""; + private IAConfiguration cfg; + // Label class for a preference page. + static class LabelFieldEditor extends FieldEditor { + private String fTitle; + private Label fTitleLabel; + + public LabelFieldEditor( Composite parent, String title ) { + fTitle = title; + this.createControl( parent ); + } + + protected void adjustForNumColumns( int numColumns ) { + ((GridData)fTitleLabel.getLayoutData()).horizontalSpan = 2; + } + + protected void doFillIntoGrid( Composite parent, int numColumns ) { + fTitleLabel = new Label( parent, SWT.WRAP ); + fTitleLabel.setText( fTitle ); + GridData gd = new GridData(); + gd.verticalAlignment = SWT.TOP; + gd.grabExcessHorizontalSpace = false; + gd.horizontalSpan = 2; + fTitleLabel.setLayoutData( gd ); + } + + public int getNumberOfControls() { return 1; } + /** + * The label field editor is only used to present a text label on a preference page. + */ + protected void doLoad() {} + protected void doLoadDefault() {} + protected void doStore() {} + } + + private ArrayList<FieldEditor> fieldEditors; + + public AutotoolsCategoryPropertyOptionPage(ToolListElement element, IAConfiguration cfg) { + super(element.getName()); + this.catName = element.getName(); + this.cfg = cfg; + fieldEditors = new ArrayList<FieldEditor>(); + } + + public String getName() { + return super.getName(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() + */ + protected void createFieldEditors() { + super.createFieldEditors(); + Composite parent = getFieldEditorParent(); +// FontMetrics fm = AbstractCPropertyTab.getFontMetrics(parent); + AutotoolsConfiguration.Option[] options = AutotoolsConfiguration.getChildOptions(catName); + for (int i = 0; i < options.length; ++i) { + AutotoolsConfiguration.Option option = options[i]; + switch (option.getType()) { + case IConfigureOption.STRING: + case IConfigureOption.INTERNAL: + case IConfigureOption.MULTIARG: + parent = getFieldEditorParent(); + StringFieldEditor f = new StringFieldEditor(option.getName(), option.getDescription(), 20, parent); + f.getLabelControl(parent).setToolTipText(option.getToolTip()); + addField(f); + fieldEditors.add(f); + break; + case IConfigureOption.BIN: + case IConfigureOption.FLAGVALUE: + parent = getFieldEditorParent(); + BooleanFieldEditor b = new BooleanFieldEditor(option.getName(), option.getDescription(), parent); + b.getDescriptionControl(parent).setToolTipText(option.getToolTip()); + addField(b); + fieldEditors.add(b); + break; + case IConfigureOption.FLAG: + parent = getFieldEditorParent(); + FieldEditor l = createLabelEditor(parent, option.getName()); + addField(l); + fieldEditors.add(l); + break; + } + } + } + + protected FieldEditor createLabelEditor( Composite parent, String title ) { + return new LabelFieldEditor( parent, title ); + } + + /** + * Update the field editor that displays all the build options + */ + public void updateFields() { + setValues(); + } + + public void setValues() { + for (int i = 0; i < fieldEditors.size(); ++i) { + fieldEditors.get(i).load(); + } + } + + public void propertyChange(PropertyChangeEvent event) { + // allow superclass to handle as well + super.propertyChange(event); + + if (event.getSource() instanceof StringFieldEditor) { + StringFieldEditor f = (StringFieldEditor)event.getSource(); + cfg.setOption(f.getPreferenceName(), f.getStringValue()); + } else if (event.getSource() instanceof BooleanFieldEditor) { + BooleanFieldEditor b = (BooleanFieldEditor)event.getSource(); + cfg.setOption(b.getPreferenceName(), Boolean.toString(b.getBooleanValue())); + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePrefStore.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePrefStore.java new file mode 100644 index 00000000000..43b3315bc66 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePrefStore.java @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; + +/** + * @author jjohnstn + * + */ +public class AutotoolsConfigurePrefStore implements IPreferenceStore { + + public final static String EMPTY_STRING = ""; + public final static String ALL_OPTIONS_ID = EMPTY_STRING; + + private static AutotoolsConfigurePrefStore instance = null; + private ToolListElement selectedElement; + private IAConfiguration cfg; + private ListenerList listenerList = new ListenerList(); + private boolean isdirty; + + private AutotoolsConfigurePrefStore() { + // private constructor + } + + public static AutotoolsConfigurePrefStore getInstance() { + if (instance == null) + instance = new AutotoolsConfigurePrefStore(); + return instance; + } + + public void setSelection(IAConfiguration cfg, ToolListElement element) { + this.cfg = cfg; + selectedElement = element; + } + + /* (non-Javadoc) + * + * @see org.eclipse.jface.preference.IPreferenceStore#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener) + */ + public void addPropertyChangeListener(IPropertyChangeListener listener) { + listenerList.add(listener); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#contains(java.lang.String) + */ + public boolean contains(String name) { + return cfg.getOption(name) != null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#firePropertyChangeEvent(java.lang.String, java.lang.Object, java.lang.Object) + */ + public void firePropertyChangeEvent(String name, Object oldValue, + Object newValue) { + Object[] listeners = listenerList.getListeners(); + if (listeners.length > 0 && (oldValue == null || !oldValue.equals(newValue))) + { + PropertyChangeEvent pe = new PropertyChangeEvent(this, name, oldValue, newValue); + for (int i = 0; i < listeners.length; ++i) + { + IPropertyChangeListener l = (IPropertyChangeListener)listeners[i]; + l.propertyChange( pe ); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getBoolean(java.lang.String) + */ + public boolean getBoolean(String name) { + IConfigureOption option = cfg.getOption(name); + if (option != null && (option.getType() == IConfigureOption.BIN || + option.getType() == IConfigureOption.FLAGVALUE)) { + return Boolean.parseBoolean(option.getValue()); + } + // otherwise punt + return getDefaultBoolean(name); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultBoolean(java.lang.String) + */ + public boolean getDefaultBoolean(String name) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultDouble(java.lang.String) + */ + public double getDefaultDouble(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultFloat(java.lang.String) + */ + public float getDefaultFloat(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultInt(java.lang.String) + */ + public int getDefaultInt(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultLong(java.lang.String) + */ + public long getDefaultLong(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultString(java.lang.String) + */ + public String getDefaultString(String name) { + return EMPTY_STRING; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getDouble(java.lang.String) + */ + public double getDouble(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getFloat(java.lang.String) + */ + public float getFloat(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getInt(java.lang.String) + */ + public int getInt(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getLong(java.lang.String) + */ + public long getLong(String name) { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#getString(java.lang.String) + */ + public String getString(String name) { + if (name.equals(ALL_OPTIONS_ID) && selectedElement.getType() == IConfigureOption.TOOL) { + return cfg.getToolParameters(selectedElement.getName()); + } + IConfigureOption option = cfg.getOption(name); + if (option != null) { + return option.getValue(); + } + // otherwise punt + return getDefaultString(name); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#isDefault(java.lang.String) + */ + public boolean isDefault(String name) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#needsSaving() + */ + public boolean needsSaving() { + return isdirty; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#putValue(java.lang.String, java.lang.String) + */ + public void putValue(String name, String value) { + setValue(name, value); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener) + */ + public void removePropertyChangeListener(IPropertyChangeListener listener) { + listenerList.remove(listener); + } + + protected void setDirty(boolean isdirty) { + this.isdirty = isdirty; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, double) + */ + public void setDefault(String name, double value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, float) + */ + public void setDefault(String name, float value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, int) + */ + public void setDefault(String name, int value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, long) + */ + public void setDefault(String name, long value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, java.lang.String) + */ + public void setDefault(String name, String defaultObject) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, boolean) + */ + public void setDefault(String name, boolean value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setToDefault(java.lang.String) + */ + public void setToDefault(String name) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, double) + */ + public void setValue(String name, double value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, float) + */ + public void setValue(String name, float value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, int) + */ + public void setValue(String name, int value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, long) + */ + public void setValue(String name, long value) {} + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, java.lang.String) + */ + public void setValue(String name, String value) { + IConfigureOption option = cfg.getOption(name); + if (option != null) + option.setValue(value); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, boolean) + */ + public void setValue(String name, boolean value) { + IConfigureOption option = cfg.getOption(name); + if (option != null) + option.setValue(Boolean.toString(value)); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePropertyPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePropertyPage.java new file mode 100644 index 00000000000..d0965e1b8d4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePropertyPage.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007, 2009 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.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager; +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.ui.newui.AbstractPage; + +public class AutotoolsConfigurePropertyPage extends AbstractPage { + + private ICConfigurationDescription cfgd; + + protected boolean isSingle() { + return true; + } + + /** + * Default constructor + */ + public AutotoolsConfigurePropertyPage() { + super(); + } + + public ICConfigurationDescription getCfgd() { + return cfgd; + } + + public void getAllConfigurationData() { + ICConfigurationDescription[] cfgds = getCfgsEditable(); + for (int i = 0; i < cfgds.length; ++i) { + @SuppressWarnings("unused") + // Following will trigger an option value handler check which will + // clone a configuration if necessary + CConfigurationData data = cfgds[i].getConfigurationData(); + } + } + + public IAConfiguration getConfiguration(ICConfigurationDescription cfgd) { + IAConfiguration acfg = AutotoolsConfigurationManager.getInstance().getTmpConfiguration(getProject(), cfgd); + return acfg; + } + + protected void cfgChanged(ICConfigurationDescription _cfgd) { + cfgd = _cfgd; + // Let super update all pages + super.cfgChanged(_cfgd); + } +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePropertyTab.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePropertyTab.java new file mode 100644 index 00000000000..0e0e1f952ce --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsConfigurePropertyTab.java @@ -0,0 +1,390 @@ +/******************************************************************************* + * 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICResourceDescription; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager; +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; +import org.eclipse.cdt.internal.autotools.ui.AbstractAutotoolsCPropertyTab; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IMultiConfiguration; +import org.eclipse.cdt.ui.newui.AbstractPage; +import org.eclipse.cdt.ui.newui.PageLayout; +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.preference.IPreferencePageContainer; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ScrollBar; + +public class AutotoolsConfigurePropertyTab extends AbstractAutotoolsCPropertyTab implements IPreferencePageContainer { + + private TreeViewer fTree; + private SashForm sashForm; + private Composite settingsPageContainer; + private AutotoolsConfigurePrefStore settingsStore; + private AbstractConfigurePropertyOptionsPage currentSettingsPage; + private ScrolledComposite containerSC; + private ToolListContentProvider listprovider; + private ToolListElement selectedElement; + private ICConfigurationDescription icfgd; + + private Map<String, List<AbstractConfigurePropertyOptionsPage>> configToPageListMap; + + private IProject getProject() { + return page.getProject(); + } + + public boolean canBeVisible() { + if (page.isForProject() || page.isForPrefs()) { + return true; + } + return false; + } + + public IAConfiguration getAutotoolsCfg() { + AutotoolsConfigurePropertyPage ap = (AutotoolsConfigurePropertyPage)page; + // We call getConfigurationData() to get the name because if the configuration has been renamed, + // it will cause the option value handler to clone the IAConfiguration + return ap.getConfiguration(icfgd); + } + + private void syncClones() { + AutotoolsConfigurePropertyPage ap = (AutotoolsConfigurePropertyPage)page; + // We call getConfigurationData() to get the name because if the configuration has been renamed, + // it will cause the option value handler to clone the IAConfiguration + ap.getAllConfigurationData(); + } + + public IPreferenceStore getPreferenceStore() { + return settingsStore; + } + + public void createControls(Composite parent) { + AutotoolsConfigurationManager.getInstance().clearTmpConfigurations(getProject()); + syncClones(); + + super.createControls(parent); + Composite composite= usercomp; + + settingsStore = AutotoolsConfigurePrefStore.getInstance(); + configToPageListMap = new HashMap<String, List<AbstractConfigurePropertyOptionsPage>>(); + + // assume parent page uses griddata + GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL | GridData.FILL_HORIZONTAL + | GridData.FILL_VERTICAL); + composite.setLayoutData(gd); + GridLayout layout= new GridLayout(); +// layout.numColumns= 2; + //PixelConverter pc= new PixelConverter(composite); + //layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2; + composite.setLayout(layout); + + // Create the sash form + sashForm = new SashForm(usercomp, SWT.NONE); + sashForm.setOrientation(SWT.HORIZONTAL); + sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); + + layout = new GridLayout(2, true); + layout.marginHeight = 5; + sashForm.setLayout(layout); + createSelectionArea(sashForm); + createEditArea(sashForm); + +// usercomp.addControlListener(new ControlAdapter() { +// @Override +// public void controlResized(ControlEvent e) { +// specificResize(); +// }}); + + } + +// private void specificResize() { +// Point p1 = fTree.getTree().computeSize(-1, -1); +// Point p2 = fTree.getTree().getSize(); +// Point p3 = usercomp.getSize(); +// p1.x += calcExtra(); +// if (p3.x >= p1.x && (p1.x < p2.x || (p2.x * 2 < p3.x))) { +// fTree.getTree().setSize(p1.x , p2.y); +// sashForm.setWeights(new int[] {p1.x, (p3.x - p1.x)}); +// } +// } +// +// private int calcExtra() { +// int x = fTree.getTree().getBorderWidth() * 2; +// ScrollBar sb = fTree.getTree().getVerticalBar(); +// if (sb != null) x += sb.getSize().x; +// return x; +// } + + protected void createSelectionArea (Composite parent) { + fTree = new TreeViewer(parent, SWT.SINGLE|SWT.H_SCROLL|SWT.V_SCROLL|SWT.BORDER); + fTree.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + handleOptionSelection(); + }}); + fTree.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); + // Create a temporary default AutotoolsConfiguration to use for label info + IAConfiguration tmp = AutotoolsConfigurationManager.getInstance().createDefaultConfiguration(getProject(), ""); + fTree.setLabelProvider(new ToolListLabelProvider(tmp)); + } + + protected void createEditArea(Composite parent) { + containerSC = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + containerSC.setExpandHorizontal(true); + containerSC.setExpandVertical(true); + + // Add a container for the build settings page + settingsPageContainer = new Composite(containerSC, SWT.NONE); + settingsPageContainer.setLayout(new PageLayout()); + + containerSC.setContent(settingsPageContainer); +// containerSC.setMinSize(settingsPageContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + settingsPageContainer.layout(); + } + + protected void setValues() { + /* + * This method updates the context of the build property pages + * - Which configuration/resource configuration is selected + * - Which tool/option category is selected + * + * It is called: + * - When a property page becomes visible + * - When the user changes the configuration selection + * - When the user changes the "exclude" setting for a resource + */ + + + IConfiguration icfg = getCfg(icfgd.getConfiguration()); + if (icfg instanceof IMultiConfiguration) { + fTree.setInput(null); + fTree.getControl().setEnabled(false); + currentSettingsPage.setVisible(false); + return; + } + + IAConfiguration currCfg = getAutotoolsCfg(); + + // Create the Tree Viewer content provider if first time + if (listprovider == null) { + listprovider = new ToolListContentProvider(); + fTree.setContentProvider(listprovider); + } + + // Update the selected configuration and the Tree Viewer + ToolListElement[] newElements; + + fTree.setInput(currCfg); + fTree.getControl().setEnabled(true); + newElements = (ToolListElement[])listprovider.getElements(currCfg); + fTree.expandAll(); + + selectedElement = newElements[0]; + fTree.setSelection(new StructuredSelection(selectedElement), true); + +// // Determine what the selection in the tree should be +// // If the saved selection is not null, try to match the saved selection +// // with an object in the new element list. +// // Otherwise, select the first tool in the tree +// Object primaryObject = null; +// if (selectedElement != null) { +// selectedElement = matchSelectionElement(selectedElement, newElements); +// } +// +// if (selectedElement == null) { +// selectedElement = (newElements != null && newElements.length > 0 ? newElements[0] : null); +// } +// +// if (selectedElement != null) { +// primaryObject = selectedElement.getTool(); +// if (primaryObject == null) { +// primaryObject = selectedElement.getOptionCategory(); +// } +// if (primaryObject != null) { +// if (primaryObject instanceof IOptionCategory) { +// ((ToolSettingsPrefStore)settingsStore).setSelection(getResDesc(), selectedElement, (IOptionCategory)primaryObject); +// } +// optionList.setSelection(new StructuredSelection(selectedElement), true); +// } +// } +// specificResize(); + } + + private void handleOptionSelection() { + // Get the selection from the tree list + if (fTree == null) return; + IStructuredSelection selection = (IStructuredSelection) fTree.getSelection(); + ToolListElement element = (ToolListElement)selection.getFirstElement(); + if (element != null) { + displayPageForElement(element); + } + + ScrollBar sb = containerSC.getHorizontalBar(); + if (sb != null && sb.isVisible()) { + settingsPageContainer.pack(true); + containerSC.setMinSize(settingsPageContainer.getSize()); + ((AbstractPage)page).resize(); + } + } + + private void displayPageForElement(ToolListElement element) { + selectedElement = element; + settingsStore.setSelection(getAutotoolsCfg(), selectedElement); + + AbstractConfigurePropertyOptionsPage oldPage = currentSettingsPage; + currentSettingsPage = null; + + // Create a new settings page if necessary + List<AbstractConfigurePropertyOptionsPage> pages = getPagesForConfig(); + ListIterator<AbstractConfigurePropertyOptionsPage> iter = pages.listIterator(); + + while (iter.hasNext()) { + AbstractConfigurePropertyOptionsPage page = iter.next(); + if (page.getName().equals(element.getName())) { + currentSettingsPage = page; + break; + } + } + if (currentSettingsPage == null) { + if (element.getType() == IConfigureOption.TOOL) { + currentSettingsPage = new AutotoolsToolPropertyOptionPage( + element, getAutotoolsCfg()); + } + else { + currentSettingsPage = new AutotoolsCategoryPropertyOptionPage( + element, getAutotoolsCfg()); + } + pages.add(currentSettingsPage); + currentSettingsPage.setContainer(this); + if (currentSettingsPage.getControl() == null) { + currentSettingsPage.createControl(settingsPageContainer); + } + } + + // Make all the other pages invisible + Control[] children = settingsPageContainer.getChildren(); + Control currentControl = currentSettingsPage.getControl(); + for (int i = 0; i < children.length; i++) { + if (children[i] != currentControl) + children[i].setVisible(false); + } + currentSettingsPage.setVisible(true); + currentSettingsPage.updateFields(); + + if (oldPage != null && oldPage != currentSettingsPage) + oldPage.setVisible(false); + + // Set the size of the scrolled area + containerSC.setMinSize(currentSettingsPage.computeSize()); + settingsPageContainer.layout(); + + } + + /* (non-Javadoc) + * Answers the list of settings pages for the selected configuration + */ + private List<AbstractConfigurePropertyOptionsPage> getPagesForConfig() { + if (getCfg() == null) return null; + List<AbstractConfigurePropertyOptionsPage> pages = configToPageListMap.get(getCfg().getName()); + if (pages == null) { + pages = new ArrayList<AbstractConfigurePropertyOptionsPage>(); + configToPageListMap.put(getCfg().getName(), pages); + } + return pages; + } + + /** + * Returns the "dirty" state + */ + public boolean isDirty() { + // Check each settings page + List<AbstractConfigurePropertyOptionsPage> pages = getPagesForConfig(); + // Make sure we have something to work on + if (pages == null) { + // Nothing to do + return false; + } + ListIterator<AbstractConfigurePropertyOptionsPage> iter = pages.listIterator(); + while (iter.hasNext()) { + AbstractConfigurePropertyOptionsPage page = iter.next(); + if (page == null) continue; + if (page.isDirty()) return true; + } + return false; + } + + protected void performOK() { + ICConfigurationDescription[] cfgs = page.getCfgsEditable(); + AutotoolsConfigurePropertyPage ap = (AutotoolsConfigurePropertyPage)page; + Map<String, IAConfiguration> cfgList = new HashMap<String, IAConfiguration>(); + for (int i = 0; i < cfgs.length; ++i) { + ICConfigurationDescription cd = cfgs[i]; + IAConfiguration acfg = ap.getConfiguration(cd); + cfgList.put(cd.getId(), acfg); + } + IProject project = getProject(); + AutotoolsConfigurationManager.getInstance().replaceProjectConfigurations(project, cfgList, cfgs); + AutotoolsConfigurationManager.getInstance().clearTmpConfigurations(project); + } + + protected void performCancel() { + AutotoolsConfigurationManager.getInstance().clearTmpConfigurations(getProject()); + } + + protected void performApply(ICResourceDescription src, ICResourceDescription dst) { + IProject project = getProject(); + ICConfigurationDescription[] cfgs = page.getCfgsEditable(); + // Apply all changes to existing saved configurations and new configurations, but do not perform + // deletions. + AutotoolsConfigurationManager.getInstance().applyConfigs(project.getName(), cfgs); + } + + protected void performDefaults() { + IAConfiguration cfg = getAutotoolsCfg(); + cfg.setDefaultOptions(); + setValues(); + } + + protected void updateData(ICResourceDescription rd) { + if (rd == null) return; + icfgd = rd.getConfiguration(); + setValues(); + } + + public void setVisible (boolean b) { + super.setVisible(b); + } + + // IPreferencePageContainer methods + @Override + public void updateButtons() {} + public void updateMessage() {} + public void updateTitle() {} +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsEditorPropertyTab.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsEditorPropertyTab.java new file mode 100644 index 00000000000..b98b38fe7a4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsEditorPropertyTab.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.core.settings.model.ICResourceDescription; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.ui.AbstractAutotoolsCPropertyTab; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +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.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + + +public class AutotoolsEditorPropertyTab extends AbstractAutotoolsCPropertyTab { + + 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 { +// AutotoolsEditorPropertyTab.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 { +// AutotoolsEditorPropertyTab.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() { + return page.getProject(); + } + + 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) { + // Nothing to do + } + + public void updateButtons() { + // Nothing to do + } + + 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsGeneralPropertyPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsGeneralPropertyPage.java new file mode 100644 index 00000000000..8cb774f4ef7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsGeneralPropertyPage.java @@ -0,0 +1,15 @@ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.ui.newui.AbstractPage; + +public class AutotoolsGeneralPropertyPage extends AbstractPage { + + @Override + protected boolean isSingle() { + return false; + } + + @Override + protected boolean showsConfig() { return false; } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsHeadPropertyPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsHeadPropertyPage.java new file mode 100644 index 00000000000..bb15d14691f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsHeadPropertyPage.java @@ -0,0 +1,15 @@ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.ui.newui.AbstractPage; + +public class AutotoolsHeadPropertyPage extends AbstractPage { + + @Override + protected boolean isSingle() { + return true; + } + + @Override + protected boolean showsConfig() { return false; } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyManager.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyManager.java new file mode 100644 index 00000000000..0f6d47eae04 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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 volatile 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyMessages.java new file mode 100644 index 00000000000..82781d6e4e2 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyMessages.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2002, 2006, 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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyMessages.properties new file mode 100644 index 00000000000..a9c612595ab --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsPropertyMessages.properties @@ -0,0 +1,44 @@ +############################################################################### +# Copyright (c) 2007, 2009 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 + +AutoBuildName.label=Automatically generate build directory names for additional configurations +AutoBuildName.tooltip=When a configuration other than the first configuration is created, generate a unique build directory using the configuration name. diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsToolPropertyOptionPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsToolPropertyOptionPage.java new file mode 100644 index 00000000000..691271daa8a --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsToolPropertyOptionPage.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2009 Red Hat Inc. + * 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.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.internal.autotools.core.configure.ConfigureMessages; +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.ui.newui.AbstractCPropertyTab; +import org.eclipse.cdt.ui.newui.MultiLineTextFieldEditor; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +public class AutotoolsToolPropertyOptionPage extends + AbstractConfigurePropertyOptionsPage { + + private ToolListElement element; + private String toolName = ""; + private IAConfiguration cfg; + // Label class for a preference page. + static class LabelFieldEditor extends FieldEditor { + private String fTitle; + private Label fTitleLabel; + + public LabelFieldEditor( Composite parent, String title ) { + fTitle = title; + this.createControl( parent ); + } + + protected void adjustForNumColumns( int numColumns ) { + ((GridData)fTitleLabel.getLayoutData()).horizontalSpan = 2; + } + + protected void doFillIntoGrid( Composite parent, int numColumns ) { + fTitleLabel = new Label( parent, SWT.WRAP ); + fTitleLabel.setText( fTitle ); + GridData gd = new GridData(); + gd.verticalAlignment = SWT.TOP; + gd.grabExcessHorizontalSpace = false; + gd.horizontalSpan = 2; + fTitleLabel.setLayoutData( gd ); + } + + public int getNumberOfControls() { return 1; } + /** + * The label field editor is only used to present a text label on a preference page. + */ + protected void doLoad() {} + protected void doLoadDefault() {} + protected void doStore() {} + } + + public AutotoolsToolPropertyOptionPage(ToolListElement element, IAConfiguration cfg) { + super(element.getName()); + this.element = element; + this.toolName = element.getName(); + this.cfg = cfg; + } + + public String getName() { + return super.getName(); + } + + public ToolListElement getElement() { + return element; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() + */ + protected void createFieldEditors() { + super.createFieldEditors(); + // Add a string editor to edit the tool command + Composite parent = getFieldEditorParent(); + FontMetrics fm = AbstractCPropertyTab.getFontMetrics(parent); + commandStringField = new StringFieldEditor(toolName, + ConfigureMessages.getString(COMMAND), + parent); + commandStringField.setEmptyStringAllowed(false); + GridData gd = ((GridData)commandStringField.getTextControl(parent).getLayoutData()); + gd.grabExcessHorizontalSpace = true; + gd.minimumWidth = Dialog.convertWidthInCharsToPixels(fm, 3); + addField(commandStringField); + // Add a field editor that displays overall build options + Composite par = getFieldEditorParent(); + allOptionFieldEditor = new MultiLineTextFieldEditor(AutotoolsConfigurePrefStore.ALL_OPTIONS_ID, + ConfigureMessages.getString(ALL_OPTIONS), par); + allOptionFieldEditor.getTextControl(par).setEditable(false); +// gd = ((GridData)allOptionFieldEditor.getTextControl().getLayoutData()); + gd.grabExcessHorizontalSpace = true; + gd.minimumWidth = Dialog.convertWidthInCharsToPixels(fm, 20); + addField(allOptionFieldEditor); + } + + protected FieldEditor createLabelEditor( Composite parent, String title ) { + return new LabelFieldEditor( parent, title ); + } + + // field editor that displays all the build options for a particular tool + private MultiLineTextFieldEditor allOptionFieldEditor; + //tool command field + private StringFieldEditor commandStringField; + // all build options field editor label + private static final String ALL_OPTIONS = "Tool.allopts"; //$NON-NLS-1$ + // Field editor label for tool command + private static final String COMMAND = "Tool.command"; //$NON-NLS-1$ + + /** + * Update the field editor that displays all the build options + */ + public void updateFields() { + allOptionFieldEditor.load(); + } + + public void setValues(){ + commandStringField.load(); + updateFields(); + } + + public void propertyChange(PropertyChangeEvent event) { + // allow superclass to handle as well + super.propertyChange(event); + + if(event.getSource() == commandStringField){ + cfg.setOption(toolName, commandStringField.getStringValue()); + updateFields(); + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsToolsPropertyTab.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsToolsPropertyTab.java new file mode 100644 index 00000000000..e79fd9987db --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/AutotoolsToolsPropertyTab.java @@ -0,0 +1,346 @@ +/******************************************************************************* + * Copyright (c) 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.core.settings.model.ICResourceDescription; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfiguration; +import org.eclipse.cdt.internal.autotools.ui.AbstractAutotoolsCPropertyTab; +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 AutotoolsToolsPropertyTab extends AbstractAutotoolsCPropertyTab { + + 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 fAutomakePath; + protected Text fAutoconfPath; + protected Text fAutoheaderPath; + protected Text fAutoreconfPath; + protected Text fLibtoolizePath; + private IProject project; + + + private IProject getProject() { + return page.getProject(); + } + + public boolean canBeVisible() { + return true; + } + + public void cfgChanged(AutotoolsConfiguration cfg) { + // Nothing to do + } + + 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 autoheader 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 autoreconf 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 libtoolize 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) { + // Nothing to do + } + + public void updateButtons() { + // Nothing to do + } + + 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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/IProjectPropertyListener.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/IProjectPropertyListener.java new file mode 100644 index 00000000000..3c322a0c5bc --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/IPropertyChangeManager.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/IPropertyChangeManager.java new file mode 100644 index 00000000000..a4ecb2c1b24 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/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.cdt.internal.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/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListContentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListContentProvider.java new file mode 100644 index 00000000000..f8436c5b47b --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListContentProvider.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import java.util.ArrayList; + +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class ToolListContentProvider implements ITreeContentProvider { + + private ToolListElement[] elements; + + private ToolListElement[] createElements() { + ArrayList<ToolListElement> toolList = new ArrayList<ToolListElement>(); + AutotoolsConfiguration.Option[] options = AutotoolsConfiguration.getTools(); + for (int i = 0; i < options.length; ++i) { + AutotoolsConfiguration.Option opt = options[i]; + String optName = opt.getName(); + ToolListElement tool = new ToolListElement(optName, IConfigureOption.TOOL); + toolList.add(tool); + AutotoolsConfiguration.Option[] categories = + AutotoolsConfiguration.getChildOptions(optName); + for (int j = 0; j < categories.length; ++j) { + String catName = categories[j].getName(); + ToolListElement newItem = new ToolListElement(catName, IConfigureOption.CATEGORY); + tool.addChild(newItem); + } + } + return toolList.toArray(new ToolListElement[toolList.size()]); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof AutotoolsConfiguration) { + return elements.clone(); + } + return ((ToolListElement)parentElement).getChildren(); + } + + public Object getParent(Object element) { + return ((ToolListElement)element).getParent(); + } + + public boolean hasChildren(Object element) { + return ((ToolListElement)element).hasChildren(); + } + + public Object[] getElements(Object inputElement) { + if (elements != null) + return elements.clone(); + return null; + } + + public void dispose() { + // nothing needed + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // TODO Auto-generated method stub + elements = createElements(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListElement.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListElement.java new file mode 100644 index 00000000000..0b37affaff6 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListElement.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 Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import java.util.ArrayList; + +public class ToolListElement { + + private ArrayList<ToolListElement> children; + private ToolListElement parent; + private String name; + private int type; + + public ToolListElement(String name, int type) { + this.name = name; + this.type = type; + this.children = new ArrayList<ToolListElement>(); + } + + public void setParent(ToolListElement p) { + parent = p; + } + + public ToolListElement getParent() { + return parent; + } + + public String getName() { + return name; + } + + public int getType() { + return type; + } + + public void addChild(ToolListElement e) { + children.add(e); + e.setParent(this); + } + + public boolean hasChildren() { + return children.size() > 0; + } + + public Object[] getChildren() { + return children.toArray(); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListLabelProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListLabelProvider.java new file mode 100644 index 00000000000..10a2d48aa99 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/properties/ToolListLabelProvider.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007, 2009 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 + * Red Hat Inc. - Modification for Autotools usage + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.properties; + +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; +import org.eclipse.cdt.internal.autotools.ui.AutotoolsUIPluginImages; +import org.eclipse.cdt.ui.newui.UIMessages; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +public class ToolListLabelProvider extends LabelProvider { + private final Image IMG_TOOL = AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_CFG_TOOL); + private final Image IMG_CAT = AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_CFG_CATEGORY); + private static final String ERROR_UNKNOWN_ELEMENT = "ConfigurePropertyPage.error.Unknown_tree_element"; //$NON-NLS-1$ + + private ImageDescriptor descriptor = null; + private ResourceManager manager = null; + private IAConfiguration cfg = null; + + public ToolListLabelProvider(IAConfiguration cfg) { + this.cfg = cfg; + } + + public IAConfiguration getCfg() { + return cfg; + } + + public void setCfg(IAConfiguration cfg) { + this.cfg = cfg; + } + + public Image getImage(Object element) { + if (!(element instanceof ToolListElement)) { + throw unknownElement(element); + } + Image defaultImage = IMG_CAT; + ToolListElement toolListElement = (ToolListElement)element; + IConfigureOption cat = cfg.getOption(toolListElement.getName()); + + if (cat == null) { + defaultImage = IMG_TOOL; + } + + // Use default icon for display + return defaultImage; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getText(Object) + */ + public String getText(Object element) { + if (!(element instanceof ToolListElement)) { + throw unknownElement(element); + } + ToolListElement toolListElement = (ToolListElement)element; + IConfigureOption cat = cfg.getOption(toolListElement.getName()); + + if (cat == null) { + return toolListElement.getName(); + } + else { + return cat.getDescription(); + } + } + + protected RuntimeException unknownElement(Object element) { + return new RuntimeException(UIMessages.getFormattedString(ERROR_UNKNOWN_ELEMENT, element.getClass().getName())); + } + + /** + * Disposing any images that were allocated for it. + * + * @since 3.0 + */ + public void dispose() { + if (descriptor != null && manager != null) { + manager.destroyImage(descriptor); + } + }; +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/AutoconfPrototype.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/AutoconfPrototype.java new file mode 100644 index 00000000000..1ddceef597c --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/AutoconfPrototype.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.text.hover; + +import java.util.ArrayList; + +public class AutoconfPrototype { + protected String name; + protected int numPrototypes; + protected ArrayList<Integer> minParms; + protected ArrayList<Integer> maxParms; + protected ArrayList<ArrayList<String>> parmList; + + public AutoconfPrototype() { + numPrototypes = 0; + minParms = new ArrayList<Integer>(); + maxParms = new ArrayList<Integer>(); + parmList = new ArrayList<ArrayList<String>>(); + } + + public String getName() { + return name; + } + + public void setName(String newName) { + name = newName; + } + + public int getNumPrototypes() { + return numPrototypes; + } + + public void setNumPrototypes(int num) { + numPrototypes = num; + } + + public int getMinParms(int prototypeNum) { + return ((Integer)minParms.get(prototypeNum)).intValue(); + } + + public void setMinParms(int prototypeNum, int value) { + minParms.add(prototypeNum, Integer.valueOf(value)); + } + + public int getMaxParms(int prototypeNum) { + return ((Integer)maxParms.get(prototypeNum)).intValue(); + } + + public void setMaxParms(int prototypeNum, int value) { + maxParms.add(prototypeNum, Integer.valueOf(value)); + } + + public String getParmName(int prototypeNum, int parmNum) { + ArrayList<String> parms = parmList.get(prototypeNum); + return (String)parms.get(parmNum); + } + + // This function assumes that parms will be added in order starting + // with lowest prototype first. + public void setParmName(int prototypeNum, int parmNum, String value) { + ArrayList<String> parms; + if (parmList.size() == prototypeNum) { + parms = new ArrayList<String>(); + parmList.add(parms); + } + else + parms = parmList.get(prototypeNum); + if (parms.size() == parmNum) + parms.add(value); + else + parms.set(parmNum, value); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/AutoconfTextHover.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/AutoconfTextHover.java new file mode 100644 index 00000000000..01ee959d0aa --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/AutoconfTextHover.java @@ -0,0 +1,599 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.text.hover; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.autotools.ui.editors.AutoconfEditor; +import org.eclipse.cdt.autotools.ui.editors.AutoconfMacro; +import org.eclipse.cdt.autotools.ui.editors.IAutotoolEditorActionDefinitionIds; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.ui.CWordFinder; +import org.eclipse.cdt.internal.autotools.ui.HTMLPrinter; +import org.eclipse.cdt.internal.autotools.ui.HTMLTextPresenter; +import org.eclipse.cdt.internal.autotools.ui.preferences.AutotoolsEditorPreferenceConstants; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextHoverExtension; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.keys.IBindingService; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + + +public class AutoconfTextHover implements ITextHover, ITextHoverExtension { + + public static final String LOCAL_AUTOCONF_MACROS_DOC_NAME = "macros/acmacros"; + public static final String LOCAL_AUTOMAKE_MACROS_DOC_NAME = "macros/ammacros"; + public static final String AUTOCONF_MACROS_DOC_NAME = "http://www.sourceware.org/eclipse/autotools/acmacros"; //$NON-NLS-1$ + public static final String AUTOMAKE_MACROS_DOC_NAME = "http://www.sourceware.org/eclipse/autotools/ammacros"; //$NON-NLS-1$ + + private static class AutotoolsHoverDoc { + public Document[] documents = new Document[2]; + public AutotoolsHoverDoc(Document ac_document, Document am_document) { + this.documents[0] = ac_document; + this.documents[1] = am_document; + } + public Document getAcDocument() { + return documents[0]; + } + public Document getAmDocument() { + return documents[1]; + } + public Document[] getDocuments() { + return documents; + } + }; + + private static Map<String, Document> acHoverDocs; + private static Map<String, Document> amHoverDocs; + private static Map<Document, ArrayList<AutoconfMacro>> acHoverMacros; + private static String fgStyleSheet; + private static AutoconfEditor fEditor; + + /* Mapping key to action */ + private static IBindingService fBindingService; + { + fBindingService= (IBindingService)PlatformUI.getWorkbench().getAdapter(IBindingService.class); + } + + public static String getAutoconfMacrosDocName(String version) { + return AUTOCONF_MACROS_DOC_NAME + "-" //$NON-NLS-1$ + + version + + ".xml"; //$NON-NLS-1$ + } + + public static String getLocalAutoconfMacrosDocName(String version) { + return LOCAL_AUTOCONF_MACROS_DOC_NAME + "-" //$NON-NLS-1$ + + version + + ".xml"; //$NON-NLS-1$ + } + + /* Get the preferences default for the autoconf macros document name. */ + public static String getDefaultAutoconfMacrosVer() { + return AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOCONF_VERSION); + } + + public static String getAutomakeMacrosDocName(String version) { + return AUTOMAKE_MACROS_DOC_NAME + "-" //$NON-NLS-1$ + + version + + ".xml"; //$NON-NLS-1$ + } + + public static String getLocalAutomakeMacrosDocName(String version) { + return LOCAL_AUTOMAKE_MACROS_DOC_NAME + "-" //$NON-NLS-1$ + + version + + ".xml"; //$NON-NLS-1$ + } + + /* Get the preferences default for the autoconf macros document name. */ + public static String getDefaultAutomakeMacrosVer() { + return AutotoolsPlugin.getDefault().getPreferenceStore().getString(AutotoolsEditorPreferenceConstants.AUTOMAKE_VERSION); + } + + protected static Document getACDoc(String acDocVer) { + Document ac_document = null; + if (acHoverDocs == null) { + acHoverDocs = new HashMap<String, Document>(); + } + ac_document = (Document)acHoverDocs.get(acDocVer); + if (ac_document == null) { + Document doc = null; + try { + // see comment in initialize() + try { + InputStream docStream = null; + try { + URI uri = new URI(getLocalAutoconfMacrosDocName(acDocVer)); + IPath p = URIUtil.toPath(uri); + // Try to open the file as local to this plug-in. + docStream = FileLocator.openStream(AutotoolsUIPlugin.getDefault().getBundle(), p, false); + } catch (IOException e) { + // Local open failed. Try normal external location. + URI acDoc = new URI(getAutoconfMacrosDocName(acDocVer)); + IPath p = URIUtil.toPath(acDoc); + if (p == null) { + URL url = acDoc.toURL(); + docStream = url.openStream(); + } else { + docStream = new FileInputStream(p.toFile()); + } + } + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.parse(docStream); + } catch (SAXParseException saxException) { + doc = null; + } catch (SAXException saxEx) { + doc = null; + } catch (ParserConfigurationException pce) { + doc = null; + } catch (IOException ioe) { + doc = null; + } finally { + if (docStream != null) + docStream.close(); + } + } catch (FileNotFoundException e) { + AutotoolsPlugin.log(e); + } catch (MalformedURLException e) { + AutotoolsPlugin.log(e); + } catch (URISyntaxException e) { + AutotoolsPlugin.log(e); + } + ac_document = doc; + } + catch (IOException ioe) { + } + } + acHoverDocs.put(acDocVer, ac_document); + return ac_document; + } + + protected static Document getAMDoc(String amDocVer) { + Document am_document = null; + if (amHoverDocs == null) { + amHoverDocs = new HashMap<String, Document>(); + } + am_document = (Document)amHoverDocs.get(amDocVer); + if (am_document == null) { + Document doc = null; + try { + // see comment in initialize() + try { + InputStream docStream = null; + try { + URI uri = new URI(getLocalAutomakeMacrosDocName(amDocVer)); + IPath p = URIUtil.toPath(uri); + // Try to open the file as local to this plug-in. + docStream = FileLocator.openStream(AutotoolsUIPlugin.getDefault().getBundle(), p, false); + } catch (IOException e) { + // Local open failed. Try normal external location. + URI acDoc = new URI(getAutomakeMacrosDocName(amDocVer)); + IPath p = URIUtil.toPath(acDoc); + if (p == null) { + URL url = acDoc.toURL(); + docStream = url.openStream(); + } else { + docStream = new FileInputStream(p.toFile()); + } + } + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.parse(docStream); + } catch (SAXParseException saxException) { + doc = null; + } catch (SAXException saxEx) { + doc = null; + } catch (ParserConfigurationException pce) { + doc = null; + } catch (IOException ioe) { + doc = null; + } finally { + if (docStream != null) + docStream.close(); + } + } catch (FileNotFoundException e) { + AutotoolsPlugin.log(e); + } catch (MalformedURLException e) { + AutotoolsPlugin.log(e); + } catch (URISyntaxException e) { + AutotoolsPlugin.log(e); + } + am_document = doc; + } + catch (IOException ioe) { + } + } + amHoverDocs.put(amDocVer, am_document); + return am_document; + } + + protected static AutotoolsHoverDoc getHoverDoc(IEditorInput input) { + String acDocVer = getDefaultAutoconfMacrosVer(); + String amDocVer = getDefaultAutomakeMacrosVer(); + if (input instanceof IFileEditorInput) { + IFileEditorInput fe = (IFileEditorInput)input; + IFile f = fe.getFile(); + IProject p = f.getProject(); + try { + String acVer = p.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION); + if (acVer != null) + acDocVer = acVer; + else { // look for compat project properties + acVer = p.getPersistentProperty(AutotoolsPropertyConstants.AUTOCONF_VERSION_COMPAT); + if (acVer != null) + acDocVer = acVer; + } + } catch (CoreException ce1) { + // do nothing + } + try { + String amVer = p.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION); + if (amVer != null) + amDocVer = amVer; + else { // look for compat project properties + amVer = p.getPersistentProperty(AutotoolsPropertyConstants.AUTOMAKE_VERSION_COMPAT); + if (amVer != null) + amDocVer = amVer; + } + } catch (CoreException ce2) { + // do nothing + } + } + Document ac_document = getACDoc(acDocVer); + Document am_document = getAMDoc(amDocVer); + return new AutoconfTextHover.AutotoolsHoverDoc(ac_document, am_document); + } + + public AutoconfTextHover(AutoconfEditor editor) { + fEditor = editor; + } + + public static String getIndexedInfo(String name, AutoconfEditor editor) { + AutotoolsHoverDoc h = getHoverDoc(editor.getEditorInput()); + String x = getIndexedInfoFromDocument(name, h.getAcDocument()); + if (x == null) + x = getIndexedInfoFromDocument(name, h.getAmDocument()); + return x; + } + + private static String getIndexedInfoFromDocument(String name, Document document) { + StringBuffer buffer = new StringBuffer(); + + if (document != null && name != null) { + Element elem = document.getElementById(name); + if (null != elem) { + int prototypeCount = 0; + buffer.append("<B>Macro:</B> " + name); + NodeList nl = elem.getChildNodes(); + for (int i = 0; i < nl.getLength(); ++i) { + Node n = nl.item(i); + String nodeName = n.getNodeName(); + if (nodeName.equals("prototype")) { //$NON-NLS-1$ + StringBuffer prototype = new StringBuffer(); + ++prototypeCount; + if (prototypeCount == 1) { + buffer.append(" ("); + } else + buffer.append(" <B>or</B> " + name + " (<I>"); //$NON-NLS-2$ + NodeList varList = n.getChildNodes(); + for (int j = 0; j < varList.getLength(); ++j) { + Node v = varList.item(j); + String vnodeName = v.getNodeName(); + if (vnodeName.equals("parameter")) { //$NON-NLS-1$ + NamedNodeMap parms = v.getAttributes(); + Node parmNode = parms.item(0); + String parm = parmNode.getNodeValue(); + if (prototype.toString().equals("")) + prototype.append(parm); + else + prototype.append(", " + parm); + } + } + buffer.append(prototype.toString() + "</I>)<br>"); //$NON-NLS-1$ + } + if (nodeName.equals("synopsis")) { //$NON-NLS-1$ + Node textNode = n.getLastChild(); + buffer.append("<br><B>Synopsis:</B> "); + buffer.append(textNode.getNodeValue()); + } + } + } + } + if (buffer.length() > 0) { + HTMLPrinter.insertPageProlog(buffer, 0); + HTMLPrinter.addPageEpilog(buffer); + return buffer.toString(); + } + + return null; + } + + public static AutoconfMacro[] getMacroList(AutoconfEditor editor) { + IEditorInput input = editor.getEditorInput(); + AutotoolsHoverDoc hoverdoc = getHoverDoc(input); + AutoconfMacro[] macros = getMacroList(hoverdoc); + return macros; + } + + private static AutoconfMacro[] getMacroList(AutotoolsHoverDoc hoverdoc) { + if (acHoverMacros == null) { + acHoverMacros = new HashMap<Document, ArrayList<AutoconfMacro>>(); + } + + ArrayList<AutoconfMacro> masterList = new ArrayList<AutoconfMacro>(); + Document[] doc = hoverdoc.getDocuments(); + for (int ix = 0; ix < doc.length; ++ix) { + Document macroDoc = doc[ix]; + ArrayList<AutoconfMacro> list = acHoverMacros.get(macroDoc); + if (list == null && macroDoc != null) { + list = new ArrayList<AutoconfMacro>(); + NodeList nl = macroDoc.getElementsByTagName("macro"); //$NON-NLS-1$ + for (int i = 0; i < nl.getLength(); ++i) { + Node macro = nl.item(i); + NamedNodeMap macroAttrs = macro.getAttributes(); + Node n2 = macroAttrs.getNamedItem("id"); //$NON-NLS-1$ + if (n2 != null) { + String name = n2.getNodeValue(); + StringBuffer parms = new StringBuffer(); + NodeList macroChildren = macro.getChildNodes(); + for (int j = 0; j < macroChildren.getLength(); ++j) { + Node x = macroChildren.item(j); + if (x.getNodeName().equals("prototype")) { //$NON-NLS-1$ + // Use parameters for context info. + NodeList parmList = x.getChildNodes(); + int parmCount = 0; + for (int k = 0; k < parmList.getLength(); ++k) { + Node n3 = parmList.item(k); + if (n3.getNodeName() == "parameter") { //$NON-NLS-1$ + NamedNodeMap parmVals = n3.getAttributes(); + Node parmVal = parmVals.item(0); + if (parmCount > 0) + parms = parms.append(", "); //$NON-NLS-1$ + parms.append(parmVal.getNodeValue()); + ++parmCount; + } + } + } + } + AutoconfMacro m = new AutoconfMacro(name, parms.toString()); + list.add(m); + } + } + // Cache the arraylist of macros for later usage. + acHoverMacros.put(macroDoc, list); + } + if (list != null) + masterList.addAll(list); + } + // Convert to a sorted array of macros and return result. + AutoconfMacro[] macros = new AutoconfMacro[masterList.size()]; + masterList.toArray(macros); + Arrays.sort(macros); + return macros; + } + + public static AutoconfPrototype getPrototype(String name, AutoconfEditor editor) { + IEditorInput input = editor.getEditorInput(); + AutotoolsHoverDoc hoverdoc = getHoverDoc(input); + AutoconfPrototype x = getPrototype(name, hoverdoc.getAcDocument()); + if (x == null) + x = getPrototype(name, hoverdoc.getAmDocument()); + return x; + } + + private static AutoconfPrototype getPrototype(String name, Document document) { + AutoconfPrototype p = null; + if (document != null && name != null) { + Element elem = document.getElementById(name); + if (null != elem) { + int prototypeCount = -1; + p = new AutoconfPrototype(); + p.setName(name); + NodeList nl = elem.getChildNodes(); + for (int i = 0; i < nl.getLength(); ++i) { + Node n = nl.item(i); + String nodeName = n.getNodeName(); + if (nodeName.equals("prototype")) { //$NON-NLS-1$ + ++prototypeCount; + int parmCount = 0; + int minParmCount = -1; + p.setNumPrototypes(prototypeCount + 1); + NodeList varList = n.getChildNodes(); + for (int j = 0; j < varList.getLength(); ++j) { + Node v = varList.item(j); + String vnodeName = v.getNodeName(); + if (vnodeName.equals("parameter")) { //$NON-NLS-1$ + ++parmCount; + NamedNodeMap parms = v.getAttributes(); + Node parmNode = parms.item(0); + String parm = parmNode.getNodeValue(); + // Check for first optional parameter which means + // we know the minimum number of parameters needed. + if (minParmCount < 0 && (parm.charAt(0) == '[' || + parm.startsWith("..."))) + minParmCount = parmCount - 1; + // Old style documentation sometimes had '[' in + // prototypes so look for one at end of a parm too. + else if (minParmCount < 0 && parm.endsWith("[")) + minParmCount = parmCount; + p.setParmName(prototypeCount, parmCount - 1, parm); + } + } + p.setMaxParms(prototypeCount, parmCount); + // If we see no evidence of optional parameters, then + // the min and max number of parameters are equal. + if (minParmCount < 0) + minParmCount = parmCount; + p.setMinParms(prototypeCount, minParmCount); + } + } + } + } + return p; + } + + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + + String hoverInfo = null; + + IDocument d = textViewer.getDocument(); + + try { + String name = d.get(hoverRegion.getOffset(), hoverRegion.getLength()); + hoverInfo = getIndexedInfo(name, fEditor); + } catch (BadLocationException e) { + // do nothing + } + // TODO Auto-generated method stub + return hoverInfo; + } + + /* + * @see ITextHover#getHoverRegion(ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + + if (textViewer != null) { + /* + * If the hover offset falls within the selection range return the + * region for the whole selection. + */ + Point selectedRange = textViewer.getSelectedRange(); + if (selectedRange.x >= 0 && selectedRange.y > 0 + && offset >= selectedRange.x + && offset <= selectedRange.x + selectedRange.y) + return new Region(selectedRange.x, selectedRange.y); + else { + return CWordFinder.findWord(textViewer.getDocument(), offset); + } + } + return null; + } + + /* + * @see ITextHoverExtension#getHoverControlCreator() + * @since 3.0 + */ + public IInformationControlCreator getHoverControlCreator() { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, getTooltipAffordanceString(), + new HTMLTextPresenter(false)); + } + }; + } + + /* + * Static member function to allow content assist to add hover help. + */ + public static IInformationControlCreator getInformationControlCreator() { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, getTooltipAffordanceString(), + new HTMLTextPresenter(false)); + } + }; + } + + protected static String getTooltipAffordanceString() { + if (fBindingService == null) + return null; + + String keySequence= fBindingService.getBestActiveBindingFormattedFor(IAutotoolEditorActionDefinitionIds.SHOW_TOOLTIP); + if (keySequence == null) + return null; + + return HoverMessages.getFormattedString("ToolTipFocus", keySequence); //$NON-NLS-1$ + } + + /** + * Returns the style sheet. + * + * @since 3.2 + */ + protected static String getStyleSheet() { + if (fgStyleSheet == null) { + Bundle bundle= Platform.getBundle(AutotoolsUIPlugin.PLUGIN_ID); + URL styleSheetURL= bundle.getEntry("/AutoconfHoverStyleSheet.css"); //$NON-NLS-1$ + if (styleSheetURL != null) { + try { + styleSheetURL= FileLocator.toFileURL(styleSheetURL); + BufferedReader reader= new BufferedReader(new InputStreamReader(styleSheetURL.openStream())); + try { + StringBuffer buffer= new StringBuffer(200); + String line= reader.readLine(); + while (line != null) { + buffer.append(line); + buffer.append('\n'); + line= reader.readLine(); + } + fgStyleSheet= buffer.toString(); + } finally { + reader.close(); + } + } catch (IOException ex) { + AutotoolsUIPlugin.log(ex); + fgStyleSheet= ""; //$NON-NLS-1$ + } + } + } + return fgStyleSheet; + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/HoverMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/HoverMessages.java new file mode 100644 index 00000000000..c48c6fee8e8 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/HoverMessages.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * 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.cdt.internal.autotools.ui.text.hover; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + + +/** + * AutoconfEditorMessages + */ +public class HoverMessages { + + private static final String RESOURCE_BUNDLE= HoverMessages.class.getName(); + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private HoverMessages() { + } + + 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 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[] { Boolean.valueOf(arg) }); + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/HoverMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/HoverMessages.properties new file mode 100644 index 00000000000..d9326d9d0af --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/text/hover/HoverMessages.properties @@ -0,0 +1,11 @@ +################################################################################# +# Copyright (c) 2006 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 +################################################################################# +ToolTipFocus="Press ''{0}'' for focus."
\ No newline at end of file diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsBuildWizard.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsBuildWizard.java new file mode 100644 index 00000000000..838f61ca487 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsBuildWizard.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008, 2009 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - initial API and implementation + * Red Hat Inc - modification for Autotools project + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; +import java.util.SortedMap; + +import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyManager; +import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType; +import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue; +import org.eclipse.cdt.managedbuilder.core.BuildListComparator; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.ui.wizards.AbstractCWizard; +import org.eclipse.cdt.managedbuilder.ui.wizards.MBSWizardHandler; +import org.eclipse.cdt.ui.newui.CDTPrefUtil; +import org.eclipse.cdt.ui.wizards.EntryDescriptor; +import org.eclipse.jface.wizard.IWizard; + +/** + * + */ +public class AutotoolsBuildWizard extends AbstractCWizard { + public static final String OTHERS_LABEL = AutotoolsWizardMessages.getResourceString("AutotoolsBuildWizard.1"); //$NON-NLS-1$ + public static final String AUTOTOOLS_PROJECTTYPE_ID = "org.eclipse.linuxtools.cdt.autotools.core.projectType"; //$NON-NLS-1$ + + /** + * @since 5.1 + */ + public static final String EMPTY_PROJECT = AutotoolsWizardMessages.getResourceString("AutotoolsBuildWizard.2"); //$NON-NLS-1$ + /** + * Creates and returns an array of items to be displayed + */ + public EntryDescriptor[] createItems(boolean supportedOnly, IWizard wizard) { + IBuildPropertyManager bpm = ManagedBuildManager.getBuildPropertyManager(); + IBuildPropertyType bpt = bpm.getPropertyType(MBSWizardHandler.ARTIFACT); + IBuildPropertyValue[] vs = bpt.getSupportedValues(); + Arrays.sort(vs, BuildListComparator.getInstance()); + ArrayList<EntryDescriptor> items = new ArrayList<EntryDescriptor>(); + + // look for Autotools project type + EntryDescriptor oldsRoot = null; + SortedMap<String, IProjectType> sm = ManagedBuildManager.getExtensionProjectTypeMap(); + for (Map.Entry<String, IProjectType> e : sm.entrySet()) { + IProjectType pt = e.getValue(); + if (pt.getId().equals(AUTOTOOLS_PROJECTTYPE_ID)) { + AutotoolsBuildWizardHandler h = new AutotoolsBuildWizardHandler(pt, parent, wizard); + IToolChain[] tcs = ManagedBuildManager.getExtensionToolChains(pt); + for(int i = 0; i < tcs.length; i++){ + IToolChain t = tcs[i]; + if(t.isSystemObject()) + continue; + if (!isValid(t, supportedOnly, wizard)) + continue; + + h.addTc(t); + } + + String pId = null; + if (CDTPrefUtil.getBool(CDTPrefUtil.KEY_OTHERS)) { + if (oldsRoot == null) { + oldsRoot = new EntryDescriptor(OTHERS_LABEL, null, OTHERS_LABEL, true, null, null); + items.add(oldsRoot); + } + pId = oldsRoot.getId(); + } else { // do not group to <Others> + pId = null; + } + items.add(new EntryDescriptor(pt.getId(), pId, pt.getName(), true, h, null)); + } + } + return (EntryDescriptor[])items.toArray(new EntryDescriptor[items.size()]); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsBuildWizardHandler.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsBuildWizardHandler.java new file mode 100644 index 00000000000..ffc48468c94 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsBuildWizardHandler.java @@ -0,0 +1,97 @@ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.util.Map; + +import org.eclipse.cdt.autotools.core.AutotoolsNewProjectNature; +import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext; +import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set; +import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2Set; +import org.eclipse.cdt.make.core.scannerconfig.InfoContext; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.IResourceInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.ui.wizards.MBSWizardHandler; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.swt.widgets.Composite; + +public class AutotoolsBuildWizardHandler extends MBSWizardHandler { + public AutotoolsBuildWizardHandler(Composite p, IWizard w) { + super(AutotoolsWizardMessages.getResourceString("AutotoolsBuildWizard.0"), p, w); //$NON-NLS-1$ + } + + public AutotoolsBuildWizardHandler(IProjectType pt, Composite parent, IWizard wizard) { + super(pt, parent, wizard); + } + + @SuppressWarnings("restriction") + @Override + public void createProject(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor) throws CoreException { + super.createProject(project, defaults, onFinish, monitor); + // Fix for bug #312298 + // Following is required to get around the fact that the Scanner Discovery BuildInfo isn't + // created at this point. This is due to some complications caused by us superclassing the + // gnu gcc compiler or gnu g++ compiler as tools in our toolchain. We are essentially + // copying the logic from the Discovery Tab of the C/C++ Properties when the Ok button + // gets pushed. We reset the project description and this causes the Scanner Discovery + // BuildInfo to be written to the .cproject file. Without this fix, a new project + // will require rebuilding upon startup of Eclipse each time to recreate the Scanner + // Discovery info and avoid warnings regarding header files and errors regarding missing + // macro definitions. This code will likely go away when the Scanner Discovery mechanism + // gets rewritten in CDT (post 8.0). + ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager(); + ICProjectDescription des = mngr.getProjectDescription(project); + ICConfigurationDescription cfgd = des.getActiveConfiguration(); + IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgd); + ICfgScannerConfigBuilderInfo2Set cbi = CfgScannerConfigProfileManager.getCfgScannerConfigBuildInfo(cfg); + IScannerConfigBuilderInfo2Set baseCbi = ScannerConfigProfileManager.createScannerConfigBuildInfo2Set(project); + Map<InfoContext, IScannerConfigBuilderInfo2> baseInfoMap = baseCbi.getInfoMap(); + Map<CfgInfoContext, IScannerConfigBuilderInfo2> infoMap = cbi.getInfoMap(); + for (Map.Entry<CfgInfoContext, IScannerConfigBuilderInfo2> e : infoMap.entrySet()) { + @SuppressWarnings("unused") + String s = null; + CfgInfoContext cfgInfoContext = e.getKey(); + IResourceInfo rcInfo = cfgInfoContext.getResourceInfo(); + if (rcInfo == null) { // per configuration + s = cfgInfoContext.getConfiguration().getName(); + } else { // per resource + IInputType typ = cfgInfoContext.getInputType(); + s = typ.getName(); + } + IScannerConfigBuilderInfo2 bi2 = infoMap.get(cfgInfoContext); + String profileId = bi2.getSelectedProfileId(); + bi2.setSelectedProfileId(profileId); + } + CoreModel.getDefault().setProjectDescription(project, des); + } + + @Override + public void convertProject(IProject proj, IProgressMonitor monitor) throws CoreException { + super.convertProject(proj, monitor); + AutotoolsNewProjectNature.addAutotoolsNature(proj, monitor); + + // For each IConfiguration, create a corresponding Autotools Configuration + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(proj); + IConfiguration[] cfgs = info.getManagedProject().getConfigurations(); + for (int i = 0; i < cfgs.length; ++i) { + IConfiguration cfg = cfgs[i]; + ICConfigurationDescription cfgd = ManagedBuildManager.getDescriptionForConfiguration(cfg); + String id = cfgd.getId(); + AutotoolsConfigurationManager.getInstance().getConfiguration(proj, id, true); + } + AutotoolsConfigurationManager.getInstance().saveConfigs(proj); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsNewCCProjectWizardV2.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsNewCCProjectWizardV2.java new file mode 100644 index 00000000000..756aa31e4e3 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsNewCCProjectWizardV2.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.cdt.autotools.core.AutotoolsNewProjectNature; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +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.ui.wizards.MBSCustomPageManager; +import org.eclipse.cdt.ui.newui.CDTHelpContextIds; +import org.eclipse.cdt.ui.wizards.NewCCProjectWizard; +import org.eclipse.cdt.ui.wizards.NewCProjectWizardPage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; + + + +@SuppressWarnings("deprecation") +public class AutotoolsNewCCProjectWizardV2 extends NewCCProjectWizard { + + /* (non-Javadoc) + * String constants + */ + protected static final String PREFIX = "WizardAutotoolsNewCCProjectV2"; //$NON-NLS-1$ + protected static final String OP_ERROR = PREFIX + ".op_error"; //$NON-NLS-1$ + protected static final String WZ_TITLE = PREFIX + ".title"; //$NON-NLS-1$ + protected static final String WZ_DESC = PREFIX + ".description"; //$NON-NLS-1$ + protected static final String WINDOW_TITLE = PREFIX + ".windowTitle"; //$NON-NLS-1$ + protected static final String CONF_TITLE = PREFIX + ".config.title"; //$NON-NLS-1$ + protected static final String CONF_DESC = PREFIX + ".config.desc"; //$NON-NLS-1$ + protected static final String OPTIONS_TITLE = PREFIX + ".options.title"; //$NON-NLS-1$ + protected static final String OPTIONS_DESC = PREFIX + ".options.desc"; //$NON-NLS-1$ + protected static final String MSG_ADD_NATURE = PREFIX + ".message.add_nature"; //$NON-NLS-1$ + protected static final String MSG_ADD_BUILDER = PREFIX + ".message.add_builder"; //$NON-NLS-1$ + protected static final String MSG_SAVE = PREFIX + ".message.save"; //$NON-NLS-1$ + + // Wizard pages + protected CProjectPlatformPage projectConfigurationPage; + protected NewAutotoolsProjectOptionPage optionPage; + protected IProjectType projectType; + + public AutotoolsNewCCProjectWizardV2() { + this(AutotoolsUIPlugin.getResourceString(WZ_TITLE), AutotoolsUIPlugin.getResourceString(WZ_DESC)); + } + + public AutotoolsNewCCProjectWizardV2(String title, String description) { + super(title, description); + } + /** + * Method getWzDescriptionResource, allows Wizard description label value + * to be changed by subclasses + * + * @return String + */ + protected static String getWzDescriptionResource() { + return AutotoolsUIPlugin.getResourceString(WZ_DESC); + } + + /** + * Method getWzTitleResource, allows Wizard description label value + * to be changed by subclasses + * + * @return String + */ + protected static String getWzTitleResource() { + return AutotoolsUIPlugin.getResourceString(WZ_TITLE); + } + + /** + * Method getWindowTitleResource, allows Wizard Title label value to be + * changed by subclasses + * + * @return String + */ + protected static String getWindowTitleResource() { + return AutotoolsUIPlugin.getResourceString(WINDOW_TITLE); + } + + /** + * Method getPrefix, allows prefix value to be changed by subclasses + * + * @return String + */ + protected static String getPrefix() { + return PREFIX; + } + + public void addPages() { + // Add the default page for all new projects + super.addPages(); + + // Add the configuration selection page + projectConfigurationPage = new CProjectPlatformPage(PREFIX, this); + projectConfigurationPage.setTitle(AutotoolsUIPlugin.getResourceString(CONF_TITLE)); + projectConfigurationPage.setDescription(AutotoolsUIPlugin.getResourceString(CONF_DESC)); + addPage(projectConfigurationPage); + + // Add the options (tabbed) page + optionPage = new NewAutotoolsProjectOptionPage(PREFIX, this); + optionPage.setTitle(AutotoolsUIPlugin.getResourceString(OPTIONS_TITLE)); + optionPage.setDescription(AutotoolsUIPlugin.getResourceString(OPTIONS_DESC)); + addPage(optionPage); + + // add custom pages + MBSCustomPageManager.init(); + + // add stock pages + MBSCustomPageManager.addStockPage(fMainPage, NewCProjectWizardPage.PAGE_ID); + MBSCustomPageManager.addStockPage(projectConfigurationPage, CProjectPlatformPage.PAGE_ID); + MBSCustomPageManager.addStockPage(optionPage, NewAutotoolsProjectOptionPage.PAGE_ID); + + } + + public void createPageControls(Composite pageContainer) { + super.createPageControls( pageContainer ); + + IWizardPage [] pages = getPages(); + + if (pages != null) { + for (int i = 0; i < pages.length; i++) { + IWizardPage page = pages[i]; + if (page instanceof NewCProjectWizardPage) { + // Setup the help information + PlatformUI.getWorkbench().getHelpSystem().setHelp(pageContainer, CDTHelpContextIds.MAN_PROJ_WIZ_NAME_PAGE); + } + else if (page instanceof NewAutotoolsProjectOptionPage) { + NewAutotoolsProjectOptionPage optionPage = (NewAutotoolsProjectOptionPage) page; + optionPage.setupHelpContextIds(); + } + // The other built-in page is the CProjectPlatformPage which already has a help id. + } + } + } + + public void updateProjectTypeProperties() { + // Update the error parser list + optionPage.updateProjectTypeProperties(); + } + + protected void addNature(IProgressMonitor monitor) throws CoreException { + monitor.beginTask("", 4); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_NATURE)); + ManagedCProjectNature.addManagedNature(newProject, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_BUILDER)); + ManagedCProjectNature.addManagedBuilder(newProject, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_NATURE)); + AutotoolsNewProjectNature.addAutotoolsNature(newProject, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_BUILDER)); + AutotoolsNewProjectNature.addAutotoolsBuilder(newProject, new SubProgressMonitor(monitor, 1)); + monitor.done(); + } + + public IProjectType getProjectType() { + return projectConfigurationPage.getProjectType(); + } + + protected void doRun(IProgressMonitor monitor) throws CoreException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + // super.doRun() just creates the project and does not assign a builder to it. + super.doRun(new SubProgressMonitor(monitor, 5)); + + // Add the managed build nature and builder + try { + addNature(new SubProgressMonitor(monitor, 2)); + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + } + // FIXME: Default scanner property: make -w - eventually we want to use Make core's build scanner + newProject.setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, AutotoolsPropertyConstants.TRUE); + + CCorePlugin.getDefault().mapCProjectOwner(newProject, getProjectID(), true); + + // Add the ManagedProject to the project + IManagedProject newManagedProject = null; + IManagedBuildInfo info = null; + try { + info = ManagedBuildManager.createBuildInfo(newProject); + IProjectType parent = getProjectType(); + newManagedProject = ManagedBuildManager.createManagedProject(newProject, parent); + if (newManagedProject != null) { + IConfiguration [] selectedConfigs = getSelectedConfigurations(); + for (int i = 0; i < selectedConfigs.length; i++) { + IConfiguration config = selectedConfigs[i]; + int id = ManagedBuildManager.getRandomNumber(); + IConfiguration newConfig = newManagedProject.createConfiguration(config, config.getId() + "." + id); //$NON-NLS-1$ + newConfig.setArtifactName(newManagedProject.getDefaultArtifactName()); + } + // Now add the first supported config in the list as the default + IConfiguration defaultCfg = null; + IConfiguration[] newConfigs = newManagedProject.getConfigurations(); + for(int i = 0; i < newConfigs.length; i++) { + if(newConfigs[i].isSupported()){ + defaultCfg = newConfigs[i]; + break; + } + } + + if(defaultCfg == null && newConfigs.length > 0) + defaultCfg = newConfigs[0]; + + if(defaultCfg != null) { + ManagedBuildManager.setDefaultConfiguration(newProject, defaultCfg); + ManagedBuildManager.setSelectedConfiguration(newProject, defaultCfg); + } + ManagedBuildManager.setNewProjectVersion(newProject); + ICDescriptor desc = null; + try { + desc = CCorePlugin.getDefault().getCProjectDescription(newProject, true); + desc.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, ManagedBuildManager.INTERFACE_IDENTITY); + // TODO: The binary parser setting is currently per-project in the rest of CDT. + // In the MBS, it is per-coonfiguration. For now, select the binary parsers of the + // first configuration. +// if (newConfigs.length > 0) { +// IToolChain tc = newConfigs[0].getToolChain(); +// ITargetPlatform targetPlatform = tc.getTargetPlatform(); +// } + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + } + } + } catch (BuildException e) { + AutotoolsUIPlugin.log(e); + } + + // Following is a bit of a hack because changing the project options + // causes a change event to be fired which will try to reindex the project. + // We are in the middle of setting the project indexer which may end up + // being the null indexer. In that case, we don't want the default indexer + // (Fast Indexer) to be invoked. + //IPDOMManager manager = CCorePlugin.getPDOMManager(); + //ICProject cproject = CoreModel.getDefault().create(newProject); + //manager.setIndexerId(cproject, ConvertToAutotoolsProjectWizard.NULL_INDEXER_ID); + + // Modify the project settings + if (newProject != null) { + optionPage.performApply(new SubProgressMonitor(monitor, 2)); + } + + // Save the build options + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_SAVE)); + if (info != null) { + info.setValid(true); + ManagedBuildManager.saveBuildInfo(newProject, true); + } + + IStatus initResult = ManagedBuildManager.initBuildInfoContainer(newProject); + if (initResult.getCode() != IStatus.OK) { + // At this point, I can live with a failure + AutotoolsUIPlugin.log(initResult); + } + + monitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#doRunPrologue(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void doRunPrologue(IProgressMonitor monitor) { + // Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#doRunEpilogue(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void doRunEpilogue(IProgressMonitor monitor) { + // Get my initializer to run + if(newProject == null) + return; + + IStatus initResult = ManagedBuildManager.initBuildInfoContainer(newProject); + if (initResult.getCode() != IStatus.OK) { + // At this point, I can live with a failure + AutotoolsUIPlugin.log(initResult); + } + + // execute any operations specified by custom pages + // execute any operations specified by custom pages + IRunnableWithProgress operations[] = MBSCustomPageManager.getOperations(); + + if (operations != null) + { + for(int k = 0; k < operations.length; k++) + { + try { + operations[k].run(monitor); + } catch(InvocationTargetException e) { + //TODO: what should we do? + } catch(InterruptedException e) { + //TODO: what should we do? + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#getProjectID() + */ + public String getProjectID() { +// return "org.eclipse.cdt.make.core.make"; //$NON-NLS-1$ + return ManagedBuilderCorePlugin.MANAGED_MAKE_PROJECT_ID; + } + +// public IProjectType getSelectedProjectType() { +// return projectConfigurationPage.getSelectedProjectType(); +// } + + public IConfiguration[] getSelectedConfigurations() { + return projectConfigurationPage.getSelectedConfigurations(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsNewCProjectWizardV2.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsNewCProjectWizardV2.java new file mode 100644 index 00000000000..4d459e27a79 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsNewCProjectWizardV2.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.cdt.autotools.core.AutotoolsNewProjectNature; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +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.ui.wizards.MBSCustomPageManager; +import org.eclipse.cdt.ui.newui.CDTHelpContextIds; +import org.eclipse.cdt.ui.wizards.NewCProjectWizard; +import org.eclipse.cdt.ui.wizards.NewCProjectWizardPage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; + + + +@SuppressWarnings("deprecation") +public class AutotoolsNewCProjectWizardV2 extends NewCProjectWizard { + + /* (non-Javadoc) + * String constants + */ + protected static final String PREFIX = "WizardAutotoolsNewCProjectV2"; //$NON-NLS-1$ + protected static final String OP_ERROR = PREFIX + ".op_error"; //$NON-NLS-1$ + protected static final String WZ_TITLE = PREFIX + ".title"; //$NON-NLS-1$ + protected static final String WZ_DESC = PREFIX + ".description"; //$NON-NLS-1$ + protected static final String WINDOW_TITLE = PREFIX + ".windowTitle"; //$NON-NLS-1$ + protected static final String CONF_TITLE = PREFIX + ".config.title"; //$NON-NLS-1$ + protected static final String CONF_DESC = PREFIX + ".config.desc"; //$NON-NLS-1$ + protected static final String OPTIONS_TITLE = PREFIX + ".options.title"; //$NON-NLS-1$ + protected static final String OPTIONS_DESC = PREFIX + ".options.desc"; //$NON-NLS-1$ + protected static final String MSG_ADD_NATURE = PREFIX + ".message.add_nature"; //$NON-NLS-1$ + protected static final String MSG_ADD_BUILDER = PREFIX + ".message.add_builder"; //$NON-NLS-1$ + protected static final String MSG_SAVE = PREFIX + ".message.save"; //$NON-NLS-1$ + + // Wizard pages + protected CProjectPlatformPage projectConfigurationPage; + protected NewAutotoolsProjectOptionPage optionPage; + protected IProjectType projectType; + + public AutotoolsNewCProjectWizardV2() { + this(AutotoolsUIPlugin.getResourceString(WZ_TITLE), AutotoolsUIPlugin.getResourceString(WZ_DESC)); + } + + public AutotoolsNewCProjectWizardV2(String title, String description) { + super(title, description); + } + /** + * Method getWzDescriptionResource, allows Wizard description label value + * to be changed by subclasses + * + * @return String + */ + protected static String getWzDescriptionResource() { + return AutotoolsUIPlugin.getResourceString(WZ_DESC); + } + + /** + * Method getWzTitleResource, allows Wizard description label value + * to be changed by subclasses + * + * @return String + */ + protected static String getWzTitleResource() { + return AutotoolsUIPlugin.getResourceString(WZ_TITLE); + } + + /** + * Method getWindowTitleResource, allows Wizard Title label value to be + * changed by subclasses + * + * @return String + */ + protected static String getWindowTitleResource() { + return AutotoolsUIPlugin.getResourceString(WINDOW_TITLE); + } + + /** + * Method getPrefix, allows prefix value to be changed by subclasses + * + * @return String + */ + protected static String getPrefix() { + return PREFIX; + } + + public void addPages() { + // Add the default page for all new projects + super.addPages(); + + // Add the configuration selection page + projectConfigurationPage = new CProjectPlatformPage(PREFIX, this); + projectConfigurationPage.setTitle(AutotoolsUIPlugin.getResourceString(CONF_TITLE)); + projectConfigurationPage.setDescription(AutotoolsUIPlugin.getResourceString(CONF_DESC)); + addPage(projectConfigurationPage); + + // Add the options (tabbed) page + optionPage = new NewAutotoolsProjectOptionPage(PREFIX, this); + optionPage.setTitle(AutotoolsUIPlugin.getResourceString(OPTIONS_TITLE)); + optionPage.setDescription(AutotoolsUIPlugin.getResourceString(OPTIONS_DESC)); + addPage(optionPage); + + // add custom pages + MBSCustomPageManager.init(); + + // add stock pages + MBSCustomPageManager.addStockPage(fMainPage, NewCProjectWizardPage.PAGE_ID); + MBSCustomPageManager.addStockPage(projectConfigurationPage, CProjectPlatformPage.PAGE_ID); + MBSCustomPageManager.addStockPage(optionPage, NewAutotoolsProjectOptionPage.PAGE_ID); + + } + + public void createPageControls(Composite pageContainer) { + super.createPageControls( pageContainer ); + + IWizardPage [] pages = getPages(); + + if (pages != null) { + for (int i = 0; i < pages.length; i++) { + IWizardPage page = pages[i]; + if (page instanceof NewCProjectWizardPage) { + // Setup the help information + PlatformUI.getWorkbench().getHelpSystem().setHelp(pageContainer, CDTHelpContextIds.MAN_PROJ_WIZ_NAME_PAGE); + } + else if (page instanceof NewAutotoolsProjectOptionPage) { + NewAutotoolsProjectOptionPage optionPage = (NewAutotoolsProjectOptionPage) page; + optionPage.setupHelpContextIds(); + } + // The other built-in page is the CProjectPlatformPage which already has a help id. + } + } + } + + public void updateProjectTypeProperties() { + // Update the error parser list + optionPage.updateProjectTypeProperties(); + } + + protected void addNature(IProgressMonitor monitor) throws CoreException { + monitor.beginTask("", 4); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_NATURE)); + ManagedCProjectNature.addManagedNature(newProject, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_BUILDER)); + ManagedCProjectNature.addManagedBuilder(newProject, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_NATURE)); + AutotoolsNewProjectNature.addAutotoolsNature(newProject, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_BUILDER)); + AutotoolsNewProjectNature.addAutotoolsBuilder(newProject, new SubProgressMonitor(monitor, 1)); + monitor.done(); + } + + public IProjectType getProjectType() { + return projectConfigurationPage.getProjectType(); + } + + protected void doRun(IProgressMonitor monitor) throws CoreException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + // super.doRun() just creates the project and does not assign a builder to it. + super.doRun(new SubProgressMonitor(monitor, 5)); + + // Add the managed build nature and builder + try { + addNature(new SubProgressMonitor(monitor, 2)); + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + } + // FIXME: Default scanner property: make -w - eventually we want to use Make core's build scanner + newProject.setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, AutotoolsPropertyConstants.TRUE); + + CCorePlugin.getDefault().mapCProjectOwner(newProject, getProjectID(), true); + + // Add the ManagedProject to the project + IManagedProject newManagedProject = null; + IManagedBuildInfo info = null; + try { + info = ManagedBuildManager.createBuildInfo(newProject); + IProjectType parent = getProjectType(); + newManagedProject = ManagedBuildManager.createManagedProject(newProject, parent); + if (newManagedProject != null) { + IConfiguration [] selectedConfigs = getSelectedConfigurations(); + for (int i = 0; i < selectedConfigs.length; i++) { + IConfiguration config = selectedConfigs[i]; + int id = ManagedBuildManager.getRandomNumber(); + IConfiguration newConfig = newManagedProject.createConfiguration(config, config.getId() + "." + id); //$NON-NLS-1$ + newConfig.setArtifactName(newManagedProject.getDefaultArtifactName()); + } + // Now add the first supported config in the list as the default + IConfiguration defaultCfg = null; + IConfiguration[] newConfigs = newManagedProject.getConfigurations(); + for(int i = 0; i < newConfigs.length; i++) { + if(newConfigs[i].isSupported()){ + defaultCfg = newConfigs[i]; + break; + } + } + + if(defaultCfg == null && newConfigs.length > 0) + defaultCfg = newConfigs[0]; + + if(defaultCfg != null) { + ManagedBuildManager.setDefaultConfiguration(newProject, defaultCfg); + ManagedBuildManager.setSelectedConfiguration(newProject, defaultCfg); + } + ManagedBuildManager.setNewProjectVersion(newProject); + ICDescriptor desc = null; + try { + desc = CCorePlugin.getDefault().getCProjectDescription(newProject, true); + desc.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, ManagedBuildManager.INTERFACE_IDENTITY); + // TODO: The binary parser setting is currently per-project in the rest of CDT. + // In the MBS, it is per-coonfiguration. For now, select the binary parsers of the + // first configuration. +// if (newConfigs.length > 0) { +// IToolChain tc = newConfigs[0].getToolChain(); +// ITargetPlatform targetPlatform = tc.getTargetPlatform(); +// } + } catch (CoreException e) { + AutotoolsUIPlugin.log(e); + } + } + } catch (BuildException e) { + AutotoolsUIPlugin.log(e); + } + + // Following is a bit of a hack because changing the project options + // causes a change event to be fired which will try to reindex the project. + // We are in the middle of setting the project indexer which may end up + // being the null indexer. In that case, we don't want the default indexer + // (Fast Indexer) to be invoked. + //IPDOMManager manager = CCorePlugin.getPDOMManager(); + //ICProject cproject = CoreModel.getDefault().create(newProject); + //manager.setIndexerId(cproject, ConvertToAutotoolsProjectWizard.NULL_INDEXER_ID); + + // Modify the project settings + if (newProject != null) { + optionPage.performApply(new SubProgressMonitor(monitor, 2)); + } + + // Save the build options + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_SAVE)); + if (info != null) { + info.setValid(true); + ManagedBuildManager.saveBuildInfo(newProject, true); + } + + IStatus initResult = ManagedBuildManager.initBuildInfoContainer(newProject); + if (initResult.getCode() != IStatus.OK) { + // At this point, I can live with a failure + AutotoolsUIPlugin.log(initResult); + } + + monitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#doRunPrologue(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void doRunPrologue(IProgressMonitor monitor) { + // Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#doRunEpilogue(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void doRunEpilogue(IProgressMonitor monitor) { + // Get my initializer to run + if(newProject == null) + return; + + IStatus initResult = ManagedBuildManager.initBuildInfoContainer(newProject); + if (initResult.getCode() != IStatus.OK) { + // At this point, I can live with a failure + AutotoolsUIPlugin.log(initResult); + } + + // execute any operations specified by custom pages + // execute any operations specified by custom pages + IRunnableWithProgress operations[] = MBSCustomPageManager.getOperations(); + + if (operations != null) + { + for(int k = 0; k < operations.length; k++) + { + try { + operations[k].run(monitor); + } catch(InvocationTargetException e) { + //TODO: what should we do? + } catch(InterruptedException e) { + //TODO: what should we do? + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#getProjectID() + */ + public String getProjectID() { +// return "org.eclipse.cdt.make.core.make"; //$NON-NLS-1$ + return ManagedBuilderCorePlugin.MANAGED_MAKE_PROJECT_ID; + } + +// public IProjectType getSelectedProjectType() { +// return projectConfigurationPage.getSelectedProjectType(); +// } + + public IConfiguration[] getSelectedConfigurations() { + return projectConfigurationPage.getSelectedConfigurations(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsWizardMessages.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsWizardMessages.java new file mode 100644 index 00000000000..4ba794aaef7 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsWizardMessages.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * Red Hat - Copy from org.eclipse.cdt.wizards to here plus rename + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @since 2.0 + */ +public class AutotoolsWizardMessages { + // Bundle ID + private static final String BUNDLE_ID = AutotoolsWizardMessages.class.getName(); + //Resource bundle. + private static ResourceBundle resourceBundle; + + static { + try { + resourceBundle = ResourceBundle.getBundle(BUNDLE_ID); + } catch (MissingResourceException x) { + resourceBundle = null; + } + } + + public static String getFormattedString(String key, String arg) { + return MessageFormat.format(getResourceString(key), new Object[] { arg }); + } + + public static String getFormattedString(String key, String[] args) { + return MessageFormat.format(getResourceString(key), (Object[])args); + } + + public static String getResourceString(String key) { + try { + return resourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$ + } catch (NullPointerException e) { + return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + private AutotoolsWizardMessages() { + // No constructor + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsWizardMessages.properties b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsWizardMessages.properties new file mode 100644 index 00000000000..00732afa9db --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/AutotoolsWizardMessages.properties @@ -0,0 +1,368 @@ +############################################################################### +# Copyright (c) 2000, 2006, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM - Initial API and implementation +# Red Hat - Copy to AutotoolsWizardMessages.properties +############################################################################### + +# ------- Project Update Messages ------- +ManagedBuilderStartup.update.20x.title=Update Managed Make Project +ManagedBuilderStartup.update.20x.message=The project {0} has been detected in your workspace.\n Its build settings are stored in a format that is no longer supported.\n Would you like to convert them now? + +AutotoolsBuildWizard.0=GNU Autotools project +AutotoolsBuildWizard.1=Others +AutotoolsBuildWizard.2=Empty Project + +# ------- NewProjectCreationPluginPage------- +MngMakeProjectWizard.op_error=Managed Make Error +MngMakeProjectWizard.title=Managed Make Project +MngMakeProjectWizard.description=Create a new Managed Make project. +#MngMakeProjectWizardSettings.title=Managed Make Settings +#MngMakeProjectWizardSettings.description=Define the Managed Make build settings. +MngMakeProjectWizard.message.add_nature=Adding Managed Nature +MngMakeProjectWizard.message.add_builder=Adding Makefile Generator +MngMakeProjectWizard.message.save=Saving new build options + +MngCWizard.title=Managed Make C Project +MngCWizard.description=Create a new Managed Make C project. +MngCWizardSettings.title=Managed Make C Settings +MngCWizardSettings.description=Define the Managed Make C build settings. + +MngCCWizard.title=Managed Make C++ Project +MngCCWizard.description=Create a new Managed Make C++ Project. +MngCCWizard.message.creating=Creating a new C++ Project with a makefile generator +MngCCWizardSettings.title=Managed Make C++ Settings +MngCCWizardSettings.description=Define the Managed Make C++ build settings. + +ReferenceBlock_task_ReferenceProjects=Reference Projects + +# -- Strings for the platform selection page -- +MngMakeProjectWizard.config.title=Select a type of project +MngMakeProjectWizard.config.desc=Select the platform and configurations you wish to deploy on +PlatformBlock.tip.platform=Select the type of project for the build goal +PlatformBlock.tip.forcedconfigs=There are no buildable configurations on this platform for this project type.\n By default, all configurations selected. +PlatformBlock.label.platform=Project Type: +PlatformBlock.label.configs=Configurations: +PlatformBlock.label.showall=Show All Project Types +PlatformBlock.label.showall.config=Show All Configurations +PlatformBlock.label.selectAll=Select All +PlatformBlock.label.deselectAll=Deselect All +PlatformBlock.message.error.noconfigs=You must select at least one configuration + +# -- Strings for the additional options tab +MngMakeProjectWizard.options.title=Additional Project Settings +MngMakeProjectWizard.options.desc=Define the inter-project dependencies, if any. + +# ----------- Configuration Selection Page ----------- +BuildPropertyPage.label.Platform=Project Type: +BuildPropertyPage.label.Configuration=Configuration: +BuildPropertyPage.label.Active=Active configuration +BuildPropertyPage.label.Settings=Configuration Settings +BuildPropertyPage.label.AddConfButton=Manage... +BuildPropertyPage.selection.configuration.all=All configurations +BuildPropertyPage.tip.platform=Select a platform for the project +BuildPropertyPage.tip.config=Select the configuration to edit +BuildPropertyPage.tip.addconf=Add configurations for the platform +BuildPropertyPage.tip.remconf=Remove configurations for the platform +BuildPropertyPage.manage.title=Manage +BuildPropertyPage.error.Unknown_tree_element=Unknown type of element in tree of type {0} +BuildPropertyPage.error.version_low=The Managed Make project settings for this project are not available. +BuildPropertyPage.defaults.title=Reset Configuration Tools +BuildPropertyPage.defaults.message=This action will reset all of the tools in the selected configuration to their default settings.\n\nDo you want to proceed? +BuildPropertyPage.changes.save.title=Apply Configuration Changes +BuildPropertyPage.changes.save.question=You have made changes to the {0} configuration.\n\nDo you want to apply these changes before switching to the {1} configuration? +BuildPropertyPage.changes.save.error=The configuration changes could not be applied. +BuildPropertyPage.unsupported.proj=The project support is not installed on the system +BuildPropertyPage.unsupported.config=The configuration support is not installed on the system +BuildPropertyPage.config.notselected=No configurations selected + +# ----------- Managed Build Custom Wizard Page Manager Error Strings ----------- +MBSCustomPageManager.error0=Unknown element type +MBSCustomPageManager.error1=\ for extension point +MBSCustomPageManager.error2=Unknown child element type +MBSCustomPageManager.error3=\ for wizardPage element in extension point +MBSCustomPageManager.error4=Missing projectType ID +MBSCustomPageManager.error5=Missing projectType ID +MBSCustomPageManager.error6=Missing nature ID + + +# ----------- Managed Build Preference Page ----------- +BuildPreferencePage.label.Settings=Workspace Settings +BuildPreferencePage.job.rebuild=Rebuilding the Managed Projects +BuildPreferencePage.apply.internal.error=An Internal error has occured please check error log. + +#--------------- Resource Configuration Selection Page -------------- +ResourceBuildPropertyPage.defaults.title=Reset Resource Configuration Tool +ResourceBuildPropertyPage.defaults.message=This action will reset all options of the tool in the current resource configuration to their default settings.\n\nDo you want to proceed? + +# ----------- Tools Settings Block ----------- +ToolsSettingsBlock.label.Settings=Tool Settings +ToolsSettingsBlock.label.ToolTree=Tools +ToolsSettingsBlock.label.ToolOptions=Options + +# ----------- Build Settings Block ----------- +BuildSettingsBlock.label.Settings=Build Settings +BuildSettingsBlock.label.makecmdgroup=Build command +BuildSettingsBlock.label.makecmddef=Use default command +BuildSettingsBlock.label.output.group=Build output +BuildSettingsBlock.label.output.name=Artifact name: +BuildSettingsBlock.label.output.extension=Artifact extension: +BuildSettingsBlock.defaults.title=Reset Build Settings +BuildSettingsBlock.defaults.message=This action will reset the build settings to their default settings.\n\nDo you want to proceed? +BuildSettingsBlock.label.macros.group=Build Macros usage +BuildSettingsBlock.label.macros.expand=Expand Build Environment Macros +BuildSettingsBlock.label.internal.builder.group=Internal Builder +BuildSettingsBlock.label.internal.builder.enable=Enable Internal Builder +BuildSettingsBlock.label.internal.builder.ignore.err=Ignore build errorors +BuildSettingsBlock.label.internal.builder.experimental.note=NOTE: This is experimental functionality + + +# ----------- Build Steps Block ----------- +BuildStepSettingsBlock.label.Settings=Build Steps +BuildStepSettingsBlock.label.prebuildstep.group=Pre-build step: +BuildStepSettingsBlock.label.prebuildstep.cmd=Command: +BuildStepSettingsBlock.label.prebuildstep.desc=Description: +BuildStepSettingsBlock.label.postbuildstep.group=Post-build step: +BuildStepSettingsBlock.label.postbuildstep.cmd=Command: +BuildStepSettingsBlock.label.postbuildstep.desc=Description: +BuildStepsSettingsBlock.defaults.title=Reset Build Steps +BuildStepsSettingsBlock.defaults.message=This action will reset the pre-build and post-build steps to their default settings.\n\nDo you want to proceed? + +# ----------- Environment Set Block ----------- +EnvironmentSetBlock.label.environment=Environment +EnvironmentSetBlock.label.environment.group=Environment variables +EnvironmentSetBlock.label.tab.configuration=Configuration +EnvironmentSetBlock.label.tab.project=Project +EnvironmentSetBlock.label.tab.workspace=Workspace +EnvironmentSetBlock.label.tab.eclipse=Eclipse Environment + +# ----------- Environment Block ----------- +EnvironmentBlock.label.header.name=Name +EnvironmentBlock.label.header.value=Value +EnvironmentBlock.label.button.new=New +EnvironmentBlock.label.button.edit=Edit +EnvironmentBlock.label.button.delete=Delete +EnvironmentBlock.label.button.undef=Undefine +EnvironmentBlock.label.value.undef=<UNDEFINED> +EnvironmentBlock.label.button.check.chow.parent=Show parent level variables +EnvironmentBlock.label.user.var=User Variables +EnvironmentBlock.label.system.var=System Variables +EnvironmentBlock.label.delete.confirm.title=Variable deletion confirmation +EnvironmentBlock.label.delete.confirm.message=Are you sure you want to delete the selected user variable(s)? +EnvironmentBlock.label.delete.all.confirm.title=Variable deletion confirmation +EnvironmentBlock.label.delete.all.confirm.message=Are you sure you want to delete all user variables? + +# ----------- New Env Var Dialog ----------- +NewEnvVarDialog.label.name=Name +NewEnvVarDialog.label.value=Value +NewEnvVarDialog.label.delimiter=Delimiter +NewEnvVarDialog.label.operation=Operation +NewEnvVarDialog.label.operation.replace=Replace +NewEnvVarDialog.label.operation.prepend=Prepend +NewEnvVarDialog.label.operation.append=Append +NewEnvVarDialog.label.operation.remove=Remove +NewEnvVarDialog.label.value.prepend=Prepended Value +NewEnvVarDialog.label.value.append=Appended Value +NewEnvVarDialog.label.value.undef=<UNDEFINED> +NewEnvVarDialog.label.title.new=Define a new variable +NewEnvVarDialog.label.title.edit=Edit existing variable +NewEnvVarDialog.label.status.cannot.create=The "{0}" Variable can not be created by user + +# ----------- Macros Set Block ----------- +MacrosSetBlock.label.macros=Macros +MacrosSetBlock.label.macros.group=Macros +MacrosSetBlock.label.tab.configuration=Configuration +MacrosSetBlock.label.tab.project=Project +MacrosSetBlock.label.tab.workspace=Workspace + +# ----------- Macros Block ----------- +MacrosBlock.label.header.name=Name +MacrosBlock.label.header.type=Type +MacrosBlock.label.header.value=Value +MacrosBlock.label.button.new=New +MacrosBlock.label.button.edit=Edit +MacrosBlock.label.button.delete=Delete +MacrosBlock.label.button.check.chow.parent=Show parent context macros +MacrosBlock.label.user.macros=User Macros +MacrosBlock.label.system.macros=System Macros +MacrosBlock.label.delete.confirm.title=Macro deletion confirmation +MacrosBlock.label.delete.confirm.message=Are you sure you want to delete the selected user Macro(s)? +MacrosBlock.label.delete.all.confirm.title=Macro deletion confirmation +MacrosBlock.label.delete.all.confirm.message=Are you sure you want to delete all user macros? +MacrosBlock.label.value.eclipse.dynamic=<ECLIPSE DYNAMIC VARIABLE> +MacrosBlock.label.type.text=String +MacrosBlock.label.type.text.list=StringList +MacrosBlock.label.type.path.file=File +MacrosBlock.label.type.path.dir=Dir +MacrosBlock.label.type.path.file.list=FileList +MacrosBlock.label.type.path.dir.list=DirList +MacrosBlock.label.type.path.any=Path +MacrosBlock.label.type.path.any.list=PathList + + +# ----------- New Build Macro Dialog ----------- +NewBuildMacroDialog.label.name=Name +NewBuildMacroDialog.label.value=Value +NewBuildMacroDialog.label.type=Type +NewBuildMacroDialog.label.type.text=String +NewBuildMacroDialog.label.type.text.list=List of Strings +NewBuildMacroDialog.label.type.path.file=File +NewBuildMacroDialog.label.type.path.dir=Directory +NewBuildMacroDialog.label.type.path.file.list=List of Files +NewBuildMacroDialog.label.type.path.dir.list=List of Directories +NewBuildMacroDialog.label.type.path.any=File or Directory +NewBuildMacroDialog.label.type.path.any.list=List of Files or Directories +NewBuildMacroDialog.label.browse=Browse +NewBuildMacroDialog.label.title.new=Define a new macro +NewBuildMacroDialog.label.title.edit=Edit existing macro +NewBuildMacroDialog.label.list.title=Macro Value +NewBuildMacroDialog.label.status.cannot.create=The "{0}" Macro can not be created by user + +# ------------Resource Configuration Selection Page +ResourceBuildPropertyPage.label.ActiveResource=Active Resource configuration +ResourceBuildPropertyPage.label.ResourceSettings=Resource Configuration settings +ResourceBuildPropertyPage.label.Configuration=Configuration: +ResourceBuildPropertyPage.label.ExcludeCheckBox= Exclude from build +ResourceBuildPropertyPage.selection.configuration.all=All configurations +ResourceBuildPropertyPage.label.ToolTree=Tools +ResourceBuildPropertyPage.label.ToolOptions=Options +ResourceBuildPropertyPage.label.NotMBSFile=The project is closed or the file is not contained within a Managed Make project. +ResourceBuildPropertyPage.error.version_low=The Managed Make project settings for this project are not available. +ResourceBuildPropertyPage.tip.excludecheck=Exclude the file from building in the selected configuration +ResourceBuildPropertyPage.tip.config=Select the configuration to edit +ResourceBuildPropertyPage.unsupported.proj=The project support is not installed on the system +ResourceBuildPropertyPage.unsupported.config=The configuration support is not installed on the system +ResourceBuildPropertyPage.config.notselected=No configurations selected +ResourceBuildPropertyPage.rc.non.build=Managed Build settings for this resource are not available +ResourceBuildPropertyPage.rc.generated=The selected resource is created by the buildfile generator + +# ----------- Resource Custom Build Step Block ----------- +ResourceCustomBuildStepBlock.label.settings=Custom Build Steps +ResourceCustomBuildStepBlock.label.tool.group=Resource Custom Build Step +ResourceCustomBuildStepBlock.label.applicability=Custom Build Step Applicability +ResourceCustomBuildStepBlock.label.applicability.rule.before=Apply Custom Build Step Before Other Tools +ResourceCustomBuildStepBlock.label.applicability.rule.after=Apply Custom Build Step After Other Tools +ResourceCustomBuildStepBlock.label.applicability.rule.override=Apply Custom Build Step Overriding Other Tools +ResourceCustomBuildStepBlock.label.applicability.rule.disable=Disable Custom Build Step +ResourceCustomBuildStepBlock.label.input.filenames=Additional Input file name(s): +ResourceCustomBuildStepBlock.label.output.filenames=Output file name(s): +ResourceCustomBuildStepBlock.label.command.cmd=Command: +ResourceCustomBuildStepBlock.label.description.desc=Description: +ResourceCustomBuildStepBlock.tip.applicability=specifies how to apply the custom build step with respect to other resource configuration tools +ResourceCustomBuildStepBlock.tip.inputs=a semicolon separated list of additional input files for this build step. Paths are interpreted as relative to the Project directory. +ResourceCustomBuildStepBlock.tip.outputs=a semicolon separated list of the output files produced by this build step. Paths are interpreted as relative to the Build directory. +ResourceCustomBuildStepBlock.tip.command=a semicolon separated list of commands or a single command to be executed by this build step. Paths are interpreted as relative to the Build directory. +ResourceCustomBuildStepBlock.tip.announcement=a message to be output in the build log upon execution of this build step +ResourceCustomBuildStepBlock.defaults.title=Reset Resource Custom Build Step +ResourceCustomBuildStepBlock.defaults.message=This action will reset the resource custom build step to the default settings.\n\nDo you want to proceed? + +# ----------- Entry Dialog ----------- +BrowseEntryDialog.error.Folder_name_invalid = Folder name invalid +BrowseEntryDialog.message.file = File: +BrowseEntryDialog.message.directory = Directory: +BrowseEntryDialog.file.title.add=Add file path +BrowseEntryDialog.dir.title.add=Add directory path +BrowseEntryDialog.file.title.edit=Edit file path +BrowseEntryDialog.dir.title.edit=Edit directory path +BrowseEntryDialog.wsp.dir.dlg.title=Folder selection +BrowseEntryDialog.wsp.file.dlg.title=File selection +BrowseEntryDialog.wsp.dir.dlg.msg=Select a folder from workspace: +BrowseEntryDialog.wsp.file.dlg.msg=Select a file from workspace: +BrowseEntryDialog.wsp.file.dlg.err=The selected element is not a file. +BrowseEntryDialog.fs.dir.dlg.msg=Select a folder from file system: + +# ----------- New Configuration ----------- +NewConfiguration.label.name=Name: +NewConfiguration.label.description=Description: +NewConfiguration.label.group=Copy settings from +NewConfiguration.label.copy=Default configuration: +NewConfiguration.label.clone=Existing configuration: +NewConfiguration.label.showall=Show unsupported configurations +NewConfiguration.error.duplicateName=A configuration named "{0}" already exists. +NewConfiguration.error.caseName=A configuration name that differs only in case to "{0}" exists. +NewConfiguration.error.invalidName=The name "{0}" is invalid. + +# ----------- Rename Configuration ----------- +RenameConfiguration.label.name=Name: +RenameConfiguration.label.description=Description: +RenameConfiguration.error.duplicateName=A configuration named "{0}" already exists. +RenameConfiguration.error.caseName=A configuration name that differs only in case to "{0}" exists. +RenameConfiguration.error.invalidName=The name "{0}" is invalid. + +# ----------- Target/Config management dialog ----------------- +ManageConfig.label.configs=Manage configurations +ManageConfig.label.rename=Rename +ManageConfig.label.conversionTargetLabel=Tool chain conversion targets: +ManageConfig.label.convertTarget=Convert +ManageConfig.label.new.config.dialog=Create configuration +ManageConfig.label.rename.config.dialog=Rename configuration +ManageConfig.deletedialog.message=Are you sure you want to delete the "{0}" configuration? +ManageConfig.deletedialog.title=Confirm Delete + +# Toolchain Conversion Target confirmation Dialog +ConfigurationConvert.confirmdialog.message=Currently the "{0}" Configuration uses "{1}" tool-chain. After conversion it will use "{2}" tool-chain. Do you want to proceed? +ConfigurationConvert.confirmdialog.title=Confirm Configuration Conversion + +# ----------- Build Property Common ----------- +BuildPropertyCommon.label.title=Enter Value +BuildPropertyCommon.label.new=New... +BuildPropertyCommon.label.remove=Remove +BuildPropertyCommon.label.up=Up +BuildPropertyCommon.label.down=Down +BuildPropertyCommon.label.editVar=Edit... +BuildPropertyCommon.label.addVar=Add +BuildPropertyCommon.label.message=Value: +BuildPropertyCommon.label.browse=Browse... +BuildPropertyCommon.label.configs=Defined configurations: + +# ----------- Field Editors ----------- +Multiline.error.message=Please give correct input + +# ----------- Build Tool Settings ----------- +BuildToolSettingsPage.alloptions=All options: +BuildToolSettingsPage.tool.command=Command: +BuildToolSettingsPage.tool.commandLinePattern=Command\nline pattern: +BuildToolSettingsPage.tool.advancedSettings=Expert settings: + +# ----------- File List Control ----------- +FileListControl.add=Add +FileListControl.delete=Delete +FileListControl.edit=Edit +FileListControl.moveup=Move Up +FileListControl.movedown=Move Down +FileListControl.filedialog.title=Select File +FileListControl.dirdialog.title=Select Include Directory +FileListControl.dirdialog.desc=Select Include Paths +FileListControl.deletedialog.message=Are you sure you want to delete the selected files or directories? +FileListControl.deletedialog.title=Confirm Delete +FileListControl.editdialog.title=Edit Dialog +FileListControl.newdialog.title=New Dialog +FileListControl.button.workspace=Workspace... +FileListControl.button.fs=File system... + +# ----------- Property Page ---------- +MngMakeProjectPropertyPage.closedproject=Project Closed +MngMakeProjectPropertyPage.internalError=An Internal error has occur please check error log. + +# Copies from org.eclipse.ui.workbench +showAdvanced = &Advanced >> +hideAdvanced = << &Advanced +NewFolderDialog.folderNameEmpty = Folder name must be specified + +# Project Conversion Dialog messages +ProjectConvert.confirmdialog.title=Confirm Project Conversion +ProjectConvert.confirmdialog.message=The selected project {0} will be converted. Do you want to proceed ? + +ProjectConvert.conversionErrordialog.title=Project Conversion Error +ProjectConvert.conversionErrordialog.message=Error has occured during the conversion of the project {0} . + +ProjectConvert.noConverterErrordialog.title=Project Conversion Error +ProjectConvert.noConverterErrordialog.message=There are no converters available to convert the project {0} . + +ProjectConvert.title=Project Converters for {0} +ProjectConvert.convertersList=Converters List diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/CProjectPlatformPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/CProjectPlatformPage.java new file mode 100644 index 00000000000..fae75c497ed --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/CProjectPlatformPage.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.ui.wizards.MBSCustomPageManager; +import org.eclipse.cdt.ui.newui.CDTHelpContextIds; +import org.eclipse.cdt.ui.wizards.NewCProjectWizard; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +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.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + + +/** + * Class that implements the project type and configuration selection page in the new + * project wizard for managed builder projects. + * + * @since 1.2 + */ +public class CProjectPlatformPage extends WizardPage { + /* + * Dialog variables and string constants + */ + private static final String PREFIX = "PlatformBlock"; //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ + private static final String TIP = PREFIX + ".tip"; //$NON-NLS-1$ + private static final String CONFIG_LABEL = LABEL + ".configs"; //$NON-NLS-1$ + private static final String TARGET_LABEL = LABEL + ".platform"; //$NON-NLS-1$ + private static final String TARGET_TIP = TIP + ".platform"; //$NON-NLS-1$ + private static final String FORCEDCONFIG_TIP = TIP + ".forcedconfigs"; //$NON-NLS-1$ + + // support for exporting data to custom wizard pages + public static final String PAGE_ID = "org.eclipse.cdt.managedbuilder.ui.wizard.platformPage"; //$NON-NLS-1$ + public static final String PROJECT_TYPE = "projectType"; //$NON-NLS-1$ + public static final String TOOLCHAIN = "toolchain"; //$NON-NLS-1$ + public static final String NATURE = "nature"; //$NON-NLS-1$ + + protected Wizard parentWizard; + protected Text platformSelection; + private ArrayList<Object> selectedConfigurations; + protected IProjectType projectType; + protected Button showAllConfigs; + protected boolean showAllConfigsForced; + protected CheckboxTableViewer tableViewer; + protected IConfiguration configurations[]; + + /** + * Constructor. + * @param pageName + * @param wizard + */ + public CProjectPlatformPage(String pageName, Wizard parentWizard) { + super(pageName); + setPageComplete(false); + projectType = ManagedBuildManager.getExtensionProjectType("org.eclipse.linuxtools.cdt.autotools.core.projectType"); //$NON-NLS-1$ + selectedConfigurations = new ArrayList<Object>(0); + this.parentWizard = parentWizard; + showAllConfigsForced = false; + } + + /** + * @see org.eclipse.jface.wizard.IWizardPage#canFlipToNextPage() + */ + public boolean canFlipToNextPage() { + return validatePage(); + } + + private void createConfigSelectionGroup (Composite parent) { + // Create the group composite + Composite composite = new Composite(parent, SWT.NULL); + composite.setFont(parent.getFont()); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Create a check box table of valid configurations + final Label configLabel = new Label(composite, SWT.LEFT); + configLabel.setFont(composite.getFont()); + configLabel.setText(AutotoolsWizardMessages.getResourceString(CONFIG_LABEL)); + + Table table = new Table(composite, SWT.CHECK | SWT.BORDER | SWT.MULTI + | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + table.setHeaderVisible(true); + table.setLinesVisible(false); + + // Add a table layout to the table + TableLayout tableLayout = new TableLayout(); + table.setHeaderVisible(false); + table.setLayout(tableLayout); + + // Add the viewer + tableViewer = new CheckboxTableViewer(table); + tableViewer.setLabelProvider(new ConfigurationLabelProvider()); + tableViewer.setContentProvider(new ConfigurationContentProvider()); + tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent e) { + // will default to false until a selection is made + handleConfigurationSelectionChange(); + } + }); + + } + + /** + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + // Create the composite control for the tab + Composite composite = new Composite(parent, SWT.NULL); + composite.setFont(parent.getFont()); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Setup the help information + PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, CDTHelpContextIds.MAN_PROJ_PLATFORM_HELP); + + // Create the widgets + createTypeSelectGroup(composite); + createConfigSelectionGroup(composite); + + // Publish which project type has been chosen with the custom wizard page manager + MBSCustomPageManager.addPageProperty(PAGE_ID, PROJECT_TYPE, projectType.getId()); + + // Select configuration + populateConfigurations(); + setPageComplete(validatePage()); + + // Do the nasty + setErrorMessage(null); + setMessage(null); + setControl(composite); + } + + + private void createTypeSelectGroup(Composite parent) { + // Create the group composite + Composite composite = new Composite(parent, SWT.NULL); + composite.setFont(parent.getFont()); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Create the platform selection label and combo widgets + final Label platformLabel = new Label(composite, SWT.LEFT); + platformLabel.setFont(composite.getFont()); + platformLabel.setText(AutotoolsWizardMessages.getResourceString(TARGET_LABEL)); + + platformSelection = new Text(composite, SWT.READ_ONLY); +// platformSelection = new Combo(composite, SWT.READ_ONLY | SWT.BORDER); + platformSelection.setFont(composite.getFont()); + platformSelection.setToolTipText(AutotoolsWizardMessages.getResourceString(TARGET_TIP)); + platformSelection.setText("GNU Autotools"); //$NON-NLS-1$ + platformSelection.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + platformSelection = null; + } + }); + + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + // Make this the same as NewCProjectWizardPage.SIZING_TEXT_FIELD_WIDTH + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + 50; + platformSelection.setLayoutData(gd); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getProject() + */ + public IProject getProject() { + return ((NewCProjectWizard)getWizard()).getNewProject(); + } + + /** + * @return + */ + public IConfiguration[] getSelectedConfigurations() { + return (IConfiguration[]) selectedConfigurations.toArray(new IConfiguration[selectedConfigurations.size()]); + } + + /** + * Returns the selected project type. + * + * @return IProjectType Selected type or <code>null</code> if an invalid selection + * has been made. + */ + public IProjectType getProjectType() { + return projectType; + } + + private void handleConfigurationSelectionChange() { + // Get the selections from the table viewer + selectedConfigurations.clear(); + selectedConfigurations.addAll(Arrays.asList(tableViewer.getCheckedElements())); + + // support for publishing the toolchains for the selected configs so that custom wizard + // pages will know which toolchains have been selected + + // get the toolchains from the selected configs and put them into a set + Set<IToolChain> toolchainSet = new LinkedHashSet<IToolChain>(); + for(int k = 0; k < selectedConfigurations.size(); k++) + { + IConfiguration config = (IConfiguration) selectedConfigurations.get(k); + IToolChain toolchain = config.getToolChain(); + toolchainSet.add(toolchain); + } + + // publish the set of selected toolchains with the custom page manager + MBSCustomPageManager.addPageProperty(PAGE_ID, TOOLCHAIN, toolchainSet); + + // TODO: Don't know where this goes and how to find true nature + MBSCustomPageManager.addPageProperty(CProjectPlatformPage.PAGE_ID, CProjectPlatformPage.NATURE, CProjectNature.C_NATURE_ID); + + setPageComplete(validatePage()); + } + + /** + * Populate the table viewer with either all known configurations + * or only with the supported configurations depending on whether a user + * has chosen to display unsupported configurations or not + * By default, only supported configurations are selected. + */ + private void populateConfigurations() { + if (projectType == null) + return; + IConfiguration selected[] = null; + + configurations = filterSupportedConfigurations(projectType.getConfigurations()); + selected = configurations; + + // Check for buildable configs on this platform + if (selected.length == 0) { + // Indicate that there are no buildable configurations on this platform for this project + // type and that all configurations will be selected + setMessage(AutotoolsWizardMessages.getResourceString(FORCEDCONFIG_TIP), WARNING); + } + else { + setMessage(null, NONE); + } + + tableViewer.setInput(configurations); + tableViewer.setCheckedElements(selected); + handleConfigurationSelectionChange(); + } + + /** + * Returns the array of supported configurations found in the configurations + * passed to this method + */ + IConfiguration[] filterSupportedConfigurations(IConfiguration cfgs[]){ + ArrayList<IConfiguration> supported = new ArrayList<IConfiguration>(); + String os = Platform.getOS(); + String arch = Platform.getOSArch(); + + for (int i = 0; i < cfgs.length; i++) { + // First, filter on supported state + if (cfgs[i].isSupported()) { + // Now, apply the OS and ARCH filters to determine if the configuration should be shown + // Determine if the configuration's tool-chain supports this OS & Architecture. + IToolChain tc = cfgs[i].getToolChain(); + List<String> osList = Arrays.asList(tc.getOSList()); + if (osList.contains("all") || osList.contains(os)) { //$NON-NLS-1$ + List<String> archList = Arrays.asList(tc.getArchList()); + if (archList.contains("all") || archList.contains(arch)) { //$NON-NLS-1$ + supported.add(cfgs[i]); + } + } + } + } + return (IConfiguration[])supported.toArray(new IConfiguration[supported.size()]); + } + + + /** + * @return + */ + private boolean validatePage() { + // TODO some validation ... maybe + if ((tableViewer.getCheckedElements()).length > 0) { + setErrorMessage(null); + return true; + } else { + setErrorMessage(AutotoolsWizardMessages.getResourceString("PlatformBlock.message.error.noconfigs")); //$NON-NLS-1$ + return false; + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConfigurationContentProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConfigurationContentProvider.java new file mode 100644 index 00000000000..7f650d39fac --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConfigurationContentProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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 + * Red Hat Inc. - Copy from CDT 3.1.2 to here + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class ConfigurationContentProvider implements IStructuredContentProvider { + // The contents of the parent of the table is a list of configurations + public Object[] getElements(Object parent) { + // The content is an array of configurations + Object array[] = (Object[])parent; + return (array == null || array.length == 0) ? new Object[0] : array; + } + + public void dispose() { + } + + public void inputChanged( + Viewer viewer, + Object oldInput, + Object newInput) { + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConfigurationLabelProvider.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConfigurationLabelProvider.java new file mode 100644 index 00000000000..0414d8a2f9f --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConfigurationLabelProvider.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005, 2007 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + * Red Hat Inc. - Copy from CDT 3.1.2 to here + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + + +import org.eclipse.cdt.internal.autotools.ui.AutotoolsUIPluginImages; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + + +public class ConfigurationLabelProvider extends LabelProvider implements ITableLabelProvider { + private final Image IMG_CFG = + AutotoolsUIPluginImages.get(AutotoolsUIPluginImages.IMG_BUILD_CONFIG); + + // + public String getColumnText(Object obj, int index) { + if (obj instanceof IConfiguration) { + IConfiguration tmpConfig = (IConfiguration) obj; + + if( (tmpConfig.getDescription() == null)|| (tmpConfig.getDescription().equals("")) ) //$NON-NLS-1$ + return ((IConfiguration) obj).getName(); + else + return ( tmpConfig.getName() + " ( " + tmpConfig.getDescription() + " )"); //$NON-NLS-1$ //$NON-NLS-2$ + } + return ""; + } + + public Image getColumnImage(Object obj, int index) { + return IMG_CFG; + } +} + diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConvertToAutotoolsProjectWizard.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConvertToAutotoolsProjectWizard.java new file mode 100644 index 00000000000..8274ef4bca4 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConvertToAutotoolsProjectWizard.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.cdt.internal.autotools.ui.wizards; + + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.ui.wizards.MBSCustomPageManager; +import org.eclipse.cdt.ui.wizards.NewCProjectWizardPage; +import org.eclipse.cdt.ui.wizards.conversion.ConversionWizard; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.Wizard; + + +/** + * This wizard provides a method by which the user can + * add a C nature to a project that previously had no nature associated with it. + */ +public class ConvertToAutotoolsProjectWizard extends ConversionWizard { + + private static final String WZ_TITLE = "WizardAutotoolsProjectConversion.title"; //$NON-NLS-1$ + private static final String WZ_DESC = "WizardAutotoolsProjectConversion.description"; //$NON-NLS-1$ + private static final String PREFIX = "WizardAutotoolsConversion"; //$NON-NLS-1$ + private static final String WINDOW_TITLE = "WizardAutotoolsConversion.windowTitle"; //$NON-NLS-1$ + protected static final String CONF_TITLE = PREFIX + ".config.title"; //$NON-NLS-1$ + protected static final String CONF_DESC = PREFIX + ".config.desc"; //$NON-NLS-1$ + protected static final String MSG_SAVE = PREFIX + ".message.save"; //$NON-NLS-1$ + protected static final String OPTIONS_TITLE = PREFIX + ".options.title"; //$NON-NLS-1$ + protected static final String OPTIONS_DESC = PREFIX + ".options.desc"; //$NON-NLS-1$ + + public static final String NULL_INDEXER_ID = "org.eclipse.cdt.core.nullindexer"; //$NON-NLS-1$ + + protected CProjectPlatformPage projectConfigurationPage; + protected NewAutotoolsProjectOptionPage optionPage; + + protected IProject curProject; + + /** + * ConvertToAutotoolsConversionWizard Wizard constructor + */ + public ConvertToAutotoolsProjectWizard() { + this(getWindowTitleResource(), getWzDescriptionResource()); + } + /** + * ConvertToAutotoolsConversionWizard Wizard constructor + * + * @param title + * @param desc + */ + public ConvertToAutotoolsProjectWizard(String title, String desc) { + super(title, desc); + } + + /** + * Method getWzDescriptionResource, allows Wizard description label value + * to be changed by subclasses + * + * @return String + */ + protected static String getWzDescriptionResource() { + return AutotoolsUIPlugin.getResourceString(WZ_DESC); + } + + /** + * Method getWzTitleResource, allows Wizard description label value + * to be changed by subclasses + * + * @return String + */ + protected static String getWzTitleResource() { + return AutotoolsUIPlugin.getResourceString(WZ_TITLE); + } + + /** + * Method getWindowTitleResource, allows Wizard Title label value to be + * changed by subclasses + * + * @return String + */ + protected static String getWindowTitleResource() { + return AutotoolsUIPlugin.getResourceString(WINDOW_TITLE); + } + + /** + * Method getPrefix, allows prefix value to be changed by subclasses + * + * @return String + */ + protected static String getPrefix() { + return PREFIX; + } + + /** + * Method addPages adds our Simple to C conversion Wizard page. + * + * @see Wizard#createPages + */ + public void addPages() { + addPage(mainPage = new ConvertToAutotoolsProjectWizardPage(getPrefix(), this)); + + // Add the configuration selection page + projectConfigurationPage = new CProjectPlatformPage(PREFIX, this); + projectConfigurationPage.setTitle(AutotoolsUIPlugin.getResourceString(CONF_TITLE)); + projectConfigurationPage.setDescription(AutotoolsUIPlugin.getResourceString(CONF_DESC)); + addPage(projectConfigurationPage); + + // Add the options (tabbed) page + optionPage = new NewAutotoolsProjectOptionPage(PREFIX, this); + optionPage.setTitle(AutotoolsUIPlugin.getResourceString(OPTIONS_TITLE)); + optionPage.setDescription(AutotoolsUIPlugin.getResourceString(OPTIONS_DESC)); + addPage(optionPage); + + // add custom pages + MBSCustomPageManager.init(); + + // add stock pages + MBSCustomPageManager.addStockPage(fMainPage, NewCProjectWizardPage.PAGE_ID); + MBSCustomPageManager.addStockPage(projectConfigurationPage, CProjectPlatformPage.PAGE_ID); + MBSCustomPageManager.addStockPage(optionPage, NewAutotoolsProjectOptionPage.PAGE_ID); + } + + public String getProjectID() { + return ManagedBuilderCorePlugin.MANAGED_MAKE_PROJECT_ID; + } + + public IProjectType getProjectType() { + return projectConfigurationPage.getProjectType(); + } + + public IConfiguration[] getSelectedConfigurations() { + return projectConfigurationPage.getSelectedConfigurations(); + } + + protected void setCurrentProject (IProject project) { + curProject = project; + } + + public IProject getProject() { + return curProject; + } + + @SuppressWarnings("deprecation") + public void applyOptions(IProject project, IProgressMonitor monitor) { + // When applying the project options, we need to specify which + // project because the conversion wizard allows us to convert + // more than one project at once. We accomplish this by setting + // the current project we are working on. The optionPage when + // applying options will ask the wizard (us) to get the project which + // we will report is the current project being converted. + setCurrentProject(project); + optionPage.performApply(monitor); + } + + protected void doRun(IProgressMonitor monitor) throws CoreException { + monitor.beginTask(AutotoolsUIPlugin.getResourceString("WizardAutotoolsProjectConversion.monitor.convertingToMakeProject"), 2); //$NON-NLS-1$ + try { + super.doRun(new SubProgressMonitor(monitor, 5)); + } finally { + monitor.done(); + } + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#doRunPrologue(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void doRunPrologue(IProgressMonitor monitor) { + // Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizard#doRunEpilogue(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void doRunEpilogue(IProgressMonitor monitor) { + // Get my initializer to run +// if (project == null) +// return; +// +// IStatus initResult = ManagedBuildManager.initBuildInfoContainer(project); +// if (initResult.getCode() != IStatus.OK) { +// // At this point, I can live with a failure +// ManagedBuilderUIPlugin.log(initResult); +// } + + // execute any operations specified by custom pages + IRunnableWithProgress operations[] = MBSCustomPageManager.getOperations(); + + if (operations != null) + { + for(int k = 0; k < operations.length; k++) + { + try { + operations[k].run(monitor); + } catch(InvocationTargetException e) { + //TODO: what should we do? + } catch(InterruptedException e) { + //TODO: what should we do? + } + } + } + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConvertToAutotoolsProjectWizardPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConvertToAutotoolsProjectWizardPage.java new file mode 100644 index 00000000000..400727ec5fc --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ConvertToAutotoolsProjectWizardPage.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.cdt.internal.autotools.ui.wizards; + + +import org.eclipse.cdt.autotools.core.AutotoolsNewProjectNature; +import org.eclipse.cdt.autotools.ui.AutotoolsUIPlugin; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.internal.autotools.core.AutotoolsPropertyConstants; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; +import org.eclipse.cdt.ui.wizards.conversion.ConvertProjectWizardPage; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; + + +/** + * + * ConvertToAutotoolsProjectWizardPage + * Standard main page for a wizard that adds a Managed Make C project Nature to a project with no nature associated with it. + * This conversion is one way in that the project cannot be converted back (i.e have the nature removed). + * + * @author Jeff Johnston + * @since Feb 8, 2006 + *<p> + * Example useage: + * <pre> + * mainPage = new ConvertToAutotoolsProjectWizardPage("ConvertProjectPage"); + * mainPage.setTitle("Project Conversion"); + * mainPage.setDescription("Add C or C++ Managed Make Nature to a project."); + * </pre> + * </p> + */ +public class ConvertToAutotoolsProjectWizardPage extends ConvertProjectWizardPage { + + private static final String WZ_TITLE = "WizardAutotoolsProjectConversion.title"; //$NON-NLS-1$ + private static final String WZ_DESC = "WizardAutotoolsProjectConversion.description"; //$NON-NLS-1$ + private static final String PREFIX = "WizardAutotoolsProjectConversion"; + protected static final String MSG_ADD_NATURE = PREFIX + ".message.add_nature"; //$NON-NLS-1$ + protected static final String MSG_ADD_BUILDER = PREFIX + ".message.add_builder"; //$NON-NLS-1$ + protected static final String MSG_SAVE = PREFIX + ".message.save"; //$NON-NLS-1$ + + /** + * Constructor for ConvertToStdMakeProjectWizardPage. + * @param pageName + */ + public ConvertToAutotoolsProjectWizardPage(String pageName, ConvertToAutotoolsProjectWizard wizard) { + super(pageName); + setWizard(wizard); + } + + /** + * Method getWzTitleResource returns the correct Title Label for this class + * overriding the default in the superclass. + */ + protected String getWzTitleResource(){ + return AutotoolsUIPlugin.getResourceString(WZ_TITLE); + } + + /** + * Method getWzDescriptionResource returns the correct description + * Label for this class overriding the default in the superclass. + */ + protected String getWzDescriptionResource(){ + return AutotoolsUIPlugin.getResourceString(WZ_DESC); + } + + /** + * Method isCandidate returns true for all projects. + * + * @param project + * @return boolean + */ + public boolean isCandidate(IProject project) { + return true; // all + } + + protected IProjectType getProjectType() { + return ((ConvertToAutotoolsProjectWizard)getWizard()).getProjectType(); + } + + protected IConfiguration[] getSelectedConfigurations() { + return ((ConvertToAutotoolsProjectWizard)getWizard()).getSelectedConfigurations(); + } + + protected void applyOptions(IProject project, IProgressMonitor monitor) { + ((ConvertToAutotoolsProjectWizard)getWizard()).applyOptions(project, monitor); + } + + public void convertProject(IProject project, IProgressMonitor monitor, String projectID) throws CoreException { + monitor.beginTask(AutotoolsUIPlugin.getResourceString("WizardMakeProjectConversion.monitor.convertingToMakeProject"), 7); //$NON-NLS-1$ + IConfiguration defaultCfg = null; + try { + super.convertProject(project, new SubProgressMonitor(monitor, 1), projectID); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_NATURE)); + ManagedCProjectNature.addManagedNature(project, new SubProgressMonitor(monitor, 1)); + AutotoolsNewProjectNature.addAutotoolsNature(project, new SubProgressMonitor(monitor, 1)); + // We need to remove any old Autotools nature, if one exists. + AutotoolsNewProjectNature.removeOldAutotoolsNature(project, new SubProgressMonitor(monitor, 1)); + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_ADD_BUILDER)); +// ManagedCProjectNature.addManagedBuilder(project, new SubProgressMonitor(monitor, 1)); + AutotoolsNewProjectNature.addAutotoolsBuilder(project, new SubProgressMonitor(monitor,1)); + // FIXME: Default scanner property: make -w - eventually we want to use Make core's build scanner + project.setPersistentProperty(AutotoolsPropertyConstants.SCANNER_USE_MAKE_W, AutotoolsPropertyConstants.TRUE); + // Specify false for override in next call as override can cause the method to throw an + // exception. + CCorePlugin.getDefault().mapCProjectOwner(project, projectID, false); + // Add the ManagedProject to the project + IManagedProject newManagedProject = null; + IManagedBuildInfo info = null; + try { + info = ManagedBuildManager.createBuildInfo(project); + IProjectType parent = getProjectType(); + newManagedProject = ManagedBuildManager.createManagedProject(project, parent); + if (newManagedProject != null) { + IConfiguration [] selectedConfigs = getSelectedConfigurations(); + for (int i = 0; i < selectedConfigs.length; i++) { + IConfiguration config = selectedConfigs[i]; + int id = ManagedBuildManager.getRandomNumber(); + IConfiguration newConfig = newManagedProject.createConfiguration(config, config.getId() + "." + id); //$NON-NLS-1$ + newConfig.setArtifactName(newManagedProject.getDefaultArtifactName()); + } + // Now add the first supported config in the list as the default + IConfiguration[] newConfigs = newManagedProject.getConfigurations(); + for(int i = 0; i < newConfigs.length; i++) { + if(newConfigs[i].isSupported()){ + defaultCfg = newConfigs[i]; + break; + } + } + + if(defaultCfg == null && newConfigs.length > 0) + defaultCfg = newConfigs[0]; + + + if(defaultCfg != null) { + ManagedBuildManager.setDefaultConfiguration(project, defaultCfg); + ManagedBuildManager.setSelectedConfiguration(project, defaultCfg); + } + ManagedBuildManager.setNewProjectVersion(project); + } + } catch (BuildException e) { + AutotoolsUIPlugin.log(e); + } + + // Following is a bit of a hack because changing the project options + // causes a change event to be fired which will try to reindex the project. + // We are in the middle of setting the project indexer which may end up + // being the null indexer. In that case, we don't want the default indexer + // (Fast Indexer) to be invoked. + //IIndexManager manager = CCorePlugin.getIndexManager(); + //ICProject cproject = CoreModel.getDefault().create(project); + //manager.setIndexerId(cproject, ConvertToAutotoolsProjectWizard.NULL_INDEXER_ID); + + // Modify the project settings + if (project != null) { + applyOptions(project, new SubProgressMonitor(monitor, 2)); + } + +// Set the ScannerInfoProvider. We must do this after +// applying the options because changing the ScannerInfoProvider +// is considered a change to the project and a reindex will +// occur. One of the options being applied above is the indexer +// selected by the user. Thus, we wait until now. +// try { +// AutotoolsUIPlugin.setScannerInfoProvider(project); +// } catch (CoreException e) { +// ManagedBuilderUIPlugin.log(e); +// } + + // Save the build options + monitor.subTask(AutotoolsUIPlugin.getResourceString(MSG_SAVE)); + if (info != null) { + info.setValid(true); + ManagedBuildManager.saveBuildInfo(project, true); + } + } finally { + // Create a default Autotools configuration and save it. + // We must do this after the ManagedBuildManager does a save because + // we might not yet have a Configuration Description set up for the + // default configuration and we need the id to create our own form + // of configuration. + ICConfigurationDescription cfgd = ManagedBuildManager.getDescriptionForConfiguration(defaultCfg); + String id = cfgd.getId(); + AutotoolsConfigurationManager.getInstance().getConfiguration(project, id, true); + AutotoolsConfigurationManager.getInstance().saveConfigs(project); + IStatus initResult = ManagedBuildManager.initBuildInfoContainer(project); + if (initResult.getCode() != IStatus.OK) { + // At this point, I can live with a failure + AutotoolsUIPlugin.log(initResult); + } + monitor.done(); + } + } + + public void createControl(Composite parent) { + super.createControl(parent); + IStructuredSelection sel = ((BasicNewResourceWizard)getWizard()).getSelection(); + if ( sel != null) { + tableViewer.setCheckedElements(sel.toArray()); + setPageComplete(validatePage()); + } + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ManagedProjectOptionBlock.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ManagedProjectOptionBlock.java new file mode 100644 index 00000000000..8853ec815cb --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ManagedProjectOptionBlock.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * 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 + * Red Hat - Copy from CDT 3.1.2 + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import org.eclipse.cdt.internal.autotools.ui.ErrorParserBlock; +import org.eclipse.cdt.ui.dialogs.BinaryParserBlock; +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock; +import org.eclipse.cdt.ui.newui.CDTHelpContextIds; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.PlatformUI; + + +@SuppressWarnings("deprecation") +public class ManagedProjectOptionBlock extends TabFolderOptionBlock { + + private ErrorParserBlock errParserBlock; + private BinaryParserBlock binaryParserBlock; + + /** + * @param parent + */ + public ManagedProjectOptionBlock(ICOptionContainer parent) { + super(parent, false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock#addTabs() + */ + protected void addTabs() { + errParserBlock = new ErrorParserBlock(null); + addTab(errParserBlock); + addTab(binaryParserBlock = new BinaryParserBlock()); + } + + public BinaryParserBlock getBinaryParserBlock() { + return binaryParserBlock; + } + + public ErrorParserBlock getErrorParserBlock() { + return errParserBlock; + } + + public Control createContents(Composite parent) { + Control control = super.createContents( parent ); + ((GridLayout)((Composite)control).getLayout()).marginWidth = 1; + GridData gd = new GridData(GridData.FILL_BOTH); + ((Composite)control).setLayoutData(gd); + + if (getErrorParserBlock()!= null) + PlatformUI.getWorkbench().getHelpSystem().setHelp(getErrorParserBlock().getControl(), CDTHelpContextIds.MAN_PROJ_ERROR_PARSER); + + return control; + } + + public void updateValues() { + if (getErrorParserBlock()!= null) { + getErrorParserBlock().updateValues(); + } + if (getBinaryParserBlock()!= null) { + // TODO + //getBinaryParserBlock().updateValues(); + } + } + + public void update() { + super.update(); + } +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/NewAutotoolsProjectOptionPage.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/NewAutotoolsProjectOptionPage.java new file mode 100644 index 00000000000..4a39f28f285 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/NewAutotoolsProjectOptionPage.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2002, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.internal.autotools.ui.ErrorParserBlock; +import org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin; +import org.eclipse.cdt.managedbuilder.ui.wizards.MBSCustomPageManager; +import org.eclipse.cdt.ui.dialogs.ICOptionPage; +import org.eclipse.cdt.ui.dialogs.IndexerBlock; +import org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock; +import org.eclipse.cdt.ui.newui.CDTHelpContextIds; +import org.eclipse.cdt.ui.wizards.NewCProjectWizard; +import org.eclipse.cdt.ui.wizards.NewCProjectWizardOptionPage; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.ui.PlatformUI; + + +@SuppressWarnings("deprecation") +public class NewAutotoolsProjectOptionPage extends NewCProjectWizardOptionPage { + + public static final String PAGE_ID = "org.eclipse.cdt.managedbuilder.ui.wizard.projectOptionsPage"; //$NON-NLS-1$ + + public static class ManagedWizardOptionBlock extends ManagedProjectOptionBlock { + + NewAutotoolsProjectOptionPage parent; + IndexerBlock indexBlock; + + + public ManagedWizardOptionBlock(NewAutotoolsProjectOptionPage parentPage) { + super(parentPage); + parent = parentPage; + } + + public class AutotoolsReferenceBlock extends ReferenceBlock { + AutotoolsReferenceBlock() { + super(); + } + + public void performApply(IProgressMonitor monitor) throws CoreException { + try { + super.performApply(monitor); + } catch (RuntimeException e) { + // TODO: Fix ReferenceBlock not to generate NullPointerException + // when no projects are referenced + } + } + } + public void updateProjectTypeProperties() { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock#addTabs() + */ + protected void addTabs() { + addTab(new AutotoolsReferenceBlock()); + // NOTE: The setting of error parsers is commented out here + // because they need to be set per-configuration. + // The other tabs on this page are per-project. + // Error parsers can be selected per configuration in the + // project properties + //errorParsers = new ErrorParserBlock(); + //addTab(errorParsers); + addTab(indexBlock = new IndexerBlock()); + } + + public void setupHelpContextIds(){ + List<ICOptionPage> pages = getOptionPages(); + + Iterator<ICOptionPage> iter = pages.iterator(); + for( int i = 0; i < 3 && iter.hasNext(); i++ ) { + ICOptionPage page = (ICOptionPage) iter.next(); + + String id = null; + if (page instanceof ReferenceBlock) { + id = CDTHelpContextIds.MAN_PROJ_WIZ_PROJECTS_TAB; + } else if (page instanceof ErrorParserBlock) { + id = CDTHelpContextIds.MAN_PROJ_WIZ_ERRORPARSERS_TAB; + } else if (page instanceof IndexerBlock) { + id = CDTHelpContextIds.MAN_PROJ_WIZ_INDEXER_TAB; + } + PlatformUI.getWorkbench().getHelpSystem().setHelp(page.getControl(), id); + } + } + } + + protected ManagedWizardOptionBlock optionBlock; + protected NewCProjectWizard parentWizard; + + /** + * @param pageName + */ + public NewAutotoolsProjectOptionPage(String pageName, NewCProjectWizard parentWizard) { + super(pageName); + this.parentWizard = parentWizard; + optionBlock = new ManagedWizardOptionBlock(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.wizards.NewCProjectWizardOptionPage#createOptionBlock() + */ + protected TabFolderOptionBlock createOptionBlock() { + return optionBlock; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getProject() + */ + public IProject getProject() { + if (getWizard() instanceof ConvertToAutotoolsProjectWizard) + return ((ConvertToAutotoolsProjectWizard)getWizard()).getProject(); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getPreferenceStore() + */ + public Preferences getPreferences() { + return ManagedBuilderUIPlugin.getDefault().getPluginPreferences(); + } + + public void updateProjectTypeProperties() { + // Update the error parser list + optionBlock.updateProjectTypeProperties(); + } + + public void setupHelpContextIds(){ + optionBlock.setupHelpContextIds(); + } + + public IWizardPage getNextPage() + { + return MBSCustomPageManager.getNextPage(PAGE_ID); // get first custom page, if any + } + +} diff --git a/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ReferenceBlock.java b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ReferenceBlock.java new file mode 100644 index 00000000000..15923b8dd76 --- /dev/null +++ b/build/org.eclipse.cdt.autotools.ui/src/org/eclipse/cdt/internal/autotools/ui/wizards/ReferenceBlock.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2003, 2010 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.ui.wizards; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.model.WorkbenchContentProvider; +import org.eclipse.ui.model.WorkbenchLabelProvider; + +/** + * @deprecated as of CDT 4.0. This Block was used for New Project Wizard + * for 3.X style projects. + * + * @noextend This class is not intended to be subclassed by clients. + */ +@Deprecated +public class ReferenceBlock extends AbstractCOptionPage { + + private static final String PREFIX = "ReferenceBlock"; // $NON-NLS-1$ //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; // $NON-NLS-1$ //$NON-NLS-1$ + private static final String DESC = PREFIX + ".desc"; // $NON-NLS-1$ //$NON-NLS-1$ + + private CheckboxTableViewer referenceProjectsViewer; + + private static final int PROJECT_LIST_MULTIPLIER = 10; + + public ReferenceBlock() { + super(CUIPlugin.getResourceString(LABEL)); + setDescription(CUIPlugin.getResourceString(DESC)); + } + + @Override + public Image getImage() { + return PlatformUI.getWorkbench().getSharedImages().getImage(IDE.SharedImages.IMG_OBJ_PROJECT); + } + + /** + * Returns a content provider for the reference project + * viewer. It will return all projects in the workspace. + * + * @return the content provider + */ + protected IStructuredContentProvider getContentProvider() { + return new WorkbenchContentProvider() { + @Override + public Object[] getChildren(Object element) { + if (!(element instanceof IWorkspace)) + return new Object[0]; + ArrayList<IProject> aList = new ArrayList<IProject>(15); + final IProject[] projects = ((IWorkspace)element).getRoot().getProjects(); + for (int i = 0; i < projects.length; i++) { + if (CoreModel.hasCNature(projects[i])) { + // Do not show the actual project being look at + if ((getContainer().getProject() != null) && getContainer().getProject().equals(projects[i])) { + continue; + } + aList.add(projects[i]); + } + } + return aList.toArray(); + } + }; + } + + protected void initializeValues () { + if (getContainer().getProject() != null) { + try { + IProject[] referenced = getContainer().getProject().getReferencedProjects(); + referenceProjectsViewer.setCheckedElements(referenced); + } catch (CoreException e) { + } + } + } + + /** + * Returns the referenced projects selected by the user. + * + * @return the referenced projects + */ + public IProject[] getReferencedProjects() { + Object[] elements = referenceProjectsViewer.getCheckedElements(); + IProject[] projects = new IProject[elements.length]; + System.arraycopy(elements, 0, projects, 0, elements.length); + return projects; + } + + @Override + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label label = new Label(composite, SWT.LEFT); + label.setText(CUIPlugin.getResourceString(DESC)); + GridData lbldata = new GridData(GridData.FILL_HORIZONTAL); + lbldata.horizontalSpan = 1; + label.setLayoutData(lbldata); + + + referenceProjectsViewer = + CheckboxTableViewer.newCheckList(composite, SWT.TOP | SWT.BORDER); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessHorizontalSpace = true; + data.heightHint = + getDefaultFontHeight( + referenceProjectsViewer.getTable(), + PROJECT_LIST_MULTIPLIER); + + //Only set a height hint if it will not result in a cut off dialog + referenceProjectsViewer.getTable().setLayoutData(data); + + referenceProjectsViewer.setLabelProvider(new WorkbenchLabelProvider()); + referenceProjectsViewer.setContentProvider(getContentProvider()); + referenceProjectsViewer.setInput(ResourcesPlugin.getWorkspace()); + + initializeValues(); + setControl(composite); + } + + /** + * Get the defualt widget height for the supplied control. + * @return int + * @param control - the control being queried about fonts + * @param lines - the number of lines to be shown on the table. + */ + private static int getDefaultFontHeight(Control control, int lines) { + FontData[] viewerFontData = control.getFont().getFontData(); + int fontHeight = 10; + + //If we have no font data use our guess + if (viewerFontData.length > 0) + fontHeight = viewerFontData[0].getHeight(); + return lines * fontHeight; + + } + + @Override + public void performApply(IProgressMonitor monitor) throws CoreException { + IProject[] refProjects = getReferencedProjects(); + if (refProjects != null) { + IProject project = getContainer().getProject(); + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(AutotoolsWizardMessages.getResourceString("ReferenceBlock_task_ReferenceProjects"), 1); + try { + IProjectDescription description = project.getDescription(); + description.setReferencedProjects(refProjects); + project.setDescription(description, new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + } + } + + } + + @Override + public void performDefaults() { + initializeValues(); + } +} |