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

Refactored Scanner2 to make it subclassable.

Started to merge GCCScannerExtension into Scanner2 making it configuration based.
This commit is contained in:
John Camelon 2004-12-13 20:40:02 +00:00
parent 0d99c950b0
commit 7c23d4f9bb
15 changed files with 337 additions and 237 deletions

View file

@ -962,13 +962,7 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertTrue( ((IASTSimpleTypeSpecifier)function.getReturnType().getTypeSpecifier()).isComplex() ); assertTrue( ((IASTSimpleTypeSpecifier)function.getReturnType().getTypeSpecifier()).isComplex() );
} }
public void testBug39551B() throws Exception
{
//this used to be 99.99 * __I__, but I don't know where the __I__ came from, its not in C99, nor in GCC
IASTVariable variable = (IASTVariable)parse("_Imaginary double id = 99.99 * 1i;", true, ParserLanguage.C).getDeclarations().next(); //$NON-NLS-1$
assertEquals( variable.getName(), "id"); //$NON-NLS-1$
assertTrue( ((IASTSimpleTypeSpecifier)variable.getAbstractDeclaration().getTypeSpecifier()).isImaginary() );
}
public void testCBool() throws Exception public void testCBool() throws Exception
{ {

View file

@ -179,6 +179,14 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest {
parse(code.toString()); parse(code.toString());
} }
public void testBug39551B() throws Exception
{
//this used to be 99.99 * __I__, but I don't know where the __I__ came from, its not in C99, nor in GCC
IASTVariable variable = (IASTVariable)parse("_Imaginary double id = 99.99 * 1i;", true, ParserLanguage.C).getDeclarations().next(); //$NON-NLS-1$
assertEquals( variable.getName(), "id"); //$NON-NLS-1$
assertTrue( ((IASTSimpleTypeSpecifier)variable.getAbstractDeclaration().getTypeSpecifier()).isImaginary() );
}
public void testBug39681() throws Exception public void testBug39681() throws Exception
{ {
Writer code = new StringWriter(); Writer code = new StringWriter();

View file

@ -32,6 +32,9 @@ import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.extension.ExtensionDialect; import org.eclipse.cdt.core.parser.extension.ExtensionDialect;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.parser.ParserExtensionFactory; import org.eclipse.cdt.internal.core.parser.ParserExtensionFactory;
import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro; import org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro;
import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2; import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2;
@ -77,7 +80,12 @@ public class BaseScanner2Test extends TestCase {
IParserLogService logService = ( log == null ) ? ParserFactory.createDefaultLogService() : log; IParserLogService logService = ( log == null ) ? ParserFactory.createDefaultLogService() : log;
ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode ); ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode );
ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor ); ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor );
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, new ParserExtensionFactory( ExtensionDialect.GCC ).createScannerExtension(), workingCopies ); IScannerConfiguration configuration = null;
if( language == ParserLanguage.C )
configuration = new GCCScannerConfiguration();
else
configuration = new GPPScannerConfiguration();
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, new ParserExtensionFactory( ExtensionDialect.GCC ).createScannerExtension(), workingCopies, configuration );
} }
public int fullyTokenize() throws Exception public int fullyTokenize() throws Exception

View file

@ -62,4 +62,11 @@ public class GCCScannerExtensionsTest extends BaseScanner2Test {
validateToken( IToken.tRPAREN ); validateToken( IToken.tRPAREN );
validateInteger( "0" ); //$NON-NLS-1$ validateInteger( "0" ); //$NON-NLS-1$
} }
public void testImaginary() throws Exception
{
initializeScanner( "3i", ParserLanguage.C ); //$NON-NLS-1$
validateInteger( "3i" ); //$NON-NLS-1$
validateEOF();
}
} }

View file

@ -21,6 +21,9 @@ import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.extension.ExtensionDialect; import org.eclipse.cdt.core.parser.extension.ExtensionDialect;
import org.eclipse.cdt.internal.core.parser.ParserExtensionFactory; import org.eclipse.cdt.internal.core.parser.ParserExtensionFactory;
import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2; import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2;
// A test that just calculates the speed of the parser // A test that just calculates the speed of the parser
@ -83,7 +86,12 @@ public class SpeedTest2 extends TestCase {
IParserLogService logService = ( log == null ) ? ParserFactory.createDefaultLogService() : log; IParserLogService logService = ( log == null ) ? ParserFactory.createDefaultLogService() : log;
ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode ); ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode );
ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor ); ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor );
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, new ParserExtensionFactory( ExtensionDialect.GCC ).createScannerExtension(), workingCopies ); IScannerConfiguration configuration = null;
if( language == ParserLanguage.C )
configuration = new GCCScannerConfiguration();
else
configuration = new GPPScannerConfiguration();
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, new ParserExtensionFactory( ExtensionDialect.GCC ).createScannerExtension(), workingCopies, configuration );
} }
private static final ISourceElementRequestor CALLBACK = new NullSourceElementRequestor(); private static final ISourceElementRequestor CALLBACK = new NullSourceElementRequestor();

View file

@ -24,6 +24,9 @@ import org.eclipse.cdt.internal.core.parser.QuickParseCallback;
import org.eclipse.cdt.internal.core.parser.StructuralParseCallback; import org.eclipse.cdt.internal.core.parser.StructuralParseCallback;
import org.eclipse.cdt.internal.core.parser.ast.complete.CompleteParseASTFactory; import org.eclipse.cdt.internal.core.parser.ast.complete.CompleteParseASTFactory;
import org.eclipse.cdt.internal.core.parser.ast.quick.QuickParseASTFactory; import org.eclipse.cdt.internal.core.parser.ast.quick.QuickParseASTFactory;
import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2; import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2;
import org.eclipse.cdt.internal.core.parser.token.KeywordSets; import org.eclipse.cdt.internal.core.parser.token.KeywordSets;
@ -84,7 +87,13 @@ public class ParserFactory {
IParserLogService logService = ( log == null ) ? createDefaultLogService() : log; IParserLogService logService = ( log == null ) ? createDefaultLogService() : log;
ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode ); ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode );
ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor ); ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor );
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, extensionFactory.createScannerExtension(), workingCopies ); IScannerConfiguration configuration = null;
if( language == ParserLanguage.C )
configuration = new GCCScannerConfiguration();
else
configuration = new GPPScannerConfiguration();
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, extensionFactory.createScannerExtension(), workingCopies, configuration );
} }
public static IScanner createScanner( String fileName, IScannerInfo config, ParserMode mode, ParserLanguage language, ISourceElementRequestor requestor, IParserLogService log, List workingCopies ) throws ParserFactoryError, IOException public static IScanner createScanner( String fileName, IScannerInfo config, ParserMode mode, ParserLanguage language, ISourceElementRequestor requestor, IParserLogService log, List workingCopies ) throws ParserFactoryError, IOException

