import java.util.*;
import Jakarta.util.FixDosOutputStream;
import Jakarta.util.Util;
import java.io.*;
/******************** Main class **************************
* @layer<CommonBase>
*/
// this layer assumes the following.
// a previous layer has defined in class Main a static method usageOftk
// which prints out how the -t,-k options are interpreted
// a previous layer has defined in class JTSParseTree a pair of methods:
// public void preprocessTree( $TEqn.AST_Program root ) throws Exception
// for Jampack, this does nothing. for Mixin, it is to prepare the tree
public class Main {
public static boolean typeSort = false;
public static boolean keySort = false;
public static boolean copyMode = false;
public static boolean tagging = false;
static void usageOftk() {} // to be refined!
private static void usage( String err ) {
System.err.println( "Error: " + err );
System.err.print( "Usage: java " + "Main [options]" );
System.err.println( " baseFile extensionFile1 extensionFile2 ..." );
usageOftk(); // to be refined!
System.err.println( " -a <layerName> name of layer to generate " );
System.err.println( " -f <fileName> name file to generate" );
System.err.println( " -c copy single file equation" );
System.err.println( " -l label classes/methods with feature source" );
System.exit( 1 );
}
public static void main( String[] args ) {
int i;
int argc = args.length;
int non_switch_args;
JTSParseTree base = null;
JTSParseTree ext = null;
String aspectName = null;
String fileName = null;
// Step 1: a general routine to pick off command line options
// options are removed from command line and
// args array is adjusted accordingly.
// right now, there are no command-line options
// but this code is here for future expansion
non_switch_args = 0;
for ( i=0; i < argc; i++ ) {
if ( args[i].charAt( 0 ) != '-' ) {
args[non_switch_args] = args[i];
non_switch_args++;
continue ;
}
String arg = args [i] ;
// Switches of form -xxx where xxx is a word:
//
if ( arg.equals( "-layer" ) && i + 1 < args.length ) {
aspectName = args [++i] ;
continue ;
}
if ( arg.equals( "-model" ) && i + 1 < args.length ) {
setModelDirectory( args [++i] ) ;
continue ;
}
if ( arg.equals( "-output" ) && i + 1 < args.length ) {
fileName = args [++i] ;
continue ;
}
// Switches of form -xxx where each x is a switch character:
//
for ( int j=1; j < arg.length(); j++ ) {
char cur = arg.charAt( j );
// Simple toggle switches:
//
if ( cur == 'k' ) {
keySort = true;
continue;
}
if ( cur == 't' ) {
typeSort = true;
continue;
}
if ( cur == 'c' ) {
copyMode = true;
continue;
}
if ( cur == 'l' ) {
tagging = true;
continue;
}
// Switches with an argument:
//
if ( cur != 'a' && cur != 'f' )
usage( "unrecognized option: " + cur );
if ( i + 1 >= args.length )
usage( "option requires an argument: " + cur ) ;
if ( cur == 'a' ) {
aspectName = args[++i];
continue;
}
if ( cur == 'f' ) {
fileName = args[++i];
continue;
}
usage( "unrecognized option: " + cur );
}
}
if ( getModelDirectory() == null )
setModelDirectory( null ) ;
// Step 2: there must be at least one real input argument,
// otherwise error
if ( non_switch_args == 0 )
usage( "must specify at least one input file" );
// Step 3a: if we have an equation that has a single term (file) AND
// we are in copy mode, then simply copy the file verbatim
// and return
if ( copyMode && non_switch_args == 1 ) {
try {
if ( fileName == null )
; //Util.copyFile( new File(args[0]), System.out );
else
Util.copyFile( new File( args[0] ), new File( fileName ) );
}
catch ( Exception e ) {
AstNode.fatalError( e, "failed to parse" );
}
return;
}
// Step 3: initialize JTSParseTree
if ( fileName != null )
setBaseURI( Util.getFullPath( new File( fileName ) ) ) ;
else
setBaseURI( "." ) ;
JTSParseTree.resetCounters();
JTSParseTree.setReportStream( new PrintWriter( System.err ) );
// Step 4: parse the base file
try {
base = new JTSParseTree( args[0] );
}
catch ( Exception e ) {
AstNode.fatalError( e, "failed to parse" );
}
// Step 5: for each extension, parse it and compose it with base
try {
for ( i=1; i<non_switch_args; i++ ) {
ext = new JTSParseTree( args[i] );
base.compose( ext );
}
}
catch ( ParseException pe ) {
AstNode.fatalError( pe, "failed to parse" );
}
catch ( Exception e ) {
AstNode.fatalError( e, "failed to compose" );
}
if ( aspectName != null )
base.setAspectName( aspectName );
// Step 6: do cleanup
if ( base.errorCount() == 0 ) {
// we had no errors, maybe some warnings
AstProperties props = AstProperties.open( fileName );
base.root.reduce2java( props );
props.close();
/*
if ( fileName == null )
base.print();
else {
base.print2file( fileName );
}
*/
System.out.flush();
}
else {
AstNode.toolReport( base.errorCountString() );
}
} //end main()
}