antlr.build.Tool Maven / Gradle / Ivy
package antlr.build;
import antlr.Utils;
import java.io.*;
import java.lang.reflect.*;
/** An application-specific build tool for ANTLR. Old build
* was a shell script that of course is not portable. All it
* did though was to compile; this Java program is a portable
* compile script. :)
*
* This class knows how to portable invoke a system command with
* wildcard expansion. It also knows to how dynamically load a project
* description based upon the name. Actions are just method names
* within that object. The ANTLR object defines build and jar methods
* that use Tool to portably compile and jar--it is the replacement
* the script.
*
* I almost used Python for this, but I hate forcing users to download
* yet another tool just to compile this one. (Another reason not
* to use Ant).
*
* I am using a class to describe the build (e.g., ANTLR) rather than
* a file format at the moment since I am not sure how all this will
* progress.
*
* Properties antlr.build.compiler and antlr.build.root may be set
* according to your needs. They default to "javac" and ".". The
* root is the dir containing the antlr directory associated with
* the antlr Java package.
*
* To build this builder, run "javac *.java" in this dir.
*
* To build ANTLR, just run
*
* java antlr.build.Tool build"
*
* from the
* directory containing package antlr's "antlr" dir. Or, use
* something like:
*
* java -Dantlr.build.root=/usr/local/antlr-2.7.2 antlr.build.Tool build
*
* To make the antlr.jar file, use
*
* java antlr.build.Tool jar
*/
public class Tool {
public String os = null;
public Tool() {
os = System.getProperty("os.name");
}
public static void main(String[] args) {
if ( args.length!=1 ) {
System.err.println("usage: java antlr.build.Tool action");
return;
}
String app = "antlr.build.ANTLR"; // hardcode to build ANTLR app
String action = args[0];
Tool t = new Tool();
t.perform(app, action);
}
/** Find a class named after the app and then find a method within
* that is named after the action.
*/
public void perform(String app, String action) {
if ( app==null || action==null ) {
error("missing app or action");
return;
}
Class c = null;
Method m = null;
Object appObj = null;
try {
appObj = Utils.createInstanceOf(app);
}
catch (Exception e) {
// try again with antlr.build.app
try {
if ( !app.startsWith("antlr.build.") ) {
c = Utils.loadClass("antlr.build."+app);
}
error("no such application "+app, e);
}
catch (Exception e2) {
error("no such application "+app, e2);
}
}
if ( c==null || appObj==null ) {
return;
}
try {
m = c.getMethod(action, new Class[] {antlr.build.Tool.class});
//log("begin "+action+" on "+app);
m.invoke(appObj, new Object[] {this});
//log("end "+action+" on "+app);
}
catch (Exception e) {
error("no such action for application "+app, e);
}
}
/** A portable system command execution routine that logs stdout/stderr
* and handles cmd-line wildcards properly.
*/
public void system(String cmd) {
Runtime rt = Runtime.getRuntime();
try {
log(cmd);
Process proc = null;
if ( !os.startsWith("Windows") ) {
// assume unixen if not windoze (windoze tool expands *)
proc = rt.exec(new String[] {"sh","-c",cmd});
}
else {
proc = rt.exec(cmd);
}
StreamScarfer stderrScarfer =
new StreamScarfer(proc.getErrorStream(), "stderr", this);
StreamScarfer stdoutScarfer =
new StreamScarfer(proc.getInputStream(), "stdout", this);
stderrScarfer.start();
stdoutScarfer.start();
int exitVal = proc.waitFor();
}
catch (Exception e) {
error("cannot exec "+cmd, e);
}
}
/** Run ANTLR on a grammar file, leaving the output in the directory of the
* grammar file.
*/
public void antlr(String fullyQualifiedFilename) {
String path = null;
try {
path = new File(fullyQualifiedFilename).getParent();
if ( path!=null ) {
path = new File(path).getCanonicalPath();
}
}
catch (IOException ioe) {
error("Invalid grammar file: "+fullyQualifiedFilename);
}
if ( path!=null ) {
log("java antlr.Tool -o "+path+" "+fullyQualifiedFilename);
antlr.Tool theTool = new antlr.Tool();
theTool.doEverything(new String[] {"-o", path, fullyQualifiedFilename});
}
}
/** Stdout from executing sub tools */
public void stdout(String s) {
System.out.println(s);
}
/** Stderr from executing sub tools */
public void stderr(String s) {
System.err.println(s);
}
public void error(String msg) {
System.err.println("antlr.build.Tool: "+msg);
}
public void log(String cmd) {
System.out.println("executing: "+cmd);
}
public void error(String msg, Exception e) {
System.err.println("antlr.build.Tool: "+msg);
e.printStackTrace(System.err);
}
}