Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] [FIXED] 72611 patch


I cleaned up the code and added a test for
'bufferPos[index] = bufferLimit[index];'

John, I noticed that this code will often return a null token to nextToken() so
I added the following:

                if (finished)
                {
+                        if (isCancelled)
+                                throw new ParseError( ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
                       
                        if( offsetBoundary == -1 )
                                throw EOF;                        
                        throwOLRE();
                }

[FIXED] 72611 [Parser] Timeout strategy does not affect scanner infinite loops



Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada
Index: parser/org/eclipse/cdt/core/parser/IScanner.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java,v
retrieving revision 1.28
diff -u -r1.28 IScanner.java
--- parser/org/eclipse/cdt/core/parser/IScanner.java	11 Sep 2004 23:04:27 -0000	1.28
+++ parser/org/eclipse/cdt/core/parser/IScanner.java	1 Oct 2004 15:12:56 -0000
@@ -36,5 +36,5 @@
 	public int  getCount();
 	public boolean isOnTopContext();
 	public CharArrayObjectMap getRealDefinitions();
-
+	public void cancel();
 }
Index: parser/org/eclipse/cdt/internal/core/parser/Parser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java,v
retrieving revision 1.256
diff -u -r1.256 Parser.java
--- parser/org/eclipse/cdt/internal/core/parser/Parser.java	30 Sep 2004 21:19:10 -0000	1.256
+++ parser/org/eclipse/cdt/internal/core/parser/Parser.java	1 Oct 2004 15:12:58 -0000
@@ -6276,6 +6276,7 @@
 	 */
 	public synchronized void cancel() {
 		isCancelled = true;
+		scanner.cancel();
 	}
 	
 	/* (non-Javadoc)
Index: parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java,v
retrieving revision 1.75
diff -u -r1.75 Scanner2.java
--- parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java	30 Sep 2004 20:23:30 -0000	1.75
+++ parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java	1 Oct 2004 15:12:59 -0000
@@ -31,6 +31,7 @@
 import org.eclipse.cdt.core.parser.KeywordSetKey;
 import org.eclipse.cdt.core.parser.Keywords;
 import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
+import org.eclipse.cdt.core.parser.ParseError;
 import org.eclipse.cdt.core.parser.ParserFactory;
 import org.eclipse.cdt.core.parser.ParserLanguage;
 import org.eclipse.cdt.core.parser.ParserMode;
@@ -380,8 +381,13 @@
 	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
 	private static final char[] EMPTY_STRING_CHAR_ARRAY = new char[0];
 
+	private boolean isCancelled = false;
 	
-
+	public synchronized void cancel() {
+		isCancelled = true;
+		int index = bufferStackPos < 0 ? 0 : bufferStackPos; 
+		bufferPos[index] = bufferLimit[index];
+	}
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.cdt.core.parser.IScanner#nextToken()
@@ -397,6 +403,8 @@
 			{
 			    if( e instanceof OffsetLimitReachedException )
 			        throw (OffsetLimitReachedException) e;
+			    if( e instanceof ArrayIndexOutOfBoundsException && isCancelled ) 
+			    	throw new ParseError( ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
 
 			    exception = true;
 				errorHandle();
@@ -413,6 +421,9 @@
 		
 		if (finished)
 		{
+			if (isCancelled)
+				throw new ParseError( ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
+			
 			if( offsetBoundary == -1 )
 				throw EOF;			
 			throwOLRE();
@@ -491,7 +502,9 @@
 		++count;
 		contextLoop:
 		while (bufferStackPos >= 0) {
-
+			if (isCancelled == true)
+				throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
+			
 			// Find the first thing we would care about
 			skipOverWhiteSpace();
 			
Index: parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java,v
retrieving revision 1.6
diff -u -r1.6 CompleteParsePluginTest.java
--- parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java	17 Sep 2004 14:10:16 -0000	1.6
+++ parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java	1 Oct 2004 15:13:56 -0000
@@ -14,300 +14,35 @@
  */
 package org.eclipse.cdt.core.parser.tests;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 import junit.framework.Test;
-import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.model.ICProject;
-import org.eclipse.cdt.core.parser.CodeReader;
-import org.eclipse.cdt.core.parser.IParser;
-import org.eclipse.cdt.core.parser.IProblem;
-import org.eclipse.cdt.core.parser.ISourceElementRequestor;
-import org.eclipse.cdt.core.parser.NullLogService;
-import org.eclipse.cdt.core.parser.ParserFactory;
-import org.eclipse.cdt.core.parser.ParserLanguage;
-import org.eclipse.cdt.core.parser.ParserMode;
-import org.eclipse.cdt.core.parser.ParserUtil;
-import org.eclipse.cdt.core.parser.ScannerInfo;
-import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
-import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
-import org.eclipse.cdt.core.parser.ast.IASTClassReference;
-import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
-import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
-import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
-import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
-import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
-import org.eclipse.cdt.core.parser.ast.IASTEnumerationReference;
-import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
-import org.eclipse.cdt.core.parser.ast.IASTEnumeratorReference;
-import org.eclipse.cdt.core.parser.ast.IASTField;
-import org.eclipse.cdt.core.parser.ast.IASTFieldReference;
-import org.eclipse.cdt.core.parser.ast.IASTFunction;
-import org.eclipse.cdt.core.parser.ast.IASTFunctionReference;
-import org.eclipse.cdt.core.parser.ast.IASTInclusion;
-import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
-import org.eclipse.cdt.core.parser.ast.IASTMacro;
-import org.eclipse.cdt.core.parser.ast.IASTMethod;
-import org.eclipse.cdt.core.parser.ast.IASTMethodReference;
-import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
-import org.eclipse.cdt.core.parser.ast.IASTNamespaceReference;
-import org.eclipse.cdt.core.parser.ast.IASTParameterReference;
-import org.eclipse.cdt.core.parser.ast.IASTScope;
-import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
-import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
-import org.eclipse.cdt.core.parser.ast.IASTTemplateParameterReference;
-import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
-import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
-import org.eclipse.cdt.core.parser.ast.IASTTypedefReference;
-import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
-import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
 import org.eclipse.cdt.core.parser.ast.IASTVariable;
