Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Scanner Updates 3/10/03

- added in support for detecting and reporting circular inclusions
- added optimization by caching inclusion directories
- added macro pasting capabilities and tests
- updated inclusion searching algorithm for local inclusions

JohnC

Index: parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java,v
retrieving revision 1.4
diff -u -r1.4 ScannerTestCase.java
--- parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java	7 Mar 2003 13:41:21 -0000	1.4
+++ parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java	10 Mar 2003 19:41:01 -0000
@@ -154,7 +154,6 @@
 		"This statement should not be reached "
 			+ "as we sent in bad preprocessor input to the scanner";
 	public final static boolean verbose= false;
-	public final static boolean doConcatenation= false;
 	public final static boolean doIncludeStdio= false;
 	public final static boolean doIncludeWindowsH= false;
 	public final static boolean doIncludeWinUserH= false;
@@ -349,7 +348,7 @@
 	public void prepareForWindowsRH()
 	{
 		scanner.addIncludePath(
-			"C:\\Program Files\\Microsoft Visual Studio .NET\\Vc7\\PlatformSDK\\include");
+			"C:\\Program Files\\Microsoft Visual Studio\\VC98\\Include");
 		scanner.addDefinition("_WIN32_WINNT", "0x0300");
 		scanner.addDefinition("WINVER", "0x0400");
 		scanner.addDefinition("_WIN32_WINDOWS", "0x0300");
@@ -359,51 +358,74 @@
 	public void prepareForWindowsH()
 	{
 		scanner.addIncludePath(
-			"C:\\Program Files\\Microsoft Visual Studio .NET\\Vc7\\PlatformSDK\\include");
-		scanner.addIncludePath(
-			"C:\\Program Files\\Microsoft Visual Studio .NET\\Vc7\\include");
+			"C:\\Program Files\\Microsoft Visual Studio\\VC98\\Include");
 		scanner.addDefinition("_MSC_VER", "1200");
 		scanner.addDefinition("__cplusplus", "1");
 		scanner.addDefinition("__STDC__", "1");
 		scanner.addDefinition("_WIN32", "");		
-		scanner.addDefinition( "__midl", "1000" ); 
+		scanner.addDefinition( "__midl", "1000" );
+		scanner.addDefinition("_WIN32_WINNT", "0x0300");
+		scanner.addDefinition("WINVER", "0x0400");
+		scanner.addDefinition( "_M_IX86", "300");
+		scanner.addDefinition( "_INTEGRAL_MAX_BITS", "64");
 	}
 
 	public void prepareForStdio()
 	{
 		scanner.addIncludePath(
-			"C:\\Program Files\\Microsoft Visual Studio .NET\\Vc7\\include");
+			"C:\\Program Files\\Microsoft Visual Studio\\VC98\\Include");
 		scanner.addDefinition("_MSC_VER", "1100");
 		scanner.addDefinition("__STDC__", "1");
 		scanner.addDefinition("_INTEGRAL_MAX_BITS", "64");
 		scanner.addDefinition("_WIN32", "");
