1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

<BR>Patch for Dave Daoust

<BR>Modified Scanner Performance by 
<BR>1. Moved ScannerContext sentinal to ContextStack 
<BR>2. Delay Stringizing macro parameter until needed 
<BR>3. Removed the sentinal from the scanner constructor
This commit is contained in:
John Camelon 2004-04-16 18:34:39 +00:00
parent 181f9ff6b7
commit 0ce4a707ab
7 changed files with 1583 additions and 1595 deletions

View file

@ -1,3 +1,17 @@
2004-04-15 David Daoust
Modified Scanner Performance by
1. Moved ScannerContext sentinal to ContextStack
2. Delay Stringizing macro parameter until needed
3. Removed the sentinal from the scanner constructor
Effect on #include <windows.h>
total bytes objs time(ms)tokens
orig 59905960 1455079 1593 83812
move sentinel 53824616 1262428 1462 83812
delay stringizing 40868312 950355 1322 83812
remove sentinal 38598848 910909 1312 83812
2004-04-15 Andrew Niefer 2004-04-15 Andrew Niefer
fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58492 fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58492

View file

@ -3,6 +3,7 @@ package org.eclipse.cdt.core.parser;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.parser.ast.IASTFactory; import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.internal.core.parser.scanner.IScannerContext;
/** /**
* @author jcamelon * @author jcamelon
@ -48,5 +49,6 @@ public interface IScanner extends IFilenameProvider {
* @return * @return
*/ */
public boolean isOnTopContext(); public boolean isOnTopContext();
public void setScannerContext(IScannerContext context);
} }

View file

