xref: /openbsd-src/usr.bin/lex/main.c (revision 5a38ef86d0b61900239c7913d24a05e7b88a58f0)
1 /*	$OpenBSD: main.c,v 1.28 2021/06/23 02:53:44 deraadt Exp $	*/
2 
3 /* flex - tool to generate fast lexical analyzers */
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 
38 #include "flexdef.h"
39 #include "version.h"
40 #include "options.h"
41 #include "tables.h"
42 
43 static char flex_version[] = FLEX_VERSION;
44 
45 /* declare functions that have forward references */
46 
47 void flexinit PROTO((int, char **));
48 void readin PROTO((void));
49 void set_up_initial_allocations PROTO((void));
50 static char *basename2 PROTO((char *path, int should_strip_ext));
51 
52 
53 /* these globals are all defined and commented in flexdef.h */
54 int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt;
55 int interactive, lex_compat, posix_compat, do_yylineno, useecs, fulltbl,
56  usemecs;
57 int fullspd, gen_line_dirs, performance_report, backing_up_report;
58 int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize;
59 int reentrant, bison_bridge_lval, bison_bridge_lloc;
60 int yymore_used, reject, real_reject, continued_action, in_rule;
61 int yymore_really_used, reject_really_used;
62 int datapos, dataline, linenum;
63 FILE *skelfile = NULL;
64 int skel_ind = 0;
65 char *action_array;
66 int action_size, defs1_offset, prolog_offset, action_offset, action_index;
67 char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL;
68 int did_outfilename;
69 char *prefix, *yyclass, *extra_type = NULL;
70 int do_stdinit, use_stdout;
71 int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
72 int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
73 int maximum_mns, current_mns, current_max_rules;
74 int num_rules, num_eof_rules, default_rule, lastnfa;
75 int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2;
76 int *accptnum, *assoc_rule, *state_type;
77 int *rule_type, *rule_linenum, *rule_useful;
78 int current_state_type;
79 int variable_trailing_context_rules;
80 int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
81 int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
82 int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
83 int tecbck[CSIZE + 1];
84 int lastsc, *scset, *scbol, *scxclu, *sceof;
85 int current_max_scs;
86 char **scname;
87 int current_max_dfa_size, current_max_xpairs;
88 int current_max_template_xpairs, current_max_dfas;
89 int lastdfa, *nxt, *chk, *tnxt;
90 int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz;
91 union dfaacc_union *dfaacc;
92 int *accsiz, *dhash, numas;
93 int numsnpairs, jambase, jamstate;
94 int lastccl, *cclmap, *ccllen, *cclng, cclreuse;
95 int current_maxccls, current_max_ccl_tbl_size;
96 u_char *ccltbl;
97 char nmstr[MAXLINE];
98 int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
99 int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
100 int num_backing_up, bol_needed;
101 FILE *backing_up_file;
102 int end_of_buffer_state;
103 char **input_files;
104 int num_input_files;
105 jmp_buf flex_main_jmp_buf;
106 bool *rule_has_nl, *ccl_has_nl;
107 int nlch = '\n';
108 bool ansi_func_defs, ansi_func_protos;
109 
110 bool tablesext, tablesverify, gentables;
111 char *tablesfilename = 0, *tablesname = 0;
112 struct yytbl_writer tableswr;
113 
114 /* Make sure program_name is initialized so we don't crash if writing
115  * out an error message before getting the program name from argv[0].
116  */
117 char *program_name = "flex";
118 
119 static const char *outfile_template = "lex.%s.%s";
120 static const char *backing_name = "lex.backup";
121 static const char *tablesfile_template = "lex.%s.tables";
122 
123 /* From scan.l */
124 extern FILE *yyout;
125 
126 static char outfile_path[MAXLINE];
127 static int outfile_created = 0;
128 static char *skelname = NULL;
129 static int _stdout_closed = 0;	/* flag to prevent double-fclose() on stdout. */
130 const char *escaped_qstart = "[[]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[[]]";
131 const char *escaped_qend = "[[]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[[]]";
132 
133 /* For debugging. The max number of filters to apply to skeleton. */
134 static int preproc_level = 1000;
135 
136 int flex_main PROTO((int argc, char *argv[]));
137 int main PROTO((int argc, char *argv[]));
138 
139 int
140 flex_main(argc, argv)
141 	int argc;
142 	char *argv[];
143 {
144 	int i, exit_status, child_status;
145 
146 	/*
147 	 * Set a longjmp target. Yes, I know it's a hack, but it gets worse:
148 	 * The return value of setjmp, if non-zero, is the desired exit code
149 	 * PLUS ONE. For example, if you want 'main' to return with code '2',
150 	 * then call longjmp() with an argument of 3. This is because it is
151 	 * invalid to specify a value of 0 to longjmp. FLEX_EXIT(n) should be
152 	 * used instead of exit(n);
153 	 */
154 	exit_status = setjmp(flex_main_jmp_buf);
155 	if (exit_status) {
156 		if (stdout && !_stdout_closed && !ferror(stdout)) {
157 			fflush(stdout);
158 			fclose(stdout);
159 		}
160 		while (wait(&child_status) > 0) {
161 			if (!WIFEXITED(child_status)
162 			    || WEXITSTATUS(child_status) != 0) {
163 				/*
164 				 * report an error of a child
165 				 */
166 				if (exit_status <= 1)
167 					exit_status = 2;
168 
169 			}
170 		}
171 		return exit_status - 1;
172 	}
173 	flexinit(argc, argv);
174 
175 	readin();
176 
177 	skelout();
178 	/* %% [1.5] DFA */
179 	ntod();
180 
181 	for (i = 1; i <= num_rules; ++i)
182 		if (!rule_useful[i] && i != default_rule)
183 			line_warning(_("rule cannot be matched"),
184 			    rule_linenum[i]);
185 
186 	if (spprdflt && !reject && rule_useful[default_rule])
187 		line_warning(_
188 		    ("-s option given but default rule can be matched"),
189 		    rule_linenum[default_rule]);
190 
191 	/* Generate the C state transition tables from the DFA. */
192 	make_tables();
193 
194 	/*
195 	 * Note, flexend does not return.  It exits with its argument as
196 	 * status.
197 	 */
198 	flexend(0);
199 
200 	return 0;		/* keep compilers/lint happy */
201 }
202 
203 /* Wrapper around flex_main, so flex_main can be built as a library. */
204 int
205 main(argc, argv)
206 	int argc;
207 	char *argv[];
208 {
209 #if ENABLE_NLS
210 #if HAVE_LOCALE_H
211 	setlocale(LC_MESSAGES, "");
212 	setlocale(LC_CTYPE, "");
213 	textdomain(PACKAGE);
214 	bindtextdomain(PACKAGE, LOCALEDIR);
215 #endif
216 #endif
217 
218 	if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) {
219 		fprintf(stderr, _("%s: pledge\n"),
220 		    program_name);
221 		exit(1);
222 	}
223 	return flex_main(argc, argv);
224 }
225 
226 /* check_options - check user-specified options */
227 
228 void
229 check_options()
230 {
231 	int i;
232 
233 	if (lex_compat) {
234 		if (C_plus_plus)
235 			flexerror(_("Can't use -+ with -l option"));
236 
237 		if (fulltbl || fullspd)
238 			flexerror(_("Can't use -f or -F with -l option"));
239 
240 		if (reentrant || bison_bridge_lval)
241 			flexerror(_
242 			    ("Can't use --reentrant or --bison-bridge with -l option"));
243 
244 		yytext_is_array = true;
245 		do_yylineno = true;
246 		use_read = false;
247 	}
248 #if 0
249 	/* This makes no sense whatsoever. I'm removing it. */
250 	if (do_yylineno)
251 		/* This should really be "maintain_backup_tables = true" */
252 		reject_really_used = true;
253 #endif
254 
255 	if (csize == unspecified) {
256 		if ((fulltbl || fullspd) && !useecs)
257 			csize = DEFAULT_CSIZE;
258 		else
259 			csize = CSIZE;
260 	}
261 	if (interactive == unspecified) {
262 		if (fulltbl || fullspd)
263 			interactive = false;
264 		else
265 			interactive = true;
266 	}
267 	if (fulltbl || fullspd) {
268 		if (usemecs)
269 			flexerror(_
270 			    ("-Cf/-CF and -Cm don't make sense together"));
271 
272 		if (interactive)
273 			flexerror(_("-Cf/-CF and -I are incompatible"));
274 
275 		if (lex_compat)
276 			flexerror(_
277 			    ("-Cf/-CF are incompatible with lex-compatibility mode"));
278 
279 
280 		if (fulltbl && fullspd)
281 			flexerror(_
282 			    ("-Cf and -CF are mutually exclusive"));
283 	}
284 	if (C_plus_plus && fullspd)
285 		flexerror(_("Can't use -+ with -CF option"));
286 
287 	if (C_plus_plus && yytext_is_array) {
288 		warn(_("%array incompatible with -+ option"));
289 		yytext_is_array = false;
290 	}
291 	if (C_plus_plus && (reentrant))
292 		flexerror(_("Options -+ and --reentrant are mutually exclusive."));
293 
294 	if (C_plus_plus && bison_bridge_lval)
295 		flexerror(_("bison bridge not supported for the C++ scanner."));
296 
297 
298 	if (useecs) {		/* Set up doubly-linked equivalence classes. */
299 
300 		/*
301 		 * We loop all the way up to csize, since ecgroup[csize] is
302 		 * the position used for NUL characters.
303 		 */
304 		ecgroup[1] = NIL;
305 
306 		for (i = 2; i <= csize; ++i) {
307 			ecgroup[i] = i - 1;
308 			nextecm[i - 1] = i;
309 		}
310 
311 		nextecm[csize] = NIL;
312 	} else {
313 		/* Put everything in its own equivalence class. */
314 		for (i = 1; i <= csize; ++i) {
315 			ecgroup[i] = i;
316 			nextecm[i] = BAD_SUBSCRIPT;	/* to catch errors */
317 		}
318 	}
319 
320 	if (!ansi_func_defs)
321 		buf_m4_define(&m4defs_buf, "M4_YY_NO_ANSI_FUNC_DEFS", NULL);
322 
323 	if (!ansi_func_protos)
324 		buf_m4_define(&m4defs_buf, "M4_YY_NO_ANSI_FUNC_PROTOS", NULL);
325 
326 	if (extra_type)
327 		buf_m4_define(&m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type);
328 
329 	if (!use_stdout) {
330 		FILE *prev_stdout;
331 
332 		if (!did_outfilename) {
333 			char *suffix;
334 
335 			if (C_plus_plus)
336 				suffix = "cc";
337 			else
338 				suffix = "c";
339 
340 			snprintf(outfile_path, sizeof(outfile_path), outfile_template,
341 			    prefix, suffix);
342 
343 			outfilename = outfile_path;
344 		}
345 		prev_stdout = freopen(outfilename, "w+", stdout);
346 
347 		if (prev_stdout == NULL)
348 			lerrsf(_("could not create %s"), outfilename);
349 
350 		outfile_created = 1;
351 	}
352 	/* Setup the filter chain. */
353 	output_chain = filter_create_int(NULL, filter_tee_header, headerfilename);
354 	filter_create_ext(output_chain, M4, "-P", 0);
355 	filter_create_int(output_chain, filter_fix_linedirs, NULL);
356 
357 	/* For debugging, only run the requested number of filters. */
358 	if (preproc_level > 0) {
359 		filter_truncate(output_chain, preproc_level);
360 		filter_apply_chain(output_chain);
361 	}
362 	yyout = stdout;
363 
364 
365 	/* always generate the tablesverify flag. */
366 	buf_m4_define(&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0");
367 	if (tablesext)
368 		gentables = false;
369 
370 	if (tablesverify)
371 		/* force generation of C tables. */
372 		gentables = true;
373 
374 
375 	if (tablesext) {
376 		FILE *tablesout;
377 		struct yytbl_hdr hdr;
378 		char *pname = 0;
379 		int nbytes = 0;
380 
381 		buf_m4_define(&m4defs_buf, "M4_YY_TABLES_EXTERNAL", NULL);
382 
383 		if (!tablesfilename) {
384 			nbytes = strlen(prefix) + strlen(tablesfile_template) + 2;
385 			tablesfilename = pname = (char *) calloc(nbytes, 1);
386 			snprintf(pname, nbytes, tablesfile_template, prefix);
387 		}
388 		if ((tablesout = fopen(tablesfilename, "w")) == NULL)
389 			lerrsf(_("could not create %s"), tablesfilename);
390 		free(pname);
391 		tablesfilename = 0;
392 
393 		yytbl_writer_init(&tableswr, tablesout);
394 
395 		nbytes = strlen(prefix) + strlen("tables") + 2;
396 		tablesname = (char *) calloc(nbytes, 1);
397 		snprintf(tablesname, nbytes, "%stables", prefix);
398 		yytbl_hdr_init(&hdr, flex_version, tablesname);
399 
400 		if (yytbl_hdr_fwrite(&tableswr, &hdr) <= 0)
401 			flexerror(_("could not write tables header"));
402 	}
403 	if (skelname && (skelfile = fopen(skelname, "r")) == NULL)
404 		lerrsf(_("can't open skeleton file %s"), skelname);
405 
406 	if (reentrant) {
407 		buf_m4_define(&m4defs_buf, "M4_YY_REENTRANT", NULL);
408 		if (yytext_is_array)
409 			buf_m4_define(&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL);
410 	}
411 	if (bison_bridge_lval)
412 		buf_m4_define(&m4defs_buf, "M4_YY_BISON_LVAL", NULL);
413 
414 	if (bison_bridge_lloc)
415 		buf_m4_define(&m4defs_buf, "<M4_YY_BISON_LLOC>", NULL);
416 
417 	buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix);
418 
419 	if (did_outfilename)
420 		line_directive_out(stdout, 0);
421 
422 	if (do_yylineno)
423 		buf_m4_define(&m4defs_buf, "M4_YY_USE_LINENO", NULL);
424 
425 	/* Create the alignment type. */
426 	buf_strdefine(&userdef_buf, "YY_INT_ALIGNED",
427 	    long_align ? "long int" : "short int");
428 
429 	/* Define the start condition macros. */
430 	{
431 		struct Buf tmpbuf;
432 		buf_init(&tmpbuf, sizeof(char));
433 		for (i = 1; i <= lastsc; i++) {
434 			char *str, *fmt = "#define %s %d\n";
435 			size_t strsz;
436 
437 			str = (char *) malloc(strsz = strlen(fmt) + strlen(scname[i]) + (int) (1 + log10(i)) + 2);
438 			if (!str)
439 				flexfatal(_("allocation of macro definition failed"));
440 			snprintf(str, strsz, fmt, scname[i], i - 1);
441 			buf_strappend(&tmpbuf, str);
442 			free(str);
443 		}
444 		buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts);
445 		buf_destroy(&tmpbuf);
446 	}
447 
448 	/* This is where we begin writing to the file. */
449 
450 	/* Dump the %top code. */
451 	if (top_buf.elts)
452 		outn((char *) top_buf.elts);
453 
454 	/* Dump the m4 definitions. */
455 	buf_print_strings(&m4defs_buf, stdout);
456 	m4defs_buf.nelts = 0;	/* memory leak here. */
457 
458 	/* Place a bogus line directive, it will be fixed in the filter. */
459 	outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n");
460 
461 	/* Dump the user defined preproc directives. */
462 	if (userdef_buf.elts)
463 		outn((char *) (userdef_buf.elts));
464 
465 	skelout();
466 	/* %% [1.0] */
467 }
468 
469 /* flexend - terminate flex
470  *
471  * note
472  *    This routine does not return.
473  */
474 
475 void
476 flexend(exit_status)
477 	int exit_status;
478 
479 {
480 	static int called_before = -1;	/* prevent infinite recursion. */
481 	int tblsiz;
482 
483 	if (++called_before)
484 		FLEX_EXIT(exit_status);
485 
486 	if (skelfile != NULL) {
487 		if (ferror(skelfile))
488 			lerrsf(_("input error reading skeleton file %s"),
489 			    skelname);
490 
491 		else if (fclose(skelfile))
492 			lerrsf(_("error closing skeleton file %s"),
493 			    skelname);
494 	}
495 #if 0
496 	fprintf(header_out,
497 	    "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n");
498 	fprintf(header_out,
499 	    "/* Beware! Start conditions are not prefixed. */\n");
500 
501 	/* Special case for "INITIAL" */
502 	fprintf(header_out,
503 	    "#undef INITIAL\n#define INITIAL 0\n");
504 	for (i = 2; i <= lastsc; i++)
505 		fprintf(header_out, "#define %s %d\n", scname[i], i - 1);
506 	fprintf(header_out,
507 	    "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n");
508 
509 	/*
510 	 * Kill ALL flex-related macros. This is so the user can #include
511 	 * more than one generated header file.
512 	 */
513 	fprintf(header_out, "#ifndef YY_HEADER_NO_UNDEFS\n");
514 	fprintf(header_out,
515 	    "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n");
516 
517 	{
518 		const char *undef_list[] = {
519 
520 			"BEGIN",
521 			"ECHO",
522 			"EOB_ACT_CONTINUE_SCAN",
523 			"EOB_ACT_END_OF_FILE",
524 			"EOB_ACT_LAST_MATCH",
525 			"FLEX_SCANNER",
526 			"FLEX_STD",
527 			"REJECT",
528 			"YYFARGS0",
529 			"YYFARGS1",
530 			"YYFARGS2",
531 			"YYFARGS3",
532 			"YYLMAX",
533 			"YYSTATE",
534 			"YY_AT_BOL",
535 			"YY_BREAK",
536 			"YY_BUFFER_EOF_PENDING",
537 			"YY_BUFFER_NEW",
538 			"YY_BUFFER_NORMAL",
539 			"YY_BUF_SIZE",
540 			"M4_YY_CALL_LAST_ARG",
541 			"M4_YY_CALL_ONLY_ARG",
542 			"YY_CURRENT_BUFFER",
543 			"YY_DECL",
544 			"M4_YY_DECL_LAST_ARG",
545 			"M4_YY_DEF_LAST_ARG",
546 			"M4_YY_DEF_ONLY_ARG",
547 			"YY_DO_BEFORE_ACTION",
548 			"YY_END_OF_BUFFER",
549 			"YY_END_OF_BUFFER_CHAR",
550 			"YY_EXIT_FAILURE",
551 			"YY_EXTRA_TYPE",
552 			"YY_FATAL_ERROR",
553 			"YY_FLEX_DEFINED_ECHO",
554 			"YY_FLEX_LEX_COMPAT",
555 			"YY_FLEX_MAJOR_VERSION",
556 			"YY_FLEX_MINOR_VERSION",
557 			"YY_FLEX_SUBMINOR_VERSION",
558 			"YY_FLUSH_BUFFER",
559 			"YY_G",
560 			"YY_INPUT",
561 			"YY_INTERACTIVE",
562 			"YY_INT_ALIGNED",
563 			"YY_LAST_ARG",
564 			"YY_LESS_LINENO",
565 			"YY_LEX_ARGS",
566 			"YY_LEX_DECLARATION",
567 			"YY_LEX_PROTO",
568 			"YY_MAIN",
569 			"YY_MORE_ADJ",
570 			"YY_NEED_STRLEN",
571 			"YY_NEW_FILE",
572 			"YY_NULL",
573 			"YY_NUM_RULES",
574 			"YY_ONLY_ARG",
575 			"YY_PARAMS",
576 			"YY_PROTO",
577 			"M4_YY_PROTO_LAST_ARG",
578 			"M4_YY_PROTO_ONLY_ARG void",
579 			"YY_READ_BUF_SIZE",
580 			"YY_REENTRANT",
581 			"YY_RESTORE_YY_MORE_OFFSET",
582 			"YY_RULE_SETUP",
583 			"YY_SC_TO_UI",
584 			"YY_SKIP_YYWRAP",
585 			"YY_START",
586 			"YY_START_STACK_INCR",
587 			"YY_STATE_EOF",
588 			"YY_STDINIT",
589 			"YY_TRAILING_HEAD_MASK",
590 			"YY_TRAILING_MASK",
591 			"YY_USER_ACTION",
592 			"YY_USE_CONST",
593 			"YY_USE_PROTOS",
594 			"unput",
595 			"yyTABLES_NAME",
596 			"yy_create_buffer",
597 			"yy_delete_buffer",
598 			"yy_flex_debug",
599 			"yy_flush_buffer",
600 			"yy_init_buffer",
601 			"yy_load_buffer_state",
602 			"yy_new_buffer",
603 			"yy_scan_buffer",
604 			"yy_scan_bytes",
605 			"yy_scan_string",
606 			"yy_set_bol",
607 			"yy_set_interactive",
608 			"yy_switch_to_buffer",
609 			"yypush_buffer_state",
610 			"yypop_buffer_state",
611 			"yyensure_buffer_stack",
612 			"yyalloc",
613 			"yyconst",
614 			"yyextra",
615 			"yyfree",
616 			"yyget_debug",
617 			"yyget_extra",
618 			"yyget_in",
619 			"yyget_leng",
620 			"yyget_lineno",
621 			"yyget_lloc",
622 			"yyget_lval",
623 			"yyget_out",
624 			"yyget_text",
625 			"yyin",
626 			"yyleng",
627 			"yyless",
628 			"yylex",
629 			"yylex_destroy",
630 			"yylex_init",
631 			"yylex_init_extra",
632 			"yylineno",
633 			"yylloc",
634 			"yylval",
635 			"yymore",
636 			"yyout",
637 			"yyrealloc",
638 			"yyrestart",
639 			"yyset_debug",
640 			"yyset_extra",
641 			"yyset_in",
642 			"yyset_lineno",
643 			"yyset_lloc",
644 			"yyset_lval",
645 			"yyset_out",
646 			"yytables_destroy",
647 			"yytables_fload",
648 			"yyterminate",
649 			"yytext",
650 			"yytext_ptr",
651 			"yywrap",
652 
653 			/* must be null-terminated */
654 		NULL};
655 
656 
657 		for (i = 0; undef_list[i] != NULL; i++)
658 			fprintf(header_out, "#undef %s\n", undef_list[i]);
659 	}
660 
661 	/* undef any of the auto-generated symbols. */
662 	for (i = 0; i < defs_buf.nelts; i++) {
663 
664 		/* don't undef start conditions */
665 		if (sclookup(((char **) defs_buf.elts)[i]) > 0)
666 			continue;
667 		fprintf(header_out, "#undef %s\n",
668 		    ((char **) defs_buf.elts)[i]);
669 	}
670 
671 	fprintf(header_out,
672 	    "#endif /* !YY_HEADER_NO_UNDEFS */\n");
673 	fprintf(header_out, "\n");
674 	fprintf(header_out, "#undef %sIN_HEADER\n", prefix);
675 	fprintf(header_out, "#endif /* %sHEADER_H */\n", prefix);
676 
677 	if (ferror(header_out))
678 		lerrsf(_("error creating header file %s"),
679 		    headerfilename);
680 	fflush(header_out);
681 	fclose(header_out);
682 #endif
683 
684 	if (exit_status != 0 && outfile_created) {
685 		if (ferror(stdout))
686 			lerrsf(_("error writing output file %s"),
687 			    outfilename);
688 
689 		else if ((_stdout_closed = 1) && fclose(stdout))
690 			lerrsf(_("error closing output file %s"),
691 			    outfilename);
692 
693 		else if (unlink(outfilename))
694 			lerrsf(_("error deleting output file %s"),
695 			    outfilename);
696 	}
697 	if (backing_up_report && backing_up_file) {
698 		if (num_backing_up == 0)
699 			fprintf(backing_up_file, _("No backing up.\n"));
700 		else if (fullspd || fulltbl)
701 			fprintf(backing_up_file,
702 			    _
703 			    ("%d backing up (non-accepting) states.\n"),
704 			    num_backing_up);
705 		else
706 			fprintf(backing_up_file,
707 			    _("Compressed tables always back up.\n"));
708 
709 		if (ferror(backing_up_file))
710 			lerrsf(_("error writing backup file %s"),
711 			    backing_name);
712 
713 		else if (fclose(backing_up_file))
714 			lerrsf(_("error closing backup file %s"),
715 			    backing_name);
716 	}
717 	if (printstats) {
718 		fprintf(stderr, _("%s version %s usage statistics:\n"),
719 		    program_name, flex_version);
720 
721 		fprintf(stderr, _("  scanner options: -"));
722 
723 		if (C_plus_plus)
724 			putc('+', stderr);
725 		if (backing_up_report)
726 			putc('b', stderr);
727 		if (ddebug)
728 			putc('d', stderr);
729 		if (sf_case_ins())
730 			putc('i', stderr);
731 		if (lex_compat)
732 			putc('l', stderr);
733 		if (posix_compat)
734 			putc('X', stderr);
735 		if (performance_report > 0)
736 			putc('p', stderr);
737 		if (performance_report > 1)
738 			putc('p', stderr);
739 		if (spprdflt)
740 			putc('s', stderr);
741 		if (reentrant)
742 			fputs("--reentrant", stderr);
743 		if (bison_bridge_lval)
744 			fputs("--bison-bridge", stderr);
745 		if (bison_bridge_lloc)
746 			fputs("--bison-locations", stderr);
747 		if (use_stdout)
748 			putc('t', stderr);
749 		if (printstats)
750 			putc('v', stderr);	/* always true! */
751 		if (nowarn)
752 			putc('w', stderr);
753 		if (interactive == false)
754 			putc('B', stderr);
755 		if (interactive == true)
756 			putc('I', stderr);
757 		if (!gen_line_dirs)
758 			putc('L', stderr);
759 		if (trace)
760 			putc('T', stderr);
761 
762 		if (csize == unspecified)
763 			/*
764 			 * We encountered an error fairly early on, so csize
765 			 * never got specified.  Define it now, to prevent
766 			 * bogus table sizes being written out below.
767 			 */
768 			csize = 256;
769 
770 		if (csize == 128)
771 			putc('7', stderr);
772 		else
773 			putc('8', stderr);
774 
775 		fprintf(stderr, " -C");
776 
777 		if (long_align)
778 			putc('a', stderr);
779 		if (fulltbl)
780 			putc('f', stderr);
781 		if (fullspd)
782 			putc('F', stderr);
783 		if (useecs)
784 			putc('e', stderr);
785 		if (usemecs)
786 			putc('m', stderr);
787 		if (use_read)
788 			putc('r', stderr);
789 
790 		if (did_outfilename)
791 			fprintf(stderr, " -o%s", outfilename);
792 
793 		if (skelname)
794 			fprintf(stderr, " -S%s", skelname);
795 
796 		if (strcmp(prefix, "yy"))
797 			fprintf(stderr, " -P%s", prefix);
798 
799 		putc('\n', stderr);
800 
801 		fprintf(stderr, _("  %d/%d NFA states\n"),
802 		    lastnfa, current_mns);
803 		fprintf(stderr, _("  %d/%d DFA states (%d words)\n"),
804 		    lastdfa, current_max_dfas, totnst);
805 		fprintf(stderr, _("  %d rules\n"),
806 		    num_rules + num_eof_rules -
807 		    1 /* - 1 for def. rule */ );
808 
809 		if (num_backing_up == 0)
810 			fprintf(stderr, _("  No backing up\n"));
811 		else if (fullspd || fulltbl)
812 			fprintf(stderr,
813 			    _
814 			    ("  %d backing-up (non-accepting) states\n"),
815 			    num_backing_up);
816 		else
817 			fprintf(stderr,
818 			    _
819 			    ("  Compressed tables always back-up\n"));
820 
821 		if (bol_needed)
822 			fprintf(stderr,
823 			    _("  Beginning-of-line patterns used\n"));
824 
825 		fprintf(stderr, _("  %d/%d start conditions\n"), lastsc,
826 		    current_max_scs);
827 		fprintf(stderr,
828 		    _
829 		    ("  %d epsilon states, %d double epsilon states\n"),
830 		    numeps, eps2);
831 
832 		if (lastccl == 0)
833 			fprintf(stderr, _("  no character classes\n"));
834 		else
835 			fprintf(stderr,
836 			    _
837 			    ("  %d/%d character classes needed %d/%d words of storage, %d reused\n"),
838 			    lastccl, current_maxccls,
839 			    cclmap[lastccl] + ccllen[lastccl],
840 			    current_max_ccl_tbl_size, cclreuse);
841 
842 		fprintf(stderr, _("  %d state/nextstate pairs created\n"),
843 		    numsnpairs);
844 		fprintf(stderr,
845 		    _("  %d/%d unique/duplicate transitions\n"),
846 		    numuniq, numdup);
847 
848 		if (fulltbl) {
849 			tblsiz = lastdfa * numecs;
850 			fprintf(stderr, _("  %d table entries\n"),
851 			    tblsiz);
852 		} else {
853 			tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
854 
855 			fprintf(stderr,
856 			    _("  %d/%d base-def entries created\n"),
857 			    lastdfa + numtemps, current_max_dfas);
858 			fprintf(stderr,
859 			    _
860 			    ("  %d/%d (peak %d) nxt-chk entries created\n"),
861 			    tblend, current_max_xpairs, peakpairs);
862 			fprintf(stderr,
863 			    _
864 			    ("  %d/%d (peak %d) template nxt-chk entries created\n"),
865 			    numtemps * nummecs,
866 			    current_max_template_xpairs,
867 			    numtemps * numecs);
868 			fprintf(stderr, _("  %d empty table entries\n"),
869 			    nummt);
870 			fprintf(stderr, _("  %d protos created\n"),
871 			    numprots);
872 			fprintf(stderr,
873 			    _("  %d templates created, %d uses\n"),
874 			    numtemps, tmpuses);
875 		}
876 
877 		if (useecs) {
878 			tblsiz = tblsiz + csize;
879 			fprintf(stderr,
880 			    _
881 			    ("  %d/%d equivalence classes created\n"),
882 			    numecs, csize);
883 		}
884 		if (usemecs) {
885 			tblsiz = tblsiz + numecs;
886 			fprintf(stderr,
887 			    _
888 			    ("  %d/%d meta-equivalence classes created\n"),
889 			    nummecs, csize);
890 		}
891 		fprintf(stderr,
892 		    _
893 		    ("  %d (%d saved) hash collisions, %d DFAs equal\n"),
894 		    hshcol, hshsave, dfaeql);
895 		fprintf(stderr, _("  %d sets of reallocations needed\n"),
896 		    num_reallocs);
897 		fprintf(stderr, _("  %d total table entries needed\n"),
898 		    tblsiz);
899 	}
900 	FLEX_EXIT(exit_status);
901 }
902 
903 
904 /* flexinit - initialize flex */
905 
906 void
907 flexinit(argc, argv)
908 	int argc;
909 	char **argv;
910 {
911 	int i, sawcmpflag, rv, optind;
912 	char *arg;
913 	scanopt_t sopt;
914 
915 	printstats = syntaxerror = trace = spprdflt = false;
916 	lex_compat = posix_compat = C_plus_plus = backing_up_report =
917 	    ddebug = fulltbl = false;
918 	fullspd = long_align = nowarn = yymore_used = continued_action =
919 	    false;
920 	do_yylineno = yytext_is_array = in_rule = reject = do_stdinit =
921 	    false;
922 	yymore_really_used = reject_really_used = unspecified;
923 	interactive = csize = unspecified;
924 	do_yywrap = gen_line_dirs = usemecs = useecs = true;
925 	reentrant = bison_bridge_lval = bison_bridge_lloc = false;
926 	performance_report = 0;
927 	did_outfilename = 0;
928 	prefix = "yy";
929 	yyclass = 0;
930 	use_read = use_stdout = false;
931 	tablesext = tablesverify = false;
932 	gentables = true;
933 	tablesfilename = tablesname = NULL;
934 	ansi_func_defs = ansi_func_protos = true;
935 
936 	sawcmpflag = false;
937 
938 	/* Initialize dynamic array for holding the rule actions. */
939 	action_size = 2048;	/* default size of action array in bytes */
940 	action_array = allocate_character_array(action_size);
941 	defs1_offset = prolog_offset = action_offset = action_index = 0;
942 	action_array[0] = '\0';
943 
944 	/* Initialize any buffers. */
945 	buf_init(&userdef_buf, sizeof(char));	/* one long string */
946 	buf_init(&defs_buf, sizeof(char *));	/* list of strings */
947 	buf_init(&yydmap_buf, sizeof(char));	/* one long string */
948 	buf_init(&top_buf, sizeof(char));	/* one long string */
949 
950 	{
951 		const char *m4defs_init_str[] = {"m4_changequote\n",
952 		"m4_changequote([[, ]])\n"};
953 		buf_init(&m4defs_buf, sizeof(char *));
954 		buf_append(&m4defs_buf, &m4defs_init_str, 2);
955 	}
956 
957 	sf_init();
958 
959 	/* initialize regex lib */
960 	flex_init_regex();
961 
962 	/* Enable C++ if program name ends with '+'. */
963 	program_name = basename2(argv[0], 0);
964 
965 	if (program_name[0] != '\0' &&
966 	    program_name[strlen(program_name) - 1] == '+')
967 		C_plus_plus = true;
968 
969 	/* read flags */
970 	sopt = scanopt_init(flexopts, argc, argv, 0);
971 	if (!sopt) {
972 		/* This will only happen when flexopts array is altered. */
973 		fprintf(stderr,
974 		    _("Internal error. flexopts are malformed.\n"));
975 		FLEX_EXIT(1);
976 	}
977 	while ((rv = scanopt(sopt, &arg, &optind)) != 0) {
978 
979 		if (rv < 0) {
980 			usage();
981 			FLEX_EXIT(1);
982 		}
983 		switch ((enum flexopt_flag_t) rv) {
984 		case OPT_CPLUSPLUS:
985 			C_plus_plus = true;
986 			break;
987 
988 		case OPT_BATCH:
989 			interactive = false;
990 			break;
991 
992 		case OPT_BACKUP:
993 			backing_up_report = true;
994 			break;
995 
996 		case OPT_DONOTHING:
997 			break;
998 
999 		case OPT_COMPRESSION:
1000 			if (!sawcmpflag) {
1001 				useecs = false;
1002 				usemecs = false;
1003 				fulltbl = false;
1004 				sawcmpflag = true;
1005 			}
1006 			for (i = 0; arg && arg[i] != '\0'; i++)
1007 				switch (arg[i]) {
1008 				case 'a':
1009 					long_align = true;
1010 					break;
1011 
1012 				case 'e':
1013 					useecs = true;
1014 					break;
1015 
1016 				case 'F':
1017 					fullspd = true;
1018 					break;
1019 
1020 				case 'f':
1021 					fulltbl = true;
1022 					break;
1023 
1024 				case 'm':
1025 					usemecs = true;
1026 					break;
1027 
1028 				case 'r':
1029 					use_read = true;
1030 					break;
1031 
1032 				default:
1033 					lerrif(_
1034 					    ("unknown -C option '%c'"),
1035 					    (int) arg[i]);
1036 					break;
1037 				}
1038 			break;
1039 
1040 		case OPT_DEBUG:
1041 			ddebug = true;
1042 			break;
1043 
1044 		case OPT_NO_DEBUG:
1045 			ddebug = false;
1046 			break;
1047 
1048 		case OPT_FULL:
1049 			useecs = usemecs = false;
1050 			use_read = fulltbl = true;
1051 			break;
1052 
1053 		case OPT_FAST:
1054 			useecs = usemecs = false;
1055 			use_read = fullspd = true;
1056 			break;
1057 
1058 		case OPT_HELP:
1059 			usage();
1060 			FLEX_EXIT(0);
1061 
1062 		case OPT_INTERACTIVE:
1063 			interactive = true;
1064 			break;
1065 
1066 		case OPT_CASE_INSENSITIVE:
1067 			sf_set_case_ins(true);
1068 			break;
1069 
1070 		case OPT_LEX_COMPAT:
1071 			lex_compat = true;
1072 			break;
1073 
1074 		case OPT_POSIX_COMPAT:
1075 			posix_compat = true;
1076 			break;
1077 
1078 		case OPT_PREPROC_LEVEL:
1079 			preproc_level = strtol(arg, NULL, 0);
1080 			break;
1081 
1082 		case OPT_MAIN:
1083 			buf_strdefine(&userdef_buf, "YY_MAIN", "1");
1084 			do_yywrap = false;
1085 			break;
1086 
1087 		case OPT_NO_MAIN:
1088 			buf_strdefine(&userdef_buf, "YY_MAIN", "0");
1089 			break;
1090 
1091 		case OPT_NO_LINE:
1092 			gen_line_dirs = false;
1093 			break;
1094 
1095 		case OPT_OUTFILE:
1096 			outfilename = arg;
1097 			did_outfilename = 1;
1098 			break;
1099 
1100 		case OPT_PREFIX:
1101 			prefix = arg;
1102 			break;
1103 
1104 		case OPT_PERF_REPORT:
1105 			++performance_report;
1106 			break;
1107 
1108 		case OPT_BISON_BRIDGE:
1109 			bison_bridge_lval = true;
1110 			break;
1111 
1112 		case OPT_BISON_BRIDGE_LOCATIONS:
1113 			bison_bridge_lval = bison_bridge_lloc = true;
1114 			break;
1115 
1116 		case OPT_REENTRANT:
1117 			reentrant = true;
1118 			break;
1119 
1120 		case OPT_NO_REENTRANT:
1121 			reentrant = false;
1122 			break;
1123 
1124 		case OPT_SKEL:
1125 			skelname = arg;
1126 			break;
1127 
1128 		case OPT_DEFAULT:
1129 			spprdflt = false;
1130 			break;
1131 
1132 		case OPT_NO_DEFAULT:
1133 			spprdflt = true;
1134 			break;
1135 
1136 		case OPT_STDOUT:
1137 			use_stdout = true;
1138 			break;
1139 
1140 		case OPT_NO_UNISTD_H:
1141 			//buf_strdefine(&userdef_buf, "YY_NO_UNISTD_H", "1");
1142 			buf_m4_define(&m4defs_buf, "M4_YY_NO_UNISTD_H", 0);
1143 			break;
1144 
1145 		case OPT_TABLES_FILE:
1146 			tablesext = true;
1147 			tablesfilename = arg;
1148 			break;
1149 
1150 		case OPT_TABLES_VERIFY:
1151 			tablesverify = true;
1152 			break;
1153 
1154 		case OPT_TRACE:
1155 			trace = true;
1156 			break;
1157 
1158 		case OPT_VERBOSE:
1159 			printstats = true;
1160 			break;
1161 
1162 		case OPT_VERSION:
1163 			printf(_("%s %s\n"), program_name, flex_version);
1164 			FLEX_EXIT(0);
1165 
1166 		case OPT_WARN:
1167 			nowarn = false;
1168 			break;
1169 
1170 		case OPT_NO_WARN:
1171 			nowarn = true;
1172 			break;
1173 
1174 		case OPT_7BIT:
1175 			csize = 128;
1176 			break;
1177 
1178 		case OPT_8BIT:
1179 			csize = CSIZE;
1180 			break;
1181 
1182 		case OPT_ALIGN:
1183 			long_align = true;
1184 			break;
1185 
1186 		case OPT_NO_ALIGN:
1187 			long_align = false;
1188 			break;
1189 
1190 		case OPT_ALWAYS_INTERACTIVE:
1191 			buf_m4_define(&m4defs_buf, "M4_YY_ALWAYS_INTERACTIVE", 0);
1192 			break;
1193 
1194 		case OPT_NEVER_INTERACTIVE:
1195 			buf_m4_define(&m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0);
1196 			break;
1197 
1198 		case OPT_ARRAY:
1199 			yytext_is_array = true;
1200 			break;
1201 
1202 		case OPT_POINTER:
1203 			yytext_is_array = false;
1204 			break;
1205 
1206 		case OPT_ECS:
1207 			useecs = true;
1208 			break;
1209 
1210 		case OPT_NO_ECS:
1211 			useecs = false;
1212 			break;
1213 
1214 		case OPT_HEADER_FILE:
1215 			headerfilename = arg;
1216 			break;
1217 
1218 		case OPT_META_ECS:
1219 			usemecs = true;
1220 			break;
1221 
1222 		case OPT_NO_META_ECS:
1223 			usemecs = false;
1224 			break;
1225 
1226 		case OPT_PREPROCDEFINE:
1227 			{
1228 				/* arg is "symbol" or "symbol=definition". */
1229 				char *def;
1230 
1231 				for (def = arg;
1232 				    *def != '\0' && *def != '='; ++def);
1233 
1234 				buf_strappend(&userdef_buf, "#define ");
1235 				if (*def == '\0') {
1236 					buf_strappend(&userdef_buf, arg);
1237 					buf_strappend(&userdef_buf,
1238 					    " 1\n");
1239 				} else {
1240 					buf_strnappend(&userdef_buf, arg,
1241 					    def - arg);
1242 					buf_strappend(&userdef_buf, " ");
1243 					buf_strappend(&userdef_buf,
1244 					    def + 1);
1245 					buf_strappend(&userdef_buf, "\n");
1246 				}
1247 			}
1248 			break;
1249 
1250 		case OPT_READ:
1251 			use_read = true;
1252 			break;
1253 
1254 		case OPT_STACK:
1255 			//buf_strdefine(&userdef_buf, "YY_STACK_USED", "1");
1256 			buf_m4_define(&m4defs_buf, "M4_YY_STACK_USED", 0);
1257 			break;
1258 
1259 		case OPT_STDINIT:
1260 			do_stdinit = true;
1261 			break;
1262 
1263 		case OPT_NO_STDINIT:
1264 			do_stdinit = false;
1265 			break;
1266 
1267 		case OPT_YYCLASS:
1268 			yyclass = arg;
1269 			break;
1270 
1271 		case OPT_YYLINENO:
1272 			do_yylineno = true;
1273 			break;
1274 
1275 		case OPT_NO_YYLINENO:
1276 			do_yylineno = false;
1277 			break;
1278 
1279 		case OPT_YYWRAP:
1280 			do_yywrap = true;
1281 			break;
1282 
1283 		case OPT_NO_YYWRAP:
1284 			do_yywrap = false;
1285 			break;
1286 
1287 		case OPT_YYMORE:
1288 			yymore_really_used = true;
1289 			break;
1290 
1291 		case OPT_NO_YYMORE:
1292 			yymore_really_used = false;
1293 			break;
1294 
1295 		case OPT_REJECT:
1296 			reject_really_used = true;
1297 			break;
1298 
1299 		case OPT_NO_REJECT:
1300 			reject_really_used = false;
1301 			break;
1302 
1303 		case OPT_NO_ANSI_FUNC_DEFS:
1304 			ansi_func_defs = false;
1305 			break;
1306 
1307 		case OPT_NO_ANSI_FUNC_PROTOS:
1308 			ansi_func_protos = false;
1309 			break;
1310 
1311 		case OPT_NO_YY_PUSH_STATE:
1312 			//buf_strdefine(&userdef_buf, "YY_NO_PUSH_STATE", "1");
1313 			buf_m4_define(&m4defs_buf, "M4_YY_NO_PUSH_STATE", 0);
1314 			break;
1315 		case OPT_NO_YY_POP_STATE:
1316 			//buf_strdefine(&userdef_buf, "YY_NO_POP_STATE", "1");
1317 			buf_m4_define(&m4defs_buf, "M4_YY_NO_POP_STATE", 0);
1318 			break;
1319 		case OPT_NO_YY_TOP_STATE:
1320 			//buf_strdefine(&userdef_buf, "YY_NO_TOP_STATE", "1");
1321 			buf_m4_define(&m4defs_buf, "M4_YY_NO_TOP_STATE", 0);
1322 			break;
1323 		case OPT_NO_UNPUT:
1324 			//buf_strdefine(&userdef_buf, "YY_NO_UNPUT", "1");
1325 			buf_m4_define(&m4defs_buf, "M4_YY_NO_UNPUT", 0);
1326 			break;
1327 		case OPT_NO_YY_SCAN_BUFFER:
1328 			//buf_strdefine(&userdef_buf, "YY_NO_SCAN_BUFFER", "1");
1329 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SCAN_BUFFER", 0);
1330 			break;
1331 		case OPT_NO_YY_SCAN_BYTES:
1332 			//buf_strdefine(&userdef_buf, "YY_NO_SCAN_BYTES", "1");
1333 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SCAN_BYTES", 0);
1334 			break;
1335 		case OPT_NO_YY_SCAN_STRING:
1336 			//buf_strdefine(&userdef_buf, "YY_NO_SCAN_STRING", "1");
1337 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SCAN_STRING", 0);
1338 			break;
1339 		case OPT_NO_YYGET_EXTRA:
1340 			//buf_strdefine(&userdef_buf, "YY_NO_GET_EXTRA", "1");
1341 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_EXTRA", 0);
1342 			break;
1343 		case OPT_NO_YYSET_EXTRA:
1344 			//buf_strdefine(&userdef_buf, "YY_NO_SET_EXTRA", "1");
1345 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_EXTRA", 0);
1346 			break;
1347 		case OPT_NO_YYGET_LENG:
1348 			//buf_strdefine(&userdef_buf, "YY_NO_GET_LENG", "1");
1349 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LENG", 0);
1350 			break;
1351 		case OPT_NO_YYGET_TEXT:
1352 			//buf_strdefine(&userdef_buf, "YY_NO_GET_TEXT", "1");
1353 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_TEXT", 0);
1354 			break;
1355 		case OPT_NO_YYGET_LINENO:
1356 			//buf_strdefine(&userdef_buf, "YY_NO_GET_LINENO", "1");
1357 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LINENO", 0);
1358 			break;
1359 		case OPT_NO_YYSET_LINENO:
1360 			//buf_strdefine(&userdef_buf, "YY_NO_SET_LINENO", "1");
1361 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_LINENO", 0);
1362 			break;
1363 		case OPT_NO_YYGET_IN:
1364 			//buf_strdefine(&userdef_buf, "YY_NO_GET_IN", "1");
1365 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_IN", 0);
1366 			break;
1367 		case OPT_NO_YYSET_IN:
1368 			//buf_strdefine(&userdef_buf, "YY_NO_SET_IN", "1");
1369 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_IN", 0);
1370 			break;
1371 		case OPT_NO_YYGET_OUT:
1372 			//buf_strdefine(&userdef_buf, "YY_NO_GET_OUT", "1");
1373 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_OUT", 0);
1374 			break;
1375 		case OPT_NO_YYSET_OUT:
1376 			//buf_strdefine(&userdef_buf, "YY_NO_SET_OUT", "1");
1377 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_OUT", 0);
1378 			break;
1379 		case OPT_NO_YYGET_LVAL:
1380 			//buf_strdefine(&userdef_buf, "YY_NO_GET_LVAL", "1");
1381 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LVAL", 0);
1382 			break;
1383 		case OPT_NO_YYSET_LVAL:
1384 			//buf_strdefine(&userdef_buf, "YY_NO_SET_LVAL", "1");
1385 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_LVAL", 0);
1386 			break;
1387 		case OPT_NO_YYGET_LLOC:
1388 			//buf_strdefine(&userdef_buf, "YY_NO_GET_LLOC", "1");
1389 			buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LLOC", 0);
1390 			break;
1391 		case OPT_NO_YYSET_LLOC:
1392 			//buf_strdefine(&userdef_buf, "YY_NO_SET_LLOC", "1");
1393 			buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_LLOC", 0);
1394 			break;
1395 
1396 		}		/* switch */
1397 	}			/* while scanopt() */
1398 
1399 	scanopt_destroy(sopt);
1400 
1401 	num_input_files = argc - optind;
1402 	input_files = argv + optind;
1403 	set_input_file(num_input_files > 0 ? input_files[0] : NULL);
1404 
1405 	lastccl = lastsc = lastdfa = lastnfa = 0;
1406 	num_rules = num_eof_rules = default_rule = 0;
1407 	numas = numsnpairs = tmpuses = 0;
1408 	numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst =
1409 	    0;
1410 	numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
1411 	num_backing_up = onesp = numprots = 0;
1412 	variable_trailing_context_rules = bol_needed = false;
1413 
1414 	linenum = sectnum = 1;
1415 	firstprot = NIL;
1416 
1417 	/*
1418 	 * Used in mkprot() so that the first proto goes in slot 1 of the
1419 	 * proto queue.
1420 	 */
1421 	lastprot = 1;
1422 
1423 	set_up_initial_allocations();
1424 }
1425 
1426 
1427 /* readin - read in the rules section of the input file(s) */
1428 
1429 void
1430 readin()
1431 {
1432 	static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;";
1433 	static char yy_nostdinit[] =
1434 	"FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;";
1435 
1436 	line_directive_out((FILE *) 0, 1);
1437 
1438 	if (yyparse()) {
1439 		pinpoint_message(_("fatal parse error"));
1440 		flexend(1);
1441 	}
1442 	if (syntaxerror)
1443 		flexend(1);
1444 
1445 	/*
1446 	 * If the user explicitly requested posix compatibility by specifing
1447 	 * the posix-compat option, then we check for conflicting options.
1448 	 * However, if the POSIXLY_CORRECT variable is set, then we quietly
1449 	 * make flex as posix-compatible as possible.  This is the
1450 	 * recommended behavior according to the GNU Coding Standards.
1451 	 *
1452 	 * Note: The posix option was added to flex to provide the posix
1453 	 * behavior of the repeat operator in regular expressions, e.g.,
1454 	 * `ab{3}'
1455 	 */
1456 	if (posix_compat) {
1457 		/*
1458 		 * TODO: This is where we try to make flex behave according
1459 		 * to posiz, AND check for conflicting options. How far
1460 		 * should we go with this? Should we disable all the neat-o
1461 		 * flex features?
1462 		 */
1463 		/*
1464 		 * Update: Estes says no, since other flex features don't
1465 		 * violate posix.
1466 		 */
1467 	}
1468 	if (getenv("POSIXLY_CORRECT")) {
1469 		posix_compat = true;
1470 	}
1471 	if (backing_up_report) {
1472 		backing_up_file = fopen(backing_name, "w");
1473 		if (backing_up_file == NULL)
1474 			lerrsf(_
1475 			    ("could not create backing-up info file %s"),
1476 			    backing_name);
1477 	} else
1478 		backing_up_file = NULL;
1479 
1480 	if (yymore_really_used == true)
1481 		yymore_used = true;
1482 	else if (yymore_really_used == false)
1483 		yymore_used = false;
1484 
1485 	if (reject_really_used == true)
1486 		reject = true;
1487 	else if (reject_really_used == false)
1488 		reject = false;
1489 
1490 	if (performance_report > 0) {
1491 		if (lex_compat) {
1492 			fprintf(stderr,
1493 			    _
1494 			    ("-l AT&T lex compatibility option entails a large performance penalty\n"));
1495 			fprintf(stderr,
1496 			    _
1497 			    (" and may be the actual source of other reported performance penalties\n"));
1498 		} else if (do_yylineno) {
1499 			fprintf(stderr,
1500 			    _
1501 			    ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n"));
1502 		}
1503 		if (performance_report > 1) {
1504 			if (interactive)
1505 				fprintf(stderr,
1506 				    _
1507 				    ("-I (interactive) entails a minor performance penalty\n"));
1508 
1509 			if (yymore_used)
1510 				fprintf(stderr,
1511 				    _
1512 				    ("yymore() entails a minor performance penalty\n"));
1513 		}
1514 		if (reject)
1515 			fprintf(stderr,
1516 			    _
1517 			    ("REJECT entails a large performance penalty\n"));
1518 
1519 		if (variable_trailing_context_rules)
1520 			fprintf(stderr,
1521 			    _
1522 			    ("Variable trailing context rules entail a large performance penalty\n"));
1523 	}
1524 	if (reject)
1525 		real_reject = true;
1526 
1527 	if (variable_trailing_context_rules)
1528 		reject = true;
1529 
1530 	if ((fulltbl || fullspd) && reject) {
1531 		if (real_reject)
1532 			flexerror(_
1533 			    ("REJECT cannot be used with -f or -F"));
1534 		else if (do_yylineno)
1535 			flexerror(_
1536 			    ("%option yylineno cannot be used with REJECT"));
1537 		else
1538 			flexerror(_
1539 			    ("variable trailing context rules cannot be used with -f or -F"));
1540 	}
1541 	if (reject) {
1542 		out_m4_define("M4_YY_USES_REJECT", NULL);
1543 		//outn("\n#define YY_USES_REJECT");
1544 	}
1545 	if (!do_yywrap) {
1546 		if (!C_plus_plus) {
1547 			if (reentrant)
1548 				outn("\n#define yywrap(yyscanner) 1");
1549 			else
1550 				outn("\n#define yywrap() 1");
1551 		}
1552 		outn("#define YY_SKIP_YYWRAP");
1553 	}
1554 	if (ddebug)
1555 		outn("\n#define FLEX_DEBUG");
1556 
1557 	OUT_BEGIN_CODE();
1558 	if (csize == 256)
1559 		outn("typedef unsigned char YY_CHAR;");
1560 	else
1561 		outn("typedef char YY_CHAR;");
1562 	OUT_END_CODE();
1563 
1564 	if (C_plus_plus) {
1565 		outn("#define yytext_ptr yytext");
1566 
1567 		if (interactive)
1568 			outn("#define YY_INTERACTIVE");
1569 	} else {
1570 		OUT_BEGIN_CODE();
1571 		/* In reentrant scanner, stdinit is handled in flex.skl. */
1572 		if (do_stdinit) {
1573 			if (reentrant) {
1574 				outn("#define YY_STDINIT");
1575 			}
1576 			outn(yy_stdinit);
1577 		} else {
1578 			if (!reentrant)
1579 				outn(yy_nostdinit);
1580 		}
1581 		OUT_END_CODE();
1582 	}
1583 
1584 	OUT_BEGIN_CODE();
1585 	if (fullspd)
1586 		outn("typedef yyconst struct yy_trans_info *yy_state_type;");
1587 	else if (!C_plus_plus)
1588 		outn("typedef int yy_state_type;");
1589 	OUT_END_CODE();
1590 
1591 	if (lex_compat)
1592 		outn("#define YY_FLEX_LEX_COMPAT");
1593 
1594 	if (!C_plus_plus && !reentrant) {
1595 		outn("extern int yylineno;");
1596 		OUT_BEGIN_CODE();
1597 		outn("int yylineno = 1;");
1598 		OUT_END_CODE();
1599 	}
1600 	if (C_plus_plus) {
1601 		outn("\n#include <FlexLexer.h>");
1602 
1603 		if (!do_yywrap) {
1604 			outn("\nint yyFlexLexer::yywrap() { return 1; }");
1605 		}
1606 		if (yyclass) {
1607 			outn("int yyFlexLexer::yylex()");
1608 			outn("\t{");
1609 			outn("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );");
1610 			outn("\treturn 0;");
1611 			outn("\t}");
1612 
1613 			out_str("\n#define YY_DECL int %s::yylex()\n",
1614 			    yyclass);
1615 		}
1616 	} else {
1617 
1618 		/*
1619 		 * Watch out: yytext_ptr is a variable when yytext is an
1620 		 * array, but it's a macro when yytext is a pointer.
1621 		 */
1622 		if (yytext_is_array) {
1623 			if (!reentrant)
1624 				outn("extern char yytext[];\n");
1625 		} else {
1626 			if (reentrant) {
1627 				outn("#define yytext_ptr yytext_r");
1628 			} else {
1629 				outn("extern char *yytext;");
1630 				outn("#define yytext_ptr yytext");
1631 			}
1632 		}
1633 
1634 		if (yyclass)
1635 			flexerror(_
1636 			    ("%option yyclass only meaningful for C++ scanners"));
1637 	}
1638 
1639 	if (useecs)
1640 		numecs = cre8ecs(nextecm, ecgroup, csize);
1641 	else
1642 		numecs = csize;
1643 
1644 	/* Now map the equivalence class for NUL to its expected place. */
1645 	ecgroup[0] = ecgroup[csize];
1646 	NUL_ec = ABS(ecgroup[0]);
1647 
1648 	if (useecs)
1649 		ccl2ecl();
1650 }
1651 
1652 
1653 /* set_up_initial_allocations - allocate memory for internal tables */
1654 
1655 void
1656 set_up_initial_allocations()
1657 {
1658 	maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS);
1659 	current_mns = INITIAL_MNS;
1660 	firstst = allocate_integer_array(current_mns);
1661 	lastst = allocate_integer_array(current_mns);
1662 	finalst = allocate_integer_array(current_mns);
1663 	transchar = allocate_integer_array(current_mns);
1664 	trans1 = allocate_integer_array(current_mns);
1665 	trans2 = allocate_integer_array(current_mns);
1666 	accptnum = allocate_integer_array(current_mns);
1667 	assoc_rule = allocate_integer_array(current_mns);
1668 	state_type = allocate_integer_array(current_mns);
1669 
1670 	current_max_rules = INITIAL_MAX_RULES;
1671 	rule_type = allocate_integer_array(current_max_rules);
1672 	rule_linenum = allocate_integer_array(current_max_rules);
1673 	rule_useful = allocate_integer_array(current_max_rules);
1674 	rule_has_nl = allocate_bool_array(current_max_rules);
1675 
1676 	current_max_scs = INITIAL_MAX_SCS;
1677 	scset = allocate_integer_array(current_max_scs);
1678 	scbol = allocate_integer_array(current_max_scs);
1679 	scxclu = allocate_integer_array(current_max_scs);
1680 	sceof = allocate_integer_array(current_max_scs);
1681 	scname = allocate_char_ptr_array(current_max_scs);
1682 
1683 	current_maxccls = INITIAL_MAX_CCLS;
1684 	cclmap = allocate_integer_array(current_maxccls);
1685 	ccllen = allocate_integer_array(current_maxccls);
1686 	cclng = allocate_integer_array(current_maxccls);
1687 	ccl_has_nl = allocate_bool_array(current_maxccls);
1688 
1689 	current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
1690 	ccltbl = allocate_Character_array(current_max_ccl_tbl_size);
1691 
1692 	current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
1693 
1694 	current_max_xpairs = INITIAL_MAX_XPAIRS;
1695 	nxt = allocate_integer_array(current_max_xpairs);
1696 	chk = allocate_integer_array(current_max_xpairs);
1697 
1698 	current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
1699 	tnxt = allocate_integer_array(current_max_template_xpairs);
1700 
1701 	current_max_dfas = INITIAL_MAX_DFAS;
1702 	base = allocate_integer_array(current_max_dfas);
1703 	def = allocate_integer_array(current_max_dfas);
1704 	dfasiz = allocate_integer_array(current_max_dfas);
1705 	accsiz = allocate_integer_array(current_max_dfas);
1706 	dhash = allocate_integer_array(current_max_dfas);
1707 	dss = allocate_int_ptr_array(current_max_dfas);
1708 	dfaacc = allocate_dfaacc_union(current_max_dfas);
1709 
1710 	nultrans = (int *) 0;
1711 }
1712 
1713 
1714 /* extracts basename from path, optionally stripping the extension "\.*"
1715  * (same concept as /bin/sh `basename`, but different handling of extension). */
1716 static char *
1717 basename2(path, strip_ext)
1718 	char *path;
1719 	int strip_ext;		/* boolean */
1720 {
1721 	char *b, *e = 0;
1722 
1723 	b = path;
1724 	for (b = path; *path; path++)
1725 		if (*path == '/')
1726 			b = path + 1;
1727 		else if (*path == '.')
1728 			e = path;
1729 
1730 	if (strip_ext && e && e > b)
1731 		*e = '\0';
1732 	return b;
1733 }
1734 
1735 void
1736 usage(void)
1737 {
1738 	extern char *__progname;
1739 
1740 	(void) fprintf(stderr,
1741 		"usage: %s [-78BbFfhIiLlnpsTtVvw+?] [-C[aeFfmr]] [--help]"
1742 		" [--version]\n"
1743 		"\t[-ooutput] [-Pprefix] [-Sskeleton] [file ...]\n", __progname);
1744 }
1745