/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.main; import polyglot.frontend.*; import polyglot.frontend.Compiler; import polyglot.util.ErrorInfo; import polyglot.util.ErrorQueue; import polyglot.util.StdErrorQueue; import polyglot.util.QuotedStringTokenizer; import java.io.*; import java.util.*; import x10.ExtensionInfo; /** Main is the main program of the extensible compiler. It should not * need to be replaced. */ public class Main { protected long startTime; /** Source files specified on the command line */ private Set<String> source; /* modifies args */ protected ExtensionInfo getExtensionInfo(List<String> args) throws TerminationException { ExtensionInfo ext = null; for (Iterator<String> i = args.iterator(); i.hasNext(); ) { String s = i.next(); if (s.equals("-ext") || s.equals("-extension")) { if (ext != null) { throw new TerminationException("only one extension can be specified"); } i.remove(); if (!i.hasNext()) { throw new TerminationException("missing argument"); } String extName = i.next(); i.remove(); ext = loadExtension("polyglot.ext." + extName + ".ExtensionInfo"); } else if (s.equals("-extclass")) { if (ext != null) { throw new TerminationException("only one extension can be specified"); } i.remove(); if (!i.hasNext()) { throw new TerminationException("missing argument"); } String extClass = i.next(); i.remove(); ext = loadExtension(extClass); } } if (ext != null) { return ext; } return loadExtension("polyglot.frontend.JLExtensionInfo"); } public void start(String[] argv) throws TerminationException { start(argv, null, null); } public void start(String[] argv, ExtensionInfo ext) throws TerminationException { start(argv, ext, null); } public void start(String[] argv, ErrorQueue eq) throws TerminationException { start(argv, null, eq); } public Compiler getCompiler(String[] argv, ExtensionInfo ext, ErrorQueue eq, Set<String> source) { List<String> args = explodeOptions(argv); if (ext == null) { ext = getExtensionInfo(args); } Options options = ext.getOptions(); try { argv = args.toArray(new String[0]); options.parseCommandLine(argv, source); } catch (UsageError ue) { PrintStream out = (ue.exitCode==0 ? System.out : System.err); if (ue.getMessage() != null && ue.getMessage().length() > 0) { out.println(ext.compilerName() +": " + ue.getMessage()); } options.usage(out); throw new TerminationException(ue.exitCode); } // TODO: until we can get rid of static Report, give it // the reporter Report.initialize(options.reporter); // Time as much of the setup as we can ext.stats.initialize(ext, startTime); ext.stats.startTiming("getCompiler", "getCompiler"); options.reporter.start_reporting(Reporter.verbose); if (eq == null) { eq = new StdErrorQueue(System.err, options.error_count, ext.compilerName()); } Compiler compiler = new Compiler(ext, eq); Globals.initialize(compiler); ext.stats.stopTiming(); return compiler; } public void start(String[] argv, ExtensionInfo ext, ErrorQueue eq) throws TerminationException { startTime = System.nanoTime(); source = new LinkedHashSet<String>(); Compiler compiler = getCompiler(argv, ext, eq, source); boolean success = compiler.compileFiles(source); x10.ExtensionInfo x10Info = (x10.ExtensionInfo) compiler.sourceExtension(); x10Info.stats.reportFrequency(); x10Info.stats.reportTime(); if (!success) { throw new TerminationException(1); } } private List<String> explodeOptions(String[] args) throws TerminationException { LinkedList<String> ll = new LinkedList<String>(); for (int i = 0; i < args.length; i++) { // special case for the @ command-line parameter if (args[i].startsWith("@")) { String fn = args[i].substring(1); try { BufferedReader lr = new BufferedReader(new FileReader(fn)); LinkedList<String> newArgs = new LinkedList<String>(); while (true) { String l = lr.readLine(); if (l == null) break; StringTokenizer st = new StringTokenizer(l, " "); while (st.hasMoreTokens()) newArgs.add(st.nextToken()); } lr.close(); ll.addAll(newArgs); } catch (java.io.IOException e) { throw new TerminationException("cmdline parser: couldn't read args file "+fn); } continue; } ll.add(args[i]); } return ll; } public static void main(String args[]) { try { //long time = - System.currentTimeMillis(); new Main().start(args); //time += System.currentTimeMillis(); //System.out.println(time + " ms"); } catch (TerminationException te) { if (te.getMessage() != null) (te.exitCode==0?System.out:System.err).println(te.getMessage()); System.exit(te.exitCode); } } public static ExtensionInfo loadExtension(String ext) throws TerminationException { if (ext != null && ! ext.equals("")) { Class<?> extClass = null; try { extClass = Class.forName(ext); } catch (ClassNotFoundException e) { throw new TerminationException( "Extension " + ext + " not found: could not find class " + ext + "."); } try { return (ExtensionInfo) extClass.newInstance(); } catch (ClassCastException e) { throw new TerminationException( ext + " is not a valid polyglot extension:" + " extension class " + ext + " exists but is not a subclass of ExtensionInfo"); } catch (Exception e) { throw new TerminationException( "Extension " + ext + " could not be loaded: could not instantiate " + ext + "."); } } return null; } /** * This exception signals termination of the compiler. It should be used * instead of <code>System.exit</code> to allow Polyglot to be called * within a JVM that wasn't started specifically for Polyglot, e.g. the * Apache ANT framework. */ public static class TerminationException extends RuntimeException { private static final long serialVersionUID = 4797129061362187975L; final public int exitCode; public TerminationException(String msg) { this(msg, 1); } public TerminationException(int exit) { this.exitCode = exit; } public TerminationException(String msg, int exit) { super(msg); this.exitCode = exit; } } }