View file

@ -19,16 +19,11 @@ import org.eclipse.cdt.internal.core.parser.scanner2.IScannerData;
*/ */
public interface IScannerExtension { public interface IScannerExtension {
public char[] initializeMacroValue( IScannerData scannerData, char[] original );
public void setupBuiltInMacros(IScannerData scannerData); public void setupBuiltInMacros(IScannerData scannerData);
public boolean isExtensionKeyword(ParserLanguage language, char[] tokenImage); public boolean isExtensionKeyword(ParserLanguage language, char[] tokenImage);
public boolean isExtensionOperator(ParserLanguage language, char[] query);
public IToken createExtensionToken(IScannerData scannerData, char[] image); public IToken createExtensionToken(IScannerData scannerData, char[] image);
public boolean offersDifferentIdentifierCharacters();
public boolean isValidIdentifierStartCharacter(int c);
public boolean isValidIdentifierCharacter( int c );
public boolean isExtensionOperator(ParserLanguage language, char[] query);
public boolean isValidNumericLiteralSuffix(char c);
} }

View file

@ -0,0 +1,53 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.List;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.extension.IScannerExtension;
/**
* @author jcamelon
*/
public class DOMScanner extends Scanner2 {
/**
* @param reader
* @param info
* @param requestor
* @param parserMode
* @param language
* @param log
* @param extension
* @param workingCopies
*/
public DOMScanner(CodeReader reader, IScannerInfo info, ParserMode parserMode, ParserLanguage language, IParserLogService log, IScannerExtension extension, List workingCopies, IScannerConfiguration configuration) {
super(reader, info, null, parserMode, language, log, extension,
workingCopies, configuration);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver()
*/
public ILocationResolver getLocationResolver() {
if( locationMap instanceof ILocationResolver )
return (ILocationResolver) locationMap;
return null;
}
final IScannerPreprocessorLog locationMap = new LocationMap();
}

View file

@ -0,0 +1,35 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
/**
* @author jcamelon
*/
public class GCCScannerConfiguration extends GNUScannerConfiguration implements IScannerConfiguration {
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#supportMinAndMaxOperators()
*/
public boolean supportMinAndMaxOperators() {
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#getAdditionalKeywords()
*/
public CharArrayIntMap getAdditionalKeywords() {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -37,14 +37,6 @@ public class GCCScannerExtension implements IScannerExtension {
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScannerExtension#initializeMacroValue(java.lang.String)
*/
public char[] initializeMacroValue(IScannerData scannerData, char[] original) {
if( original == null || original.length == 0 ) //$NON-NLS-1$
return "1".toCharArray(); //$NON-NLS-1$
return original;
}
private static final char [] emptyCharArray = "".toCharArray(); //$NON-NLS-1$ private static final char [] emptyCharArray = "".toCharArray(); //$NON-NLS-1$
// gcc built-ins // gcc built-ins
private static final ObjectStyleMacro __inline__ private static final ObjectStyleMacro __inline__
@ -125,54 +117,29 @@ public class GCCScannerExtension implements IScannerExtension {
*/ */
public void setupBuiltInMacros(IScannerData scannerData) { public void setupBuiltInMacros(IScannerData scannerData) {
// gcc extensions // gcc extensions
scannerData.getRealDefinitions().put(__inline__.name, __inline__); CharArrayObjectMap realDefinitions = scannerData.getRealDefinitions();
scannerData.getRealDefinitions().put(__cdecl.name, __cdecl ); realDefinitions.put(__inline__.name, __inline__);
scannerData.getRealDefinitions().put( __const__.name, __const__ ); realDefinitions.put(__cdecl.name, __cdecl );
scannerData.getRealDefinitions().put( __const.name, __const ); realDefinitions.put( __const__.name, __const__ );
scannerData.getRealDefinitions().put(__extension__.name, __extension__); realDefinitions.put( __const.name, __const );
scannerData.getRealDefinitions().put(__attribute__.name, __attribute__); realDefinitions.put(__extension__.name, __extension__);
scannerData.getRealDefinitions().put( __declspec.name, __declspec ); realDefinitions.put(__attribute__.name, __attribute__);
scannerData.getRealDefinitions().put(__restrict__.name, __restrict__); realDefinitions.put( __declspec.name, __declspec );
scannerData.getRealDefinitions().put(__restrict.name, __restrict); realDefinitions.put(__restrict__.name, __restrict__);
scannerData.getRealDefinitions().put(__volatile__.name, __volatile__); realDefinitions.put(__restrict.name, __restrict);
scannerData.getRealDefinitions().put(__signed__.name, __signed__ ); realDefinitions.put(__volatile__.name, __volatile__);
scannerData.getRealDefinitions().put(__complex__.name, __complex__ ); realDefinitions.put(__signed__.name, __signed__ );
scannerData.getRealDefinitions().put(__imag__.name, __imag__ ); realDefinitions.put(__complex__.name, __complex__ );
scannerData.getRealDefinitions().put(__real__.name, __real__ ); realDefinitions.put(__imag__.name, __imag__ );
scannerData.getRealDefinitions().put( __builtin_va_arg.name, __builtin_va_arg ); realDefinitions.put(__real__.name, __real__ );
scannerData.getRealDefinitions().put( __builtin_constant_p.name, __builtin_constant_p ); realDefinitions.put( __builtin_va_arg.name, __builtin_va_arg );
realDefinitions.put( __builtin_constant_p.name, __builtin_constant_p );
if( scannerData.getLanguage() == ParserLanguage.CPP ) if( scannerData.getLanguage() == ParserLanguage.CPP )
scannerData.getRealDefinitions().put(__asm__.name, __asm__); realDefinitions.put(__asm__.name, __asm__);
else{ else{
scannerData.getRealDefinitions().put(_Pragma.name, _Pragma ); realDefinitions.put(_Pragma.name, _Pragma );
scannerData.getRealDefinitions().put( __builtin_choose_expr.name, __builtin_choose_expr ); realDefinitions.put( __builtin_choose_expr.name, __builtin_choose_expr );
} }
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.extension.IScannerExtension#offersDifferentIdentifierCharacters()
*/
public boolean offersDifferentIdentifierCharacters() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.extension.IScannerExtension#isValidIdentifierStartCharacter(int)
*/
public boolean isValidIdentifierStartCharacter(int c) {
return Character.isLetter((char)c) || ( c == '_') || ( c == '$' );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.extension.IScannerExtension#isValidIdentifierCharacter(int)
*/
public boolean isValidIdentifierCharacter(int c) {
return ((c >= 'a') && (c <= 'z'))
|| ((c >= 'A') && (c <= 'Z'))
|| ((c >= '0') && (c <= '9'))
|| (c == '_') || ( c== '$' ) ||
Character.isUnicodeIdentifierPart( (char)c);
} }
private static final CharArrayIntMap additionalCPPKeywords; private static final CharArrayIntMap additionalCPPKeywords;
@ -245,18 +212,4 @@ public class GCCScannerExtension implements IScannerExtension {
return false; return false;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.extension.IScannerExtension#isValidNumericLiteralSuffix(char)
*/
public boolean isValidNumericLiteralSuffix(char c) {
switch( c )
{
case 'i':
case 'j':
return true;
default:
return false;
}
}
} }

View file

@ -0,0 +1,30 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
/**
* @author jcamelon
*/
public class GNUScannerConfiguration {
public boolean initializeMacroValuesTo1() {
return true;
}
public boolean support$InIdentifiers() {
return true;
}
public char[] supportAdditionalNumericLiteralSuffixes() {
return "ij".toCharArray(); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,36 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
/**
* @author jcamelon
*/
public class GPPScannerConfiguration extends GNUScannerConfiguration implements
IScannerConfiguration {
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#supportMinAndMaxOperators()
*/
public boolean supportMinAndMaxOperators() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#getAdditionalKeywords()
*/
public CharArrayIntMap getAdditionalKeywords() {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -0,0 +1,27 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
/**
* @author jcamelon
*/
public interface IScannerConfiguration {
public boolean initializeMacroValuesTo1();
public boolean support$InIdentifiers();
public boolean supportMinAndMaxOperators();
public CharArrayIntMap getAdditionalKeywords();
public char [] supportAdditionalNumericLiteralSuffixes();
}

View file

@ -10,50 +10,18 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.Iterator;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory;
/** /**
* @author jcamelon * @author jcamelon
*/ */
public interface IScannerData { public interface IScannerData {
public abstract IASTFactory getASTFactory();
/**
* @return Returns the problemFactory.
*/
public abstract IProblemFactory getProblemFactory();
/** /**
* @return Returns the language. * @return Returns the language.
*/ */
public abstract ParserLanguage getLanguage(); public abstract ParserLanguage getLanguage();
/**
* @return Returns the parserMode.
*/
public abstract ParserMode getParserMode();
/**
* @return Returns the requestor.
*/
public abstract ISourceElementRequestor getClientRequestor();
public abstract IParserLogService getLogService();
public Iterator getWorkingCopies();
/**
* @param restOfLine
* @param offset
* @return
*/
// public abstract InclusionDirective parseInclusionDirective(String restOfLine, int offset) throws InclusionParseException;
/** /**
* @return * @return
@ -77,5 +45,5 @@ public interface IScannerData {
/** /**
* @return * @return
*/ */
public abstract CharArrayObjectMap getRealDefinitions(); public CharArrayObjectMap getRealDefinitions();
} }

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import java.io.File; import java.io.File;
import java.io.PrintStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
@ -45,7 +44,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode; import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator;
import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory;
import org.eclipse.cdt.internal.core.parser.token.ImagedExpansionToken; import org.eclipse.cdt.internal.core.parser.token.ImagedExpansionToken;
import org.eclipse.cdt.internal.core.parser.token.ImagedToken; import org.eclipse.cdt.internal.core.parser.token.ImagedToken;
import org.eclipse.cdt.internal.core.parser.token.KeywordSets; import org.eclipse.cdt.internal.core.parser.token.KeywordSets;
@ -58,7 +56,8 @@ import org.eclipse.cdt.internal.core.parser.token.SimpleToken;
*/ */
public class Scanner2 implements IScanner, IScannerData { public class Scanner2 implements IScanner, IScannerData {
private static final char[] ELLIPSIS_CHARARRAY = "...".toString().toCharArray(); //$NON-NLS-1$ private static final char[] ONE = "1".toCharArray(); //$NON-NLS-1$
private static final char[] ELLIPSIS_CHARARRAY = "...".toString().toCharArray(); //$NON-NLS-1$
private static final char[] VA_ARGS_CHARARRAY = "__VA_ARGS__".toCharArray(); //$NON-NLS-1$ private static final char[] VA_ARGS_CHARARRAY = "__VA_ARGS__".toCharArray(); //$NON-NLS-1$
/** /**
* @author jcamelon * @author jcamelon
@ -128,11 +127,10 @@ public class Scanner2 implements IScanner, IScannerData {
// Utility // Utility
private static String[] emptyStringArray = new String[0]; private static String[] EMPTY_STRING_ARRAY = new String[0];
private static char[] emptyCharArray = new char[0]; private static char[] EMPTY_CHAR_ARRAY = new char[0];
private static EndOfFileException EOF = new EndOfFileException(); private static EndOfFileException EOF = new EndOfFileException();
PrintStream dlog;
private ParserMode parserMode; private ParserMode parserMode;
@ -140,13 +138,9 @@ public class Scanner2 implements IScanner, IScannerData {
private Iterator preIncludeFiles = EmptyIterator.EMPTY_ITERATOR; private Iterator preIncludeFiles = EmptyIterator.EMPTY_ITERATOR;
private boolean isInitialized = false; private boolean isInitialized = false;
private final char [] suffixes;
boolean support$Initializers = false;
{
// try {
// dlog = new PrintStream(new FileOutputStream("C:/dlog.txt"));
// } catch (FileNotFoundException e) {
// }
}
public Scanner2(CodeReader reader, public Scanner2(CodeReader reader,
IScannerInfo info, IScannerInfo info,
@ -155,7 +149,7 @@ public class Scanner2 implements IScanner, IScannerData {
ParserLanguage language, ParserLanguage language,
IParserLogService log, IParserLogService log,
IScannerExtension extension, IScannerExtension extension,
List workingCopies) { List workingCopies, IScannerConfiguration configuration) {
this.scannerExtension = extension; this.scannerExtension = extension;
this.requestor = requestor; this.requestor = requestor;
@ -165,6 +159,11 @@ public class Scanner2 implements IScanner, IScannerData {
this.workingCopies = workingCopies; this.workingCopies = workingCopies;
this.callbackManager = new ScannerCallbackManager( requestor ); this.callbackManager = new ScannerCallbackManager( requestor );
this.expressionEvaluator = new ExpressionEvaluator(callbackManager, spf); this.expressionEvaluator = new ExpressionEvaluator(callbackManager, spf);
if( configuration.supportAdditionalNumericLiteralSuffixes() != null )
suffixes = configuration.supportAdditionalNumericLiteralSuffixes();
else
suffixes = EMPTY_CHAR_ARRAY;
support$Initializers = configuration.support$InIdentifiers();
if( language == ParserLanguage.C ) if( language == ParserLanguage.C )
keywords = ckeywords; keywords = ckeywords;
@ -178,14 +177,16 @@ public class Scanner2 implements IScanner, IScannerData {
if (info.getDefinedSymbols() != null) { if (info.getDefinedSymbols() != null) {
Map symbols = info.getDefinedSymbols(); Map symbols = info.getDefinedSymbols();
String[] keys = (String[])symbols.keySet().toArray(emptyStringArray); String[] keys = (String[])symbols.keySet().toArray(EMPTY_STRING_ARRAY);
for (int i = 0; i < keys.length; ++i) { for (int i = 0; i < keys.length; ++i) {
String symbolName = keys[i]; String symbolName = keys[i];
Object value = symbols.get(symbolName); Object value = symbols.get(symbolName);
if( value instanceof String ) { if( value instanceof String ) {
//TODO add in check here for '(' and ')' if( configuration.initializeMacroValuesTo1() && ((String)value).trim().equals( EMPTY_STRING ))
addDefinition( symbolName.toCharArray(), scannerExtension.initializeMacroValue(this, ((String)value).toCharArray())); addDefinition( symbolName.toCharArray(), ONE );
else
addDefinition( symbolName.toCharArray(), ((String)value).toCharArray());
} }
} }
} }
@ -230,7 +231,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
private void pushContext(char[] buffer) { protected void pushContext(char[] buffer) {
if (++bufferStackPos == bufferStack.length) { if (++bufferStackPos == bufferStack.length) {
int size = bufferStack.length * 2; int size = bufferStack.length * 2;
@ -268,7 +269,7 @@ public class Scanner2 implements IScanner, IScannerData {
bufferLimit[bufferStackPos] = buffer.length; bufferLimit[bufferStackPos] = buffer.length;
} }
private void pushContext(char[] buffer, Object data) { protected void pushContext(char[] buffer, Object data) {
if( data instanceof InclusionData ) if( data instanceof InclusionData )
{ {
boolean isCircular = false; boolean isCircular = false;
@ -308,7 +309,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
} }
private void popContext() { protected void popContext() {
bufferStack[bufferStackPos] = null; bufferStack[bufferStackPos] = null;
if( bufferData[bufferStackPos] instanceof InclusionData ) if( bufferData[bufferStackPos] instanceof InclusionData )
{ {
@ -330,7 +331,7 @@ public class Scanner2 implements IScanner, IScannerData {
/** /**
* *
*/ */
private void pushForcedInclusion() { protected void pushForcedInclusion() {
CodeReader r = null; CodeReader r = null;
while( r == null ) while( r == null )
{ {
@ -526,14 +527,14 @@ public class Scanner2 implements IScanner, IScannerData {
/** /**
* *
*/ */
private void throwOLRE() throws OffsetLimitReachedException { protected void throwOLRE() throws OffsetLimitReachedException {
if( lastToken != null && lastToken.getEndOffset() != offsetBoundary ) if( lastToken != null && lastToken.getEndOffset() != offsetBoundary )
throw new OffsetLimitReachedException( (IToken)null ); throw new OffsetLimitReachedException( (IToken)null );
throw new OffsetLimitReachedException( lastToken ); throw new OffsetLimitReachedException( lastToken );
} }
// Return null to signify end of file // Return null to signify end of file
private IToken fetchToken() throws EndOfFileException{ protected IToken fetchToken() throws EndOfFileException{
++count; ++count;
contextLoop: contextLoop:
while (bufferStackPos >= 0) { while (bufferStackPos >= 0) {
@ -902,12 +903,13 @@ public class Scanner2 implements IScanner, IScannerData {
return newToken(IToken.tCOMMA ); return newToken(IToken.tCOMMA );
default: default:
if( Character.isLetter( buffer[pos] ) || scannerExtension.isValidIdentifierStartCharacter( buffer[pos ]) ){ if( Character.isLetter( buffer[pos] ) || buffer[pos] == '_' || ( support$Initializers && buffer[pos] == '$' )) {
t = scanIdentifier(); t = scanIdentifier();
if (t instanceof MacroExpansionToken) if (t instanceof MacroExpansionToken)
continue; continue;
return t; return t;
} }
// skip over anything we don't handle // skip over anything we don't handle
} }
} }
@ -919,7 +921,7 @@ public class Scanner2 implements IScanner, IScannerData {
/** /**
* @return * @return
*/ */
private IToken newToken( int signal ) { protected IToken newToken( int signal ) {
if( bufferData[bufferStackPos] instanceof MacroData ) if( bufferData[bufferStackPos] instanceof MacroData )
{ {
int mostRelevant; int mostRelevant;
@ -932,7 +934,7 @@ public class Scanner2 implements IScanner, IScannerData {
return new SimpleToken(signal, bufferPos[bufferStackPos] + 1 , getCurrentFilename(), getLineNumber( bufferPos[bufferStackPos] + 1) ); return new SimpleToken(signal, bufferPos[bufferStackPos] + 1 , getCurrentFilename(), getLineNumber( bufferPos[bufferStackPos] + 1) );
} }
private IToken newToken( int signal, char [] buffer ) protected IToken newToken( int signal, char [] buffer )
{ {
if( bufferData[bufferStackPos] instanceof MacroData ) if( bufferData[bufferStackPos] instanceof MacroData )
{ {
@ -950,7 +952,7 @@ public class Scanner2 implements IScanner, IScannerData {
return i; return i;
} }
private IToken scanIdentifier() { protected IToken scanIdentifier() {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
boolean escapedNewline = false; boolean escapedNewline = false;
int start = bufferPos[bufferStackPos]; int start = bufferPos[bufferStackPos];
@ -981,7 +983,7 @@ public class Scanner2 implements IScanner, IScannerData {
continue; continue;
} }
} }
else if( scannerExtension.isValidIdentifierCharacter( c )) else if( ( support$Initializers && c == '$' ) )
{ {
++len; ++len;
continue; continue;
@ -1043,7 +1045,7 @@ public class Scanner2 implements IScanner, IScannerData {
* @param expObject * @param expObject
* @return * @return
*/ */
private boolean shouldExpandMacro( IMacro macro ) { protected boolean shouldExpandMacro( IMacro macro ) {
// but not if it has been expanded on the stack already // but not if it has been expanded on the stack already
// i.e. recursion avoidance // i.e. recursion avoidance
if( macro != null && !isLimitReached() ) if( macro != null && !isLimitReached() )
@ -1059,7 +1061,7 @@ public class Scanner2 implements IScanner, IScannerData {
/** /**
* @return * @return
*/ */
private final boolean isLimitReached() { protected final boolean isLimitReached() {
if( offsetBoundary == -1 || bufferStackPos != 0 ) return false; if( offsetBoundary == -1 || bufferStackPos != 0 ) return false;
if( bufferPos[bufferStackPos] == offsetBoundary - 1 ) return true; if( bufferPos[bufferStackPos] == offsetBoundary - 1 ) return true;
if( bufferPos[bufferStackPos] == offsetBoundary ) if( bufferPos[bufferStackPos] == offsetBoundary )
@ -1071,7 +1073,7 @@ public class Scanner2 implements IScanner, IScannerData {
return false; return false;
} }
private IToken scanString() { protected IToken scanString() {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int tokenType = IToken.tSTRING; int tokenType = IToken.tSTRING;
@ -1125,7 +1127,7 @@ public class Scanner2 implements IScanner, IScannerData {
return newToken(tokenType, result); return newToken(tokenType, result);
} }
private IToken scanCharLiteral() { protected IToken scanCharLiteral() {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int start = bufferPos[bufferStackPos]; int start = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -1139,7 +1141,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
if (start >= limit) { if (start >= limit) {
return newToken(tokenType, emptyCharArray ); return newToken(tokenType, EMPTY_CHAR_ARRAY );
} }
@ -1160,12 +1162,12 @@ public class Scanner2 implements IScanner, IScannerData {
if( bufferPos[ bufferStackPos ] == limit ) if( bufferPos[ bufferStackPos ] == limit )
{ {
handleProblem( IProblem.SCANNER_BAD_CHARACTER, start, CharArrayUtils.extract(buffer, start, length) ); handleProblem( IProblem.SCANNER_BAD_CHARACTER, start, CharArrayUtils.extract(buffer, start, length) );
return newToken( tokenType, emptyCharArray ); return newToken( tokenType, EMPTY_CHAR_ARRAY );
} }
char[] image = length > 0 char[] image = length > 0
? CharArrayUtils.extract(buffer, start, length) ? CharArrayUtils.extract(buffer, start, length)
: emptyCharArray; : EMPTY_CHAR_ARRAY;
return newToken(tokenType, image ); return newToken(tokenType, image );
} }
@ -1174,9 +1176,9 @@ public class Scanner2 implements IScanner, IScannerData {
/** /**
* @param scanner_bad_character * @param scanner_bad_character
*/ */
private void handleProblem(int id, int startOffset, char [] arg ) { protected void handleProblem(int id, int startOffset, char [] arg ) {
if( parserMode == ParserMode.COMPLETION_PARSE ) return; if( parserMode == ParserMode.COMPLETION_PARSE ) return;
IProblem p = spf.createProblem( id, startOffset, bufferPos[bufferStackPos], getLineNumber( bufferPos[bufferStackPos] ), getCurrentFilename(), arg != null ? arg : emptyCharArray, false, true ); IProblem p = spf.createProblem( id, startOffset, bufferPos[bufferStackPos], getLineNumber( bufferPos[bufferStackPos] ), getCurrentFilename(), arg != null ? arg : EMPTY_CHAR_ARRAY, false, true );
callbackManager.pushCallback( p ); callbackManager.pushCallback( p );
} }
@ -1206,7 +1208,7 @@ public class Scanner2 implements IScanner, IScannerData {
return lineNum; return lineNum;
} }
private IToken scanNumber() throws EndOfFileException { protected IToken scanNumber() throws EndOfFileException {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int start = bufferPos[bufferStackPos]; int start = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -1394,9 +1396,14 @@ public class Scanner2 implements IScanner, IScannerData {
break; break;
default: default:
if( scannerExtension.isValidNumericLiteralSuffix( buffer[pos] )) boolean success = false;
continue; for( int iter = 0; iter < suffixes.length; iter++ )
// not part of our number if( buffer[pos] == suffixes[iter] )
{
success = true;
break;
}
if( success ) continue;
} }
// If we didn't continue in the switch, we're done // If we didn't continue in the switch, we're done
@ -1417,7 +1424,7 @@ public class Scanner2 implements IScanner, IScannerData {
return newToken( tokenType, result ); return newToken( tokenType, result );
} }
private boolean branchState( int state ){ protected boolean branchState( int state ){
if( state != BRANCH_IF && branchStackPos == -1 ) if( state != BRANCH_IF && branchStackPos == -1 )
return false; return false;
@ -1454,7 +1461,7 @@ public class Scanner2 implements IScanner, IScannerData {
return false; return false;
} }
private void handlePPDirective(int pos) throws EndOfFileException { protected void handlePPDirective(int pos) throws EndOfFileException {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
int startingLineNumber = getLineNumber( pos ); int startingLineNumber = getLineNumber( pos );
@ -1512,12 +1519,10 @@ public class Scanner2 implements IScanner, IScannerData {
handleCompletionOnExpression( CharArrayUtils.extract( buffer, start, len ) ); handleCompletionOnExpression( CharArrayUtils.extract( buffer, start, len ) );
branchState( BRANCH_IF ); branchState( BRANCH_IF );
if (expressionEvaluator.evaluate(buffer, start, len, definitions, getLineNumber( bufferPos[bufferStackPos] ), getCurrentFilename()) == 0) { if (expressionEvaluator.evaluate(buffer, start, len, definitions, getLineNumber( bufferPos[bufferStackPos] ), getCurrentFilename()) == 0) {
if (dlog != null) dlog.println("#if <FALSE> " + new String(buffer,start+1,len-1)); //$NON-NLS-1$
skipOverConditionalCode(true); skipOverConditionalCode(true);
if( isLimitReached() ) if( isLimitReached() )
handleInvalidCompletion(); handleInvalidCompletion();
} else }
if (dlog != null) dlog.println("#if <TRUE> " + new String(buffer,start+1,len-1)); //$NON-NLS-1$
return; return;
case ppElse: case ppElse:
case ppElif: case ppElif:
@ -1564,7 +1569,7 @@ public class Scanner2 implements IScanner, IScannerData {
skipToNewLine(); skipToNewLine();
} }
private void handlePPInclude(int pos2, boolean next, int startingLineNumber) { protected void handlePPInclude(int pos2, boolean next, int startingLineNumber) {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -1711,7 +1716,6 @@ public class Scanner2 implements IScanner, IScannerData {
fileCache.put(reader.filename, reader); fileCache.put(reader.filename, reader);
} }
if (reader != null) { if (reader != null) {
if (dlog != null) dlog.println("#include \"" + finalPath + "\""); //$NON-NLS-1$ //$NON-NLS-2$
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false ); IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false );
pushContext(reader.buffer, new InclusionData( reader, inclusion )); pushContext(reader.buffer, new InclusionData( reader, inclusion ));
return; return;
@ -1739,7 +1743,6 @@ public class Scanner2 implements IScanner, IScannerData {
fileCache.put(reader.filename, reader); fileCache.put(reader.filename, reader);
} }
if (reader != null) { if (reader != null) {
if (dlog != null) dlog.println("#include <" + finalPath + ">"); //$NON-NLS-1$ //$NON-NLS-2$
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false ); IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false );
pushContext(reader.buffer, new InclusionData( reader, inclusion )); pushContext(reader.buffer, new InclusionData( reader, inclusion ));
return; return;
@ -1754,7 +1757,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
private void handlePPDefine(int pos2, int startingLineNumber) { protected void handlePPDefine(int pos2, int startingLineNumber) {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -1788,7 +1791,6 @@ public class Scanner2 implements IScanner, IScannerData {
nameLine = getLineNumber( bufferPos[ bufferStackPos ] ); nameLine = getLineNumber( bufferPos[ bufferStackPos ] );
char[] name = new char[idlen]; char[] name = new char[idlen];
System.arraycopy(buffer, idstart, name, 0, idlen); System.arraycopy(buffer, idstart, name, 0, idlen);
if (dlog != null) dlog.println("#define " + new String(buffer, idstart, idlen)); //$NON-NLS-1$
// Now check for function style macro to store the arguments // Now check for function style macro to store the arguments
char[][] arglist = null; char[][] arglist = null;
@ -1863,7 +1865,7 @@ public class Scanner2 implements IScanner, IScannerData {
int textlen = textend - textstart + 1; int textlen = textend - textstart + 1;
endingLine = getLineNumber( bufferPos[ bufferStackPos ] ); endingLine = getLineNumber( bufferPos[ bufferStackPos ] );
char[] text = emptyCharArray; char[] text = EMPTY_CHAR_ARRAY;
if (textlen > 0) { if (textlen > 0) {
text = new char[textlen]; text = new char[textlen];
System.arraycopy(buffer, textstart, text, 0, textlen); System.arraycopy(buffer, textstart, text, 0, textlen);
@ -1884,7 +1886,7 @@ public class Scanner2 implements IScanner, IScannerData {
callbackManager.pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, getCurrentFilename(), !isInitialized ) ); callbackManager.pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, getCurrentFilename(), !isInitialized ) );
} }
private char[][] extractMacroParameters( int idstart, char[] name, boolean reportProblems ){ protected char[][] extractMacroParameters( int idstart, char[] name, boolean reportProblems ){
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -1936,7 +1938,7 @@ public class Scanner2 implements IScanner, IScannerData {
* @param text * @param text
* @return * @return
*/ */
private char[] removedEscapedNewline(char[] text, int start, int len ) { protected char[] removedEscapedNewline(char[] text, int start, int len ) {
if( CharArrayUtils.indexOf( '\n', text, start, len ) == -1 ) if( CharArrayUtils.indexOf( '\n', text, start, len ) == -1 )
return text; return text;
char [] result = new char[ text.length ]; char [] result = new char[ text.length ];
@ -1958,7 +1960,7 @@ public class Scanner2 implements IScanner, IScannerData {
* @param text * @param text
* @return * @return
*/ */
private char[] removeMultilineCommentFromBuffer(char[] text) { protected char[] removeMultilineCommentFromBuffer(char[] text) {
char [] result = new char[ text.length ]; char [] result = new char[ text.length ];
Arrays.fill( result, ' '); Arrays.fill( result, ' ');
int resultCount = 0; int resultCount = 0;
@ -1978,7 +1980,7 @@ public class Scanner2 implements IScanner, IScannerData {
return CharArrayUtils.trim( result ); return CharArrayUtils.trim( result );
} }
private void handlePPUndef() throws EndOfFileException { protected void handlePPUndef() throws EndOfFileException {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -2014,10 +2016,9 @@ public class Scanner2 implements IScanner, IScannerData {
skipToNewLine(); skipToNewLine();
definitions.remove(buffer, idstart, idlen); definitions.remove(buffer, idstart, idlen);
if (dlog != null) dlog.println("#undef " + new String(buffer, idstart, idlen)); //$NON-NLS-1$
} }
private void handlePPIfdef(boolean positive) throws EndOfFileException { protected void handlePPIfdef(boolean positive) throws EndOfFileException {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -2061,14 +2062,10 @@ public class Scanner2 implements IScanner, IScannerData {
branchState( BRANCH_IF ); branchState( BRANCH_IF );
if ((definitions.get(buffer, idstart, idlen) != null) == positive) { if ((definitions.get(buffer, idstart, idlen) != null) == positive) {
if (dlog != null) dlog.println((positive ? "#ifdef" : "#ifndef") //$NON-NLS-1$ //$NON-NLS-2$
+ " <TRUE> " + new String(buffer, idstart, idlen)); //$NON-NLS-1$
// continue on // continue on
return; return;
} }
if (dlog != null) dlog.println((positive ? "#ifdef" : "#ifndef") //$NON-NLS-1$ //$NON-NLS-2$
+ " <FALSE> " + new String(buffer, idstart, idlen)); //$NON-NLS-1$
// skip over this group // skip over this group
skipOverConditionalCode(true); skipOverConditionalCode(true);
if( isLimitReached() ) if( isLimitReached() )
@ -2076,7 +2073,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
// checkelse - if potential for more, otherwise skip to endif // checkelse - if potential for more, otherwise skip to endif
private void skipOverConditionalCode(boolean checkelse) { protected void skipOverConditionalCode(boolean checkelse) {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
int nesting = 0; int nesting = 0;
@ -2169,7 +2166,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
} }
private boolean skipOverWhiteSpace() { protected boolean skipOverWhiteSpace() {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -2237,7 +2234,7 @@ public class Scanner2 implements IScanner, IScannerData {
return encounteredMultiLineComment; return encounteredMultiLineComment;
} }
private int indexOfNextNonWhiteSpace( char[] buffer, int start, int limit ) { protected int indexOfNextNonWhiteSpace( char[] buffer, int start, int limit ) {
if( start < 0 || start >= buffer.length || limit > buffer.length ) if( start < 0 || start >= buffer.length || limit > buffer.length )
return -1; return -1;
@ -2282,10 +2279,10 @@ public class Scanner2 implements IScanner, IScannerData {
return pos; return pos;
} }
private void skipOverNonWhiteSpace(){ protected void skipOverNonWhiteSpace(){
skipOverNonWhiteSpace( false ); skipOverNonWhiteSpace( false );
} }
private boolean skipOverNonWhiteSpace( boolean stopAtPound ) { protected boolean skipOverNonWhiteSpace( boolean stopAtPound ) {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -2397,7 +2394,7 @@ public class Scanner2 implements IScanner, IScannerData {
return true; return true;
} }
private int skipOverMacroArg(){ protected int skipOverMacroArg(){
char [] buffer = bufferStack[bufferStackPos]; char [] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
int argEnd = bufferPos[bufferStackPos]--; int argEnd = bufferPos[bufferStackPos]--;
@ -2447,7 +2444,7 @@ public class Scanner2 implements IScanner, IScannerData {
return argEnd; return argEnd;
} }
private void skipOverIdentifier() { protected void skipOverIdentifier() {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -2506,7 +2503,7 @@ public class Scanner2 implements IScanner, IScannerData {
--bufferPos[bufferStackPos]; --bufferPos[bufferStackPos];
} }
private void skipToNewLine() { protected void skipToNewLine() {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
int pos = ++bufferPos[bufferStackPos]; int pos = ++bufferPos[bufferStackPos];
@ -2556,7 +2553,7 @@ public class Scanner2 implements IScanner, IScannerData {
} }
} }
private char[] handleFunctionStyleMacro(FunctionStyleMacro macro, boolean pushContext) { protected char[] handleFunctionStyleMacro(FunctionStyleMacro macro, boolean pushContext) {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
int start = bufferPos[bufferStackPos] - macro.name.length + 1; int start = bufferPos[bufferStackPos] - macro.name.length + 1;
@ -2578,7 +2575,7 @@ public class Scanner2 implements IScanner, IScannerData {
int stackpPos = bufferStackPos; int stackpPos = bufferStackPos;
while( bufferData[stackpPos] != null && bufferData[stackpPos] instanceof MacroData ){ while( bufferData[stackpPos] != null && bufferData[stackpPos] instanceof MacroData ){
stackpPos--; stackpPos--;
if( stackpPos < 0 ) return emptyCharArray; if( stackpPos < 0 ) return EMPTY_CHAR_ARRAY;
idx = indexOfNextNonWhiteSpace( bufferStack[stackpPos], bufferPos[stackpPos], bufferLimit[stackpPos] ); idx = indexOfNextNonWhiteSpace( bufferStack[stackpPos], bufferPos[stackpPos], bufferLimit[stackpPos] );
if( idx >= bufferLimit[stackpPos] ) continue; if( idx >= bufferLimit[stackpPos] ) continue;
if( idx > 0 && bufferStack[stackpPos][idx] == '(' ) break; if( idx > 0 && bufferStack[stackpPos][idx] == '(' ) break;
@ -2653,7 +2650,7 @@ public class Scanner2 implements IScanner, IScannerData {
} else } else
argend = skipOverMacroArg(); argend = skipOverMacroArg();
char[] arg = emptyCharArray; char[] arg = EMPTY_CHAR_ARRAY;
int arglen = argend - argstart + 1; int arglen = argend - argstart + 1;
if (arglen > 0) { if (arglen > 0) {
arg = new char[arglen]; arg = new char[arglen];
@ -2688,20 +2685,20 @@ public class Scanner2 implements IScanner, IScannerData {
return result; return result;
} }
private char[] replaceArgumentMacros( char [] arg ){ protected char[] replaceArgumentMacros( char [] arg ){
int limit = arg.length; int limit = arg.length;
int start = -1, end = -1; int start = -1, end = -1;
Object expObject = null; Object expObject = null;
for( int pos = 0; pos < limit; pos++ ){ for( int pos = 0; pos < limit; pos++ ){
char c = arg[pos]; char c = arg[pos];
if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ||
Character.isLetter( c ) || scannerExtension.isValidIdentifierStartCharacter( c ) ) Character.isLetter( c ) || ( support$Initializers && c == '$' ) )
{ {
start = pos; start = pos;
while (++pos < limit) { while (++pos < limit) {
c = arg[pos]; c = arg[pos];
if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') ||
scannerExtension.isValidIdentifierCharacter(c) || Character.isUnicodeIdentifierPart(c) ) ( support$Initializers && c == '$' )|| Character.isUnicodeIdentifierPart(c) )
{ {
continue; continue;
} }
@ -2753,14 +2750,14 @@ public class Scanner2 implements IScanner, IScannerData {
System.arraycopy( arg, end + 1, result, start + expansion.length, limit - end - 1 ); System.arraycopy( arg, end + 1, result, start + expansion.length, limit - end - 1 );
//we need to put the macro on the context stack in order to detect recursive macros //we need to put the macro on the context stack in order to detect recursive macros
pushContext( emptyCharArray, new MacroData( start, start + ((IMacro)expObject).getName().length, (IMacro)expObject) ); pushContext( EMPTY_CHAR_ARRAY, new MacroData( start, start + ((IMacro)expObject).getName().length, (IMacro)expObject) );
arg = replaceArgumentMacros( result ); //rescan for more macros arg = replaceArgumentMacros( result ); //rescan for more macros
popContext(); popContext();
} }
return arg; return arg;
} }
private int expandFunctionStyleMacro( protected int expandFunctionStyleMacro(
char[] expansion, char[] expansion,
CharArrayObjectMap argmap, CharArrayObjectMap replacedArgs, CharArrayObjectMap argmap, CharArrayObjectMap replacedArgs,
char[] result) { char[] result) {
@ -3081,11 +3078,11 @@ public class Scanner2 implements IScanner, IScannerData {
// standard built-ins // standard built-ins
private static final ObjectStyleMacro __cplusplus private static final ObjectStyleMacro __cplusplus
= new ObjectStyleMacro("__cplusplus".toCharArray(), "1".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ = new ObjectStyleMacro("__cplusplus".toCharArray(), ONE ); //$NON-NLS-1$ //$NON-NLS-2$
private static final ObjectStyleMacro __STDC__ private static final ObjectStyleMacro __STDC__
= new ObjectStyleMacro("__STDC__".toCharArray(), "1".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ = new ObjectStyleMacro("__STDC__".toCharArray(), ONE ); //$NON-NLS-1$ //$NON-NLS-2$
private static final ObjectStyleMacro __STDC_HOSTED__ private static final ObjectStyleMacro __STDC_HOSTED__
= new ObjectStyleMacro("__STDC_HOSTED_".toCharArray(), "1".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ = new ObjectStyleMacro("__STDC_HOSTED_".toCharArray(), ONE ); //$NON-NLS-1$ //$NON-NLS-2$
private static final ObjectStyleMacro __STDC_VERSION__ private static final ObjectStyleMacro __STDC_VERSION__
= new ObjectStyleMacro("__STDC_VERSION_".toCharArray(), "199901L".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ = new ObjectStyleMacro("__STDC_VERSION_".toCharArray(), "199901L".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$
private final DynamicStyleMacro __FILE__ = private final DynamicStyleMacro __FILE__ =
@ -3194,49 +3191,24 @@ public class Scanner2 implements IScanner, IScannerData {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getASTFactory() * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getASTFactory()
*/ */
public final IASTFactory getASTFactory() { protected final IASTFactory getASTFactory() {
if( astFactory == null ) if( astFactory == null )
astFactory = ParserFactory.createASTFactory( parserMode, language ); astFactory = ParserFactory.createASTFactory( parserMode, language );
return astFactory; return astFactory;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getClientRequestor()
*/
public ISourceElementRequestor getClientRequestor() {
return requestor;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getLanguage() * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getLanguage()
*/ */
public ParserLanguage getLanguage() { public ParserLanguage getLanguage() {
return language; return language;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getLogService()
*/
public IParserLogService getLogService() {
return log;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getParserMode()
*/
public ParserMode getParserMode() {
return parserMode;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getProblemFactory()
*/
public IProblemFactory getProblemFactory() {
return spf;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getWorkingCopies() * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getWorkingCopies()
*/ */
public Iterator getWorkingCopies() { protected Iterator getWorkingCopies() {
if( workingCopies == null ) return EmptyIterator.EMPTY_ITERATOR; if( workingCopies == null ) return EmptyIterator.EMPTY_ITERATOR;
return workingCopies.iterator(); return workingCopies.iterator();
} }
@ -3245,7 +3217,7 @@ public class Scanner2 implements IScanner, IScannerData {
if( bufferData != null && bufferData[0] != null && bufferData[0] instanceof CodeReader ) if( bufferData != null && bufferData[0] != null && bufferData[0] instanceof CodeReader )
return ((CodeReader)bufferData[0]).filename; return ((CodeReader)bufferData[0]).filename;
return emptyCharArray; return EMPTY_CHAR_ARRAY;
} }
public final char[] getCurrentFilename() { public final char[] getCurrentFilename() {
@ -3256,10 +3228,10 @@ public class Scanner2 implements IScanner, IScannerData {
if( bufferData[i] instanceof CodeReader ) if( bufferData[i] instanceof CodeReader )
return ((CodeReader)bufferData[i]).filename; return ((CodeReader)bufferData[i]).filename;
} }
return emptyCharArray; return EMPTY_CHAR_ARRAY;
} }
private final int getCurrentFileIndex() { protected final int getCurrentFileIndex() {
for( int i = bufferStackPos; i >= 0; --i ) for( int i = bufferStackPos; i >= 0; --i )
{ {
if( bufferData[i] instanceof InclusionData || bufferData[i] instanceof CodeReader ) if( bufferData[i] instanceof InclusionData || bufferData[i] instanceof CodeReader )
@ -3466,10 +3438,7 @@ public class Scanner2 implements IScanner, IScannerData {
* @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver() * @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver()
*/ */
public ILocationResolver getLocationResolver() { public ILocationResolver getLocationResolver() {
if( locationMap instanceof ILocationResolver )
return (ILocationResolver) locationMap;
return null; return null;
} }
final IScannerPreprocessorLog locationMap = new LocationMap();
} }