KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > main > Options


1 package polyglot.main;
2 import java.io.File JavaDoc;
3 import java.io.PrintStream JavaDoc;
4 import java.util.Collection JavaDoc;
5 import java.util.HashSet JavaDoc;
6 import java.util.Iterator JavaDoc;
7 import java.util.LinkedList JavaDoc;
8 import java.util.Set JavaDoc;
9 import java.util.StringTokenizer JavaDoc;
10
11 import polyglot.frontend.ExtensionInfo;
12
13 /**
14  * This object encapsulates various polyglot options.
15  */

16 public class Options {
17     /**
18      * An annoying hack to allow objects to get their hands on the Options
19      * object. This should be fixed. XXX###@@@
20      */

21     public static Options global;
22     
23     /**
24      * Back pointer to the extension that owns this options
25      */

26     protected ExtensionInfo extension = null;
27     
28     /*
29      * Fields for storing values for options.
30      */

31     public int error_count = 100;
32     public Collection JavaDoc source_path; // List[String]
33
public File JavaDoc output_directory;
34     public String JavaDoc default_classpath;
35     public String JavaDoc classpath;
36     public String JavaDoc bootclasspath = null;
37     public boolean assertions = false;
38
39     public String JavaDoc[] source_ext = null; // e.g., java, jl, pj
40
public String JavaDoc output_ext = "java"; // java, by default
41
public boolean output_stdout = false; // whether to output to stdout
42
public String JavaDoc post_compiler;
43       // compiler to run on java output file
44

45     public int output_width = 120;
46     public boolean fully_qualified_names = false;
47   
48     /** Inject type information in serialized form into output file? */
49     public boolean serialize_type_info = true;
50   
51     /** Dump the AST after the following passes? */
52     public Set JavaDoc dump_ast = new HashSet JavaDoc();
53   
54     /** Pretty-print the AST after the following passes? */
55     public Set JavaDoc print_ast = new HashSet JavaDoc();
56  
57     /** Disable the following passes? */
58     public Set JavaDoc disable_passes = new HashSet JavaDoc();
59   
60     /** keep output files */
61     public boolean keep_output_files = true;
62   
63
64     /**
65      * Constructor
66      */

67     public Options(ExtensionInfo extension) {
68         this.extension = extension;
69         setDefaultValues();
70     }
71     
72     /**
73      * Set default values for options
74      */

75     public void setDefaultValues() {
76         String JavaDoc default_bootpath = System.getProperty("sun.boot.class.path");
77         if (default_bootpath == null) {
78           default_bootpath = System.getProperty("java.home") +
79                      File.separator + "jre" +
80                      File.separator + "lib" +
81                      File.separator + "rt.jar";
82         }
83     
84         default_classpath = System.getProperty("java.class.path") +
85                             File.pathSeparator + default_bootpath;
86         classpath = default_classpath;
87
88
89         String JavaDoc java_home = System.getProperty("java.home");
90         String JavaDoc current_dir = System.getProperty("user.dir");
91     
92         source_path = new LinkedList JavaDoc();
93         source_path.add(new File JavaDoc(current_dir));
94     
95         output_directory = new File JavaDoc(current_dir);
96     
97         // First try: $JAVA_HOME/../bin/javac
98
// This should work with JDK 1.2 and 1.3
99
//
100
// If not found, try: $JAVA_HOME/bin/javac
101
// This should work for JDK 1.1.
102
//
103
// If neither found, assume "javac" is in the path.
104
//
105
post_compiler = java_home + File.separator + ".." + File.separator +
106                             "bin" + File.separator + "javac";
107     
108         if (! new File JavaDoc(post_compiler).exists()) {
109           post_compiler = java_home + File.separator +
110                               "bin" + File.separator + "javac";
111     
112           if (! new File JavaDoc(post_compiler).exists()) {
113             post_compiler = "javac";
114           }
115         }
116     }
117     
118     /**
119      * Parse the command line
120      *
121      * @throws UsageError if the usage is incorrect.
122      */

123     public void parseCommandLine(String JavaDoc args[], Set JavaDoc source) throws UsageError {
124         if(args.length < 1) {
125             throw new UsageError("No command line arguments given");
126         }
127     
128         for(int i = 0; i < args.length; ) {
129             try {
130                 int ni = parseCommand(args, i, source);
131                 if (ni == i) {
132                     throw new UsageError("illegal option -- " + args[i]);
133                 }
134                 
135                 i = ni;
136
137             }
138             catch (ArrayIndexOutOfBoundsException JavaDoc e) {
139                 throw new UsageError("missing argument");
140             }
141         }
142                     
143         if (source.size() < 1) {
144           throw new UsageError("must specify at least one source file");
145         }
146     }
147     
148     /**
149      * Parse a command
150      * @return the next index to process. i.e., if calling this method
151      * processes two commands, then the return value should be index+2
152      */

153     protected int parseCommand(String JavaDoc args[], int index, Set JavaDoc source)
154             throws UsageError, Main.TerminationException {
155         int i = index;
156         if (args[i].equals("-h") ||
157             args[i].equals("-help") ||
158             args[i].equals("--help")) {
159             throw new UsageError("", 0);
160         }
161         else if (args[i].equals("-version")) {
162             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
163             if (extension != null) {
164                 sb.append(extension.compilerName() +
165                           " version " + extension.version() + "\n");
166             }
167             sb.append("Polyglot compiler toolkit version " +
168                                new polyglot.ext.jl.Version());
169             throw new Main.TerminationException(sb.toString(), 0);
170         }
171         else if (args[i].equals("-d"))
172         {
173             i++;
174             output_directory = new File JavaDoc(args[i]);
175             i++;
176         }
177         else if (args[i].equals("-classpath") ||
178                  args[i].equals("-cp")) {
179             i++;
180             classpath = args[i] + System.getProperty("path.separator") +
181                         default_classpath;
182             i++;
183         }
184         else if (args[i].equals("-bootclasspath")) {
185             i++;
186             bootclasspath = args[i];
187             i++;
188         }
189         else if (args[i].equals("-sourcepath"))
190         {
191             i++;
192             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(args[i], File.pathSeparator);
193             while(st.hasMoreTokens())
194             {
195                 File JavaDoc f = new File JavaDoc(st.nextToken());
196                 if (f != null && !source_path.contains(f))
197                     source_path.add(f);
198             }
199             i++;
200         }
201         else if (args[i].equals("-assert"))
202         {
203             i++;
204             assertions = true;
205         }
206         else if (args[i].equals("-fqcn"))
207         {
208             i++;
209             fully_qualified_names = true;
210         }
211         else if (args[i].equals("-c"))
212         {
213             post_compiler = null;
214             i++;
215         }
216         else if (args[i].equals("-errors"))
217         {
218             i++;
219             try {
220                 error_count = Integer.parseInt(args[i]);
221                 } catch (NumberFormatException JavaDoc e) {}
222                 i++;
223         }
224         else if (args[i].equals("-w"))
225         {
226             i++;
227             try {
228                 output_width = Integer.parseInt(args[i]);
229                 } catch (NumberFormatException JavaDoc e) {}
230                 i++;
231         }
232         else if (args[i].equals("-post"))
233         {
234             i++;
235             post_compiler = args[i];
236             i++;
237         }
238         else if (args[i].equals("-stdout"))
239         {
240             i++;
241             output_stdout = true;
242         }
243         else if (args[i].equals("-sx"))
244         {
245             i++;
246             if (source_ext == null) {
247                 source_ext = new String JavaDoc[] { args[i] };
248             }
249             else {
250                 String JavaDoc[] s = new String JavaDoc[source_ext.length+1];
251                 System.arraycopy(source_ext, 0, s, 0, source_ext.length);
252                 s[s.length-1] = args[i];
253                 source_ext = s;
254             }
255             i++;
256         }
257         else if (args[i].equals("-ox"))
258         {
259             i++;
260             output_ext = args[i];
261             i++;
262         }
263         else if (args[i].equals("-noserial"))
264         {
265             i++;
266             serialize_type_info = false;
267         }
268         else if (args[i].equals("-dump"))
269         {
270             i++;
271             String JavaDoc pass_name = args[i];
272             dump_ast.add(pass_name);
273             i++;
274         }
275         else if (args[i].equals("-print"))
276         {
277             i++;
278             String JavaDoc pass_name = args[i];
279             print_ast.add(pass_name);
280             i++;
281         }
282         else if (args[i].equals("-disable"))
283         {
284             i++;
285             String JavaDoc pass_name = args[i];
286             disable_passes.add(pass_name);
287             i++;
288         }
289         else if (args[i].equals("-nooutput"))
290         {
291             i++;
292             keep_output_files = false;
293             output_width = 1000; // we do not keep the output files, so
294
// set the output_width to a large number
295
// to reduce the time spent pretty-printing
296
}
297         else if (args[i].equals("-v") || args[i].equals("-verbose"))
298         {
299             i++;
300             Report.addTopic("verbose", 1);
301         }
302         else if (args[i].equals("-report")) {
303             i++;
304             String JavaDoc report_option = args[i];
305             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(args[i], "=");
306             String JavaDoc topic = ""; int level = 0;
307             if (st.hasMoreTokens()) topic = st.nextToken();
308             if (st.hasMoreTokens()) {
309                 try {
310                     level = Integer.parseInt(st.nextToken());
311                 }
312                 catch (NumberFormatException JavaDoc e) {}
313             }
314             Report.addTopic(topic, level);
315             i++;
316         }
317         else if (!args[i].startsWith("-")) {
318             source.add(args[i]);
319             File JavaDoc f = new File JavaDoc(args[i]).getParentFile();
320             if (f != null && !source_path.contains(f))
321                 source_path.add(f);
322             i++;
323         }
324         
325         return i;
326     }
327     
328     /**
329      * Print usage information
330      */

331     public void usage(PrintStream JavaDoc out) {
332         out.println("usage: " + extension.compilerName() + " [options] " +
333                            "<source-file>." + extension.fileExtensions()[0] + " ...");
334         out.println("where [options] includes:");
335         usageForFlag(out, "@<file>", "read options from <file>");
336         usageForFlag(out, "-d <directory>", "output directory");
337         usageForFlag(out, "-assert", "recognize the assert keyword");
338         usageForFlag(out, "-sourcepath <path>", "source path");
339         usageForFlag(out, "-bootclasspath <path>",
340                           "path for bootstrap class files");
341         usageForFlag(out, "-ext <extension>", "use language extension");
342         usageForFlag(out, "-extclass <ext-class>", "use language extension");
343         usageForFlag(out, "-fqcn", "use fully-qualified class names");
344         usageForFlag(out, "-sx <ext>", "set source extension");
345         usageForFlag(out, "-ox <ext>", "set output extension");
346         usageForFlag(out, "-errors <num>", "set the maximum number of errors");
347         usageForFlag(out, "-w <num>",
348                           "set the maximum width of the .java output files");
349         usageForFlag(out, "-dump <pass>", "dump the ast after pass <pass>");
350         usageForFlag(out, "-print <pass>",
351                       "pretty-print the ast after pass <pass>");
352         usageForFlag(out, "-disable <pass>", "disable pass <pass>");
353 // usageForFlag(out, "-scramble [seed]", "scramble the ast (for testing)");
354
usageForFlag(out, "-noserial", "disable class serialization");
355         usageForFlag(out, "-nooutput", "delete output files after compilation");
356         usageForFlag(out, "-c", "compile only to .java");
357         usageForFlag(out, "-post <compiler>",
358                           "run javac-like compiler after translation");
359         usageForFlag(out, "-v -verbose", "print verbose debugging information");
360         usageForFlag(out, "-report <topic>=<level>",
361                           "print verbose debugging information about " +
362                           "topic at specified verbosity");
363
364         StringBuffer JavaDoc allowedTopics = new StringBuffer JavaDoc("Allowed topics: ");
365         for (Iterator JavaDoc iter = Report.topics.iterator(); iter.hasNext(); ) {
366             allowedTopics.append(iter.next().toString());
367             if (iter.hasNext()) {
368                 allowedTopics.append(", ");
369             }
370         }
371         usageSubsection(out, allowedTopics.toString());
372         
373         usageForFlag(out, "-version", "print version info");
374         usageForFlag(out, "-h", "print this message");
375     }
376     
377     /**
378      * The maximum width of a line when printing usage information. Used
379      * by <code>usageForFlag</code> and <code>usageSubsection</code>.
380      */

381     protected int USAGE_SCREEN_WIDTH = 76;
382     /**
383      * The number of spaces from the left that the descriptions for flags will
384      * be displayed. Used
385      * by <code>usageForFlag</code>.
386      */

387     protected int USAGE_FLAG_WIDTH = 27;
388     /**
389      * The number of spaces to indent a subsection of usage information.
390      * Used by <code>usageSubsection</code>.
391      */

392     protected int USAGE_SUBSECTION_INDENT = 8;
393
394     /**
395      * Output a flag and a description of its usage in a nice format. This
396      * makes it easier for extensions to output their usage in a consistent
397      * format.
398      *
399      * @param out output PrintStream
400      * @param flag
401      * @param description description of the flag.
402      */

403     protected void usageForFlag(PrintStream JavaDoc out, String JavaDoc flag, String JavaDoc description) {
404         out.print(" ");
405         out.print(flag);
406         // cur is where the cursor is on the screen.
407
int cur = flag.length() + 2;
408         
409         // print space to get up to indentation level
410
if (cur < USAGE_FLAG_WIDTH) {
411             printSpaces(out, USAGE_FLAG_WIDTH - cur);
412         }
413         else {
414             // the flag is long. Get a new line before printing the
415
// description.
416
out.println();
417             printSpaces(out, USAGE_FLAG_WIDTH);
418         }
419         cur = USAGE_FLAG_WIDTH;
420         
421         // break up the description.
422
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(description);
423         while (st.hasMoreTokens()) {
424             String JavaDoc s = st.nextToken();
425             if (cur + s.length() > USAGE_SCREEN_WIDTH) {
426                 out.println();
427                 printSpaces(out, USAGE_FLAG_WIDTH);
428                 cur = USAGE_FLAG_WIDTH;
429             }
430             out.print(s);
431             cur += s.length();
432             if (st.hasMoreTokens()) {
433                 if (cur + 1 > USAGE_SCREEN_WIDTH) {
434                     out.println();
435                     printSpaces(out, USAGE_FLAG_WIDTH);
436                     cur = USAGE_FLAG_WIDTH;
437                 }
438                 else {
439                     out.print(" ");
440                     cur++;
441                 }
442             }
443         }
444         out.println();
445     }
446     
447     /**
448      * Output a section of text for usage information. This text will be
449      * displayed indented a certain amount from the left, controlled by
450      * the field <code>USAGE_SUBSECTION_INDENT</code>
451      *
452      * @param out the output PrintStream
453      * @param text the text to output.
454      */

455     protected void usageSubsection(PrintStream JavaDoc out, String JavaDoc text) {
456         // print space to get up to indentation level
457
printSpaces(out, USAGE_SUBSECTION_INDENT);
458
459         // cur is where the cursor is on the screen.
460
int cur = USAGE_SUBSECTION_INDENT;
461         
462         // break up the description.
463
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(text);
464         while (st.hasMoreTokens()) {
465             String JavaDoc s = st.nextToken();
466             if (cur + s.length() > USAGE_SCREEN_WIDTH) {
467                 out.println();
468                 printSpaces(out, USAGE_SUBSECTION_INDENT);
469                 cur = USAGE_SUBSECTION_INDENT;
470             }
471             out.print(s);
472             cur += s.length();
473             if (st.hasMoreTokens()) {
474                 if (cur + 1 > USAGE_SCREEN_WIDTH) {
475                     out.println();
476                     printSpaces(out, USAGE_SUBSECTION_INDENT);
477                     cur = USAGE_SUBSECTION_INDENT;
478                 }
479                 else {
480                     out.print(' ');
481                     cur++;
482                 }
483             }
484         }
485         out.println();
486     }
487     
488     /**
489      * Utility method to print a number of spaces to a PrintStream.
490      * @param out output PrintStream
491      * @param n number of spaces to print.
492      */

493     protected static void printSpaces(PrintStream JavaDoc out, int n) {
494         while (n-- > 0) {
495             out.print(' ');
496         }
497     }
498
499   public String JavaDoc constructFullClasspath() {
500       StringBuffer JavaDoc fullcp = new StringBuffer JavaDoc();
501       if (bootclasspath != null) {
502       fullcp.append(bootclasspath);
503       }
504       fullcp.append(classpath);
505       return fullcp.toString();
506   }
507
508   public String JavaDoc constructPostCompilerClasspath() {
509       return output_directory + File.pathSeparator
510               + "." + File.pathSeparator
511               + System.getProperty("java.class.path");
512   }
513 }
514
Popular Tags