diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 11216c0d519..bd44f8fcfd0 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -2,12 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true -Bundle-Version: 5.11.0.qualifier +Bundle-Version: 5.12.0.qualifier Bundle-Activator: org.eclipse.cdt.core.CCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.core.browser, + org.eclipse.cdt.core.build, org.eclipse.cdt.core.cdtvariables, org.eclipse.cdt.core.dom, org.eclipse.cdt.core.dom.ast, @@ -73,7 +74,11 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.core.indexer;x-internal:=true, org.eclipse.cdt.internal.core.language;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.language.settings.providers;x-internal:=true, - org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.debug.ui,org.eclipse.cdt.codan.ui", + org.eclipse.cdt.internal.core.model; + x-friends:="org.eclipse.cdt.ui, + org.eclipse.cdt.debug.core, + org.eclipse.cdt.debug.ui, + org.eclipse.cdt.codan.ui", org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.parser;x-internal:=true, org.eclipse.cdt.internal.core.parser.problem;x-internal:=true, @@ -122,6 +127,7 @@ Require-Bundle: org.eclipse.cdt.core.native;bundle-version="[5.7.0,6.0.0)";visib org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)", org.eclipse.ltk.core.refactoring;bundle-version="3.4.0", org.eclipse.text;bundle-version="[3.2.0,4.0.0)", - com.ibm.icu;bundle-version="4.4.2" + com.ibm.icu;bundle-version="4.4.2", + com.google.gson;bundle-version="2.2.4" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index d5e0020806e..f258d41eec2 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -683,6 +683,7 @@ + @@ -856,5 +857,22 @@ ordering="first"> + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core/pom.xml b/core/org.eclipse.cdt.core/pom.xml index 61c12cda467..051df4d494a 100644 --- a/core/org.eclipse.cdt.core/pom.xml +++ b/core/org.eclipse.cdt.core/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 5.11.0-SNAPSHOT + 5.12.0-SNAPSHOT org.eclipse.cdt.core eclipse-plugin diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/schema/consoleService.exsd b/core/org.eclipse.cdt.core/schema/ToolChain.exsd similarity index 60% rename from toolchains/arduino/org.eclipse.cdt.arduino.core/schema/consoleService.exsd rename to core/org.eclipse.cdt.core/schema/ToolChain.exsd index e56c770ca91..c421b87247b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/schema/consoleService.exsd +++ b/core/org.eclipse.cdt.core/schema/ToolChain.exsd @@ -1,10 +1,10 @@ - + - - - + + + [Enter description of this extension point.] @@ -12,13 +12,13 @@ - + - + - - + + @@ -39,60 +39,72 @@ - + - + - + + + + A toolchain that implements the CToolChain interface and identified with the id attribute. + + - + - + id for the toolchain. - - - + + + + + + The adaptor class for the toolchain. This is passed to getAdaptor on the CBuildConfiguration object. + + + + - + - + [Enter the first release in which this extension point appears.] - + - + [Enter extension point usage example here.] - + - + [Enter API information here.] - + - + [Enter information about supplied implementation of this extension point.] diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java index a46940444f9..0d832f38595 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java @@ -50,6 +50,7 @@ import org.eclipse.cdt.internal.core.CDTLogWriter; import org.eclipse.cdt.internal.core.CdtVarPathEntryVariableManager; import org.eclipse.cdt.internal.core.ICConsole; import org.eclipse.cdt.internal.core.PositionTrackerManager; +import org.eclipse.cdt.internal.core.build.ScannerInfoSaveParticipant; import org.eclipse.cdt.internal.core.cdtvariables.CdtVariableManager; import org.eclipse.cdt.internal.core.cdtvariables.UserVarSupplier; import org.eclipse.cdt.internal.core.dom.ast.tag.TagService; @@ -92,8 +93,8 @@ import org.osgi.framework.BundleContext; import com.ibm.icu.text.MessageFormat; /** - * CCorePlugin is the life-cycle owner of the core plug-in, and starting point for access to many - * core APIs. + * CCorePlugin is the life-cycle owner of the core plug-in, and starting point + * for access to many core APIs. * * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. @@ -103,7 +104,9 @@ public class CCorePlugin extends Plugin { public static final int STATUS_CDTPROJECT_MISMATCH = 2; public static final int CDT_PROJECT_NATURE_ID_MISMATCH = 3; /** - * Status code for core exception that is thrown if a pdom grew larger than the supported limit. + * Status code for core exception that is thrown if a pdom grew larger than + * the supported limit. + * * @since 5.2 */ public static final int STATUS_PDOM_TOO_LARGE = 4; @@ -115,7 +118,8 @@ public class CCorePlugin extends Plugin { public static final String BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + BINARY_PARSER_SIMPLE_ID; //$NON-NLS-1$ public static final String PREF_BINARY_PARSER = "binaryparser"; //$NON-NLS-1$ public static final String DEFAULT_BINARY_PARSER_SIMPLE_ID = "ELF"; //$NON-NLS-1$ - public static final String DEFAULT_BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + DEFAULT_BINARY_PARSER_SIMPLE_ID; //$NON-NLS-1$ + public static final String DEFAULT_BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." //$NON-NLS-1$ + + DEFAULT_BINARY_PARSER_SIMPLE_ID; public static final String PREF_USE_STRUCTURAL_PARSE_MODE = "useStructualParseMode"; //$NON-NLS-1$ public static final String INDEX_SIMPLE_ID = "CIndex"; //$NON-NLS-1$ @@ -150,22 +154,23 @@ public class CCorePlugin extends Plugin { /** * Name of the extension point for contributing a source code formatter */ - public static final String FORMATTER_EXTPOINT_ID = "CodeFormatter" ; //$NON-NLS-1$ + public static final String FORMATTER_EXTPOINT_ID = "CodeFormatter"; //$NON-NLS-1$ - /** - * Possible configurable option ID. - * @see #getDefaultOptions - */ - public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * + * @see #getDefaultOptions + */ + public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$ /** * IContentType id for C Source Unit */ - public static final String CONTENT_TYPE_CSOURCE = "org.eclipse.cdt.core.cSource"; //$NON-NLS-1$ + public static final String CONTENT_TYPE_CSOURCE = "org.eclipse.cdt.core.cSource"; //$NON-NLS-1$ /** * IContentType id for C Header Unit */ - public static final String CONTENT_TYPE_CHEADER = "org.eclipse.cdt.core.cHeader"; //$NON-NLS-1$ + public static final String CONTENT_TYPE_CHEADER = "org.eclipse.cdt.core.cHeader"; //$NON-NLS-1$ /** * IContentType id for C++ Source Unit */ @@ -184,22 +189,26 @@ public class CCorePlugin extends Plugin { public static final String CONTENT_TYPE_BINARYFILE = "org.eclipse.cdt.core.binaryFile"; //$NON-NLS-1$ /** - * Possible configurable option value. + * Possible configurable option value. + * * @see #getDefaultOptions() */ public static final String INSERT = "insert"; //$NON-NLS-1$ /** - * Possible configurable option value. + * Possible configurable option value. + * * @see #getDefaultOptions() */ public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$ /** - * Possible configurable option value. + * Possible configurable option value. + * * @see #getDefaultOptions() */ public static final String TAB = "tab"; //$NON-NLS-1$ /** - * Possible configurable option value. + * Possible configurable option value. + * * @see #getDefaultOptions() */ public static final String SPACE = "space"; //$NON-NLS-1$ @@ -227,24 +236,30 @@ public class CCorePlugin extends Plugin { @Override public void write(byte[] b) throws IOException { } + @Override public void write(byte[] b, int off, int len) throws IOException { } + @Override public void write(int c) throws IOException { } }; + @Override public void start(IProject project) { } + @Override public ConsoleOutputStream getOutputStream() { return nullStream; } + @Override public ConsoleOutputStream getInfoStream() { return nullStream; } + @Override public ConsoleOutputStream getErrorStream() { return nullStream; @@ -262,7 +277,9 @@ public class CCorePlugin extends Plugin { } /** - * Returns the shared working copies currently registered for the default buffer factory. + * Returns the shared working copies currently registered for the default + * buffer factory. + * * @since 5.1 */ public static IWorkingCopy[] getSharedWorkingCopies() { @@ -296,9 +313,9 @@ public class CCorePlugin extends Plugin { return fgResourceBundle; } - public static IPositionTrackerManager getPositionTrackerManager() { - return PositionTrackerManager.getInstance(); - } + public static IPositionTrackerManager getPositionTrackerManager() { + return PositionTrackerManager.getInstance(); + } public static CCorePlugin getDefault() { return fgCPlugin; @@ -312,11 +329,11 @@ public class CCorePlugin extends Plugin { try { pdomManager.shutdown(); - PositionTrackerManager.getInstance().uninstall(); + PositionTrackerManager.getInstance().uninstall(); -// if (fDescriptorManager != null) { -// fDescriptorManager.shutdown(); -// } + // if (fDescriptorManager != null) { + // fDescriptorManager.shutdown(); + // } if (fCoreModel != null) { fCoreModel.shutdown(); @@ -330,10 +347,10 @@ public class CCorePlugin extends Plugin { fPathEntryVariableManager.shutdown(); } - fNewCProjectDescriptionManager.shutdown(); - ResourceLookup.shutdown(); + fNewCProjectDescriptionManager.shutdown(); + ResourceLookup.shutdown(); - savePluginPreferences(); + savePluginPreferences(); } finally { super.stop(context); } @@ -349,11 +366,11 @@ public class CCorePlugin extends Plugin { // do harmless stuff first. cdtLog = new CDTLogWriter(CCorePlugin.getDefault().getStateLocation().append(".log").toFile()); //$NON-NLS-1$ configurePluginDebugOptions(); - PositionTrackerManager.getInstance().install(); - ResourceLookup.startup(); + PositionTrackerManager.getInstance().install(); + ResourceLookup.startup(); - // new project model needs to register the resource listener first. - CProjectDescriptionManager descManager = CProjectDescriptionManager.getInstance(); + // new project model needs to register the resource listener first. + CProjectDescriptionManager descManager = CProjectDescriptionManager.getInstance(); final Job post1 = descManager.startup(); fNewCProjectDescriptionManager = descManager; @@ -364,172 +381,198 @@ public class CCorePlugin extends Plugin { fCoreModel.startup(); pdomManager = new PDOMManager(); - final Job post2= pdomManager.startup(); + final Job post2 = pdomManager.startup(); - // bug 186755, when started after the platform has been started the job manager - // is no longer suspended. So we have to start a job at the very end to make - // sure we don't trigger a concurrent plug-in activation from within the job. + // bug 186755, when started after the platform has been started the job + // manager + // is no longer suspended. So we have to start a job at the very end to + // make + // sure we don't trigger a concurrent plug-in activation from within the + // job. post1.schedule(); post2.schedule(); + + // Save participant for toolchain data + ResourcesPlugin.getWorkspace().addSaveParticipant(PLUGIN_ID, new ScannerInfoSaveParticipant()); } /** - * TODO: Add all options here - * Returns a table of all known configurable options with their default values. - * These options allow to configure the behavior of the underlying components. - * The client may safely use the result as a template that they can modify and - * then pass to setOptions. - * - * Helper constants have been defined on CCorePlugin for each of the option ID and - * their possible constant values. - * - * Note: more options might be added in further releases. - *
-     * RECOGNIZED OPTIONS:
-     *
-     * CORE / Specify Default Source Encoding Format
-     *    Get the encoding format for translated sources. This setting is read-only, it is equivalent
-     *    to 'ResourcesPlugin.getEncoding()'.
-     *     - option id:         "org.eclipse.cdt.core.encoding"
-     *     - possible values:   { any of the supported encoding names}.
-     *     - default:           
-     * 
- * - * @return a mutable map containing the default settings of all known options - * (key type: String; value type: String) - * @see #setOptions - */ - public static HashMap getDefaultOptions() { - HashMap defaultOptions = new HashMap(10); + * TODO: Add all options here Returns a table of all known configurable + * options with their default values. These options allow to configure the + * behavior of the underlying components. The client may safely use the + * result as a template that they can modify and then pass to + * setOptions. + * + * Helper constants have been defined on CCorePlugin for each of the option + * ID and their possible constant values. + * + * Note: more options might be added in further releases. + * + *
+	 * RECOGNIZED OPTIONS:
+	 *
+	 * CORE / Specify Default Source Encoding Format
+	 *    Get the encoding format for translated sources. This setting is read-only, it is equivalent
+	 *    to 'ResourcesPlugin.getEncoding()'.
+	 *     - option id:         "org.eclipse.cdt.core.encoding"
+	 *     - possible values:   { any of the supported encoding names}.
+	 *     - default:           
+	 * 
+ * + * @return a mutable map containing the default settings of all known + * options (key type: String; value type: + * String) + * @see #setOptions + */ + public static HashMap getDefaultOptions() { + HashMap defaultOptions = new HashMap(10); - // see #initializeDefaultPluginPreferences() for changing default settings - Preferences preferences = getDefault().getPluginPreferences(); - HashSet optionNames = CModelManager.OptionNames; + // see #initializeDefaultPluginPreferences() for changing default + // settings + Preferences preferences = getDefault().getPluginPreferences(); + HashSet optionNames = CModelManager.OptionNames; - // get preferences set to their default - for (String propertyName : preferences.defaultPropertyNames()) { - if (optionNames.contains(propertyName)) - defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); - } - // get preferences not set to their default - for (String propertyName : preferences.propertyNames()) { - if (optionNames.contains(propertyName)) - defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); - } - // get encoding through resource plugin - defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); + // get preferences set to their default + for (String propertyName : preferences.defaultPropertyNames()) { + if (optionNames.contains(propertyName)) + defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); + } + // get preferences not set to their default + for (String propertyName : preferences.propertyNames()) { + if (optionNames.contains(propertyName)) + defaultOptions.put(propertyName, preferences.getDefaultString(propertyName)); + } + // get encoding through resource plugin + defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); - return defaultOptions; - } - - /** - * Helper method for returning one option value only. Equivalent to (String)CCorePlugin.getOptions().get(optionName) - * Note that it may answer null if this option does not exist. - *

- * For a complete description of the configurable options, see getDefaultOptions. - *

- * - * @param optionName the name of an option - * @return the String value of a given option - * @see CCorePlugin#getDefaultOptions - */ - public static String getOption(String optionName) { - - if (CORE_ENCODING.equals(optionName)) { - return ResourcesPlugin.getEncoding(); - } - if (CModelManager.OptionNames.contains(optionName)) { - Preferences preferences = getDefault().getPluginPreferences(); - return preferences.getString(optionName).trim(); - } - return null; - } - - /** - * Returns the table of the current options. Initially, all options have their default values, - * and this method returns a table that includes all known options. - *

- * For a complete description of the configurable options, see getDefaultOptions. - *

- * - * @return table of current settings of all options - * (key type: String; value type: String) - * @see CCorePlugin#getDefaultOptions - */ - public static HashMap getOptions() { - HashMap options = new HashMap(10); - - // see #initializeDefaultPluginPreferences() for changing default settings - Plugin plugin = getDefault(); - if (plugin != null) { - Preferences preferences = plugin.getPluginPreferences(); - HashSet optionNames = CModelManager.OptionNames; - - // get preferences set to their default - for (String propertyName : preferences.defaultPropertyNames()) { - if (optionNames.contains(propertyName)) { - options.put(propertyName, preferences.getDefaultString(propertyName)); - } - } - // get preferences not set to their default - for (String propertyName : preferences.propertyNames()) { - if (optionNames.contains(propertyName)) { - options.put(propertyName, preferences.getString(propertyName).trim()); - } - } - // get encoding through resource plugin - options.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); - } - return options; - } - - /** - * Sets the current table of options. All and only the options explicitly included in the given table - * are remembered; all previous option settings are forgotten, including ones not explicitly - * mentioned. - *

- * For a complete description of the configurable options, see getDefaultOptions. - *

- * - * @param newOptions the new options (key type: String; value type: String), - * or null to reset all options to their default values - * @see CCorePlugin#getDefaultOptions - */ - public static void setOptions(HashMap newOptions) { - - // see #initializeDefaultPluginPreferences() for changing default settings - Preferences preferences = getDefault().getPluginPreferences(); - - if (newOptions == null) { - newOptions = getDefaultOptions(); - } - for (String key : newOptions.keySet()) { - if (!CModelManager.OptionNames.contains(key)) continue; // unrecognized option - if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs - String value = newOptions.get(key); - preferences.setValue(key, value); - } - - // persist options - getDefault().savePluginPreferences(); - } + return defaultOptions; + } /** - * Create CDT console adapter for build console defined as an extension. - * See {@code org.eclipse.cdt.core.CBuildConsole} extension point. - * If the console class is instance of {@link ICConsole} it is initialized - * with context id, name and icon to be shown in the list of consoles in the + * Helper method for returning one option value only. Equivalent to + * (String)CCorePlugin.getOptions().get(optionName) Note that + * it may answer null if this option does not exist. + *

+ * For a complete description of the configurable options, see + * getDefaultOptions. + *

+ * + * @param optionName + * the name of an option + * @return the String value of a given option + * @see CCorePlugin#getDefaultOptions + */ + public static String getOption(String optionName) { + + if (CORE_ENCODING.equals(optionName)) { + return ResourcesPlugin.getEncoding(); + } + if (CModelManager.OptionNames.contains(optionName)) { + Preferences preferences = getDefault().getPluginPreferences(); + return preferences.getString(optionName).trim(); + } + return null; + } + + /** + * Returns the table of the current options. Initially, all options have + * their default values, and this method returns a table that includes all + * known options. + *

+ * For a complete description of the configurable options, see + * getDefaultOptions. + *

+ * + * @return table of current settings of all options (key type: + * String; value type: String) + * @see CCorePlugin#getDefaultOptions + */ + public static HashMap getOptions() { + HashMap options = new HashMap(10); + + // see #initializeDefaultPluginPreferences() for changing default + // settings + Plugin plugin = getDefault(); + if (plugin != null) { + Preferences preferences = plugin.getPluginPreferences(); + HashSet optionNames = CModelManager.OptionNames; + + // get preferences set to their default + for (String propertyName : preferences.defaultPropertyNames()) { + if (optionNames.contains(propertyName)) { + options.put(propertyName, preferences.getDefaultString(propertyName)); + } + } + // get preferences not set to their default + for (String propertyName : preferences.propertyNames()) { + if (optionNames.contains(propertyName)) { + options.put(propertyName, preferences.getString(propertyName).trim()); + } + } + // get encoding through resource plugin + options.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); + } + return options; + } + + /** + * Sets the current table of options. All and only the options explicitly + * included in the given table are remembered; all previous option settings + * are forgotten, including ones not explicitly mentioned. + *

+ * For a complete description of the configurable options, see + * getDefaultOptions. + *

+ * + * @param newOptions + * the new options (key type: String; value type: + * String), or null to reset all + * options to their default values + * @see CCorePlugin#getDefaultOptions + */ + public static void setOptions(HashMap newOptions) { + + // see #initializeDefaultPluginPreferences() for changing default + // settings + Preferences preferences = getDefault().getPluginPreferences(); + + if (newOptions == null) { + newOptions = getDefaultOptions(); + } + for (String key : newOptions.keySet()) { + if (!CModelManager.OptionNames.contains(key)) + continue; // unrecognized option + if (key.equals(CORE_ENCODING)) + continue; // skipped, contributed by resource prefs + String value = newOptions.get(key); + preferences.setValue(key, value); + } + + // persist options + getDefault().savePluginPreferences(); + } + + /** + * Create CDT console adapter for build console defined as an extension. See + * {@code org.eclipse.cdt.core.CBuildConsole} extension point. If the + * console class is instance of {@link ICConsole} it is initialized with + * context id, name and icon to be shown in the list of consoles in the * Console view. * - * @param extConsoleId - console id defined in the extension point. - * @param contextId - context menu id in the Console view. A caller needs to define - * a distinct one for own use. - * @param name - name of console to appear in the list of consoles in context menu - * in the Console view. - * @param iconUrl - a {@link URL} of the icon for the context menu of the Console - * view. The url is expected to point to an image in eclipse OSGi bundle. - * Here is an example how to retrieve URL:
- * + * @param extConsoleId + * - console id defined in the extension point. + * @param contextId + * - context menu id in the Console view. A caller needs to + * define a distinct one for own use. + * @param name + * - name of console to appear in the list of consoles in context + * menu in the Console view. + * @param iconUrl + * - a {@link URL} of the icon for the context menu of the + * Console view. The url is expected to point to an image in + * eclipse OSGi bundle. Here is an example how to retrieve URL: + *
+ * * URL iconUrl = CUIPlugin.getDefault().getBundle().getEntry("icons/obj16/flask.png"); * * @@ -539,14 +582,16 @@ public class CCorePlugin extends Plugin { */ public IConsole getConsole(String extConsoleId, String contextId, String name, URL iconUrl) { try { - IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, "CBuildConsole"); //$NON-NLS-1$ + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(CCorePlugin.PLUGIN_ID, "CBuildConsole"); //$NON-NLS-1$ if (extensionPoint != null) { IExtension[] extensions = extensionPoint.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configElements = extension.getConfigurationElements(); for (IConfigurationElement configElement : configElements) { String consoleID = configElement.getAttribute("id"); //$NON-NLS-1$ - if ((extConsoleId == null && consoleID == null) || (extConsoleId != null && extConsoleId.equals(consoleID))) { + if ((extConsoleId == null && consoleID == null) + || (extConsoleId != null && extConsoleId.equals(consoleID))) { IConsole console = (IConsole) configElement.createExecutableExtension("class"); //$NON-NLS-1$ if (console instanceof ICConsole) { ((ICConsole) console).init(contextId, name, iconUrl); @@ -563,12 +608,13 @@ public class CCorePlugin extends Plugin { } /** - * Create CDT console adapter. - * The adapter serves as a bridge between core plugin and UI console API in a way that - * a user can create a UI console from plugins having no dependencies to UI. + * Create CDT console adapter. The adapter serves as a bridge between core + * plugin and UI console API in a way that a user can create a UI console + * from plugins having no dependencies to UI. * - * @param id - id of the console specified in extension point to instantiate - * console adapter. + * @param id + * - id of the console specified in extension point to + * instantiate console adapter. * @return CDT console adapter. */ public IConsole getConsole(String id) { @@ -580,19 +626,23 @@ public class CCorePlugin extends Plugin { * {@code org.eclipse.cdt.internal.ui.buildconsole.CBuildConsole} is created * and initialized with the parameters. * - * @param contextId - context menu id in the Console view. A caller needs to define - * a distinct one for own use. - * @param name - name of console to appear in the list of consoles in context menu - * in the Console view. - * @param iconUrl - a {@link URL} of the icon for the context menu of the Console - * view. The url is expected to point to an image in eclipse OSGi bundle. - * Here is an example how to retrieve URL:
- * + * @param contextId + * - context menu id in the Console view. A caller needs to + * define a distinct one for own use. + * @param name + * - name of console to appear in the list of consoles in context + * menu in the Console view. + * @param iconUrl + * - a {@link URL} of the icon for the context menu of the + * Console view. The url is expected to point to an image in + * eclipse OSGi bundle. Here is an example how to retrieve URL: + *
+ * * URL iconUrl = CUIPlugin.getDefault().getBundle().getResource("icons/obj16/flask.png"); - * - *
- * {@code iconUrl} can be null, in that case the default image is used. - * See {@code org.eclipse.cdt.internal.ui.buildconsole.BuildConsole(IBuildConsoleManager, String, String, URL)} + *

+ * {@code iconUrl} can be null, in that case the default + * image is used. See + * {@code org.eclipse.cdt.internal.ui.buildconsole.BuildConsole(IBuildConsoleManager, String, String, URL)} * * @return CDT console adapter. * @@ -611,7 +661,8 @@ public class CCorePlugin extends Plugin { } /** - * @deprecated Use {@link #getDefaultBinaryParserExtensions(IProject)} instead. + * @deprecated Use {@link #getDefaultBinaryParserExtensions(IProject)} + * instead. */ @Deprecated public ICExtensionReference[] getBinaryParserExtensions(IProject project) throws CoreException { @@ -619,7 +670,7 @@ public class CCorePlugin extends Plugin { if (project != null) { try { ICDescriptor cdesc = getCProjectDescription(project, false); - if (cdesc==null) + if (cdesc == null) return ext; ICExtensionReference[] cextensions = cdesc.get(BINARY_PARSER_UNIQ_ID, true); if (cextensions != null && cextensions.length > 0) @@ -632,10 +683,13 @@ public class CCorePlugin extends Plugin { } /** - * Returns the binary parser extensions for the default settings configuration. + * Returns the binary parser extensions for the default settings + * configuration. + * * @since 5.2 */ - public ICConfigExtensionReference[] getDefaultBinaryParserExtensions(IProject project) throws CoreException { + public ICConfigExtensionReference[] getDefaultBinaryParserExtensions(IProject project) + throws CoreException { ICConfigExtensionReference ext[] = new ICConfigExtensionReference[0]; if (project != null) { ICProjectDescription desc = CCorePlugin.getDefault().getProjectDescription(project, false); @@ -664,7 +718,7 @@ public class CCorePlugin extends Plugin { for (ICExtensionReference ref : cextensions) { IBinaryParser parser = null; try { - parser = (IBinaryParser)ref.createExtension(); + parser = (IBinaryParser) ref.createExtension(); } catch (ClassCastException e) { log(e); // wrong binary parser definition ? } @@ -682,7 +736,7 @@ public class CCorePlugin extends Plugin { if (parsers == null) { IBinaryParser parser = getDefaultBinaryParser(); if (parser != null) { - parsers = new IBinaryParser[] {parser}; + parsers = new IBinaryParser[] { parser }; } } return parsers; @@ -694,7 +748,8 @@ public class CCorePlugin extends Plugin { if (id == null || id.isEmpty()) { id = DEFAULT_BINARY_PARSER_UNIQ_ID; } - IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, BINARY_PARSER_SIMPLE_ID); + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(CCorePlugin.PLUGIN_ID, BINARY_PARSER_SIMPLE_ID); IExtension extension = extensionPoint.getExtension(id); if (extension != null) { IConfigurationElement element[] = extension.getConfigurationElements(); @@ -705,7 +760,8 @@ public class CCorePlugin extends Plugin { } } } else { - IStatus s = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, CCorePlugin.getResourceString("CCorePlugin.exception.noBinaryFormat"), null); //$NON-NLS-1$ + IStatus s = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, + CCorePlugin.getResourceString("CCorePlugin.exception.noBinaryFormat"), null); //$NON-NLS-1$ throw new CoreException(s); } return parser; @@ -740,14 +796,16 @@ public class CCorePlugin extends Plugin { /** * Please use {@link #getProjectDescription(IProject, boolean)} to fetch the - * ICProjectDescription for the project. And use {@link ICProjectDescription#getConfigurations()} - * to get an array of ICConfigurationDescriptions, which have similar API to ICDescriptor, - * allowing you to store settings and configure extensions at the Configuration level - * rather than at the project level. + * ICProjectDescription for the project. And use + * {@link ICProjectDescription#getConfigurations()} to get an array of + * ICConfigurationDescriptions, which have similar API to ICDescriptor, + * allowing you to store settings and configure extensions at the + * Configuration level rather than at the project level. * * @param project * @param create - * @return ICDescriptor or null if create is false and no .cdtproject file exists on disk. + * @return ICDescriptor or null if create is false and + * no .cdtproject file exists on disk. * @throws CoreException * @deprecated */ @@ -758,24 +816,26 @@ public class CCorePlugin extends Plugin { public void mapCProjectOwner(IProject project, String id, boolean override) throws CoreException { try { - if (!override) { - fNewCProjectDescriptionManager.getDescriptorManager().configure(project, id); - } else { - fNewCProjectDescriptionManager.getDescriptorManager().convert(project, id); - } + if (!override) { + fNewCProjectDescriptionManager.getDescriptorManager().configure(project, id); + } else { + fNewCProjectDescriptionManager.getDescriptorManager().convert(project, id); + } } catch (Exception e) { throw ExceptionFactory.createCoreException(e); } } /** - * @deprecated Settings should be set per ICConfigurationDescription rather than - * global to the project. Please use {@link #getProjectDescription(IProject, boolean)} - * to fetch the ICProjectDescription for the project. And use - * {@link ICProjectDescription#getConfigurations()} to get an array of - * ICConfigurationDescriptions, which have similar API to ICDescriptor, - * allowing you to store settings and configure extensions at the Configuration level - * rather than at the project level. + * @deprecated Settings should be set per ICConfigurationDescription rather + * than global to the project. Please use + * {@link #getProjectDescription(IProject, boolean)} to fetch + * the ICProjectDescription for the project. And use + * {@link ICProjectDescription#getConfigurations()} to get an + * array of ICConfigurationDescriptions, which have similar API + * to ICDescriptor, allowing you to store settings and configure + * extensions at the Configuration level rather than at the + * project level. */ @Deprecated public ICDescriptorManager getCDescriptorManager() { @@ -785,20 +845,23 @@ public class CCorePlugin extends Plugin { /** * Creates a C project resource given the project handle and description. * - * @param description the project description to create a project resource for - * @param projectHandle the project handle to create a project resource for - * @param monitor the progress monitor to show visual progress with - * @param projectID required for mapping the project to an owner + * @param description + * the project description to create a project resource for + * @param projectHandle + * the project handle to create a project resource for + * @param monitor + * the progress monitor to show visual progress with + * @param projectID + * required for mapping the project to an owner * - * @exception CoreException if the operation fails - * @exception OperationCanceledException if the operation is canceled + * @exception CoreException + * if the operation fails + * @exception OperationCanceledException + * if the operation is canceled */ - public IProject createCProject( - final IProjectDescription description, - final IProject projectHandle, - IProgressMonitor monitor, - final String projectID) - throws CoreException, OperationCanceledException { + public IProject createCProject(final IProjectDescription description, final IProject projectHandle, + IProgressMonitor monitor, final String projectID) + throws CoreException, OperationCanceledException { getWorkspace().run(new IWorkspaceRunnable() { @Override @@ -831,19 +894,13 @@ public class CCorePlugin extends Plugin { return projectHandle; } - public IProject createCDTProject( - final IProjectDescription description, - final IProject projectHandle, - IProgressMonitor monitor) throws CoreException, OperationCanceledException{ + public IProject createCDTProject(final IProjectDescription description, final IProject projectHandle, + IProgressMonitor monitor) throws CoreException, OperationCanceledException { return createCDTProject(description, projectHandle, null, monitor); } - public IProject createCDTProject( - final IProjectDescription description, - final IProject projectHandle, - final String bsId, - IProgressMonitor monitor) - throws CoreException, OperationCanceledException { + public IProject createCDTProject(final IProjectDescription description, final IProject projectHandle, + final String bsId, IProgressMonitor monitor) throws CoreException, OperationCanceledException { getWorkspace().run(new IWorkspaceRunnable() { @Override @@ -864,7 +921,7 @@ public class CCorePlugin extends Plugin { // Open first. projectHandle.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1)); - // mapCProjectOwner(projectHandle, projectID, false); + // mapCProjectOwner(projectHandle, projectID, false); // Add C Nature ... does not add duplicates CProjectNature.addCNature(projectHandle, new SubProgressMonitor(monitor, 1)); @@ -883,7 +940,8 @@ public class CCorePlugin extends Plugin { if (cfg == null) { ICConfigurationDescription prefCfg = getPreferenceConfiguration(bsId); if (prefCfg != null) { - cfg = projDes.createConfiguration(CDataUtil.genId(prefCfg.getId()), prefCfg.getName(), prefCfg); + cfg = projDes.createConfiguration(CDataUtil.genId(prefCfg.getId()), + prefCfg.getName(), prefCfg); } } @@ -900,32 +958,30 @@ public class CCorePlugin extends Plugin { } /** - * Method convertProjectFromCtoCC converts - * a C Project to a C++ Project - * The newProject MUST, not be null, already have a C Nature - * && must NOT already have a C++ Nature + * Method convertProjectFromCtoCC converts a C Project to a C++ Project The + * newProject MUST, not be null, already have a C Nature && must NOT already + * have a C++ Nature * * @param projectHandle * @param monitor * @throws CoreException */ - public void convertProjectFromCtoCC(IProject projectHandle, IProgressMonitor monitor) throws CoreException { - if ((projectHandle != null) - && projectHandle.hasNature(CProjectNature.C_NATURE_ID) - && !projectHandle.hasNature(CCProjectNature.CC_NATURE_ID)) { + public void convertProjectFromCtoCC(IProject projectHandle, IProgressMonitor monitor) + throws CoreException { + if ((projectHandle != null) && projectHandle.hasNature(CProjectNature.C_NATURE_ID) + && !projectHandle.hasNature(CCProjectNature.CC_NATURE_ID)) { // Add C++ Nature ... does not add duplicates CCProjectNature.addCCNature(projectHandle, monitor); } } /** - * Method to convert a project to a C nature - * All checks should have been done externally - * (as in the Conversion Wizards). - * This method blindly does the conversion. + * Method to convert a project to a C nature All checks should have been + * done externally (as in the Conversion Wizards). This method blindly does + * the conversion. */ public void convertProjectToC(IProject projectHandle, IProgressMonitor monitor, String projectID) - throws CoreException { + throws CoreException { if ((projectHandle == null) || (monitor == null) || (projectID == null)) { return; } @@ -936,7 +992,7 @@ public class CCorePlugin extends Plugin { } public void convertProjectToNewC(IProject projectHandle, String bsId, IProgressMonitor monitor) - throws CoreException { + throws CoreException { if ((projectHandle == null) || (monitor == null) || (bsId == null)) { throw new NullPointerException(); } @@ -950,7 +1006,7 @@ public class CCorePlugin extends Plugin { * Method to convert a project to a C++ nature */ public void convertProjectToCC(IProject projectHandle, IProgressMonitor monitor, String projectID) - throws CoreException { + throws CoreException { if ((projectHandle == null) || (monitor == null) || (projectID == null)) { return; } @@ -960,7 +1016,7 @@ public class CCorePlugin extends Plugin { } public void convertProjectToNewCC(IProject projectHandle, String bsId, IProgressMonitor monitor) - throws CoreException { + throws CoreException { if ((projectHandle == null) || (monitor == null) || (bsId == null)) { throw new NullPointerException(); } @@ -971,10 +1027,12 @@ public class CCorePlugin extends Plugin { /** * Get the IProcessList contributed interface for the platform. + * * @return IProcessList */ public IProcessList getProcessList() throws CoreException { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, "ProcessList"); //$NON-NLS-1$ + IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, + "ProcessList"); //$NON-NLS-1$ if (extension != null) { IExtension[] extensions = extension.getExtensions(); IConfigurationElement defaultContributor = null; @@ -983,7 +1041,8 @@ public class CCorePlugin extends Plugin { for (IConfigurationElement configElement : configElements) { if (configElement.getName().equals("processList")) { //$NON-NLS-1$ String platform = configElement.getAttribute("platform"); //$NON-NLS-1$ - if (platform == null) { // first contributor found with not platform will be default. + if (platform == null) { // first contributor found with + // not platform will be default. if (defaultContributor == null) { defaultContributor = configElement; } @@ -1002,18 +1061,23 @@ public class CCorePlugin extends Plugin { } /** - * @deprecated since CDT 6.1. Use {@link ErrorParserManager#getErrorParserAvailableIds()} instead + * @deprecated since CDT 6.1. Use + * {@link ErrorParserManager#getErrorParserAvailableIds()} + * instead * @return array of error parsers ids */ @Deprecated public String[] getAllErrorParsersIDs() { ErrorParserExtensionManager.loadErrorParserExtensions(); - return ErrorParserExtensionManager.getErrorParserAvailableIdsInContext(ErrorParserManager.BUILD_CONTEXT); + return ErrorParserExtensionManager + .getErrorParserAvailableIdsInContext(ErrorParserManager.BUILD_CONTEXT); } /** - * @deprecated since CDT 6.1. Use {@link ErrorParserManager#getErrorParserCopy(String)} instead - * @param id - id of error parser + * @deprecated since CDT 6.1. Use + * {@link ErrorParserManager#getErrorParserCopy(String)} instead + * @param id + * - id of error parser * @return array of error parsers */ @Deprecated @@ -1036,11 +1100,13 @@ public class CCorePlugin extends Plugin { if (provider != null) return provider; - // Next search the extension registry to see if a provider is registered with a build command + // Next search the extension registry to see if a provider is + // registered with a build command provider = getExtensionScannerInfoProvider2(project); // Regular usage is where Language Settings Providers are employed - if (provider == null && ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project)) { + if (provider == null && ScannerDiscoveryLegacySupport + .isLanguageSettingsProvidersFunctionalityEnabled(project)) { provider = new LanguageSettingsScannerInfoProvider(); } @@ -1055,14 +1121,15 @@ public class CCorePlugin extends Plugin { return null; log(e); - } + } return provider; } /** - * Clears cached scanner info provider for the given project so that the next call to - * {@link #getScannerInfoProvider(IProject)} would return an up to date scanner info provider. + * Clears cached scanner info provider for the given project so that the + * next call to {@link #getScannerInfoProvider(IProject)} would return an up + * to date scanner info provider. * * @noreference This method is not intended to be referenced by clients. */ @@ -1078,8 +1145,8 @@ public class CCorePlugin extends Plugin { } /** - * Find {@link IScannerInfoProvider} registered as extension via extension point - * org.eclipse.cdt.core.ScannerInfoProvider2. + * Find {@link IScannerInfoProvider} registered as extension via extension + * point org.eclipse.cdt.core.ScannerInfoProvider2. */ private IScannerInfoProvider getExtensionScannerInfoProvider2(IProject project) throws CoreException { IScannerInfoProvider provider = null; @@ -1096,7 +1163,7 @@ public class CCorePlugin extends Plugin { ICommand[] commands = desc.getBuildSpec(); for (ICommand command : commands) if (builder.equals(command.getBuilderName())) - provider = (IScannerInfoProvider)elem.createExecutableExtension("class"); //$NON-NLS-1$ + provider = (IScannerInfoProvider) elem.createExecutableExtension("class"); //$NON-NLS-1$ } } } @@ -1105,10 +1172,12 @@ public class CCorePlugin extends Plugin { } /** - * Helper function, returning the content type for a filename - * Same as:
-	 * 	getContentType(null, filename)
+	 * Helper function, returning the content type for a filename Same as:
+	 * 
+	 * 
+	 * getContentType(null, filename)
 	 * 
+ * * @param filename * @return the content type found, or null */ @@ -1117,11 +1186,15 @@ public class CCorePlugin extends Plugin { } /** - * Returns the content type for a filename. The method respects - * project specific content type definitions. The lookup prefers case- - * sensitive matches over the others. - * @param project a project with possible project specific settings. Can be null - * @param filename a filename to compute the content type for + * Returns the content type for a filename. The method respects project + * specific content type definitions. The lookup prefers case- sensitive + * matches over the others. + * + * @param project + * a project with possible project specific settings. Can be + * null + * @param filename + * a filename to compute the content type for * @return the content type found or null */ public static IContentType getContentType(IProject project, String filename) { @@ -1142,35 +1215,42 @@ public class CCorePlugin extends Plugin { CContentTypes.setUseProjectSpecificContentTypes(project, val); } - private static final String MODEL = CCorePlugin.PLUGIN_ID + "/debug/model" ; //$NON-NLS-1$ - private static final String PARSER = CCorePlugin.PLUGIN_ID + "/debug/parser" ; //$NON-NLS-1$ - private static final String PARSER_EXCEPTIONS = CCorePlugin.PLUGIN_ID + "/debug/parser/exceptions" ; //$NON-NLS-1$ + private static final String MODEL = CCorePlugin.PLUGIN_ID + "/debug/model"; //$NON-NLS-1$ + private static final String PARSER = CCorePlugin.PLUGIN_ID + "/debug/parser"; //$NON-NLS-1$ + private static final String PARSER_EXCEPTIONS = CCorePlugin.PLUGIN_ID + "/debug/parser/exceptions"; //$NON-NLS-1$ private static final String SCANNER = CCorePlugin.PLUGIN_ID + "/debug/scanner"; //$NON-NLS-1$ - private static final String DELTA = CCorePlugin.PLUGIN_ID + "/debug/deltaprocessor" ; //$NON-NLS-1$ + private static final String DELTA = CCorePlugin.PLUGIN_ID + "/debug/deltaprocessor"; //$NON-NLS-1$ /** - * Configure the plug-in with respect to option settings defined in ".options" file + * Configure the plug-in with respect to option settings defined in + * ".options" file */ public void configurePluginDebugOptions() { if (CCorePlugin.getDefault().isDebugging()) { String option = Platform.getDebugOption(PARSER); - if (option != null) Util.VERBOSE_PARSER = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if (option != null) + Util.VERBOSE_PARSER = option.equalsIgnoreCase("true"); //$NON-NLS-1$ option = Platform.getDebugOption(PARSER_EXCEPTIONS); - if (option != null) Util.PARSER_EXCEPTIONS = option.equalsIgnoreCase("true"); //$NON-NLS-1$ + if (option != null) + Util.PARSER_EXCEPTIONS = option.equalsIgnoreCase("true"); //$NON-NLS-1$ option = Platform.getDebugOption(SCANNER); - if (option != null) Util.VERBOSE_SCANNER = option.equalsIgnoreCase("true"); //$NON-NLS-1$ + if (option != null) + Util.VERBOSE_SCANNER = option.equalsIgnoreCase("true"); //$NON-NLS-1$ option = Platform.getDebugOption(MODEL); - if (option != null) Util.VERBOSE_MODEL = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if (option != null) + Util.VERBOSE_MODEL = option.equalsIgnoreCase("true"); //$NON-NLS-1$ option = Platform.getDebugOption(DELTA); - if (option != null) Util.VERBOSE_DELTA= option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if (option != null) + Util.VERBOSE_DELTA = option.equalsIgnoreCase("true"); //$NON-NLS-1$ } } - // Preference to turn on/off the use of structural parse mode to build the CModel. + // Preference to turn on/off the use of structural parse mode to build the + // CModel. public void setStructuralParseMode(boolean useNewParser) { getPluginPreferences().setValue(PREF_USE_STRUCTURAL_PARSE_MODE, useNewParser); savePluginPreferences(); @@ -1181,11 +1261,12 @@ public class CCorePlugin extends Plugin { } /** - * @deprecated use {@link ITranslationUnit} or {@link ILanguage} to construct ASTs, instead. + * @deprecated use {@link ITranslationUnit} or {@link ILanguage} to + * construct ASTs, instead. */ @Deprecated public org.eclipse.cdt.core.dom.CDOM getDOM() { - return org.eclipse.cdt.core.dom.CDOM.getInstance(); + return org.eclipse.cdt.core.dom.CDOM.getInstance(); } public ICdtVariableManager getCdtVariableManager() { @@ -1196,62 +1277,77 @@ public class CCorePlugin extends Plugin { return EnvironmentVariableManager.getDefault(); } - public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId) throws CoreException{ + public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId) throws CoreException { return fNewCProjectDescriptionManager.getPreferenceConfiguration(buildSystemId); } - public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId, boolean write) throws CoreException{ + public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId, boolean write) + throws CoreException { return fNewCProjectDescriptionManager.getPreferenceConfiguration(buildSystemId, write); } - public void setPreferenceConfiguration(String buildSystemId, ICConfigurationDescription des) throws CoreException { + public void setPreferenceConfiguration(String buildSystemId, ICConfigurationDescription des) + throws CoreException { fNewCProjectDescriptionManager.setPreferenceConfiguration(buildSystemId, des); } /** - * Equivalent to createProjectDescription(IProject, boolean, false). + * Equivalent to + * createProjectDescription(IProject, boolean, false). * * @see #createProjectDescription(IProject, boolean, boolean) */ - public ICProjectDescription createProjectDescription(IProject project, boolean loadIfExists) throws CoreException{ + public ICProjectDescription createProjectDescription(IProject project, boolean loadIfExists) + throws CoreException { return fNewCProjectDescriptionManager.createProjectDescription(project, loadIfExists); } /** * Creates and returns a writable project description. * - * @param project project for which the project description is requested - * @param loadIfExists if true the method first tries to load and return the project description - * from the settings file (.cproject), - * if false, the stored settings are ignored and the new (empty) project description is - * created - * @param creating if true the created project description will be contain the true - * "isCdtProjectCreating" state. - *
NOTE: in case the project already contains the project description AND its - * "isCdtProjectCreating" is false the resulting description will be created with the false - * "isCdtProjectCreating" state. + * @param project + * project for which the project description is requested + * @param loadIfExists + * if true the method first tries to load and return the project + * description from the settings file (.cproject), if false, the + * stored settings are ignored and the new (empty) project + * description is created + * @param creating + * if true the created project description will be contain the + * true "isCdtProjectCreating" state.
+ * NOTE: in case the project already contains the project + * description AND its "isCdtProjectCreating" is false the + * resulting description will be created with the false + * "isCdtProjectCreating" state. * - *
NOTE: changes made to the returned project description will not be applied until - * the {@link #setProjectDescription(IProject, ICProjectDescription)} is called. + *
+ * NOTE: changes made to the returned project description will + * not be applied until the + * {@link #setProjectDescription(IProject, ICProjectDescription)} + * is called. * @return {@link ICProjectDescription} * @throws CoreException */ - public ICProjectDescription createProjectDescription(IProject project, boolean loadIfExists, boolean creating) throws CoreException{ + public ICProjectDescription createProjectDescription(IProject project, boolean loadIfExists, + boolean creating) throws CoreException { return fNewCProjectDescriptionManager.createProjectDescription(project, loadIfExists, creating); } /** - * Returns the project description associated with this project or null if the project does not - * contain the CDT data associated with it. + * Returns the project description associated with this project or null if + * the project does not contain the CDT data associated with it. * - * This is a convenience method fully equivalent to getProjectDescription(project, true) - * see {@link #getProjectDescription(IProject, boolean)} for more detail. + * This is a convenience method fully equivalent to + * getProjectDescription(project, true) see + * {@link #getProjectDescription(IProject, boolean)} for more detail. * * @param project - * @return a writable copy of the ICProjectDescription or null if the project does not contain - * the CDT data associated with it. - *
Note: changes to the project description will not be reflected/used by the core - * until the {@link #setProjectDescription(IProject, ICProjectDescription)} is called. + * @return a writable copy of the ICProjectDescription or null if the + * project does not contain the CDT data associated with it.
+ * Note: changes to the project description will not be + * reflected/used by the core until the + * {@link #setProjectDescription(IProject, ICProjectDescription)} is + * called. * * @see #getProjectDescription(IProject, boolean) */ @@ -1260,9 +1356,9 @@ public class CCorePlugin extends Plugin { } /** - * Called to save/apply the project description. - * The method should be called to apply changes made to the project description - * returned by the {@link #getProjectDescription(IProject, boolean)} or + * Called to save/apply the project description. The method should be called + * to apply changes made to the project description returned by the + * {@link #getProjectDescription(IProject, boolean)} or * {@link #createProjectDescription(IProject, boolean)} * * @param project @@ -1276,37 +1372,46 @@ public class CCorePlugin extends Plugin { fNewCProjectDescriptionManager.setProjectDescription(project, des); } - public void setProjectDescription(IProject project, ICProjectDescription des, boolean force, IProgressMonitor monitor) throws CoreException { + public void setProjectDescription(IProject project, ICProjectDescription des, boolean force, + IProgressMonitor monitor) throws CoreException { fNewCProjectDescriptionManager.setProjectDescription(project, des, force, monitor); } /** - * Returns the project description associated with this project or null if the project - * does not contain the CDT data associated with it. + * Returns the project description associated with this project or null if + * the project does not contain the CDT data associated with it. * - * @param project project for which the description is requested - * @param write if true, the writable description copy is returned. - * If false the cached read-only description is returned. + * @param project + * project for which the description is requested + * @param write + * if true, the writable description copy is returned. If false + * the cached read-only description is returned. * - *
CDT core maintains the cached project description settings. If only read access is needed - * to description, then the read-only project description should be obtained. - * This description always operates with cached data and thus it is better to use it for - * performance reasons. All set* calls to the read-only description result in - * the {@link WriteAccessException}. + *
+ * CDT core maintains the cached project description settings. If + * only read access is needed to description, then the read-only + * project description should be obtained. This description + * always operates with cached data and thus it is better to use + * it for performance reasons. All set* calls to the read-only + * description result in the {@link WriteAccessException}. * - * When the writable description is requested, the description copy is created. Changes to this - * description will not be reflected/used by the core and the Build System until the - * {@link #setProjectDescription(IProject, ICProjectDescription)} is called. + * When the writable description is requested, the description + * copy is created. Changes to this description will not be + * reflected/used by the core and the Build System until the + * {@link #setProjectDescription(IProject, ICProjectDescription)} + * is called. * - * Each getProjectDescription(project, true) returns a new copy of the project description. + * Each getProjectDescription(project, true) returns a new copy + * of the project description. * - * The writable description uses the cached data until the first set call - * after that the description communicates directly to the Build System - * i.e. the implementer of the org.eclipse.cdt.core.CConfigurationDataProvider extension - * This ensures the Core<->Build System settings integrity. + * The writable description uses the cached data until the first + * set call after that the description communicates directly to + * the Build System i.e. the implementer of the + * org.eclipse.cdt.core.CConfigurationDataProvider extension This + * ensures the Core<->Build System settings integrity. * - * @return {@link ICProjectDescription} or null if the project does not contain the - * CDT data associated with it. + * @return {@link ICProjectDescription} or null if the project does not + * contain the CDT data associated with it. */ public ICProjectDescription getProjectDescription(IProject project, boolean write) { return fNewCProjectDescriptionManager.getProjectDescription(project, write); @@ -1315,11 +1420,14 @@ public class CCorePlugin extends Plugin { /** * Forces the cached data of the specified projects to be re-calculated. * - * @param projects if null, all projects within the workspace are updated + * @param projects + * if null, all projects within the workspace are + * updated * @param monitor * @throws CoreException */ - public void updateProjectDescriptions(IProject projects[], IProgressMonitor monitor) throws CoreException{ + public void updateProjectDescriptions(IProject projects[], IProgressMonitor monitor) + throws CoreException { fNewCProjectDescriptionManager.updateProjectDescriptions(projects, monitor); } @@ -1332,7 +1440,8 @@ public class CCorePlugin extends Plugin { } /** - * Answers whether the given project is a new-style project, i.e. CConfigurationDataProvider-driven + * Answers whether the given project is a new-style project, i.e. + * CConfigurationDataProvider-driven */ public boolean isNewStyleProject(ICProjectDescription des) { return fNewCProjectDescriptionManager.isNewStyleProject(des); @@ -1352,7 +1461,8 @@ public class CCorePlugin extends Plugin { // NON-API /** - * @noreference This constructor is not intended to be referenced by clients. + * @noreference This constructor is not intended to be referenced by + * clients. */ public CCorePlugin() { super(); @@ -1369,9 +1479,12 @@ public class CCorePlugin extends Plugin { /** * Prints a message in the log * - * @param severity - desired severity of the message in the log, - * one of {@link IStatus#INFO}, {@link IStatus#WARNING} or {@link IStatus#ERROR} - * @param msg - message + * @param severity + * - desired severity of the message in the log, one of + * {@link IStatus#INFO}, {@link IStatus#WARNING} or + * {@link IStatus#ERROR} + * @param msg + * - message * * @since 5.5 * @noreference This method is not intended to be referenced by clients. @@ -1379,13 +1492,16 @@ public class CCorePlugin extends Plugin { public static void log(int severity, String msg) { log(new Status(severity, PLUGIN_ID, msg)); } - + /** * Prints a message in the log accompanied by stack trace * - * @param severity - desired severity of the message in the log, - * one of {@link IStatus#INFO}, {@link IStatus#WARNING} or {@link IStatus#ERROR} - * @param msg - message + * @param severity + * - desired severity of the message in the log, one of + * {@link IStatus#INFO}, {@link IStatus#WARNING} or + * {@link IStatus#ERROR} + * @param msg + * - message * * @since 5.5 * @noreference This method is not intended to be referenced by clients. @@ -1393,12 +1509,12 @@ public class CCorePlugin extends Plugin { public static void logStackTrace(int severity, String msg) { log(new Status(severity, PLUGIN_ID, msg, new Exception())); } - + /** * @noreference This method is not intended to be referenced by clients. */ public static void log(Throwable e) { - String msg= e.getMessage(); + String msg = e.getMessage(); if (msg == null) { log("Error", e); //$NON-NLS-1$ } else { @@ -1449,14 +1565,15 @@ public class CCorePlugin extends Plugin { } /** - * Returns the preference controlling whether source roots are shown at the top of projects - * or embedded within the resource tree of projects when they are not top level folders. + * Returns the preference controlling whether source roots are shown at the + * top of projects or embedded within the resource tree of projects when + * they are not top level folders. * * @return boolean preference value * @since 5.2 */ public static boolean showSourceRootsAtTopOfProject() { return InstanceScope.INSTANCE.getNode(PLUGIN_ID) - .getBoolean(CCorePreferenceConstants.SHOW_SOURCE_ROOTS_AT_TOP_LEVEL_OF_PROJECT, true); + .getBoolean(CCorePreferenceConstants.SHOW_SOURCE_ROOTS_AT_TOP_LEVEL_OF_PROJECT, true); } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java new file mode 100644 index 00000000000..f7535045101 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java @@ -0,0 +1,139 @@ +package org.eclipse.cdt.core.build; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.osgi.service.prefs.BackingStoreException; + +/** + * Root class for CDT build configurations. Provides access to the build + * settings for subclasses. + * + * @since 5.12 + */ +public abstract class CBuildConfiguration extends PlatformObject { + + private static final String TOOLCHAIN = "cdt.toolChain"; //$NON-NLS-1$ + + private final IBuildConfiguration config; + private CToolChain toolChain; + + protected CBuildConfiguration(IBuildConfiguration config) { + this.config = config; + } + + public IBuildConfiguration getBuildConfiguration() { + return config; + } + + public String getName() { + return config.getName(); + } + + public IProject getProject() { + return config.getProject(); + } + + public void setActive(IProgressMonitor monitor) throws CoreException { + IProject project = config.getProject(); + if (config.equals(project.getActiveBuildConfig())) { + // already set + return; + } + + IProjectDescription projectDesc = project.getDescription(); + projectDesc.setActiveBuildConfig(config.getName()); + project.setDescription(projectDesc, monitor); + } + + protected IEclipsePreferences getSettings() { + return (IEclipsePreferences) new ProjectScope(config.getProject()).getNode("org.eclipse.cdt.core") //$NON-NLS-1$ + .node("config") //$NON-NLS-1$ + .node(config.getName()); + } + + private synchronized CToolChain getToolChain(String id) throws CoreException { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint point = registry.getExtensionPoint(CCorePlugin.PLUGIN_ID + ".ToolChain"); //$NON-NLS-1$ + for (IExtension extension : point.getExtensions()) { + for (IConfigurationElement element : extension.getConfigurationElements()) { + String eid = element.getAttribute("id"); //$NON-NLS-1$ + if (id.equals(eid)) { + String clsName = element.getAttribute("adaptor"); //$NON-NLS-1$ + if (clsName != null) { + try { + Class cls = Class.forName(clsName); + return (CToolChain) getAdapter(cls); + } catch (ClassNotFoundException e) { + throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, + "creating toolchain", e)); //$NON-NLS-1$ + } + } + } + } + } + return null; + } + + public synchronized void setToolChain(String id) throws CoreException { + CToolChain newtc = getToolChain(id); + if (newtc == null) { + throw new CoreException( + new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "unknown toolchain: " + id)); //$NON-NLS-1$ + } + + IEclipsePreferences settings = getSettings(); + settings.put(TOOLCHAIN, id); + try { + settings.flush(); + } catch (BackingStoreException e) { + throw new CoreException( + new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "saving toolchain id", e)); //$NON-NLS-1$ + } + + toolChain = newtc; + } + + public CToolChain getToolChain() throws CoreException { + if (toolChain == null) { + IEclipsePreferences settings = getSettings(); + String id = settings.get(TOOLCHAIN, ""); //$NON-NLS-1$ + if (id.isEmpty()) { + return null; + } else { + toolChain = getToolChain(id); + } + } + return toolChain; + } + + public IScannerInfo getScannerInfo(IResource resource) throws CoreException { + // By default, get it from the toolchain. + CToolChain toolChain = getToolChain(); + return toolChain != null ? toolChain.getScannerInfo(resource) : null; + } + + public void clearScannerInfo() throws CoreException { + } + + public CConsoleParser[] getConsoleParsers() throws CoreException { + CToolChain toolChain = getToolChain(); + return toolChain != null ? toolChain.getConsoleParsers() : null; + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CConsoleParser.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CConsoleParser.java new file mode 100644 index 00000000000..49b8a0f7ab9 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CConsoleParser.java @@ -0,0 +1,121 @@ +package org.eclipse.cdt.core.build; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; + +/** + * This could be temporary. Provides a core parser for the TextConsole's + * IPatternMatchListener. + * + * TODO that framework doesn't work well for builds that need to use different + * parsers at different times. Should consider taking that architecture and + * making it work well for our needs. + * + * @since 5.12 + */ +public abstract class CConsoleParser { + + private final String pattern; + private final int flags; + private final String lineQualifier; + + private final Pattern errorPattern; + + public static final String LINK_OFFSET = "cdt.link.offset"; //$NON-NLS-1$ + public static final String LINK_LENGTH = "cdt.link.length"; //$NON-NLS-1$ + + protected CConsoleParser(String pattern, int flags, String lineQualifier) { + this.pattern = pattern; + this.flags = flags; + this.lineQualifier = lineQualifier; + this.errorPattern = Pattern.compile(pattern); + } + + protected CConsoleParser(String pattern) { + this(pattern, 0, null); + } + + /** + * Returns the pattern to be used for matching. The pattern is a string + * representing a regular expression. + * + * @return the regular expression to be used for matching + */ + public String getPattern() { + return pattern; + } + + /** + * Returns the flags to use when compiling this pattern match listener's + * regular expression, as defined by by + * Pattern.compile(String regex, int flags) + * + * @return the flags to use when compiling this pattern match listener's + * regular expression + * @see java.util.regex.Pattern#compile(java.lang.String, int) + */ + public int getCompilerFlags() { + return flags; + } + + /** + * Returns a simple regular expression used to identify lines that may match + * this pattern matcher's complete pattern, or null. Use of + * this attribute can improve performance by disqualifying lines from the + * search. When a line is found containing a match for this expression, the + * line is searched from the beginning for this pattern matcher's complete + * pattern. Lines not containing this pattern are discarded. + * + * @return a simple regular expression used to identify lines that may match + * this pattern matcher's complete pattern, or null + */ + public String getLineQualifier() { + return lineQualifier; + } + + protected abstract String getFileName(Matcher matcher); + + protected abstract int getLineNumber(Matcher matcher); + + protected abstract String getMessage(Matcher matcher); + + protected abstract int getSeverity(Matcher matcher); + + protected abstract int getLinkOffset(Matcher matcher); + + protected abstract int getLinkLength(Matcher matcher); + + public IMarker generateMarker(IFolder buildDirectory, String text) { + Matcher matcher = errorPattern.matcher(text); + if (matcher.matches()) { + String fileName = getFileName(matcher); + + IFile file = buildDirectory.getFile(fileName); + if (file.exists()) { + try { + IMarker marker = file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, getMessage(matcher)); + marker.setAttribute(IMarker.SEVERITY, getSeverity(matcher)); + marker.setAttribute(IMarker.LINE_NUMBER, getLineNumber(matcher)); + marker.setAttribute(IMarker.CHAR_START, -1); + marker.setAttribute(IMarker.CHAR_END, -1); + marker.setAttribute(LINK_OFFSET, getLinkOffset(matcher)); + marker.setAttribute(LINK_LENGTH, getLinkLength(matcher)); + return marker; + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } + } + } + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CToolChain.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CToolChain.java new file mode 100644 index 00000000000..c09a6166744 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CToolChain.java @@ -0,0 +1,119 @@ +package org.eclipse.cdt.core.build; + +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.internal.core.build.ScannerInfoData; +import org.eclipse.cdt.internal.core.build.ToolChainScannerInfo; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.PlatformObject; + +/** + * Root class for CDT toolchains. + * + * @since 5.12 + */ +public abstract class CToolChain extends PlatformObject { + + private final CBuildConfiguration config; + + private ScannerInfoData scannerInfo; + + protected CToolChain(CBuildConfiguration config) { + this.config = config; + } + + public static String[] splitCommand(String command) { + // TODO deal with quotes properly, for now just strip + return command.replace("\"", "").split("\\s+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public CBuildConfiguration getBuildConfiguration() { + return config; + } + + /** + * Update the given environment to run the toolchain. + * + * @param env + */ + public void setEnvironment(Map env) { + // default, nothing + } + + /** + * Scan the commandLine and save the scanner info for the resource being + * built, or if perProject is true, for all resources in the project. The + * buildFolder to help find the resource is where the command ran. + * + * @param buildFolder + * @param commandLine + * @throws CoreException + */ + public void scanBuildOutput(IFolder buildFolder, String commandLine, boolean perProject) + throws CoreException { + // default, nothing + } + + protected void putScannerInfo(IResource resource, Map definedSymbols, + List includePaths, List macroFiles, List includeFiles, + List localIncludePath) throws CoreException { + if (scannerInfo == null) { + loadScannerInfo(); + } + scannerInfo.putScannerInfo(resource, new ToolChainScannerInfo(definedSymbols, includePaths, + macroFiles, includeFiles, localIncludePath)); + } + + protected void putScannerInfo(ILanguage language, Map definedSymbols, + List includePaths, List macroFiles, List includeFiles, + List localIncludePath) throws CoreException { + if (scannerInfo == null) { + loadScannerInfo(); + } + scannerInfo.putScannerInfo(language, new ToolChainScannerInfo(definedSymbols, includePaths, + macroFiles, includeFiles, localIncludePath)); + } + + private void loadScannerInfo() { + if (scannerInfo == null) { + scannerInfo = ScannerInfoData.load(this); + } + } + + /** + * Return the scanner info for the given resource. + * + * @param resource + * @return scanner info for the resource + * @throws CoreException + */ + public IScannerInfo getScannerInfo(IResource resource) throws CoreException { + loadScannerInfo(); + return scannerInfo.getScannerInfo(resource); + } + + public void clearScannerInfo() throws CoreException { + if (scannerInfo == null) { + scannerInfo = new ScannerInfoData(); + scannerInfo.queueSave(); + } else { + scannerInfo.clear(); + } + } + + /** + * Return the console parsers to be used when this toolchain is being used + * for a build. + * + * @return console parsers + */ + public CConsoleParser[] getConsoleParsers() { + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/GCCToolChain.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/GCCToolChain.java new file mode 100644 index 00000000000..f62d7b0643f --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/GCCToolChain.java @@ -0,0 +1,224 @@ +package org.eclipse.cdt.core.build; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.LanguageManager; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.content.IContentType; + +/** + * The GCC toolchain. Placing it in cdt.core for now. + * + * TODO move to it's own plug-in. + * + * @since 5.12 + */ +public class GCCToolChain extends CToolChain { + + public static final String ID = "org.eclipse.cdt.core.gcc"; //$NON-NLS-1$ + + public GCCToolChain(CBuildConfiguration config) { + super(config); + } + + private static Map cache = new HashMap<>(); + + public static class Factory implements IAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public T getAdapter(Object adaptableObject, Class adapterType) { + if (adapterType.equals(GCCToolChain.class) && adaptableObject instanceof CBuildConfiguration) { + CBuildConfiguration config = (CBuildConfiguration) adaptableObject; + GCCToolChain toolChain = cache.get(config); + if (toolChain == null) { + toolChain = new GCCToolChain(config); + cache.put(config, toolChain); + } + return (T) toolChain; + } + return null; + } + + @Override + public Class[] getAdapterList() { + return new Class[] { GCCToolChain.class }; + } + } + + @Override + public void scanBuildOutput(IFolder buildFolder, String commandLine, boolean perProject) + throws CoreException { + try { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + // Need to flip over the slashes on Windows + commandLine = commandLine.replace('\\', '/'); + } + String[] command = splitCommand(commandLine); + + // Change output to stdout + for (int i = 0; i < command.length - 1; ++i) { + if (command[i].equals("-o")) { //$NON-NLS-1$ + command[i + 1] = "-"; //$NON-NLS-1$ + break; + } + } + + // Change source file to a tmp file (needs to be empty) + Path tmpFile = null; + IFile file = null; + for (int i = 1; i < command.length; ++i) { + if (!command[i].startsWith("-")) { //$NON-NLS-1$ + // TODO optimize by dealing with multi arg options like -o + IFile f = buildFolder.getFile(command[i]); + if (f.exists() && CoreModel.isTranslationUnit(f)) { + // replace it with a temp file + Path parentPath = new File(((IFolder) f.getParent()).getLocationURI()).toPath(); + int n = 0; + while (true) { + tmpFile = parentPath.resolve(".sc" + n + "." + f.getFileExtension()); //$NON-NLS-1$ //$NON-NLS-2$ + command[i] = tmpFile.toString(); + try { + Files.createFile(tmpFile); + break; + } catch (FileAlreadyExistsException e) { + // try again + ++n; + } + } + file = f; + break; + } + } + } + + if (file == null) { + // can't do much without the source file + CCorePlugin.log("No source file for scanner discovery"); //$NON-NLS-1$ + return; + } + + // Add in the magic potion: -E -P -v -dD + String[] fullCmd = new String[command.length + 4]; + fullCmd[0] = command[0]; + fullCmd[1] = "-E"; //$NON-NLS-1$ + fullCmd[2] = "-P"; //$NON-NLS-1$ + fullCmd[3] = "-v"; //$NON-NLS-1$ + fullCmd[4] = "-dD"; //$NON-NLS-1$ + System.arraycopy(command, 1, fullCmd, 5, command.length - 1); + + File buildDir = new File(buildFolder.getLocationURI()); + Files.createDirectories(buildDir.toPath()); + + // Startup the command + ProcessBuilder processBuilder = new ProcessBuilder(fullCmd).directory(buildDir) + .redirectErrorStream(true); + setEnvironment(processBuilder.environment()); + Process process = processBuilder.start(); + + // Scan for the scanner info + Map symbols = new HashMap<>(); + List includePath = new ArrayList<>(); + Pattern definePattern = Pattern.compile("#define (.*)\\s(.*)"); //$NON-NLS-1$ + boolean inIncludePaths = false; + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()))) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (inIncludePaths) { + if (line.equals("End of search list.")) { //$NON-NLS-1$ + inIncludePaths = false; + } else { + includePath.add(line.trim()); + } + } else if (line.startsWith("#define ")) { //$NON-NLS-1$ + Matcher matcher = definePattern.matcher(line); + if (matcher.matches()) { + symbols.put(matcher.group(1), matcher.group(2)); + } + } else if (line.equals("#include <...> search starts here:")) { //$NON-NLS-1$ + inIncludePaths = true; + } + } + } + + if (perProject) { + IProject project = buildFolder.getProject(); + IContentType contentType = CCorePlugin.getContentType(project, file.getName()); + if (contentType != null) { + ILanguage language = LanguageManager.getInstance().getLanguage(contentType, project); + putScannerInfo(language, symbols, includePath, null, null, null); + } + } else { + putScannerInfo(file, symbols, includePath, null, null, null); + } + + if (tmpFile != null) { + Files.delete(tmpFile); + } + } catch (IOException e) { + throw new CoreException( + new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Scanning build output", e)); //$NON-NLS-1$ + } + } + + @Override + public CConsoleParser[] getConsoleParsers() { + // ../src/Test.cpp:4:1: error: 'x' was not declared in this scope + + return new CConsoleParser[] { new CConsoleParser("(.*?):(\\d+):(\\d+:)? (fatal )?error: (.*)") { //$NON-NLS-1$ + @Override + protected int getSeverity(Matcher matcher) { + return IMarker.SEVERITY_ERROR; + } + + @Override + protected String getMessage(Matcher matcher) { + return matcher.group(5); + } + + @Override + protected int getLineNumber(Matcher matcher) { + return Integer.parseInt(matcher.group(2)); + } + + @Override + protected String getFileName(Matcher matcher) { + return matcher.group(1); + } + + @Override + protected int getLinkOffset(Matcher matcher) { + return 0; + } + + @Override + protected int getLinkLength(Matcher matcher) { + return matcher.group(1).length() + 1 + matcher.group(2).length() + 1 + + matcher.group(3).length(); + } + } }; + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IConsoleService.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IConsoleService.java new file mode 100644 index 00000000000..cacc1e264d6 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IConsoleService.java @@ -0,0 +1,45 @@ +package org.eclipse.cdt.core.build; + +import java.io.IOException; + +import org.eclipse.core.resources.IFolder; + +/** + * This may be temporary. It's uses the TextConsole's parsing and hyperlink + * framework to parse build output for errors. + * + * TODO Should we replace all CDT build consoles with this. + * + * @since 5.12 + */ +public interface IConsoleService { + + /** + * Display the stdout and stderr of the process in the console. Use the + * console parsers to parse that output to mark errors and warnings and + * such. The build directory helps to find resources for markers. + * + * @param process + * @param consoleParsers + * @param buildDirectory + * @throws IOException + */ + void monitor(Process process, CConsoleParser[] consoleParsers, IFolder buildDirectory) throws IOException; + + /** + * Write a message on the console stdout. + * + * @param msg + * @throws IOException + */ + void writeOutput(String msg) throws IOException; + + /** + * Write a message on the console stderr. + * + * @param msg + * @throws IOException + */ + void writeError(String msg) throws IOException; + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ScannerInfoData.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ScannerInfoData.java new file mode 100644 index 00000000000..6de24163102 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ScannerInfoData.java @@ -0,0 +1,166 @@ +package org.eclipse.cdt.internal.core.build; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.build.CBuildConfiguration; +import org.eclipse.cdt.core.build.CToolChain; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.LanguageManager; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.content.IContentType; + +import com.google.gson.Gson; + +public class ScannerInfoData { + + private Set perResourceInfo; + private Map perLanguageInfo; + + private transient Path savePath; + private transient Map infoCache; + private transient Map resourceCache; + + public void createCache() { + infoCache = new HashMap<>(); + resourceCache = new HashMap<>(); + if (perResourceInfo != null) { + for (ToolChainScannerInfo info : perResourceInfo) { + infoCache.put(info, info); + for (String path : info.getResourcePaths()) { + resourceCache.put(path, info); + } + } + } + } + + private boolean perResource() { + return perResourceInfo != null && !perResourceInfo.isEmpty(); + } + + private boolean perLanguage() { + return perLanguageInfo != null && !perLanguageInfo.isEmpty(); + } + + public IScannerInfo getScannerInfo(IResource resource) { + if (perResource()) { + ToolChainScannerInfo info = resourceCache.get(resource.getFullPath().toString()); + if (info != null) { + return info.getScannerInfo(); + } + } + + // Else try language + if (perLanguage()) { + IProject project = resource.getProject(); + IContentType contentType = CCorePlugin.getContentType(project, resource.getName()); + if (contentType != null) { + ILanguage language = LanguageManager.getInstance().getLanguage(contentType, project); + ToolChainScannerInfo info = perLanguageInfo.get(language.getId()); + if (info != null) { + return info.getScannerInfo(); + } + } + } + + return null; + } + + public IScannerInfo getScannerInfo(ILanguage language) { + if (perLanguage()) { + ToolChainScannerInfo info = perLanguageInfo.get(language.getId()); + if (info != null) { + return info.getScannerInfo(); + } + } + return null; + } + + public void putScannerInfo(IResource resource, ToolChainScannerInfo info) { + if (perResourceInfo == null) { + perResourceInfo = new HashSet<>(); + infoCache = new HashMap<>(); + infoCache.put(info, info); + } else { + ToolChainScannerInfo existing = infoCache.get(info); + if (existing != null) { + info = existing; + } else { + perResourceInfo.add(info); + infoCache.put(info, info); + } + } + + info.addResource(resource); + resourceCache.put(resource.getFullPath().toString(), info); + queueSave(); + } + + public void putScannerInfo(ILanguage language, ToolChainScannerInfo info) { + if (perLanguageInfo == null) { + perLanguageInfo = new HashMap<>(); + } + perLanguageInfo.put(language.getId(), info); + queueSave(); + } + + public static ScannerInfoData load(CToolChain toolChain) { + IPath stateLoc = Platform.getStateLocation(CCorePlugin.getDefault().getBundle()); + CBuildConfiguration config = toolChain.getBuildConfiguration(); + IPath scannerInfoPath = stateLoc.append(config.getProject().getName()) + .append(config.getName() + ".scInfo"); //$NON-NLS-1$ + File scannerInfoFile = scannerInfoPath.toFile(); + ScannerInfoData info = null; + if (scannerInfoFile.canRead()) { + try (Reader reader = new FileReader(scannerInfoFile)) { + info = new Gson().fromJson(reader, ScannerInfoData.class); + } catch (Exception e) { + CCorePlugin.log(e); + } + } + + if (info == null) { + info = new ScannerInfoData(); + } + + info.savePath = scannerInfoFile.toPath(); + info.createCache(); + return info; + } + + public void save() { + try { + String json = new Gson().toJson(this); + Files.createDirectories(savePath.getParent()); + Files.write(savePath, json.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + CCorePlugin.log(e); + } + } + + public void queueSave() { + ScannerInfoSaveParticipant.getInstance().save(this); + } + + public void clear() { + perLanguageInfo = null; + perResourceInfo = null; + createCache(); + queueSave(); + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ScannerInfoSaveParticipant.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ScannerInfoSaveParticipant.java new file mode 100644 index 00000000000..cac8016956c --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ScannerInfoSaveParticipant.java @@ -0,0 +1,50 @@ +package org.eclipse.cdt.internal.core.build; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.ISaveParticipant; +import org.eclipse.core.runtime.CoreException; + +public class ScannerInfoSaveParticipant implements ISaveParticipant { + + private static ScannerInfoSaveParticipant instance; + private Set toBeSaved = new HashSet<>(); + + public ScannerInfoSaveParticipant() { + assert instance == null; + instance = this; + } + + public static ScannerInfoSaveParticipant getInstance() { + return instance; + } + + public void save(ScannerInfoData info) { + toBeSaved.add(info); + } + + @Override + public void doneSaving(ISaveContext context) { + } + + @Override + public void prepareToSave(ISaveContext context) throws CoreException { + } + + @Override + public void rollback(ISaveContext context) { + // TODO Auto-generated method stub + + } + + @Override + public void saving(ISaveContext context) throws CoreException { + for (ScannerInfoData info : toBeSaved) { + info.save(); + } + toBeSaved.clear(); + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainScannerInfo.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainScannerInfo.java new file mode 100644 index 00000000000..34ed440785f --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainScannerInfo.java @@ -0,0 +1,56 @@ +package org.eclipse.cdt.internal.core.build; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.parser.ExtendedScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.core.resources.IResource; + +public class ToolChainScannerInfo { + private Map definedSymbols; + private List includePaths; + private List macroFiles; + private List includeFiles; + private List localIncludePath; + private Set resourcePaths; + + private transient IScannerInfo scannerInfo; + + public ToolChainScannerInfo(Map definedSymbols, List includePaths, + List macroFiles, List includeFiles, List localIncludePath) { + this.definedSymbols = definedSymbols; + this.includePaths = includePaths; + this.macroFiles = macroFiles; + this.includeFiles = includeFiles; + this.localIncludePath = localIncludePath; + } + + public IScannerInfo getScannerInfo() { + if (scannerInfo == null) { + scannerInfo = new ExtendedScannerInfo(definedSymbols, + includePaths != null ? includePaths.toArray(new String[includePaths.size()]) : null, + macroFiles != null ? macroFiles.toArray(new String[includePaths.size()]) : null, + includeFiles != null ? includeFiles.toArray(new String[includePaths.size()]) : null, + localIncludePath != null ? localIncludePath.toArray(new String[includePaths.size()]) + : null); + } + return scannerInfo; + } + + public Collection getResourcePaths() { + return resourcePaths != null ? resourcePaths : Collections. emptySet(); + } + + public void addResource(IResource resource) { + if (resourcePaths == null) { + resourcePaths = new HashSet<>(); + } + resourcePaths.add(resource.getFullPath().toString()); + } + +} diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index 9b97619ec8b..0c0eda18f02 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true -Bundle-Version: 5.11.0.qualifier +Bundle-Version: 5.12.0.qualifier Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -126,3 +126,4 @@ Require-Bundle: org.eclipse.cdt.core;bundle-version="[5.2.0,6.0.0)", org.eclipse.e4.ui.css.swt.theme Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Service-Component: OSGI-INF/consoleservice.xml diff --git a/core/org.eclipse.cdt.ui/OSGI-INF/consoleservice.xml b/core/org.eclipse.cdt.ui/OSGI-INF/consoleservice.xml new file mode 100644 index 00000000000..bedd5d36824 --- /dev/null +++ b/core/org.eclipse.cdt.ui/OSGI-INF/consoleservice.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/core/org.eclipse.cdt.ui/pom.xml b/core/org.eclipse.cdt.ui/pom.xml index fb7a8ba58e1..3ed7481ec3e 100644 --- a/core/org.eclipse.cdt.ui/pom.xml +++ b/core/org.eclipse.cdt.ui/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 5.11.0-SNAPSHOT + 5.12.0-SNAPSHOT org.eclipse.cdt.ui eclipse-plugin diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtConsoleService.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CConsoleService.java similarity index 64% rename from qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtConsoleService.java rename to core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CConsoleService.java index 0a5756cccbc..89e3a2aaece 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtConsoleService.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CConsoleService.java @@ -1,12 +1,13 @@ -package org.eclipse.cdt.internal.qt.ui; +package org.eclipse.cdt.internal.ui.build; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CountDownLatch; -import org.eclipse.cdt.internal.qt.core.QtPlugin; -import org.eclipse.cdt.internal.qt.core.build.IConsoleService; +import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IncrementalProjectBuilder; @@ -18,14 +19,21 @@ import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; -public class QtConsoleService implements IConsoleService, IResourceChangeListener { +import org.eclipse.cdt.core.build.CConsoleParser; +import org.eclipse.cdt.core.build.IConsoleService; +import org.eclipse.cdt.ui.CUIPlugin; + +public class CConsoleService implements IConsoleService, IResourceChangeListener { private MessageConsole console; private MessageConsoleStream out; private MessageConsoleStream err; + private IFolder buildDirectory; + List listeners = new ArrayList<>(); + private void initConsole() { - console = new MessageConsole("Qt Builds", null); + console = new MessageConsole("C/C++", null); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console }); out = console.newMessageStream(); err = console.newMessageStream(); @@ -57,19 +65,39 @@ public class QtConsoleService implements IConsoleService, IResourceChangeListene } @Override - public void monitor(final Process process) throws IOException { + public void monitor(final Process process, CConsoleParser[] consoleParsers, IFolder buildDirectory) + throws IOException { if (console == null) { initConsole(); } + this.buildDirectory = buildDirectory; + + // Clear the old listeners + for (CPatternMatchListener listener : listeners) { + console.removePatternMatchListener(listener); + } + listeners.clear(); + + // Add in the new ones if any + if (consoleParsers != null) { + for (CConsoleParser parser : consoleParsers) { + CPatternMatchListener listener = new CPatternMatchListener(this, parser); + listeners.add(listener); + console.addPatternMatchListener(listener); + } + } + console.activate(); final CountDownLatch latch = new CountDownLatch(2); // Output stream reader - new Thread("Qt Build Console Output") { + new Thread("C/C++ Build Console Output") { //$NON-NLS-1$ + @Override public void run() { - try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + try (BufferedReader processOut = new BufferedReader( + new InputStreamReader(process.getInputStream()))) { for (String line = processOut.readLine(); line != null; line = processOut.readLine()) { out.write(line); out.write('\n'); @@ -83,9 +111,11 @@ public class QtConsoleService implements IConsoleService, IResourceChangeListene }.start(); // Error stream reader - new Thread("Qt Build Console Error") { + new Thread("C/C++ Build Console Error") { //$NON-NLS-1$ + @Override public void run() { - try (BufferedReader processErr = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + try (BufferedReader processErr = new BufferedReader( + new InputStreamReader(process.getErrorStream()))) { for (String line = processErr.readLine(); line != null; line = processErr.readLine()) { err.write(line); out.write('\n'); @@ -102,7 +132,7 @@ public class QtConsoleService implements IConsoleService, IResourceChangeListene latch.await(); process.waitFor(); } catch (InterruptedException e) { - QtPlugin.log(e); + CUIPlugin.log(e); } } @@ -122,4 +152,8 @@ public class QtConsoleService implements IConsoleService, IResourceChangeListene err.write(msg); } + public IFolder getBuildDirectory() { + return buildDirectory; + } + } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoHyperlink.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CHyperlink.java similarity index 72% rename from toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoHyperlink.java rename to core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CHyperlink.java index 155f3b89c10..a29ea02d746 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoHyperlink.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CHyperlink.java @@ -1,6 +1,5 @@ -package org.eclipse.cdt.arduino.ui.internal.launch; +package org.eclipse.cdt.internal.ui.build; -import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.core.resources.IMarker; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; @@ -8,11 +7,13 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.IHyperlink; import org.eclipse.ui.ide.IDE; -public class ArduinoHyperlink implements IHyperlink { +import org.eclipse.cdt.ui.CUIPlugin; + +public class CHyperlink implements IHyperlink { private final IMarker marker; - public ArduinoHyperlink(IMarker marker) { + public CHyperlink(IMarker marker) { this.marker = marker; } @@ -30,7 +31,7 @@ public class ArduinoHyperlink implements IHyperlink { try { IDE.openEditor(page, marker); } catch (PartInitException e) { - Activator.log(e); + CUIPlugin.log(e); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CPatternMatchListener.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CPatternMatchListener.java new file mode 100644 index 00000000000..f06099fc1c8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/build/CPatternMatchListener.java @@ -0,0 +1,63 @@ +package org.eclipse.cdt.internal.ui.build; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.ui.console.IPatternMatchListener; +import org.eclipse.ui.console.PatternMatchEvent; +import org.eclipse.ui.console.TextConsole; + +import org.eclipse.cdt.core.build.CConsoleParser; +import org.eclipse.cdt.ui.CUIPlugin; + +public class CPatternMatchListener implements IPatternMatchListener { + + protected final CConsoleService console; + protected final CConsoleParser parser; + + protected TextConsole textConsole; + + public CPatternMatchListener(CConsoleService console, CConsoleParser parser) { + this.console = console; + this.parser = parser; + } + + @Override + public void connect(TextConsole console) { + this.textConsole = console; + } + + @Override + public void disconnect() { + } + + @Override + public void matchFound(PatternMatchEvent event) { + try { + String text = textConsole.getDocument().get(event.getOffset(), event.getLength()); + IMarker marker = parser.generateMarker(console.getBuildDirectory(), text); + if (marker != null) { + textConsole.addHyperlink(new CHyperlink(marker), + event.getOffset() + marker.getAttribute(CConsoleParser.LINK_OFFSET, 0), + marker.getAttribute(CConsoleParser.LINK_LENGTH, event.getLength())); + } + } catch (BadLocationException e) { + CUIPlugin.log(e); + } + } + + @Override + public String getPattern() { + return parser.getPattern(); + } + + @Override + public int getCompilerFlags() { + return parser.getCompilerFlags(); + } + + @Override + public String getLineQualifier() { + return parser.getLineQualifier(); + } + +} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/IConsoleService.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/IConsoleService.java deleted file mode 100644 index bac8e25d50b..00000000000 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/IConsoleService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.eclipse.cdt.internal.qt.core.build; - -import java.io.IOException; - -public interface IConsoleService { - - // TODO add error parsers - void monitor(Process process) throws IOException; - - void writeOutput(String msg) throws IOException; - - void writeError(String msg) throws IOException; - -} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java index 83c0d5b8042..06ef2941907 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; import java.util.Map; +import org.eclipse.cdt.core.build.IConsoleService; import org.eclipse.cdt.internal.qt.core.QtPlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -43,12 +44,12 @@ public class QtBuilder extends IncrementalProjectBuilder { } msg.append('\n'); console.writeOutput(msg.toString()); - console.monitor(process); + console.monitor(process, null, buildFolder); } // run make Process process = new ProcessBuilder("make").directory(new File(buildFolder.getLocationURI())).start(); //$NON-NLS-1$ - console.monitor(process); + console.monitor(process, null, buildFolder); buildFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor); return new IProject[] { project }; diff --git a/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF b/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF index f2a8ef978f0..71c77dfb49b 100644 --- a/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF +++ b/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF @@ -20,4 +20,3 @@ Require-Bundle: org.eclipse.core.runtime, Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.internal.qt.ui.assist;x-friends:="org.eclipse.cdt.qt.tests" -Service-Component: OSGI-INF/consoleservice.xml diff --git a/qt/org.eclipse.cdt.qt.ui/OSGI-INF/consoleservice.xml b/qt/org.eclipse.cdt.qt.ui/OSGI-INF/consoleservice.xml deleted file mode 100644 index 06dbdbbc437..00000000000 --- a/qt/org.eclipse.cdt.qt.ui/OSGI-INF/consoleservice.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtUIPlugin.java b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtUIPlugin.java index 62edffb37a8..8e2daf6091a 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtUIPlugin.java +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtUIPlugin.java @@ -44,9 +44,6 @@ public class QtUIPlugin extends AbstractUIPlugin { public void start(BundleContext context) throws Exception { super.start(context); plugin = this; - - // context.registerService(IConsoleService.class, new - // QtConsoleService(), null); } @Override diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF b/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF index 6231695e45f..454e80cf257 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF @@ -22,6 +22,5 @@ Bundle-ClassPath: libs/freemarker-2.3.22.jar, Export-Package: org.eclipse.cdt.arduino.core.internal;x-friends:="org.eclipse.cdt.arduino.ui", org.eclipse.cdt.arduino.core.internal.board;x-friends:="org.eclipse.cdt.arduino.ui", org.eclipse.cdt.arduino.core.internal.build;x-friends:="org.eclipse.cdt.arduino.ui", - org.eclipse.cdt.arduino.core.internal.console;x-friends:="org.eclipse.cdt.arduino.ui", org.eclipse.cdt.arduino.core.internal.remote;x-friends:="org.eclipse.cdt.arduino.ui" Bundle-Localization: plugin diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties b/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties index a20aa47b2f0..73094ad4b81 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/build.properties @@ -4,6 +4,5 @@ bin.includes = META-INF/,\ plugin.xml,\ templates/,\ about.html,\ - schema/,\ plugin.properties,\ libs/ diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml index 676505ab53b..170aa8240e1 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml @@ -1,7 +1,6 @@ - cache = new HashMap<>(); @@ -135,23 +131,6 @@ public class ArduinoBuildConfiguration { return arduinoConfig; } - public void setActive(IProgressMonitor monitor) throws CoreException { - IProject project = config.getProject(); - if (config.equals(project.getActiveBuildConfig())) { - // already set - return; - } - - IProjectDescription projectDesc = project.getDescription(); - projectDesc.setActiveBuildConfig(config.getName()); - project.setDescription(projectDesc, monitor); - } - - public IEclipsePreferences getSettings() { - return (IEclipsePreferences) new ProjectScope(config.getProject()).getNode(Activator.getId()).node("config") //$NON-NLS-1$ - .node(config.getName()); - } - public void setBoard(ArduinoBoard board) throws CoreException { this.board = board; @@ -165,7 +144,7 @@ public class ArduinoBuildConfiguration { try { settings.flush(); } catch (BackingStoreException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$ } } @@ -191,15 +170,15 @@ public class ArduinoBuildConfiguration { } properties.put("runtime.ide.version", "10607"); //$NON-NLS-1$ //$NON-NLS-2$ properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$ - properties.put("build.path", config.getName()); //$NON-NLS-1$ + properties.put("build.path", getName()); //$NON-NLS-1$ } // always do this in case the project changes names - properties.put("build.project_name", config.getProject().getName()); //$NON-NLS-1$ + properties.put("build.project_name", getProject().getName()); //$NON-NLS-1$ return properties; } public IFolder getBuildFolder() throws CoreException { - IProject project = config.getProject(); + IProject project = getProject(); return project.getFolder("build"); //$NON-NLS-1$ } @@ -215,7 +194,7 @@ public class ArduinoBuildConfiguration { } public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException { - final IProject project = config.getProject(); + final IProject project = getProject(); IFolder buildFolder = getBuildFolder(); if (!buildFolder.exists()) { @@ -368,7 +347,7 @@ public class ArduinoBuildConfiguration { List toolPaths = new ArrayList<>(); if (isWindows) { // Add in the tools/make directory to pick up make - toolPaths.add(ArduinoPreferences.getArduinoHome().resolve("tools/make")); + toolPaths.add(ArduinoPreferences.getArduinoHome().resolve("tools/make")); //$NON-NLS-1$ } ArduinoBoard board = getBoard(); ArduinoPlatform platform = board.getPlatform(); @@ -444,57 +423,40 @@ public class ArduinoBuildConfiguration { String command = resolveProperty("tools." + toolName + ".upload.pattern", properties); //$NON-NLS-1$ //$NON-NLS-2$ if (isWindows) { - return splitCommand(command); + return CToolChain.splitCommand(command); } else { return new String[] { "sh", "-c", command }; //$NON-NLS-1$ //$NON-NLS-2$ } } public IScannerInfo getScannerInfo(IResource resource) throws CoreException { - // what language is this resource and pick the right path; - switch (CCorePlugin.getContentType(resource.getProject(), resource.getName()).getId()) { - case CCorePlugin.CONTENT_TYPE_CXXSOURCE: - case CCorePlugin.CONTENT_TYPE_CXXHEADER: - if (cppScannerInfo == null) { - cppScannerInfo = calculateScannerInfo("recipe.cpp.o.pattern", resource); //$NON-NLS-1$ + IScannerInfo info = super.getScannerInfo(resource); + if (info == null) { + // what language is this resource and pick the right recipe + String recipe; + switch (CCorePlugin.getContentType(resource.getProject(), resource.getName()).getId()) { + case CCorePlugin.CONTENT_TYPE_CXXSOURCE: + case CCorePlugin.CONTENT_TYPE_CXXHEADER: + recipe = "recipe.cpp.o.pattern"; //$NON-NLS-1$ + break; + default: + recipe = "recipe.c.o.pattern"; //$NON-NLS-1$ } - return cppScannerInfo; - default: - if (cScannerInfo == null) { - cScannerInfo = calculateScannerInfo("recipe.c.o.pattern", resource); //$NON-NLS-1$ - } - return cScannerInfo; - } - } - public void clearScannerInfoCache() { - cppScannerInfo = null; - cScannerInfo = null; - } - - public static String pathString(Path path) { - String str = path.toString(); - if (isWindows) { - str = str.replaceAll("\\\\", "/"); - } - return str; - } - - private IScannerInfo calculateScannerInfo(String recipe, IResource resource) throws CoreException { - try { ArduinoPlatform platform = getBoard().getPlatform(); Properties properties = new Properties(); properties.putAll(getProperties()); - Path tmpFile = Files.createTempFile("cdt", ".cpp"); //$NON-NLS-1$ //$NON-NLS-2$ - properties.put("source_file", pathString(tmpFile)); //$NON-NLS-1$ + Path resourcePath = new File(resource.getLocationURI()).toPath(); + Path sourcePath = getBuildDirectory().toPath().relativize(resourcePath); + properties.put("source_file", pathString(sourcePath)); //$NON-NLS-1$ properties.put("object_file", "-"); //$NON-NLS-1$ //$NON-NLS-2$ - String includes = "-E -P -v -dD"; //$NON-NLS-1$ + String includes = ""; //$NON-NLS-1$ for (Path include : platform.getIncludePath()) { includes += " -I\"" + pathString(include) + '"'; //$NON-NLS-1$ } - Collection libs = ArduinoManager.instance.getLibraries(config.getProject()); + Collection libs = ArduinoManager.instance.getLibraries(getProject()); for (ArduinoLibrary lib : libs) { for (Path path : lib.getIncludePath()) { includes += " -I\"" + pathString(path) + '"'; //$NON-NLS-1$ @@ -502,87 +464,18 @@ public class ArduinoBuildConfiguration { } properties.put("includes", includes); //$NON-NLS-1$ - String[] command; - if (isWindows) { - command = splitCommand(resolveProperty(recipe, properties)); - } else { - command = new String[] { "sh", "-c", resolveProperty(recipe, properties) }; //$NON-NLS-1$ //$NON-NLS-2$ - } - ProcessBuilder processBuilder = new ProcessBuilder(command).directory(tmpFile.getParent().toFile()) - .redirectErrorStream(true); - setEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); - - Map symbols = new HashMap<>(); - List includePath = new ArrayList<>(); - Pattern definePattern = Pattern.compile("#define (.*)\\s(.*)"); //$NON-NLS-1$ - boolean inIncludePaths = false; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - if (inIncludePaths) { - if (line.equals("End of search list.")) { //$NON-NLS-1$ - inIncludePaths = false; - } else { - includePath.add(line.trim()); - } - } else if (line.startsWith("#define ")) { //$NON-NLS-1$ - Matcher matcher = definePattern.matcher(line); - if (matcher.matches()) { - symbols.put(matcher.group(1), matcher.group(2)); - } - } else if (line.equals("#include <...> search starts here:")) { //$NON-NLS-1$ - inIncludePaths = true; - } - } - } - Files.delete(tmpFile); - ExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(symbols, - includePath.toArray(new String[includePath.size()])); - return scannerInfo; - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Compiler built-ins", e)); + getToolChain().scanBuildOutput(getBuildFolder(), resolveProperty(recipe, properties), true); + info = super.getScannerInfo(resource); } + return info; } - private String[] splitCommand(String command) { - // TODO deal with quotes properly, for now just strip - return command.replaceAll("\"", "").split("\\s+"); - } - - public ArduinoConsoleParser[] getBuildConsoleParsers() { - // ../src/Test.cpp:4:1: error: 'x' was not declared in this scope - - return new ArduinoConsoleParser[] { new ArduinoErrorParser("(.*?):(\\d+):(\\d+:)? (fatal )?error: (.*)") { //$NON-NLS-1$ - @Override - protected int getSeverity(Matcher matcher) { - return IMarker.SEVERITY_ERROR; - } - - @Override - protected String getMessage(Matcher matcher) { - return matcher.group(5); - } - - @Override - protected int getLineNumber(Matcher matcher) { - return Integer.parseInt(matcher.group(2)); - } - - @Override - protected String getFileName(Matcher matcher) { - return matcher.group(1); - } - - @Override - protected int getLinkOffset(Matcher matcher) { - return 0; - } - - @Override - protected int getLinkLength(Matcher matcher) { - return matcher.group(1).length() + 1 + matcher.group(2).length() + 1 + matcher.group(3).length(); - } - } }; + public static String pathString(Path path) { + String str = path.toString(); + if (isWindows) { + str = str.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$ + } + return str; } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java index a4f55b5dc0a..0275c0c4a26 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java @@ -15,7 +15,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.cdt.arduino.core.internal.Activator; -import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService; +import org.eclipse.cdt.core.build.IConsoleService; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -39,8 +39,8 @@ public class ArduinoBuilder extends IncrementalProjectBuilder { try { project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - ArduinoConsoleService consoleService = Activator.getConsoleService(); - consoleService.writeOutput(String.format("\nBuilding %s\n", project.getName())); + IConsoleService consoleService = Activator.getService(IConsoleService.class); + consoleService.writeOutput(String.format("Building %s\n", project.getName())); ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class); config.generateMakeFile(monitor); @@ -50,15 +50,16 @@ public class ArduinoBuilder extends IncrementalProjectBuilder { config.setEnvironment(processBuilder.environment()); Process process = processBuilder.start(); - consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder()); + consoleService.monitor(process, config.getConsoleParsers(), config.getBuildFolder()); if (process.exitValue() == 0) { showSizes(config, consoleService); } config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor); + consoleService.writeOutput("\n"); //$NON-NLS-1$ } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); //$NON-NLS-1$ } // TODO if there are references we want to watch, return them here @@ -71,8 +72,8 @@ public class ArduinoBuilder extends IncrementalProjectBuilder { IProject project = getProject(); project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - ArduinoConsoleService consoleService = Activator.getConsoleService(); - consoleService.writeOutput(String.format("\nCleaning %s\n", project.getName())); + IConsoleService consoleService = Activator.getService(IConsoleService.class); + consoleService.writeOutput(String.format("Cleaning %s\n", project.getName())); ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class); @@ -81,15 +82,16 @@ public class ArduinoBuilder extends IncrementalProjectBuilder { config.setEnvironment(processBuilder.environment()); Process process = processBuilder.start(); - consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder()); + consoleService.monitor(process, config.getConsoleParsers(), config.getBuildFolder()); config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor); + consoleService.writeOutput("\n"); //$NON-NLS-1$ } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); //$NON-NLS-1$ } } - private void showSizes(ArduinoBuildConfiguration config, ArduinoConsoleService console) throws CoreException { + private void showSizes(ArduinoBuildConfiguration config, IConsoleService console) throws CoreException { try { int codeSize = -1; int dataSize = -1; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleParser.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleParser.java deleted file mode 100644 index 62329eb68c5..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleParser.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.eclipse.cdt.arduino.core.internal.console; - -public abstract class ArduinoConsoleParser { - - private final String pattern; - private final int flags; - private final String lineQualifier; - - protected ArduinoConsoleParser(String pattern, int flags, String lineQualifier) { - this.pattern = pattern; - this.flags = flags; - this.lineQualifier = lineQualifier; - } - - /** - * Returns the pattern to be used for matching. The pattern is a string - * representing a regular expression. - * - * @return the regular expression to be used for matching - */ - public String getPattern() { - return pattern; - } - - /** - * Returns the flags to use when compiling this pattern match listener's - * regular expression, as defined by by - * Pattern.compile(String regex, int flags) - * - * @return the flags to use when compiling this pattern match listener's - * regular expression - * @see java.util.regex.Pattern#compile(java.lang.String, int) - */ - public int getCompilerFlags() { - return flags; - } - - /** - * Returns a simple regular expression used to identify lines that may match - * this pattern matcher's complete pattern, or null. Use of - * this attribute can improve performance by disqualifying lines from the - * search. When a line is found containing a match for this expression, the - * line is searched from the beginning for this pattern matcher's complete - * pattern. Lines not containing this pattern are discarded. - * - * @return a simple regular expression used to identify lines that may match - * this pattern matcher's complete pattern, or null - */ - public String getLineQualifier() { - return lineQualifier; - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleService.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleService.java deleted file mode 100644 index 5ac7dba8731..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleService.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.arduino.core.internal.console; - -import java.io.IOException; - -import org.eclipse.core.resources.IFolder; - -public interface ArduinoConsoleService { - - void monitor(Process process, ArduinoConsoleParser[] consoleParsers, IFolder buildDirectory) throws IOException; - - void writeOutput(String msg) throws IOException; - - void writeError(String msg) throws IOException; - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoErrorParser.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoErrorParser.java deleted file mode 100644 index 96031b72aef..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoErrorParser.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.eclipse.cdt.arduino.core.internal.console; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.cdt.arduino.core.internal.Activator; -import org.eclipse.cdt.core.model.ICModelMarker; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.CoreException; - -public abstract class ArduinoErrorParser extends ArduinoConsoleParser { - - public static final String LINK_OFFSET = "arduino.link.offset"; //$NON-NLS-1$ - public static final String LINK_LENGTH = "arduino.link.length"; //$NON-NLS-1$ - - private final Pattern errorPattern; - - public ArduinoErrorParser(String pattern, int flags, String lineQualifier) { - super(pattern, flags, lineQualifier); - this.errorPattern = Pattern.compile(pattern); - } - - public ArduinoErrorParser(String pattern) { - this(pattern, 0, null); - } - - protected abstract String getFileName(Matcher matcher); - - protected abstract int getLineNumber(Matcher matcher); - - protected abstract String getMessage(Matcher matcher); - - protected abstract int getSeverity(Matcher matcher); - - protected abstract int getLinkOffset(Matcher matcher); - - protected abstract int getLinkLength(Matcher matcher); - - public IMarker generateMarker(IFolder buildDirectory, String text) { - Matcher matcher = errorPattern.matcher(text); - if (matcher.matches()) { - String fileName = getFileName(matcher); - - IFile file = buildDirectory.getFile(fileName); - if (file.exists()) { - try { - IMarker marker = file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER); - marker.setAttribute(IMarker.MESSAGE, getMessage(matcher)); - marker.setAttribute(IMarker.SEVERITY, getSeverity(matcher)); - marker.setAttribute(IMarker.LINE_NUMBER, getLineNumber(matcher)); - marker.setAttribute(IMarker.CHAR_START, -1); - marker.setAttribute(IMarker.CHAR_END, -1); - marker.setAttribute(LINK_OFFSET, getLinkOffset(matcher)); - marker.setAttribute(LINK_LENGTH, getLinkLength(matcher)); - return marker; - } catch (CoreException e) { - Activator.log(e); - return null; - } - } - } - return null; - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java index 0b02d6f995c..e6dc733cd0b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java @@ -16,8 +16,8 @@ import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.Messages; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; -import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService; import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection; +import org.eclipse.cdt.core.build.IConsoleService; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -76,7 +76,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg new Job(Messages.ArduinoLaunchConfigurationDelegate_0) { protected IStatus run(IProgressMonitor monitor) { try { - ArduinoConsoleService consoleService = Activator.getConsoleService(); + IConsoleService consoleService = Activator.getService(IConsoleService.class); IRemoteConnection target = getTarget(configuration); if (target == null) { return new Status(IStatus.ERROR, Activator.getId(), diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml index 7971aae6958..a453e907a50 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml @@ -30,12 +30,6 @@ project="true"> - - - - listeners = new ArrayList<>(); - - public ArduinoConsole() { - if (console == null) { - console = new MessageConsole(Messages.ArduinoLaunchConsole_0, null); - ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console }); - out = console.newMessageStream(); - err = console.newMessageStream(); - - // set the colors - final Display display = Display.getDefault(); - display.syncExec(new Runnable() { - @Override - public void run() { - out.setColor(display.getSystemColor(SWT.COLOR_BLACK)); - err.setColor(display.getSystemColor(SWT.COLOR_RED)); - } - }); - ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_BUILD); - } - } - - @Override - public void resourceChanged(IResourceChangeEvent event) { - switch (event.getType()) { - case IResourceChangeEvent.PRE_BUILD: - if (event.getBuildKind() != IncrementalProjectBuilder.AUTO_BUILD) { - // TODO this really should be done from the core and only when - // our projects are being built - console.clearConsole(); - } - break; - } - } - - public IFolder getBuildDirectory() { - return buildDirectory; - } - - @Override - public void monitor(final Process process, ArduinoConsoleParser[] consoleParsers, IFolder buildDirectory) - throws IOException { - this.buildDirectory = buildDirectory; - - // Clear the old listeners - for (ArduinoPatternMatchListener listener : listeners) { - console.removePatternMatchListener(listener); - } - listeners.clear(); - - // Add in the new ones if any - if (consoleParsers != null) { - for (ArduinoConsoleParser parser : consoleParsers) { - ArduinoPatternMatchListener listener; - if (parser instanceof ArduinoErrorParser) { - listener = new ArduinoErrorMatchListener(this, (ArduinoErrorParser) parser); - } else { - continue; - } - listeners.add(listener); - console.addPatternMatchListener(listener); - } - } - - console.activate(); - - final Semaphore sema = new Semaphore(-1); - - // Output stream reader - new Thread(Messages.ArduinoLaunchConsole_2) { - public void run() { - try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - for (String line = processOut.readLine(); line != null; line = processOut.readLine()) { - out.write(line); - out.write('\n'); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - sema.release(); - } - } - }.start(); - - // Error stream reader - new Thread(Messages.ArduinoLaunchConsole_2) { - public void run() { - try (BufferedReader processErr = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - for (String line = processErr.readLine(); line != null; line = processErr.readLine()) { - err.write(line); - out.write('\n'); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - sema.release(); - } - } - }.start(); - - try { - sema.acquire(); - process.waitFor(); - } catch (InterruptedException e) { - Activator.log(e); - } - } - - @Override - public void writeOutput(String msg) throws IOException { - out.write(msg); - } - - @Override - public void writeError(String msg) throws IOException { - err.write(msg); - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoErrorMatchListener.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoErrorMatchListener.java deleted file mode 100644 index 839d16f2a78..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoErrorMatchListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.eclipse.cdt.arduino.ui.internal.launch; - -import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser; -import org.eclipse.cdt.arduino.ui.internal.Activator; -import org.eclipse.core.resources.IMarker; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.ui.console.PatternMatchEvent; - -public class ArduinoErrorMatchListener extends ArduinoPatternMatchListener { - - public ArduinoErrorMatchListener(ArduinoConsole arduinoConsole, ArduinoErrorParser parser) { - super(arduinoConsole, parser); - } - - @Override - public void matchFound(PatternMatchEvent event) { - try { - String text = textConsole.getDocument().get(event.getOffset(), event.getLength()); - IMarker marker = ((ArduinoErrorParser) parser).generateMarker(arduinoConsole.getBuildDirectory(), text); - if (marker != null) { - textConsole.addHyperlink(new ArduinoHyperlink(marker), - event.getOffset() + marker.getAttribute(ArduinoErrorParser.LINK_OFFSET, 0), - marker.getAttribute(ArduinoErrorParser.LINK_LENGTH, event.getLength())); - } - } catch (BadLocationException e) { - Activator.log(e); - } - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoPatternMatchListener.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoPatternMatchListener.java deleted file mode 100644 index 1b6f40f854c..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoPatternMatchListener.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.eclipse.cdt.arduino.ui.internal.launch; - -import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser; -import org.eclipse.ui.console.IPatternMatchListener; -import org.eclipse.ui.console.TextConsole; - -public abstract class ArduinoPatternMatchListener implements IPatternMatchListener { - - protected final ArduinoConsole arduinoConsole; - protected final ArduinoConsoleParser parser; - - protected TextConsole textConsole; - - public ArduinoPatternMatchListener(ArduinoConsole arduinoConsole, ArduinoConsoleParser parser) { - this.arduinoConsole = arduinoConsole; - this.parser = parser; - } - - @Override - public void connect(TextConsole console) { - this.textConsole = console; - } - - @Override - public void disconnect() { - } - - @Override - public String getPattern() { - return parser.getPattern(); - } - - @Override - public int getCompilerFlags() { - return parser.getCompilerFlags(); - } - - @Override - public String getLineQualifier() { - return parser.getLineQualifier(); - } - -}