mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Patch for Andrew Niefer:
- Fixed Bug36316 Parser/Scanner in infinite loop
This commit is contained in:
parent
080e040924
commit
0c47e3bed5
5 changed files with 299 additions and 177 deletions
|
@ -0,0 +1,130 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2003 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v0.5
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v05.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corp. - Rational Software - initial implementation
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.internal.core.parser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aniefer
|
||||||
|
*
|
||||||
|
* To change the template for this generated type comment go to
|
||||||
|
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||||
|
*/
|
||||||
|
public class ContextStack {
|
||||||
|
|
||||||
|
public ContextStack(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateContext(Reader reader, String filename, int type) throws ScannerException {
|
||||||
|
undoStack.clear();
|
||||||
|
|
||||||
|
push( new ScannerContext().initialize(reader, filename, type ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void push( IScannerContext context ) throws ScannerException
|
||||||
|
{
|
||||||
|
if( context.getKind() == IScannerContext.INCLUSION )
|
||||||
|
{
|
||||||
|
if( !inclusions.add( context.getFilename() ) )
|
||||||
|
throw new ScannerException( "Inclusion " + context.getFilename() + " already encountered." );
|
||||||
|
} else if( context.getKind() == IScannerContext.MACROEXPANSION )
|
||||||
|
{
|
||||||
|
if( !defines.add( context.getFilename() ) )
|
||||||
|
throw new ScannerException( "Define " + context.getFilename() + " already encountered." );
|
||||||
|
}
|
||||||
|
if( currentContext != null )
|
||||||
|
contextStack.push(currentContext);
|
||||||
|
|
||||||
|
currentContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean rollbackContext() {
|
||||||
|
try {
|
||||||
|
currentContext.getReader().close();
|
||||||
|
} catch (IOException ie) {
|
||||||
|
System.out.println("Error closing reader");
|
||||||
|
}
|
||||||
|
|
||||||
|
if( currentContext.getKind() == IScannerContext.INCLUSION )
|
||||||
|
{
|
||||||
|
inclusions.remove( currentContext.getFilename() );
|
||||||
|
} else if( currentContext.getKind() == IScannerContext.MACROEXPANSION )
|
||||||
|
{
|
||||||
|
defines.remove( currentContext.getFilename() );
|
||||||
|
}
|
||||||
|
|
||||||
|
undoStack.addFirst( currentContext );
|
||||||
|
|
||||||
|
if (contextStack.isEmpty()) {
|
||||||
|
currentContext = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentContext = (ScannerContext) contextStack.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void undoRollback( IScannerContext undoTo ) throws ScannerException {
|
||||||
|
if( currentContext == undoTo ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = undoStack.size();
|
||||||
|
if( size > 0 )
|
||||||
|
{
|
||||||
|
Iterator iter = undoStack.iterator();
|
||||||
|
for( int i = size; i > 0; i-- )
|
||||||
|
{
|
||||||
|
push( (IScannerContext) undoStack.removeFirst() );
|
||||||
|
|
||||||
|
if( currentContext == undoTo )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param symbol
|
||||||
|
* @return boolean, whether or not we should expand this definition
|
||||||
|
*
|
||||||
|
* 16.3.4-2 If the name of the macro being replaced is found during
|
||||||
|
* this scan of the replacement list it is not replaced. Further, if
|
||||||
|
* any nested replacements encounter the name of the macro being replaced,
|
||||||
|
* it is not replaced.
|
||||||
|
*/
|
||||||
|
protected boolean shouldExpandDefinition( String symbol )
|
||||||
|
{
|
||||||
|
return !defines.contains( symbol );
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScannerContext getCurrentContext(){
|
||||||
|
return currentContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IScannerContext currentContext;
|
||||||
|
|
||||||
|
private Stack contextStack = new Stack();
|
||||||
|
private LinkedList undoStack = new LinkedList();
|
||||||
|
|
||||||
|
|
||||||
|
private Set inclusions = new HashSet();
|
||||||
|
private Set defines = new HashSet();
|
||||||
|
|
||||||
|
}
|
|
@ -18,12 +18,9 @@ import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
@ -40,18 +37,21 @@ public class Scanner implements IScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void init(Reader reader, String filename) {
|
protected void init(Reader reader, String filename) {
|
||||||
// this is a hack to get around a sudden EOF experience
|
try {
|
||||||
contextStack.push(
|
//this is a hack to get around a sudden EOF experience
|
||||||
new ScannerContext().initialize(
|
contextStack.push(
|
||||||
new StringReader("\n"),
|
new ScannerContext().initialize(
|
||||||
START,
|
new StringReader("\n"),
|
||||||
ScannerContext.SENTINEL));
|
START,
|
||||||
if (filename == null)
|
ScannerContext.SENTINEL));
|
||||||
currentContext =
|
|
||||||
new ScannerContext().initialize(reader, TEXT, ScannerContext.TOP );
|
if (filename == null)
|
||||||
else
|
contextStack.push( new ScannerContext().initialize(reader, TEXT, ScannerContext.TOP ) );
|
||||||
currentContext =
|
else
|
||||||
new ScannerContext().initialize(reader, filename, ScannerContext.TOP );
|
contextStack.push( new ScannerContext().initialize(reader, filename, ScannerContext.TOP ) );
|
||||||
|
} catch( ScannerException se ) {
|
||||||
|
//won't happen since we aren't adding an include or a macro
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scanner() {
|
public Scanner() {
|
||||||
|
@ -62,42 +62,7 @@ public class Scanner implements IScanner {
|
||||||
definitions = defns;
|
definitions = defns;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, type );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean rollbackContext() {
|
|
||||||
try {
|
|
||||||
currentContext.getReader().close();
|
|
||||||
} catch (IOException ie) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentContext = (ScannerContext) contextStack.pop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addIncludePath(String includePath) {
|
public void addIncludePath(String includePath) {
|
||||||
includePathNames.add(includePath);
|
includePathNames.add(includePath);
|
||||||
|
@ -137,7 +102,7 @@ public class Scanner implements IScanner {
|
||||||
return includePathNames.toArray();
|
return includePathNames.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean skipOverWhitespace() {
|
protected boolean skipOverWhitespace() throws ScannerException {
|
||||||
int c = getChar();
|
int c = getChar();
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
while ((c != NOCHAR) && ((c == ' ') || (c == '\t')))
|
while ((c != NOCHAR) && ((c == ' ') || (c == '\t')))
|
||||||
|
@ -233,7 +198,7 @@ public class Scanner implements IScanner {
|
||||||
return currentToken;
|
return currentToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getNextIdentifier() {
|
protected String getNextIdentifier() throws ScannerException {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
skipOverWhitespace();
|
skipOverWhitespace();
|
||||||
int c = getChar();
|
int c = getChar();
|
||||||
|
@ -275,7 +240,7 @@ public class Scanner implements IScanner {
|
||||||
try {
|
try {
|
||||||
FileReader inclusionReader =
|
FileReader inclusionReader =
|
||||||
new FileReader(includeFile);
|
new FileReader(includeFile);
|
||||||
updateContext(inclusionReader, newPath, ScannerContext.INCLUSION );
|
contextStack.updateContext(inclusionReader, newPath, ScannerContext.INCLUSION );
|
||||||
return;
|
return;
|
||||||
} catch (FileNotFoundException fnf) {
|
} catch (FileNotFoundException fnf) {
|
||||||
// do nothing - check the next directory
|
// do nothing - check the next directory
|
||||||
|
@ -286,7 +251,7 @@ public class Scanner implements IScanner {
|
||||||
}
|
}
|
||||||
else // local inclusion
|
else // local inclusion
|
||||||
{
|
{
|
||||||
String currentFilename = currentContext.getFilename();
|
String currentFilename = contextStack.getCurrentContext().getFilename();
|
||||||
File currentIncludeFile = new File( currentFilename );
|
File currentIncludeFile = new File( currentFilename );
|
||||||
String parentDirectory = currentIncludeFile.getParent();
|
String parentDirectory = currentIncludeFile.getParent();
|
||||||
currentIncludeFile = null;
|
currentIncludeFile = null;
|
||||||
|
@ -296,7 +261,7 @@ public class Scanner implements IScanner {
|
||||||
try {
|
try {
|
||||||
FileReader inclusionReader =
|
FileReader inclusionReader =
|
||||||
new FileReader(includeFile);
|
new FileReader(includeFile);
|
||||||
updateContext(inclusionReader, fullPath, ScannerContext.INCLUSION );
|
contextStack.updateContext(inclusionReader, fullPath, ScannerContext.INCLUSION );
|
||||||
return;
|
return;
|
||||||
} catch (FileNotFoundException fnf) {
|
} catch (FileNotFoundException fnf) {
|
||||||
if (throwExceptionOnInclusionNotFound)
|
if (throwExceptionOnInclusionNotFound)
|
||||||
|
@ -321,14 +286,14 @@ public class Scanner implements IScanner {
|
||||||
private static final String DEFINED = "defined";
|
private static final String DEFINED = "defined";
|
||||||
private static final String POUND_DEFINE = "#define ";
|
private static final String POUND_DEFINE = "#define ";
|
||||||
|
|
||||||
private IScannerContext currentContext;
|
private ContextStack contextStack = new ContextStack();
|
||||||
private Stack contextStack = new Stack();
|
private IScannerContext lastContext = null;
|
||||||
|
|
||||||
private List includePathNames = new ArrayList();
|
private List includePathNames = new ArrayList();
|
||||||
private List includePaths = new ArrayList();
|
private List includePaths = new ArrayList();
|
||||||
private Hashtable definitions = new Hashtable();
|
private Hashtable definitions = new Hashtable();
|
||||||
private StringBuffer storageBuffer = null;
|
private StringBuffer storageBuffer = null;
|
||||||
private Set inclusions = new HashSet();
|
|
||||||
private int count = 0;
|
private int count = 0;
|
||||||
private static HashMap keywords = new HashMap();
|
private static HashMap keywords = new HashMap();
|
||||||
private static HashMap ppDirectives = new HashMap();
|
private static HashMap ppDirectives = new HashMap();
|
||||||
|
@ -367,7 +332,10 @@ public class Scanner implements IScanner {
|
||||||
|
|
||||||
private int getChar( boolean insideString ) {
|
private int getChar( boolean insideString ) {
|
||||||
int c = NOCHAR;
|
int c = NOCHAR;
|
||||||
if (currentContext == null)
|
|
||||||
|
lastContext = contextStack.getCurrentContext();
|
||||||
|
|
||||||
|
if (contextStack.getCurrentContext() == null)
|
||||||
// past the end of file
|
// past the end of file
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
@ -375,13 +343,13 @@ public class Scanner implements IScanner {
|
||||||
do {
|
do {
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
if (currentContext.undoStackSize() != 0 ) {
|
if (contextStack.getCurrentContext().undoStackSize() != 0 ) {
|
||||||
c = currentContext.popUndo();
|
c = contextStack.getCurrentContext().popUndo();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
c = currentContext.read();
|
c = contextStack.getCurrentContext().read();
|
||||||
if (c == NOCHAR) {
|
if (c == NOCHAR) {
|
||||||
if (rollbackContext() == false) {
|
if (contextStack.rollbackContext() == false) {
|
||||||
c = NOCHAR;
|
c = NOCHAR;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -389,7 +357,7 @@ public class Scanner implements IScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (rollbackContext() == false) {
|
if (contextStack.rollbackContext() == false) {
|
||||||
c = NOCHAR;
|
c = NOCHAR;
|
||||||
} else {
|
} else {
|
||||||
done = false;
|
done = false;
|
||||||
|
@ -413,13 +381,14 @@ public class Scanner implements IScanner {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ungetChar(int c) {
|
private void ungetChar(int c) throws ScannerException{
|
||||||
// Should really check whether there already is a char there
|
// Should really check whether there already is a char there
|
||||||
// If so, we should be using a buffer, instead of a single char
|
// If so, we should be using a buffer, instead of a single char
|
||||||
currentContext.pushUndo(c);
|
contextStack.getCurrentContext().pushUndo(c);
|
||||||
|
contextStack.undoRollback( lastContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean lookAheadForTokenPasting()
|
protected boolean lookAheadForTokenPasting() throws ScannerException
|
||||||
{
|
{
|
||||||
int c = getChar();
|
int c = getChar();
|
||||||
if( c == '#' )
|
if( c == '#' )
|
||||||
|
@ -526,7 +495,7 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
type,
|
type,
|
||||||
buff.toString(),
|
buff.toString(),
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (throwExceptionOnUnboundedString)
|
if (throwExceptionOnUnboundedString)
|
||||||
|
@ -563,9 +532,11 @@ public class Scanner implements IScanner {
|
||||||
Object mapping = definitions.get(ident);
|
Object mapping = definitions.get(ident);
|
||||||
|
|
||||||
if (mapping != null) {
|
if (mapping != null) {
|
||||||
expandDefinition(ident, mapping);
|
if( contextStack.shouldExpandDefinition( POUND_DEFINE + ident ) ) {
|
||||||
c = getChar();
|
expandDefinition(ident, mapping);
|
||||||
continue;
|
c = getChar();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object tokenTypeObject = keywords.get(ident);
|
Object tokenTypeObject = keywords.get(ident);
|
||||||
|
@ -590,7 +561,7 @@ public class Scanner implements IScanner {
|
||||||
if( storageBuffer != null )
|
if( storageBuffer != null )
|
||||||
{
|
{
|
||||||
storageBuffer.append( ident );
|
storageBuffer.append( ident );
|
||||||
updateContext( new StringReader( storageBuffer.toString()), PASTING, IScannerContext.MACROEXPANSION );
|
contextStack.updateContext( new StringReader( storageBuffer.toString()), PASTING, IScannerContext.MACROEXPANSION );
|
||||||
storageBuffer = null;
|
storageBuffer = null;
|
||||||
c = getChar();
|
c = getChar();
|
||||||
continue;
|
continue;
|
||||||
|
@ -598,7 +569,7 @@ public class Scanner implements IScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newToken(tokenType, ident, currentContext);
|
return newToken(tokenType, ident, contextStack.getCurrentContext());
|
||||||
} else if ((c >= '0') && (c <= '9') || c == '.' ) {
|
} else if ((c >= '0') && (c <= '9') || c == '.' ) {
|
||||||
StringBuffer buff;
|
StringBuffer buff;
|
||||||
|
|
||||||
|
@ -625,10 +596,10 @@ public class Scanner implements IScanner {
|
||||||
if( ! firstCharZero && floatingPoint )
|
if( ! firstCharZero && floatingPoint )
|
||||||
{
|
{
|
||||||
ungetChar( c );
|
ungetChar( c );
|
||||||
return newToken( Token.tDOT, ".", currentContext );
|
return newToken( Token.tDOT, ".", contextStack.getCurrentContext() );
|
||||||
}
|
}
|
||||||
else if( ! firstCharZero )
|
else if( ! firstCharZero )
|
||||||
throw new ScannerException( "Invalid Hexidecimal @ offset " + currentContext.getOffset() );
|
throw new ScannerException( "Invalid Hexidecimal @ offset " + contextStack.getCurrentContext().getOffset() );
|
||||||
|
|
||||||
hex = true;
|
hex = true;
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -647,7 +618,7 @@ public class Scanner implements IScanner {
|
||||||
if( floatingPoint || hex ) {
|
if( floatingPoint || hex ) {
|
||||||
if( buff.toString().equals( "..") && getChar() == '.' )
|
if( buff.toString().equals( "..") && getChar() == '.' )
|
||||||
return newToken( Token.tELIPSE, "..." );
|
return newToken( Token.tELIPSE, "..." );
|
||||||
throw new ScannerException( "Invalid floating point @ offset " + currentContext.getOffset() );
|
throw new ScannerException( "Invalid floating point @ offset " + contextStack.getCurrentContext().getOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
floatingPoint = true;
|
floatingPoint = true;
|
||||||
|
@ -705,7 +676,7 @@ public class Scanner implements IScanner {
|
||||||
{
|
{
|
||||||
if( storageBuffer != null )
|
if( storageBuffer != null )
|
||||||
{
|
{
|
||||||
updateContext( new StringReader( buff.toString()), PASTING, IScannerContext.MACROEXPANSION );
|
contextStack.updateContext( new StringReader( buff.toString()), PASTING, IScannerContext.MACROEXPANSION );
|
||||||
storageBuffer = null;
|
storageBuffer = null;
|
||||||
c = getChar();
|
c = getChar();
|
||||||
continue;
|
continue;
|
||||||
|
@ -724,10 +695,10 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
tokenType,
|
tokenType,
|
||||||
result,
|
result,
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
|
|
||||||
} else if (c == '#') {
|
} else if (c == '#') {
|
||||||
int beginningOffset = currentContext.getOffset() - 1;
|
int beginningOffset = contextStack.getCurrentContext().getOffset() - 1;
|
||||||
// lets prepare for a preprocessor statement
|
// lets prepare for a preprocessor statement
|
||||||
StringBuffer buff = new StringBuffer();
|
StringBuffer buff = new StringBuffer();
|
||||||
buff.append((char) c);
|
buff.append((char) c);
|
||||||
|
@ -740,7 +711,7 @@ public class Scanner implements IScanner {
|
||||||
if( c == '#' )
|
if( c == '#' )
|
||||||
{
|
{
|
||||||
if( skipped )
|
if( skipped )
|
||||||
throw new ScannerException(BAD_PP + currentContext.getOffset());
|
throw new ScannerException(BAD_PP + contextStack.getCurrentContext().getOffset());
|
||||||
else
|
else
|
||||||
return newToken( tPOUNDPOUND, "##" );
|
return newToken( tPOUNDPOUND, "##" );
|
||||||
}
|
}
|
||||||
|
@ -758,7 +729,7 @@ public class Scanner implements IScanner {
|
||||||
if (directive == null) {
|
if (directive == null) {
|
||||||
if (throwExceptionOnBadPreprocessorSyntax)
|
if (throwExceptionOnBadPreprocessorSyntax)
|
||||||
throw new ScannerException(
|
throw new ScannerException(
|
||||||
BAD_PP + currentContext.getOffset());
|
BAD_PP + contextStack.getCurrentContext().getOffset());
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -832,7 +803,7 @@ public class Scanner implements IScanner {
|
||||||
case PreprocessorDirectives.ENDIF :
|
case PreprocessorDirectives.ENDIF :
|
||||||
String restOfLine = getRestOfPreprocessorLine().trim();
|
String restOfLine = getRestOfPreprocessorLine().trim();
|
||||||
if( ! restOfLine.equals( "" ) && throwExceptionOnBadPreprocessorSyntax )
|
if( ! restOfLine.equals( "" ) && throwExceptionOnBadPreprocessorSyntax )
|
||||||
throw new ScannerException( BAD_PP + currentContext.getOffset() );
|
throw new ScannerException( BAD_PP + contextStack.getCurrentContext().getOffset() );
|
||||||
passOnToClient = branches.poundendif();
|
passOnToClient = branches.poundendif();
|
||||||
c = getChar();
|
c = getChar();
|
||||||
continue;
|
continue;
|
||||||
|
@ -905,7 +876,7 @@ public class Scanner implements IScanner {
|
||||||
if (!remainderOfLine.equals("")) {
|
if (!remainderOfLine.equals("")) {
|
||||||
if (throwExceptionOnBadPreprocessorSyntax)
|
if (throwExceptionOnBadPreprocessorSyntax)
|
||||||
throw new ScannerException(
|
throw new ScannerException(
|
||||||
BAD_PP + currentContext.getOffset());
|
BAD_PP + contextStack.getCurrentContext().getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -913,7 +884,7 @@ public class Scanner implements IScanner {
|
||||||
default :
|
default :
|
||||||
if (throwExceptionOnBadPreprocessorSyntax)
|
if (throwExceptionOnBadPreprocessorSyntax)
|
||||||
throw new ScannerException(
|
throw new ScannerException(
|
||||||
BAD_PP + currentContext.getOffset());
|
BAD_PP + contextStack.getCurrentContext().getOffset());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -923,10 +894,10 @@ public class Scanner implements IScanner {
|
||||||
c = getChar();
|
c = getChar();
|
||||||
int next = getChar();
|
int next = getChar();
|
||||||
if( next == '\'' )
|
if( next == '\'' )
|
||||||
return newToken( Token.tCHAR, new Character( (char)c ).toString(), currentContext );
|
return newToken( Token.tCHAR, new Character( (char)c ).toString(), contextStack.getCurrentContext() );
|
||||||
else
|
else
|
||||||
if( throwExceptionOnBadCharacterRead )
|
if( throwExceptionOnBadCharacterRead )
|
||||||
throw new ScannerException( "Invalid character '" + (char)c + "' read @ offset " + currentContext.getOffset() + " of file " + currentContext.getFilename() );
|
throw new ScannerException( "Invalid character '" + (char)c + "' read @ offset " + contextStack.getCurrentContext().getOffset() + " of file " + contextStack.getCurrentContext().getFilename() );
|
||||||
case ':' :
|
case ':' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -934,32 +905,32 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tCOLONCOLON,
|
Token.tCOLONCOLON,
|
||||||
"::",
|
"::",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tCOLON,
|
Token.tCOLON,
|
||||||
":",
|
":",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case ';' :
|
case ';' :
|
||||||
return newToken(Token.tSEMI, ";", currentContext);
|
return newToken(Token.tSEMI, ";", contextStack.getCurrentContext());
|
||||||
case ',' :
|
case ',' :
|
||||||
return newToken(Token.tCOMMA, ",", currentContext);
|
return newToken(Token.tCOMMA, ",", contextStack.getCurrentContext());
|
||||||
case '?' :
|
case '?' :
|
||||||
return newToken(Token.tQUESTION, "?", currentContext);
|
return newToken(Token.tQUESTION, "?", contextStack.getCurrentContext());
|
||||||
case '(' :
|
case '(' :
|
||||||
return newToken(Token.tLPAREN, "(", currentContext);
|
return newToken(Token.tLPAREN, "(", contextStack.getCurrentContext());
|
||||||
case ')' :
|
case ')' :
|
||||||
return newToken(Token.tRPAREN, ")", currentContext);
|
return newToken(Token.tRPAREN, ")", contextStack.getCurrentContext());
|
||||||
case '[' :
|
case '[' :
|
||||||
return newToken(Token.tLBRACKET, "[", currentContext);
|
return newToken(Token.tLBRACKET, "[", contextStack.getCurrentContext());
|
||||||
case ']' :
|
case ']' :
|
||||||
return newToken(Token.tRBRACKET, "]", currentContext);
|
return newToken(Token.tRBRACKET, "]", contextStack.getCurrentContext());
|
||||||
case '{' :
|
case '{' :
|
||||||
return newToken(Token.tLBRACE, "{", currentContext);
|
return newToken(Token.tLBRACE, "{", contextStack.getCurrentContext());
|
||||||
case '}' :
|
case '}' :
|
||||||
return newToken(Token.tRBRACE, "}", currentContext);
|
return newToken(Token.tRBRACE, "}", contextStack.getCurrentContext());
|
||||||
case '+' :
|
case '+' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -967,18 +938,18 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tPLUSASSIGN,
|
Token.tPLUSASSIGN,
|
||||||
"+=",
|
"+=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
case '+' :
|
case '+' :
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tINCR,
|
Token.tINCR,
|
||||||
"++",
|
"++",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tPLUS,
|
Token.tPLUS,
|
||||||
"+",
|
"+",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '-' :
|
case '-' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -987,12 +958,12 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tMINUSASSIGN,
|
Token.tMINUSASSIGN,
|
||||||
"-=",
|
"-=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
case '-' :
|
case '-' :
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tDECR,
|
Token.tDECR,
|
||||||
"--",
|
"--",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
case '>' :
|
case '>' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -1000,20 +971,20 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tARROWSTAR,
|
Token.tARROWSTAR,
|
||||||
"->*",
|
"->*",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tARROW,
|
Token.tARROW,
|
||||||
"->",
|
"->",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tMINUS,
|
Token.tMINUS,
|
||||||
"-",
|
"-",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '*' :
|
case '*' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1022,13 +993,13 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tSTARASSIGN,
|
Token.tSTARASSIGN,
|
||||||
"*=",
|
"*=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tSTAR,
|
Token.tSTAR,
|
||||||
"*",
|
"*",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '%' :
|
case '%' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1037,13 +1008,13 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tMODASSIGN,
|
Token.tMODASSIGN,
|
||||||
"%=",
|
"%=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tMOD,
|
Token.tMOD,
|
||||||
"%",
|
"%",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '^' :
|
case '^' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1052,13 +1023,13 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tXORASSIGN,
|
Token.tXORASSIGN,
|
||||||
"^=",
|
"^=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tXOR,
|
Token.tXOR,
|
||||||
"^",
|
"^",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '&' :
|
case '&' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1067,18 +1038,18 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tAMPERASSIGN,
|
Token.tAMPERASSIGN,
|
||||||
"&=",
|
"&=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
case '&' :
|
case '&' :
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tAND,
|
Token.tAND,
|
||||||
"&&",
|
"&&",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tAMPER,
|
Token.tAMPER,
|
||||||
"&",
|
"&",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '|' :
|
case '|' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1087,21 +1058,21 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tBITORASSIGN,
|
Token.tBITORASSIGN,
|
||||||
"|=",
|
"|=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
case '|' :
|
case '|' :
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tOR,
|
Token.tOR,
|
||||||
"||",
|
"||",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tBITOR,
|
Token.tBITOR,
|
||||||
"|",
|
"|",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '~' :
|
case '~' :
|
||||||
return newToken(Token.tCOMPL, "~", currentContext);
|
return newToken(Token.tCOMPL, "~", contextStack.getCurrentContext());
|
||||||
case '!' :
|
case '!' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -1109,13 +1080,13 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tNOTEQUAL,
|
Token.tNOTEQUAL,
|
||||||
"!=",
|
"!=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tNOT,
|
Token.tNOT,
|
||||||
"!",
|
"!",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '=' :
|
case '=' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1124,13 +1095,13 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tEQUAL,
|
Token.tEQUAL,
|
||||||
"==",
|
"==",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tASSIGN,
|
Token.tASSIGN,
|
||||||
"=",
|
"=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '<' :
|
case '<' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1142,22 +1113,22 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tSHIFTLASSIGN,
|
Token.tSHIFTLASSIGN,
|
||||||
"<<=",
|
"<<=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tSHIFTL,
|
Token.tSHIFTL,
|
||||||
"<<",
|
"<<",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '=' :
|
case '=' :
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tLTEQUAL,
|
Token.tLTEQUAL,
|
||||||
"<=",
|
"<=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(Token.tLT, "<", currentContext);
|
return newToken(Token.tLT, "<", contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '>' :
|
case '>' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1169,22 +1140,22 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tSHIFTRASSIGN,
|
Token.tSHIFTRASSIGN,
|
||||||
">>=",
|
">>=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tSHIFTR,
|
Token.tSHIFTR,
|
||||||
">>",
|
">>",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '=' :
|
case '=' :
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tGTEQUAL,
|
Token.tGTEQUAL,
|
||||||
">=",
|
">=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(Token.tGT, ">", currentContext);
|
return newToken(Token.tGT, ">", contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
case '.' :
|
case '.' :
|
||||||
c = getChar();
|
c = getChar();
|
||||||
|
@ -1196,7 +1167,7 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tELIPSE,
|
Token.tELIPSE,
|
||||||
"...",
|
"...",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1205,13 +1176,13 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tDOTSTAR,
|
Token.tDOTSTAR,
|
||||||
".*",
|
".*",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tDOT,
|
Token.tDOT,
|
||||||
".",
|
".",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '/' :
|
case '/' :
|
||||||
|
@ -1230,18 +1201,18 @@ public class Scanner implements IScanner {
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tDIVASSIGN,
|
Token.tDIVASSIGN,
|
||||||
"/=",
|
"/=",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
default :
|
default :
|
||||||
ungetChar(c);
|
ungetChar(c);
|
||||||
return newToken(
|
return newToken(
|
||||||
Token.tDIV,
|
Token.tDIV,
|
||||||
"/",
|
"/",
|
||||||
currentContext);
|
contextStack.getCurrentContext());
|
||||||
}
|
}
|
||||||
default :
|
default :
|
||||||
// Bad character
|
// Bad character
|
||||||
if( throwExceptionOnBadCharacterRead )
|
if( throwExceptionOnBadCharacterRead )
|
||||||
throw new ScannerException( "Invalid character '" + (char)c + "' read @ offset " + currentContext.getOffset() + " of file " + currentContext.getFilename() );
|
throw new ScannerException( "Invalid character '" + (char)c + "' read @ offset " + contextStack.getCurrentContext().getOffset() + " of file " + contextStack.getCurrentContext().getFilename() );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c = ' ';
|
c = ' ';
|
||||||
|
@ -1509,7 +1480,7 @@ public class Scanner implements IScanner {
|
||||||
{
|
{
|
||||||
if( callback != null )
|
if( callback != null )
|
||||||
{
|
{
|
||||||
offset = currentContext.getOffset() - f.length() - 1; // -1 for the end quote
|
offset = contextStack.getCurrentContext().getOffset() - f.length() - 1; // -1 for the end quote
|
||||||
|
|
||||||
callback.inclusionBegin( f, offset, beginningOffset );
|
callback.inclusionBegin( f, offset, beginningOffset );
|
||||||
callback.inclusionEnd();
|
callback.inclusionEnd();
|
||||||
|
@ -1523,7 +1494,7 @@ public class Scanner implements IScanner {
|
||||||
skipOverWhitespace();
|
skipOverWhitespace();
|
||||||
// definition
|
// definition
|
||||||
String key = getNextIdentifier();
|
String key = getNextIdentifier();
|
||||||
int offset = currentContext.getOffset() - key.length() - currentContext.undoStackSize();
|
int offset = contextStack.getCurrentContext().getOffset() - key.length() - contextStack.getCurrentContext().undoStackSize();
|
||||||
|
|
||||||
if (!quickScan) {
|
if (!quickScan) {
|
||||||
String checkForRedefinition = (String) definitions.get(key);
|
String checkForRedefinition = (String) definitions.get(key);
|
||||||
|
@ -1617,24 +1588,24 @@ public class Scanner implements IScanner {
|
||||||
// it is a bad statement
|
// it is a bad statement
|
||||||
if (throwExceptionOnBadPreprocessorSyntax)
|
if (throwExceptionOnBadPreprocessorSyntax)
|
||||||
throw new ScannerException(
|
throw new ScannerException(
|
||||||
BAD_PP + currentContext.getOffset());
|
BAD_PP + contextStack.getCurrentContext().getOffset());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Unexpected character " + ((char) c));
|
System.out.println("Unexpected character " + ((char) c));
|
||||||
if (throwExceptionOnBadPreprocessorSyntax)
|
if (throwExceptionOnBadPreprocessorSyntax)
|
||||||
throw new ScannerException(BAD_PP + currentContext.getOffset());
|
throw new ScannerException(BAD_PP + contextStack.getCurrentContext().getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// call the callback accordingly
|
// call the callback accordingly
|
||||||
if( callback != null )
|
if( callback != null )
|
||||||
callback.macro( key, offset, beginning, currentContext.getOffset() );
|
callback.macro( key, offset, beginning, contextStack.getCurrentContext().getOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void expandDefinition(String symbol, Object expansion)
|
protected void expandDefinition(String symbol, Object expansion)
|
||||||
throws ScannerException {
|
throws ScannerException {
|
||||||
if (expansion instanceof String ) {
|
if (expansion instanceof String ) {
|
||||||
String replacementValue = (String) expansion;
|
String replacementValue = (String) expansion;
|
||||||
updateContext( new StringReader(replacementValue), (POUND_DEFINE + symbol ), ScannerContext.MACROEXPANSION );
|
contextStack.updateContext( new StringReader(replacementValue), (POUND_DEFINE + symbol ), ScannerContext.MACROEXPANSION );
|
||||||
} else if (expansion instanceof IMacroDescriptor ) {
|
} else if (expansion instanceof IMacroDescriptor ) {
|
||||||
IMacroDescriptor macro = (IMacroDescriptor) expansion;
|
IMacroDescriptor macro = (IMacroDescriptor) expansion;
|
||||||
skipOverWhitespace();
|
skipOverWhitespace();
|
||||||
|
@ -1710,7 +1681,7 @@ public class Scanner implements IScanner {
|
||||||
buffer.append( " " );
|
buffer.append( " " );
|
||||||
}
|
}
|
||||||
String finalString = buffer.toString();
|
String finalString = buffer.toString();
|
||||||
updateContext(
|
contextStack.updateContext(
|
||||||
new StringReader(finalString),
|
new StringReader(finalString),
|
||||||
POUND_DEFINE + macro.getSignature(), ScannerContext.MACROEXPANSION );
|
POUND_DEFINE + macro.getSignature(), ScannerContext.MACROEXPANSION );
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2003-04-11 Andrew Niefer
|
||||||
|
Moved ScannerFailedTest::testBug36316 to ScannerTestCase::testBug36316
|
||||||
|
Added ScannerFailedTest::testBug36047
|
||||||
|
Added ScannerTestCase::testNestedRecursiveDefines
|
||||||
|
|
||||||
2003-04-10 John Camelon
|
2003-04-10 John Camelon
|
||||||
Added DOMTests::testBug36237().
|
Added DOMTests::testBug36237().
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,14 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.core.parser.failedTests;
|
package org.eclipse.cdt.core.parser.failedTests;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.tests.ScannerTestCase;
|
import org.eclipse.cdt.core.parser.tests.ScannerTestCase;
|
||||||
|
import org.eclipse.cdt.internal.core.parser.ScannerException;
|
||||||
import org.eclipse.cdt.internal.core.parser.Token;
|
import org.eclipse.cdt.internal.core.parser.Token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,29 +37,34 @@ public class ScannerFailedTest extends ScannerTestCase {
|
||||||
{
|
{
|
||||||
TestSuite suite = new TestSuite();
|
TestSuite suite = new TestSuite();
|
||||||
|
|
||||||
suite.addTest( new ScannerFailedTest( "testBug36316" ) );
|
suite.addTest( new ScannerFailedTest( "testBug36047" ) );
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBug36316() throws Exception
|
public void testBug36047() throws Exception
|
||||||
{
|
{
|
||||||
|
boolean testPassed = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
initializeScanner( "#define A B->A\nA" );
|
StringWriter writer = new StringWriter();
|
||||||
|
writer.write( "# define MAD_VERSION_STRINGIZE(str) #str\n" );
|
||||||
|
writer.write( "# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)\n" );
|
||||||
|
writer.write( "# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) \".\"\n" );
|
||||||
|
initializeScanner( writer.toString() );
|
||||||
|
validateEOF();
|
||||||
|
|
||||||
|
testPassed = true;
|
||||||
|
|
||||||
validateIdentifier("B");
|
|
||||||
validateDefinition("A", "B->A");
|
|
||||||
validateToken(Token.tARROW);
|
|
||||||
validateIdentifier("A");
|
|
||||||
validateEOF();
|
|
||||||
|
|
||||||
fail( "This test was expected to fail." );
|
|
||||||
} catch( Throwable e )
|
|
||||||
{
|
|
||||||
if( !( e instanceof AssertionFailedError ) ){
|
|
||||||
fail( "Unexpected failure" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch( ScannerException se )
|
||||||
|
{
|
||||||
|
if( !se.getMessage().equals( "Invalid preprocessor directive encountered at offset 5" ) ){
|
||||||
|
fail( "Unexpected Error: " + se.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( testPassed )
|
||||||
|
fail( "The expected error did not occur." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1192,23 +1192,6 @@ public class ScannerTestCase extends TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void testBug36047()
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// StringWriter writer = new StringWriter();
|
|
||||||
// writer.write( "# define MAD_VERSION_STRINGIZE(str) #str\n" );
|
|
||||||
// writer.write( "# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)\n" );
|
|
||||||
// writer.write( "# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) \".\"\n" );
|
|
||||||
// initializeScanner( writer.toString() );
|
|
||||||
// validateEOF();
|
|
||||||
// }
|
|
||||||
// catch( ScannerException se )
|
|
||||||
// {
|
|
||||||
// fail( EXCEPTION_THROWN + se.toString() );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void testBug36045() throws Exception
|
public void testBug36045() throws Exception
|
||||||
{
|
{
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
@ -1294,4 +1277,29 @@ public class ScannerTestCase extends TestCase
|
||||||
fail(EXCEPTION_THROWN + se.toString());
|
fail(EXCEPTION_THROWN + se.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNestedRecursiveDefines() throws Exception
|
||||||
|
{
|
||||||
|
initializeScanner( "#define C B A\n#define B C C\n#define A B\nA" );
|
||||||
|
|
||||||
|
validateIdentifier("B");
|
||||||
|
validateDefinition("A", "B");
|
||||||
|
validateDefinition("B", "C C");
|
||||||
|
validateDefinition("C", "B A");
|
||||||
|
validateIdentifier("A");
|
||||||
|
validateIdentifier("B");
|
||||||
|
validateIdentifier("A");
|
||||||
|
validateEOF();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBug36316() throws Exception
|
||||||
|
{
|
||||||
|
initializeScanner( "#define A B->A\nA" );
|
||||||
|
|
||||||
|
validateIdentifier("B");
|
||||||
|
validateDefinition("A", "B->A");
|
||||||
|
validateToken(Token.tARROW);
|
||||||
|
validateIdentifier("A");
|
||||||
|
validateEOF();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue