diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java index 16a20afc35b..56d0d16a84f 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java @@ -10,6 +10,7 @@ **********************************************************************/ package org.eclipse.cdt.make.core.scannerconfig; +import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; @@ -31,5 +32,5 @@ public interface IExternalScannerInfoProvider { public boolean invokeProvider(IProgressMonitor monitor, IProject currentProject, IScannerConfigBuilderInfo buildInfo, - String[] targetSpecificOptions); + List targetSpecificOptions); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java index 035ce3445e9..69529c9485f 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java @@ -10,11 +10,11 @@ **********************************************************************/ package org.eclipse.cdt.make.core.scannerconfig; +import java.util.Map; import org.eclipse.cdt.core.resources.ACBuilder; import org.eclipse.cdt.make.core.MakeCorePlugin; -import org.eclipse.cdt.make.internal.core.scannerconfig.*; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector; import org.eclipse.core.resources.IProject; -import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.SubProgressMonitor; diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java index 7aa290c7842..e6d55607f0e 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java @@ -14,10 +14,13 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Enumeration; +import java.util.List; import java.util.Properties; import java.util.StringTokenizer; +import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.CommandLauncher; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.model.ICModelMarker; @@ -26,6 +29,7 @@ import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; import org.eclipse.cdt.make.internal.core.StreamMonitor; +import org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerConfigUtil; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -51,10 +55,13 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP private String fCompileArguments; /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider#invokeProvider(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.resources.IProject, org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo, java.lang.String[]) + * @see org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider#invokeProvider(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.resources.IProject, org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo, java.util.List) */ - public boolean invokeProvider(IProgressMonitor monitor, IProject currentProject, IScannerConfigBuilderInfo buildInfo, String[] targetSpecificOptions) { - if (!initialize(currentProject, buildInfo)) { + public boolean invokeProvider(IProgressMonitor monitor, IProject currentProject, IScannerConfigBuilderInfo buildInfo, List targetSpecificOptions) { + if (targetSpecificOptions == null) { + targetSpecificOptions = new ArrayList(); + } + if (!initialize(currentProject, buildInfo, targetSpecificOptions)) { return false; } if (monitor == null) { @@ -125,12 +132,31 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP /** * @param currentProject * @param buildInfo + * @param targetSpecificOptions * @return boolean */ - private boolean initialize(IProject currentProject, IScannerConfigBuilderInfo buildInfo) { + private boolean initialize(IProject currentProject, IScannerConfigBuilderInfo buildInfo, List targetSpecificOptions) { boolean rc = false; + if (buildInfo.isDefaultESIProviderCmd()) { fWorkingDirectory = MakeCorePlugin.getWorkingDirectory(); + String targetFile = "dummy"; //$NON-NLS-1$ + try { + if (currentProject.hasNature(CCProjectNature.CC_NATURE_ID)) { + targetFile = GCCScannerConfigUtil.CPP_SPECS_FILE; + } + else if (currentProject.hasNature(CProjectNature.C_NATURE_ID)) { + targetFile = GCCScannerConfigUtil.C_SPECS_FILE; + } + } catch (CoreException e) { + //TODO VMIR better error handling + MakeCorePlugin.log(e.getStatus()); + } + IPath path2File = fWorkingDirectory.append(targetFile); + if (!path2File.toFile().exists()) { + GCCScannerConfigUtil.createSpecs(); + } + targetSpecificOptions.add(targetFile); } else { fWorkingDirectory = currentProject.getLocation(); @@ -144,10 +170,10 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP } /** - * @param tso + * @param tso - target specific options * @return */ - private String[] prepareArguments(String[] tso) { + private String[] prepareArguments(List tso) { String[] rv = null; // commandArguments may have multiple arguments; tokenizing int nTokens = 0; @@ -155,17 +181,17 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP StringTokenizer tokenizer = new StringTokenizer(fCompileArguments, " ");//$NON-NLS-1$ nTokens = tokenizer.countTokens(); if (nTokens > 0) { - rv = new String[nTokens + tso.length]; + rv = new String[nTokens + tso.size()]; for (int i = 0; tokenizer.hasMoreTokens(); ++i) { rv[i] = tokenizer.nextToken(); } } } if (rv == null) { - rv = new String[tso.length]; + rv = new String[tso.size()]; } - for (int i = 0; i < tso.length; ++i) { - rv[nTokens + i] = tso[i]; + for (int i = 0; i < tso.size(); ++i) { + rv[nTokens + i] = (String) tso.get(i); } return rv; } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java index 69eaae329b4..9246f7ca291 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java @@ -96,9 +96,9 @@ public class ScannerInfoCollector { project.hasNature(CCProjectNature.CC_NATURE_ID))) { String projectName = project.getName(); - contribute(projectName, discoveredIncludes, includes); - contribute(projectName, discoveredSymbols, symbols); - contribute(projectName, discoveredTSO, targetSpecificOptions); + contribute(projectName, discoveredIncludes, includes, true); + contribute(projectName, discoveredSymbols, symbols, false); + contribute(projectName, discoveredTSO, targetSpecificOptions, false); } } catch (CoreException e) { @@ -110,9 +110,10 @@ public class ScannerInfoCollector { * @param project * @param discovered symbols | includes | targetSpecificOptions * @param delta symbols | includes | targetSpecificOptions + * @param ordered - to preserve order or append at the end * @return true if there is a change in discovered symbols | includes | targetSpecificOptions */ - private boolean contribute(String projectName, Map discovered, List delta) { + private boolean contribute(String projectName, Map discovered, List delta, boolean ordered) { if (delta == null || delta.isEmpty()) return false; List projectDiscovered = (List) discovered.get(projectName); @@ -121,14 +122,29 @@ public class ScannerInfoCollector { discovered.put(projectName, projectDiscovered); return true; } - boolean added = false; - for (Iterator i = delta.iterator(); i.hasNext(); ) { + return addItemsWithOrder(delta, projectDiscovered, ordered); + } + + /** + * Adds new items to the already accumulated ones preserving order + * + * @param includes - items to be added + * @param sumIncludes - previously accumulated items + * @param ordered - to preserve order or append at the end + * @return boolean - true if added + */ + private boolean addItemsWithOrder(List includes, List sumIncludes, boolean ordered) { + boolean addedIncludes = false; + int prev = sumIncludes.size() - 1; // index of previously added/found contribution in already discovered list + for (Iterator i = includes.iterator(); i.hasNext(); ) { String item = (String) i.next(); - if (!projectDiscovered.contains(item)) { - added |= projectDiscovered.add(item); + if (!sumIncludes.contains(item)) { + sumIncludes.add(prev + 1, item); + addedIncludes = true; } + prev = ordered ? sumIncludes.indexOf(item) : sumIncludes.size() - 1; } - return added; + return addedIncludes; } /** @@ -200,12 +216,7 @@ public class ScannerInfoCollector { addedIncludes = true; } else { - for (Iterator i = includes.iterator(); i.hasNext(); ) { - String include = (String) i.next(); - if (!sumIncludes.contains(include)) { - addedIncludes |= sumIncludes.add(include); - } - } + addedIncludes = addItemsWithOrder(includes, sumIncludes, true); } // try to translate cygpaths to absolute paths List finalSumIncludes = translateIncludePaths(sumIncludes); @@ -214,17 +225,30 @@ public class ScannerInfoCollector { LinkedHashMap persistedIncludes = discScanInfo.getDiscoveredIncludePaths(); // Step 3. Merge scanner config from steps 1 and 2 - for (Iterator i = finalSumIncludes.iterator(); i.hasNext(); ) { - String include = (String) i.next(); - if (!persistedIncludes.containsKey(include)) { - persistedIncludes.put(include, - ((new Path(include)).toFile().exists()) ? Boolean.FALSE : Boolean.TRUE); - addedIncludes |= true; + // order is important, use list to preserve it + ArrayList persistedKeyList = new ArrayList(persistedIncludes.keySet()); + addedIncludes = addItemsWithOrder(finalSumIncludes, persistedKeyList, true); + + LinkedHashMap newPersistedIncludes; + if (addedIncludes) { + newPersistedIncludes = new LinkedHashMap(persistedKeyList.size()); + for (Iterator i = persistedKeyList.iterator(); i.hasNext(); ) { + String include = (String) i.next(); + if (persistedIncludes.containsKey(include)) { + newPersistedIncludes.put(include, persistedIncludes.get(include)); + } + else { + newPersistedIncludes.put(include, + ((new Path(include)).toFile().exists()) ? Boolean.FALSE : Boolean.TRUE); + } } } + else { + newPersistedIncludes = persistedIncludes; + } // Step 4. Set resulting scanner config - discScanInfo.setDiscoveredIncludePaths(persistedIncludes); + discScanInfo.setDiscoveredIncludePaths(newPersistedIncludes); // Step 5. Invalidate discovered include paths and symbol definitions discoveredIncludes.put(projectName, null); @@ -331,14 +355,7 @@ public class ScannerInfoCollector { if (esiProvider != null) { ISafeRunnable runnable = new ISafeRunnable() { public void run() { - String[] tsoArray; - if (tso == null) { - tsoArray = new String[0]; - } - else { - tsoArray = (String[])tso.toArray(new String[tso.size()]); - } - esiProvider.invokeProvider(monitor, project, buildInfo, tsoArray); + esiProvider.invokeProvider(monitor, project, buildInfo, tso); } public void handleException(Throwable exception) { @@ -391,4 +408,35 @@ public class ScannerInfoCollector { } // TODO VMIR define error message } + + /** + * Delete a specific include path + * + * @param project + * @param path + */ + public void deletePath(IProject project, String path) { + if (project != null) { + List sumIncludes = (List) sumDiscoveredIncludes.get(project.getName()); + if (sumIncludes != null) { + sumIncludes.remove(path); + } + } + } + + /** + * Delete a specific symbol definition + * + * @param project + * @param path + */ + public void deleteSymbol(IProject project, String symbol) { + if (project != null) { + Map sumSymbols = (Map) sumDiscoveredSymbols.get(project.getName()); + if (sumSymbols != null) { + // remove it from the Map of SymbolEntries + ScannerConfigUtil.removeSymbolEntryValue(symbol, sumSymbols); + } + } + } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java index 290aa167ac6..d605812c457 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java @@ -12,13 +12,8 @@ package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; import java.util.StringTokenizer; -import org.eclipse.cdt.core.CCProjectNature; -import org.eclipse.cdt.core.CProjectNature; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; import org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility; import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector; @@ -43,29 +38,6 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { public void startup(IProject project, IScannerInfoConsoleParserUtility util) { fProject = project; fUtil = util; - - IPath workingDirectory = MakeCorePlugin.getWorkingDirectory(); - String targetFile = "dummy"; //$NON-NLS-1$ - try { - if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { - targetFile = GCCScannerConfigUtil.CPP_SPECS_FILE; - } - else if (project.hasNature(CProjectNature.C_NATURE_ID)) { - targetFile = GCCScannerConfigUtil.C_SPECS_FILE; - } - } catch (CoreException e) { - //TODO VMIR better error handling - MakeCorePlugin.log(e.getStatus()); - } - IPath path2File = workingDirectory.append(targetFile); - if (!path2File.toFile().exists()) { - GCCScannerConfigUtil.createSpecs(); - } - List targetSpecificOptions = new ArrayList(); - targetSpecificOptions.add(targetFile); - - ScannerInfoCollector.getInstance(). - contributeToScannerConfig(project, null, null, targetSpecificOptions); } /* (non-Javadoc) @@ -104,13 +76,24 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { rc = true; String fileName = null; + String cashedToken = null; while (scanner.hasMoreTokens()) { - token = scanner.nextToken(); + if (cashedToken == null) { + token = scanner.nextToken(); + } + else { + token = cashedToken; + cashedToken = null; + } if (token.startsWith("-D")) {//$NON-NLS-1$ String symbol = token.substring(2); if (symbol.length() == 0) { if (scanner.hasMoreTokens()) { symbol = scanner.nextToken(); + if (symbol.startsWith("-")) { // $NON-NLS-1$ + cashedToken = symbol; + continue; + } } else { continue; @@ -124,6 +107,10 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { if (iPath.length() == 0) { if (scanner.hasMoreTokens()) { iPath = scanner.nextToken(); + if (iPath.startsWith("-")) { // $NON-NLS-1$ + cashedToken = iPath; + continue; + } } else { continue; diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java index 8e3bff7a7ff..4a29269f9ed 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.make.internal.core.scannerconfig.util; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -169,4 +170,82 @@ public final class ScannerConfigUtil { } return rc; } + + /** + * Returns a symbol key (i.e. for DEF=1 returns DEF) + * + * @param symbol - in + * @param key - out + */ + public static String getSymbolKey(String symbol) { + int index = symbol.indexOf('='); + if (index != -1) { + return symbol.substring(0, index); + } + return symbol; + } + + /** + * Returns a symbol value (i.e. for DEF=1 returns 1) + * + * @param symbol - in + * @param key - out (may be null) + */ + public static String getSymbolValue(String symbol) { + int index = symbol.indexOf('='); + if (index != -1) { + return symbol.substring(index+1); + } + return null; + } + + /** + * Removes a symbol value from the symbol entry. If it was an only value than + * it symbol entry will be removed alltogether. + * + * @param symbol + * @param symbolEntryMap map of [symbol's key, symbolEntry] + */ + public static void removeSymbolEntryValue(String symbol, Map symbolEntryMap) { + String key = getSymbolKey(symbol); + String value = getSymbolValue(symbol); + // find it in the discoveredSymbols Map of SymbolEntries + SymbolEntry se = (SymbolEntry) symbolEntryMap.get(key); + if (se != null) { + se.remove(value); + if (se.numberOfValues() == 0) { + symbolEntryMap.remove(key); + } + } + } + + /** + * Swaps two include paths in the include paths Map. + * Used by Up/Down discovered paths + * + * @param sumPaths + * @param index1 + * @param index2 + * @return new map of include paths + */ + public static LinkedHashMap swapIncludePaths(LinkedHashMap sumPaths, int index1, int index2) { + int size = sumPaths.size(); + if (index1 == index2 || + !(index1 >= 0 && index1 < size && + index2 >= 0 && index2 < size)) { + return sumPaths; + } + ArrayList pathKeyList = new ArrayList(sumPaths.keySet()); + String temp1 = (String) pathKeyList.get(index1); + String temp2 = (String) pathKeyList.get(index2); + pathKeyList.set(index1, temp2); + pathKeyList.set(index2, temp1); + + LinkedHashMap newSumPaths = new LinkedHashMap(sumPaths.size()); + for (Iterator i = pathKeyList.iterator(); i.hasNext(); ) { + String key = (String) i.next(); + newSumPaths.put(key, sumPaths.get(key)); + } + return newSumPaths; + } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java index cdd75c93b01..0900f6a576d 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java @@ -372,33 +372,43 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse StringBuffer buf = new StringBuffer(path); int len = buf.length(); StringBuffer newBuf = new StringBuffer(buf.length()); - int i = 0; - int sp = 0; + int scp = 0; // starting copy point + int ssp = 0; // starting search point int sdot; - while (sp < len && (sdot = buf.indexOf(".", sp)) != -1) { //$NON-NLS-1$ - int ddot = buf.indexOf("..", sp);//$NON-NLS-1$ + boolean validPrefix; + while (ssp < len && (sdot = buf.indexOf(".", ssp)) != -1) { //$NON-NLS-1$ + validPrefix = false; + int ddot = buf.indexOf("..", ssp);//$NON-NLS-1$ if (sdot < ddot || ddot == -1) { - newBuf.append(buf.substring(i, sdot)); - i = sdot + 1; - if (i < len) { - char nextChar = buf.charAt(i); - if (nextChar == '/') { - ++i; + newBuf.append(buf.substring(scp, sdot)); + ssp = sdot + 1; + if (ssp < len) { + if (sdot == 0 || buf.charAt(sdot - 1) == '/' || buf.charAt(sdot - 1) == '\\') { + validPrefix = true; } - else if (nextChar == '\\') { - ++i; - if (i < len - 1 && buf.charAt(i) == '\\') { - ++i; + char nextChar = buf.charAt(ssp); + if (validPrefix && nextChar == '/') { + ++ssp; + scp = ssp; + } + else if (validPrefix && nextChar == '\\') { + ++ssp; + if (ssp < len - 1 && buf.charAt(ssp) == '\\') { + ++ssp; } + scp = ssp; + } + else { + // no path delimiter, must be '.' inside the path + scp = ssp - 1; } } - sp = i; } else if (sdot == ddot) { - sp = sdot + 2; + ssp = sdot + 2; } } - newBuf.append(buf.substring(i, len)); + newBuf.append(buf.substring(scp, len)); IPath orgPath = new Path(newBuf.toString()); return orgPath.toString(); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java index fe079d9a653..e48b76b9438 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java @@ -139,4 +139,8 @@ public class SymbolEntry { } return rv; } + + public int numberOfValues() { + return values.size(); + } } diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties index 8fccaf16544..d9a51f22a51 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties @@ -206,6 +206,8 @@ ManageIncludePathsDialog.discoveredGroup.title=Discovered include paths ManageScannerConfigDialogCommon.discoveredGroup.selected.label=Selected: ManageScannerConfigDialogCommon.discoveredGroup.removed.label=Removed: +ManageScannerConfigDialogCommon.discoveredGroup.buttons.up.label=Up +ManageScannerConfigDialogCommon.discoveredGroup.buttons.down.label=Down ManageScannerConfigDialogCommon.discoveredGroup.buttons.remove.label=Remove ManageScannerConfigDialogCommon.discoveredGroup.buttons.restore.label=Restore ManageScannerConfigDialogCommon.discoveredGroup.buttons.delete.label=Delete diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java index 6adbb651c49..9d56bbdf6e8 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.make.core.MakeScannerInfo; import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfo; import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfoProvider; import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil; import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry; import org.eclipse.cdt.make.internal.ui.MakeUIPlugin; import org.eclipse.cdt.make.internal.ui.MessageLine; @@ -94,6 +95,7 @@ public class ManageDefinedSymbolsDialog extends Dialog { boolean alreadyCreated; // Set when dialog is created for the first time (vs. reopened) private ArrayList returnSymbols; private ArrayList userSymbols; + private ArrayList deletedDiscoveredSymbols; private LinkedHashMap discoveredSymbols; private LinkedHashMap workingDiscoveredSymbols; // working copy of discoveredSymbols, until either OK or CANCEL is pressed private boolean fDirty; @@ -497,8 +499,8 @@ public class ManageDefinedSymbolsDialog extends Dialog { int id = discList.getSelectionIndex(); if (id != -1) { String symbol = discList.getItem(id); - String key = getSymbolKey(symbol); - String value = getSymbolValue(symbol); + String key = ScannerConfigUtil.getSymbolKey(symbol); + String value = ScannerConfigUtil.getSymbolValue(symbol); // find it in the discoveredSymbols Map of SymbolEntries SymbolEntry se = (SymbolEntry) workingDiscoveredSymbols.get(key); if (se != null) { @@ -535,17 +537,14 @@ public class ManageDefinedSymbolsDialog extends Dialog { int id = discList.getSelectionIndex(); if (id >= 0) { String symbol = discList.getItem(id); + // add it to the deleted list + if (deletedDiscoveredSymbols == null) { + deletedDiscoveredSymbols = new ArrayList(); + } + deletedDiscoveredSymbols.add(symbol); + // remove it from the Map of SymbolEntries - String key = getSymbolKey(symbol); - String value = getSymbolValue(symbol); - // find it in the discoveredSymbols Map of SymbolEntries - SymbolEntry se = (SymbolEntry) workingDiscoveredSymbols.get(key); - if (se != null) { - se.remove(value); - } - else { - //TODO VMIR generate an error - } + ScannerConfigUtil.removeSymbolEntryValue(symbol, workingDiscoveredSymbols); int items = discList.getItemCount(); discList.setItems(getDiscDefinedSymbols(workingDiscoveredSymbols, type)); @@ -560,34 +559,6 @@ public class ManageDefinedSymbolsDialog extends Dialog { } } - /** - * Returns a symbol key (i.e. for DEF=1 returns DEF) - * - * @param symbol - in - * @param key - out - */ - private String getSymbolKey(String symbol) { - int index = symbol.indexOf('='); - if (index != -1) { - return symbol.substring(0, index); - } - return symbol; - } - - /** - * Returns a symbol value (i.e. for DEF=1 returns 1) - * - * @param symbol - in - * @param key - out (may be null) - */ - private String getSymbolValue(String symbol) { - int index = symbol.indexOf('='); - if (index != -1) { - return symbol.substring(index+1); - } - return null; - } - /** * */ @@ -671,6 +642,7 @@ public class ManageDefinedSymbolsDialog extends Dialog { fDirty = fWorkingDirty; } else if (IDialogConstants.CANCEL_ID == buttonId) { + deletedDiscoveredSymbols = null; workingDiscoveredSymbols = null; setDirty(false); } @@ -689,6 +661,13 @@ public class ManageDefinedSymbolsDialog extends Dialog { if (fDirty || (fProject == null && fContainer.getProject() != null)) {// New Standard Make project wizard info.setUserDefinedSymbols(userSymbols); info.setDiscoveredSymbolDefinitions(discoveredSymbols); + // remove deleted symbols from discovered SC + if (deletedDiscoveredSymbols != null) { + for (Iterator i = deletedDiscoveredSymbols.iterator(); i.hasNext(); ) { + ScannerInfoCollector.getInstance().deleteSymbol(fProject, (String) i.next()); + } + deletedDiscoveredSymbols = null; + } } setDirty(false); fDirty = false; @@ -701,11 +680,14 @@ public class ManageDefinedSymbolsDialog extends Dialog { if (fProject != null) { userSymbols = new ArrayList(Arrays.asList(BuildPathInfoBlock.getSymbols( MakeCorePlugin.getDefault().getPluginPreferences()))); + // remove discovered symbols + ScannerInfoCollector.getInstance().deleteAllSymbols(fProject); } else { userSymbols = new ArrayList(); } discoveredSymbols = new LinkedHashMap(); + deletedDiscoveredSymbols = null; fDirty = true; } } diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java index b388f46e9ed..6bed99e12c0 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java @@ -75,6 +75,8 @@ public class ManageIncludePathsDialog extends Dialog { private static final String DISC_COMMON_PREFIX = "ManageScannerConfigDialogCommon"; //$NON-NLS-1$ private static final String SELECTED_LABEL = DISC_COMMON_PREFIX + ".discoveredGroup.selected.label"; //$NON-NLS-1$ private static final String REMOVED_LABEL = DISC_COMMON_PREFIX + ".discoveredGroup.removed.label"; //$NON-NLS-1$ + private static final String UP_DISCOVERED = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.up.label"; //$NON-NLS-1$ + private static final String DOWN_DISCOVERED = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.down.label"; //$NON-NLS-1$ private static final String REMOVE_DISCOVERED = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.remove.label"; //$NON-NLS-1$ private static final String RESTORE_DISCOVERED = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.restore.label"; //$NON-NLS-1$ private static final String DELETE_DISCOVERED = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.delete.label"; //$NON-NLS-1$ @@ -89,8 +91,12 @@ public class ManageIncludePathsDialog extends Dialog { private static final int DO_REMOVE = 0; private static final int DO_RESTORE = 1; + private static final int DISC_UP = 0; + private static final int DISC_DOWN = 1; + private ArrayList returnPaths; private ArrayList userPaths; + private ArrayList deletedDiscoveredPaths; private LinkedHashMap discoveredPaths; private LinkedHashMap workingDiscoveredPaths; // working copy of discoveredPaths, until either OK or CANCEL is pressed private boolean fDirty; @@ -113,6 +119,8 @@ public class ManageIncludePathsDialog extends Dialog { private Label removedLabel; private List discActiveList; private List discRemovedList; + private Button upDiscPath; + private Button downDiscPath; private Button removeDiscPath; private Button restoreDiscPath; private Button deleteDiscPath; @@ -181,8 +189,10 @@ public class ManageIncludePathsDialog extends Dialog { setListContents(); userList.select(0); + userList.setFocus(); enableUserButtons(); discActiveList.select(0); + discActiveList.setFocus(); enableDiscoveredButtons(); return composite; @@ -475,6 +485,24 @@ public class ManageIncludePathsDialog extends Dialog { Composite pathButtonComp = ControlFactory.createComposite(discoveredGroup, 1); // Add the buttons + upDiscPath = ControlFactory.createPushButton(pathButtonComp, getTitle(UP_DISCOVERED)); + upDiscPath.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleUpDownDiscPath(DISC_UP); + } + }); + upDiscPath.setEnabled(true); + SWTUtil.setButtonDimensionHint(upDiscPath); + + downDiscPath = ControlFactory.createPushButton(pathButtonComp, getTitle(DOWN_DISCOVERED)); + downDiscPath.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleUpDownDiscPath(DISC_DOWN); + } + }); + downDiscPath.setEnabled(true); + SWTUtil.setButtonDimensionHint(downDiscPath); + removeDiscPath = ControlFactory.createPushButton(pathButtonComp, getTitle(REMOVE_DISCOVERED)); removeDiscPath.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { @@ -530,6 +558,58 @@ public class ManageIncludePathsDialog extends Dialog { discRemovedList.setLayoutData(gd2); } + /** + * @param direction (DISC_UP or DISC_DOWN) + */ + protected void handleUpDownDiscPath(int direction) { + int delta = (direction == DISC_UP) ? -1 : 1; + List selectedList; + boolean removed; + int selectedSet; + if (discActiveList.getSelectionIndex() == -1) { + selectedList = discRemovedList; + removed = true; + selectedSet = REMOVED; + } + else { + selectedList = discActiveList; + removed = false; + selectedSet = ACTIVE; + } + int selectedItem = selectedList.getFocusIndex(); + String selected = selectedList.getItem(selectedItem); + ArrayList pathKeyList = new ArrayList(workingDiscoveredPaths.keySet()); + int curIndex = pathKeyList.indexOf(selected); + int otherIndex = curIndex + delta; + boolean found = false; + for (; otherIndex >= 0 && otherIndex < pathKeyList.size(); otherIndex+=delta) { + Boolean val = (Boolean) workingDiscoveredPaths.get(pathKeyList.get(otherIndex)); + if (val != null && val.booleanValue() == removed) { + found = true; + break; + } + } + if (found) { + // swap the entries in the working copy + String temp = (String) pathKeyList.get(curIndex); + pathKeyList.add(curIndex, pathKeyList.get(otherIndex)); + pathKeyList.add(otherIndex, temp); + + LinkedHashMap newWorkingDiscoveredPaths = new LinkedHashMap(workingDiscoveredPaths.size()); + for (Iterator i = pathKeyList.iterator(); i.hasNext(); ) { + String key = (String) i.next(); + newWorkingDiscoveredPaths.put(key, workingDiscoveredPaths.get(key)); + } + workingDiscoveredPaths = newWorkingDiscoveredPaths; + // update UI + selectedList.setItems(getDiscIncludePaths(workingDiscoveredPaths, selectedSet)); + selectedList.setSelection(selectedItem + delta); + selectedList.setFocus(); + enableDiscoveredButtons(); + setDirty(true); + } + } + /** * */ @@ -584,6 +664,12 @@ public class ManageIncludePathsDialog extends Dialog { int id = discList.getSelectionIndex(); if (id >= 0) { String path = discList.getItem(id); + // add it to the deleted list + if (deletedDiscoveredPaths == null) { + deletedDiscoveredPaths = new ArrayList(); + } + deletedDiscoveredPaths.add(path); + workingDiscoveredPaths.remove(path); discList.setItems(getDiscIncludePaths(workingDiscoveredPaths, type)); int items = discList.getItemCount(); @@ -621,19 +707,17 @@ public class ManageIncludePathsDialog extends Dialog { discRemovedList.setEnabled(fProject != null); int activeItems = discActiveList.getItemCount(); - int activeSeclection = discActiveList.getSelectionIndex(); + int activeSelection = discActiveList.getSelectionIndex(); int removedItems = discRemovedList.getItemCount(); int removedSelection = discRemovedList.getSelectionIndex(); - // To maintain the proper TAB order of enabled buttons - if (activeItems > 0 && activeSeclection >= 0) { - removeDiscPath.setEnabled(activeItems > 0 && activeSeclection >= 0); - restoreDiscPath.setEnabled(removedItems > 0 && removedSelection >= 0); - } - else { - restoreDiscPath.setEnabled(removedItems > 0 && removedSelection >= 0); - removeDiscPath.setEnabled(activeItems > 0 && activeSeclection >= 0); - } - deleteDiscPath.setEnabled((activeItems > 0 && activeSeclection >= 0) || + // To maintain the proper TAB order of enabled buttons + upDiscPath.setEnabled((activeItems > 0 && activeSelection > 0) || + (removedItems > 0 && removedSelection > 0)); + downDiscPath.setEnabled((activeItems > 0 && activeSelection >= 0 && activeSelection < activeItems-1) || + (removedItems > 0 && removedSelection >= 0 && removedSelection < removedItems-1)); + removeDiscPath.setEnabled(activeItems > 0 && activeSelection >= 0); + restoreDiscPath.setEnabled(removedItems > 0 && removedSelection >= 0); + deleteDiscPath.setEnabled((activeItems > 0 && activeSelection >= 0) || (removedItems > 0 && removedSelection >= 0)); deleteAllDiscPaths.setEnabled(activeItems > 0 || removedItems > 0); } @@ -681,6 +765,7 @@ public class ManageIncludePathsDialog extends Dialog { fDirty = fWorkingDirty; } else if (IDialogConstants.CANCEL_ID == buttonId) { + deletedDiscoveredPaths = null; workingDiscoveredPaths = null; setDirty(false); } @@ -699,6 +784,13 @@ public class ManageIncludePathsDialog extends Dialog { if (fDirty || (fProject == null && fContainer.getProject() != null)) {// New Standard Make project wizard info.setUserIncludePaths(userPaths); info.setDiscoveredIncludePaths(discoveredPaths); + // remove deleted paths from discovered SC + if (deletedDiscoveredPaths != null) { + for (Iterator i = deletedDiscoveredPaths.iterator(); i.hasNext(); ) { + ScannerInfoCollector.getInstance().deletePath(fProject, (String) i.next()); + } + deletedDiscoveredPaths = null; + } } setDirty(false); fDirty = false; @@ -711,11 +803,14 @@ public class ManageIncludePathsDialog extends Dialog { if (fProject != null) { userPaths = new ArrayList(Arrays.asList(BuildPathInfoBlock.getIncludes( MakeCorePlugin.getDefault().getPluginPreferences()))); + // remove discovered paths + ScannerInfoCollector.getInstance().deleteAllPaths(fProject); } else { userPaths = new ArrayList(); } discoveredPaths = new LinkedHashMap(); + deletedDiscoveredPaths = null; fDirty = true; } }