+		scanner.addDefinition( "_M_IX86", "300");
 	}
 
 	public void testConcatenation()
 	{
-		if (doConcatenation)
+		try
 		{
-			try
-			{
-				initializeScanner("#define F1 3\n#define F2 F1##F1\nint x=F2;");
-				validateToken(Token.t_int);
-				validateDefinition("F1", "3");
-				validateDefinition("F2", "F1##F1");
-				validateIdentifier("x");
-				validateToken(Token.tASSIGN);
-				validateInteger("33");
-				validateToken(Token.tSEMI);
-				validateEOF();
-				
-				initializeScanner("#define PREFIX RT_\n#define RUN PREFIX##Run"); 
-				validateEOF(); 
-				validateDefinition( "PREFIX", "RT_" ); 
-				validateDefinition( "RUN", "RT_Run" );
-			}
-			catch (Exception e)
-			{
-				fail(EXCEPTION_THROWN + e.toString());
-			}
+			initializeScanner("#define F1 3\n#define F2 F1##F1\nint x=F2;");
+			validateToken(Token.t_int);
+			validateDefinition("F1", "3");
+			validateDefinition( "F2", "F1##F1");
+			validateIdentifier("x");
+			validateToken(Token.tASSIGN);
+			validateInteger("33");
+			validateToken(Token.tSEMI);
+			validateEOF();
+			
+			initializeScanner("#define PREFIX RT_\n#define RUN PREFIX##Run"); 
+			validateEOF(); 
+			validateDefinition( "PREFIX", "RT_" ); 
+			validateDefinition( "RUN", "PREFIX##Run" );
+		}
+		catch (Exception e)
+		{
+			fail(EXCEPTION_THROWN + e.toString());
+		}
+		
+		try
+		{
+			initializeScanner( "#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name\n DECLARE_HANDLE( joe )" );
+			validateToken( Token.t_struct );
+			validateIdentifier( "joe__"); 
+			validateToken( Token.tLBRACE);  
+			validateToken( Token.t_int ); 
+			validateIdentifier( "unused"); 
+			validateToken( Token.tSEMI ); 
+			validateToken( Token.tRBRACE );
+			validateToken( Token.tSEMI ); 
+			validateToken( Token.t_typedef ); 
+			validateToken( Token.t_struct ); 
+			validateIdentifier( "joe__" ); 
+			validateToken( Token.tSTAR ); 
+			validateIdentifier( "joe");  
+			validateEOF();
+		}
+		catch( Exception e )
+		{ 
+			fail(EXCEPTION_THROWN + e.toString());			
 		}
 	}
 
@@ -1089,5 +1111,5 @@
 		{
 			fail(EXCEPTION_THROWN + se.toString());			
 		}
-	} 
+	}
 }
Index: parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java,v
retrieving revision 1.2
diff -u -r1.2 IScannerContext.java
--- parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java	4 Mar 2003 18:25:40 -0000	1.2
+++ parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java	10 Mar 2003 19:40:47 -0000
@@ -1,6 +1,6 @@
 package org.eclipse.cdt.internal.core.parser;
-import java.io.Reader;
 import java.io.IOException;
+import java.io.Reader;
 /**
  * @author jcamelon
  *
@@ -11,11 +11,24 @@
  * Window>Preferences>Java>Code Generation.
  */
 public interface IScannerContext {
-	IScannerContext initialize(Reader r, String f, int u);
+	
+	public static int SENTINEL = 0;
+	public static int TOP = 1; 
+	public static int INCLUSION = 2; 
+	public static int MACROEXPANSION = 3; 
+
+	
+	IScannerContext initialize(Reader r, String f, int k);
 	int read() throws IOException;
 	String getFilename();
 	int getOffset();
 	Reader getReader();
-	int getUndo();
-	void setUndo(int undo);
+	
+	int undoStackSize();  
+	int popUndo();
+	void pushUndo(int undo);
+	
+	
+	int getKind(); 
+	void setKind( int kind ); 
 }
Index: parser/org/eclipse/cdt/internal/core/parser/Scanner.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java,v
retrieving revision 1.3
diff -u -r1.3 Scanner.java
--- parser/org/eclipse/cdt/internal/core/parser/Scanner.java	7 Mar 2003 13:41:26 -0000	1.3
+++ parser/org/eclipse/cdt/internal/core/parser/Scanner.java	10 Mar 2003 19:40:47 -0000
@@ -10,6 +10,7 @@
  ******************************************************************************/
 package org.eclipse.cdt.internal.core.parser;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
@@ -17,9 +18,11 @@
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.Stack;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -46,13 +49,13 @@
 			new ScannerContext().initialize(
 				new StringReader("\n"),
 				START,
-				NOCHAR));
+				ScannerContext.SENTINEL));
 		if (filename == null)
 			currentContext =
-				new ScannerContext().initialize(reader, TEXT, NOCHAR);
+				new ScannerContext().initialize(reader, TEXT, ScannerContext.TOP ); 
 		else
 			currentContext =
