/******************************************************************************* * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.make.internal.core.scannerconfig; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry; import org.eclipse.core.runtime.IPath; /** * Utility class that handles some Scanner Config specifig collection conversions * * @author vhirsl */ public final class ScannerConfigUtil { /** * Adds all new discovered symbols/values to the existing ones. * * @param sumSymbols - a map of [String, Map] where Map is a SymbolEntry */ public static boolean scAddSymbolsList2SymbolEntryMap(Map<String, SymbolEntry> sumSymbols, List<String> symbols, boolean active) { boolean rc = false; for (String symbol : symbols) { String key; String value = null; int index = symbol.indexOf("="); //$NON-NLS-1$ if (index != -1) { key = symbol.substring(0, index).trim(); value = symbol.substring(index + 1).trim(); } else { key = symbol.trim(); } SymbolEntry sEntry = sumSymbols.get(key); if (sEntry == null) { // make only the first one to be active sEntry = new SymbolEntry(key, value, true); rc = true; } else { rc |= sEntry.add(value, active); } sumSymbols.put(key, sEntry); } return rc; } /** * Gets all discovered symbols with either active or removed values */ public static List<String> scSymbolsSymbolEntryMap2List(Map<String, SymbolEntry> sumSymbols, boolean active) { Set<Entry<String, SymbolEntry>> symbols = sumSymbols.entrySet(); List<String> rv = new ArrayList<String>(symbols.size()); for (Entry<String, SymbolEntry> symbol : symbols) { SymbolEntry sEntry = symbol.getValue(); if (active) { rv.addAll(sEntry.getActiveRaw()); } else { rv.addAll(sEntry.getRemovedRaw()); } } return rv; } /** * MapsSymbolEntryMap to a plain Map * * @param sumSymbols (in) - discovered symbols in SymbolEntryMap * @return - active symbols as a plain Map */ public static Map<String, String> scSymbolEntryMap2Map(Map<String, SymbolEntry> sumSymbols) { Map<String, String> rv = new HashMap<String, String>(); Set<String> keys = sumSymbols.keySet(); for (String key : keys) { SymbolEntry entries = sumSymbols.get(key); List<String> values = entries.getValuesOnly(true); for (String value : values) { rv.put(key, value); // multiple active values will be condensed to one !!! } } return rv; } /** * Adds a single symbol definition string ("DEBUG_LEVEL=4") to the SymbolEntryMap */ public static boolean scAddSymbolString2SymbolEntryMap(Map<String, SymbolEntry> symbols, String symbol, boolean active) { boolean rc = false; String key; String value = null; int index = symbol.indexOf("="); //$NON-NLS-1$ if (index != -1) { key = getSymbolKey(symbol); value = getSymbolValue(symbol); } else { key = symbol.trim(); } SymbolEntry sEntry = symbols.get(key); if (sEntry == null) { // make only the first one to be active sEntry = new SymbolEntry(key, value, active); rc = true; } else { rc |= sEntry.add(value, active); } symbols.put(key, sEntry); return rc; } /** * @param result (out) * @param addend (in) */ public static boolean scAddSymbolEntryMap2SymbolEntryMap(Map<String, SymbolEntry> result, Map<String, SymbolEntry> addend) { boolean rc = false; Set<String> keySet = addend.keySet(); for (String key : keySet) { if (result.keySet().contains(key)) { SymbolEntry rSE = result.get(key); SymbolEntry aSE = addend.get(key); List<String> activeValues = rSE.getActiveRaw(); for (String aValue : aSE.getActiveRaw()) { if (!activeValues.contains(aValue)) { // result does not contain addend's value; add it rSE.add(getSymbolValue(aValue), true); rc |= true; } } List<String> removedValues = rSE.getRemovedRaw(); for (String aValue : aSE.getRemovedRaw()) { if (!removedValues.contains(aValue)) { // result does not contain addend's value; add it rSE.add(getSymbolValue(aValue), false); rc |= true; } } } else { // result does not contain the symbol; add it // shallow copy SymbolEntry aSymbolEntry = addend.get(key); result.put(key, aSymbolEntry); rc |= true; } } return rc; } /** * Returns a symbol key (i.e. for DEF=1 returns DEF) */ public static String getSymbolKey(String symbol) { int index = symbol.indexOf('='); if (index != -1) { return symbol.substring(0, index).trim(); } return symbol; } /** * Returns a symbol value (i.e. for DEF=1 returns 1), may be null */ public static String getSymbolValue(String symbol) { int index = symbol.indexOf('='); if (index != -1) { return symbol.substring(index+1).trim(); } 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 symbolEntryMap map of [symbol's key, symbolEntry] */ public static void removeSymbolEntryValue(String symbol, Map<String, SymbolEntry> symbolEntryMap) { String key = getSymbolKey(symbol); String value = getSymbolValue(symbol); // find it in the discoveredSymbols Map of SymbolEntries SymbolEntry se = 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 * * @return new map of include paths */ public static LinkedHashMap<String, SymbolEntry> swapIncludePaths(LinkedHashMap<String, SymbolEntry> sumPaths, int index1, int index2) { int size = sumPaths.size(); if (index1 == index2 || !(index1 >= 0 && index1 < size && index2 >= 0 && index2 < size)) { return sumPaths; } ArrayList<String> pathKeyList = new ArrayList<String>(sumPaths.keySet()); String temp1 = pathKeyList.get(index1); String temp2 = pathKeyList.get(index2); pathKeyList.set(index1, temp2); pathKeyList.set(index2, temp1); LinkedHashMap<String, SymbolEntry> newSumPaths = new LinkedHashMap<String, SymbolEntry>(sumPaths.size()); for (String key : pathKeyList) { newSumPaths.put(key, sumPaths.get(key)); } return newSumPaths; } /** * Tokenizes string with quotes */ public static String[] tokenizeStringWithQuotes(String line, String quoteStyle) { ArrayList<String> allTokens = new ArrayList<String>(); String[] tokens = line.split(quoteStyle); for (int i = 0; i < tokens.length; ++i) { if (i % 2 == 0) { // even tokens need further tokenization String[] sTokens = tokens[i].split("\\s+"); //$NON-NLS-1$ for (int j = 0; j < sTokens.length; allTokens.add(sTokens[j++])) {} } else { allTokens.add(tokens[i]); } } return allTokens.toArray(new String[allTokens.size()]); } /** * Converts array of IPath-s to array of String-s */ public static String[] iPathArray2StringArray(IPath[] paths) { String[] rv = new String[paths.length]; for (int i = 0; i < paths.length; ++i) { rv[i] = paths[i].toString(); } return rv; } }