1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-08 19:13:27 +02:00

Bug 321443 - First implementation of new build model.

Includes adaptation of the Arduino build model where many of these
ideas started to the new model. And start of the Qt build system which
uses it.

Change-Id: Icb212185773ebc4d415e8a9862101744703ff80b
This commit is contained in:
Doug Schaefer 2015-08-31 11:26:50 -04:00 committed by Gerrit Code Review @ Eclipse.org
parent f505c21a48
commit 64c5782589
39 changed files with 1658 additions and 1007 deletions

View file

@ -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

View file

@ -683,6 +683,7 @@
<extension-point id="LanguageSettingsProvider" name="%LanguageSettingsProvider.name" schema="schema/LanguageSettingsProvider.exsd"/>
<extension-point id="UNCPathConverter" name="%uncPathConverter.name" schema="schema/UNCPathConverter.exsd"/>
<extension-point id="ProblemMarkerFilter" name="%problemMarkerFilter.name" schema="schema/ProblemMarkerFilter.exsd"/>
<extension-point id="ToolChain" name="ToolChain" schema="schema/ToolChain.exsd"/>
<extension
point="org.eclipse.cdt.core.templateProcessTypes">
@ -856,5 +857,22 @@
ordering="first">
</filterMatcher>
</extension>
<extension
point="org.eclipse.cdt.core.ToolChain">
<toolChain
adaptor="org.eclipse.cdt.core.build.GCCToolChain"
id="org.eclipse.cdt.core.gcc">
</toolChain>
</extension>
<extension
point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="org.eclipse.cdt.core.build.CBuildConfiguration"
class="org.eclipse.cdt.core.build.GCCToolChain$Factory">
<adapter
type="org.eclipse.cdt.core.build.GCCToolChain">
</adapter>
</factory>
</extension>
</plugin>

View file

@ -11,7 +11,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<version>5.11.0-SNAPSHOT</version>
<version>5.12.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.core</artifactId>
<packaging>eclipse-plugin</packaging>
</project>

View file

@ -1,10 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.arduino.core" xmlns="http://www.w3.org/2001/XMLSchema">
<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.cdt.arduino.core" id="consoleService" name="Arduino Launch Console Service"/>
</appinfo>
<appInfo>
<meta.schema plugin="org.eclipse.cdt.core" id="ToolChain" name="ToolChain"/>
</appInfo>
<documentation>
[Enter description of this extension point.]
</documentation>
@ -12,13 +12,13 @@
<element name="extension">
<annotation>
<appinfo>
<appInfo>
<meta.element />
</appinfo>
</appInfo>
</annotation>
<complexType>
<sequence>
<element ref="provider"/>
<sequence minOccurs="1" maxOccurs="unbounded">
<element ref="toolChain"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
@ -39,60 +39,72 @@
<documentation>
</documentation>
<appinfo>
<appInfo>
<meta.attribute translatable="true"/>
</appinfo>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="provider">
<complexType>
<attribute name="class" type="string" use="required">
<element name="toolChain">
<annotation>
<documentation>
A toolchain that implements the CToolChain interface and identified with the id attribute.
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.arduino.core.internal.launch.ArduinoLaunchConsoleService"/>
</appinfo>
</annotation>
<complexType>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
id for the toolchain.
</documentation>
</annotation>
</attribute>
<attribute name="adaptor" type="string" use="required">
<annotation>
<documentation>
The adaptor class for the toolchain. This is passed to getAdaptor on the CBuildConfiguration object.
</documentation>
<appInfo>
<meta.attribute kind="java" basedOn="org.eclipse.cdt.core.build.CToolChain:"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<appInfo>
<meta.section type="since"/>
</appinfo>
</appInfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>
<annotation>
<appinfo>
<appInfo>
<meta.section type="examples"/>
</appinfo>
</appInfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<appInfo>
<meta.section type="apiinfo"/>
</appinfo>
</appInfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<appInfo>
<meta.section type="implementation"/>
</appinfo>
</appInfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>