-				new ScannerContext().initialize(reader, filename, NOCHAR);
+				new ScannerContext().initialize(reader, filename, ScannerContext.TOP ); 
 	}
 
 	public Scanner() {
@@ -63,13 +66,19 @@
 		definitions = defns;
 	}
 
-	protected void updateContext(Reader reader, String filename) {
-//		if (callback != null)
-//			callback.inclusionBegin(filename); // not quite right ... fix me!!!
+	protected void updateContext(Reader reader, String filename, int type) throws ScannerException {
+		if( type == IScannerContext.INCLUSION )
+		{
+			if( !inclusions.add( filename ) )
+				throw new ScannerException( "Inclusion " + filename + " already encountered." ); 	
+				
+			System.out.println( "Handle inclusion - " + filename );	
+		}
 
 		contextStack.push(currentContext);
 		currentContext =
-			new ScannerContext().initialize(reader, filename, NOCHAR);
+			new ScannerContext().initialize(reader, filename, type );
+			
 	}
 
 	protected boolean rollbackContext() {
@@ -79,26 +88,41 @@
 			System.out.println("Error closing reader");
 		}
 
+		if( currentContext.getKind() == IScannerContext.INCLUSION )
+		{
+			inclusions.remove( currentContext.getFilename() );
+			System.out.println( "Completed inclusion - " + currentContext.getFilename() );
+		}
+
 		if (contextStack.isEmpty()) {
 			currentContext = null;
 			return false;
 		}
 
-		//if (callback != null)
-		//	callback.inclusionEnd();
-
 		currentContext = (ScannerContext) contextStack.pop();
 		return true;
 	}
 
 	public void addIncludePath(String includePath) {
-		includePaths.add(includePath);
+		includePathNames.add(includePath);
+		includePaths.add( new File( includePath ) );
 	}
 
 	public void overwriteIncludePath(List newIncludePaths) {
-		includePaths = null;
-		includePaths = new ArrayList();
-		includePaths.addAll(newIncludePaths);
+		includePathNames = null;
+		includePaths = null; 
+		includePathNames = new ArrayList();
+		includePaths = new ArrayList(); 
+		includePathNames.addAll(newIncludePaths);
+		
+		Iterator i = includePathNames.iterator(); 
+		while( i.hasNext() )
+		{
+			String path = (String) i.next();
+			includePaths.add( new File( path )); 
+		}
+		
+		
 	}
 
 	public void addDefinition(String key, IMacroDescriptor macro) {
@@ -114,15 +138,20 @@
 	}
 
 	public final Object[] getIncludePaths() {
-		return includePaths.toArray();
+		return includePathNames.toArray();
 	}
 
-	protected void skipOverWhitespace() {
+	protected boolean skipOverWhitespace() {
 		int c = getChar();
+		boolean result = false; 
 		while ((c != NOCHAR) && ((c == ' ') || (c == '\t')))
+		{
 			c = getChar();
+			result = true; 
+		}
 		if (c != NOCHAR)
 			ungetChar(c);
+		return result; 
 
 	}
 
@@ -192,6 +221,12 @@
 		currentToken = t;
 	}
 
+	protected void resetStorageBuffer()
+	{
+		if( storageBuffer != null ) 
+			storageBuffer = null; 
+	}
+
 	protected Token newToken(int t, String i, IScannerContext c) {
 		setCurrentToken(new Token(t, i, c));
 		return currentToken;
@@ -201,7 +236,7 @@
 		setCurrentToken(new Token(t, i));
 		return currentToken;
 	}
-
+	
 	protected String getNextIdentifier() {
 		StringBuffer buffer = new StringBuffer();
 		skipOverWhitespace();
@@ -225,56 +260,81 @@
 		return buffer.toString();
 	}
 
