1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Added undef support, including remove method for CharArrayMaps.

This commit is contained in:
Doug Schaefer 2004-06-17 15:25:34 +00:00
parent 13c9743ab8
commit e92ee9c4db
5 changed files with 305 additions and 21 deletions

View file

@ -54,7 +54,7 @@ public class Scanner2SpeedTest extends SpeedTest2 {
}
private void runTest(int n) throws Exception {
String code =
String code =
"#include <windows.h>\n" +
"#include <stdio.h>\n" +
"#include <iostream>\n";

View file

@ -1640,4 +1640,23 @@ public class Scanner2Test extends BaseScanner2Test
validateToken( IToken.tRBRACE);
validateEOF();
}
public void test__attribute__() throws Exception {
initializeScanner(
"#define __cdecl __attribute__((cdecl))\n" +
"__cdecl;");
validateToken(IToken.tSEMI);
validateEOF();
}
public void testUndef() throws Exception {
initializeScanner(
"#define A 5\n" +
"#define B 10\n" +
"#undef A\n" +
"A B");
validateIdentifier("A");
validateInteger("10");
validateEOF();
}
}

View file

@ -38,6 +38,10 @@ public abstract class CharArrayMap {
return CharArrayUtils.hash(buffer, start, len) & (keyTable.length - 1);
}
private int hash(char[] buffer) {
return hash(buffer, 0, buffer.length);
}
private void insert(int i) {
insert(i, hash(keyTable[i], 0, keyTable[i].length));
}
@ -124,6 +128,40 @@ public abstract class CharArrayMap {
return -1;
}
protected void removeEntry(int i) {
// Remove the hash entry
int hash = hash(keyTable[i]);
if (hashTable[hash] == i + 1)
hashTable[hash] = nextTable[i];
else {
// find entry pointing to me
int j = hashTable[hash] - 1;
while (nextTable[j] != 0 && nextTable[j] != i + 1)
j = nextTable[j] - 1;
nextTable[j] = nextTable[i];
}
if (i < currEntry) {
// shift everything over
System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i);
System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i);
// adjust hash and next entries for things that moved
for (int j = 0; j < hashTable.length; ++j)
if (hashTable[j] > i)
--hashTable[j];
for (int j = 0; j < nextTable.length; ++j)
if (nextTable[j] > i)
--nextTable[j];
}
// last entry is now free
keyTable[currEntry] = null;
nextTable[currEntry] = 0;
--currEntry;
}
public void dumpNexts() {
for (int i = 0; i < nextTable.length; ++i) {
if (nextTable[i] == 0)

View file

@ -52,4 +52,29 @@ public class CharArrayObjectMap extends CharArrayMap {
return get(key, 0, key.length);
}
public Object remove(char[] key, int start, int length) {
int i = lookup(key, start, length);
if (i < 0)
return null;
Object value = valueTable[i];
removeEntry(i);
return value;
}
public Object remove(char[] key) {
return remove(key, 0, key.length);
}
protected void removeEntry(int i) {
// Remove the entry from the valueTable, shifting everything over if necessary
if (i < currEntry)
System.arraycopy(valueTable, i + 1, valueTable, i, currEntry - i);
valueTable[currEntry] = null;
// Make sure you remove the value before calling super where currEntry will change
super.removeEntry(i);
}
}

View file

@ -52,7 +52,7 @@ public class Scanner2 implements IScanner, IScannerData {
protected IParserLogService log;
private IScannerExtension scannerExtension;
private List workingCopies;
private CharArrayObjectMap definitions;
private CharArrayObjectMap definitions = new CharArrayObjectMap(64);
private String[] includePaths;
int count;
@ -93,10 +93,11 @@ public class Scanner2 implements IScanner, IScannerData {
pushContext(reader.buffer, reader);
setupBuiltInMacros();
if (info.getDefinedSymbols() != null) {
Map symbols = info.getDefinedSymbols();
String[] keys = (String[])symbols.keySet().toArray(emptyStringArray);
definitions = new CharArrayObjectMap(symbols.size());
for (int i = 0; i < keys.length; ++i) {
String symbolName = (String)keys[i];
Object value = symbols.get(symbolName);
@ -107,8 +108,6 @@ public class Scanner2 implements IScanner, IScannerData {
} else if( value instanceof IMacroDescriptor )
addDefinition( symbolName, (IMacroDescriptor)value);
}
} else {
definitions = new CharArrayObjectMap(4);
}
includePaths = info.getIncludePaths();
@ -952,6 +951,9 @@ public class Scanner2 implements IScanner, IScannerData {
case ppDefine:
handlePPDefine();
return;
case ppUndef:
handlePPUndef();
return;
case ppIfdef:
handlePPIfdef(true);
return;
@ -1161,6 +1163,41 @@ public class Scanner2 implements IScanner, IScannerData {
: new FunctionStyleMacro(name, text, arglist));
}
private void handlePPUndef() {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
skipOverWhiteSpace();
// get the Identifier
int idstart = ++bufferPos[bufferStackPos];
if (idstart >= limit)
return;
char c = buffer[idstart];
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')) {
skipToNewLine();
return;
}
int idlen = 1;
while (++bufferPos[bufferStackPos] < limit) {
c = buffer[bufferPos[bufferStackPos]];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| c == '_' || (c >= '0' && c <= '9')) {
++idlen;
continue;
} else {
break;
}
}
--bufferPos[bufferStackPos];
skipToNewLine();
definitions.remove(buffer, idstart, idlen);
}
private void handlePPIfdef(boolean positive) {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
@ -1436,11 +1473,27 @@ public class Scanner2 implements IScanner, IScannerData {
return;
boolean escaped = false;
while (++bufferPos[bufferStackPos] < limit)
boolean inComment = false;
while (++bufferPos[bufferStackPos] < limit) {
switch (buffer[bufferPos[bufferStackPos]]) {
case '/':
pos = bufferPos[bufferStackPos];
if (pos + 1 < limit && buffer[pos + 1] == '*') {
++bufferPos[bufferStackPos];
while (++bufferPos[bufferStackPos] < limit) {
pos = bufferPos[bufferStackPos];
if (buffer[pos] == '*'
&& pos + 1 < limit
&& buffer[pos + 1] == '/') {
++bufferPos[bufferStackPos];
break;
}
}
}
break;
case '\\':
escaped = !escaped;
break;
continue;
case '\n':
if (escaped) {
escaped = false;
@ -1448,9 +1501,9 @@ public class Scanner2 implements IScanner, IScannerData {
} else {
return;
}
default:
escaped = false;
}
escaped = false;
}
}
private void handleFunctionStyleMacro(FunctionStyleMacro macro) {
@ -1464,7 +1517,6 @@ public class Scanner2 implements IScanner, IScannerData {
FunctionStyleMacro.Expansion exp = macro.new Expansion();
char[][] arglist = macro.arglist;
int currarg = -1;
int parens = 0;
while (bufferPos[bufferStackPos] < limit) {
if (++currarg >= arglist.length || arglist[currarg] == null)
@ -1476,22 +1528,14 @@ public class Scanner2 implements IScanner, IScannerData {
int pos = ++bufferPos[bufferStackPos];
char c = buffer[pos];
if (c == ')') {
if (parens == 0)
// end of macro
break;
else {
--parens;
continue;
}
// end of macro
break;
} else if (c == ',') {
// empty arg
exp.definitions.put(arglist[currarg], emptyCharArray);
continue;
} else if (c == '(') {
++parens;
continue;
}
// peel off the arg
--bufferPos[bufferStackPos];
int argend = bufferPos[bufferStackPos];
@ -1534,6 +1578,164 @@ public class Scanner2 implements IScanner, IScannerData {
pushContext(expText, exp);
}
// gcc built-ins
private static final ObjectStyleMacro __cplusplus
= new ObjectStyleMacro("__cplusplus".toCharArray(), "1".toCharArray());
private static final ObjectStyleMacro __STDC_HOSTED__
= new ObjectStyleMacro("__STDC_HOSTED__".toCharArray(), "0".toCharArray());
private static final ObjectStyleMacro __STDC_VERSION__
= new ObjectStyleMacro("__STDC_VERSION__".toCharArray(), "199001L".toCharArray());
private static final FunctionStyleMacro __attribute__
= new FunctionStyleMacro(
"__attribute__".toCharArray(),
emptyCharArray,
new char[][] { "arg".toCharArray() });
// standard built-ins
private static final ObjectStyleMacro __STDC__
= new ObjectStyleMacro("__STDC__".toCharArray(), "1".toCharArray());
protected void setupBuiltInMacros() {
// gcc extensions
if( language == ParserLanguage.CPP )
definitions.put(__cplusplus.name, __cplusplus);
definitions.put(__STDC_HOSTED__.name, __STDC_HOSTED__);
definitions.put(__STDC_VERSION__.name, __STDC_VERSION__);
definitions.put(__attribute__.name, __attribute__);
/*
// add these to private table
if( scannerData.getScanner().getDefinition( __ATTRIBUTE__) == null )
scannerData.getPrivateDefinitions().put( __ATTRIBUTE__, ATTRIBUTE_MACRO);
if( scannerData.getScanner().getDefinition( __DECLSPEC) == null )
scannerData.getPrivateDefinitions().put( __DECLSPEC, DECLSPEC_MACRO );
if( scannerData.getScanner().getDefinition( __EXTENSION__ ) == null )
scannerData.getPrivateDefinitions().put( __EXTENSION__, EXTENSION_MACRO);
if( scannerData.getScanner().getDefinition( __CONST__ ) == null )
scannerData.getPrivateDefinitions().put( __CONST__, __CONST__MACRO);
if( scannerData.getScanner().getDefinition( __CONST ) == null )
scannerData.getPrivateDefinitions().put( __CONST, __CONST_MACRO);
if( scannerData.getScanner().getDefinition( __INLINE__ ) == null )
scannerData.getPrivateDefinitions().put( __INLINE__, __INLINE__MACRO);
if( scannerData.getScanner().getDefinition( __SIGNED__ ) == null )
scannerData.getPrivateDefinitions().put( __SIGNED__, __SIGNED__MACRO);
if( scannerData.getScanner().getDefinition( __VOLATILE__ ) == null )
scannerData.getPrivateDefinitions().put( __VOLATILE__, __VOLATILE__MACRO);
ObjectMacroDescriptor __RESTRICT_MACRO = new ObjectMacroDescriptor( __RESTRICT, Keywords.RESTRICT );
if( scannerData.getScanner().getDefinition( __RESTRICT ) == null )
scannerData.getPrivateDefinitions().put( __RESTRICT, __RESTRICT_MACRO);
if( scannerData.getScanner().getDefinition( __RESTRICT__ ) == null )
scannerData.getPrivateDefinitions().put( __RESTRICT__, __RESTRICT__MACRO);
if( scannerData.getScanner().getDefinition( __TYPEOF__ ) == null )
scannerData.getPrivateDefinitions().put( __TYPEOF__, __TYPEOF__MACRO);
if( scannerData.getLanguage() == ParserLanguage.CPP )
if( scannerData.getScanner().getDefinition( __ASM__ ) == null )
scannerData.getPrivateDefinitions().put( __ASM__, __ASM__MACRO);
*/
// standard extensions
definitions.put(__STDC__.name, __STDC__);
/*
if( getDefinition(__STDC__) == null )
addDefinition( __STDC__, STDC_MACRO );
if( language == ParserLanguage.C )
{
if( getDefinition(__STDC_HOSTED__) == null )
addDefinition( __STDC_HOSTED__, STDC_HOSTED_MACRO);
if( getDefinition( __STDC_VERSION__) == null )
addDefinition( __STDC_VERSION__, STDC_VERSION_MACRO);
}
else
if( getDefinition( __CPLUSPLUS ) == null )
addDefinition( __CPLUSPLUS, CPLUSPLUS_MACRO); //$NON-NLS-1$
if( getDefinition(__FILE__) == null )
addDefinition( __FILE__,
new DynamicMacroDescriptor( __FILE__, new DynamicMacroEvaluator() {
public String execute() {
return contextStack.getMostRelevantFileContext().getContextName();
}
} ) );
if( getDefinition( __LINE__) == null )
addDefinition( __LINE__,
new DynamicMacroDescriptor( __LINE__, new DynamicMacroEvaluator() {
public String execute() {
return new Integer( contextStack.getCurrentLineNumber() ).toString();
}
} ) );
if( getDefinition( __DATE__ ) == null )
addDefinition( __DATE__,
new DynamicMacroDescriptor( __DATE__, new DynamicMacroEvaluator() {
public String getMonth()
{
if( Calendar.MONTH == Calendar.JANUARY ) return "Jan" ; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.FEBRUARY) return "Feb"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.MARCH) return "Mar"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.APRIL) return "Apr"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.MAY) return "May"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.JUNE) return "Jun"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.JULY) return "Jul"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.AUGUST) return "Aug"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.SEPTEMBER) return "Sep"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.OCTOBER) return "Oct"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.NOVEMBER) return "Nov"; //$NON-NLS-1$
if( Calendar.MONTH == Calendar.DECEMBER) return "Dec"; //$NON-NLS-1$
return ""; //$NON-NLS-1$
}
public String execute() {
StringBuffer result = new StringBuffer();
result.append( getMonth() );
result.append(" "); //$NON-NLS-1$
if( Calendar.DAY_OF_MONTH < 10 )
result.append(" "); //$NON-NLS-1$
result.append(Calendar.DAY_OF_MONTH);
result.append(" "); //$NON-NLS-1$
result.append( Calendar.YEAR );
return result.toString();
}
} ) );
if( getDefinition( __TIME__) == null )
addDefinition( __TIME__,
new DynamicMacroDescriptor( __TIME__, new DynamicMacroEvaluator() {
public String execute() {
StringBuffer result = new StringBuffer();
if( Calendar.AM_PM == Calendar.PM )
result.append( Calendar.HOUR + 12 );
else
{
if( Calendar.HOUR < 10 )
result.append( '0');
result.append(Calendar.HOUR);
}
result.append(':');
if( Calendar.MINUTE < 10 )
result.append( '0');
result.append(Calendar.MINUTE);
result.append(':');
if( Calendar.SECOND < 10 )
result.append( '0');
result.append(Calendar.SECOND);
return result.toString();
}
} ) );
*/
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScanner#nextToken(boolean)