diff --git a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF index b9888dee03e..83727b35fa5 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true -Bundle-Version: 9.0.0.qualifier +Bundle-Version: 9.1.0.qualifier Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java index 56ac320955e..0576eb01a0d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java @@ -418,6 +418,20 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett */ protected abstract AbstractOptionParser[] getOptionParsers(); + /** + * @return array of option parsers defining how to parse a string to + * {@link ICLanguageSettingEntry}. + * See {@link AbstractOptionParser} and its specific extenders. + * + * @param optionToParse the option string to be parsed. + * This can be used as a hint in order to return a subset of parsers, for better performance. + * + * @since 9.1 + */ + protected AbstractOptionParser[] getOptionParsers(String optionToParse) { + return getOptionParsers(); + } + /** * @return {@code true} when the provider tries to resolve relative or remote paths * to the existing paths in the workspace or local file-system using certain heuristics. @@ -499,8 +513,8 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett List options = parseOptions(line); if (options != null) { - AbstractOptionParser[] optionParsers = getOptionParsers(); for (String option : options) { + AbstractOptionParser[] optionParsers = getOptionParsers(option); for (AbstractOptionParser optionParser : optionParsers) { try { if (optionParser.parseOption(option)) { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/GCCBuildCommandParser.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/GCCBuildCommandParser.java index 9aeff8a0cc2..64e6507df4b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/GCCBuildCommandParser.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/GCCBuildCommandParser.java @@ -13,6 +13,11 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.language.settings.providers; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import org.eclipse.cdt.core.errorparsers.RegexErrorPattern; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider; import org.eclipse.cdt.core.settings.model.ICSettingEntry; @@ -32,34 +37,124 @@ import org.eclipse.cdt.core.settings.model.ICSettingEntry; */ public class GCCBuildCommandParser extends AbstractBuildCommandParser implements ILanguageSettingsEditableProvider { @SuppressWarnings("nls") - static final AbstractOptionParser[] optionParsers = { + static final AbstractOptionParser[] includeOptionParsers = { new IncludePathOptionParser("-I\\s*(?[\"'])(.*)\\k", "$2"), - new IncludePathOptionParser("-I\\s*([^\\s\"']*)", "$1"), + new IncludePathOptionParser("-I\\s*([^\\s\"']*)", "$1"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] systemIncludeOptionParsers = { new IncludePathOptionParser("-isystem\\s*(?[\"'])(.*)\\k", "$2"), - new IncludePathOptionParser("-isystem\\s*([^\\s\"']*)", "$1"), + new IncludePathOptionParser("-isystem\\s*([^\\s\"']*)", "$1"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] frameworkOptionParsers = { new IncludePathOptionParser("-(F|(iframework))\\s*(?[\"'])(.*)\\k", "$4", ICSettingEntry.FRAMEWORKS_MAC), - new IncludePathOptionParser("-(F|(iframework))\\s*([^\\s\"']*)", "$3", ICSettingEntry.FRAMEWORKS_MAC), + new IncludePathOptionParser("-(F|(iframework))\\s*([^\\s\"']*)", "$3", ICSettingEntry.FRAMEWORKS_MAC), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] forceIncludeOptionParsers = { new IncludeFileOptionParser("-include\\s*(?[\"'])(.*)\\k", "$2"), - new IncludeFileOptionParser("-include\\s*([^\\s\"']*)", "$1"), + new IncludeFileOptionParser("-include\\s*([^\\s\"']*)", "$1"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] defineOptionParsers = { new MacroOptionParser("-D\\s*(?[\"'])([^=]*)(=(.*))?\\k", "$2", "$4"), new MacroOptionParser("-D\\s*([^\\s=\"']*)=(\"\\\\(\")(.*?)\\\\\"\")", "$1", "$3$4$3"), new MacroOptionParser("-D\\s*([^\\s=\"']*)=(?\\\\([\"']))(.*?)\\k", "$1", "$3$4$3"), new MacroOptionParser("-D\\s*([^\\s=\"']*)=(?[\"'])(.*?)\\k", "$1", "$3"), new MacroOptionParser("-D\\s*([^\\s=\"']*)=([^\\s\"']*)?", "$1", "$2"), - new MacroOptionParser("-D\\s*([^\\s=\"']*)", "$1", "1"), - new MacroOptionParser("-U\\s*([^\\s=\"']*)", "$1", ICSettingEntry.UNDEFINED), + new MacroOptionParser("-D\\s*([^\\s=\"']*)", "$1", "1"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] undefineOptionParsers = { + new MacroOptionParser("-U\\s*([^\\s=\"']*)", "$1", ICSettingEntry.UNDEFINED), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] macrosOptionParsers = { new MacroFileOptionParser("-imacros\\s*(?[\"'])(.*)\\k", "$2"), - new MacroFileOptionParser("-imacros\\s*([^\\s\"']*)", "$1"), + new MacroFileOptionParser("-imacros\\s*([^\\s\"']*)", "$1"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] libraryOptionParsers = { new LibraryPathOptionParser("-L\\s*(?[\"'])(.*)\\k", "$2"), new LibraryPathOptionParser("-L\\s*([^\\s\"']*)", "$1"), new LibraryFileOptionParser("-l\\s*([^\\s\"']*)", "lib$1.a"), }; + static final AbstractOptionParser[] emptyParsers = new AbstractOptionParser[0]; + + static final AbstractOptionParser[] optionParsers; + static { + List parsers = new ArrayList<>(Arrays.asList(includeOptionParsers)); + Collections.addAll(parsers, systemIncludeOptionParsers); + Collections.addAll(parsers, frameworkOptionParsers); + Collections.addAll(parsers, forceIncludeOptionParsers); + Collections.addAll(parsers, defineOptionParsers); + Collections.addAll(parsers, undefineOptionParsers); + Collections.addAll(parsers, macrosOptionParsers); + Collections.addAll(parsers, libraryOptionParsers); + + optionParsers = parsers.toArray(new AbstractOptionParser[0]); + } + @Override protected AbstractOptionParser[] getOptionParsers() { return optionParsers; } + @SuppressWarnings("nls") + @Override + protected AbstractOptionParser[] getOptionParsers(String optionToParse) { + if (optionToParse.length() <= 1) { + return emptyParsers; + } + + // Skip -, we know it's there with the OPTIONS_PATTERN + String optionName = optionToParse.substring(1); + + if (optionName.startsWith("I")) { + return includeOptionParsers; + } + + if (optionName.startsWith("D")) { + return defineOptionParsers; + } + + if (optionName.startsWith("l") || optionName.startsWith("L")) { + return libraryOptionParsers; + } + + if (optionName.startsWith("i")) { + if (optionName.startsWith("include")) { + return forceIncludeOptionParsers; + } + + if (optionName.startsWith("isystem")) { + return systemIncludeOptionParsers; + } + + if (optionName.startsWith("imacros")) { + return macrosOptionParsers; + } + + if (optionName.startsWith("iframework")) { + return frameworkOptionParsers; + } + + return emptyParsers; + } + + if (optionName.startsWith("F")) { + return frameworkOptionParsers; + } + + if (optionName.startsWith("U")) { + return undefineOptionParsers; + } + + return emptyParsers; + } + @Override public GCCBuildCommandParser cloneShallow() throws CloneNotSupportedException { return (GCCBuildCommandParser) super.cloneShallow(); diff --git a/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCBuildCommandParser.java b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCBuildCommandParser.java index 8089a8e6271..d45314ee0e6 100644 --- a/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCBuildCommandParser.java +++ b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCBuildCommandParser.java @@ -11,6 +11,8 @@ package org.eclipse.cdt.msw.build.core; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -93,12 +95,22 @@ public class MSVCBuildCommandParser extends AbstractBuildCommandParser implement } @SuppressWarnings("nls") - static final AbstractOptionParser[] optionParsers = { new MSVCIncludePathOptionParser("(-|/)I\\s*\"(.*)\"", "$2"), - new MSVCIncludePathOptionParser("(-|/)I\\s*([^\\s\"]*)", "$2"), + static final AbstractOptionParser[] includeOptionParsers = { + new MSVCIncludePathOptionParser("(-|/)I\\s*\"(.*)\"", "$2"), + new MSVCIncludePathOptionParser("(-|/)I\\s*([^\\s\"]*)", "$2"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] forceIncludeOptionParsers = { new MSVCForceIncludePathOptionParser("(-|/)FI\\s*\"(.*)\"", "$2"), - new MSVCForceIncludePathOptionParser("(-|/)FI\\s*([^\\s\"]*)", "$2"), + new MSVCForceIncludePathOptionParser("(-|/)FI\\s*([^\\s\"]*)", "$2"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] msvcIncludeOptionParsers = { new ClangCLMSVCSystemPathOptionParser("(-|/)imsvc\\s*\"(.*)\"", "$2"), - new ClangCLMSVCSystemPathOptionParser("(-|/)imsvc\\s*([^\\s\"]*)", "$2"), + new ClangCLMSVCSystemPathOptionParser("(-|/)imsvc\\s*([^\\s\"]*)", "$2"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] defineOptionParsers = { // /D "FOO=bar" new MSVCMacroOptionParser("(-|/)D\\s*\"([^=]+)=(.*)\"", "$2", "$3"), // /D FOO="bar" @@ -108,12 +120,28 @@ public class MSVCBuildCommandParser extends AbstractBuildCommandParser implement // /D FOO new MSVCMacroOptionParser("(-|/)D\\s*([^\\s=\"]+)", "$2", "1"), // /D"FOO" - new MSVCMacroOptionParser("(-|/)D\\s*\"([^\\s=\"]+)\"", "$2", "1"), + new MSVCMacroOptionParser("(-|/)D\\s*\"([^\\s=\"]+)\"", "$2", "1"), }; + + @SuppressWarnings("nls") + static final AbstractOptionParser[] undefineOptionParsers = { // /U FOO new MacroOptionParser("(-|/)U\\s*([^\\s=\"]+)", "$2", ICSettingEntry.UNDEFINED), // /U "FOO" new MacroOptionParser("(-|/)U\\s*\"(.*?)\"", "$2", ICSettingEntry.UNDEFINED) }; + static final AbstractOptionParser[] emptyParsers = new AbstractOptionParser[0]; + + static final AbstractOptionParser[] optionParsers; + static { + List parsers = new ArrayList<>(Arrays.asList(includeOptionParsers)); + Collections.addAll(parsers, defineOptionParsers); + Collections.addAll(parsers, msvcIncludeOptionParsers); + Collections.addAll(parsers, forceIncludeOptionParsers); + Collections.addAll(parsers, undefineOptionParsers); + + optionParsers = parsers.toArray(new AbstractOptionParser[0]); + } + /** * "foo" or "C:\foo\\" * @@ -147,6 +175,39 @@ public class MSVCBuildCommandParser extends AbstractBuildCommandParser implement return optionParsers; } + @SuppressWarnings("nls") + @Override + protected AbstractOptionParser[] getOptionParsers(String optionToParse) { + if (optionToParse.length() <= 1) { + return emptyParsers; + } + + // Skip - or /, we know it's there with the OPTIONS_PATTERN + String optionName = optionToParse.substring(1); + + if (optionName.startsWith("I")) { + return includeOptionParsers; + } + + if (optionName.startsWith("D")) { + return defineOptionParsers; + } + + if (optionName.startsWith("imsvc")) { + return msvcIncludeOptionParsers; + } + + if (optionName.startsWith("FI")) { + return forceIncludeOptionParsers; + } + + if (optionName.startsWith("U")) { + return undefineOptionParsers; + } + + return emptyParsers; + } + @Override public MSVCBuildCommandParser cloneShallow() throws CloneNotSupportedException { return (MSVCBuildCommandParser) super.cloneShallow();