View file

@ -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$
@ -154,6 +158,7 @@ public class CCorePlugin extends Plugin {
/**
* Possible configurable option ID.
*
* @see #getDefaultOptions
*/
public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$
@ -185,21 +190,25 @@ public class CCorePlugin extends Plugin {
/**
* Possible configurable option value.
*
* @see #getDefaultOptions()
*/
public static final String INSERT = "insert"; //$NON-NLS-1$
/**
* Possible configurable option value.
*
* @see #getDefaultOptions()
*/
public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
/**
* Possible configurable option value.
*
* @see #getDefaultOptions()
*/
public static final String TAB = "tab"; //$NON-NLS-1$
/**
* 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() {
@ -366,24 +383,31 @@ public class CCorePlugin extends Plugin {
pdomManager = new PDOMManager();
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 <code>setOptions</code>.
* 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
* <code>setOptions</code>.
*
* Helper constants have been defined on CCorePlugin for each of the option ID and
* their possible constant values.
* 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.
*
* <pre>
* RECOGNIZED OPTIONS:
*
@ -395,14 +419,16 @@ public class CCorePlugin extends Plugin {
* - default: <platform default>
* </pre>
*
* @return a mutable map containing the default settings of all known options
* (key type: <code>String</code>; value type: <code>String</code>)
* @return a mutable map containing the default settings of all known
* options (key type: <code>String</code>; value type:
* <code>String</code>)
* @see #setOptions
*/
public static HashMap<String, String> getDefaultOptions() {
HashMap<String, String> defaultOptions = new HashMap<String, String>(10);
// see #initializeDefaultPluginPreferences() for changing default settings
// see #initializeDefaultPluginPreferences() for changing default
// settings
Preferences preferences = getDefault().getPluginPreferences();
HashSet<String> optionNames = CModelManager.OptionNames;
@ -423,13 +449,16 @@ public class CCorePlugin extends Plugin {
}
/**
* Helper method for returning one option value only. Equivalent to <code>(String)CCorePlugin.getOptions().get(optionName)</code>
* Note that it may answer <code>null</code> if this option does not exist.
* Helper method for returning one option value only. Equivalent to
* <code>(String)CCorePlugin.getOptions().get(optionName)</code> Note that
* it may answer <code>null</code> if this option does not exist.
* <p>
* For a complete description of the configurable options, see <code>getDefaultOptions</code>.
* For a complete description of the configurable options, see
* <code>getDefaultOptions</code>.
* </p>
*
* @param optionName the name of an option
* @param optionName
* the name of an option
* @return the String value of a given option
* @see CCorePlugin#getDefaultOptions
*/
@ -446,20 +475,23 @@ public class CCorePlugin extends Plugin {
}
/**
* 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.
* 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.
* <p>
* For a complete description of the configurable options, see <code>getDefaultOptions</code>.
* For a complete description of the configurable options, see
* <code>getDefaultOptions</code>.
* </p>
*
* @return table of current settings of all options
* (key type: <code>String</code>; value type: <code>String</code>)
* @return table of current settings of all options (key type:
* <code>String</code>; value type: <code>String</code>)
* @see CCorePlugin#getDefaultOptions
*/
public static HashMap<String, String> getOptions() {
HashMap<String, String> options = new HashMap<String, String>(10);
// see #initializeDefaultPluginPreferences() for changing default settings
// see #initializeDefaultPluginPreferences() for changing default
// settings
Plugin plugin = getDefault();
if (plugin != null) {
Preferences preferences = plugin.getPluginPreferences();
@ -484,28 +516,34 @@ public class CCorePlugin extends Plugin {
}
/**
* 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.
* 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.
* <p>
* For a complete description of the configurable options, see <code>getDefaultOptions</code>.
* For a complete description of the configurable options, see
* <code>getDefaultOptions</code>.
* </p>
*
* @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
* or <code>null</code> to reset all options to their default values
* @param newOptions
* the new options (key type: <code>String</code>; value type:
* <code>String</code>), or <code>null</code> to reset all
* options to their default values
* @see CCorePlugin#getDefaultOptions
*/
public static void setOptions(HashMap<String, String> newOptions) {
// see #initializeDefaultPluginPreferences() for changing default settings
// 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
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);
}
@ -515,20 +553,25 @@ public class CCorePlugin extends Plugin {
}
/**
* 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
* 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:<br/>
* @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:
* <br/>
* <code>
* URL iconUrl = CUIPlugin.getDefault().getBundle().getEntry("icons/obj16/flask.png");
* </code>
@ -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:<br/>
* @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:
* <br/>
* <code>
* URL iconUrl = CUIPlugin.getDefault().getBundle().getResource("icons/obj16/flask.png");
* </code>
* <br/>
* {@code iconUrl} can be <b>null</b>, in that case the default image is used.
* See {@code org.eclipse.cdt.internal.ui.buildconsole.BuildConsole(IBuildConsoleManager, String, String, URL)}
* </code> <br/>
* {@code iconUrl} can be <b>null</b>, 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 {
@ -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);
@ -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 <b>null</b> if <b>create</b> is <b>false</b> and no .cdtproject file exists on disk.
* @return ICDescriptor or <b>null</b> if <b>create</b> is <b>false</b> and
* no .cdtproject file exists on disk.
* @throws CoreException
* @deprecated
*/
@ -769,13 +827,15 @@ public class CCorePlugin extends Plugin {
}
/**
* @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,19 +845,22 @@ 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)
public IProject createCProject(final IProjectDescription description, final IProject projectHandle,
IProgressMonitor monitor, final String projectID)
throws CoreException, OperationCanceledException {
getWorkspace().run(new IWorkspaceRunnable() {
@ -831,19 +894,13 @@ public class CCorePlugin extends Plugin {
return projectHandle;
}
public IProject createCDTProject(
final IProjectDescription description,
final IProject projectHandle,
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
@ -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,18 +958,17 @@ 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)
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);
@ -919,10 +976,9 @@ public class CCorePlugin extends Plugin {
}
/**
* 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 {
@ -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();
}
@ -1061,8 +1127,9 @@ public class CCorePlugin extends Plugin {
}
/**
* 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;
@ -1105,10 +1172,12 @@ public class CCorePlugin extends Plugin {
}
/**
* Helper function, returning the content type for a filename
* Same as: <pre>
* Helper function, returning the content type for a filename Same as:
*
* <pre>
* getContentType(null, filename)
* </pre>
*
* @param filename
* @return the content type found, or <code>null</code>
*/
@ -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 <code>null</code>
* @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
* <code>null</code>
* @param filename
* a filename to compute the content type for
* @return the content type found or <code>null</code>
*/
public static IContentType getContentType(IProject project, String filename) {
@ -1149,28 +1222,35 @@ public class CCorePlugin extends Plugin {
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,7 +1261,8 @@ 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() {
@ -1200,58 +1281,73 @@ public class CCorePlugin extends Plugin {
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 <code>createProjectDescription(IProject, boolean, false)</code>.
* Equivalent to
* <code>createProjectDescription(IProject, boolean, false)</code>.
*
* @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.
* <br>NOTE: in case the project already contains the project description AND its
* "isCdtProjectCreating" is false the resulting description will be created with the false
* @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. <br>
* 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.
*
* <br>NOTE: changes made to the returned project description will not be applied until
* the {@link #setProjectDescription(IProject, ICProjectDescription)} is called.
* <br>
* 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.
* <br>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. <br>
* 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.
*
* <br>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}.
* <br>
* 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 <code>null</code>, all projects within the workspace are updated
* @param projects
* if <code>null</code>, 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.
@ -1383,9 +1496,12 @@ public class CCorePlugin extends Plugin {
/**
* 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.
@ -1449,8 +1565,9 @@ 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

View file

@ -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;
}
}

View file

@ -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
* <code>Pattern.compile(String regex, int flags)</code>
*
* @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 <code>null</code>. 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 <code>null</code>
*/
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;
}
}

View file

@ -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<String, String> 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<String, String> definedSymbols,
List<String> includePaths, List<String> macroFiles, List<String> includeFiles,
List<String> localIncludePath) throws CoreException {
if (scannerInfo == null) {
loadScannerInfo();
}
scannerInfo.putScannerInfo(resource, new ToolChainScannerInfo(definedSymbols, includePaths,
macroFiles, includeFiles, localIncludePath));
}
protected void putScannerInfo(ILanguage language, Map<String, String> definedSymbols,
List<String> includePaths, List<String> macroFiles, List<String> includeFiles,
List<String> 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;
}
}

View file

@ -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<CBuildConfiguration, GCCToolChain> cache = new HashMap<>();
public static class Factory implements IAdapterFactory {
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> 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<String, String> symbols = new HashMap<>();
List<String> 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();
}
} };
}
}

View file

@ -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;
}

