KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > main > Main


1 package polyglot.main;
2
3 import polyglot.frontend.Compiler;
4 import polyglot.frontend.ExtensionInfo;
5 import polyglot.util.ErrorInfo;
6 import polyglot.util.ErrorQueue;
7 import polyglot.util.StdErrorQueue;
8
9 import java.io.*;
10 import java.util.*;
11
12 /** Main is the main program of the extensible compiler. It should not
13  * need to be replaced.
14  */

15 public class Main
16 {
17
18   /** Source files specified on the command line */
19   private Set source;
20
21   final static String JavaDoc verbose = "verbose";
22
23   /* modifies args */
24   protected ExtensionInfo getExtensionInfo(List args) throws TerminationException {
25       ExtensionInfo ext = null;
26
27       for (Iterator i = args.iterator(); i.hasNext(); ) {
28           String JavaDoc s = (String JavaDoc)i.next();
29           if (s.equals("-ext") || s.equals("-extension"))
30           {
31               if (ext != null) {
32                   throw new TerminationException("only one extension can be specified");
33               }
34
35               i.remove();
36               if (!i.hasNext()) {
37                   throw new TerminationException("missing argument");
38               }
39               String JavaDoc extName = (String JavaDoc)i.next();
40               i.remove();
41               ext = loadExtension("polyglot.ext." + extName + ".ExtensionInfo");
42           }
43           else if (s.equals("-extclass"))
44           {
45               if (ext != null) {
46                   throw new TerminationException("only one extension can be specified");
47               }
48
49               i.remove();
50               if (!i.hasNext()) {
51                   throw new TerminationException("missing argument");
52               }
53               String JavaDoc extClass = (String JavaDoc)i.next();
54               i.remove();
55               ext = loadExtension(extClass);
56           }
57       }
58       if (ext != null) {
59           return ext;
60       }
61       return loadExtension("polyglot.ext.jl.ExtensionInfo");
62   }
63
64   public void start(String JavaDoc[] argv) throws TerminationException {
65       start(argv, null);
66   }
67
68   public void start(String JavaDoc[] argv, ErrorQueue eq) throws TerminationException {
69       source = new HashSet();
70       List args = explodeOptions(argv);
71       ExtensionInfo ext = getExtensionInfo(args);
72       Options options = ext.getOptions();
73
74       // Allow all objects to get access to the Options object. This hack should
75
// be fixed somehow. XXX###@@@
76
Options.global = options;
77       try {
78           argv = (String JavaDoc[]) args.toArray(new String JavaDoc[0]);
79           options.parseCommandLine(argv, source);
80       }
81       catch (UsageError ue) {
82           PrintStream out = (ue.exitCode==0 ? System.out : System.err);
83           if (ue.getMessage() != null && ue.getMessage().length() > 0) {
84               out.println(ext.compilerName() +": " + ue.getMessage());
85           }
86           options.usage(out);
87           throw new TerminationException(ue.exitCode);
88       }
89
90       if (eq == null) {
91           eq = new StdErrorQueue(System.err,
92                                  options.error_count,
93                                  ext.compilerName());
94       }
95
96       Compiler JavaDoc compiler = new Compiler JavaDoc(ext, eq);
97
98       long time0 = System.currentTimeMillis();
99
100       if (!compiler.compile(source)) {
101           throw new TerminationException(1);
102       }
103
104       if (Report.should_report(verbose, 1))
105           Report.report(1, "Output files: " + compiler.outputFiles());
106
107       long start_time = System.currentTimeMillis();
108
109       /* Now call javac or jikes, if necessary. */
110       if (!invokePostCompiler(options, compiler, eq)) {
111           throw new TerminationException(1);
112       }
113
114       if (Report.should_report(verbose, 1)) {
115           reportTime("Finished compiling Java output files. time=" +
116                   (System.currentTimeMillis() - start_time), 1);
117
118           reportTime("Total time=" + (System.currentTimeMillis() - time0), 1);
119       }
120   }
121
122   protected boolean invokePostCompiler(Options options,
123                                     Compiler JavaDoc compiler,
124                                     ErrorQueue eq) {
125       if (options.post_compiler != null && !options.output_stdout) {
126           Runtime JavaDoc runtime = Runtime.getRuntime();
127
128           Iterator iter = compiler.outputFiles().iterator();
129           StringBuffer JavaDoc outputFiles = new StringBuffer JavaDoc();
130           while(iter.hasNext()) {
131               outputFiles.append((String JavaDoc)iter.next());
132               outputFiles.append(" ");
133           }
134
135           String JavaDoc command = options.post_compiler + " -classpath " +
136                         options.constructPostCompilerClasspath() + " "
137                         + outputFiles.toString();
138
139           if (Report.should_report(verbose, 1))
140               Report.report(1, "Executing post-compiler " + command);
141
142           try {
143               Process JavaDoc proc = runtime.exec(command);
144
145               InputStreamReader err = null;
146
147               try {
148                   err = new InputStreamReader(proc.getErrorStream());
149                   char[] c = new char[72];
150                   int len;
151                   StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
152                   while((len = err.read(c)) > 0) {
153                       sb.append(String.valueOf(c, 0, len));
154                   }
155
156                   if (sb.length() != 0) {
157                       eq.enqueue(ErrorInfo.POST_COMPILER_ERROR, sb.toString());
158                   }
159               }
160               finally {
161                   err.close();
162               }
163
164               proc.waitFor();
165
166               if (!options.keep_output_files) {
167                 String JavaDoc command2 = "rm " + outputFiles.toString();
168                 runtime.exec(command2);
169               }
170
171               if (proc.exitValue() > 0) {
172                 eq.enqueue(ErrorInfo.POST_COMPILER_ERROR,
173                                  "Non-zero return code: " + proc.exitValue());
174                 return false;
175               }
176           }
177           catch(Exception JavaDoc e) {
178               eq.enqueue(ErrorInfo.POST_COMPILER_ERROR, e.getMessage());
179               return false;
180           }
181       }
182       return true;
183   }
184
185   private List explodeOptions(String JavaDoc[] args) throws TerminationException {
186       LinkedList ll = new LinkedList();
187
188       for (int i = 0; i < args.length; i++) {
189           // special case for the @ command-line parameter
190
if (args[i].startsWith("@")) {
191               String JavaDoc fn = args[i].substring(1);
192               try {
193                   BufferedReader lr = new BufferedReader(new FileReader(fn));
194                   LinkedList newArgs = new LinkedList();
195
196                   while (true) {
197                       String JavaDoc l = lr.readLine();
198                       if (l == null)
199                           break;
200
201                       StringTokenizer st = new StringTokenizer(l, " ");
202                       while (st.hasMoreTokens())
203                           newArgs.add(st.nextToken());
204                   }
205
206                   lr.close();
207                   ll.addAll(newArgs);
208               }
209               catch (java.io.IOException JavaDoc e) {
210                   throw new TerminationException("cmdline parser: couldn't read args file "+fn);
211               }
212               continue;
213           }
214
215           ll.add(args[i]);
216       }
217
218       return ll;
219   }
220
221   public static final void main(String JavaDoc args[]) {
222       try {
223           new Main().start(args);
224       }
225       catch (TerminationException te) {
226           if (te.getMessage() != null)
227               (te.exitCode==0?System.out:System.err).println(te.getMessage());
228           System.exit(te.exitCode);
229       }
230   }
231
232   static final ExtensionInfo loadExtension(String JavaDoc ext) throws TerminationException {
233     if (ext != null && ! ext.equals("")) {
234       Class JavaDoc extClass = null;
235
236       try {
237         extClass = Class.forName(ext);
238       }
239       catch (ClassNotFoundException JavaDoc e) {
240           throw new TerminationException(
241             "Extension " + ext +
242             " not found: could not find class " + ext + "." +
243                 e.getMessage());
244       }
245
246       try {
247         return (ExtensionInfo) extClass.newInstance();
248       }
249       catch (ClassCastException JavaDoc e) {
250           throw new TerminationException(
251         ext + " is not a valid polyglot extension:" +
252         " extension class " + ext +
253         " exists but is not a subclass of ExtensionInfo");
254       }
255       catch (Exception JavaDoc e) {
256           throw new TerminationException(
257                "Extension " + ext +
258                " could not be loaded: could not instantiate " + ext + ".");
259       }
260     }
261     return null;
262   }
263
264   static private Collection timeTopics = new ArrayList(1);
265   static {
266       timeTopics.add("time");
267   }
268
269   static private void reportTime(String JavaDoc msg, int level) {
270       Report.report(level, msg);
271   }
272
273   /**
274    * This exception signals termination of the compiler. It should be used
275    * instead of <code>System.exit</code> to allow Polyglot to be called
276    * within a JVM that wasn't started specifically for Polyglot, e.g. the
277    * Apache ANT framework.
278    */

279   public static class TerminationException extends RuntimeException JavaDoc {
280       final public int exitCode;
281       public TerminationException(String JavaDoc msg) {
282           this(msg, 1);
283       }
284       public TerminationException(int exit) {
285           this.exitCode = exit;
286       }
287       public TerminationException(String JavaDoc msg, int exit) {
288           super(msg);
289           this.exitCode = exit;
290       }
291   }
292 }
293
Popular Tags