/* * 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.visit; import java.io.InputStreamReader; import java.util.Collection; import java.util.Iterator; import polyglot.frontend.*; import polyglot.frontend.Compiler; import polyglot.main.Options; import polyglot.main.Reporter; import polyglot.util.*; /** The post compiler pass runs after all jobs complete. It invokes the post-compiler on the output files stored in compiler.outputFiles(). */ public class PostCompiled extends AllBarrierGoal { private static final long serialVersionUID = -1965473009038288138L; ExtensionInfo ext; Reporter reporter; /** * Create a Translator. The output of the visitor is a collection of files * whose names are added to the collection <code>outputFiles</code>. */ public PostCompiled(ExtensionInfo ext) { super("PostCompile",ext.scheduler()); this.ext = ext; this.reporter = ext.getOptions().reporter; } public Goal prereqForJob(Job job) { if (scheduler.shouldCompile(job)) { return scheduler.End(job); } else { return new SourceGoal_c("DummyEnd", job) { private static final long serialVersionUID = 3275850403775521984L; public boolean runTask() { return true; } }.intern(scheduler); } } public final static String postcompile = "postcompile"; public boolean runTask() { Compiler compiler = ext.compiler(); if (reporter.should_report(postcompile, 2)) reporter.report(2, "Output files: " + compiler.outputFiles()); return invokePostCompiler(ext.getOptions(), compiler, compiler.errorQueue()); } protected boolean invokePostCompiler(Options options, Compiler compiler, ErrorQueue eq) { if (options.post_compiler != null && !options.output_stdout) { Runtime runtime = Runtime.getRuntime(); QuotedStringTokenizer st = new QuotedStringTokenizer(options.post_compiler, '?'); int pc_size = st.countTokens(); Collection<String> outputFiles = compiler.flatOutputFiles(); String[] javacCmd = new String[pc_size+2+outputFiles.size()]; int j = 0; for (int i = 0; i < pc_size; i++) { javacCmd[j++] = st.nextToken(); } javacCmd[j++] = "-classpath"; javacCmd[j++] = options.constructPostCompilerClasspath(); Iterator<String> iter = outputFiles.iterator(); for (; iter.hasNext(); j++) { javacCmd[j] = (String) iter.next(); } if (reporter.should_report(postcompile, 1)) { StringBuffer cmdStr = new StringBuffer(); for (int i = 0; i < javacCmd.length; i++) cmdStr.append(javacCmd[i]+" "); reporter.report(1, "Executing post-compiler " + cmdStr); } try { Process proc = runtime.exec(javacCmd); InputStreamReader err = new InputStreamReader(proc.getErrorStream()); try { char[] c = new char[72]; int len; StringBuffer sb = new StringBuffer(); while((len = err.read(c)) > 0) { sb.append(String.valueOf(c, 0, len)); } if (sb.length() != 0) { eq.enqueue(ErrorInfo.POST_COMPILER_ERROR, sb.toString()); } } finally { err.close(); } proc.waitFor(); if (!options.keep_output_files) { String[] rmCmd = new String[1+compiler.outputFiles().size()]; rmCmd[0] = "rm"; iter = outputFiles.iterator(); for (int i = 1; iter.hasNext(); i++) rmCmd[i] = (String) iter.next(); runtime.exec(rmCmd); } if (proc.exitValue() > 0) { eq.enqueue(ErrorInfo.POST_COMPILER_ERROR, "Non-zero return code: " + proc.exitValue()); return false; } } catch(Exception e) { eq.enqueue(ErrorInfo.POST_COMPILER_ERROR, e.getMessage()); return false; } } return true; } }