import Jakarta.util.FixDosOutputStream; import Jakarta.util.Util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Reader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.HashSet; public class Main { final private static String SOURCE_FILE = "source file" ; private ArgList instanceArgs = null ; private PositionalArg sourceFile = null ; private int myLayerID; public static boolean verbose = false; private static HashSet filesProcessed = new HashSet(); public static String currentOutputFileName =""; // given absolute path of file, directoryPath returns // the absolute path of the file's directory String directoryPath( String path ) { if ( path == null ) return "."; int lst = path.lastIndexOf( File.separatorChar ); if ( lst == -1 ) return "."; else return path.substring( 0, lst ); } /** * Overrides previous version to allow multiple source files in the * argument list. This is done by successively substituting the * "source file" argument by each of the extra arguments. * * <p> * <em>Note:</em> * The argument processing here is a mess, mostly because the command * line parsing design is poor. That's another area of clean-up. * * @layer<Java> */ protected boolean driver( ArgList args ) { instanceArgs = args ; // Find the "source file" argument to be updated. // for ( Iterator p = args.iterator() ; p.hasNext() ; ) { Object object = p.next() ; if ( object instanceof PositionalArg ) { PositionalArg arg = ( PositionalArg ) object ; if ( SOURCE_FILE.equals( arg.name ) ) { sourceFile = arg ; break ; } } } if ( sourceFile == null ) throw new IllegalStateException( "invalid source file parse" ) ; // Get verbosity level: // for ( Iterator p = args.iterator() ; p.hasNext() ; ) { Object object = p.next() ; if ( object instanceof Switch ) { Switch sw = ( Switch ) object ; if ( sw.name == "quiet" ) verbose = false ; else if ( sw.name == "verbose" ) verbose = true ; } } // Handle first source file argument (at least one is required): // processing( packageName, sourceFile.binding ) ; // If there are no extra arguments, then we're done. // if ( extraArgs == null || extraArgs.size() < 1 ) return true; // Substitute each extra source file argument into the source file // position, then re-evaluate command line. // for ( Iterator p = extraArgs.iterator() ; p.hasNext() ; ) processing( packageName, ( String ) p.next() ) ; return true; } protected void processing( String label, String fileName ) { sourceFile.binding = fileName ; kernelConstants.globals().currentFileName = fileName; boolean processed = this.driver( instanceArgs ); if ( verbose && processed ) System.err.println( label + ": file \"" + fileName + '"' ) ; } //************************************************** // Method called by the top-most layer to allow a layer to request // switches and arguments. //************************************************** protected void argInquire( int _layer ) { Switch sw; // Save my layer number myLayerID = _layer; // Register my switches sw = new Switch( "d", "debug mode for parser", null, true, _layer ); switchRegister( sw ); sw = new Switch( "s", "send output to stdout", null, true, _layer ); switchRegister( sw ); sw = new Switch( "b", "bootstrap from JTS to FOP", null, true, _layer ); switchRegister( sw ); sw = new Switch( "v", "FOP (exit(1)) or JTS (exit(0)) version", null, true, _layer ); switchRegister( sw ); sw = new Switch( "x", "override default file extension", new String[1], true, _layer ); switchRegister( sw ); // Verbosity selection: // switchRegister( new Switch( "quiet", "disables verbose output", null, true, _layer ) ) ; switchRegister( new Switch( "verbose", "enables verbose output (default)", null, true, _layer ) ) ; // Register my command line positional arguments posArgRegister( new PositionalArg( SOURCE_FILE, _layer ) ) ; // Allow extra arguments: extraArgs = new ArrayList() ; // Call next layer original( nextLayer() ); } //************************************************** // createAST() //************************************************** protected AstNode createAST( ArgList argObjects ) { FileInputStream fis; PositionalArg parg; File inputFile; AstNode root; // do no file processing if -v switch is set; // just return version if ( argObjects.find( "v", Switch.class, myLayerID ) != null ) { if ( kernelConstants.LangName.equals( "" ) ) System.exit( 1 ); else System.exit( 0 ); } Switch sw = ( Switch ) argObjects.find( "x", Switch.class, myLayerID ); if ( sw != null ) { kernelConstants.jakExtension = sw.args[0]; } parg = ( PositionalArg ) argObjects.first( PositionalArg.class, myLayerID ); kernelConstants.PushParseTreeStack( parg.binding ); try { inputFile = new File( parg.binding ); fis = new FileInputStream( inputFile ); kernelConstants.globals().mainProps.setProperty( "input", inputFile ); // now add inputDirectory property String abspath = inputFile.getAbsolutePath(); kernelConstants.globals().mainProps.setProperty( "inputDirectory", directoryPath( abspath ) ); kernelConstants.globals().currentAbsPath = abspath; // extract file extension -- if there is none, use "" String x = ""; int i = parg.binding.lastIndexOf( '.' ); if ( i != -1 ) x = parg.binding.substring( i ); kernelConstants.globals().currentFileExt = x; // see if we have already processed this file. If so, return null if ( filesProcessed.contains( abspath ) ) { fis.close(); kernelConstants.PopParseTreeStack(); return null; } } catch ( Exception e ) { AstNode.fatalError( "Can't open file "+ parg.binding ); fis = null; } try { Parser parser = Parser.getInstance( fis ) ; root = parser.parseAll() ; } catch ( ParseException e ) { AstNode.parseError( e.toString() ); root = null; } return ( root ); } //************************************************** // outputAST() //************************************************** protected void outputAST( ArgList argObjects, AstNode ast ) { PrintWriter pw; String outputFileName=""; String inputFileName; String outputDirectory; int lastDot; File inputFile=null; pw = null; String lineSeparator = System.getProperties().getProperty( "line.separator" ); if ( argObjects.find( "b", Switch.class, myLayerID ) != null ) { kernelConstants.LangName = ""; } if ( argObjects.find( "s", Switch.class, myLayerID ) != null ) { if ( lineSeparator.compareTo( "\n" ) != 0 ) pw = new PrintWriter( new FixDosOutputStream( System.out ) ); else pw = new PrintWriter( System.out ); outputDirectory = "."; } else { inputFile = ( File ) kernelConstants.globals().mainProps.getProperty( "input" ); inputFileName = inputFile.getAbsolutePath(); lastDot = inputFileName.lastIndexOf( '.' ); if ( lastDot == -1 ) outputFileName = inputFileName + kernelConstants.outputFileExtension; else outputFileName = inputFileName.substring( 0, lastDot ) + kernelConstants.outputFileExtension; // @test Refactor into a method // outputFileName = computeOutputFileName(lastDot, inputFileName); outputDirectory = directoryPath( outputFileName ); try { OutputStream os; FileOutputStream fos = new FileOutputStream( outputFileName ); if ( lineSeparator.compareTo( "\n" ) != 0 ) os = new FixDosOutputStream( fos ); else os = fos; pw = new PrintWriter( os ); } catch ( IOException e ) { AstNode.fatalError( "Cannot open " + outputFileName + ": " + e.getMessage() ); } } kernelConstants.globals().mainProps.setProperty( "output", pw ); // in some future version, it might be possible to set // outputDirectory from a command-line argument. if so, // the property of outputDirectory would have been already set if ( ! kernelConstants.globals().mainProps.containsProperty( "outputDirectory" ) ) kernelConstants.globals().mainProps.setProperty( "outputDirectory", outputDirectory ); ast.reduce2java( kernelConstants.globals().mainProps ); pw.println(); pw.flush(); // Keeps the value of the OutputFileName to be accessed by Jak2aj tool // for file renaming currentOutputFileName = outputFileName; // add to list of files already processed filesProcessed.add( kernelConstants.globals().currentFileName ); kernelConstants.PopParseTreeStack(); // Call outputAST() for other layers original( argObjects, ast ); } }