mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
fix bug 72537: [Parser] environment macros with pararmeters are not respected by the parser
This commit is contained in:
parent
1d222d0636
commit
f6bae1949b
2 changed files with 82 additions and 40 deletions
|
@ -1859,4 +1859,15 @@ public class Scanner2Test extends BaseScanner2Test
|
||||||
validateToken( IToken.tSEMI );
|
validateToken( IToken.tSEMI );
|
||||||
validateEOF();
|
validateEOF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug72537() throws Exception
|
||||||
|
{
|
||||||
|
initializeScanner( "FOO BAR(boo)" ); //$NON-NLS-1$
|
||||||
|
scanner.addDefinition( "FOO".toCharArray(), "foo".toCharArray() ); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
scanner.addDefinition( "BAR(x)".toCharArray(), "x".toCharArray() ); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
|
||||||
|
validateIdentifier( "foo" ); //$NON-NLS-1$
|
||||||
|
validateIdentifier( "boo" ); //$NON-NLS-1$
|
||||||
|
validateEOF();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,7 +300,24 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
* @see org.eclipse.cdt.core.parser.IScanner#addDefinition(java.lang.String, java.lang.String)
|
* @see org.eclipse.cdt.core.parser.IScanner#addDefinition(java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public void addDefinition(char[] key, char[] value) {
|
public void addDefinition(char[] key, char[] value) {
|
||||||
|
int idx = CharArrayUtils.indexOf( '(', key );
|
||||||
|
if( idx == -1 )
|
||||||
definitions.put(key, new ObjectStyleMacro(key, value ));
|
definitions.put(key, new ObjectStyleMacro(key, value ));
|
||||||
|
else {
|
||||||
|
pushContext( key );
|
||||||
|
bufferPos[ bufferStackPos ] = idx;
|
||||||
|
char[][] args = null;
|
||||||
|
try{
|
||||||
|
args = extractMacroParameters( 0, EMPTY_STRING_CHAR_ARRAY, false );
|
||||||
|
} finally{
|
||||||
|
popContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( args != null ){
|
||||||
|
key = CharArrayUtils.extract( key, 0, idx );
|
||||||
|
definitions.put( key, new FunctionStyleMacro( key, value, args ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -1687,44 +1704,9 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
int pos = bufferPos[bufferStackPos];
|
int pos = bufferPos[bufferStackPos];
|
||||||
if (pos + 1 < limit && buffer[pos + 1] == '(') {
|
if (pos + 1 < limit && buffer[pos + 1] == '(') {
|
||||||
++bufferPos[bufferStackPos];
|
++bufferPos[bufferStackPos];
|
||||||
arglist = new char[4][];
|
arglist = extractMacroParameters( idstart, name, true );
|
||||||
int currarg = -1;
|
if( arglist == null )
|
||||||
while (bufferPos[bufferStackPos] < limit) {
|
|
||||||
pos = bufferPos[bufferStackPos];
|
|
||||||
skipOverWhiteSpace();
|
|
||||||
if (++bufferPos[bufferStackPos] >= limit)
|
|
||||||
return;
|
return;
|
||||||
c = buffer[bufferPos[bufferStackPos]];
|
|
||||||
if (c == ')') {
|
|
||||||
break;
|
|
||||||
} else if (c == ',') {
|
|
||||||
continue;
|
|
||||||
} else if (c == '.'
|
|
||||||
&& pos + 1 < limit && buffer[pos + 1] == '.'
|
|
||||||
&& pos + 2 < limit && buffer[pos + 2] == '.') {
|
|
||||||
// varargs
|
|
||||||
// TODO - something better
|
|
||||||
bufferPos[bufferStackPos] += 2;
|
|
||||||
arglist[++currarg] = "...".toCharArray(); //$NON-NLS-1$
|
|
||||||
continue;
|
|
||||||
} else if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || Character.isUnicodeIdentifierPart(c))) {
|
|
||||||
handleProblem( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, idstart, name );
|
|
||||||
// yuck
|
|
||||||
skipToNewLine();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int argstart = bufferPos[bufferStackPos];
|
|
||||||
skipOverIdentifier();
|
|
||||||
if (++currarg == arglist.length) {
|
|
||||||
char[][] oldarglist = arglist;
|
|
||||||
arglist = new char[oldarglist.length * 2][];
|
|
||||||
System.arraycopy(oldarglist, 0, arglist, 0, oldarglist.length);
|
|
||||||
}
|
|
||||||
int arglen = bufferPos[bufferStackPos] - argstart + 1;
|
|
||||||
char[] arg = new char[arglen];
|
|
||||||
System.arraycopy(buffer, argstart, arg, 0, arglen);
|
|
||||||
arglist[currarg] = arg;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture the replacement text
|
// Capture the replacement text
|
||||||
|
@ -1790,7 +1772,56 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, getCurrentFilename() ) );
|
pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, getCurrentFilename() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private char[][] extractMacroParameters( int idstart, char[] name, boolean reportProblems ){
|
||||||
|
char[] buffer = bufferStack[bufferStackPos];
|
||||||
|
int limit = bufferLimit[bufferStackPos];
|
||||||
|
|
||||||
|
if( bufferPos[bufferStackPos] >= limit || buffer[bufferPos[bufferStackPos]] != '(' )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
char c;
|
||||||
|
char[][] arglist = new char[4][];
|
||||||
|
int currarg = -1;
|
||||||
|
while (bufferPos[bufferStackPos] < limit) {
|
||||||
|
int pos = bufferPos[bufferStackPos];
|
||||||
|
skipOverWhiteSpace();
|
||||||
|
if (++bufferPos[bufferStackPos] >= limit)
|
||||||
|
return null;
|
||||||
|
c = buffer[bufferPos[bufferStackPos]];
|
||||||
|
if (c == ')') {
|
||||||
|
break;
|
||||||
|
} else if (c == ',') {
|
||||||
|
continue;
|
||||||
|
} else if (c == '.'
|
||||||
|
&& pos + 1 < limit && buffer[pos + 1] == '.'
|
||||||
|
&& pos + 2 < limit && buffer[pos + 2] == '.') {
|
||||||
|
// varargs
|
||||||
|
// TODO - something better
|
||||||
|
bufferPos[bufferStackPos] += 2;
|
||||||
|
arglist[++currarg] = "...".toCharArray(); //$NON-NLS-1$
|
||||||
|
continue;
|
||||||
|
} else if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || Character.isUnicodeIdentifierPart(c))) {
|
||||||
|
if( reportProblems )
|
||||||
|
handleProblem( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, idstart, name );
|
||||||
|
// yuck
|
||||||
|
skipToNewLine();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int argstart = bufferPos[bufferStackPos];
|
||||||
|
skipOverIdentifier();
|
||||||
|
if (++currarg == arglist.length) {
|
||||||
|
char[][] oldarglist = arglist;
|
||||||
|
arglist = new char[oldarglist.length * 2][];
|
||||||
|
System.arraycopy(oldarglist, 0, arglist, 0, oldarglist.length);
|
||||||
|
}
|
||||||
|
int arglen = bufferPos[bufferStackPos] - argstart + 1;
|
||||||
|
char[] arg = new char[arglen];
|
||||||
|
System.arraycopy(buffer, argstart, arg, 0, arglen);
|
||||||
|
arglist[currarg] = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return arglist;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param text
|
* @param text
|
||||||
* @return
|
* @return
|
||||||
|
|
Loading…
Add table
Reference in a new issue