View file

@ -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<ToolChainScannerInfo> perResourceInfo;
private Map<String, ToolChainScannerInfo> perLanguageInfo;
private transient Path savePath;
private transient Map<ToolChainScannerInfo, ToolChainScannerInfo> infoCache;
private transient Map<String, ToolChainScannerInfo> 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();
}
}

View file

@ -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<ScannerInfoData> 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();
}
}

View file

@ -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<String, String> definedSymbols;
private List<String> includePaths;
private List<String> macroFiles;
private List<String> includeFiles;
private List<String> localIncludePath;
private Set<String> resourcePaths;
private transient IScannerInfo scannerInfo;
public ToolChainScannerInfo(Map<String, String> definedSymbols, List<String> includePaths,
List<String> macroFiles, List<String> includeFiles, List<String> 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<String> getResourcePaths() {
return resourcePaths != null ? resourcePaths : Collections.<String> emptySet();
}
public void addResource(IResource resource) {
if (resourcePaths == null) {
resourcePaths = new HashSet<>();
}
resourcePaths.add(resource.getFullPath().toString());
}
}

View file

@ -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

View file

@ -0,0 +1,6 @@
<component name="QtConsoleService">
<implementation class="org.eclipse.cdt.internal.ui.build.CConsoleService"/>
<service>
<provide interface="org.eclipse.cdt.core.build.IConsoleService"/>
</service>
</component>

View file

@ -11,7 +11,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<version>5.11.0-SNAPSHOT</version>
<version>5.12.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.ui</artifactId>
<packaging>eclipse-plugin</packaging>
</project>

View file

@ -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<CPatternMatchListener> 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;
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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 };

View file

@ -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

View file

@ -1,6 +0,0 @@
<component name="QtConsoleService">
<implementation class="org.eclipse.cdt.internal.qt.ui.QtConsoleService"/>
<service>
<provide interface="org.eclipse.cdt.internal.qt.core.build.IConsoleService"/>
</service>
</component>

View file

@ -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

View file

@ -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

View file

@ -4,6 +4,5 @@ bin.includes = META-INF/,\
plugin.xml,\
templates/,\
about.html,\
schema/,\
plugin.properties,\
libs/

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension-point id="consoleService" name="Arduino Launch Console Service" schema="schema/consoleService.exsd"/>
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType

View file

@ -10,12 +10,8 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
@ -59,10 +55,4 @@ public class Activator extends Plugin {
return ref != null ? context.getService(ref) : null;
}
public static ArduinoConsoleService getConsoleService() throws CoreException {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getId(), "consoleService"); //$NON-NLS-1$
IExtension extension = point.getExtensions()[0]; // should only be one
return (ArduinoConsoleService) extension.getConfigurationElements()[0].createExecutableExtension("class"); //$NON-NLS-1$
}
}

View file

