cp/guest: clean up guest_create's console handling
[hvf.git] / build / re2c / main.cc
blob4fbacacc044eaae307cf2beba397d2d2aa0785db
1 /* $Id: main.cc 858 2008-04-03 20:53:44Z helly $ */
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #elif defined(_WIN32)
5 #include "config_w32.h"
6 #endif
8 #include <fstream>
9 #include <iostream>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "globals.h"
14 #include "parser.h"
15 #include "dfa.h"
16 #include "mbo_getopt.h"
18 namespace re2c
21 file_info sourceFileInfo;
22 file_info outputFileInfo;
23 file_info headerFileInfo;
25 bool bFlag = false;
26 bool cFlag = false;
27 bool dFlag = false;
28 bool DFlag = false;
29 bool eFlag = false;
30 bool fFlag = false;
31 bool FFlag = false;
32 bool gFlag = false;
33 bool iFlag = false;
34 bool rFlag = false;
35 bool sFlag = false;
36 bool tFlag = false;
37 bool uFlag = false;
38 bool wFlag = false;
40 bool bNoGenerationDate = false;
42 bool bSinglePass = false;
43 bool bFirstPass = true;
44 bool bLastPass = false;
45 bool bUsedYYBitmap = false;
47 bool bUsedYYAccept = false;
48 bool bUsedYYMaxFill = false;
49 bool bUsedYYMarker = true;
51 bool bEmitYYCh = true;
52 bool bUseStartLabel = false;
53 bool bUseStateNext = false;
54 bool bUseYYFill = true;
55 bool bUseYYFillParam = true;
56 bool bUseYYFillCheck = true;
57 bool bUseYYFillNaked = false;
58 bool bUseYYSetConditionParam = true;
59 bool bUseYYGetConditionNaked = false;
60 bool bUseYYSetStateParam = true;
61 bool bUseYYSetStateNaked = false;
62 bool bUseYYGetStateNaked = false;
64 std::string startLabelName;
65 std::string labelPrefix("yy");
66 std::string condPrefix("yyc_");
67 std::string condEnumPrefix("yyc");
68 std::string condDivider("/* *********************************** */");
69 std::string condDividerParam("@@");
70 std::string condGoto("goto @@;");
71 std::string condGotoParam("@@");
72 std::string yychConversion("");
73 std::string yyFillLength("@@");
74 std::string yySetConditionParam("@@");
75 std::string yySetStateParam("@@");
76 std::string yySetupRule("");
77 uint maxFill = 1;
78 uint next_label = 0;
79 uint cGotoThreshold = 9;
81 uint topIndent = 0;
82 std::string indString("\t");
83 bool yybmHexTable = false;
84 bool bUseStateAbort = false;
85 bool bWroteGetState = false;
86 bool bWroteCondCheck = false;
87 bool bCaseInsensitive = false;
88 bool bCaseInverted = false;
89 bool bTypesDone = false;
91 uint nRealChars = 256;
93 uint next_fill_index = 0;
94 uint last_fill_index = 0;
95 std::set<uint> vUsedLabels;
96 CodeNames mapCodeName;
97 std::string typesInline;
99 free_list<RegExp*> RegExp::vFreeList;
100 free_list<Range*> Range::vFreeList;
102 using namespace std;
104 static char *opt_arg = NULL;
105 static int opt_ind = 1;
107 static const mbo_opt_struct OPTIONS[] =
109 mbo_opt_struct('?', 0, "help"),
110 mbo_opt_struct('b', 0, "bit-vectors"),
111 mbo_opt_struct('c', 0, "start-conditions"),
112 mbo_opt_struct('d', 0, "debug-output"),
113 mbo_opt_struct('D', 0, "emit-dot"),
114 mbo_opt_struct('e', 0, "ecb"),
115 mbo_opt_struct('f', 0, "storable-state"),
116 mbo_opt_struct('F', 0, "flex-syntax"),
117 mbo_opt_struct('g', 0, "computed-gotos"),
118 mbo_opt_struct('h', 0, "help"),
119 mbo_opt_struct('i', 0, "no-debug-info"),
120 mbo_opt_struct('o', 1, "output"),
121 mbo_opt_struct('r', 0, "reusable"),
122 mbo_opt_struct('s', 0, "nested-ifs"),
123 mbo_opt_struct('t', 1, "type-header"),
124 mbo_opt_struct('u', 0, "unicode"),
125 mbo_opt_struct('v', 0, "version"),
126 mbo_opt_struct('V', 0, "vernum"),
127 mbo_opt_struct('w', 0, "wide-chars"),
128 mbo_opt_struct('1', 0, "single-pass"),
129 mbo_opt_struct(10, 0, "no-generation-date"),
130 mbo_opt_struct(11, 0, "case-insensitive"),
131 mbo_opt_struct(12, 0, "case-inverted"),
132 mbo_opt_struct('-', 0, NULL) /* end of args */
135 static void usage()
137 std::cerr << "usage: re2c [-bcdDefFghirsuvVw1] [-o of] [-t th] file\n"
138 "\n"
139 "-? -h --help Display this info.\n"
140 "\n"
141 "-b --bit-vectors Implies -s. Use bit vectors as well in the attempt to\n"
142 " coax better code out of the compiler. Most useful for\n"
143 " specifications with more than a few keywords (e.g. for\n"
144 " most programming languages).\n"
145 "\n"
146 "-c --conditions Require start conditions.\n"
147 "\n"
148 "-d --debug-output Creates a parser that dumps information during\n"
149 " about the current position and in which state the\n"
150 " parser is.\n"
151 "\n"
152 "-D --emit-dot Emit a Graphviz dot view of the DFA graph\n"
153 "\n"
154 "-e --ecb Cross-compile from an ASCII platform to an EBCDIC one.\n"
155 " This cannot be combined with -w, -u or -r.\n"
156 "\n"
157 "-f --storable-state Generate a scanner that supports storable states.\n"
158 "\n"
159 "-F --flex-syntax Partial support for flex syntax.\n"
160 "\n"
161 "-g --computed-gotos Implies -b. Generate computed goto code (only useable\n"
162 " with gcc).\n"
163 "\n"
164 "-i --no-debug-info Do not generate '#line' info (usefull for versioning).\n"
165 "\n"
166 "-o of --output=of Specify the output file (of) instead of stdout\n"
167 "\n"
168 "-r --reusable Allow reuse of scanner definitions.\n"
169 " This cannot be used together with -e switch.\n"
170 "\n"
171 "-s --nested-ifs Generate nested ifs for some switches. Many compilers\n"
172 " need this assist to generate better code.\n"
173 "\n"
174 "-t th --type-header=th Generate a type header file (th) with type definitions.\n"
175 "\n"
176 "-u --unicode Implies -w but supports the full Unicode character set.\n"
177 " This cannot be used together with -e switch.\n"
178 "\n"
179 "-v --version Show version information.\n"
180 "\n"
181 "-V --vernum Show version as one number.\n"
182 "\n"
183 "-w --wide-chars Create a parser that supports wide chars (UCS-2). This\n"
184 " implies -s and cannot be used together with -e switch.\n"
185 "\n"
186 "-1 --single-pass Force single pass generation, this cannot be combined\n"
187 " with -f and disables YYMAXFILL generation prior to last\n"
188 " re2c block.\n"
189 "\n"
190 "--no-generation-date Suppress date output in the generated output so that it\n"
191 " only shows the re2c version.\n"
192 "\n"
193 "--case-insensitive All strings are case insensitive, so all \"-expressions\n"
194 " are treated in the same way '-expressions are.\n"
195 "\n"
196 "--case-inverted Invert the meaning of single and double quoted strings.\n"
197 " With this switch single quotes are case sensitive and\n"
198 " double quotes are case insensitive.\n"
202 } // end namespace re2c
204 using namespace re2c;
206 int main(int argc, char *argv[])
208 int c;
209 const char *sourceFileName = 0;
210 const char *outputFileName = 0;
211 const char *headerFileName = 0;
213 if (argc == 1)
215 usage();
216 return 2;
219 while ((c = mbo_getopt(argc, argv, OPTIONS, &opt_arg, &opt_ind, 1)) != -1)
221 switch (c)
224 case 'b':
225 bFlag = true;
226 sFlag = true;
227 break;
229 case 'c':
230 cFlag = true;
231 break;
233 case 'e':
234 xlat = asc2ebc;
235 talx = ebc2asc;
236 eFlag = true;
237 break;
239 case 'd':
240 dFlag = true;
241 break;
243 case 'D':
244 DFlag = true;
245 iFlag = true;
246 break;
248 case 'f':
249 fFlag = true;
250 break;
252 case 'F':
253 FFlag = true;
254 break;
256 case 'g':
257 gFlag = true;
258 bFlag = true;
259 sFlag = true;
260 break;
262 case 'i':
263 iFlag = true;
264 break;
266 case 'o':
267 outputFileName = opt_arg;
268 break;
270 case 'r':
271 rFlag = true;
272 break;
274 case 's':
275 sFlag = true;
276 break;
278 case 't':
279 tFlag = true;
280 headerFileName = opt_arg;
281 break;
283 case '1':
284 bSinglePass = true;
285 break;
287 case 'v':
288 cout << "re2c " << PACKAGE_VERSION << "\n";
289 return 2;
291 case 'V': {
292 string vernum(PACKAGE_VERSION);
294 if (vernum[1] == '.')
296 vernum.insert(0, "0");
298 vernum.erase(2, 1);
299 if (vernum[3] == '.')
301 vernum.insert(2, "0");
303 vernum.erase(4, 1);
304 if (vernum.length() < 6 || vernum[5] < '0' || vernum[5] > '9')
306 vernum.insert(4, "0");
308 vernum.resize(6);
309 cout << vernum << endl;
310 return 2;
313 case 'w':
314 nRealChars = (1<<16); /* 0x10000 */
315 sFlag = true;
316 wFlag = true;
317 break;
319 case 'u':
320 nRealChars = 0x110000; /* 17 times w-Flag */
321 sFlag = true;
322 uFlag = true;
323 break;
325 default:
326 case 'h':
327 case '?':
328 usage();
329 return 2;
331 case 10:
332 bNoGenerationDate = true;
333 break;
335 case 11:
336 bCaseInsensitive = true;
337 break;
339 case 12:
340 bCaseInverted = true;
341 break;
345 if ((bFlag || fFlag) && bSinglePass) {
346 std::cerr << "re2c: error: Cannot combine -1 and -b or -f switch\n";
347 return 1;
349 if (!cFlag && headerFileName)
351 std::cerr << "re2c: error: Can only output a header file when using -c switch\n";
352 return 2;
355 if (rFlag && eFlag)
357 std::cerr << "re2c: error: Cannot combine -e with -r switch\n";
358 return 2;
360 if (wFlag && eFlag)
362 std::cerr << "re2c: error: Cannot combine -e with -w or -u switch\n";
363 return 2;
365 if (wFlag && uFlag)
367 std::cerr << "re2c: error: Cannot combine -u with -w switch\n";
368 return 2;
371 if (dFlag && DFlag)
373 std::cerr << "re2c: error: Cannot combine -d with -D switch\n";
374 return 2;
377 if (uFlag)
379 wFlag = true;
382 if (argc == opt_ind + 1)
384 sourceFileName = argv[opt_ind];
386 else
388 std::cerr << "Unexpected argument: " << argv[argc-1] << "\n\n";
389 usage();
390 return 2;
393 // set up the source stream
394 re2c::ifstream_lc source;
396 if (sourceFileName[0] == '-' && sourceFileName[1] == '\0')
398 if (fFlag)
400 std::cerr << "re2c: error: multiple /*!re2c stdin is not acceptable when -f is specified\n";
401 return 1;
403 sourceFileName = "<stdin>";
404 source.open(stdin);
406 else if (!source.open(sourceFileName).is_open())
408 cerr << "re2c: error: cannot open " << sourceFileName << "\n";
409 return 1;
412 // set up the output stream
413 re2c::ofstream_lc output;
414 re2c::ofstream_lc header;
416 if (outputFileName == 0 || (sourceFileName[0] == '-' && sourceFileName[1] == '\0'))
418 outputFileName = "<stdout>";
419 output.open(stdout);
421 else if (!output.open(outputFileName).is_open())
423 cerr << "re2c: error: cannot open " << outputFileName << "\n";
424 return 1;
426 if (headerFileName)
428 if (!header.open(headerFileName).is_open())
430 cerr << "re2c: error: cannot open " << headerFileName << "\n";
431 return 1;
433 headerFileInfo = file_info(headerFileName, &header);
435 Scanner scanner(source, output);
436 sourceFileInfo = file_info(sourceFileName, &scanner);
437 outputFileInfo = file_info(outputFileName, &output);
439 if (!bSinglePass)
441 bUsedYYMarker = false;
443 re2c::ifstream_lc null_source;
445 if (!null_source.open(sourceFileName).is_open())
447 cerr << "re2c: error: cannot re-open " << sourceFileName << "\n";
448 return 1;
451 null_stream null_dev;
452 Scanner null_scanner(null_source, null_dev);
453 parse(null_scanner, null_dev, NULL);
454 next_label = 0;
455 next_fill_index = 0;
456 bWroteGetState = false;
457 bWroteCondCheck = false;
458 bUsedYYMaxFill = false;
459 bFirstPass = false;
460 sourceFileInfo.set_fname(sourceFileName);
463 bLastPass = true;
464 parse(scanner, output, header.is_open() ? &header : NULL);
465 return 0;