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