@ -195,7 +195,7 @@ public class ArduinoManager {
try {
for (IBuildConfiguration config : project.getBuildConfigs()) {
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
arduinoConfig.clearScannerInfoCache();
arduinoConfig.clearScannerInfo();
}
} catch (CoreException e) {
mstatus.add(e.getStatus());

View file

@ -1,11 +1,7 @@
package org.eclipse.cdt.arduino.core.internal.build;
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
@ -15,8 +11,6 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
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.ArduinoPreferences;
@ -28,26 +22,24 @@ import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoTool;
import org.eclipse.cdt.arduino.core.internal.board.ToolDependency;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
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.build.GCCToolChain;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IOutputEntry;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IProgressMonitor;
@ -57,25 +49,29 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.service.prefs.BackingStoreException;
public class ArduinoBuildConfiguration {
public class ArduinoBuildConfiguration extends CBuildConfiguration {
private static final String PACKAGE_NAME = "packageName"; //$NON-NLS-1$
private static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$
private static final String BOARD_NAME = "boardName"; //$NON-NLS-1$
private final IBuildConfiguration config;
private ArduinoBoard board;
private Properties properties;
// Cache for scanner info
private IScannerInfo cScannerInfo;
private IScannerInfo cppScannerInfo;
private final static boolean isWindows = Platform.getOS().equals(Platform.OS_WIN32);
private ArduinoBuildConfiguration(IBuildConfiguration config) {
this.config = config;
super(config);
try {
if (getToolChain() == null) {
// For now, assume GCC is the toolchain,
// not sure it's ever not.
setToolChain(GCCToolChain.ID);
}
} catch (CoreException e) {
Activator.log(e);
}
}
private static Map<IBuildConfiguration, ArduinoBuildConfiguration> 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<Path> 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;
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:
if (cppScannerInfo == null) {
cppScannerInfo = calculateScannerInfo("recipe.cpp.o.pattern", resource); //$NON-NLS-1$
}
return cppScannerInfo;
recipe = "recipe.cpp.o.pattern"; //$NON-NLS-1$
break;
default:
if (cScannerInfo == null) {
cScannerInfo = calculateScannerInfo("recipe.c.o.pattern", resource); //$NON-NLS-1$
}
return cScannerInfo;
}
recipe = "recipe.c.o.pattern"; //$NON-NLS-1$
}
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<ArduinoLibrary> libs = ArduinoManager.instance.getLibraries(config.getProject());
Collection<ArduinoLibrary> 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;
getToolChain().scanBuildOutput(getBuildFolder(), resolveProperty(recipe, properties), true);
info = super.getScannerInfo(resource);
}
return info;
}
public static String pathString(Path path) {
String str = path.toString();
if (isWindows) {
command = splitCommand(resolveProperty(recipe, properties));
} else {
command = new String[] { "sh", "-c", resolveProperty(recipe, properties) }; //$NON-NLS-1$ //$NON-NLS-2$
str = str.replaceAll("\\\\", "/"); //$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<String, String> symbols = new HashMap<>();
List<String> 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));
}
}
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();
}
} };
return str;
}
}

View file

@ -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;

View file

@ -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
* <code>Pattern.compile(String regex, int flags)</code>
*
* @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 <code>null</code>. 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 <code>null</code>
*/
public String getLineQualifier() {
return lineQualifier;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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(),

View file

@ -30,12 +30,6 @@
project="true">
</wizard>
</extension>
<extension
point="org.eclipse.cdt.arduino.core.consoleService">
<provider
class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoConsole">
</provider>
</extension>
<extension
point="org.eclipse.ui.propertyPages">
<page

View file

@ -1,162 +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.ui.internal.launch;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;
public class ArduinoConsole implements ArduinoConsoleService, IResourceChangeListener {
private static MessageConsole console;
private static MessageConsoleStream out;
private static MessageConsoleStream err;
private IFolder buildDirectory;
List<ArduinoPatternMatchListener> 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);
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}