Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: fb7b309bde9de6b2d0a8b3b25f3071f5cc20d952 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                                                
                            





                                        
                                           
                                                  
                                                 
                                                  
                                              
                                               



















































































































































































































                                                                                                                                              
                                                                                                            
                                                                             
                                                                                                                                                                                                                                                        
                                












                                                                 
/*******************************************************************************
 * Copyright (c) 2001 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v0.5 
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *     IBM Corp. - Rational Software - initial implementation
 ******************************************************************************/
package org.eclipse.cdt.core.parser.tests;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import junit.framework.Test;

import org.eclipse.cdt.core.parser.IParser;
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.ScannerInfo;
import org.eclipse.core.runtime.Path;

/**
 * @author aniefer
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class FractionalAutomatedTest extends AutomatedFramework {

	public FractionalAutomatedTest() {
		super();
	}

	public FractionalAutomatedTest(String name) {
		super(name);
	}
	
	protected AutomatedFramework newTest( String name ){
		return new FractionalAutomatedTest( name );
	}
	protected void loadProperties() throws Exception{
		String resourcePath = org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile();
		resourcePath += "resources/parser/AutomatedTest";
	
		try{
			FileInputStream propertiesIn = new FileInputStream( resourcePath + "/FractionalAutomatedTest.properties");
			properties.load( propertiesIn );
		
			outputFile = properties.getProperty( "outputFile", "" );
			String sourceInfo = properties.getProperty( "source", "" );

			stepSize = Integer.parseInt( properties.getProperty( "stepSize", "50" ) );
			windowSize = Integer.parseInt( properties.getProperty( "windowSize", "200" ) );
			timeOut = Integer.parseInt( properties.getProperty( "timeOut", "5000" ));
			outputDir = properties.getProperty( "outDir", "" );
			
			if( sourceInfo.equals("") )
				throw new FileNotFoundException();
			else{
				StringTokenizer tokenizer = new StringTokenizer( sourceInfo, "," );
				String str = null, val = null;
				try{
					while( tokenizer.hasMoreTokens() ){
						str = tokenizer.nextToken().trim();
						val = tokenizer.nextToken().trim();
					
						testSources.put( str, val );
					}
				} catch ( NoSuchElementException e ){
					//only way to get here is to have a missing val, assume cpp for that str
					testSources.put( str, "cpp" );
				}
			
			}
		} catch ( FileNotFoundException e ){
			testSources.put( resourcePath + "/defaultCpp", "cpp" );
			testSources.put( resourcePath + "/defaultC", "c" );
		}
	}
	
	public static Test suite()
	{
		AutomatedFramework frame = new FractionalAutomatedTest();
		
		return frame.createSuite();
	}
	
	static private String outputFile( String code ) {
		if( outputDir == null || outputDir.equals("") )
			return "";
			
		File output = new File( outputDir );
				
		try{
			if( output.exists() ){
				if( output.isFile() ){
					output.delete();
					output.createNewFile();
					FileOutputStream stream = new FileOutputStream( output );
					stream.write( code.getBytes() );
					stream.flush();
					stream.close();
					return outputDir;
				}
			} else {
				output.mkdir();
			}
			File file = new File( outputDir + "/" + failures++ + ".tmp" );
			if( file.exists() )
				file.delete();
			file.createNewFile();
			FileOutputStream stream = new FileOutputStream( file );
			stream.write( code.getBytes() );
			stream.flush();
			stream.close();
			
			return file.getCanonicalPath();
			
		} catch ( Exception e )
		{}
		return "";
	}
	
	static public void reportHang( String code, String file ){
		String output = outputFile( code.toString() );
		if( output.equals("") )
			output = "Parser hang while parsing " + file + "\n";
		else 
			output = "Parser hang while parsing " + output + "\n";
	 
		if( report != null ){
			try{
				report.write( output.getBytes() );
			} catch ( IOException e ) {}
		}

		fail( output );
	}
	
	static public void reportException( String code, String file, String exception ){
		String output = outputFile( code.toString() );

		if( output.equals("") )
			output = exception.getClass().toString() + " encountered in " + file + "\n";
		else 
			output = exception.getClass().toString() + " encountered in " + output + "\n";
	 
		if( report != null ){
			try{
				report.write( output.getBytes() );
			} catch ( IOException e ) {}
		}
		
		fail( output );
	}
	
	public void doFile() throws Throwable {
		assertNotNull( fileList );
		
		File file = (File)fileList.removeFirst();
		FileInputStream stream = new FileInputStream( file );

		String filePath = file.getCanonicalPath();
		String nature = (String)natures.get( filePath );

		boolean cppNature = nature.equalsIgnoreCase("cpp");
		
		StringWriter code = new StringWriter(); 
		
		ParseThread thread = new ParseThread();
		
		byte b[] = new byte[stepSize]; 
		int n = stream.read( b );
		while( n != -1 ){
			code.write( new String( b ) );

			thread.code = code.toString();
			thread.cppNature = cppNature;
			thread.start();
			thread.join( timeOut );
			
			if( thread.isAlive() ){
				//Use deprecated Thread.stop() for now
				//alternative is to create a callback which could stop the parse on a flag
				//by throwing something, but that has the disadvantage of being unable to 
				//stop any loops that don't involve callbacks.
				thread.stop();
				reportHang( code.toString(), filePath );
			} else if( thread.result != null ) {
				reportException( code.toString(), filePath, thread.result );
			}
			
			n = stream.read( b );
		}
		
		String fullCode = code.toString();
		String windowedCode = null;
		int length = fullCode.length();
		int curPos = 0;
		
		while( curPos + windowSize < length){
			windowedCode = fullCode.substring( 0, curPos );
			windowedCode += "\n" + fullCode.substring( curPos + windowSize, length );
			
			thread.code = windowedCode;
			thread.cppNature = cppNature;
			thread.file = filePath;
			thread.start();
			thread.join( timeOut );

			if( thread.isAlive() )
			{
				thread.stop();
				reportHang( windowedCode, filePath );	
			} else if( thread.result != null ) {
				reportException( windowedCode, filePath, thread.result );
			}

			curPos += stepSize;
		}
	}

	static class ParseThread extends Thread{
		public String code;
		public boolean cppNature;
		public String file;
		public String result;
		
		public void run(){
			try{
				result = null;
				ParserLanguage language = cppNature ? ParserLanguage.CPP : ParserLanguage.C;
				IParser parser = ParserFactory.createParser( 
					ParserFactory.createScanner( new StringReader( code ), null, new ScannerInfo(), ParserMode.QUICK_PARSE, language, nullCallback,  new NullLogService() ), nullCallback, ParserMode.QUICK_PARSE, language, null );
				
				parser.parse();
			} catch ( Exception e ){
				result = e.getClass().toString();
			}
		}
	}
	
	static protected int stepSize = 50;
	static protected int windowSize = 200;
	static protected int timeOut = 5000;
	static protected String outputDir = null;
	static protected int failures = 0;
}

Back to the top