Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Scanner config discovery - fixes

This patch addresses following bugs:

PR 62809 [Scanner Config] Handling -DMACRO="value"
PR 63330 [Scanner Config] Auto-discovering dirs with escaped spaces
PR 64226 [Scanner Config] Path discovery supporting UNC filepaths

Also, new tests (for now only SC console parsing) have been created in 
managedbuilder.core.tests plugin.

The patch is applicable to both 2.0 branch and HEAD.

Thanks,
Vmir

Index: src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigUtil.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigUtil.java,v
retrieving revision 1.2
diff -u -r1.2 ScannerConfigUtil.java
--- src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigUtil.java	22 Jun 2004 20:12:03 -0000	1.2
+++ src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigUtil.java	9 Jul 2004 16:07:23 -0000
@@ -12,7 +12,6 @@
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -268,13 +267,18 @@
 	 * @param String
 	 * @return String[] 
 	 */
-	public static String[] tokenizeStringWithQuotes(String line) {
+	public static String[] tokenizeStringWithQuotes(String line, String quoteStyle) {
 		ArrayList allTokens = new ArrayList();
-		String[] tokens = line.split("\"");	//$NON-NLS-1$
+		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$
-				allTokens.addAll(Arrays.asList(sTokens));
+				// remove empty strings
+				for (int j = 0; j < sTokens.length; ++j) {
+					if (sTokens[j].length() > 0) {
+						allTokens.add(sTokens[j]);
+					}
+				}
 			}
 			else {
 				allTokens.add(tokens[i]);
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java,v
retrieving revision 1.10
diff -u -r1.10 DefaultExternalScannerInfoProvider.java
--- src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java	22 Jun 2004 13:19:49 -0000	1.10
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java	9 Jul 2004 16:07:24 -0000
@@ -104,7 +104,7 @@
 			
 			OutputStream sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer(
 					cos, currentProject, buildInfo, collector);
-			TraceUtil.outputTrace("Default provider running command:", fCompileCommand.toString() + ca, ""); //$NON-NLS-1$ //$NON-NLS-2$
+			TraceUtil.outputTrace("Default provider is executing command:", fCompileCommand.toString() + ca, ""); //$NON-NLS-1$ //$NON-NLS-2$
 			Process p = launcher.execute(fCompileCommand, compileArguments, setEnvironment(launcher), fWorkingDirectory);
 			if (p != null) {
 				try {
@@ -168,7 +168,7 @@
 		}
 		fCompileCommand = buildInfo.getESIProviderCommand();
 		if (fCompileCommand != null) {
-			fCompileArguments = ScannerConfigUtil.tokenizeStringWithQuotes(buildInfo.getESIProviderArguments());
+			fCompileArguments = ScannerConfigUtil.tokenizeStringWithQuotes(buildInfo.getESIProviderArguments(), "\"");//$NON-NLS-1$
 			for (int i = 0; i < fCompileArguments.length; ++i) {
 				fCompileArguments[i] = fCompileArguments[i].replaceAll("\\$\\{plugin_state_location\\}",	//$NON-NLS-1$ 
 						MakeCorePlugin.getWorkingDirectory().toString());
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java,v
retrieving revision 1.11
diff -u -r1.11 GCCScannerInfoConsoleParser.java
--- src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java	26 Jun 2004 20:08:14 -0000	1.11
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java	9 Jul 2004 16:07:24 -0000
@@ -16,7 +16,6 @@
 import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
 import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
 import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParserUtility;
-import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigUtil;
 import org.eclipse.cdt.make.internal.core.MakeMessages;
 import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
 
@@ -33,11 +32,16 @@
  * @author vhirsl
  */
 public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser {
-
+	private final static String SINGLE_QUOTE_STRING = "\'"; //$NON-NLS-1$
+	private final static String DOUBLE_QUOTE_STRING = "\""; //$NON-NLS-1$
+	
 	private IProject fProject = null;
 	private IScannerInfoConsoleParserUtility fUtil = null;
 	private IScannerInfoCollector fCollector = null;
 	
+	private boolean bMultiline = false;
+	private String sMultiline = ""; //$NON-NLS-1$
+	
 	/* (non-Javadoc)
 	 * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector)
 	 */
@@ -52,6 +56,17 @@
 	 */
 	public boolean processLine(String line) {
 		boolean rc = false;
+		// check for multiline commands (ends with '\')
+		if (line.endsWith("\\")) { //$NON-NLS-1$
+			sMultiline += line.substring(0, line.length()-1);// + " "; //$NON-NLS-1$
+			bMultiline = true;
+			return rc;
+		}
+		if (bMultiline) {
+			line = sMultiline + line;
+			bMultiline = false;
+			sMultiline = ""; //$NON-NLS-1$
+		}
 		TraceUtil.outputTrace("GCCScannerInfoConsoleParser parsing line:", TraceUtil.EOL, line);	//$NON-NLS-1$ //$NON-NLS-2$
 		// make\[[0-9]*\]:  error_desc
 		int firstColon= line.indexOf(':');
@@ -65,19 +80,21 @@
 			    int e = msg.indexOf('\'');
 			    if (s != -1 && e != -1) {
 			    	String dir = msg.substring(s+1, e);
-			    	fUtil.changeMakeDirectory(dir, getDirectoryLevel(line), enter);
+					if (fUtil != null) {
+						fUtil.changeMakeDirectory(dir, getDirectoryLevel(line), enter);
+					}
 			    	return rc;
 				}
 			}
 		}
 		// Known patterns:
 		// (a) gcc|g++ ... -Dxxx -Iyyy ...
-		ArrayList allTokens = new ArrayList(Arrays.asList(ScannerConfigUtil.tokenizeStringWithQuotes(line)));
+		ArrayList allTokens = new ArrayList(Arrays.asList(line.split("\\s")));//$NON-NLS-1$
 		if (allTokens.size() <= 1)
 			return false;
 		Iterator I = allTokens.iterator();
 		String token = ((String) I.next()).toLowerCase();
-		if (token.indexOf("gcc") != -1 || token.indexOf("g++") != -1 || token.indexOf("qcc") != -1) {//$NON-NLS-1$ //$NON-NLS-2$
+		if (token.indexOf("gcc") != -1 || token.indexOf("g++") != -1 || token.indexOf("gcc") != -1) {//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 			// Recognized gcc or g++ compiler invocation
 			List includes = new ArrayList();
 			List symbols = new ArrayList();
@@ -85,60 +102,20 @@
 
 			rc = true;
 			String fileName = null;
-			String cashedToken = null;
+			// discover all -I options
+			parseLineForIncludePaths(line, includes);
+			// discover all -D options
+			parseLineForSymbolDefinitions(line, symbols);
+			
 			while (I.hasNext()) {
-				if (cashedToken == null) {
-					token = (String) I.next();
-				}
-				else {
-					token = cashedToken;
-					cashedToken = null;
-				}
-				if (token.length() == 0) {
-					continue;
-				}
-				if (token.startsWith("-D")) {//$NON-NLS-1$
-					String symbol = token.substring(2);
-					if (symbol.length() == 0) {
-						if (I.hasNext()) {
-							symbol = (String) I.next();
-						}
-						else {
-							continue;
-						}
-					}
-					if (symbol.charAt(0) == '-') {
-						cashedToken = symbol;
-						continue;
-					}
-					if (!symbols.contains(symbol))
-						symbols.add(symbol);
-				}
-				else if (token.startsWith("-I")) {//$NON-NLS-1$
-					String iPath = token.substring(2);
-					if (iPath.length() == 0) {
-						if (I.hasNext()) {
-							iPath = (String) I.next();
-						}
-						else {
-							continue;
-						}
-					}
-					if (iPath.charAt(0) == '-') {
-						cashedToken = iPath;
-						continue;
-					}
-					String nPath = fUtil.normalizePath(iPath);
-					if (!includes.contains(nPath))
-						includes.add(nPath);
-				}
-				else if (token.equals("-mwin32") ||		//$NON-NLS-1$
-						 token.equals("-mno-win32") ||	//$NON-NLS-1$
-						 token.equals("-mno-cygwin") ||	//$NON-NLS-1$
-						 token.equals("-ansi") ||		//$NON-NLS-1$
-						 token.equals("-nostdinc") ||	//$NON-NLS-1$
-						 token.equals("-posix") ||		//$NON-NLS-1$
-						 token.equals("-pthread")) {	//$NON-NLS-1$
+				token = (String) I.next();
+				if (token.equals("-mwin32") ||		//$NON-NLS-1$
+					token.equals("-mno-win32") ||	//$NON-NLS-1$
+					token.equals("-mno-cygwin") ||	//$NON-NLS-1$
+					token.equals("-ansi") ||		//$NON-NLS-1$
+					token.equals("-nostdinc") ||	//$NON-NLS-1$
+					token.equals("-posix") ||		//$NON-NLS-1$
+					token.equals("-pthread")) {		//$NON-NLS-1$
 					if (!targetSpecificOptions.contains(token))
 						targetSpecificOptions.add(token);
 				}
@@ -164,18 +141,22 @@
 			List translatedIncludes = includes;
 			if (includes.size() > 0) {
 				if (fileName != null) {
-					file = fUtil.findFile(fileName);
-					if (file != null) {
-						project = file.getProject();
-						translatedIncludes = fUtil.translateRelativePaths(file, fileName, includes);
+					if (fUtil != null) {
+						file = fUtil.findFile(fileName);
+						if (file != null) {
+							project = file.getProject();
+							translatedIncludes = fUtil.translateRelativePaths(file, fileName, includes);
+						}
 					}
 				}
 				else {
 					final String error = MakeMessages.getString("ConsoleParser.Filename_Missing_Error_Message"); //$NON-NLS-1$ 
-					TraceUtil.outputError(error, line);	
-					fUtil.generateMarker(fProject, -1, error + line, IMarkerGenerator.SEVERITY_WARNING, null);
+					TraceUtil.outputError(error, line);
+					if (fUtil != null) {
+						fUtil.generateMarker(fProject, -1, error + line, IMarkerGenerator.SEVERITY_WARNING, null);
+					}
 				}
-				if (file == null) {
+				if (file == null && fUtil != null) {	// real world case
 					// remove include paths since there was no chance to translate them
 					translatedIncludes.clear();
 				}
@@ -191,6 +172,124 @@
 			}
 		}
 		return rc;
+	}
+
+	/**
+	 * @param line
+	 * @param includes
+	 */
+	private void parseLineForIncludePaths(String line, List includes) {
+		final String fDashI = "-I"; //$NON-NLS-1$
+		int prevIndex = 0;
+		for (int index = line.indexOf(fDashI, prevIndex); index != -1; 
+			 prevIndex = index+2, index = line.indexOf(fDashI, prevIndex)) {
+			String delimiter = "\\s"; //$NON-NLS-1$
+			if (line.charAt(index-1) == '\'' || line.charAt(index-1) == '\"') {
+				// look for only one more ' or "
+				delimiter = String.valueOf(line.charAt(index-1));
+			}
+			String postfix = line.substring(index+2).trim();
+			if (postfix.charAt(0) == '-') {	// empty -I
+				continue;
+			}
+			if (postfix.startsWith(SINGLE_QUOTE_STRING) || postfix.startsWith(DOUBLE_QUOTE_STRING)) { //$NON-NLS-1$ //$NON-NLS-2$
+				delimiter = postfix.substring(0, 1);
+			}
+			String[] tokens = postfix.split(delimiter);
+			int tokIndex = (tokens.length > 1 && tokens[0].length() == 0) ? 1 : 0;
+			String iPath = tokens[tokIndex];
+			String temp = iPath;
+			// check for '\ '
+			for (++tokIndex; (temp.endsWith("\\") && tokIndex < tokens.length &&  //$NON-NLS-1$
+							 tokens[tokIndex].length() > 0 && !tokens[tokIndex].startsWith("-")); //$NON-NLS-1$
+				 ++tokIndex) { 
+				int beg = postfix.indexOf(temp)+temp.length();
+				int end = postfix.indexOf(tokens[tokIndex])+tokens[tokIndex].length();
+				iPath = iPath.substring(0, iPath.length()-1) + postfix.substring(beg, end);
+				temp += postfix.substring(beg, end);
+			}
+			String nPath = iPath;
+			if (fUtil != null) {
+				nPath = fUtil.normalizePath(iPath);
+			}
+			if (!includes.contains(nPath)) {
+				includes.add(nPath);
+			}
+		}
+	}
+
+	/**
+	 * @param line
+	 * @param symbols
+	 */
+	private void parseLineForSymbolDefinitions(String line, List symbols) {
+		final String fDashD = "-D"; //$NON-NLS-1$
+		int prevIndex = 0;
+		for (int index = line.indexOf(fDashD, prevIndex); index != -1; 
+			 prevIndex = index+2, index = line.indexOf(fDashD, prevIndex)) {
+			String delimiter = "\\s"; //$NON-NLS-1$
+			int nDelimiterSymbols = 2;
+			String postfix = line.substring(index+2).trim();
+			if (postfix.charAt(0) == '-') {	// empty -D
+				continue;
+			}
+			if (line.charAt(index-1) == '\'' || line.charAt(index-1) == '\"') {
+				// look for only one more ' or "
+				delimiter = String.valueOf(line.charAt(index-1)); 
+				nDelimiterSymbols = 1;
+			}
+			else {
+				String[] tokens = postfix.split(delimiter, 2);
+				if (tokens.length > 0 && tokens[0].length() > 0) {
+					int sQuoteIndex = tokens[0].indexOf(SINGLE_QUOTE_STRING);
+					int dQuoteIndex = tokens[0].indexOf(DOUBLE_QUOTE_STRING);
+					if (sQuoteIndex == -1 && dQuoteIndex == -1) {
+						// simple case, no quotes
+						if (!symbols.contains(tokens[0])) {
+							symbols.add(tokens[0]);
+						}
+					}
+					else {
+						delimiter = (sQuoteIndex != -1 && (dQuoteIndex == -1 || sQuoteIndex < dQuoteIndex)) ? SINGLE_QUOTE_STRING : DOUBLE_QUOTE_STRING;
+					}
+				}
+				else 
+					continue;
+			}
+			
+			// find next matching delimiter
+			int nextDelimiterIndex = -1;
+			int prevDelimiterIndex = -1;
+			do {
+				nextDelimiterIndex = postfix.indexOf(delimiter, nextDelimiterIndex+1);
+				if (nextDelimiterIndex == 0 || (nextDelimiterIndex > 0 && postfix.charAt(nextDelimiterIndex-1) != '\\')) {
+					--nDelimiterSymbols;
+					if (nDelimiterSymbols > 0) {
+						prevDelimiterIndex = nextDelimiterIndex;
+					}
+				}
+			}
+			while (nDelimiterSymbols > 0 && nextDelimiterIndex != -1);
+			if (nDelimiterSymbols > 0) 
+				continue; // non matching delimiter
+
+			// take everything up to the last delimiter
+			boolean bStartsWithDelimiter = postfix.startsWith(delimiter);
+			String symbol = postfix.substring(bStartsWithDelimiter ? 1 : 0, nextDelimiterIndex);
+			if (!bStartsWithDelimiter) {
+				// there is still a delimiter to be removed
+				if (prevDelimiterIndex != -1) {
+					symbol = symbol.substring(0, prevDelimiterIndex) + symbol.substring(prevDelimiterIndex+1);
+				}
+			}
+			// transform '\"' into '"'
+			if (delimiter.equals(DOUBLE_QUOTE_STRING)) {
+				symbol = symbol.replaceAll("\\\\\"", DOUBLE_QUOTE_STRING); //$NON-NLS-1$
+			}
+			if (!symbols.contains(symbol)) {
+				symbols.add(symbol);
+			}
+		}
 	}
 
 	/* (non-Javadoc)
Index: suite/org/eclipse/cdt/standardbuilder/core/tests/AllStandardBuildTests.java
===================================================================
RCS file: suite/org/eclipse/cdt/standardbuilder/core/tests/AllStandardBuildTests.java
diff -N suite/org/eclipse/cdt/standardbuilder/core/tests/AllStandardBuildTests.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ suite/org/eclipse/cdt/standardbuilder/core/tests/AllStandardBuildTests.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.standardbuilder.core.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Invokes all standard builder tests
+ * 
+ * @author vhirsl
+ */
+public class AllStandardBuildTests extends TestSuite {
+
+	/**
+	 * @param string
+	 */
+	public AllStandardBuildTests(String title) {
+		super(title);
+	}
+
+	public static void main(String[] args) {
+		junit.textui.TestRunner.run(AllStandardBuildTests.suite());
+	}
+
+	public static Test suite() {
+		TestSuite suite = new AllStandardBuildTests("Test for org.eclipse.cdt.standardbuild.core.tests");
+		//$JUnit-BEGIN$
+		suite.addTest(ScannerConfigConsoleParserTests.suite());
+		//$JUnit-END$
+		return suite;
+	}
+}
Index: suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java
===================================================================
RCS file: suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java
diff -N suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,156 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.standardbuilder.core.tests;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
+import org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerInfoConsoleParser;
+import org.eclipse.core.resources.IResource;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Scanner configuration console parser tests
+ * 
+ * @author vhirsl
+ */
+public class ScannerConfigConsoleParserTests extends TestCase {
+	
+	private IScannerInfoConsoleParser clParser;
+
+	public ScannerConfigConsoleParserTests(String name) {
+		super(name);
+	}
+
+	/* (non-Javadoc)
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		
+		clParser = new GCCScannerInfoConsoleParser();			
+	}
+	/* (non-Javadoc)
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		
+		clParser.shutdown();
+		clParser = null;
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(ScannerConfigConsoleParserTests.class.getName());
+		
+		suite.addTest(new ScannerConfigConsoleParserTests("testParsingIncludePaths"));
+		suite.addTest(new ScannerConfigConsoleParserTests("testParsingSymbolDefinitions"));
+		
+		return suite;
+	}
+
+	/*
+	 * Tests GCCScannerInfoConsoleParser. Utility object not provided.
+	 * Only tests parsing of the imput (make build output) 
+	 */
+	public void testParsingIncludePaths() {
+		final ArrayList sumIncludes = new ArrayList();
+		// initialize it with the utility
+		clParser.startup(null, null, new IScannerInfoCollector() {
+			public void contributeToScannerConfig(IResource resource, List includes, List symbols, Map extraInfo) {
+				sumIncludes.addAll(includes);
+			}
+		});
+		
+		clParser.processLine("gcc -I /dir/include -I C:\\dir\\include -ID:/dir/include -c test.c");	// absolute paths
+		clParser.processLine("gcc -I -I /dir2/include -c test.c");	// empty -I
+		clParser.processLine("gcc -I../back_dir/include -I./cur_dir/include -c test.c"); // relative paths
+		clParser.processLine("gcc '-I /squoted/dir1' -I '/squoted/dir2' -I'/squoted/dir3' -c test.c"); // single quote dirs
+		clParser.processLine("gcc \"-I /dquoted/dir1\" -I \"/dquoted/dir2\" -I\"/dquoted/dir3\" -c test.c"); // double quote dirs
+		clParser.processLine("gcc '-I /with spaces 1' -I'/with spaces 2' -c test.c"); // dirs with spaces 1,2
+		clParser.processLine("gcc \"-I /with spaces 3\" -I \"/with spaces 4\" -c test.c"); // dirs with spaces 3,4
+		clParser.processLine("gcc -I /with\\ spaces\\ 5 -c test.c"); // dirs with spaces 5
+		clParser.processLine("gcc -I '\\\\server1\\include' '-I\\\\server2\\include' -I \"\\\\server3\\include\" -c test.c"); // UNC paths
+		clParser.processLine("gcc -I //server4/include -I '//server5/include' '-I//server6/include' -c test.c"); // UNC paths
+		clParser.processLine("gcc -I \\");
+		clParser.processLine("/multiline\\");
+		clParser.processLine("/dir -c test.c"); // multiline
+		
+		assertTrue(sumIncludes.contains("/dir/include"));
+		assertTrue(sumIncludes.contains("C:\\dir\\include"));
+		assertTrue(sumIncludes.contains("D:/dir/include"));
+		assertTrue(sumIncludes.contains("/dir2/include"));
+		assertTrue(sumIncludes.contains("../back_dir/include"));
+		assertTrue(sumIncludes.contains("./cur_dir/include"));
+		assertTrue(sumIncludes.contains("/squoted/dir1"));
+		assertTrue(sumIncludes.contains("/squoted/dir2"));
+		assertTrue(sumIncludes.contains("/squoted/dir3"));
+		assertTrue(sumIncludes.contains("/dquoted/dir1"));
+		assertTrue(sumIncludes.contains("/dquoted/dir2"));
+		assertTrue(sumIncludes.contains("/dquoted/dir3"));
+		assertTrue(sumIncludes.contains("/with spaces 1"));
+		assertTrue(sumIncludes.contains("/with spaces 2"));
+		assertTrue(sumIncludes.contains("/with spaces 3"));
+		assertTrue(sumIncludes.contains("/with spaces 4"));
+		assertTrue(sumIncludes.contains("/with spaces 5"));
+		assertTrue(sumIncludes.contains("\\\\server1\\include"));
+		assertTrue(sumIncludes.contains("\\\\server2\\include"));
+		assertTrue(sumIncludes.contains("\\\\server3\\include"));
+		assertTrue(sumIncludes.contains("//server4/include"));
+		assertTrue(sumIncludes.contains("//server5/include"));
+		assertTrue(sumIncludes.contains("//server6/include"));
+		assertTrue(sumIncludes.contains("/multiline/dir"));
+	}
+	
+	public void testParsingSymbolDefinitions() {
+		final ArrayList sumSymbols = new ArrayList();
+		// initialize it with the utility
+		clParser.startup(null, null, new IScannerInfoCollector() {
+			public void contributeToScannerConfig(IResource resource, List includes, List symbols, Map extraInfo) {
+				sumSymbols.addAll(symbols);
+			}
+		});
+		
+		clParser.processLine("gcc -DMACRO1 -D MACRO2=value2 -c test.c");	// simple definitions
+		clParser.processLine("gcc -D -DMACRO3 -c test.c");	// empty -D
+		clParser.processLine("gcc -D MACRO4='value4' -D 'MACRO5=value5' '-D MACRO6 = value6' -c test.c");	// single quotes
+		clParser.processLine("gcc -D'MACRO7=\"value 7\"' -D MACRO8='\"value 8\"' -c test.c");	// single quotes
+		clParser.processLine("gcc -DMACRO9=\"value9\" -D \"MACRO10=value10\" \"-D MACRO11 = value11\" -c test.c");	// double quotes
+		clParser.processLine("gcc -D\"MACRO12=\\\"value 12\\\"\" -D MACRO13=\"\\\"value 13\\\"\" -c test.c");	// single quotes
+		clParser.processLine("gcc -D \\");
+		clParser.processLine("MULTILINE=TRUE	\\");
+		clParser.processLine("-c test.c"); // multiline
+		clParser.processLine("gcc -D 'SUM(x, y) = (x) + (y)' -c test.c"); // more complex macro definition
+		
+		assertTrue(sumSymbols.contains("MACRO1"));
+		assertTrue(sumSymbols.contains("MACRO2=value2"));
+		assertTrue(sumSymbols.contains("MACRO3"));
+		assertTrue(sumSymbols.contains("MACRO4=value4"));
+		assertTrue(sumSymbols.contains("MACRO5=value5"));
+		assertTrue(sumSymbols.contains("MACRO6 = value6"));
+		assertTrue(sumSymbols.contains("MACRO7=\"value 7\""));
+		assertTrue(sumSymbols.contains("MACRO8=\"value 8\""));
+		assertTrue(sumSymbols.contains("MACRO9=value9"));
+		assertTrue(sumSymbols.contains("MACRO10=value10"));
+		assertTrue(sumSymbols.contains("MACRO11 = value11"));
+		assertTrue(sumSymbols.contains("MACRO12=\"value 12\""));
+		assertTrue(sumSymbols.contains("MACRO13=\"value 13\""));
+		assertTrue(sumSymbols.contains("MULTILINE=TRUE"));
+		assertTrue(sumSymbols.contains("SUM(x, y) = (x) + (y)"));
+	}
+}

Back to the top