Line | Count | Source |
1 | | /* flex - tool to generate fast lexical analyzers */ |
2 | | |
3 | | /* SPDX-License-Identifier: BSD-3-Clause-flex */ |
4 | | |
5 | | /* Copyright (c) 1990 The Regents of the University of California. */ |
6 | | /* All rights reserved. */ |
7 | | |
8 | | /* This code is derived from software contributed to Berkeley by */ |
9 | | /* Vern Paxson. */ |
10 | | |
11 | | /* The United States Government has rights in this work pursuant */ |
12 | | /* to contract no. DE-AC03-76SF00098 between the United States */ |
13 | | /* Department of Energy and the University of California. */ |
14 | | |
15 | | /* This file is part of flex. */ |
16 | | |
17 | | /* Redistribution and use in source and binary forms, with or without */ |
18 | | /* modification, are permitted provided that the following conditions */ |
19 | | /* are met: */ |
20 | | |
21 | | /* 1. Redistributions of source code must retain the above copyright */ |
22 | | /* notice, this list of conditions and the following disclaimer. */ |
23 | | /* 2. Redistributions in binary form must reproduce the above copyright */ |
24 | | /* notice, this list of conditions and the following disclaimer in the */ |
25 | | /* documentation and/or other materials provided with the distribution. */ |
26 | | |
27 | | /* Neither the name of the University nor the names of its contributors */ |
28 | | /* may be used to endorse or promote products derived from this software */ |
29 | | /* without specific prior written permission. */ |
30 | | |
31 | | /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ |
32 | | /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ |
33 | | /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ |
34 | | /* PURPOSE. */ |
35 | | |
36 | | |
37 | | #include "flexdef.h" |
38 | | #include "version.h" |
39 | | #include "options.h" |
40 | | #include "tables.h" |
41 | | #include "parse.h" |
42 | | |
43 | | static char flex_version[] ="ran";// FLEX_VERSION; |
44 | | |
45 | | /* declare functions that have forward references */ |
46 | | |
47 | | void flexinit(int, char **); |
48 | | void readin(void); |
49 | | void set_up_initial_allocations(void); |
50 | | |
51 | | /* these globals are all defined and commented in flexdef.h */ |
52 | | bool syntaxerror, eofseen; |
53 | | int yymore_used, reject, real_reject, continued_action, in_rule; |
54 | | int datapos, dataline, linenum; |
55 | | FILE *skelfile = NULL; |
56 | | int skel_ind = 0; |
57 | | char *action_array; |
58 | | int action_size, defs1_offset, prolog_offset, action_offset, |
59 | | action_index; |
60 | | char *infilename = NULL; |
61 | | char *extra_type = NULL; |
62 | | int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; |
63 | | int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; |
64 | | int maximum_mns, current_mns, current_max_rules; |
65 | | int num_rules, num_eof_rules, default_rule, lastnfa; |
66 | | int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; |
67 | | int *accptnum, *assoc_rule, *state_type; |
68 | | int *rule_type, *rule_linenum; |
69 | | int current_state_type; |
70 | | bool variable_trailing_context_rules; |
71 | | int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; |
72 | | int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; |
73 | | int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, |
74 | | tecfwd[CSIZE + 1]; |
75 | | int tecbck[CSIZE + 1]; |
76 | | int lastsc, *scset, *scbol; |
77 | | /* scxclu[] and sceof[] are boolean arrays, but allocated as char |
78 | | * arrays for size. */ |
79 | | char *scxclu, *sceof; |
80 | | int current_max_scs; |
81 | | const char **scname; |
82 | | int current_max_dfa_size, current_max_xpairs; |
83 | | int current_max_template_xpairs, current_max_dfas; |
84 | | int lastdfa, *nxt, *chk, *tnxt; |
85 | | int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; |
86 | | union dfaacc_union *dfaacc; |
87 | | int *accsiz, *dhash, numas; |
88 | | int numsnpairs, jambase, jamstate; |
89 | | int lastccl, *cclmap, *ccllen, *cclng, cclreuse; |
90 | | int current_maxccls, current_max_ccl_tbl_size; |
91 | | unsigned char *ccltbl; |
92 | | char nmstr[MAXLINE]; |
93 | | int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs, nmval; |
94 | | int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; |
95 | | int num_backing_up, bol_needed; |
96 | | int end_of_buffer_state; |
97 | | char **input_files; |
98 | | int num_input_files; |
99 | | jmp_buf flex_main_jmp_buf; |
100 | | /* rule_useful[], rule_has_nl[] and ccl_has_nl[] are boolean arrays, |
101 | | * but allocated as char arrays for size. */ |
102 | | char *rule_useful, *rule_has_nl, *ccl_has_nl; |
103 | | int nlch = '\n'; |
104 | | |
105 | | bool tablesext, tablesverify, gentables; |
106 | | char *tablesfilename=0,*tablesname=0; |
107 | | struct yytbl_writer tableswr; |
108 | | size_t footprint; |
109 | | |
110 | | struct ctrl_bundle_t ctrl; |
111 | | struct env_bundle_t env; |
112 | | |
113 | | /* Make sure program_name is initialized so we don't crash if writing |
114 | | * out an error message before getting the program name from argv[0]. |
115 | | */ |
116 | | char *program_name = "flex"; |
117 | | |
118 | | static const char outfile_template[] = "lex.%s.%s"; |
119 | | static const char *backing_name = "lex.backup"; |
120 | | static const char tablesfile_template[] = "lex.%s.tables"; |
121 | | |
122 | | /* From scan.l */ |
123 | | extern FILE* yyout; |
124 | | |
125 | | static char outfile_path[MAXLINE]; |
126 | | static int outfile_created = 0; |
127 | | static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ |
128 | | const char *escaped_qstart = "]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[["; |
129 | | const char *escaped_qend = "]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[["; |
130 | | |
131 | | /* For debugging. The max number of filters to apply to skeleton. */ |
132 | | static int preproc_level = 1000; |
133 | | |
134 | | int flex_main (int argc, char *argv[]); |
135 | | |
136 | | int flex_main (int argc, char *argv[]) |
137 | 778 | { |
138 | 778 | int i, exit_status, child_status; |
139 | 778 | int did_eof_rule = false; |
140 | | |
141 | | /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The |
142 | | * return value of setjmp, if non-zero, is the desired exit code PLUS ONE. |
143 | | * For example, if you want 'main' to return with code '2', then call |
144 | | * longjmp() with an argument of 3. This is because it is invalid to |
145 | | * specify a value of 0 to longjmp. FLEX_EXIT(n) should be used instead of |
146 | | * exit(n); |
147 | | */ |
148 | 778 | exit_status = setjmp (flex_main_jmp_buf); |
149 | 778 | if (exit_status){ |
150 | 778 | if (stdout && !_stdout_closed && !ferror(stdout)){ |
151 | 0 | fflush(stdout); |
152 | 0 | fclose(stdout); |
153 | 0 | } |
154 | 778 | return 0; |
155 | | /* |
156 | | while (wait(&child_status) > 0){ |
157 | | if (!WIFEXITED (child_status) |
158 | | || WEXITSTATUS (child_status) != 0){ |
159 | | if( exit_status <= 1 ) |
160 | | exit_status = 2; |
161 | | |
162 | | } |
163 | | } |
164 | | return exit_status - 1; |
165 | | */ |
166 | 778 | } |
167 | | |
168 | 0 | flexinit (argc, argv); |
169 | |
|
170 | 0 | readin (); |
171 | 0 | skelout (true); /* %% [1.0] DFA */ |
172 | 0 | footprint += ntod (); |
173 | |
|
174 | 0 | for (i = 1; i <= num_rules; ++i) |
175 | 0 | if (!rule_useful[i] && i != default_rule) |
176 | 0 | line_warning (_("rule cannot be matched"), |
177 | 0 | rule_linenum[i]); |
178 | |
|
179 | 0 | if (ctrl.spprdflt && !reject && rule_useful[default_rule]) |
180 | 0 | line_warning (_ |
181 | 0 | ("-s option given but default rule can be matched"), |
182 | 0 | rule_linenum[default_rule]); |
183 | |
|
184 | 0 | comment("START of m4 controls\n"); |
185 | | |
186 | | // mode switches for yy_trans_info specification |
187 | | // nultrans |
188 | 0 | if (nultrans) |
189 | 0 | visible_define ( "M4_MODE_NULTRANS"); |
190 | 0 | else { |
191 | 0 | visible_define ( "M4_MODE_NO_NULTRANS"); |
192 | 0 | if (ctrl.fulltbl) |
193 | 0 | visible_define ( "M4_MODE_NULTRANS_FULLTBL"); |
194 | 0 | else |
195 | 0 | visible_define ( "M4_MODE_NO_NULTRANS_FULLTBL"); |
196 | 0 | if (ctrl.fullspd) |
197 | 0 | visible_define ( "M4_MODE_NULTRANS_FULLSPD"); |
198 | 0 | else |
199 | 0 | visible_define ( "M4_MODE_NO_NULTRANS_FULLSPD"); |
200 | 0 | } |
201 | | |
202 | 0 | comment("END of m4 controls\n"); |
203 | 0 | out ("\n"); |
204 | |
|
205 | 0 | comment("START of Flex-generated definitions\n"); |
206 | 0 | out_str_dec ("M4_HOOK_CONST_DEFINE_UINT(%s, %d)", "YY_NUM_RULES", num_rules); |
207 | 0 | out_str_dec ("M4_HOOK_CONST_DEFINE_STATE(%s, %d)", "YY_END_OF_BUFFER", num_rules + 1); |
208 | 0 | out_str_dec ("M4_HOOK_CONST_DEFINE_STATE(%s, %d)", "YY_JAMBASE", jambase); |
209 | 0 | out_str_dec ("M4_HOOK_CONST_DEFINE_STATE(%s, %d)", "YY_JAMSTATE", jamstate); |
210 | 0 | out_str_dec ("M4_HOOK_CONST_DEFINE_BYTE(%s, %d)", "YY_NUL_EC", NUL_ec); |
211 | | /* Need to define the transet type as a size large |
212 | | * enough to hold the biggest offset. |
213 | | */ |
214 | 0 | out_str ("M4_HOOK_SET_OFFSET_TYPE(%s)", optimize_pack(tblend + numecs + 1)->name); |
215 | 0 | comment("END of Flex-generated definitions\n"); |
216 | |
|
217 | 0 | skelout (true); /* %% [2.0] - tables get dumped here */ |
218 | | |
219 | | /* Generate the C state transition tables from the DFA. */ |
220 | 0 | make_tables (); |
221 | |
|
222 | 0 | skelout (true); /* %% [3.0] - mode-dependent static declarations get dumped here */ |
223 | |
|
224 | 0 | out (&action_array[defs1_offset]); |
225 | |
|
226 | 0 | line_directive_out (stdout, NULL, linenum); |
227 | |
|
228 | 0 | skelout (true); /* %% [4.0] - various random yylex internals get dumped here */ |
229 | | |
230 | | /* Copy prolog to output file. */ |
231 | 0 | out (&action_array[prolog_offset]); |
232 | |
|
233 | 0 | line_directive_out (stdout, NULL, linenum); |
234 | |
|
235 | 0 | skelout (true); /* %% [5.0] - main loop of matching-engine code gets dumped here */ |
236 | | |
237 | | /* Copy actions to output file. */ |
238 | 0 | out (&action_array[action_offset]); |
239 | |
|
240 | 0 | line_directive_out (stdout, NULL, linenum); |
241 | | |
242 | | /* generate cases for any missing EOF rules */ |
243 | 0 | for (i = 1; i <= lastsc; ++i) |
244 | 0 | if (!sceof[i]) { |
245 | 0 | out_str ("M4_HOOK_EOF_STATE_CASE_ARM(%s)", scname[i]); |
246 | 0 | outc('\n'); |
247 | 0 | out ("M4_HOOK_EOF_STATE_CASE_FALLTHROUGH"); |
248 | 0 | outc('\n'); |
249 | 0 | did_eof_rule = true; |
250 | 0 | } |
251 | |
|
252 | 0 | if (did_eof_rule) { |
253 | 0 | out ("M4_HOOK_EOF_STATE_CASE_TERMINATE"); |
254 | 0 | } |
255 | |
|
256 | 0 | skelout (true); |
257 | | |
258 | | /* Copy remainder of input to output. */ |
259 | |
|
260 | 0 | line_directive_out (stdout, infilename, linenum); |
261 | |
|
262 | 0 | if (sectnum == 3) { |
263 | 0 | OUT_BEGIN_CODE (); |
264 | 0 | if (!ctrl.no_section3_escape) |
265 | 0 | fputs("[[", stdout); |
266 | 0 | (void) flexscan (); /* copy remainder of input to output */ |
267 | 0 | if (!ctrl.no_section3_escape) |
268 | 0 | fputs("]]", stdout); |
269 | 0 | OUT_END_CODE (); |
270 | 0 | } |
271 | | |
272 | | /* Note, flexend does not return. It exits with its argument |
273 | | * as status. |
274 | | */ |
275 | 0 | flexend (0); |
276 | |
|
277 | 0 | return 0; /* keep compilers/lint happy */ |
278 | 778 | } |
279 | | |
280 | | /* Wrapper around flex_main, so flex_main can be built as a library. */ |
281 | | int main2 (int argc, char *argv[]) |
282 | 0 | { |
283 | | #if defined(ENABLE_NLS) && ENABLE_NLS |
284 | | #if HAVE_LOCALE_H |
285 | | setlocale (LC_MESSAGES, ""); |
286 | | setlocale (LC_CTYPE, ""); |
287 | | textdomain (PACKAGE); |
288 | | bindtextdomain (PACKAGE, LOCALEDIR); |
289 | | #endif |
290 | | #endif |
291 | |
|
292 | 0 | return flex_main (argc, argv); |
293 | 0 | } |
294 | | |
295 | | /* Set up the output filter chain. */ |
296 | | |
297 | | void initialize_output_filters(void) |
298 | 0 | { |
299 | 0 | const char * m4 = NULL; |
300 | |
|
301 | 0 | output_chain = filter_create_int(NULL, filter_tee_header, env.headerfilename); |
302 | 0 | if ( !(m4 = getenv("M4"))) { |
303 | 0 | m4 = NULL; |
304 | 0 | } |
305 | 0 | filter_create_ext(output_chain, m4, "-P", (char *) 0); |
306 | 0 | filter_create_int(output_chain, filter_fix_linedirs, NULL); |
307 | | |
308 | | /* For debugging, only run the requested number of filters. */ |
309 | 0 | if (preproc_level > 0) { |
310 | 0 | filter_truncate(output_chain, preproc_level); |
311 | 0 | filter_apply_chain(output_chain); |
312 | 0 | } |
313 | 0 | } |
314 | | |
315 | | |
316 | | /* check_options - check user-specified options */ |
317 | | |
318 | | void check_options (void) |
319 | 231 | { |
320 | 231 | int i; |
321 | | |
322 | 231 | if (ctrl.lex_compat) { |
323 | 0 | if (ctrl.C_plus_plus) |
324 | 0 | flexerror (_("Can't use -+ with -l option")); |
325 | |
|
326 | 0 | if (ctrl.fulltbl || ctrl.fullspd) |
327 | 0 | flexerror (_("Can't use -f or -F with -l option")); |
328 | |
|
329 | 0 | if (ctrl.reentrant || ctrl.bison_bridge_lval) |
330 | 0 | flexerror (_ |
331 | 0 | ("Can't use --ctrl.reentrant or --bison-bridge with -l option")); |
332 | |
|
333 | 0 | ctrl.yytext_is_array = true; |
334 | 0 | ctrl.do_yylineno = true; |
335 | 0 | ctrl.use_read = false; |
336 | 0 | } |
337 | | |
338 | | |
339 | | #if 0 |
340 | | /* This makes no sense whatsoever. I'm removing it. */ |
341 | | if (ctrl.do_yylineno) |
342 | | /* This should really be "maintain_backup_tables = true" */ |
343 | | ctrl.reject_really_used = true; |
344 | | #endif |
345 | | |
346 | 231 | if (ctrl.csize == trit_unspecified) { |
347 | 231 | if ((ctrl.fulltbl || ctrl.fullspd) && !ctrl.useecs) |
348 | 0 | ctrl.csize = DEFAULT_CSIZE; |
349 | 231 | else |
350 | 231 | ctrl.csize = CSIZE; |
351 | 231 | } |
352 | | |
353 | 231 | if (ctrl.interactive == trit_unspecified) { |
354 | 231 | if (ctrl.fulltbl || ctrl.fullspd) |
355 | 0 | ctrl.interactive = trit_false; |
356 | 231 | else |
357 | 231 | ctrl.interactive = trit_true; |
358 | 231 | } |
359 | | |
360 | 231 | if (ctrl.fulltbl || ctrl.fullspd) { |
361 | 0 | if (ctrl.usemecs) |
362 | 0 | flexerror (_ |
363 | 0 | ("-Cf/-CF and -Cm don't make sense together")); |
364 | |
|
365 | 0 | if (ctrl.interactive != trit_false) |
366 | 0 | flexerror (_("-Cf/-CF and -I are incompatible")); |
367 | |
|
368 | 0 | if (ctrl.lex_compat) |
369 | 0 | flexerror (_ |
370 | 0 | ("-Cf/-CF are incompatible with lex-compatibility mode")); |
371 | | |
372 | |
|
373 | 0 | if (ctrl.fulltbl && ctrl.fullspd) |
374 | 0 | flexerror (_ |
375 | 0 | ("-Cf and -CF are mutually exclusive")); |
376 | 0 | } |
377 | | |
378 | 231 | if (ctrl.C_plus_plus && ctrl.fullspd) |
379 | 0 | flexerror (_("Can't use -+ with -CF option")); |
380 | | |
381 | 231 | if (ctrl.C_plus_plus && ctrl.yytext_is_array) { |
382 | 0 | lwarn (_("%array incompatible with -+ option")); |
383 | 0 | ctrl.yytext_is_array = false; |
384 | 0 | } |
385 | | |
386 | 231 | if (ctrl.C_plus_plus && (ctrl.reentrant)) |
387 | 0 | flexerror (_("Options -+ and --reentrant are mutually exclusive.")); |
388 | | |
389 | 231 | if (ctrl.C_plus_plus && ctrl.bison_bridge_lval) |
390 | 0 | flexerror (_("bison bridge not supported for the C++ scanner.")); |
391 | | |
392 | | |
393 | 231 | if (ctrl.useecs) { /* Set up doubly-linked equivalence classes. */ |
394 | | |
395 | | /* We loop all the way up to ctrl.csize, since ecgroup[ctrl.csize] is |
396 | | * the position used for NUL characters. |
397 | | */ |
398 | 231 | ecgroup[1] = NIL; |
399 | | |
400 | 59.1k | for (i = 2; i <= ctrl.csize; ++i) { |
401 | 58.9k | ecgroup[i] = i - 1; |
402 | 58.9k | nextecm[i - 1] = i; |
403 | 58.9k | } |
404 | | |
405 | 231 | nextecm[ctrl.csize] = NIL; |
406 | 231 | } |
407 | | |
408 | 0 | else { |
409 | | /* Put everything in its own equivalence class. */ |
410 | 0 | for (i = 1; i <= ctrl.csize; ++i) { |
411 | 0 | ecgroup[i] = i; |
412 | 0 | nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ |
413 | 0 | } |
414 | 0 | } |
415 | | |
416 | 231 | if (!env.use_stdout) { |
417 | 231 | FILE *prev_stdout; |
418 | | |
419 | 231 | if (!env.did_outfilename) { |
420 | 231 | snprintf (outfile_path, sizeof(outfile_path), outfile_template, |
421 | 231 | ctrl.prefix, suffix()); |
422 | | |
423 | 231 | env.outfilename = outfile_path; |
424 | 231 | } |
425 | | |
426 | 231 | prev_stdout = freopen (env.outfilename, "w+", stdout); |
427 | | |
428 | 231 | if (prev_stdout == NULL) |
429 | 0 | lerr (_("could not create %s"), env.outfilename); |
430 | | |
431 | 231 | outfile_created = 1; |
432 | 231 | } |
433 | 231 | } |
434 | | |
435 | | /* flexend - terminate flex |
436 | | * |
437 | | * note |
438 | | * This routine does not return. |
439 | | */ |
440 | | |
441 | | void flexend (int exit_status) |
442 | 778 | { |
443 | 778 | static int called_before = -1; /* prevent infinite recursion. */ |
444 | 778 | int tblsiz; |
445 | | |
446 | 778 | if (++called_before) |
447 | 777 | FLEX_EXIT (exit_status); |
448 | | |
449 | 1 | if (ctrl.yyclass != NULL && !ctrl.C_plus_plus) |
450 | 0 | flexerror (_("%option yyclass only meaningful for C++ scanners")); |
451 | | |
452 | 1 | if (skelfile != NULL) { |
453 | 0 | if (ferror (skelfile)) |
454 | 0 | lerr (_("input error reading skeleton file %s"), |
455 | 0 | env.skelname); |
456 | | |
457 | 0 | else if (fclose (skelfile)) |
458 | 0 | lerr (_("error closing skeleton file %s"), |
459 | 0 | env.skelname); |
460 | 0 | } |
461 | | |
462 | 1 | if (exit_status != 0 && outfile_created) { |
463 | 1 | if (ferror (stdout)) |
464 | 0 | lerr (_("error writing output file %s"), |
465 | 0 | env.outfilename); |
466 | | |
467 | 1 | else if ((_stdout_closed = 1) && fclose (stdout)) |
468 | 0 | lerr (_("error closing output file %s"), |
469 | 0 | env.outfilename); |
470 | | |
471 | 1 | else if (unlink (env.outfilename)) |
472 | 0 | lerr (_("error deleting output file %s"), |
473 | 0 | env.outfilename); |
474 | 1 | } |
475 | | |
476 | | |
477 | 1 | if (env.backing_up_report && ctrl.backing_up_file) { |
478 | 0 | if (num_backing_up == 0) |
479 | 0 | fprintf (ctrl.backing_up_file, _("No backing up.\n")); |
480 | 0 | else if (ctrl.fullspd || ctrl.fulltbl) |
481 | 0 | fprintf (ctrl.backing_up_file, |
482 | 0 | _ |
483 | 0 | ("%d backing up (non-accepting) states.\n"), |
484 | 0 | num_backing_up); |
485 | 0 | else |
486 | 0 | fprintf (ctrl.backing_up_file, |
487 | 0 | _("Compressed tables always back up.\n")); |
488 | |
|
489 | 0 | if (ferror (ctrl.backing_up_file)) |
490 | 0 | lerr (_("error writing backup file %s"), |
491 | 0 | backing_name); |
492 | | |
493 | 0 | else if (fclose (ctrl.backing_up_file)) |
494 | 0 | lerr (_("error closing backup file %s"), |
495 | 0 | backing_name); |
496 | 0 | } |
497 | | |
498 | 1 | if (env.printstats) { |
499 | 0 | fprintf (stderr, _("%s version %s usage statistics:\n"), |
500 | 0 | program_name, flex_version); |
501 | |
|
502 | 0 | fprintf (stderr, _(" scanner options: -")); |
503 | |
|
504 | 0 | if (ctrl.C_plus_plus) |
505 | 0 | putc ('+', stderr); |
506 | 0 | if (env.backing_up_report) |
507 | 0 | putc ('b', stderr); |
508 | 0 | if (ctrl.ddebug) |
509 | 0 | putc ('d', stderr); |
510 | 0 | if (sf_case_ins()) |
511 | 0 | putc ('i', stderr); |
512 | 0 | if (ctrl.lex_compat) |
513 | 0 | putc ('l', stderr); |
514 | 0 | if (ctrl.posix_compat) |
515 | 0 | putc ('X', stderr); |
516 | 0 | if (env.performance_hint > 0) |
517 | 0 | putc ('p', stderr); |
518 | 0 | if (env.performance_hint > 1) |
519 | 0 | putc ('p', stderr); |
520 | 0 | if (ctrl.spprdflt) |
521 | 0 | putc ('s', stderr); |
522 | 0 | if (ctrl.reentrant) |
523 | 0 | fputs ("--reentrant", stderr); |
524 | 0 | if (ctrl.bison_bridge_lval) |
525 | 0 | fputs ("--bison-bridge", stderr); |
526 | 0 | if (ctrl.bison_bridge_lloc) |
527 | 0 | fputs ("--bison-locations", stderr); |
528 | 0 | if (env.use_stdout) |
529 | 0 | putc ('t', stderr); |
530 | 0 | if (env.printstats) |
531 | 0 | putc ('v', stderr); /* always true! */ |
532 | 0 | if (env.nowarn) |
533 | 0 | putc ('w', stderr); |
534 | 0 | if (ctrl.interactive == trit_false) |
535 | 0 | putc ('B', stderr); |
536 | 0 | if (ctrl.interactive == trit_true) |
537 | 0 | putc ('I', stderr); |
538 | 0 | if (!ctrl.gen_line_dirs) |
539 | 0 | putc ('L', stderr); |
540 | 0 | if (env.trace) |
541 | 0 | putc ('T', stderr); |
542 | |
|
543 | 0 | if (ctrl.csize == trit_unspecified) |
544 | | /* We encountered an error fairly early on, so ctrl.csize |
545 | | * never got specified. Define it now, to prevent |
546 | | * bogus table sizes being written out below. |
547 | | */ |
548 | 0 | ctrl.csize = 256; |
549 | |
|
550 | 0 | if (ctrl.csize == 128) |
551 | 0 | putc ('7', stderr); |
552 | 0 | else |
553 | 0 | putc ('8', stderr); |
554 | |
|
555 | 0 | fprintf (stderr, " -C"); |
556 | |
|
557 | 0 | if (ctrl.long_align) |
558 | 0 | putc ('a', stderr); |
559 | 0 | if (ctrl.fulltbl) |
560 | 0 | putc ('f', stderr); |
561 | 0 | if (ctrl.fullspd) |
562 | 0 | putc ('F', stderr); |
563 | 0 | if (ctrl.useecs) |
564 | 0 | putc ('e', stderr); |
565 | 0 | if (ctrl.usemecs) |
566 | 0 | putc ('m', stderr); |
567 | 0 | if (ctrl.use_read) |
568 | 0 | putc ('r', stderr); |
569 | |
|
570 | 0 | if (env.did_outfilename) |
571 | 0 | fprintf (stderr, " -o%s", env.outfilename); |
572 | |
|
573 | 0 | if (env.skelname != NULL) |
574 | 0 | fprintf (stderr, " -S%s", env.skelname); |
575 | |
|
576 | 0 | if (strcmp (ctrl.prefix, "yy")) |
577 | 0 | fprintf (stderr, " -P%s", ctrl.prefix); |
578 | |
|
579 | 0 | putc ('\n', stderr); |
580 | |
|
581 | 0 | fprintf (stderr, _(" %d/%d NFA states\n"), |
582 | 0 | lastnfa, current_mns); |
583 | 0 | fprintf (stderr, _(" %d/%d DFA states (%d words)\n"), |
584 | 0 | lastdfa, current_max_dfas, totnst); |
585 | 0 | fprintf (stderr, _(" %d rules\n"), |
586 | 0 | num_rules + num_eof_rules - |
587 | 0 | 1 /* - 1 for def. rule */ ); |
588 | |
|
589 | 0 | if (num_backing_up == 0) |
590 | 0 | fprintf (stderr, _(" No backing up\n")); |
591 | 0 | else if (ctrl.fullspd || ctrl.fulltbl) |
592 | 0 | fprintf (stderr, |
593 | 0 | _ |
594 | 0 | (" %d backing-up (non-accepting) states\n"), |
595 | 0 | num_backing_up); |
596 | 0 | else |
597 | 0 | fprintf (stderr, |
598 | 0 | _ |
599 | 0 | (" Compressed tables always back-up\n")); |
600 | |
|
601 | 0 | if (bol_needed) |
602 | 0 | fprintf (stderr, |
603 | 0 | _(" Beginning-of-line patterns used\n")); |
604 | |
|
605 | 0 | fprintf (stderr, _(" %d/%d start conditions\n"), lastsc, |
606 | 0 | current_max_scs); |
607 | 0 | fprintf (stderr, |
608 | 0 | _ |
609 | 0 | (" %d epsilon states, %d double epsilon states\n"), |
610 | 0 | numeps, eps2); |
611 | |
|
612 | 0 | if (lastccl == 0) |
613 | 0 | fprintf (stderr, _(" no character classes\n")); |
614 | 0 | else |
615 | 0 | fprintf (stderr, |
616 | 0 | _ |
617 | 0 | (" %d/%d character classes needed %d/%d words of storage, %d reused\n"), |
618 | 0 | lastccl, current_maxccls, |
619 | 0 | cclmap[lastccl] + ccllen[lastccl], |
620 | 0 | current_max_ccl_tbl_size, cclreuse); |
621 | |
|
622 | 0 | fprintf (stderr, _(" %d state/nextstate pairs created\n"), |
623 | 0 | numsnpairs); |
624 | 0 | fprintf (stderr, |
625 | 0 | _(" %d/%d unique/duplicate transitions\n"), |
626 | 0 | numuniq, numdup); |
627 | |
|
628 | 0 | if (ctrl.fulltbl) { |
629 | 0 | tblsiz = lastdfa * numecs; |
630 | 0 | fprintf (stderr, _(" %d table entries\n"), |
631 | 0 | tblsiz); |
632 | 0 | } |
633 | | |
634 | 0 | else { |
635 | 0 | tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; |
636 | |
|
637 | 0 | fprintf (stderr, |
638 | 0 | _(" %d/%d base-def entries created\n"), |
639 | 0 | lastdfa + numtemps, current_max_dfas); |
640 | 0 | fprintf (stderr, |
641 | 0 | _ |
642 | 0 | (" %d/%d (peak %d) nxt-chk entries created\n"), |
643 | 0 | tblend, current_max_xpairs, peakpairs); |
644 | 0 | fprintf (stderr, |
645 | 0 | _ |
646 | 0 | (" %d/%d (peak %d) template nxt-chk entries created\n"), |
647 | 0 | numtemps * nummecs, |
648 | 0 | current_max_template_xpairs, |
649 | 0 | numtemps * numecs); |
650 | 0 | fprintf (stderr, _(" %d empty table entries\n"), |
651 | 0 | nummt); |
652 | 0 | fprintf (stderr, _(" %d protos created\n"), |
653 | 0 | numprots); |
654 | 0 | fprintf (stderr, |
655 | 0 | _(" %d templates created, %d uses\n"), |
656 | 0 | numtemps, tmpuses); |
657 | 0 | } |
658 | |
|
659 | 0 | if (ctrl.useecs) { |
660 | 0 | tblsiz = tblsiz + ctrl.csize; |
661 | 0 | fprintf (stderr, |
662 | 0 | _ |
663 | 0 | (" %d/%d equivalence classes created\n"), |
664 | 0 | numecs, ctrl.csize); |
665 | 0 | } |
666 | |
|
667 | 0 | if (ctrl.usemecs) { |
668 | 0 | tblsiz = tblsiz + numecs; |
669 | 0 | fprintf (stderr, |
670 | 0 | _ |
671 | 0 | (" %d/%d meta-equivalence classes created\n"), |
672 | 0 | nummecs, ctrl.csize); |
673 | 0 | } |
674 | |
|
675 | 0 | fprintf (stderr, |
676 | 0 | _ |
677 | 0 | (" %d (%d saved) hash collisions, %d DFAs equal\n"), |
678 | 0 | hshcol, hshsave, dfaeql); |
679 | 0 | fprintf (stderr, _(" %d sets of reallocations needed\n"), |
680 | 0 | num_reallocs); |
681 | 0 | fprintf (stderr, _(" %d total table entries needed\n"), |
682 | 0 | tblsiz); |
683 | 0 | } |
684 | | |
685 | 1 | FLEX_EXIT (exit_status); |
686 | 778 | } |
687 | | |
688 | | |
689 | | /* flexinit - initialize flex */ |
690 | | |
691 | | void flexinit (int argc, char **argv) |
692 | 778 | { |
693 | 778 | int i, sawcmpflag, rv, optind; |
694 | 778 | char *arg; |
695 | 778 | scanopt_t sopt; |
696 | | |
697 | 778 | memset(&ctrl, '\0', sizeof(ctrl)); |
698 | 778 | syntaxerror = false; |
699 | 778 | yymore_used = continued_action = false; |
700 | 778 | in_rule = reject = false; |
701 | 778 | ctrl.yymore_really_used = ctrl.reject_really_used = trit_unspecified; |
702 | | |
703 | 778 | ctrl.do_main = trit_unspecified; |
704 | 778 | ctrl.interactive = ctrl.csize = trit_unspecified; |
705 | 778 | ctrl.do_yywrap = ctrl.gen_line_dirs = ctrl.usemecs = ctrl.useecs = true; |
706 | 778 | ctrl.reentrant = ctrl.bison_bridge_lval = ctrl.bison_bridge_lloc = false; |
707 | 778 | env.performance_hint = 0; |
708 | 778 | ctrl.prefix = "yy"; |
709 | 778 | ctrl.rewrite = false; |
710 | 778 | ctrl.yylmax = BUFSIZ; |
711 | | |
712 | 778 | tablesext = tablesverify = false; |
713 | 778 | gentables = true; |
714 | 778 | tablesfilename = tablesname = NULL; |
715 | | |
716 | 778 | sawcmpflag = false; |
717 | | |
718 | | /* Initialize dynamic array for holding the rule actions. */ |
719 | 778 | action_size = 2048; /* default size of action array in bytes */ |
720 | 778 | action_array = allocate_character_array (action_size); |
721 | 778 | defs1_offset = prolog_offset = action_offset = action_index = 0; |
722 | 778 | action_array[0] = '\0'; |
723 | | |
724 | | /* Initialize any buffers. */ |
725 | 778 | buf_init (&userdef_buf, sizeof (char)); /* one long string */ |
726 | 778 | buf_init (&top_buf, sizeof (char)); /* one long string */ |
727 | | |
728 | 778 | sf_init (); |
729 | | |
730 | | /* Enable C++ if program name ends with '+'. */ |
731 | 778 | program_name = argv[0]; |
732 | | |
733 | 778 | if (program_name != NULL && |
734 | 778 | program_name[strlen (program_name) - 1] == '+') |
735 | 0 | ctrl.C_plus_plus = true; |
736 | | |
737 | | /* read flags */ |
738 | 778 | sopt = scanopt_init (flexopts, argc, argv, 0); |
739 | 778 | if (!sopt) { |
740 | | /* This will only happen when flexopts array is altered. */ |
741 | 0 | fprintf (stderr, |
742 | 0 | _("Internal error. flexopts are malformed.\n")); |
743 | 0 | FLEX_EXIT (1); |
744 | 0 | } |
745 | | |
746 | 778 | while ((rv = scanopt (sopt, &arg, &optind)) != 0) { |
747 | |
|
748 | 0 | if (rv < 0) { |
749 | | /* Scanopt has already printed an option-specific error message. */ |
750 | 0 | fprintf (stderr, |
751 | 0 | _ |
752 | 0 | ("Try `%s --help' for more information.\n"), |
753 | 0 | program_name); |
754 | 0 | FLEX_EXIT (1); |
755 | 0 | } |
756 | | |
757 | 0 | switch ((enum flexopt_flag_t) rv) { |
758 | 0 | case OPT_CPLUSPLUS: |
759 | 0 | ctrl.C_plus_plus = true; |
760 | 0 | break; |
761 | | |
762 | 0 | case OPT_BATCH: |
763 | 0 | ctrl.interactive = trit_false; |
764 | 0 | break; |
765 | | |
766 | 0 | case OPT_BACKUP: |
767 | 0 | env.backing_up_report = trit_true; |
768 | 0 | break; |
769 | | |
770 | 0 | case OPT_BACKUP_FILE: |
771 | 0 | env.backing_up_report = true; |
772 | 0 | backing_name = arg; |
773 | 0 | break; |
774 | | |
775 | 0 | case OPT_DONOTHING: |
776 | 0 | break; |
777 | | |
778 | 0 | case OPT_COMPRESSION: |
779 | 0 | if (!sawcmpflag) { |
780 | 0 | ctrl.useecs = false; |
781 | 0 | ctrl.usemecs = false; |
782 | 0 | ctrl.fulltbl = false; |
783 | 0 | sawcmpflag = true; |
784 | 0 | } |
785 | |
|
786 | 0 | for (i = 0; arg && arg[i] != '\0'; i++) |
787 | 0 | switch (arg[i]) { |
788 | 0 | case 'a': |
789 | 0 | ctrl.long_align = true; |
790 | 0 | break; |
791 | | |
792 | 0 | case 'e': |
793 | 0 | ctrl.useecs = true; |
794 | 0 | break; |
795 | | |
796 | 0 | case 'F': |
797 | 0 | ctrl.fullspd = true; |
798 | 0 | break; |
799 | | |
800 | 0 | case 'f': |
801 | 0 | ctrl.fulltbl = true; |
802 | 0 | break; |
803 | | |
804 | 0 | case 'm': |
805 | 0 | ctrl.usemecs = true; |
806 | 0 | break; |
807 | | |
808 | 0 | case 'r': |
809 | 0 | ctrl.use_read = true; |
810 | 0 | break; |
811 | | |
812 | 0 | default: |
813 | 0 | lerr (_ |
814 | 0 | ("unknown -C option '%c'"), |
815 | 0 | arg[i]); |
816 | 0 | break; |
817 | 0 | } |
818 | 0 | break; |
819 | | |
820 | 0 | case OPT_DEBUG: |
821 | 0 | ctrl.ddebug = true; |
822 | 0 | break; |
823 | | |
824 | 0 | case OPT_NO_DEBUG: |
825 | 0 | ctrl.ddebug = false; |
826 | 0 | break; |
827 | | |
828 | 0 | case OPT_FULL: |
829 | 0 | ctrl.useecs = ctrl.usemecs = false; |
830 | 0 | ctrl.use_read = ctrl.fulltbl = true; |
831 | 0 | break; |
832 | | |
833 | 0 | case OPT_FAST: |
834 | 0 | ctrl.useecs = ctrl.usemecs = false; |
835 | 0 | ctrl.use_read = ctrl.fullspd = true; |
836 | 0 | break; |
837 | | |
838 | 0 | case OPT_HELP: |
839 | 0 | usage (); |
840 | 0 | FLEX_EXIT (0); |
841 | | |
842 | 0 | case OPT_INTERACTIVE: |
843 | 0 | ctrl.interactive = true; |
844 | 0 | break; |
845 | | |
846 | 0 | case OPT_CASE_INSENSITIVE: |
847 | 0 | sf_set_case_ins(true); |
848 | 0 | break; |
849 | | |
850 | 0 | case OPT_LEX_COMPAT: |
851 | 0 | ctrl.lex_compat = true; |
852 | 0 | break; |
853 | | |
854 | 0 | case OPT_POSIX_COMPAT: |
855 | 0 | ctrl.posix_compat = true; |
856 | 0 | break; |
857 | | |
858 | 0 | case OPT_PREPROC_LEVEL: |
859 | 0 | preproc_level = (int) strtol(arg,NULL,0); |
860 | 0 | break; |
861 | | |
862 | 0 | case OPT_MAIN: |
863 | 0 | ctrl.do_yywrap = false; |
864 | 0 | ctrl.do_main = trit_true; |
865 | 0 | break; |
866 | | |
867 | 0 | case OPT_NO_MAIN: |
868 | 0 | ctrl.do_main = trit_false; |
869 | 0 | break; |
870 | | |
871 | 0 | case OPT_NO_LINE: |
872 | 0 | ctrl.gen_line_dirs = false; |
873 | 0 | break; |
874 | | |
875 | 0 | case OPT_OUTFILE: |
876 | 0 | env.outfilename = arg; |
877 | 0 | env.did_outfilename = 1; |
878 | 0 | break; |
879 | | |
880 | 0 | case OPT_PREFIX: |
881 | 0 | ctrl.prefix = arg; |
882 | 0 | break; |
883 | | |
884 | 0 | case OPT_PERF_REPORT: |
885 | 0 | ++env.performance_hint; |
886 | 0 | break; |
887 | | |
888 | 0 | case OPT_BISON_BRIDGE: |
889 | 0 | ctrl.bison_bridge_lval = true; |
890 | 0 | break; |
891 | | |
892 | 0 | case OPT_BISON_BRIDGE_LOCATIONS: |
893 | 0 | ctrl.bison_bridge_lval = ctrl.bison_bridge_lloc = true; |
894 | 0 | break; |
895 | | |
896 | 0 | case OPT_REENTRANT: |
897 | 0 | ctrl.reentrant = true; |
898 | 0 | break; |
899 | | |
900 | 0 | case OPT_NO_REENTRANT: |
901 | 0 | ctrl.reentrant = false; |
902 | 0 | break; |
903 | | |
904 | 0 | case OPT_SKEL: |
905 | 0 | env.skelname = arg; |
906 | 0 | break; |
907 | | |
908 | 0 | case OPT_DEFAULT: |
909 | 0 | ctrl.spprdflt = false; |
910 | 0 | break; |
911 | | |
912 | 0 | case OPT_NO_DEFAULT: |
913 | 0 | ctrl.spprdflt = true; |
914 | 0 | break; |
915 | | |
916 | 0 | case OPT_STDOUT: |
917 | 0 | env.use_stdout = true; |
918 | 0 | break; |
919 | | |
920 | 0 | case OPT_NO_UNISTD_H: |
921 | 0 | ctrl.no_unistd = true; |
922 | 0 | break; |
923 | | |
924 | 0 | case OPT_TABLES_FILE: |
925 | 0 | tablesext = true; |
926 | 0 | tablesfilename = arg; |
927 | 0 | break; |
928 | | |
929 | 0 | case OPT_TABLES_VERIFY: |
930 | 0 | tablesverify = true; |
931 | 0 | break; |
932 | | |
933 | 0 | case OPT_TRACE: |
934 | 0 | env.trace = true; |
935 | 0 | break; |
936 | | |
937 | 0 | case OPT_VERBOSE: |
938 | 0 | env.printstats = true; |
939 | 0 | break; |
940 | | |
941 | 0 | case OPT_VERSION: |
942 | 0 | printf ("%s %s\n", (ctrl.C_plus_plus ? "flex++" : "flex"), flex_version); |
943 | 0 | FLEX_EXIT (0); |
944 | | |
945 | 0 | case OPT_WARN: |
946 | 0 | env.nowarn = false; |
947 | 0 | break; |
948 | | |
949 | 0 | case OPT_NO_WARN: |
950 | 0 | env.nowarn = true; |
951 | 0 | break; |
952 | | |
953 | 0 | case OPT_7BIT: |
954 | 0 | ctrl.csize = 128; |
955 | 0 | break; |
956 | | |
957 | 0 | case OPT_8BIT: |
958 | 0 | ctrl.csize = CSIZE; |
959 | 0 | break; |
960 | | |
961 | 0 | case OPT_ALIGN: |
962 | 0 | ctrl.long_align = true; |
963 | 0 | break; |
964 | | |
965 | 0 | case OPT_NO_ALIGN: |
966 | 0 | ctrl.long_align = false; |
967 | 0 | break; |
968 | | |
969 | 0 | case OPT_ALWAYS_INTERACTIVE: |
970 | 0 | ctrl.always_interactive = true; |
971 | 0 | break; |
972 | | |
973 | 0 | case OPT_NEVER_INTERACTIVE: |
974 | 0 | ctrl.never_interactive = true; |
975 | 0 | break; |
976 | | |
977 | 0 | case OPT_ARRAY: |
978 | 0 | ctrl.yytext_is_array = true; |
979 | 0 | break; |
980 | | |
981 | 0 | case OPT_POINTER: |
982 | 0 | ctrl.yytext_is_array = false; |
983 | 0 | break; |
984 | | |
985 | 0 | case OPT_ECS: |
986 | 0 | ctrl.useecs = true; |
987 | 0 | break; |
988 | | |
989 | 0 | case OPT_NO_ECS: |
990 | 0 | ctrl.useecs = false; |
991 | 0 | break; |
992 | | |
993 | 0 | case OPT_EMIT: |
994 | 0 | ctrl.emit = arg; |
995 | 0 | break; |
996 | | |
997 | 0 | case OPT_HEADER_FILE: |
998 | 0 | env.headerfilename = arg; |
999 | 0 | break; |
1000 | | |
1001 | 0 | case OPT_META_ECS: |
1002 | 0 | ctrl.usemecs = true; |
1003 | 0 | break; |
1004 | | |
1005 | 0 | case OPT_NO_META_ECS: |
1006 | 0 | ctrl.usemecs = false; |
1007 | 0 | break; |
1008 | | |
1009 | 0 | case OPT_PREPROCDEFINE: |
1010 | 0 | { |
1011 | | /* arg is "symbol" or "symbol=definition". */ |
1012 | 0 | char *def; |
1013 | 0 | char buf2[4096]; |
1014 | |
|
1015 | 0 | for (def = arg; |
1016 | 0 | *def != '\0' && *def != '='; ++def) |
1017 | 0 | continue; |
1018 | 0 | if (*def == '\0') |
1019 | 0 | def = "1"; |
1020 | |
|
1021 | 0 | snprintf(buf2, sizeof(buf2), "M4_HOOK_CONST_DEFINE_UNKNOWN(%s, %s)", arg, def); |
1022 | 0 | buf_strappend (&userdef_buf, buf2); |
1023 | 0 | } |
1024 | 0 | break; |
1025 | | |
1026 | 0 | case OPT_READ: |
1027 | 0 | ctrl.use_read = true; |
1028 | 0 | break; |
1029 | | |
1030 | 0 | case OPT_STACK: |
1031 | 0 | ctrl.stack_used = true; |
1032 | 0 | break; |
1033 | | |
1034 | 0 | case OPT_STDINIT: |
1035 | 0 | ctrl.do_stdinit = true; |
1036 | 0 | break; |
1037 | | |
1038 | 0 | case OPT_NO_STDINIT: |
1039 | 0 | ctrl.do_stdinit = false; |
1040 | 0 | break; |
1041 | | |
1042 | 0 | case OPT_YYCLASS: |
1043 | 0 | ctrl.yyclass = arg; |
1044 | 0 | break; |
1045 | | |
1046 | 0 | case OPT_YYLINENO: |
1047 | 0 | ctrl.do_yylineno = true; |
1048 | 0 | break; |
1049 | | |
1050 | 0 | case OPT_NO_YYLINENO: |
1051 | 0 | ctrl.do_yylineno = false; |
1052 | 0 | break; |
1053 | | |
1054 | 0 | case OPT_YYWRAP: |
1055 | 0 | ctrl.do_yywrap = true; |
1056 | 0 | break; |
1057 | | |
1058 | 0 | case OPT_NO_YYWRAP: |
1059 | 0 | ctrl.do_yywrap = false; |
1060 | 0 | break; |
1061 | | |
1062 | 0 | case OPT_YYMORE: |
1063 | 0 | ctrl.yymore_really_used = true; |
1064 | 0 | break; |
1065 | | |
1066 | 0 | case OPT_NO_YYMORE: |
1067 | 0 | ctrl.yymore_really_used = false; |
1068 | 0 | break; |
1069 | | |
1070 | 0 | case OPT_REJECT: |
1071 | 0 | ctrl.reject_really_used = true; |
1072 | 0 | break; |
1073 | | |
1074 | 0 | case OPT_NO_REJECT: |
1075 | 0 | ctrl.reject_really_used = false; |
1076 | 0 | break; |
1077 | | |
1078 | 0 | case OPT_NO_YY_PUSH_STATE: |
1079 | 0 | ctrl.no_yy_push_state = true; |
1080 | 0 | break; |
1081 | 0 | case OPT_NO_YY_POP_STATE: |
1082 | 0 | ctrl.no_yy_pop_state = true; |
1083 | 0 | break; |
1084 | 0 | case OPT_NO_YY_TOP_STATE: |
1085 | 0 | ctrl.no_yy_top_state = true; |
1086 | 0 | break; |
1087 | 0 | case OPT_NO_YYINPUT: |
1088 | 0 | ctrl.no_yyinput = true; |
1089 | 0 | break; |
1090 | 0 | case OPT_NO_YYUNPUT: |
1091 | 0 | ctrl.no_yyunput = true; |
1092 | 0 | break; |
1093 | 0 | case OPT_NO_YY_SCAN_BUFFER: |
1094 | 0 | ctrl.no_yy_scan_buffer = true; |
1095 | 0 | break; |
1096 | 0 | case OPT_NO_YY_SCAN_BYTES: |
1097 | 0 | ctrl.no_yy_scan_bytes = true; |
1098 | 0 | break; |
1099 | 0 | case OPT_NO_YY_SCAN_STRING: |
1100 | 0 | ctrl.no_yy_scan_string = true; |
1101 | 0 | break; |
1102 | 0 | case OPT_NO_YYGET_EXTRA: |
1103 | 0 | ctrl.no_yyget_extra = true; |
1104 | 0 | break; |
1105 | 0 | case OPT_NO_YYSET_EXTRA: |
1106 | 0 | ctrl.no_yyset_extra = true; |
1107 | 0 | break; |
1108 | 0 | case OPT_NO_YYGET_LENG: |
1109 | 0 | ctrl.no_yyget_leng = true; |
1110 | 0 | break; |
1111 | 0 | case OPT_NO_YYGET_TEXT: |
1112 | 0 | ctrl.no_yyget_text = true; |
1113 | 0 | break; |
1114 | 0 | case OPT_NO_YYGET_LINENO: |
1115 | 0 | ctrl.no_yyget_lineno = true; |
1116 | 0 | break; |
1117 | 0 | case OPT_NO_YYSET_LINENO: |
1118 | 0 | ctrl.no_yyset_lineno = true; |
1119 | 0 | break; |
1120 | 0 | case OPT_NO_YYGET_COLUMN: |
1121 | 0 | ctrl.no_yyget_column = true; |
1122 | 0 | break; |
1123 | 0 | case OPT_NO_YYSET_COLUMN: |
1124 | 0 | ctrl.no_yyset_column = true; |
1125 | 0 | break; |
1126 | 0 | case OPT_NO_YYGET_IN: |
1127 | 0 | ctrl.no_yyget_in = true; |
1128 | 0 | break; |
1129 | 0 | case OPT_NO_YYSET_IN: |
1130 | 0 | ctrl.no_yyset_in = true; |
1131 | 0 | break; |
1132 | 0 | case OPT_NO_YYGET_OUT: |
1133 | 0 | ctrl.no_yyget_out = true; |
1134 | 0 | break; |
1135 | 0 | case OPT_NO_YYSET_OUT: |
1136 | 0 | ctrl.no_yyset_out = true; |
1137 | 0 | break; |
1138 | 0 | case OPT_NO_YYGET_LVAL: |
1139 | 0 | ctrl.no_yyget_lval = true; |
1140 | 0 | break; |
1141 | 0 | case OPT_NO_YYSET_LVAL: |
1142 | 0 | ctrl.no_yyset_lval = true; |
1143 | 0 | break; |
1144 | 0 | case OPT_NO_YYGET_LLOC: |
1145 | 0 | ctrl.no_yyget_lloc = true; |
1146 | 0 | break; |
1147 | 0 | case OPT_NO_YYSET_LLOC: |
1148 | 0 | ctrl.no_yyset_lloc = true; |
1149 | 0 | break; |
1150 | 0 | case OPT_NO_YYGET_DEBUG: |
1151 | 0 | ctrl.no_get_debug = true; |
1152 | 0 | break; |
1153 | 0 | case OPT_NO_YYSET_DEBUG: |
1154 | 0 | ctrl.no_set_debug = true; |
1155 | 0 | break; |
1156 | | |
1157 | 0 | case OPT_HEX: |
1158 | 0 | env.trace_hex = true; |
1159 | 0 | break; |
1160 | 0 | case OPT_NO_SECT3_ESCAPE: |
1161 | 0 | ctrl.no_section3_escape = true; |
1162 | 0 | break; |
1163 | 0 | } /* switch */ |
1164 | 0 | } /* while scanopt() */ |
1165 | | |
1166 | 778 | scanopt_destroy (sopt); |
1167 | | |
1168 | 778 | num_input_files = argc - optind; |
1169 | 778 | input_files = argv + optind; |
1170 | 778 | set_input_file (num_input_files > 0 ? input_files[0] : NULL); |
1171 | | |
1172 | 778 | lastccl = lastsc = lastdfa = lastnfa = 0; |
1173 | 778 | num_rules = num_eof_rules = default_rule = 0; |
1174 | 778 | numas = numsnpairs = tmpuses = 0; |
1175 | 778 | numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = |
1176 | 778 | 0; |
1177 | 778 | numuniq = numdup = hshsave = datapos = dataline = 0; |
1178 | 778 | eofseen = false; |
1179 | 778 | num_backing_up = onesp = numprots = 0; |
1180 | 778 | variable_trailing_context_rules = bol_needed = false; |
1181 | | |
1182 | 778 | linenum = sectnum = 1; |
1183 | 778 | firstprot = NIL; |
1184 | | |
1185 | | /* Used in mkprot() so that the first proto goes in slot 1 |
1186 | | * of the proto queue. |
1187 | | */ |
1188 | 778 | lastprot = 1; |
1189 | | |
1190 | 778 | set_up_initial_allocations (); |
1191 | 778 | } |
1192 | | |
1193 | | |
1194 | | /* readin - read in the rules section of the input file(s) */ |
1195 | | |
1196 | | void readin (void) |
1197 | 778 | { |
1198 | 778 | char buf[256]; |
1199 | | |
1200 | 778 | line_directive_out(NULL, infilename, linenum); |
1201 | | |
1202 | 778 | if (yyparse ()) { |
1203 | 547 | pinpoint_message (_("fatal parse error")); |
1204 | 547 | flexend (1); |
1205 | 547 | } |
1206 | | |
1207 | 778 | if (syntaxerror) |
1208 | 231 | flexend (1); |
1209 | | |
1210 | | /* On --emit, -e, or change backends This is where backend |
1211 | | * properties are collected, which means they can't be set |
1212 | | * from a custom skelfile. Note: might have been called sooner |
1213 | | * when %option emit was evaluated; this catches command-line |
1214 | | * optiins and the default case. |
1215 | | */ |
1216 | 778 | backend_by_name(ctrl.emit); |
1217 | | |
1218 | 778 | initialize_output_filters(); |
1219 | | |
1220 | 778 | yyout = stdout; |
1221 | | |
1222 | 778 | if (tablesext) |
1223 | 0 | gentables = false; |
1224 | | |
1225 | 778 | if (tablesverify) |
1226 | | /* force generation of C tables. */ |
1227 | 0 | gentables = true; |
1228 | | |
1229 | | |
1230 | 778 | if (tablesext) { |
1231 | 0 | FILE *tablesout; |
1232 | 0 | struct yytbl_hdr hdr; |
1233 | 0 | char *pname = 0; |
1234 | 0 | size_t nbytes = 0; |
1235 | |
|
1236 | 0 | if (!tablesfilename) { |
1237 | 0 | nbytes = strlen (ctrl.prefix) + strlen (tablesfile_template) + 2; |
1238 | 0 | tablesfilename = pname = calloc(nbytes, 1); |
1239 | 0 | snprintf (pname, nbytes, tablesfile_template, ctrl.prefix); |
1240 | 0 | } |
1241 | |
|
1242 | 0 | if ((tablesout = fopen (tablesfilename, "w")) == NULL) |
1243 | 0 | lerr (_("could not create %s"), tablesfilename); |
1244 | 0 | free(pname); |
1245 | 0 | tablesfilename = 0; |
1246 | |
|
1247 | 0 | yytbl_writer_init (&tableswr, tablesout); |
1248 | |
|
1249 | 0 | nbytes = strlen (ctrl.prefix) + strlen ("tables") + 2; |
1250 | 0 | tablesname = calloc(nbytes, 1); |
1251 | 0 | snprintf (tablesname, nbytes, "%stables", ctrl.prefix); |
1252 | 0 | yytbl_hdr_init (&hdr, flex_version, tablesname); |
1253 | |
|
1254 | 0 | if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) |
1255 | 0 | flexerror (_("could not write tables header")); |
1256 | 0 | } |
1257 | | |
1258 | 778 | if (env.skelname && (skelfile = fopen (env.skelname, "r")) == NULL) |
1259 | 0 | lerr (_("can't open skeleton file %s"), env.skelname); |
1260 | | |
1261 | 778 | if (strchr(ctrl.prefix, '[') || strchr(ctrl.prefix, ']')) |
1262 | 0 | flexerror(_("Prefix cannot include '[' or ']'")); |
1263 | | |
1264 | 778 | if (env.did_outfilename) |
1265 | 0 | line_directive_out (stdout, NULL, linenum); |
1266 | | |
1267 | | /* This is where we begin writing to the file. */ |
1268 | | |
1269 | 778 | skelout(false); /* [0.0] Make hook macros available, silently */ |
1270 | | |
1271 | 778 | comment("A lexical scanner generated by flex\n"); |
1272 | | |
1273 | | /* Dump the %top code. */ |
1274 | 778 | if( top_buf.elts) |
1275 | 0 | outn((char*) top_buf.elts); |
1276 | | |
1277 | | /* Place a bogus line directive, it will be fixed in the filter. */ |
1278 | 778 | line_directive_out(NULL, NULL, 0); |
1279 | | |
1280 | | /* User may want to set the scanner prototype */ |
1281 | 778 | if (ctrl.yydecl != NULL) { |
1282 | 0 | out_str ("M4_HOOK_SET_YY_DECL(%s)\n", ctrl.yydecl); |
1283 | 0 | } |
1284 | | |
1285 | 778 | if (ctrl.userinit != NULL) { |
1286 | 0 | out_str ("M4_HOOK_SET_USERINIT(%s)\n", ctrl.userinit); |
1287 | 0 | } |
1288 | 778 | if (ctrl.preaction != NULL) { |
1289 | 0 | out_str ("M4_HOOK_SET_PREACTION(%s)\n", ctrl.preaction); |
1290 | 0 | } |
1291 | 778 | if (ctrl.postaction != NULL) { |
1292 | 0 | out_str ("M4_HOOK_SET_POSTACTION(%s)\n", ctrl.postaction); |
1293 | 0 | } |
1294 | | |
1295 | | /* This has to be a straight textual substitution rather |
1296 | | * than a constant declaration because in C a const is |
1297 | | * not const enough to be a static array bound. |
1298 | | */ |
1299 | 778 | out_dec ("m4_define([[YYLMAX]], [[%d]])\n", ctrl.yylmax); |
1300 | | |
1301 | | /* Dump the user defined preproc directives. */ |
1302 | 778 | if (userdef_buf.elts) |
1303 | 0 | outn ((char *) (userdef_buf.elts)); |
1304 | | |
1305 | | /* If the user explicitly requested posix compatibility by specifying the |
1306 | | * posix-compat option, then we check for conflicting options. However, if |
1307 | | * the POSIXLY_CORRECT variable is set, then we quietly make flex as |
1308 | | * posix-compatible as possible. This is the recommended behavior |
1309 | | * according to the GNU Coding Standards. |
1310 | | * |
1311 | | * Note: The posix option was added to flex to provide the posix behavior |
1312 | | * of the repeat operator in regular expressions, e.g., `ab{3}' |
1313 | | */ |
1314 | 778 | if (ctrl.posix_compat) { |
1315 | | /* TODO: This is where we try to make flex behave according to |
1316 | | * POSIX, *and* check for conflicting ctrl. How far should we go |
1317 | | * with this? Should we disable all the neat-o flex features? |
1318 | | */ |
1319 | | /* Update: Estes says no, since other flex features don't violate posix. */ |
1320 | 0 | } |
1321 | | |
1322 | 778 | if (getenv ("POSIXLY_CORRECT")) { |
1323 | 0 | ctrl.posix_compat = true; |
1324 | 0 | } |
1325 | | |
1326 | 778 | if (env.backing_up_report) { |
1327 | 0 | ctrl.backing_up_file = fopen (backing_name, "w"); |
1328 | 0 | if (ctrl.backing_up_file == NULL) |
1329 | 0 | lerr (_ |
1330 | 0 | ("could not create backing-up info file %s"), |
1331 | 0 | backing_name); |
1332 | 0 | } |
1333 | | |
1334 | 778 | else |
1335 | 778 | ctrl.backing_up_file = NULL; |
1336 | | |
1337 | 778 | if (ctrl.yymore_really_used == true) |
1338 | 0 | yymore_used = true; |
1339 | 778 | else if (ctrl.yymore_really_used == false) |
1340 | 0 | yymore_used = false; |
1341 | | |
1342 | 778 | if (ctrl.reject_really_used == true) |
1343 | 0 | reject = true; |
1344 | 778 | else if (ctrl.reject_really_used == false) |
1345 | 0 | reject = false; |
1346 | | |
1347 | 778 | if (env.performance_hint > 0) { |
1348 | 0 | if (ctrl.lex_compat) { |
1349 | 0 | fprintf (stderr, |
1350 | 0 | _ |
1351 | 0 | ("-l AT&T lex compatibility option entails a large performance penalty\n")); |
1352 | 0 | fprintf (stderr, |
1353 | 0 | _ |
1354 | 0 | (" and may be the actual source of other reported performance penalties\n")); |
1355 | 0 | } |
1356 | | |
1357 | 0 | else if (ctrl.do_yylineno) { |
1358 | 0 | fprintf (stderr, |
1359 | 0 | _ |
1360 | 0 | ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); |
1361 | 0 | } |
1362 | |
|
1363 | 0 | if (env.performance_hint > 1) { |
1364 | 0 | if (ctrl.interactive == trit_true) |
1365 | 0 | fprintf (stderr, |
1366 | 0 | _ |
1367 | 0 | ("-I (interactive) entails a minor performance penalty\n")); |
1368 | |
|
1369 | 0 | if (yymore_used) |
1370 | 0 | fprintf (stderr, |
1371 | 0 | _ |
1372 | 0 | ("yymore() entails a minor performance penalty\n")); |
1373 | 0 | } |
1374 | |
|
1375 | 0 | if (reject) |
1376 | 0 | fprintf (stderr, |
1377 | 0 | _ |
1378 | 0 | ("REJECT entails a large performance penalty\n")); |
1379 | |
|
1380 | 0 | if (variable_trailing_context_rules) |
1381 | 0 | fprintf (stderr, |
1382 | 0 | _ |
1383 | 0 | ("Variable trailing context rules entail a large performance penalty\n")); |
1384 | 0 | } |
1385 | | |
1386 | 778 | if (reject) |
1387 | 0 | real_reject = true; |
1388 | | |
1389 | 778 | if (variable_trailing_context_rules) |
1390 | 0 | reject = true; |
1391 | | |
1392 | 778 | if ((ctrl.fulltbl || ctrl.fullspd) && reject) { |
1393 | 0 | if (real_reject) |
1394 | 0 | flexerror (_ |
1395 | 0 | ("REJECT cannot be used with -f or -F")); |
1396 | 0 | else if (ctrl.do_yylineno) |
1397 | 0 | flexerror (_ |
1398 | 0 | ("%option yylineno cannot be used with REJECT")); |
1399 | 0 | else |
1400 | 0 | flexerror (_ |
1401 | 0 | ("variable trailing context rules cannot be used with -f or -F")); |
1402 | 0 | } |
1403 | | |
1404 | 778 | if (ctrl.useecs) |
1405 | 0 | numecs = cre8ecs (nextecm, ecgroup, ctrl.csize); |
1406 | 778 | else |
1407 | 778 | numecs = ctrl.csize; |
1408 | | |
1409 | | /* Now map the equivalence class for NUL to its expected place. */ |
1410 | 778 | ecgroup[0] = ecgroup[ctrl.csize]; |
1411 | 778 | NUL_ec = ABS (ecgroup[0]); |
1412 | | |
1413 | 778 | if (ctrl.useecs) |
1414 | 0 | ccl2ecl (); |
1415 | | |
1416 | | // These are used to conditionalize code in the lex skeleton |
1417 | | // that historically used to be generated by C code in flex |
1418 | | // itself; by shoving all this stuff out to the skeleton file |
1419 | | // we make it easier to retarget the code generation. |
1420 | 778 | snprintf(buf, sizeof(buf), "Target: %s\n", ctrl.backend_name); |
1421 | 778 | comment(buf); |
1422 | 778 | comment("START of m4 controls\n"); |
1423 | | |
1424 | | /* Define the start condition macros. */ |
1425 | 778 | { |
1426 | 778 | struct Buf tmpbuf; |
1427 | 778 | int i; |
1428 | 778 | buf_init(&tmpbuf, sizeof(char)); |
1429 | 778 | for (i = 1; i <= lastsc; i++) { |
1430 | 0 | char *str, *fmt = "M4_HOOK_CONST_DEFINE_STATE(%s, %d)"; |
1431 | 0 | size_t strsz; |
1432 | |
|
1433 | 0 | strsz = strlen(fmt) + strlen(scname[i]) + (size_t)(1 + ceil (log10(i))) + 2; |
1434 | 0 | str = malloc(strsz); |
1435 | 0 | if (!str) |
1436 | 0 | flexfatal(_("allocation of macro definition failed")); |
1437 | 0 | snprintf(str, strsz, fmt, scname[i], i - 1); |
1438 | 0 | buf_strappend(&tmpbuf, str); |
1439 | 0 | free(str); |
1440 | 0 | } |
1441 | | // FIXME: Not dumped visibly because we plan to do away with the indirection |
1442 | 778 | out_m4_define("M4_YY_SC_DEFS", tmpbuf.elts); |
1443 | 778 | buf_destroy(&tmpbuf); |
1444 | 778 | } |
1445 | | |
1446 | 778 | if (ctrl.bison_bridge_lval) |
1447 | 0 | visible_define("M4_YY_BISON_LVAL"); |
1448 | | |
1449 | 778 | if (ctrl.bison_bridge_lloc) |
1450 | 0 | visible_define("<M4_YY_BISON_LLOC>"); |
1451 | | |
1452 | 778 | if (extra_type != NULL) |
1453 | 0 | visible_define_str ("M4_MODE_EXTRA_TYPE", extra_type); |
1454 | | |
1455 | | /* always generate the tablesverify flag. */ |
1456 | 778 | visible_define_str ("M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); |
1457 | | |
1458 | 778 | if (ctrl.reentrant) { |
1459 | 0 | visible_define ("M4_YY_REENTRANT"); |
1460 | 0 | if (ctrl.yytext_is_array) |
1461 | 0 | visible_define ("M4_MODE_REENTRANT_TEXT_IS_ARRAY"); |
1462 | 0 | } |
1463 | | |
1464 | 778 | if (ctrl.do_main == trit_true) |
1465 | 0 | visible_define_str ( "YY_MAIN", "1"); |
1466 | 778 | else if (ctrl.do_main == trit_false) |
1467 | 0 | visible_define_str ( "YY_MAIN", "0"); |
1468 | | |
1469 | 778 | if (ctrl.do_stdinit) |
1470 | 0 | visible_define ( "M4_MODE_DO_STDINIT"); |
1471 | 778 | else |
1472 | 778 | visible_define ( "M4_MODE_NO_DO_STDINIT"); |
1473 | | |
1474 | | // mode switches for YY_DO_BEFORE_ACTION code generation |
1475 | 778 | if (ctrl.yytext_is_array) |
1476 | 0 | visible_define ( "M4_MODE_YYTEXT_IS_ARRAY"); |
1477 | 778 | else |
1478 | 778 | visible_define ( "M4_MODE_NO_YYTEXT_IS_ARRAY"); |
1479 | 778 | if (yymore_used) |
1480 | 0 | visible_define ( "M4_MODE_YYMORE_USED"); |
1481 | 778 | else |
1482 | 778 | visible_define ( "M4_MODE_NO_YYMORE_USED"); |
1483 | | |
1484 | 778 | if (ctrl.fullspd) |
1485 | 0 | visible_define ( "M4_MODE_REAL_FULLSPD"); |
1486 | 778 | else |
1487 | 778 | visible_define ( "M4_MODE_NO_REAL_FULLSPD"); |
1488 | | |
1489 | 778 | if (ctrl.fulltbl) |
1490 | 0 | visible_define ( "M4_MODE_REAL_FULLTBL"); |
1491 | 778 | else |
1492 | 778 | visible_define ( "M4_MODE_NO_REAL_FULLTBL"); |
1493 | | |
1494 | | // niode switches for YYINPUT code generation |
1495 | 778 | if (ctrl.use_read) |
1496 | 0 | visible_define ( "M4_MODE_CPP_USE_READ"); |
1497 | 778 | else |
1498 | 778 | visible_define ( "M4_MODE_NO_CPP_USE_READ"); |
1499 | | |
1500 | | // mode switches for next-action code |
1501 | 778 | if (variable_trailing_context_rules) { |
1502 | 0 | visible_define ( "M4_MODE_VARIABLE_TRAILING_CONTEXT_RULES"); |
1503 | 778 | } else { |
1504 | 778 | visible_define ( "M4_MODE_NO_VARIABLE_TRAILING_CONTEXT_RULES"); |
1505 | 778 | } |
1506 | 778 | if (real_reject) |
1507 | 0 | visible_define ( "M4_MODE_REAL_REJECT"); |
1508 | 778 | if (ctrl.reject_really_used) |
1509 | 0 | visible_define ( "M4_MODE_FIND_ACTION_REJECT_REALLY_USED"); |
1510 | 778 | if (reject) |
1511 | 0 | visible_define ( "M4_MODE_USES_REJECT"); |
1512 | 778 | else |
1513 | 778 | visible_define ( "M4_MODE_NO_USES_REJECT"); |
1514 | | |
1515 | | // mode switches for computing next compressed state |
1516 | 778 | if (ctrl.usemecs) |
1517 | 0 | visible_define ( "M4_MODE_USEMECS"); |
1518 | | |
1519 | | // mode switches for find-action code |
1520 | 778 | if (ctrl.fullspd) |
1521 | 0 | visible_define ( "M4_MODE_FULLSPD"); |
1522 | 778 | else if (ctrl.fulltbl) |
1523 | 0 | visible_define ( "M4_MODE_FIND_ACTION_FULLTBL"); |
1524 | 778 | else if (reject) |
1525 | 0 | visible_define ( "M4_MODE_FIND_ACTION_REJECT"); |
1526 | 778 | else |
1527 | 778 | visible_define ( "M4_MODE_FIND_ACTION_COMPRESSED"); |
1528 | | |
1529 | | // mode switches for backup generation and gen_start_state |
1530 | 778 | if (!ctrl.fullspd) |
1531 | 0 | visible_define ( "M4_MODE_NO_FULLSPD"); |
1532 | 778 | if (bol_needed) |
1533 | 0 | visible_define ( "M4_MODE_BOL_NEEDED"); |
1534 | 778 | else |
1535 | 778 | visible_define ( "M4_MODE_NO_BOL_NEEDED"); |
1536 | | |
1537 | | // yylineno |
1538 | 778 | if (ctrl.do_yylineno) |
1539 | 0 | visible_define ( "M4_MODE_YYLINENO"); |
1540 | | |
1541 | | // Equivalence classes |
1542 | 778 | if (ctrl.useecs) |
1543 | 0 | visible_define ( "M4_MODE_USEECS"); |
1544 | 778 | else |
1545 | 778 | visible_define ( "M4_MODE_NO_USEECS"); |
1546 | | |
1547 | | // mode switches for getting next action |
1548 | 778 | if (gentables) |
1549 | 0 | visible_define ( "M4_MODE_GENTABLES"); |
1550 | 778 | else |
1551 | 778 | visible_define ( "M4_MODE_NO_GENTABLES"); |
1552 | 778 | if (ctrl.interactive == trit_true) |
1553 | 0 | visible_define ( "M4_MODE_INTERACTIVE"); |
1554 | 778 | else |
1555 | 778 | visible_define ( "M4_MODE_NO_INTERACTIVE"); |
1556 | 778 | if (!(ctrl.fullspd || ctrl.fulltbl)) |
1557 | 0 | visible_define ( "M4_MODE_NO_FULLSPD_OR_FULLTBL"); |
1558 | 778 | if (reject || ctrl.interactive == trit_true) |
1559 | 0 | visible_define ( "M4_MODE_FIND_ACTION_REJECT_OR_INTERACTIVE"); |
1560 | | |
1561 | 778 | if (ctrl.yyclass != NULL) { |
1562 | 0 | visible_define ( "M4_MODE_YYCLASS"); |
1563 | 0 | out_m4_define("M4_YY_CLASS_NAME", ctrl.yyclass); |
1564 | 0 | } |
1565 | | |
1566 | 778 | if (ctrl.ddebug) |
1567 | 0 | visible_define ( "M4_MODE_DEBUG"); |
1568 | | |
1569 | 778 | if (ctrl.lex_compat) |
1570 | 0 | visible_define ( "M4_MODE_OPTIONS.LEX_COMPAT"); |
1571 | | |
1572 | 778 | if (ctrl.do_yywrap) |
1573 | 0 | visible_define ( "M4_MODE_YYWRAP"); |
1574 | 778 | else |
1575 | 778 | visible_define ( "M4_MODE_NO_YYWRAP"); |
1576 | | |
1577 | 778 | if (ctrl.interactive == trit_true) |
1578 | 0 | visible_define ( "M4_MODE_INTERACTIVE"); |
1579 | | |
1580 | 778 | if (ctrl.noyyread) |
1581 | 0 | visible_define("M4_MODE_USER_YYREAD"); |
1582 | | |
1583 | 778 | if (is_default_backend()) { |
1584 | 0 | if (ctrl.C_plus_plus) { |
1585 | 0 | visible_define ( "M4_MODE_CXX_ONLY"); |
1586 | 0 | } else { |
1587 | 0 | visible_define ( "M4_MODE_C_ONLY"); |
1588 | 0 | } |
1589 | 0 | } |
1590 | | |
1591 | 778 | if (tablesext) |
1592 | 0 | visible_define ( "M4_MODE_TABLESEXT"); |
1593 | 778 | if (ctrl.prefix != NULL) |
1594 | 0 | visible_define_str ( "M4_MODE_PREFIX", ctrl.prefix); |
1595 | | |
1596 | 778 | if (ctrl.no_yyinput) |
1597 | 0 | visible_define("M4_MODE_NO_YYINPUT"); |
1598 | | |
1599 | 778 | if (ctrl.bufsize != 0) |
1600 | 0 | visible_define_int("M4_MODE_YY_BUFSIZE", ctrl.bufsize); |
1601 | | |
1602 | 778 | if (ctrl.yyterminate != NULL) |
1603 | 0 | visible_define_str("M4_MODE_YYTERMINATE", ctrl.yyterminate); |
1604 | | |
1605 | 778 | if (ctrl.no_yypanic) |
1606 | 0 | visible_define("M4_YY_NO_YYPANIC"); |
1607 | 778 | if (ctrl.no_yy_push_state) |
1608 | 0 | visible_define("M4_YY_NO_PUSH_STATE"); |
1609 | 778 | if (ctrl.no_yy_pop_state) |
1610 | 0 | visible_define("M4_YY_NO_POP_STATE"); |
1611 | 778 | if (ctrl.no_yy_top_state) |
1612 | 0 | visible_define("M4_YY_NO_TOP_STATE"); |
1613 | 778 | if (ctrl.no_yyunput) |
1614 | 0 | visible_define("M4_YY_NO_YYUNPUT"); |
1615 | 778 | if (ctrl.no_yy_scan_buffer) |
1616 | 0 | visible_define("M4_YY_NO_SCAN_BUFFER"); |
1617 | 778 | if (ctrl.no_yy_scan_bytes) |
1618 | 0 | visible_define("M4_YY_NO_SCAN_BYTES"); |
1619 | 778 | if (ctrl.no_yy_scan_string) |
1620 | 0 | visible_define("M4_YY_NO_SCAN_STRING"); |
1621 | 778 | if (ctrl.no_yyget_extra) |
1622 | 0 | visible_define("M4_YY_NO_GET_EXTRA"); |
1623 | 778 | if (ctrl.no_yyset_extra) |
1624 | 0 | visible_define("M4_YY_NO_SET_EXTRA"); |
1625 | 778 | if (ctrl.no_yyget_leng) |
1626 | 0 | visible_define("M4_YY_NO_GET_LENG"); |
1627 | 778 | if (ctrl.no_yyget_text) |
1628 | 0 | visible_define("M4_YY_NO_GET_TEXT"); |
1629 | 778 | if (ctrl.no_yyget_lineno) |
1630 | 0 | visible_define("M4_YY_NO_GET_LINENO"); |
1631 | 778 | if (ctrl.no_yyset_lineno) |
1632 | 0 | visible_define("M4_YY_NO_SET_LINENO"); |
1633 | 778 | if (ctrl.no_yyget_column) |
1634 | 0 | visible_define("M4_YY_NO_GET_COLUMN"); |
1635 | 778 | if (ctrl.no_yyset_column) |
1636 | 0 | visible_define("M4_YY_NO_SET_COLUMN"); |
1637 | 778 | if (ctrl.no_yyget_in) |
1638 | 0 | visible_define("M4_YY_NO_GET_IN"); |
1639 | 778 | if (ctrl.no_yyset_in) |
1640 | 0 | visible_define("M4_YY_NO_SET_IN"); |
1641 | 778 | if (ctrl.no_yyget_out) |
1642 | 0 | visible_define("M4_YY_NO_GET_OUT"); |
1643 | 778 | if (ctrl.no_yyset_out) |
1644 | 0 | visible_define("M4_YY_NO_SET_OUT"); |
1645 | 778 | if (ctrl.no_yyget_lval) |
1646 | 0 | visible_define("M4_YY_NO_GET_LVAL"); |
1647 | 778 | if (ctrl.no_yyset_lval) |
1648 | 0 | visible_define("M4_YY_NO_SET_LVAL"); |
1649 | 778 | if (ctrl.no_yyget_lloc) |
1650 | 0 | visible_define("M4_YY_NO_GET_LLOC"); |
1651 | 778 | if (ctrl.no_yyset_lloc) |
1652 | 0 | visible_define("M4_YY_NO_SET_LLOC"); |
1653 | 778 | if (ctrl.no_flex_alloc) |
1654 | 0 | visible_define("M4_YY_NO_FLEX_ALLOC"); |
1655 | 778 | if (ctrl.no_flex_realloc) |
1656 | 0 | visible_define("M4_YY_NO_FLEX_REALLOC"); |
1657 | 778 | if (ctrl.no_flex_free) |
1658 | 0 | visible_define("M4_YY_NO_FLEX_FREE"); |
1659 | 778 | if (ctrl.no_get_debug) |
1660 | 0 | visible_define("M4_YY_NO_GET_DEBUG"); |
1661 | 778 | if (ctrl.no_set_debug) |
1662 | 0 | visible_define("M4_YY_NO_SET_DEBUG"); |
1663 | | |
1664 | 778 | if (ctrl.no_unistd) |
1665 | 0 | visible_define("M4_YY_NO_UNISTD_H"); |
1666 | | |
1667 | 778 | if (ctrl.always_interactive) |
1668 | 0 | visible_define("M4_YY_ALWAYS_INTERACTIVE"); |
1669 | 778 | if (ctrl.never_interactive) |
1670 | 0 | visible_define("M4_YY_NEVER_INTERACTIVE"); |
1671 | 778 | if (ctrl.stack_used) |
1672 | 0 | visible_define("M4_YY_STACK_USED"); |
1673 | | |
1674 | 778 | if (ctrl.rewrite) |
1675 | 0 | visible_define ( "M4_MODE_REWRITE"); |
1676 | 778 | else |
1677 | 778 | visible_define ( "M4_MODE_NO_REWRITE"); |
1678 | | |
1679 | 778 | comment("END of m4 controls\n"); |
1680 | 778 | out ("\n"); |
1681 | 778 | } |
1682 | | |
1683 | | /* set_up_initial_allocations - allocate memory for internal tables */ |
1684 | | |
1685 | | void set_up_initial_allocations (void) |
1686 | 778 | { |
1687 | 778 | maximum_mns = (ctrl.long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); |
1688 | 778 | current_mns = INITIAL_MNS; |
1689 | 778 | firstst = allocate_integer_array (current_mns); |
1690 | 778 | lastst = allocate_integer_array (current_mns); |
1691 | 778 | finalst = allocate_integer_array (current_mns); |
1692 | 778 | transchar = allocate_integer_array (current_mns); |
1693 | 778 | trans1 = allocate_integer_array (current_mns); |
1694 | 778 | trans2 = allocate_integer_array (current_mns); |
1695 | 778 | accptnum = allocate_integer_array (current_mns); |
1696 | 778 | assoc_rule = allocate_integer_array (current_mns); |
1697 | 778 | state_type = allocate_integer_array (current_mns); |
1698 | | |
1699 | 778 | current_max_rules = INITIAL_MAX_RULES; |
1700 | 778 | rule_type = allocate_integer_array (current_max_rules); |
1701 | 778 | rule_linenum = allocate_integer_array (current_max_rules); |
1702 | 778 | rule_useful = allocate_array(current_max_rules, sizeof(char)); |
1703 | 778 | rule_has_nl = allocate_array(current_max_rules, sizeof(char)); |
1704 | | |
1705 | 778 | current_max_scs = INITIAL_MAX_SCS; |
1706 | 778 | scset = allocate_integer_array (current_max_scs); |
1707 | 778 | scbol = allocate_integer_array (current_max_scs); |
1708 | 778 | scxclu = allocate_array(current_max_scs, sizeof(char)); |
1709 | 778 | sceof = allocate_array(current_max_scs, sizeof(char)); |
1710 | 778 | scname = allocate_char_ptr_array (current_max_scs); |
1711 | | |
1712 | 778 | current_maxccls = INITIAL_MAX_CCLS; |
1713 | 778 | cclmap = allocate_integer_array (current_maxccls); |
1714 | 778 | ccllen = allocate_integer_array (current_maxccls); |
1715 | 778 | cclng = allocate_integer_array (current_maxccls); |
1716 | 778 | ccl_has_nl = allocate_array(current_maxccls, sizeof(char)); |
1717 | | |
1718 | 778 | current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; |
1719 | 778 | ccltbl = allocate_Character_array (current_max_ccl_tbl_size); |
1720 | | |
1721 | 778 | current_max_dfa_size = INITIAL_MAX_DFA_SIZE; |
1722 | | |
1723 | 778 | current_max_xpairs = INITIAL_MAX_XPAIRS; |
1724 | 778 | nxt = allocate_integer_array (current_max_xpairs); |
1725 | 778 | chk = allocate_integer_array (current_max_xpairs); |
1726 | | |
1727 | 778 | current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; |
1728 | 778 | tnxt = allocate_integer_array (current_max_template_xpairs); |
1729 | | |
1730 | 778 | current_max_dfas = INITIAL_MAX_DFAS; |
1731 | 778 | base = allocate_integer_array (current_max_dfas); |
1732 | 778 | def = allocate_integer_array (current_max_dfas); |
1733 | 778 | dfasiz = allocate_integer_array (current_max_dfas); |
1734 | 778 | accsiz = allocate_integer_array (current_max_dfas); |
1735 | 778 | dhash = allocate_integer_array (current_max_dfas); |
1736 | 778 | dss = allocate_int_ptr_array (current_max_dfas); |
1737 | 778 | dfaacc = allocate_array(current_max_dfas, |
1738 | 778 | sizeof(union dfaacc_union)); |
1739 | | |
1740 | 778 | nultrans = NULL; |
1741 | 778 | } |
1742 | | |
1743 | | |
1744 | | void usage (void) |
1745 | 0 | { |
1746 | 0 | FILE *f = stdout; |
1747 | |
|
1748 | 0 | if (!env.did_outfilename) { |
1749 | 0 | snprintf (outfile_path, sizeof(outfile_path), outfile_template, |
1750 | 0 | ctrl.prefix, suffix()); |
1751 | 0 | env.outfilename = outfile_path; |
1752 | 0 | } |
1753 | |
|
1754 | 0 | fprintf (f, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name); |
1755 | 0 | fprintf (f, |
1756 | 0 | _ |
1757 | 0 | ("Generates programs that perform pattern-matching on text.\n" |
1758 | 0 | "\n" "Table Compression:\n" |
1759 | 0 | " -Ca, --align trade off larger tables for better memory alignment\n" |
1760 | 0 | " -Ce, --ecs construct equivalence classes\n" |
1761 | 0 | " -Cf do not compress tables; use -f representation\n" |
1762 | 0 | " -CF do not compress tables; use -F representation\n" |
1763 | 0 | " -Cm, --meta-ecs construct meta-equivalence classes\n" |
1764 | 0 | " -Cr, --read use read() instead of stdio for scanner input\n" |
1765 | 0 | " -f, --full generate fast, large scanner. Same as -Cfr\n" |
1766 | 0 | " -F, --fast use alternate table representation. Same as -CFr\n" |
1767 | 0 | " -Cem default compression (same as --ecs --meta-ecs)\n" |
1768 | 0 | "\n" "Debugging:\n" |
1769 | 0 | " -d, --debug enable debug mode in scanner\n" |
1770 | 0 | " -b, --backup write backing-up information to %s\n" |
1771 | 0 | " -p, --perf-report write performance report to stderr\n" |
1772 | 0 | " -s, --nodefault suppress default rule to ECHO unmatched text\n" |
1773 | 0 | " -T, --env.trace %s should run in env.trace mode\n" |
1774 | 0 | " -w, --nowarn do not generate warnings\n" |
1775 | 0 | " -v, --verbose write summary of scanner statistics to stdout\n" |
1776 | 0 | " --hex use hexadecimal numbers instead of octal in debug outputs\n" |
1777 | 0 | "\n" "Files:\n" |
1778 | 0 | " -o, --outfile=FILE specify output filename\n" |
1779 | 0 | " -S, --skel=FILE specify skeleton file\n" |
1780 | 0 | " -t, --stdout write scanner on stdout instead of %s\n" |
1781 | 0 | " --yyclass=NAME name of C++ class\n" |
1782 | 0 | " --header-file=FILE create a C header file in addition to the scanner\n" |
1783 | 0 | " --tables-file[=FILE] write tables to FILE\n" |
1784 | 0 | " --backup-file=FILE write backing-up information to FILE\n" "\n" |
1785 | 0 | "Scanner behavior:\n" |
1786 | 0 | " -7, --7bit generate 7-bit scanner\n" |
1787 | 0 | " -8, --8bit generate 8-bit scanner\n" |
1788 | 0 | " -B, --batch generate batch scanner (opposite of -I)\n" |
1789 | 0 | " -i, --case-insensitive ignore case in patterns\n" |
1790 | 0 | " -l, --lex-compat maximal compatibility with original lex\n" |
1791 | 0 | " -X, --posix-compat maximal compatibility with POSIX lex\n" |
1792 | 0 | " -I, --interactive generate interactive scanner (opposite of -B)\n" |
1793 | 0 | " --yylineno track line count in yylineno\n" |
1794 | 0 | "\n" "Generated code:\n" |
1795 | 0 | " -+, --c++ generate C++ scanner class\n" |
1796 | 0 | " -Dmacro[=defn] #define macro defn (default defn is '1')\n" |
1797 | 0 | " -e, --emit=LANG Specify target language\n" |
1798 | 0 | " -L, --noline suppress #line directives in scanner\n" |
1799 | 0 | " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" |
1800 | 0 | " -R, --reentrant generate a reentrant scanner\n" |
1801 | 0 | " --bison-bridge scanner for Bison pure parser.\n" |
1802 | 0 | " --bison-locations include yylloc support.\n" |
1803 | 0 | " --stdinit initialize yyin/yyout to stdin/stdout\n" |
1804 | 0 | " --nounistd do not include <unistd.h>\n" |
1805 | 0 | " --noFUNCTION do not generate a particular FUNCTION\n" |
1806 | 0 | "\n" "Miscellaneous:\n" |
1807 | 0 | " -c do-nothing POSIX option\n" |
1808 | 0 | " -n do-nothing POSIX option\n" |
1809 | 0 | " -?\n" |
1810 | 0 | " -h, --help produce this help message\n" |
1811 | 0 | " -V, --version report %s version\n"), |
1812 | 0 | backing_name, "flex", outfile_path, "flex"); |
1813 | |
|
1814 | 0 | } |