@ -13,16 +13,12 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.Stack;
import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ISourceElementRequestor; import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.ast.IASTInclusion; import org.eclipse.cdt.core.parser.ast.IASTInclusion;
import org.eclipse.cdt.internal.core.parser.scanner.IScannerContext.ContextKind;
import org.eclipse.cdt.internal.core.parser.util.TraceUtil; import org.eclipse.cdt.internal.core.parser.util.TraceUtil;
/** /**
@ -33,34 +29,85 @@ import org.eclipse.cdt.internal.core.parser.util.TraceUtil;
*/ */
public class ContextStack { public class ContextStack {
private static class SentinelContext implements IScannerContext {
public int read() throws IOException { return '\n'; }
public String getFilename() { return ""; }
public int getMacroOffset() { return -1; }
public int getMacroLength() { return -1; }
public int getOffset() { return 0; }
public int getRelativeOffset() { return 0; }
public Reader getReader() { return null; }
public void pushUndo(int undo) { }
public int getKind() { return IScannerContext.ContextKind.SENTINEL; }
public void setKind(int kind) { }
public IASTInclusion getExtension() { return null; }
public void setExtension(IASTInclusion ext) { }
public int getLine() { return -1; }
public int undoStackSize() { return 0; }
public int popUndo() { return '\n'; }
}
private final IParserLogService log; private final IParserLogService log;
private Scanner scanner; private int current_size = 8;
public ContextStack( Scanner s, IParserLogService l ) { private IScannerContext [] cs = new IScannerContext[current_size];;
scanner = s; private int cs_pos = 0;
log = l;
private static IScannerContext sentinel = new SentinelContext();
private IScanner scanner;
private final void cs_push(IScannerContext c) {
try {
cs[cs_pos++] = c;;
}
catch (ArrayIndexOutOfBoundsException a)
{
int new_size = current_size*2;
IScannerContext [] new_cs = new IScannerContext[new_size];
for (int i = 0; i < current_size; i++) {
new_cs[i] = cs[i];
} }
public void updateContext(Reader reader, String filename, ContextKind type, IASTInclusion inclusion, ISourceElementRequestor requestor) throws ContextException { new_cs[current_size] = c;
current_size = new_size;
cs = new_cs;
}
scanner.setScannerContext(c);
}
private final IScannerContext cs_pop() {
IScannerContext context = cs[--cs_pos];
scanner.setScannerContext((cs_pos == 0) ? sentinel : cs[cs_pos -1]);
return context;
}
public ContextStack( IScanner scanner, IParserLogService l ) {
log = l;
this.scanner = scanner;
cs_push(sentinel);
scanner.setScannerContext(sentinel);
}
public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor) throws ContextException {
updateContext(reader, filename, type, inclusion, requestor, -1, -1); updateContext(reader, filename, type, inclusion, requestor, -1, -1);
} }
public void updateContext(Reader reader, String filename, ContextKind type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ContextException public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ContextException
{ {
int startLine = 1; int startLine = 1;
// If we expand a macro within a macro, then keep offsets of the top-level one, // If we expand a macro within a macro, then keep offsets of the top-level one,
// as only the top level macro identifier is properly positioned // as only the top level macro identifier is properly positioned
if (type == IScannerContext.ContextKind.MACROEXPANSION) { if (type == IScannerContext.ContextKind.MACROEXPANSION) {
if (currentContext.getKind() == IScannerContext.ContextKind.MACROEXPANSION) { if (getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION) {
macroOffset = currentContext.getMacroOffset(); macroOffset = getCurrentContext().getMacroOffset();
macroLength = currentContext.getMacroLength(); macroLength = getCurrentContext().getMacroLength();
} }
startLine = currentContext.getLine(); startLine = getCurrentContext().getLine();
} }
undoStack.clear();
IScannerContext context = new ScannerContext( reader, filename, type, null, macroOffset, macroLength, startLine ); IScannerContext context = new ScannerContext( reader, filename, type, null, macroOffset, macroLength, startLine );
context.setExtension(inclusion); context.setExtension(inclusion);
push( context, requestor ); push( context, requestor );
@ -68,70 +115,45 @@ public class ContextStack {
protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ContextException protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ContextException
{ {
if( context.getKind() == IScannerContext.ContextKind.INCLUSION ) if( context.getKind() == IScannerContext.ContextKind.INCLUSION ) {
{ if( isCircularInclusion( context.getFilename() ) )
if( !inclusions.add( context.getFilename() ) )
throw new ContextException( IProblem.PREPROCESSOR_CIRCULAR_INCLUSION ); throw new ContextException( IProblem.PREPROCESSOR_CIRCULAR_INCLUSION );
TraceUtil.outputTrace(log, "Scanner::ContextStack: entering inclusion ", null, context.getFilename(), null, null ); //$NON-NLS-1$ TraceUtil.outputTrace(log, "Scanner::ContextStack: entering inclusion ", null, context.getFilename(), null, null ); //$NON-NLS-1$
context.getExtension().enterScope( requestor ); context.getExtension().enterScope( requestor );
} else if( context.getKind() == IScannerContext.ContextKind.MACROEXPANSION )
{
if( !defines.add( context.getFilename() ) )
throw new ContextException( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN );
} }
if( currentContext != null )
contextStack.push(currentContext);
currentContext = context; // This could be replaced with a check for shouldExpandMacro -- but it is called by
if( context.getKind() == IScannerContext.ContextKind.TOP ) // the scanner before this point
topContext = context; // else if( context.getKind() == IScannerContext.ContextKind.MACROEXPANSION )
// {
// if( !defines.add( context.getFilename() ) )
// throw new ContextException( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN );
// }
cs_push(context);
} }
public boolean rollbackContext(ISourceElementRequestor requestor) { public boolean rollbackContext(ISourceElementRequestor requestor) {
IScannerContext context = getCurrentContext();
try { try {
currentContext.getReader().close(); context.getReader().close();
} catch (IOException ie) { } catch (IOException ie) {
TraceUtil.outputTrace( log, "ContextStack : Error closing reader "); //$NON-NLS-1$ TraceUtil.outputTrace( log, "ContextStack : Error closing reader "); //$NON-NLS-1$
} }
if( currentContext.getKind() == IScannerContext.ContextKind.INCLUSION ) if( context.getKind() == IScannerContext.ContextKind.INCLUSION )
{ {
TraceUtil.outputTrace(log, "Scanner::ContextStack: ending inclusion ", null, currentContext.getFilename(), null, null); //$NON-NLS-1$ TraceUtil.outputTrace(log, "Scanner::ContextStack: ending inclusion ", null, context.getFilename(), null, null); //$NON-NLS-1$
inclusions.remove( currentContext.getFilename() ); context.getExtension().exitScope( requestor );
currentContext.getExtension().exitScope( requestor ); }
} else if( currentContext.getKind() == IScannerContext.ContextKind.MACROEXPANSION ) cs_pop();
{ return cs_pos != 0;
defines.remove( currentContext.getFilename() );
} }
undoStack.addFirst( currentContext ); public void undoRollback( IScannerContext undoTo, ISourceElementRequestor requestor ) {
while (getCurrentContext() != undoTo ) {
if (contextStack.isEmpty()) { //cs_pos++;
currentContext = null; scanner.setScannerContext(cs[cs_pos++]);
return false;
}
currentContext = (ScannerContext) contextStack.pop();
return true;
}
public void undoRollback( IScannerContext undoTo, ISourceElementRequestor requestor ) throws ContextException {
if( currentContext == undoTo ){
return;
}
int size = undoStack.size();
if( size > 0 )
{
for( int i = size; i > 0; i-- )
{
push( (IScannerContext) undoStack.removeFirst(), requestor );
if( currentContext == undoTo )
break;
}
} }
} }
@ -147,58 +169,43 @@ public class ContextStack {
*/ */
protected boolean shouldExpandDefinition( String symbol ) protected boolean shouldExpandDefinition( String symbol )
{ {
return !defines.contains( symbol ); for(int i = cs_pos-1; i >= 0; i--)
if (cs[i].getKind() == IScannerContext.ContextKind.MACROEXPANSION
&& cs[i].getFilename().equals(symbol))
return false;
return true;
} }
public IScannerContext getCurrentContext(){ protected boolean isCircularInclusion( String symbol )
return currentContext; {
for(int i = cs_pos-1; i >= 0; i--)
if (cs[i].getKind() == IScannerContext.ContextKind.INCLUSION &&
cs[i].getFilename().equals(symbol))
return true;
return false;
} }
private IScannerContext currentContext, topContext; public final IScannerContext getCurrentContext(){
private Stack contextStack = new Stack(); //return (cs_pos == 0) ? sentinel : cs[cs_pos -1];
private LinkedList undoStack = new LinkedList(); return cs[cs_pos -1];
private Set inclusions = new HashSet();
private Set defines = new HashSet();
/**
* @return
*/
public IScannerContext getTopContext() {
return topContext;
} }
public IScannerContext getMostRelevantFileContext() public IScannerContext getMostRelevantFileContext()
{ {
if( currentContext != null ) IScannerContext context = sentinel;
for( int i = cs_pos - 1; i >= 0; --i )
{ {
if( currentContext.getKind() == IScannerContext.ContextKind.TOP ) return currentContext; context = cs[i];
if( currentContext.getKind() == IScannerContext.ContextKind.INCLUSION ) return currentContext; if( context.getKind() == IScannerContext.ContextKind.INCLUSION
} || context.getKind() == IScannerContext.ContextKind.TOP )
IScannerContext context = null;
for( int i = contextStack.size() - 1; i >= 0; --i )
{
context = (IScannerContext)contextStack.get(i);
if( context.getKind() == IScannerContext.ContextKind.INCLUSION || context.getKind() == IScannerContext.ContextKind.TOP )
break; break;
if( i == 0 ) context = null;
} }
return context; return context;
} }
public int getCurrentLineNumber() public int getCurrentLineNumber()
{ {
return getMostRelevantFileContext() != null ? getMostRelevantFileContext().getLine() : -1; return getMostRelevantFileContext().getLine();
} }
public int getTopFileLineNumber()
{
return topContext.getLine();
}
public Scanner getScanner()
{
return scanner;
}
} }

View file

@ -2,7 +2,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import org.eclipse.cdt.core.parser.Enum;
import org.eclipse.cdt.core.parser.ast.IASTInclusion; import org.eclipse.cdt.core.parser.ast.IASTInclusion;
/** /**
* @author jcamelon * @author jcamelon
@ -11,20 +10,12 @@ import org.eclipse.cdt.core.parser.ast.IASTInclusion;
public interface IScannerContext { public interface IScannerContext {
public static class ContextKind extends Enum public static class ContextKind
{ {
public static ContextKind SENTINEL = new ContextKind( 0 ); public static int SENTINEL = 0;
public static ContextKind TOP = new ContextKind( 1 ); public static int TOP = 1;
public static ContextKind INCLUSION = new ContextKind( 2 ); public static int INCLUSION = 2;
public static ContextKind MACROEXPANSION = new ContextKind( 3 ); public static int MACROEXPANSION = 3;
/**
* @param enumValue
*/
protected ContextKind(int enumValue) {
super(enumValue);
//
}
} }
/** /**
@ -67,8 +58,8 @@ public interface IScannerContext {
public int popUndo(); public int popUndo();
public void pushUndo(int undo); public void pushUndo(int undo);
public ContextKind getKind(); public int getKind();
public void setKind( ContextKind kind ); public void setKind( int kind );
public IASTInclusion getExtension(); public IASTInclusion getExtension();
public void setExtension( IASTInclusion ext ); public void setExtension( IASTInclusion ext );

View file

@ -30,7 +30,7 @@ public class LimitedScannerContext
* @param object * @param object
* @param offsetLimit * @param offsetLimit
*/ */
public LimitedScannerContext(Scanner scanner, Reader reader, String string, ContextKind kind, int offsetLimit) { public LimitedScannerContext(Scanner scanner, Reader reader, String string, int kind, int offsetLimit) {
super( reader, string, kind, null ); super( reader, string, kind, null );
this.scanner = scanner; this.scanner = scanner;
limit = offsetLimit; limit = offsetLimit;

View file

@ -80,6 +80,11 @@ public class Scanner implements IScanner {
private static final int NO_OFFSET_LIMIT = -1; private static final int NO_OFFSET_LIMIT = -1;
private int offsetLimit = NO_OFFSET_LIMIT; private int offsetLimit = NO_OFFSET_LIMIT;
private boolean limitReached = false; private boolean limitReached = false;
private IScannerContext currentContext;
public void setScannerContext(IScannerContext context) {
currentContext = context;
}
protected void handleProblem( int problemID, String argument, int beginningOffset, boolean warning, boolean error ) throws ScannerException protected void handleProblem( int problemID, String argument, int beginningOffset, boolean warning, boolean error ) throws ScannerException
{ {
@ -117,18 +122,6 @@ public class Scanner implements IScanner {
scannerData.setDefinitions( definitions ); scannerData.setDefinitions( definitions );
scannerData.setIncludePathNames( includePaths ); scannerData.setIncludePathNames( includePaths );
scannerData.setASTFactory( ParserFactory.createASTFactory( this, scannerData.getParserMode(), language ) ); scannerData.setASTFactory( ParserFactory.createASTFactory( this, scannerData.getParserMode(), language ) );
try {
//this is a hack to get around a sudden EOF experience
scannerData.getContextStack().push(
new ScannerContext(
new StringReader("\n"), //$NON-NLS-1$
START,
ScannerContext.ContextKind.SENTINEL, null), requestor);
} catch( ContextException ce ) {
//won't happen since we aren't adding an include or a macro
}
} }
public Scanner(Reader reader, String filename, IScannerInfo info, ISourceElementRequestor requestor, ParserMode parserMode, ParserLanguage language, IParserLogService log, IScannerExtension extension, List workingCopies ) { public Scanner(Reader reader, String filename, IScannerInfo info, ISourceElementRequestor requestor, ParserMode parserMode, ParserLanguage language, IParserLogService log, IScannerExtension extension, List workingCopies ) {
@ -140,19 +133,6 @@ public class Scanner implements IScanner {
((GCCScannerExtension)scannerExtension).setScannerData( scannerData ); ((GCCScannerExtension)scannerExtension).setScannerData( scannerData );
scannerData.setASTFactory( ParserFactory.createASTFactory( this, scannerData.getParserMode(), language ) ); scannerData.setASTFactory( ParserFactory.createASTFactory( this, scannerData.getParserMode(), language ) );
try {
//this is a hack to get around a sudden EOF experience
scannerData.getContextStack().push(
new ScannerContext(
new StringReader("\n"), //$NON-NLS-1$
START,
ScannerContext.ContextKind.SENTINEL, null), requestor);
} catch( ContextException ce ) {
//won't happen since we aren't adding an include or a macro
// assert false
}
TraceUtil.outputTrace(log, "Scanner constructed with the following configuration:"); //$NON-NLS-1$ TraceUtil.outputTrace(log, "Scanner constructed with the following configuration:"); //$NON-NLS-1$
TraceUtil.outputTrace(log, "\tPreprocessor definitions from IScannerInfo: "); //$NON-NLS-1$ TraceUtil.outputTrace(log, "\tPreprocessor definitions from IScannerInfo: "); //$NON-NLS-1$
@ -546,7 +526,7 @@ public class Scanner implements IScanner {
} }
else // local inclusion else // local inclusion
{ {
duple = ScannerUtility.createReaderDuple( new File( scannerData.getContextStack().getCurrentContext().getFilename() ).getParentFile().getAbsolutePath(), fileName, scannerData.getClientRequestor(), scannerData.getWorkingCopies() ); duple = ScannerUtility.createReaderDuple( new File( currentContext.getFilename() ).getParentFile().getAbsolutePath(), fileName, scannerData.getClientRequestor(), scannerData.getWorkingCopies() );
if( duple != null ) if( duple != null )
break totalLoop; break totalLoop;
useIncludePaths = true; useIncludePaths = true;
@ -599,7 +579,7 @@ public class Scanner implements IScanner {
File includeFile = null; File includeFile = null;
if( !useIncludePaths ) { // local inclusion is checked first if( !useIncludePaths ) { // local inclusion is checked first
String currentFilename = scannerData.getContextStack().getCurrentContext().getFilename(); String currentFilename = currentContext.getFilename();
File currentIncludeFile = new File( currentFilename ); File currentIncludeFile = new File( currentFilename );
String parentDirectory = currentIncludeFile.getParentFile().getAbsolutePath(); String parentDirectory = currentIncludeFile.getParentFile().getAbsolutePath();
currentIncludeFile = null; currentIncludeFile = null;
@ -723,9 +703,9 @@ public class Scanner implements IScanner {
private int getChar( boolean insideString ) throws ScannerException { private int getChar( boolean insideString ) throws ScannerException {
int c = NOCHAR; int c = NOCHAR;
lastContext = scannerData.getContextStack().getCurrentContext(); lastContext = currentContext;
if (lastContext == null) if (lastContext.getKind() == IScannerContext.ContextKind.SENTINEL)
// past the end of file // past the end of file
return c; return c;
@ -845,7 +825,7 @@ public class Scanner implements IScanner {
{ {
int c; int c;
try { try {
c = scannerData.getContextStack().getCurrentContext().read(); c = currentContext.read();
} }
catch (IOException e) { catch (IOException e) {
c = NOCHAR; c = NOCHAR;
@ -857,22 +837,16 @@ public class Scanner implements IScanner {
if (scannerData.getContextStack().rollbackContext(scannerData.getClientRequestor()) == false) if (scannerData.getContextStack().rollbackContext(scannerData.getClientRequestor()) == false)
return NOCHAR; return NOCHAR;
if (scannerData.getContextStack().getCurrentContext().undoStackSize() != 0 ) if (currentContext.undoStackSize() != 0 )
return scannerData.getContextStack().getCurrentContext().popUndo(); return currentContext.popUndo();
return readFromStream(); return readFromStream();
} }
final void ungetChar(int c) throws ScannerException{ final void ungetChar(int c) throws ScannerException{
scannerData.getContextStack().getCurrentContext().pushUndo(c); currentContext.pushUndo(c);
try
{
scannerData.getContextStack().undoRollback( lastContext, scannerData.getClientRequestor() ); scannerData.getContextStack().undoRollback( lastContext, scannerData.getClientRequestor() );
}
catch (ContextException e)
{
handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true );
}
} }
protected boolean lookAheadForTokenPasting() throws ScannerException protected boolean lookAheadForTokenPasting() throws ScannerException
@ -898,7 +872,7 @@ public class Scanner implements IScanner {
protected void consumeUntilOutOfMacroExpansion() throws ScannerException protected void consumeUntilOutOfMacroExpansion() throws ScannerException
{ {
while( scannerData.getContextStack().getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION ) while( currentContext.getKind() == IScannerContext.ContextKind.MACROEXPANSION )
getChar(); getChar();
} }
@ -933,7 +907,7 @@ public class Scanner implements IScanner {
} }
catch (ContextException e) catch (ContextException e)
{ {
handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true ); handleProblem( e.getId(), currentContext.getFilename(), getCurrentOffset(), false, true );
} }
storageBuffer = null; storageBuffer = null;
return true; return true;
@ -1172,7 +1146,7 @@ public class Scanner implements IScanner {
public IToken processPreprocessor() throws ScannerException, EndOfFileException public IToken processPreprocessor() throws ScannerException, EndOfFileException
{ {
int c; int c;
int beginningOffset = scannerData.getContextStack().getCurrentContext().getOffset() - 1; int beginningOffset = currentContext.getOffset() - 1;
int beginningLine = scannerData.getContextStack().getCurrentLineNumber(); int beginningLine = scannerData.getContextStack().getCurrentLineNumber();
// we are allowed arbitrary whitespace after the '#' and before the rest of the text // we are allowed arbitrary whitespace after the '#' and before the rest of the text
@ -2511,6 +2485,7 @@ public class Scanner implements IScanner {
c = getChar(); c = getChar();
} }
if ( state != 2)
if (c == NOCHAR && !isLimitReached() ) if (c == NOCHAR && !isLimitReached() )
handleProblem( IProblem.SCANNER_UNEXPECTED_EOF, null, getCurrentOffset(), false, true ); handleProblem( IProblem.SCANNER_UNEXPECTED_EOF, null, getCurrentOffset(), false, true );
else if( c== NOCHAR ) // limit reached else if( c== NOCHAR ) // limit reached
@ -2686,7 +2661,7 @@ public class Scanner implements IScanner {
protected void poundDefine(int beginning, int beginningLine ) throws ScannerException, EndOfFileException { protected void poundDefine(int beginning, int beginningLine ) throws ScannerException, EndOfFileException {
// definition // definition
String key = getNextIdentifier(); String key = getNextIdentifier();
int offset = scannerData.getContextStack().getCurrentContext().getOffset() - key.length() - scannerData.getContextStack().getCurrentContext().undoStackSize(); int offset = currentContext.getOffset() - key.length() - currentContext.undoStackSize();
int nameLine = scannerData.getContextStack().getCurrentLineNumber(); int nameLine = scannerData.getContextStack().getCurrentLineNumber();
// store the previous definition to check against later // store the previous definition to check against later
@ -2718,16 +2693,13 @@ public class Scanner implements IScanner {
handleProblem( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, potentialErrorMessage.toString(), beginning, false, true); handleProblem( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, potentialErrorMessage.toString(), beginning, false, true);
return; return;
} }
} else if( c == '\r' || c == '\n' ){ } else if( c == '\r' || c == '\n' || c == NOCHAR ){
StringBuffer potentialErrorMessage = new StringBuffer( POUND_DEFINE ); StringBuffer potentialErrorMessage = new StringBuffer( POUND_DEFINE );
potentialErrorMessage.append( buffer ); potentialErrorMessage.append( buffer );
potentialErrorMessage.append( '\\'); potentialErrorMessage.append( '\\');
potentialErrorMessage.append( (char)c ); potentialErrorMessage.append( (char)c );
handleProblem( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, potentialErrorMessage.toString(), beginning, false, true ); handleProblem( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, potentialErrorMessage.toString(), beginning, false, true );
return; return;
} else if( c == NOCHAR ){
handleProblem( IProblem.SCANNER_UNEXPECTED_EOF, null, beginning, false, true );
return;
} }
buffer.append((char) c); buffer.append((char) c);
@ -2826,7 +2798,7 @@ public class Scanner implements IScanner {
try try
{ {
scannerData.getASTFactory().createMacro( key, beginning, beginningLine, offset, offset + key.length(), nameLine, scannerData.getContextStack().getCurrentContext().getOffset(), scannerData.getContextStack().getCurrentLineNumber(), descriptor ).acceptElement( scannerData.getClientRequestor() ); scannerData.getASTFactory().createMacro( key, beginning, beginningLine, offset, offset + key.length(), nameLine, currentContext.getOffset(), scannerData.getContextStack().getCurrentLineNumber(), descriptor ).acceptElement( scannerData.getClientRequestor() );
} }
catch (Exception e) catch (Exception e)
{ {
@ -2959,7 +2931,7 @@ public class Scanner implements IScanner {
} }
catch (ContextException e) catch (ContextException e)
{ {
handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true ); handleProblem( e.getId(), currentContext.getFilename(), getCurrentOffset(), false, true );
consumeUntilOutOfMacroExpansion(); consumeUntilOutOfMacroExpansion();
return; return;
} }
@ -2990,7 +2962,7 @@ public class Scanner implements IScanner {
String betweenTheBrackets = buffer.toString().trim(); String betweenTheBrackets = buffer.toString().trim();
Vector parameterValues = getMacroParameters(betweenTheBrackets, false); Vector parameterValues = getMacroParameters(betweenTheBrackets, false);
Vector parameterValuesForStringizing = getMacroParameters(betweenTheBrackets, true); Vector parameterValuesForStringizing = null;
SimpleToken t = null; SimpleToken t = null;
// create a string that represents what needs to be tokenized // create a string that represents what needs to be tokenized
@ -3025,6 +2997,8 @@ public class Scanner implements IScanner {
} else if (t.getType() == tPOUND) { } else if (t.getType() == tPOUND) {
//next token should be a parameter which needs to be turned into //next token should be a parameter which needs to be turned into
//a string literal //a string literal
if( parameterValuesForStringizing == null)
parameterValuesForStringizing = getMacroParameters(betweenTheBrackets, true);
t = (SimpleToken) tokens.get( ++i ); t = (SimpleToken) tokens.get( ++i );
int index = parameterNames.indexOf(t.getImage()); int index = parameterNames.indexOf(t.getImage());
if( index == -1 ){ if( index == -1 ){
@ -3109,7 +3083,7 @@ public class Scanner implements IScanner {
} }
catch (ContextException e) catch (ContextException e)
{ {
handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true ); handleProblem( e.getId(), currentContext.getFilename(), getCurrentOffset(), false, true );
consumeUntilOutOfMacroExpansion(); consumeUntilOutOfMacroExpansion();
return; return;
} }
@ -3199,7 +3173,7 @@ public class Scanner implements IScanner {
* @see org.eclipse.cdt.core.parser.IScanner#isOnTopContext() * @see org.eclipse.cdt.core.parser.IScanner#isOnTopContext()
*/ */
public boolean isOnTopContext() { public boolean isOnTopContext() {
return ( scannerData.getContextStack().getCurrentContext() == scannerData.getContextStack().getTopContext() ); return ( currentContext.getKind() == IScannerContext.ContextKind.TOP );
} /* (non-Javadoc) } /* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IFilenameProvider#getCurrentFilename() * @see org.eclipse.cdt.core.parser.IFilenameProvider#getCurrentFilename()
*/ */
@ -3215,8 +3189,8 @@ public class Scanner implements IScanner {
public String toString() { public String toString() {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append( "Scanner @"); //$NON-NLS-1$ buffer.append( "Scanner @"); //$NON-NLS-1$
if( scannerData.getContextStack().getCurrentContext() != null ) if( currentContext != null )
buffer.append( scannerData.getContextStack().getCurrentContext().toString()); buffer.append( currentContext.toString());
else else
buffer.append( "EOF"); //$NON-NLS-1$ buffer.append( "EOF"); //$NON-NLS-1$
return buffer.toString(); return buffer.toString();

View file

@ -23,12 +23,12 @@ public class ScannerContext implements IScannerContext
private int macroLength = -1; private int macroLength = -1;
private int line = 1; private int line = 1;
private int offset; private int offset;
private ContextKind kind; private int kind;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int, int) * @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int, int)
*/ */
public ScannerContext(Reader r, String f, ContextKind k, IASTInclusion i, int mO, int mL, int l) public ScannerContext(Reader r, String f, int k, IASTInclusion i, int mO, int mL, int l)
{ {
reader = r; reader = r;
filename = f; filename = f;
@ -43,7 +43,7 @@ public class ScannerContext implements IScannerContext
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion) * @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion)
*/ */
public ScannerContext(Reader r, String f, ContextKind k, IASTInclusion i) public ScannerContext(Reader r, String f, int k, IASTInclusion i)
{ {
this(r, f, k, i, -1, -1, 1); this(r, f, k, i, -1, -1, 1);
} }
@ -151,7 +151,7 @@ public class ScannerContext implements IScannerContext
* Returns the kind. * Returns the kind.
* @return int * @return int
*/ */
public ContextKind getKind() { public int getKind() {
return kind; return kind;
} }
@ -159,7 +159,7 @@ public class ScannerContext implements IScannerContext
* Sets the kind. * Sets the kind.
* @param kind The kind to set * @param kind The kind to set
*/ */
public void setKind(ContextKind kind) { public void setKind(int kind) {
this.kind = kind; this.kind = kind;
} }
/* (non-Javadoc) /* (non-Javadoc)