-import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
-import org.eclipse.cdt.internal.core.parser.Parser;
-import org.eclipse.cdt.internal.core.parser.ParserException;
-import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
-import org.eclipse.cdt.testplugin.CProjectHelper;
-import org.eclipse.cdt.testplugin.FileManager;
 import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
 
 /**
  * @author aniefer
  */
-public class CompleteParsePluginTest extends TestCase {
-    static NullProgressMonitor		monitor;
-    static IWorkspace 				workspace;
-    static IProject 				project;
-    static FileManager 				fileManager;
-    
-    {
-        if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){
-			(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
-			monitor = new NullProgressMonitor();
-			
-			workspace = ResourcesPlugin.getWorkspace();
-			
-			ICProject cPrj; 
-	        try {
-	            cPrj = CProjectHelper.createCCProject("ParserTestProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$
-	        
-	            project = cPrj.getProject();
-	            project.setSessionProperty(IndexManager.activationKey,new Boolean(false));
-	        } catch ( CoreException e ) {
-	            /*boo*/
-	        }
-			if (project == null)
-				fail("Unable to create project"); //$NON-NLS-1$
+public class CompleteParsePluginTest extends FileBasePluginTest {
 	
-			//Create file manager
-			fileManager = new FileManager();
-        }
-	}
-    
-    public CompleteParsePluginTest()
-    {
-        super();
-    }
     /**
      * @param name
      */
     public CompleteParsePluginTest(String name)
     {
-        super(name);
+    	super(name, CompleteParsePluginTest.class);
     }
-    
+
     public static Test suite() {
         TestSuite suite = new TestSuite( CompleteParsePluginTest.class );
         suite.addTest( new CompleteParsePluginTest("cleanupProject") );    //$NON-NLS-1$
 	    return suite;
     }
-    
-    public void cleanupProject() throws Exception {
-        try{
-	        project.delete( true, false, monitor );
-	        project = null;
-	    } catch( Throwable e ){
-	        /*boo*/
-	    }
-    }
-    
-    protected void tearDown() throws Exception {
-        if( project == null || !project.exists() ) 
-            return;
-        
-        IResource [] members = project.members();
-        for( int i = 0; i < members.length; i++ ){
-            if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$
-                continue;
-            try{
-                members[i].delete( false, monitor );
-            } catch( Throwable e ){
-                /*boo*/
-            }
-        }
-	}
-    protected IFile importFile(String fileName, String contents ) throws Exception{
-		//Obtain file handle
-		IFile file = project.getProject().getFile(fileName);
-		
-		InputStream stream = new ByteArrayInputStream( contents.getBytes() ); 
-		//Create file input stream
-		if( file.exists() )
-		    file.setContents( stream, false, false, monitor );
-		else
-			file.create( stream, false, monitor );
-		
-		fileManager.addFile(file);
-		
-		return file;
-	}
-    
-    public static class CallbackTracker implements ISourceElementRequestor{
-        private List callbacks;
-        private IASTScope compUnit;
-        public CallbackTracker( List callbacks ){
-            this.callbacks = callbacks;
-        }
-         
-        public IASTScope getCompilationUnit()
-        {
-        	return compUnit;
-        }
-        public static final String ACCEPT_PROBLEM = "ACCEPT_PROBLEM"; //$NON-NLS-1$
-        public static final String ACCEPT_MACRO = "ACCEPT_MACRO"; //$NON-NLS-1$
-        public static final String ACCEPT_VARIABLE = "ACCEPT_VARIABLE"; //$NON-NLS-1$
-        public static final String ACCEPT_FUNCTION_DECL = "ACCEPT_FUNCTION_DECL"; //$NON-NLS-1$
-        public static final String ACCEPT_USING_DIRECTIVE = "ACCEPT_USING_DIRECTIVE"; //$NON-NLS-1$
-        public static final String ACCEPT_USING_DECL = "ACCEPT_USING_DECL"; //$NON-NLS-1$
-        public static final String ACCEPT_ASM_DEF = "ACCEPT_ASM_DEF"; //$NON-NLS-1$
-        public static final String ACCEPT_TYPEDEF = "ACCEPT_TYPEDEF"; //$NON-NLS-1$
-        public static final String ACCEPT_ENUMERATION = "ACCEPT_ENUMERATION"; //$NON-NLS-1$
-        public static final String ACCEPT_ELABORATED = "ACCEPT_ELABORATED"; //$NON-NLS-1$
-        public static final String ACCEPT_ABSTRACT_TYPESPEC = "ACCEPT_ABSTRACT_TYPESPEC"; //$NON-NLS-1$
-        public static final String ACCEPT_METHOD = "ACCEPT_METHOD"; //$NON-NLS-1$
-        public static final String ACCEPT_FIELD = "ACCEPT_FIELD"; //$NON-NLS-1$
-        public static final String ACCEPT_REFERENCE = "ACCEPT_REFERENCE"; //$NON-NLS-1$
-        public static final String ACCEPT_FRIEND = "ACCEPT_FRIEND"; //$NON-NLS-1$
-        public static final String ENTER_FUNCTION = "ENTER_FUNCTION"; //$NON-NLS-1$
-        public static final String ENTER_CODE_BLOCK = "ENTER_CODE_BLOCK"; //$NON-NLS-1$
-        public static final String ENTER_COMPILATION_UNIT = "ENTER_COMPILATION_UNIT"; //$NON-NLS-1$
-        public static final String ENTER_INCLUSION = "ENTER_INCLUSION"; //$NON-NLS-1$
-        public static final String ENTER_NAMESPACE = "ENTER_NAMESPACE"; //$NON-NLS-1$
-        public static final String ENTER_CLASS_SPEC = "ENTER_CLASS_SPEC"; //$NON-NLS-1$
-        public static final String ENTER_LINKAGE = "ENTER_LINKAGE"; //$NON-NLS-1$
-        public static final String ENTER_TEMPLATE_DECL = "ENTER_TEMPLATE_DECL"; //$NON-NLS-1$
-        public static final String ENTER_TEMPLATE_SPEC = "ENTER_TEMPLATE_SPEC"; //$NON-NLS-1$
-        public static final String ENTER_TEMPLATE_INSTANCE = "ENTER_TEMPLATE_INSTANCE"; //$NON-NLS-1$
-        public static final String ENTER_METHOD = "ENTER_METHOD"; //$NON-NLS-1$
-        public static final String EXIT_FUNCTION = "EXIT_FUNCTION"; //$NON-NLS-1$
-        public static final String EXIT_CODE_BLOCK = "EXIT_CODE_BLOCK"; //$NON-NLS-1$
-        public static final String EXIT_METHOD = "EXIT_METHOD"; //$NON-NLS-1$
-        public static final String EXIT_TEMPLATE_DECL = "EXIT_TEMPLATE_DECL"; //$NON-NLS-1$
-        public static final String EXIT_TEMPLATE_SPEC = "EXIT_TEMPLATE_SPEC"; //$NON-NLS-1$
-        public static final String EXIT_TEMPLATE_INSTANCE = "EXIT_TEMPLATE_INSTANCE"; //$NON-NLS-1$
-        public static final String EXIT_LINKAGE = "EXIT_LINKAGE"; //$NON-NLS-1$
-        public static final String EXIT_CLASS = "EXIT_CLASS"; //$NON-NLS-1$
-        public static final String EXIT_NAMESPACE = "EXIT_NAMESPACE"; //$NON-NLS-1$
-        public static final String EXIT_INCLUSION = "EXIT_INCLUSION"; //$NON-NLS-1$
-        public static final String EXIT_COMPILATION_UNIT = "EXIT_COMPILATION_UNIT"; //$NON-NLS-1$
-        
-        
-        public boolean acceptProblem( IProblem problem ) {
-            callbacks.add( ACCEPT_PROBLEM );
-            return false;
-        }
-        public void acceptMacro( IASTMacro macro ) 										{ callbacks.add( ACCEPT_MACRO ); }
-        public void acceptVariable( IASTVariable variable ) 							{ callbacks.add( ACCEPT_VARIABLE ); }
-        public void acceptFunctionDeclaration( IASTFunction function )					{ callbacks.add( ACCEPT_FUNCTION_DECL); }
-        public void acceptUsingDirective( IASTUsingDirective usageDirective ) 			{ callbacks.add( ACCEPT_USING_DIRECTIVE ); }
-        public void acceptUsingDeclaration( IASTUsingDeclaration usageDeclaration ) 	{ callbacks.add( ACCEPT_USING_DECL ); }
-        public void acceptASMDefinition( IASTASMDefinition asmDefinition ) 				{ callbacks.add( ACCEPT_ASM_DEF ); }
-        public void acceptTypedefDeclaration( IASTTypedefDeclaration typedef ) 			{ callbacks.add( ACCEPT_TYPEDEF ); }
-        public void acceptEnumerationSpecifier( IASTEnumerationSpecifier enumeration ) 	{ callbacks.add( ACCEPT_ENUMERATION); }
-        public void acceptElaboratedForewardDeclaration( IASTElaboratedTypeSpecifier elaboratedType ) { callbacks.add( ACCEPT_ELABORATED ); }
-        public void acceptAbstractTypeSpecDeclaration( IASTAbstractTypeSpecifierDeclaration abstractDeclaration ) { callbacks.add( ACCEPT_ABSTRACT_TYPESPEC); }
-        public void enterFunctionBody( IASTFunction function )							{ callbacks.add( ENTER_FUNCTION ); }
-        public void exitFunctionBody( IASTFunction function ) 							{ callbacks.add( EXIT_FUNCTION ); }
-        public void enterCodeBlock( IASTCodeScope scope ) 								{ callbacks.add( ENTER_CODE_BLOCK ); }
-        public void exitCodeBlock( IASTCodeScope scope ) 								{ callbacks.add( EXIT_CODE_BLOCK ); }
-        public void enterInclusion( IASTInclusion inclusion )							{ callbacks.add( ENTER_INCLUSION ); }
-        public void enterNamespaceDefinition( IASTNamespaceDefinition namespaceDefinition )			{ callbacks.add( ENTER_NAMESPACE ); }
-        public void enterClassSpecifier( IASTClassSpecifier classSpecification ) 		{ callbacks.add( ENTER_CLASS_SPEC ); }
-        public void enterLinkageSpecification( IASTLinkageSpecification linkageSpec ) 	{ callbacks.add( ENTER_LINKAGE ); }
-        public void enterTemplateDeclaration( IASTTemplateDeclaration declaration ) 	{ callbacks.add( ENTER_TEMPLATE_DECL ); }
-        public void enterTemplateSpecialization( IASTTemplateSpecialization specialization )		{ callbacks.add( ENTER_TEMPLATE_SPEC ); }
-        public void enterTemplateInstantiation( IASTTemplateInstantiation instantiation ) 			{ callbacks.add( ENTER_TEMPLATE_INSTANCE ); }
-        public void acceptMethodDeclaration( IASTMethod method ) 						{ callbacks.add( ACCEPT_METHOD ); }
-        public void enterMethodBody( IASTMethod method ) 								{ callbacks.add( ENTER_METHOD ); }
-        public void exitMethodBody( IASTMethod method ) 								{ callbacks.add( EXIT_METHOD ); }
-        public void acceptField( IASTField field ) 										{ callbacks.add( ACCEPT_FIELD ); }
-        public void acceptClassReference( IASTClassReference reference ) 				{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptTypedefReference( IASTTypedefReference reference )			{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptNamespaceReference( IASTNamespaceReference reference ) 		{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptEnumerationReference( IASTEnumerationReference reference ) 	{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptVariableReference( IASTVariableReference reference ) 			{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptFunctionReference( IASTFunctionReference reference ) 			{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptFieldReference( IASTFieldReference reference )	 			{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptMethodReference( IASTMethodReference reference ) 				{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptEnumeratorReference( IASTEnumeratorReference reference ) 		{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptParameterReference( IASTParameterReference reference ) 		{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptTemplateParameterReference( IASTTemplateParameterReference reference ) 	{ callbacks.add( ACCEPT_REFERENCE ); }
-        public void acceptFriendDeclaration( IASTDeclaration declaration ) 				{ callbacks.add( ACCEPT_FRIEND ); }
-        public void exitTemplateDeclaration( IASTTemplateDeclaration declaration ) 		{ callbacks.add( EXIT_TEMPLATE_DECL); }
-        public void exitTemplateSpecialization( IASTTemplateSpecialization specialization ) 		{ callbacks.add( EXIT_TEMPLATE_SPEC ); }
-        public void exitTemplateExplicitInstantiation( IASTTemplateInstantiation instantiation ) 	{ callbacks.add( EXIT_TEMPLATE_INSTANCE ); }
-        public void exitLinkageSpecification( IASTLinkageSpecification linkageSpec ) 	{ callbacks.add( ACCEPT_MACRO ); }
-        public void exitClassSpecifier( IASTClassSpecifier classSpecification )			{ callbacks.add( EXIT_CLASS ); }
-        public void exitNamespaceDefinition( IASTNamespaceDefinition namespaceDefinition ) { callbacks.add( EXIT_NAMESPACE); }
-        public void exitInclusion( IASTInclusion inclusion ) 							{ callbacks.add( EXIT_INCLUSION ); }
-        public void exitCompilationUnit( IASTCompilationUnit compilationUnit ) 			{ callbacks.add( EXIT_COMPILATION_UNIT ); }
-        public void enterCompilationUnit( IASTCompilationUnit compilationUnit ) 		
-        { 
-        	callbacks.add( ENTER_COMPILATION_UNIT );
-        	compUnit = compilationUnit;
-        }
-        public CodeReader createReader( String finalPath, Iterator workingCopies ) { 
-            return ParserUtil.createReader(finalPath,workingCopies);
-        }
-        
-    }
-	public CallbackTracker callback;
-	protected IASTScope parse( IFile code, List callbacks ) throws Exception
-    {
-    	return parse( code, callbacks, ParserLanguage.CPP );
-    }
-        
-    protected IASTScope parse(IFile code, List callbackList, ParserLanguage language) throws Exception
-    {
-    	callback = new CallbackTracker( callbackList ); 
-    	InputStream stream = code.getContents();
-    	IParser parser = ParserFactory.createParser( 
-    		ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), new ScannerInfo(), //$NON-NLS-1$
-    			ParserMode.COMPLETE_PARSE, language, callback, new NullLogService(), null ), callback, ParserMode.COMPLETE_PARSE, language, null 	
-    		);
-    	stream.close();
-    	boolean parseResult = parser.parse();
-    	// throw exception if there are generated IProblems
-		if( !parseResult ) throw new ParserException( "FAILURE"); //$NON-NLS-1$
-		if( parseResult  )
-		{
-			assertTrue( ((Parser)parser).validateCaches());
-		}
-        return callback.getCompilationUnit();
-    }
-    
+	
     public void testBug72219() throws Exception {
         String foo = "int FOO;"; //$NON-NLS-1$
         String code = "#include \"foo.h\" \n   int bar;"; //$NON-NLS-1$
Index: parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java,v
retrieving revision 1.27
diff -u -r1.27 ParserTestSuite.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java	11 Sep 2004 23:04:18 -0000	1.27
+++ parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java	1 Oct 2004 15:13:56 -0000
@@ -48,6 +48,7 @@
 		suite.addTestSuite( StructuralParseTest.class );
 		suite.addTestSuite( ObjectMapTest.class );
 		suite.addTest( CompleteParsePluginTest.suite() );
+		suite.addTest( ScannerParserLoopTest.suite() );
 		suite.addTest( GCCParserExtensionTestSuite.suite() );
 		return suite;
 	}	
Index: parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java
diff -N parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * 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 Corporation - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Created on Sept 28, 2004
+ */
+package org.eclipse.cdt.core.parser.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.parser.CodeReader;
+import org.eclipse.cdt.core.parser.IParser;
+import org.eclipse.cdt.core.parser.IProblem;
+import org.eclipse.cdt.core.parser.ISourceElementRequestor;
+import org.eclipse.cdt.core.parser.NullLogService;
+import org.eclipse.cdt.core.parser.ParserFactory;
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.core.parser.ParserUtil;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTClassReference;
+import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
+import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
+import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTEnumerationReference;
+import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTEnumeratorReference;
+import org.eclipse.cdt.core.parser.ast.IASTField;
+import org.eclipse.cdt.core.parser.ast.IASTFieldReference;
+import org.eclipse.cdt.core.parser.ast.IASTFunction;
+import org.eclipse.cdt.core.parser.ast.IASTFunctionReference;
+import org.eclipse.cdt.core.parser.ast.IASTInclusion;
+import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
+import org.eclipse.cdt.core.parser.ast.IASTMacro;
+import org.eclipse.cdt.core.parser.ast.IASTMethod;
+import org.eclipse.cdt.core.parser.ast.IASTMethodReference;
+import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTNamespaceReference;
+import org.eclipse.cdt.core.parser.ast.IASTParameterReference;
+import org.eclipse.cdt.core.parser.ast.IASTScope;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateParameterReference;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
+import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTTypedefReference;
+import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
+import org.eclipse.cdt.core.parser.ast.IASTVariable;
+import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
+
+import org.eclipse.cdt.internal.core.parser.Parser;
+import org.eclipse.cdt.internal.core.parser.ParserException;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.cdt.testplugin.CProjectHelper;
+import org.eclipse.cdt.testplugin.CTestPlugin;
+import org.eclipse.cdt.testplugin.FileManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+
+/**
+ * @author dsteffle
+ */
+public class FileBasePluginTest extends TestCase {
+    static NullProgressMonitor		monitor;
+    static IWorkspace 				workspace;
+    static IProject 				project;
+    static FileManager 				fileManager;
+    static int						numProjects = 0;
+    static Class					className;
+	static ICProject cPrj; 
+
+    private void initialize(Class aClassName){
+        if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){
+			(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
+			monitor = new NullProgressMonitor();
+			
+			workspace = ResourcesPlugin.getWorkspace();
+			
+	        try {
+	        	cPrj = CProjectHelper.createCCProject("ParserTestProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$
+	        	
+	            project = cPrj.getProject();
+	            project.setSessionProperty(IndexManager.activationKey,new Boolean(false));
+	            
+	            if (className == null || !className.equals(aClassName)) {
+	            	className = aClassName;
+	            	numProjects++;
+	            }
+	            
+	        } catch ( CoreException e ) {
+	            /*boo*/
+	        }
+			if (project == null)
+				throw new NullPointerException("Unable to create project"); //$NON-NLS-1$
+	
+			//Create file manager
+			fileManager = new FileManager();
+        }
+    }
+
+    public FileBasePluginTest(String name, Class className)
+    {
+    	super(name);
+    	initialize(className);
+    }
+    
+    public void incNumProjects() {
+        numProjects++;
+    }
+    
+    public void cleanupProject() throws Exception {
+    	numProjects--;
+    	
+    	try{
+    		if (numProjects == 0) {
+    			project.delete( true, false, monitor );
+    			project = null;
+    		}
+	    } catch( Throwable e ){
+	        /*boo*/
+	    }
+    }
+
+    protected void tearDown() throws Exception {
+        if( project == null || !project.exists() ) 
+            return;
+        
+        IResource [] members = project.members();
+        for( int i = 0; i < members.length; i++ ){
+            if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$
+                continue;
+            try{
+                members[i].delete( false, monitor );
+            } catch( Throwable e ){
+                /*boo*/
+            }
+        }
+	}
+
+    // below can be used to work with large files (too large for memory)
+    protected IFile importFile(String fileName) throws Exception {
+		IFile file = cPrj.getProject().getFile(fileName);
+		if (!file.exists()) {
+			try{
+				FileInputStream fileIn = new FileInputStream(
+						CTestPlugin.getDefault().getFileInPlugin(new Path("resources/parser/" + fileName))); 
+				file.create(fileIn,false, monitor);        
+			} catch (CoreException e) {
+				e.printStackTrace();
+			} catch (FileNotFoundException e) {
+				e.printStackTrace();
+			}
+		}
+		
+		return file;
+    }
+    
+    protected IFile importFile(String fileName, String contents ) throws Exception{
+		//Obtain file handle
+		IFile file = project.getProject().getFile(fileName);
+		
+		InputStream stream = new ByteArrayInputStream( contents.getBytes() ); 
+		//Create file input stream
+		if( file.exists() )
+		    file.setContents( stream, false, false, monitor );
+		else
+			file.create( stream, false, monitor );
+		
+		fileManager.addFile(file);
+		
+		return file;
+	}
+    
+    public static class CallbackTracker implements ISourceElementRequestor{
+        private List callbacks;
+        private IASTScope compUnit;
+        public CallbackTracker( List callbacks ){
+            this.callbacks = callbacks;
+        }
+         
+        public IASTScope getCompilationUnit()
+        {
+        	return compUnit;
+        }
+        public static final String ACCEPT_PROBLEM = "ACCEPT_PROBLEM"; //$NON-NLS-1$
+        public static final String ACCEPT_MACRO = "ACCEPT_MACRO"; //$NON-NLS-1$
+        public static final String ACCEPT_VARIABLE = "ACCEPT_VARIABLE"; //$NON-NLS-1$
+        public static final String ACCEPT_FUNCTION_DECL = "ACCEPT_FUNCTION_DECL"; //$NON-NLS-1$
+        public static final String ACCEPT_USING_DIRECTIVE = "ACCEPT_USING_DIRECTIVE"; //$NON-NLS-1$
+        public static final String ACCEPT_USING_DECL = "ACCEPT_USING_DECL"; //$NON-NLS-1$
+        public static final String ACCEPT_ASM_DEF = "ACCEPT_ASM_DEF"; //$NON-NLS-1$
+        public static final String ACCEPT_TYPEDEF = "ACCEPT_TYPEDEF"; //$NON-NLS-1$
+        public static final String ACCEPT_ENUMERATION = "ACCEPT_ENUMERATION"; //$NON-NLS-1$
+        public static final String ACCEPT_ELABORATED = "ACCEPT_ELABORATED"; //$NON-NLS-1$
+        public static final String ACCEPT_ABSTRACT_TYPESPEC = "ACCEPT_ABSTRACT_TYPESPEC"; //$NON-NLS-1$
+        public static final String ACCEPT_METHOD = "ACCEPT_METHOD"; //$NON-NLS-1$
+        public static final String ACCEPT_FIELD = "ACCEPT_FIELD"; //$NON-NLS-1$
+        public static final String ACCEPT_REFERENCE = "ACCEPT_REFERENCE"; //$NON-NLS-1$
+        public static final String ACCEPT_FRIEND = "ACCEPT_FRIEND"; //$NON-NLS-1$
+        public static final String ENTER_FUNCTION = "ENTER_FUNCTION"; //$NON-NLS-1$
+        public static final String ENTER_CODE_BLOCK = "ENTER_CODE_BLOCK"; //$NON-NLS-1$
+        public static final String ENTER_COMPILATION_UNIT = "ENTER_COMPILATION_UNIT"; //$NON-NLS-1$
+        public static final String ENTER_INCLUSION = "ENTER_INCLUSION"; //$NON-NLS-1$
+        public static final String ENTER_NAMESPACE = "ENTER_NAMESPACE"; //$NON-NLS-1$
+        public static final String ENTER_CLASS_SPEC = "ENTER_CLASS_SPEC"; //$NON-NLS-1$
+        public static final String ENTER_LINKAGE = "ENTER_LINKAGE"; //$NON-NLS-1$
+        public static final String ENTER_TEMPLATE_DECL = "ENTER_TEMPLATE_DECL"; //$NON-NLS-1$
+        public static final String ENTER_TEMPLATE_SPEC = "ENTER_TEMPLATE_SPEC"; //$NON-NLS-1$
+        public static final String ENTER_TEMPLATE_INSTANCE = "ENTER_TEMPLATE_INSTANCE"; //$NON-NLS-1$
+        public static final String ENTER_METHOD = "ENTER_METHOD"; //$NON-NLS-1$
+        public static final String EXIT_FUNCTION = "EXIT_FUNCTION"; //$NON-NLS-1$
+        public static final String EXIT_CODE_BLOCK = "EXIT_CODE_BLOCK"; //$NON-NLS-1$
+        public static final String EXIT_METHOD = "EXIT_METHOD"; //$NON-NLS-1$
+        public static final String EXIT_TEMPLATE_DECL = "EXIT_TEMPLATE_DECL"; //$NON-NLS-1$
+        public static final String EXIT_TEMPLATE_SPEC = "EXIT_TEMPLATE_SPEC"; //$NON-NLS-1$
+        public static final String EXIT_TEMPLATE_INSTANCE = "EXIT_TEMPLATE_INSTANCE"; //$NON-NLS-1$
+        public static final String EXIT_LINKAGE = "EXIT_LINKAGE"; //$NON-NLS-1$
+        public static final String EXIT_CLASS = "EXIT_CLASS"; //$NON-NLS-1$
+        public static final String EXIT_NAMESPACE = "EXIT_NAMESPACE"; //$NON-NLS-1$
+        public static final String EXIT_INCLUSION = "EXIT_INCLUSION"; //$NON-NLS-1$
+        public static final String EXIT_COMPILATION_UNIT = "EXIT_COMPILATION_UNIT"; //$NON-NLS-1$
+        
+        
+        public boolean acceptProblem( IProblem problem ) {
+            callbacks.add( ACCEPT_PROBLEM );
+            return false;
+        }
+        public void acceptMacro( IASTMacro macro ) 										{ callbacks.add( ACCEPT_MACRO ); }
+        public void acceptVariable( IASTVariable variable ) 							{ callbacks.add( ACCEPT_VARIABLE ); }
+        public void acceptFunctionDeclaration( IASTFunction function )					{ callbacks.add( ACCEPT_FUNCTION_DECL); }
+        public void acceptUsingDirective( IASTUsingDirective usageDirective ) 			{ callbacks.add( ACCEPT_USING_DIRECTIVE ); }
+        public void acceptUsingDeclaration( IASTUsingDeclaration usageDeclaration ) 	{ callbacks.add( ACCEPT_USING_DECL ); }
+        public void acceptASMDefinition( IASTASMDefinition asmDefinition ) 				{ callbacks.add( ACCEPT_ASM_DEF ); }
+        public void acceptTypedefDeclaration( IASTTypedefDeclaration typedef ) 			{ callbacks.add( ACCEPT_TYPEDEF ); }
+        public void acceptEnumerationSpecifier( IASTEnumerationSpecifier enumeration ) 	{ callbacks.add( ACCEPT_ENUMERATION); }
+        public void acceptElaboratedForewardDeclaration( IASTElaboratedTypeSpecifier elaboratedType ) { callbacks.add( ACCEPT_ELABORATED ); }
+        public void acceptAbstractTypeSpecDeclaration( IASTAbstractTypeSpecifierDeclaration abstractDeclaration ) { callbacks.add( ACCEPT_ABSTRACT_TYPESPEC); }
+        public void enterFunctionBody( IASTFunction function )							{ callbacks.add( ENTER_FUNCTION ); }
+        public void exitFunctionBody( IASTFunction function ) 							{ callbacks.add( EXIT_FUNCTION ); }
+        public void enterCodeBlock( IASTCodeScope scope ) 								{ callbacks.add( ENTER_CODE_BLOCK ); }
+        public void exitCodeBlock( IASTCodeScope scope ) 								{ callbacks.add( EXIT_CODE_BLOCK ); }
+        public void enterInclusion( IASTInclusion inclusion )							{ callbacks.add( ENTER_INCLUSION ); }
+        public void enterNamespaceDefinition( IASTNamespaceDefinition namespaceDefinition )			{ callbacks.add( ENTER_NAMESPACE ); }
+        public void enterClassSpecifier( IASTClassSpecifier classSpecification ) 		{ callbacks.add( ENTER_CLASS_SPEC ); }
+        public void enterLinkageSpecification( IASTLinkageSpecification linkageSpec ) 	{ callbacks.add( ENTER_LINKAGE ); }
+        public void enterTemplateDeclaration( IASTTemplateDeclaration declaration ) 	{ callbacks.add( ENTER_TEMPLATE_DECL ); }
+        public void enterTemplateSpecialization( IASTTemplateSpecialization specialization )		{ callbacks.add( ENTER_TEMPLATE_SPEC ); }
+        public void enterTemplateInstantiation( IASTTemplateInstantiation instantiation ) 			{ callbacks.add( ENTER_TEMPLATE_INSTANCE ); }
+        public void acceptMethodDeclaration( IASTMethod method ) 						{ callbacks.add( ACCEPT_METHOD ); }
+        public void enterMethodBody( IASTMethod method ) 								{ callbacks.add( ENTER_METHOD ); }
+        public void exitMethodBody( IASTMethod method ) 								{ callbacks.add( EXIT_METHOD ); }
+        public void acceptField( IASTField field ) 										{ callbacks.add( ACCEPT_FIELD ); }
+        public void acceptClassReference( IASTClassReference reference ) 				{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptTypedefReference( IASTTypedefReference reference )			{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptNamespaceReference( IASTNamespaceReference reference ) 		{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptEnumerationReference( IASTEnumerationReference reference ) 	{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptVariableReference( IASTVariableReference reference ) 			{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptFunctionReference( IASTFunctionReference reference ) 			{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptFieldReference( IASTFieldReference reference )	 			{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptMethodReference( IASTMethodReference reference ) 				{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptEnumeratorReference( IASTEnumeratorReference reference ) 		{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptParameterReference( IASTParameterReference reference ) 		{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptTemplateParameterReference( IASTTemplateParameterReference reference ) 	{ callbacks.add( ACCEPT_REFERENCE ); }
+        public void acceptFriendDeclaration( IASTDeclaration declaration ) 				{ callbacks.add( ACCEPT_FRIEND ); }
+        public void exitTemplateDeclaration( IASTTemplateDeclaration declaration ) 		{ callbacks.add( EXIT_TEMPLATE_DECL); }
+        public void exitTemplateSpecialization( IASTTemplateSpecialization specialization ) 		{ callbacks.add( EXIT_TEMPLATE_SPEC ); }
+        public void exitTemplateExplicitInstantiation( IASTTemplateInstantiation instantiation ) 	{ callbacks.add( EXIT_TEMPLATE_INSTANCE ); }
+        public void exitLinkageSpecification( IASTLinkageSpecification linkageSpec ) 	{ callbacks.add( ACCEPT_MACRO ); }
+        public void exitClassSpecifier( IASTClassSpecifier classSpecification )			{ callbacks.add( EXIT_CLASS ); }
+        public void exitNamespaceDefinition( IASTNamespaceDefinition namespaceDefinition ) { callbacks.add( EXIT_NAMESPACE); }
+        public void exitInclusion( IASTInclusion inclusion ) 							{ callbacks.add( EXIT_INCLUSION ); }
+        public void exitCompilationUnit( IASTCompilationUnit compilationUnit ) 			{ callbacks.add( EXIT_COMPILATION_UNIT ); }
+        public void enterCompilationUnit( IASTCompilationUnit compilationUnit ) 		
+        { 
+        	callbacks.add( ENTER_COMPILATION_UNIT );
+        	compUnit = compilationUnit;
+        }
+        public CodeReader createReader( String finalPath, Iterator workingCopies ) { 
+            return ParserUtil.createReader(finalPath,workingCopies);
+        }
+        
+    }
+	public CallbackTracker callback;
+	protected IASTScope parse( IFile code, List callbacks ) throws Exception
+    {
+    	return parse( code, callbacks, ParserLanguage.CPP );
+    }
+        
+    protected IASTScope parse(IFile code, List callbackList, ParserLanguage language) throws Exception
+    {
+    	callback = new CallbackTracker( callbackList ); 
+    	InputStream stream = code.getContents();
+    	IParser parser = ParserFactory.createParser( 
+    		ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), new ScannerInfo(), //$NON-NLS-1$
+    			ParserMode.COMPLETE_PARSE, language, callback, new NullLogService(), null ), callback, ParserMode.COMPLETE_PARSE, language, null 	
+    		);
+    	stream.close();
+    	boolean parseResult = parser.parse();
+    	// throw exception if there are generated IProblems
+		if( !parseResult ) throw new ParserException( "FAILURE"); //$NON-NLS-1$
+		if( parseResult  )
+		{
+			assertTrue( ((Parser)parser).validateCaches());
+		}
+        return callback.getCompilationUnit();
+    }
+	
+}
Index: parser/org/eclipse/cdt/core/parser/tests/ScannerParserLoopTest.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/parser/tests/ScannerParserLoopTest.java
diff -N parser/org/eclipse/cdt/core/parser/tests/ScannerParserLoopTest.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/parser/tests/ScannerParserLoopTest.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * 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 Corporation - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * Created on Sept 30, 2004
+ */
+package org.eclipse.cdt.core.parser.tests;
+
+import java.io.StringWriter;
+import java.io.Writer;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.parser.CodeReader;
+import org.eclipse.cdt.core.parser.IParser;
+import org.eclipse.cdt.core.parser.ISourceElementRequestor;
+import org.eclipse.cdt.core.parser.NullLogService;
+import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
+import org.eclipse.cdt.core.parser.ParseError;
+import org.eclipse.cdt.core.parser.ParserFactory;
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.core.parser.ParserTimeOut;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
+
+/**
+ * @author dsteffle
+ */
+public class ScannerParserLoopTest extends FileBasePluginTest {
+	private static final int CANCEL_TIMEOUT_RATIO = 4;
+	private static final int NUMBER_ITERATIONS = 50000;
+
+	public ScannerParserLoopTest(String name) {
+		super(name, ScannerParserLoopTest.class);
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(ScannerParserLoopTest.class);
+		suite.addTest(new ScannerParserLoopTest("cleanupProject")); //$NON-NLS-1$
+		return suite;
+	}
+
+	// test scanner (tests isCancelled)
+	public void testBug72611A() throws Exception {
+		Writer writer = new StringWriter();
+
+		for (int i = 0; i < NUMBER_ITERATIONS; i++) {
+			writer.write("#define A");
+			writer.write(i);
+			writer.write(" B");
+			writer.write(i);
+			writer.write("\n");
+			writer.write("#define B");
+			writer.write(i);
+			writer.write(" C");
+			writer.write(i);
+			writer.write("\n");
+			writer.write("#define C");
+			writer.write(i);
+			writer.write(" D");
+			writer.write(i);
+			writer.write("\n");
+		}
+
+		runCancelTest(writer);
+	}
+
+	// test scanner (tests bufferPos[index] = bufferLimit[index] in Scanner2.cancel())
+	public void testBug72611B() throws Exception {
+		Writer writer = new StringWriter();
+
+		writer.write("/**\n");
+		for (int i = 0; i < NUMBER_ITERATIONS; i++) {
+			writer.write("***************************");
+			writer.write("* comment line number ");
+			writer.write(i);
+			writer.write("***************************");
+			writer.write(" \n");
+		}
+		writer.write("*/\n");
+
+		runCancelTest(writer);
+	}
+	
+	// test parser
+	public void testBug72611C() throws Exception {
+		Writer writer = new StringWriter();
+
+		for (int i = 0; i < NUMBER_ITERATIONS; i++) {
+			writer.write("int a");
+			writer.write(i);
+			writer.write("; // comment\n");
+		}
+
+		runCancelTest(writer);
+	}
+
+	private void runCancelTest(Writer writer) throws Exception {
+		IFile file = importFile("code.cpp", writer.toString()); //$NON-NLS-1$
+
+		ParserTimeOut pto = new ParserTimeOut();
+
+		TimeoutCallback callback = new TimeoutCallback();
+		callback.setParserTimeOut(pto);
+
+		IParser parserOne = ParserFactory.createParser(ParserFactory
+				.createScanner(
+						new CodeReader(file.getRawLocation().toString()),
+						new ScannerInfo(), //$NON-NLS-1$
+						ParserMode.COMPLETE_PARSE, ParserLanguage.CPP,
+						callback, new NullLogService(), null), callback,
+				ParserMode.COMPLETE_PARSE, ParserLanguage.CPP, null);
+
+		long parseTimeOne = 0;
+		long parseTimeTwo = 0;
+		long startTime = 0;
+		try {
+			startTime = System.currentTimeMillis();
+			parserOne.parse();
+			parseTimeOne = System.currentTimeMillis() - startTime;
+
+			IParser parserTwo = ParserFactory.createParser(ParserFactory
+					.createScanner(new CodeReader(file.getRawLocation()
+							.toString()), new ScannerInfo(), //$NON-NLS-1$
+							ParserMode.COMPLETE_PARSE, ParserLanguage.CPP,
+							callback, new NullLogService(), null), callback,
+					ParserMode.COMPLETE_PARSE, ParserLanguage.CPP, null);
+
+			pto.setParser(parserTwo);
+			pto.setTimeout((int) (parseTimeOne / CANCEL_TIMEOUT_RATIO));
+			startTime = System.currentTimeMillis();
+			parserTwo.parse();
+
+			assertTrue(false);
+		} catch (ParseError pe) {
+			parseTimeTwo = System.currentTimeMillis() - startTime;
+			// expected
+			assertEquals(pe.getErrorKind(),
+					ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
+		}
+	}
+
+	private static class TimeoutCallback extends NullSourceElementRequestor
+			implements ISourceElementRequestor {
+		private ParserTimeOut timeout;
+
+		public void setParserTimeOut(ParserTimeOut pto) {
+			timeout = pto;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterCompilationUnit(org.eclipse.cdt.core.parser.ast.IASTCompilationUnit)
+		 */
+		public void enterCompilationUnit(IASTCompilationUnit compilationUnit) {
+			timeout.startTimer();
+		}
+	}
+}

Back to the top