Source code: org/sablecc/sablecc/Executable.java
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * This file is part of SableCC. *
3 * See the file "LICENSE" for copyright information and the *
4 * terms and conditions for copying, distribution and *
5 * modification of SableCC. *
6 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7
8 package org.sablecc.sablecc;
9
10 /**/
11 import java.util.HashSet;
12 import java.util.Iterator;
13
14 /**
15 * Template for executable applications. Supports command line options
16 * processing model based string matching. User defined
17 * application should inherit from this base class, and implement at
18 * least methods: optionsSetup() for preparing all application
19 * specific command line options, constantsSetup() for application
20 * specific constant initialization and start() for the application
21 * bootstrapping routines. User defined application should
22 * define main() as:<br><code>
23 * public static void main(String[] args){<br>
24 * ApplicationClass app = new ApplicationClass();<br>
25 * app.Main(args);<br>
26 * }<br></code> <br> and all necessary processing should be placed
27 * inside options and start() method.
28 *
29 *<br><br>
30 * Created: Wed Sep 22 22:22:55 1999
31 *<br>
32 *@author Mariusz Nowostawski
33 */
34 public abstract class Executable {
35
36 /** Application name. */
37 protected String APP_NAME = "App";
38
39 /**
40 * Application banner printed always after invocation. To be used
41 * for short application description, copyrights, authors crap, etc.*/
42 protected String APP_BANNER = "";
43
44 /** Application banner printed always after infocation. */
45 protected String APP_VERSION = "0.1";
46
47 /** Application invocation needs to have options. */
48 protected boolean NEED_OPTIONS = false;
49
50 /**/
51 private HashSet cmdln_options;
52 private Option[] options;
53
54
55 /**
56 * Main method for the template. Application main() should call
57 * this method. */
58 public void Main(String[] args){
59 constantsSetup();
60 this.options = optionsSetup();
61
62 System.out.println(APP_NAME+" version "+APP_VERSION);
63 System.out.println("\n"+APP_BANNER+"\n");
64
65 if(NEED_OPTIONS && args.length < 1){
66 System.out.println("Please specify appropriate command line options.\n");
67 displayUsage();
68 System.exit(0);
69 }
70
71 bootstrap(args);
72 start();
73 }
74
75 /**
76 * Application specific options declaration. User class must
77 * override this method, providing definition for all application
78 * specific command-line options. This implementation returns empty
79 * option table. */
80 protected Option[] optionsSetup(){
81 return new Option[0];
82 }
83
84 /**
85 * Routine to postprocess the command line arguments not
86 * matched by the Options, ie. files, patterns, etc. usually
87 * added as last command line arguments.*/
88 protected void processLeftOvers(Iterator enum){
89 return;
90 }
91
92 /**
93 * User specific constant setup goes here. User class should override this
94 * method. */
95 protected void constantsSetup(){}
96
97 /**
98 * Application specific code goes here. User class must override this
99 * method to perform bootstrapping processing. */
100 protected void start(){}
101
102 /**
103 * Usage. Should be overwritten by the application.
104 */
105 protected void displayUsage(){
106 System.out.println(optionsSetup());
107 }
108
109 /**
110 * Prepares short info for each option. This method simply
111 * concatenate short help for each option with appending new line
112 * character to each of them. The user has to format help lines
113 * herself, or overwrite this method. */
114 protected String optionsInfo(){
115 StringBuffer buf = new StringBuffer();
116 buf.append("Command line options:\n");
117 final Option[] o = this.options;
118 for(int i=0; i<o.length; i++){
119 buf.append(o[i].help).append("\n");
120 }
121 return buf.toString();
122 }
123
124 /**
125 * Creates cmdln_options set, prepares and process the user
126 * defined options. User can modify the behaviour, but for most
127 * cases it should just work. */
128 private void bootstrap(String[] args){
129 this.cmdln_options = createOptionLookupTable(args);
130 Option[] availoptions = optionsSetup();
131 processOptions(availoptions);
132 }
133
134 /**/
135 private HashSet createOptionLookupTable(String[] args){
136 final HashSet options = new HashSet();
137 for(int i=0; i<args.length; i++){
138 options.add(args[i]);
139 }
140 return options;
141 }
142
143 /**/
144 private void processOptions(Option[] option){
145 for(int i=0; i<option.length; i++){
146 option[i].match(this.cmdln_options);
147 }
148
149 if(this.cmdln_options.size() == 0) return;
150
151 processLeftOvers(this.cmdln_options.iterator());
152
153 if(this.cmdln_options.size() > 0){
154 System.out.println("\nQuiting because unknown options encountered.");
155 Iterator enum = this.cmdln_options.iterator();
156 while(enum.hasNext()){
157 System.out.println("Unknown option: "+enum.next());
158 }
159 System.exit(0);
160 }
161 }
162
163 /**
164 * Represents a single command line option.
165 * Option matching is based on pure exact string matching.
166 * Each option is declared with the given key,
167 * wich is matched against each token from command
168 * line options. This class does support options which takes
169 * more than one token.
170 **/
171 public abstract class Option {
172
173 public String[] keys;
174 public String help;
175
176 /**
177 * Initialize this option for a given patterns with a given help
178 * string. */
179 public Option(String[] keys, String help){
180 this.keys = keys;
181 this.help = help;
182 }
183
184 /**/
185 protected abstract void process(String key, Iterator iter);
186
187 /**/
188 protected void match(HashSet set){
189 Iterator enum = set.iterator();
190 while(enum.hasNext()){
191 String s = enum.next().toString();
192 for(int i=0; i<keys.length; i++){
193 if(s.equals(keys[i])){
194 enum.remove();
195 process(s, enum);
196 }
197 }
198 }
199 }
200 }//class Option
201
202 } // Executable
203 //////////////////// end of file ////////////////////