1 package antlr.build;
2 
3 import antlr.Utils;
4 
5 import java.io.*;
6 import java.lang.reflect.*;
7 
8 /** An application-specific build tool for ANTLR.  Old build
9  *  was a shell script that of course is not portable.  All it
10  *  did though was to compile; this Java program is a portable
11  *  compile script. :)
12  *
13  *  This class knows how to portable invoke a system command with
14  *  wildcard expansion.  It also knows to how dynamically load a project
15  *  description based upon the name.  Actions are just method names
16  *  within that object.  The ANTLR object defines build and jar methods
17  *  that use Tool to portably compile and jar--it is the replacement
18  *  the script.
19  *
20  *  I almost used Python for this, but I hate forcing users to download
21  *  yet another tool just to compile this one.  (Another reason not
22  *  to use Ant).
23  *
24  *  I am using a class to describe the build (e.g., ANTLR) rather than
25  *  a file format at the moment since I am not sure how all this will
26  *  progress.
27  *
28  *  Properties antlr.build.compiler and antlr.build.root may be set
29  *  according to your needs.  They default to "javac" and ".".  The
30  *  root is the dir containing the antlr directory associated with
31  *  the antlr Java package.
32  *
33  *  To build this builder, run "javac *.java" in this dir.
34  *
35  *  To build ANTLR, just run
36  *
37  *    java antlr.build.Tool build"
38  *
39  *  from the
40  *  directory containing package antlr's "antlr" dir.  Or, use
41  *  something like:
42  *
43  *  java -Dantlr.build.root=/usr/local/antlr-2.7.2 antlr.build.Tool build
44  *
45  *  To make the antlr.jar file, use
46  *
47  *  java antlr.build.Tool jar
48  */
49 public class Tool {
50     public String os = null;
51 
Tool()52     public Tool() {
53         os = System.getProperty("os.name");
54     }
55 
main(String[] args)56     public static void main(String[] args) {
57         if ( args.length!=1 ) {
58             System.err.println("usage: java antlr.build.Tool action");
59             return;
60         }
61         String app = "antlr.build.ANTLR"; // hardcode to build ANTLR app
62         String action = args[0];
63         Tool t = new Tool();
64         t.perform(app, action);
65     }
66 
67     /** Find a class named after the app and then find a method within
68      *  that is named after the action.
69      */
perform(String app, String action)70     public void perform(String app, String action) {
71         if ( app==null || action==null ) {
72             error("missing app or action");
73             return;
74         }
75         Class c = null;
76         Method m = null;
77         Object appObj = null;
78         try {
79             appObj = Utils.createInstanceOf(app);
80         }
81         catch (Exception e) {
82             // try again with antlr.build.app
83             try {
84                 if ( !app.startsWith("antlr.build.") ) {
85                     c = Utils.loadClass("antlr.build."+app);
86                 }
87                 error("no such application "+app, e);
88             }
89             catch (Exception e2) {
90                 error("no such application "+app, e2);
91             }
92         }
93         if ( c==null || appObj==null ) {
94             return;
95         }
96         try {
97             m = c.getMethod(action, new Class[] {antlr.build.Tool.class});
98             //log("begin "+action+" on "+app);
99             m.invoke(appObj, new Object[] {this});
100             //log("end "+action+" on "+app);
101         }
102         catch (Exception e) {
103             error("no such action for application "+app, e);
104         }
105     }
106 
107     /** A portable system command execution routine that logs stdout/stderr
108      *  and handles cmd-line wildcards properly.
109      */
system(String cmd)110     public void system(String cmd) {
111         Runtime rt = Runtime.getRuntime();
112         try {
113             log(cmd);
114             Process proc = null;
115             if ( !os.startsWith("Windows") ) {
116                 // assume unixen if not windoze (windoze tool expands *)
117                 proc = rt.exec(new String[] {"sh","-c",cmd});
118             }
119             else {
120                 proc = rt.exec(cmd);
121             }
122             StreamScarfer stderrScarfer =
123                     new StreamScarfer(proc.getErrorStream(), "stderr", this);
124             StreamScarfer stdoutScarfer =
125                     new StreamScarfer(proc.getInputStream(), "stdout", this);
126             stderrScarfer.start();
127             stdoutScarfer.start();
128             int exitVal = proc.waitFor();
129         }
130         catch (Exception e) {
131             error("cannot exec "+cmd, e);
132         }
133     }
134 
135     /** Run ANTLR on a grammar file, leaving the output in the directory of the
136      *  grammar file.
137      */
antlr(String fullyQualifiedFilename)138     public void antlr(String fullyQualifiedFilename) {
139         String path = null;
140         try {
141             path = new File(fullyQualifiedFilename).getParent();
142             if ( path!=null ) {
143                 path = new File(path).getCanonicalPath();
144             }
145         }
146         catch (IOException ioe) {
147             error("Invalid grammar file: "+fullyQualifiedFilename);
148         }
149         if ( path!=null ) {
150             log("java antlr.Tool -o "+path+" "+fullyQualifiedFilename);
151             antlr.Tool theTool = new antlr.Tool();
152             theTool.doEverything(new String[] {"-o", path, fullyQualifiedFilename});
153         }
154     }
155 
156     /** Stdout from executing sub tools */
stdout(String s)157     public void stdout(String s) {
158         System.out.println(s);
159     }
160 
161     /** Stderr from executing sub tools */
stderr(String s)162     public void stderr(String s) {
163         System.err.println(s);
164     }
165 
error(String msg)166     public void error(String msg) {
167         System.err.println("antlr.build.Tool: "+msg);
168     }
169 
log(String cmd)170     public void log(String cmd) {
171         System.out.println("executing: "+cmd);
172     }
173 
error(String msg, Exception e)174     public void error(String msg, Exception e) {
175         System.err.println("antlr.build.Tool: "+msg);
176         e.printStackTrace(System.err);
177     }
178 }
179