-	protected void handleInclusion(String fileName) throws ScannerException {
-		// Skip over inclusions in quickScan mode
-		if (quickScan)
-			return;
-
-		// iterate through the include paths 
-		Iterator iter = includePaths.iterator();
-
-		while (iter.hasNext()) {
-			String path = (String) iter.next();
-
-			java.io.File pathFile = new java.io.File(path);
-			if (pathFile.isDirectory()) {
-				String newPath = pathFile + "\\" + fileName;
-
-				java.io.File includeFile = new java.io.File(newPath);
-
-				if (includeFile.exists() && includeFile.isFile()) {
-					try {
-						FileReader inclusionReader =
-							new FileReader(includeFile);
-						//System.out.println( "Parsing inclusion file " + newPath );
-						updateContext(inclusionReader, newPath);
-						return;
-					} catch (FileNotFoundException fnf) {
-						// do nothing	
+	protected void handleInclusion(String fileName, boolean useIncludePaths ) throws ScannerException {
+
+		if( useIncludePaths ) // search include paths for this file
+		{
+			// iterate through the include paths 
+			Iterator iter = includePaths.iterator();
+	
+			while (iter.hasNext()) {
+	
+				File pathFile = (File)iter.next();
+				if (pathFile.isDirectory()) {
+					String newPath = pathFile.getPath() + File.separatorChar + fileName;
+	
+					File includeFile = new File(newPath);
+	
+					if (includeFile.exists() && includeFile.isFile()) {
+						try {
+							FileReader inclusionReader =
+								new FileReader(includeFile);
+							updateContext(inclusionReader, newPath, ScannerContext.INCLUSION );
+							return;
+						} catch (FileNotFoundException fnf) {
+							// do nothing - check the next directory
+						}
 					}
 				}
 			}
 		}
+		else // local inclusion
+		{
+			String currentFilename = currentContext.getFilename(); 
+			File currentIncludeFile = new File( currentFilename );
+			String parentDirectory = currentIncludeFile.getParent();
+			currentIncludeFile = null; 
+			String fullPath = parentDirectory + File.separatorChar + fileName;
+			File includeFile = new File( fullPath );
+			if (includeFile.exists() && includeFile.isFile()) {
+				try {
+					FileReader inclusionReader =
+						new FileReader(includeFile);
+					updateContext(inclusionReader, fullPath, ScannerContext.INCLUSION );
+					return;
+				} catch (FileNotFoundException fnf) {
+					if (throwExceptionOnInclusionNotFound)
+						throw new ScannerException("Cannot find inclusion " + fileName);	
+				}
+			}
+		}
+		
 		if (throwExceptionOnInclusionNotFound)
 			throw new ScannerException("Cannot find inclusion " + fileName);
 	}
 
 	// constants
-	public static final int NOCHAR = -1;
+	private static final int NOCHAR = -1;
 
 	private static final String TEXT = "<text>";
 	private static final String START = "<initial reader>";
 	private static final String EXPRESSION = "<expression>";
+	private static final String PASTING = "<pasting>";
 	private static final String BAD_PP =
 		"Invalid preprocessor directive encountered at offset ";
 	private static final String DEFINED = "defined";
 	private static final String POUND_DEFINE = "#define ";
 
+	public static final int tPOUNDPOUND = -6;
+
 	private IScannerContext currentContext;
 	private Stack contextStack = new Stack();
 
+	private List includePathNames = new ArrayList();
 	private List includePaths = new ArrayList();
 	private Hashtable definitions = new Hashtable();
+	private StringBuffer storageBuffer = null; 
+	private Set inclusions = new HashSet(); 
 	private int count = 0;
 	private static HashMap keywords = new HashMap();
 	private static HashMap ppDirectives = new HashMap();
@@ -295,7 +355,6 @@
 	private boolean throwExceptionOnUnboundedString = true;
 	private boolean throwExceptionOnEOFWithinMultilineComment = true;
 	private boolean throwExceptionOnEOFWithoutBalancedEndifs = true;
-	private boolean providedDefinedMacro = true;
 
 	private boolean quickScan = false;
 	public void setQuickScan(boolean qs) {
@@ -314,9 +373,8 @@
 		do {
 			done = true;
 
-			if (currentContext.getUndo() != NOCHAR) {
-				c = currentContext.getUndo();
-				currentContext.setUndo(NOCHAR);
+			if (currentContext.undoStackSize() != 0 ) {
+				c = currentContext.popUndo();
 			} else {
 				try {
 					c = currentContext.read();
@@ -354,11 +412,40 @@
 	private void ungetChar(int c) {
 		// Should really check whether there already is a char there
 		// If so, we should be using a buffer, instead of a single char
-		currentContext.setUndo(c);
+		currentContext.pushUndo(c);
+	}
+
+	protected boolean lookAheadForTokenPasting()
+	{
+		int c = getChar(); 
+		if( c == '#' )
+		{
+			c = getChar(); 
+			if( c == '#' )
+			{
+				return true; 
+			}
+			else
+			{
+				ungetChar( c );
+			}
+		}
+
+		ungetChar( c );
+		return false; 
+
 	}
 
+	
+
 	public Token nextToken() throws ScannerException {
+		return nextToken( true ); 
+	}
+
 
+	protected Token nextToken( boolean pasting ) throws ScannerException
+	{
+	
 		count++;
 
 		int c = getChar();
@@ -393,12 +480,9 @@
 
 				String ident = buff.toString();
 
-				if (providedDefinedMacro) {
-					if (ident.equals(DEFINED)) {
-						return newToken(Token.tINTEGER, handleDefinedMacro());
-					}
-				}
-
+				if (ident.equals(DEFINED)) 
+					return newToken(Token.tINTEGER, handleDefinedMacro());
+				
 				Object mapping = definitions.get(ident);
 
 				if (mapping != null) {
@@ -412,6 +496,31 @@
 				if (tokenTypeObject != null)
 					tokenType = ((Integer) tokenTypeObject).intValue();
 
+				if( pasting )
+				{
+					if( lookAheadForTokenPasting() )
+					{
+						if( storageBuffer == null )
+							storageBuffer = buff;
+						else
+							storageBuffer.append( ident ); 
+							 
+						c = getChar(); 
+						continue; 	
+					}
+					else
+					{
+						if( storageBuffer != null )
+						{
+							storageBuffer.append( ident );
+							updateContext( new StringReader( storageBuffer.toString()), PASTING, IScannerContext.MACROEXPANSION );
+							storageBuffer = null;  
+							c = getChar(); 
+							continue;
+						}
+					}
+				}
+
 				return newToken(tokenType, ident, currentContext);
 			} else if (c == '"') {
 				// string
@@ -436,7 +545,18 @@
 				}
 
 			} else if ((c >= '0') && (c <= '9')) {
-				StringBuffer buff = new StringBuffer();
+				StringBuffer buff;
+				
+				if( pasting )
+				{
+					if( storageBuffer != null )
+						buff = storageBuffer;
+					else
+						buff = new StringBuffer();
+				}
+				else
+					buff = new StringBuffer();
+					
 				buff.append((char) c);
 
 				c = getChar();
@@ -454,21 +574,52 @@
 				}
 
 				ungetChar(c);
+				
+				if( pasting )
+				{
+					if( lookAheadForTokenPasting() )
+					{
+						storageBuffer = buff; 
+						c = getChar(); 
+						continue; 	
+					}
+					else
+					{
+						if( storageBuffer != null )
+						{
+							updateContext( new StringReader( buff.toString()), PASTING, IScannerContext.MACROEXPANSION );
+							storageBuffer = null;  
+							c = getChar(); 
+							continue; 
+						}
+					}
+				}
+				
 				return newToken(
 					Token.tINTEGER,
 					buff.toString(),
 					currentContext);
+				
 			} else if (c == '#') {
 				// lets prepare for a preprocessor statement
 				StringBuffer buff = new StringBuffer();
 				buff.append((char) c);
 
 				// we are allowed arbitrary whitespace after the '#' and before the rest of the text
-				skipOverWhitespace();
+				boolean skipped = skipOverWhitespace();
 
 				c = getChar();
+				
+				if( c == '#' )
+				{
+					if( skipped )
+						throw new ScannerException(BAD_PP + currentContext.getOffset()); 
+					else 
+						return newToken( tPOUNDPOUND, "##" );
+				} 
+				
 				while (((c >= 'a') && (c <= 'z'))
-					|| ((c >= 'A') && (c <= 'Z')) | (c == '_')) {
+					|| ((c >= 'A') && (c <= 'Z')) || (c == '_') ) {
 					buff.append((char) c);
 					c = getChar();
 				}
@@ -1128,14 +1279,14 @@
 			}
 	
 			
-			if (expressionEvalResult.getClass() == java.lang.Integer.class) {
+			if (expressionEvalResult instanceof Integer ) {
 				int i = ((Integer) expressionEvalResult).intValue();
 				if (i == 0) {
 					return false;
 				}
 				return true;
 			} else if (
-				expressionEvalResult.getClass() == java.lang.Boolean.class) {
+				expressionEvalResult instanceof Boolean ) {
 				return ((Boolean) expressionEvalResult).booleanValue();
 			} else {
 				throw new ScannerException(
@@ -1189,6 +1340,7 @@
 		int offset;
 
 		StringBuffer fileName = new StringBuffer();
+		boolean useIncludePath = true;
 		if (c == '<') {
 			c = getChar();
 			while ((c != '>')) {
@@ -1202,7 +1354,7 @@
 				fileName.append((char) c);
 				c = getChar();
 			}
-
+			useIncludePath = false; 
 			// TO DO: Make sure the directory of the current file is in the
 			// inclusion paths.
 		}
@@ -1220,16 +1372,14 @@
 			}
 		}
 		else
-			handleInclusion(f.trim());
+			handleInclusion(f.trim(), useIncludePath );
 	}
 
 	protected void poundDefine() throws ScannerException {
 		skipOverWhitespace();
 		// definition 
 		String key = getNextIdentifier();
-		int offset = currentContext.getOffset() - key.length();
-		if( currentContext.getUndo() != Scanner.NOCHAR )
-			offset -= 1;
+		int offset = currentContext.getOffset() - key.length() - currentContext.undoStackSize();
 
 		if (throwExceptionOnRedefinition) {
 			String checkForRedefinition = (String) definitions.get(key);
@@ -1274,11 +1424,11 @@
 			helperScanner.initialize(
 				new StringReader(replacementString),
 				null);
-			Token t = helperScanner.nextToken();
+			Token t = helperScanner.nextToken(false);
 
 			while (t.type != Token.tEOF) {
 				macroReplacementTokens.add(t);
-				t = helperScanner.nextToken();
+				t = helperScanner.nextToken(false);
 			}
 
 			IMacroDescriptor descriptor = new MacroDescriptor();
@@ -1295,7 +1445,8 @@
 
 			// get what we are to map the name to and add it to the definitions list
 			String value = getRestOfPreprocessorLine();
-			addDefinition(key, value);
+			addDefinition( key, value ); 				
+		
 		} else if (c == '/') {
 			// this could be a comment	
 			c = getChar();
@@ -1333,12 +1484,10 @@
 
 	protected void expandDefinition(String symbol, Object expansion)
 		throws ScannerException {
-		if (expansion.getClass() == String.class) {
+		if (expansion instanceof String ) {
 			String replacementValue = (String) expansion;
-			updateContext(
-				new StringReader(replacementValue),
-				POUND_DEFINE + symbol);
-		} else if (expansion.getClass() == MacroDescriptor.class) {
+			updateContext( new StringReader(replacementValue), (POUND_DEFINE + symbol ), ScannerContext.MACROEXPANSION );
+		} else if (expansion instanceof IMacroDescriptor ) {
 			IMacroDescriptor macro = (IMacroDescriptor) expansion;
 			skipOverWhitespace();
 			int c = getChar();
@@ -1359,7 +1508,7 @@
 					buffer.append((char) c);
 					c = getChar();
 				}
-				String betweenTheBrackets = buffer.toString();
+				String betweenTheBrackets = buffer.toString().trim();
 				StringTokenizer tokenizer =
 					new StringTokenizer(betweenTheBrackets, ",");
 				Vector parameterValues = new Vector(tokenizer.countTokens());
@@ -1387,29 +1536,39 @@
 
 						// is this identifier in the parameterNames
 						// list? 
-
 						int index = parameterNames.indexOf(t.image);
 						if (index == -1 ) {
 							// not found
 							// just add image to buffer
-							buffer.append(t.image);
+							buffer.append(t.image );
 						} else {
 							buffer.append(
-								(String) parameterValues.elementAt(index));
+								(String) parameterValues.elementAt(index) );
 						}
 					} else {
 						buffer.append(t.image);
 					}
+					
+					boolean pastingNext = false;
+					
+					if( i != numberOfTokens - 1)
+					{
+						Token t2 = (Token) tokens.get(i+1);
+						if( t2.getType() == tPOUNDPOUND )
+							pastingNext = true;  
+					}
+					
+					if( t.getType() != tPOUNDPOUND && ! pastingNext )
+						buffer.append( " " ); 
 				}
+				String finalString = buffer.toString(); 
 				updateContext(
-					new StringReader(buffer.toString()),
-					POUND_DEFINE + macro.getSignature());
-			} else {
+					new StringReader(finalString),
+					POUND_DEFINE + macro.getSignature(), ScannerContext.MACROEXPANSION );
+			} else 
 				if (throwExceptionOnBadMacroExpansion)
 					throw new ScannerException(
 						"Improper use of macro " + symbol);
-
-			}
 
 		} else {
 			System.out.println(
Index: parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java,v
retrieving revision 1.2
diff -u -r1.2 ScannerContext.java
--- parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java	4 Mar 2003 18:25:40 -0000	1.2
+++ parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java	10 Mar 2003 19:40:46 -0000
@@ -12,21 +12,23 @@
 
 import java.io.IOException;
 import java.io.Reader;
+import java.util.Stack;
 
 public class ScannerContext implements IScannerContext
 {
 	private Reader reader;
 	private String filename;
 	private int offset;
-	private int undo; 
-		
+	private Stack undo = new Stack(); 
+	private int kind; 
+				
 	public ScannerContext(){}
-	public IScannerContext initialize(Reader r, String f, int u )
+	public IScannerContext initialize(Reader r, String f, int k)
 	{
 		reader = r;
 		filename = f;
 		offset = 0;
-		undo = u;
+		kind = k; 
 		return this;
 	}
 		
@@ -62,22 +64,44 @@
 		return reader;
 	}
 
+	public final int undoStackSize()
+	{
+		return undo.size();
+	}
+
 	/**
 	 * Returns the undo.
 	 * @return int
 	 */
-	public final int getUndo()
+	public final int popUndo()
 	{
-		return undo;
+		return ((Integer)undo.pop()).intValue();
 	}
 
 	/**
 	 * Sets the undo.
 	 * @param undo The undo to set
 	 */
-	public void setUndo(int undo)
+	public void pushUndo(int undo)
 	{
-		this.undo= undo;
+		this.undo.push( new Integer( undo )); 
+	}
+
+
+	/**
+	 * Returns the kind.
+	 * @return int
+	 */
+	public int getKind() {
+		return kind;
+	}
+
+	/**
+	 * Sets the kind.
+	 * @param kind The kind to set
+	 */
+	public void setKind(int kind) {
+		this.kind = kind;
 	}
 
 }
Index: parser/org/eclipse/cdt/internal/core/parser/Token.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Token.java,v
retrieving revision 1.2
diff -u -r1.2 Token.java
--- parser/org/eclipse/cdt/internal/core/parser/Token.java	4 Mar 2003 18:25:40 -0000	1.2
+++ parser/org/eclipse/cdt/internal/core/parser/Token.java	10 Mar 2003 19:40:47 -0000
@@ -16,10 +16,7 @@
 		type = t;
 		image = i;
 		filename = context.getFilename();
-		offset = context.getOffset() - image.length();
-		
-		if( context.getUndo() != Scanner.NOCHAR )
-			offset -= 1;
+		offset = context.getOffset() - image.length() - context.undoStackSize();
 	}
 	
 	public Token(int t, String i) {

Back to the top