1 package org.sentrysoftware.jawk.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.io.File;
26 import java.io.IOException;
27 import java.io.PrintStream;
28 import java.io.StringReader;
29 import java.net.URISyntaxException;
30 import java.util.Locale;
31
32 import org.slf4j.Logger;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public class AwkParameters {
90
91 private static final Logger LOG = AwkLogger.getLogger(AwkParameters.class);
92
93 private static final String JAR_NAME;
94 static {
95 String myName;
96 try {
97 File me = new File(AwkParameters.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
98 myName = me.getName();
99 }
100 catch (URISyntaxException e) {
101 myName = "Jawk.jar";
102 }
103 JAR_NAME = myName;
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public static AwkSettings parseCommandLineArguments(String[] args) {
124
125 AwkSettings settings = new AwkSettings();
126
127 int argIdx = 0;
128 try {
129
130 while (argIdx < args.length) {
131 assert args[argIdx] != null;
132 if (args[argIdx].length() == 0) {
133 throw new IllegalArgumentException("zero-length argument at position " + (argIdx + 1));
134 }
135 if (args[argIdx].charAt(0) != '-') {
136
137 break;
138 } else if (args[argIdx].equals("-")) {
139
140 ++argIdx;
141 break;
142 } else if (args[argIdx].equals("-v")) {
143 checkParameterHasArgument(args, argIdx);
144 ++argIdx;
145 checkInitialVariableFormat(args[argIdx]);
146 addVariable(settings, args[argIdx]);
147 } else if (args[argIdx].equals("-f")) {
148 checkParameterHasArgument(args, argIdx);
149 ++argIdx;
150 settings.addScriptSource(new ScriptFileSource(args[argIdx]));
151 } else if (args[argIdx].equals("-c")) {
152 settings.setWriteIntermediateFile(true);
153 } else if (args[argIdx].equals("-o")) {
154 checkParameterHasArgument(args, argIdx);
155 ++argIdx;
156 settings.setOutputFilename(args[argIdx]);
157 } else if (args[argIdx].equals("-S")) {
158 settings.setDumpSyntaxTree(true);
159 } else if (args[argIdx].equals("-s")) {
160 settings.setDumpIntermediateCode(true);
161 } else if (args[argIdx].equals("-x")) {
162 settings.setAdditionalFunctions(true);
163 } else if (args[argIdx].equals("-y")) {
164 settings.setAdditionalTypeFunctions(true);
165 } else if (args[argIdx].equals("-t")) {
166 settings.setUseSortedArrayKeys(true);
167 } else if (args[argIdx].equals("-r")) {
168 settings.setCatchIllegalFormatExceptions(false);
169 } else if (args[argIdx].equals("-F")) {
170 checkParameterHasArgument(args, argIdx);
171 ++argIdx;
172 settings.setFieldSeparator(args[argIdx]);
173 } else if (args[argIdx].equals("--locale")) {
174 checkParameterHasArgument(args, argIdx);
175 ++argIdx;
176 settings.setLocale(new Locale(args[argIdx]));
177 } else if (args[argIdx].equals("-ext")) {
178 settings.setUserExtensions(true);
179 } else if (args[argIdx].equals("-h") || args[argIdx].equals("-?")) {
180 if (args.length > 1) {
181 throw new IllegalArgumentException("When printing help/usage output, we do not accept other arguments.");
182 }
183 usage(System.out);
184 System.exit(0);
185 } else {
186 throw new IllegalArgumentException("Unknown parameter: " + args[argIdx]);
187 }
188
189 ++argIdx;
190 }
191
192
193 if (settings.getScriptSources().isEmpty()) {
194 if (argIdx >= args.length) {
195 throw new IllegalArgumentException("Awk script not provided.");
196 }
197 String scriptContent = args[argIdx++];
198 settings.addScriptSource(new ScriptSource(
199 ScriptSource.DESCRIPTION_COMMAND_LINE_SCRIPT,
200 new StringReader(scriptContent),
201 false));
202 } else {
203
204
205 for (ScriptSource scriptSource : settings.getScriptSources()) {
206 try {
207 if (scriptSource.isIntermediate()) {
208 scriptSource.getInputStream();
209 } else {
210 scriptSource.getReader();
211 }
212 } catch (IOException ex) {
213 LOG.error("Failed to read script '" + scriptSource.getDescription() + "'", ex);
214 System.exit(1);
215 }
216 }
217 }
218 } catch (IllegalArgumentException iae) {
219 LOG.error("Failed to parse arguments. Please see the help/usage output (cmd line switch '-h').", iae);
220 System.exit(1);
221 }
222
223
224 while (argIdx < args.length) {
225 String nameValueOrFileName = args[argIdx++];
226 settings.getNameValueOrFileNames().add(nameValueOrFileName);
227 }
228
229 return settings;
230 }
231
232
233
234
235 private static void usage(PrintStream dest) {
236
237 dest.println("Usage:");
238 dest.println(
239 "java -jar " + JAR_NAME + " [-F fs_val]"
240 + " [-f script-filename]"
241 + " [-o output-filename]"
242 + " [-c]"
243 + " [-S]"
244 + " [-s]"
245 + " [-x]"
246 + " [-y]"
247 + " [-r]"
248 + " [--locale locale]"
249 + " [-ext]"
250 + " [-t]"
251 + " [-v name=val]..."
252 + " [script]"
253 + " [name=val | input_filename]...");
254 dest.println();
255 dest.println(" -F fs_val = Use fs_val for FS.");
256 dest.println(" -f filename = Use contents of filename for script.");
257 dest.println(" -v name=val = Initial awk variable assignments.");
258 dest.println();
259 dest.println(" -t = (extension) Maintain array keys in sorted order.");
260 dest.println(" -c = (extension) Compile to intermediate file. (default: a.ai)");
261 dest.println(" -o = (extension) Specify output file.");
262 dest.println(" -S = (extension) Write the syntax tree to file. (default: syntax_tree.lst)");
263 dest.println(" -s = (extension) Write the intermediate code to file. (default: avm.lst)");
264 dest.println(" -x = (extension) Enable _sleep, _dump as keywords, and exec as a builtin func.");
265 dest.println(" -y = (extension) Enable _INTEGER, _DOUBLE, and _STRING casting keywords.");
266 dest.println(" -r = (extension) Do NOT hide IllegalFormatExceptions for [s]printf.");
267 dest.println(" --locale Locale = (extension) Specify a locale to be used instead of US-English");
268 dest.println("-ext= (extension) Enable user-defined extensions. (default: not enabled)");
269 dest.println();
270 dest.println(" -h or -? = (extension) This help screen.");
271 }
272
273
274
275
276
277
278
279
280
281
282
283 private static void checkParameterHasArgument(String[] args, int argIdx) {
284 assert argIdx < args.length;
285 assert args[argIdx].charAt(0) == '-';
286 if (argIdx + 1 >= args.length) {
287 throw new IllegalArgumentException("Need additional argument for " + args[argIdx]);
288 }
289 }
290
291
292
293
294 private static void checkInitialVariableFormat(String keyValue) {
295 int equalsCount = 0;
296 int length = keyValue.length();
297 for (int i = 0; equalsCount <= 1 && i < length; i++) {
298 if (keyValue.charAt(i) == '=') {
299 ++equalsCount;
300 }
301 }
302 if (equalsCount != 1) {
303 throw new IllegalArgumentException("keyValue \"" + keyValue + "\" must be of the form \"name=value\"");
304 }
305 }
306
307 private static void addVariable(AwkSettings settings, String keyValue) {
308 int equalsIdx = keyValue.indexOf('=');
309 assert equalsIdx >= 0;
310 String name = keyValue.substring(0, equalsIdx);
311 String valueString = keyValue.substring(equalsIdx + 1);
312 Object value;
313
314 try {
315 value = Integer.parseInt(valueString);
316 } catch (NumberFormatException nfe) {
317 try {
318 value = Double.parseDouble(valueString);
319 } catch (NumberFormatException nfe2) {
320 value = valueString;
321 }
322 }
323
324 settings.getVariables().put(name, value);
325 }
326 }