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() }