Annotation of src/usr.bin/lex/main.c, Revision 1.15
1.15 ! deraadt 1: /* $OpenBSD: main.c,v 1.14 2014/03/16 18:38:30 guenther Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: /* flex - tool to generate fast lexical analyzers */
4:
5: /*-
6: * Copyright (c) 1990 The Regents of the University of California.
7: * All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * Vern Paxson.
11: *
12: * The United States Government has rights in this work pursuant
13: * to contract no. DE-AC03-76SF00098 between the United States
14: * Department of Energy and the University of California.
15: *
1.5 deraadt 16: * Redistribution and use in source and binary forms, with or without
1.9 millert 17: * modification, are permitted provided that the following conditions
18: * are met:
19: *
20: * 1. Redistributions of source code must retain the above copyright
21: * notice, this list of conditions and the following disclaimer.
22: * 2. Redistributions in binary form must reproduce the above copyright
23: * notice, this list of conditions and the following disclaimer in the
24: * documentation and/or other materials provided with the distribution.
25: *
26: * Neither the name of the University nor the names of its contributors
27: * may be used to endorse or promote products derived from this software
28: * without specific prior written permission.
29: *
30: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
31: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
32: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33: * PURPOSE.
1.1 deraadt 34: */
35:
1.15 ! deraadt 36: /* $Header: /cvs/src/usr.bin/lex/main.c,v 1.14 2014/03/16 18:38:30 guenther Exp $ */
1.1 deraadt 37:
38:
39: #include "flexdef.h"
40: #include "version.h"
41:
42: static char flex_version[] = FLEX_VERSION;
43:
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:
51: #ifdef NEED_ARGV_FIXUP
52: extern void argv_fixup PROTO((int *, char ***));
53: #endif
54:
55:
56: /* these globals are all defined and commented in flexdef.h */
57: int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt;
58: int interactive, caseins, lex_compat, do_yylineno, useecs, fulltbl, usemecs;
59: int fullspd, gen_line_dirs, performance_report, backing_up_report;
60: int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize;
61: int yymore_used, reject, real_reject, continued_action, in_rule;
62: int yymore_really_used, reject_really_used;
63: int datapos, dataline, linenum, out_linenum;
64: FILE *skelfile = NULL;
65: int skel_ind = 0;
66: char *action_array;
67: int action_size, defs1_offset, prolog_offset, action_offset, action_index;
68: char *infilename = NULL, *outfilename = NULL;
69: int did_outfilename;
70: char *prefix, *yyclass;
71: int do_stdinit, use_stdout;
72: int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
73: int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
74: int current_mns, current_max_rules;
75: int num_rules, num_eof_rules, default_rule, lastnfa;
76: int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2;
77: int *accptnum, *assoc_rule, *state_type;
78: int *rule_type, *rule_linenum, *rule_useful;
79: int current_state_type;
80: int variable_trailing_context_rules;
81: int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
82: int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
83: int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
84: int tecbck[CSIZE + 1];
85: int lastsc, *scset, *scbol, *scxclu, *sceof;
86: int current_max_scs;
87: char **scname;
88: int current_max_dfa_size, current_max_xpairs;
89: int current_max_template_xpairs, current_max_dfas;
90: int lastdfa, *nxt, *chk, *tnxt;
91: int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz;
92: union dfaacc_union *dfaacc;
93: int *accsiz, *dhash, numas;
94: int numsnpairs, jambase, jamstate;
95: int lastccl, *cclmap, *ccllen, *cclng, cclreuse;
96: int current_maxccls, current_max_ccl_tbl_size;
97: Char *ccltbl;
98: char nmstr[MAXLINE];
99: int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
100: int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
101: int num_backing_up, bol_needed;
102: FILE *backing_up_file;
103: int end_of_buffer_state;
104: char **input_files;
105: int num_input_files;
106:
107: /* Make sure program_name is initialized so we don't crash if writing
108: * out an error message before getting the program name from argv[0].
109: */
110: char *program_name = "flex";
111:
112: #ifndef SHORT_FILE_NAMES
1.13 guenther 113: static const char outfile_template[] = "lex.%s.%s";
114: static const char backing_name[] = "lex.backup";
1.1 deraadt 115: #else
1.13 guenther 116: static const char outfile_template[] = "lex%s.%s";
117: static const char backing_name[] = "lex.bck";
1.1 deraadt 118: #endif
119:
120: #ifdef THINK_C
121: #include <console.h>
122: #endif
123:
124: #ifdef MS_DOS
125: extern unsigned _stklen = 16384;
126: #endif
127:
128: static char outfile_path[MAXLINE];
129: static int outfile_created = 0;
130: static char *skelname = NULL;
131:
132:
133: int main( argc, argv )
134: int argc;
135: char **argv;
136: {
137: int i;
1.15 ! deraadt 138:
! 139: if (pledge("stdio rpath wpath cpath", NULL) == -1)
! 140: {
! 141: fprintf( stderr, _( "%s: pledge\n" ),
! 142: program_name);
! 143: exit(1);
! 144: }
1.1 deraadt 145:
146: #ifdef THINK_C
147: argc = ccommand( &argv );
148: #endif
149: #ifdef NEED_ARGV_FIXUP
150: argv_fixup( &argc, &argv );
151: #endif
152:
153: flexinit( argc, argv );
154:
155: readin();
156:
157: ntod();
158:
159: for ( i = 1; i <= num_rules; ++i )
160: if ( ! rule_useful[i] && i != default_rule )
161: line_warning( _( "rule cannot be matched" ),
162: rule_linenum[i] );
163:
164: if ( spprdflt && ! reject && rule_useful[default_rule] )
165: line_warning(
166: _( "-s option given but default rule can be matched" ),
167: rule_linenum[default_rule] );
168:
169: /* Generate the C state transition tables from the DFA. */
170: make_tables();
171:
172: /* Note, flexend does not return. It exits with its argument
173: * as status.
174: */
175: flexend( 0 );
176:
1.14 guenther 177: return 0;
1.1 deraadt 178: }
179:
180:
181: /* check_options - check user-specified options */
182:
183: void check_options()
184: {
185: int i;
186:
187: if ( lex_compat )
188: {
189: if ( C_plus_plus )
190: flexerror( _( "Can't use -+ with -l option" ) );
191:
192: if ( fulltbl || fullspd )
193: flexerror( _( "Can't use -f or -F with -l option" ) );
194:
195: /* Don't rely on detecting use of yymore() and REJECT,
196: * just assume they'll be used.
197: */
198: yymore_really_used = reject_really_used = true;
199:
200: yytext_is_array = true;
201: do_yylineno = true;
202: use_read = false;
203: }
204:
205: if ( do_yylineno )
206: /* This should really be "maintain_backup_tables = true" */
207: reject_really_used = true;
208:
209: if ( csize == unspecified )
210: {
211: if ( (fulltbl || fullspd) && ! useecs )
212: csize = DEFAULT_CSIZE;
213: else
214: csize = CSIZE;
215: }
216:
217: if ( interactive == unspecified )
218: {
219: if ( fulltbl || fullspd )
220: interactive = false;
221: else
222: interactive = true;
223: }
224:
225: if ( fulltbl || fullspd )
226: {
227: if ( usemecs )
228: flexerror(
229: _( "-Cf/-CF and -Cm don't make sense together" ) );
230:
231: if ( interactive )
232: flexerror( _( "-Cf/-CF and -I are incompatible" ) );
233:
234: if ( lex_compat )
235: flexerror(
236: _( "-Cf/-CF are incompatible with lex-compatibility mode" ) );
237:
238: if ( do_yylineno )
239: flexerror(
240: _( "-Cf/-CF and %option yylineno are incompatible" ) );
241:
242: if ( fulltbl && fullspd )
243: flexerror( _( "-Cf and -CF are mutually exclusive" ) );
244: }
245:
246: if ( C_plus_plus && fullspd )
247: flexerror( _( "Can't use -+ with -CF option" ) );
248:
249: if ( C_plus_plus && yytext_is_array )
250: {
251: warn( _( "%array incompatible with -+ option" ) );
252: yytext_is_array = false;
253: }
254:
255: if ( useecs )
256: { /* Set up doubly-linked equivalence classes. */
257:
258: /* We loop all the way up to csize, since ecgroup[csize] is
259: * the position used for NUL characters.
260: */
261: ecgroup[1] = NIL;
262:
263: for ( i = 2; i <= csize; ++i )
264: {
265: ecgroup[i] = i - 1;
266: nextecm[i - 1] = i;
267: }
268:
269: nextecm[csize] = NIL;
270: }
271:
272: else
273: {
274: /* Put everything in its own equivalence class. */
275: for ( i = 1; i <= csize; ++i )
276: {
277: ecgroup[i] = i;
278: nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */
279: }
280: }
281:
282: if ( ! use_stdout )
283: {
284: FILE *prev_stdout;
285:
286: if ( ! did_outfilename )
287: {
288: char *suffix;
289:
290: if ( C_plus_plus )
291: suffix = "cc";
292: else
293: suffix = "c";
294:
1.8 deraadt 295: snprintf( outfile_path, sizeof outfile_path,
296: outfile_template, prefix, suffix );
1.1 deraadt 297:
298: outfilename = outfile_path;
299: }
300:
301: prev_stdout = freopen( outfilename, "w", stdout );
302:
303: if ( prev_stdout == NULL )
304: lerrsf( _( "could not create %s" ), outfilename );
305:
306: outfile_created = 1;
307: }
308:
309: if ( skelname && (skelfile = fopen( skelname, "r" )) == NULL )
310: lerrsf( _( "can't open skeleton file %s" ), skelname );
311:
312: if ( strcmp( prefix, "yy" ) )
313: {
314: #define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name )
315: if ( C_plus_plus )
316: GEN_PREFIX( "FlexLexer" );
317: else
318: {
319: GEN_PREFIX( "_create_buffer" );
320: GEN_PREFIX( "_delete_buffer" );
321: GEN_PREFIX( "_scan_buffer" );
322: GEN_PREFIX( "_scan_string" );
323: GEN_PREFIX( "_scan_bytes" );
324: GEN_PREFIX( "_flex_debug" );
325: GEN_PREFIX( "_init_buffer" );
326: GEN_PREFIX( "_flush_buffer" );
327: GEN_PREFIX( "_load_buffer_state" );
328: GEN_PREFIX( "_switch_to_buffer" );
329: GEN_PREFIX( "in" );
330: GEN_PREFIX( "leng" );
331: GEN_PREFIX( "lex" );
332: GEN_PREFIX( "out" );
333: GEN_PREFIX( "restart" );
334: GEN_PREFIX( "text" );
335:
336: if ( do_yylineno )
337: GEN_PREFIX( "lineno" );
338: }
339:
340: if ( do_yywrap )
341: GEN_PREFIX( "wrap" );
342:
343: outn( "" );
344: }
345:
346: if ( did_outfilename )
347: line_directive_out( stdout, 0 );
348:
349: skelout();
350: }
351:
352:
353: /* flexend - terminate flex
354: *
355: * note
356: * This routine does not return.
357: */
358:
359: void flexend( exit_status )
360: int exit_status;
361:
362: {
363: int tblsiz;
364: int unlink();
365:
366: if ( skelfile != NULL )
367: {
368: if ( ferror( skelfile ) )
369: lerrsf( _( "input error reading skeleton file %s" ),
370: skelname );
371:
372: else if ( fclose( skelfile ) )
373: lerrsf( _( "error closing skeleton file %s" ),
374: skelname );
375: }
376:
377: if ( exit_status != 0 && outfile_created )
378: {
379: if ( ferror( stdout ) )
380: lerrsf( _( "error writing output file %s" ),
381: outfilename );
382:
383: else if ( fclose( stdout ) )
384: lerrsf( _( "error closing output file %s" ),
385: outfilename );
386:
387: else if ( unlink( outfilename ) )
388: lerrsf( _( "error deleting output file %s" ),
389: outfilename );
390: }
391:
392: if ( backing_up_report && backing_up_file )
393: {
394: if ( num_backing_up == 0 )
395: fprintf( backing_up_file, _( "No backing up.\n" ) );
396: else if ( fullspd || fulltbl )
397: fprintf( backing_up_file,
398: _( "%d backing up (non-accepting) states.\n" ),
399: num_backing_up );
400: else
401: fprintf( backing_up_file,
402: _( "Compressed tables always back up.\n" ) );
403:
404: if ( ferror( backing_up_file ) )
405: lerrsf( _( "error writing backup file %s" ),
406: backing_name );
407:
408: else if ( fclose( backing_up_file ) )
409: lerrsf( _( "error closing backup file %s" ),
410: backing_name );
411: }
412:
413: if ( printstats )
414: {
415: fprintf( stderr, _( "%s version %s usage statistics:\n" ),
416: program_name, flex_version );
417:
418: fprintf( stderr, _( " scanner options: -" ) );
419:
420: if ( C_plus_plus )
421: putc( '+', stderr );
422: if ( backing_up_report )
423: putc( 'b', stderr );
424: if ( ddebug )
425: putc( 'd', stderr );
426: if ( caseins )
427: putc( 'i', stderr );
428: if ( lex_compat )
429: putc( 'l', stderr );
430: if ( performance_report > 0 )
431: putc( 'p', stderr );
432: if ( performance_report > 1 )
433: putc( 'p', stderr );
434: if ( spprdflt )
435: putc( 's', stderr );
436: if ( use_stdout )
437: putc( 't', stderr );
438: if ( printstats )
439: putc( 'v', stderr ); /* always true! */
440: if ( nowarn )
441: putc( 'w', stderr );
442: if ( interactive == false )
443: putc( 'B', stderr );
444: if ( interactive == true )
445: putc( 'I', stderr );
446: if ( ! gen_line_dirs )
447: putc( 'L', stderr );
448: if ( trace )
449: putc( 'T', stderr );
450:
451: if ( csize == unspecified )
452: /* We encountered an error fairly early on, so csize
453: * never got specified. Define it now, to prevent
454: * bogus table sizes being written out below.
455: */
456: csize = 256;
457:
458: if ( csize == 128 )
459: putc( '7', stderr );
460: else
461: putc( '8', stderr );
462:
463: fprintf( stderr, " -C" );
464:
465: if ( long_align )
466: putc( 'a', stderr );
467: if ( fulltbl )
468: putc( 'f', stderr );
469: if ( fullspd )
470: putc( 'F', stderr );
471: if ( useecs )
472: putc( 'e', stderr );
473: if ( usemecs )
474: putc( 'm', stderr );
475: if ( use_read )
476: putc( 'r', stderr );
477:
478: if ( did_outfilename )
479: fprintf( stderr, " -o%s", outfilename );
480:
481: if ( skelname )
482: fprintf( stderr, " -S%s", skelname );
483:
484: if ( strcmp( prefix, "yy" ) )
485: fprintf( stderr, " -P%s", prefix );
486:
487: putc( '\n', stderr );
488:
489: fprintf( stderr, _( " %d/%d NFA states\n" ),
490: lastnfa, current_mns );
491: fprintf( stderr, _( " %d/%d DFA states (%d words)\n" ),
492: lastdfa, current_max_dfas, totnst );
493: fprintf( stderr, _( " %d rules\n" ),
494: num_rules + num_eof_rules - 1 /* - 1 for def. rule */ );
495:
496: if ( num_backing_up == 0 )
497: fprintf( stderr, _( " No backing up\n" ) );
498: else if ( fullspd || fulltbl )
499: fprintf( stderr,
500: _( " %d backing-up (non-accepting) states\n" ),
501: num_backing_up );
502: else
503: fprintf( stderr,
504: _( " Compressed tables always back-up\n" ) );
505:
506: if ( bol_needed )
507: fprintf( stderr,
508: _( " Beginning-of-line patterns used\n" ) );
509:
510: fprintf( stderr, _( " %d/%d start conditions\n" ), lastsc,
511: current_max_scs );
512: fprintf( stderr,
513: _( " %d epsilon states, %d double epsilon states\n" ),
514: numeps, eps2 );
515:
516: if ( lastccl == 0 )
517: fprintf( stderr, _( " no character classes\n" ) );
518: else
519: fprintf( stderr,
520: _( " %d/%d character classes needed %d/%d words of storage, %d reused\n" ),
521: lastccl, current_maxccls,
522: cclmap[lastccl] + ccllen[lastccl],
523: current_max_ccl_tbl_size, cclreuse );
524:
525: fprintf( stderr, _( " %d state/nextstate pairs created\n" ),
526: numsnpairs );
527: fprintf( stderr, _( " %d/%d unique/duplicate transitions\n" ),
528: numuniq, numdup );
529:
530: if ( fulltbl )
531: {
532: tblsiz = lastdfa * numecs;
533: fprintf( stderr, _( " %d table entries\n" ), tblsiz );
534: }
535:
536: else
537: {
538: tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
539:
540: fprintf( stderr,
541: _( " %d/%d base-def entries created\n" ),
542: lastdfa + numtemps, current_max_dfas );
543: fprintf( stderr,
544: _( " %d/%d (peak %d) nxt-chk entries created\n" ),
545: tblend, current_max_xpairs, peakpairs );
546: fprintf( stderr,
547: _( " %d/%d (peak %d) template nxt-chk entries created\n" ),
548: numtemps * nummecs,
549: current_max_template_xpairs,
550: numtemps * numecs );
551: fprintf( stderr, _( " %d empty table entries\n" ),
552: nummt );
553: fprintf( stderr, _( " %d protos created\n" ),
554: numprots );
555: fprintf( stderr,
556: _( " %d templates created, %d uses\n" ),
557: numtemps, tmpuses );
558: }
559:
560: if ( useecs )
561: {
562: tblsiz = tblsiz + csize;
563: fprintf( stderr,
564: _( " %d/%d equivalence classes created\n" ),
565: numecs, csize );
566: }
567:
568: if ( usemecs )
569: {
570: tblsiz = tblsiz + numecs;
571: fprintf( stderr,
572: _( " %d/%d meta-equivalence classes created\n" ),
573: nummecs, csize );
574: }
575:
576: fprintf( stderr,
577: _( " %d (%d saved) hash collisions, %d DFAs equal\n" ),
578: hshcol, hshsave, dfaeql );
579: fprintf( stderr, _( " %d sets of reallocations needed\n" ),
580: num_reallocs );
581: fprintf( stderr, _( " %d total table entries needed\n" ),
582: tblsiz );
583: }
584:
585: exit( exit_status );
586: }
587:
588:
589: /* flexinit - initialize flex */
590:
591: void flexinit( argc, argv )
592: int argc;
593: char **argv;
594: {
595: int i, sawcmpflag;
1.3 millert 596: char *arg;
1.1 deraadt 597:
598: printstats = syntaxerror = trace = spprdflt = caseins = false;
599: lex_compat = C_plus_plus = backing_up_report = ddebug = fulltbl = false;
600: fullspd = long_align = nowarn = yymore_used = continued_action = false;
601: do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = false;
602: yymore_really_used = reject_really_used = unspecified;
603: interactive = csize = unspecified;
604: do_yywrap = gen_line_dirs = usemecs = useecs = true;
605: performance_report = 0;
606: did_outfilename = 0;
607: prefix = "yy";
608: yyclass = 0;
609: use_read = use_stdout = false;
610:
611: sawcmpflag = false;
612:
613: /* Initialize dynamic array for holding the rule actions. */
614: action_size = 2048; /* default size of action array in bytes */
615: action_array = allocate_character_array( action_size );
616: defs1_offset = prolog_offset = action_offset = action_index = 0;
617: action_array[0] = '\0';
618:
619: program_name = argv[0];
620:
621: if ( program_name[0] != '\0' &&
622: program_name[strlen( program_name ) - 1] == '+' )
623: C_plus_plus = true;
624:
625: /* read flags */
626: for ( --argc, ++argv; argc ; --argc, ++argv )
627: {
628: arg = argv[0];
629:
630: if ( arg[0] != '-' || arg[1] == '\0' )
631: break;
632:
633: if ( arg[1] == '-' )
634: { /* --option */
635: if ( ! strcmp( arg, "--help" ) )
636: arg = "-h";
637:
638: else if ( ! strcmp( arg, "--version" ) )
639: arg = "-V";
640:
641: else if ( ! strcmp( arg, "--" ) )
642: { /* end of options */
643: --argc;
644: ++argv;
645: break;
646: }
647: }
648:
649: for ( i = 1; arg[i] != '\0'; ++i )
650: switch ( arg[i] )
651: {
652: case '+':
653: C_plus_plus = true;
654: break;
655:
656: case 'B':
657: interactive = false;
658: break;
659:
660: case 'b':
661: backing_up_report = true;
662: break;
663:
664: case 'c':
665: break;
666:
667: case 'C':
668: if ( i != 1 )
669: flexerror(
670: _( "-C flag must be given separately" ) );
671:
672: if ( ! sawcmpflag )
673: {
674: useecs = false;
675: usemecs = false;
676: fulltbl = false;
677: sawcmpflag = true;
678: }
679:
680: for ( ++i; arg[i] != '\0'; ++i )
681: switch ( arg[i] )
682: {
683: case 'a':
684: long_align =
685: true;
686: break;
687:
688: case 'e':
689: useecs = true;
690: break;
691:
692: case 'F':
693: fullspd = true;
694: break;
695:
696: case 'f':
697: fulltbl = true;
698: break;
699:
700: case 'm':
701: usemecs = true;
702: break;
703:
704: case 'r':
705: use_read = true;
706: break;
707:
708: default:
709: lerrif(
710: _( "unknown -C option '%c'" ),
711: (int) arg[i] );
712: break;
713: }
714:
715: goto get_next_arg;
716:
717: case 'd':
718: ddebug = true;
719: break;
720:
721: case 'f':
722: useecs = usemecs = false;
723: use_read = fulltbl = true;
724: break;
725:
726: case 'F':
727: useecs = usemecs = false;
728: use_read = fullspd = true;
729: break;
730:
731: case '?':
732: case 'h':
733: usage();
734: exit( 0 );
735:
736: case 'I':
737: interactive = true;
738: break;
739:
740: case 'i':
741: caseins = true;
742: break;
743:
744: case 'l':
745: lex_compat = true;
746: break;
747:
748: case 'L':
749: gen_line_dirs = false;
750: break;
751:
752: case 'n':
753: /* Stupid do-nothing deprecated
754: * option.
755: */
756: break;
757:
758: case 'o':
759: if ( i != 1 )
760: flexerror(
761: _( "-o flag must be given separately" ) );
762:
763: outfilename = arg + i + 1;
764: did_outfilename = 1;
765: goto get_next_arg;
766:
767: case 'P':
768: if ( i != 1 )
769: flexerror(
770: _( "-P flag must be given separately" ) );
771:
772: prefix = arg + i + 1;
773: goto get_next_arg;
774:
775: case 'p':
776: ++performance_report;
777: break;
778:
779: case 'S':
780: if ( i != 1 )
781: flexerror(
782: _( "-S flag must be given separately" ) );
783:
784: skelname = arg + i + 1;
785: goto get_next_arg;
786:
787: case 's':
788: spprdflt = true;
789: break;
790:
791: case 't':
792: use_stdout = true;
793: break;
794:
795: case 'T':
796: trace = true;
797: break;
798:
799: case 'v':
800: printstats = true;
801: break;
802:
803: case 'V':
804: printf( _( "%s version %s\n" ),
805: program_name, flex_version );
806: exit( 0 );
807:
808: case 'w':
809: nowarn = true;
810: break;
811:
812: case '7':
813: csize = 128;
814: break;
815:
816: case '8':
817: csize = CSIZE;
818: break;
819:
820: default:
821: fprintf( stderr,
822: _( "%s: unknown flag '%c'. For usage, try\n\t%s --help\n" ),
823: program_name, (int) arg[i],
824: program_name );
825: exit( 1 );
826: }
827:
828: /* Used by -C, -S, -o, and -P flags in lieu of a "continue 2"
829: * control.
830: */
831: get_next_arg: ;
832: }
833:
834: num_input_files = argc;
835: input_files = argv;
836: set_input_file( num_input_files > 0 ? input_files[0] : NULL );
837:
838: lastccl = lastsc = lastdfa = lastnfa = 0;
839: num_rules = num_eof_rules = default_rule = 0;
840: numas = numsnpairs = tmpuses = 0;
841: numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0;
842: numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
843: num_backing_up = onesp = numprots = 0;
844: variable_trailing_context_rules = bol_needed = false;
845:
846: out_linenum = linenum = sectnum = 1;
847: firstprot = NIL;
848:
849: /* Used in mkprot() so that the first proto goes in slot 1
850: * of the proto queue.
851: */
852: lastprot = 1;
853:
854: set_up_initial_allocations();
855: }
856:
857:
858: /* readin - read in the rules section of the input file(s) */
859:
860: void readin()
861: {
862: static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;";
863: static char yy_nostdinit[] =
864: "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;";
865:
866: line_directive_out( (FILE *) 0, 1 );
867:
868: if ( yyparse() )
869: {
870: pinpoint_message( _( "fatal parse error" ) );
871: flexend( 1 );
872: }
873:
874: if ( syntaxerror )
875: flexend( 1 );
876:
877: if ( backing_up_report )
878: {
879: backing_up_file = fopen( backing_name, "w" );
880: if ( backing_up_file == NULL )
881: lerrsf(
882: _( "could not create backing-up info file %s" ),
883: backing_name );
884: }
885:
886: else
887: backing_up_file = NULL;
888:
889: if ( yymore_really_used == true )
890: yymore_used = true;
891: else if ( yymore_really_used == false )
892: yymore_used = false;
893:
894: if ( reject_really_used == true )
895: reject = true;
896: else if ( reject_really_used == false )
897: reject = false;
898:
899: if ( performance_report > 0 )
900: {
901: if ( lex_compat )
902: {
903: fprintf( stderr,
904: _( "-l AT&T lex compatibility option entails a large performance penalty\n" ) );
905: fprintf( stderr,
906: _( " and may be the actual source of other reported performance penalties\n" ) );
907: }
908:
909: else if ( do_yylineno )
910: {
911: fprintf( stderr,
912: _( "%%option yylineno entails a large performance penalty\n" ) );
913: }
914:
915: if ( performance_report > 1 )
916: {
917: if ( interactive )
918: fprintf( stderr,
919: _( "-I (interactive) entails a minor performance penalty\n" ) );
920:
921: if ( yymore_used )
922: fprintf( stderr,
923: _( "yymore() entails a minor performance penalty\n" ) );
924: }
925:
926: if ( reject )
927: fprintf( stderr,
928: _( "REJECT entails a large performance penalty\n" ) );
929:
930: if ( variable_trailing_context_rules )
931: fprintf( stderr,
932: _( "Variable trailing context rules entail a large performance penalty\n" ) );
933: }
934:
935: if ( reject )
936: real_reject = true;
937:
938: if ( variable_trailing_context_rules )
939: reject = true;
940:
941: if ( (fulltbl || fullspd) && reject )
942: {
943: if ( real_reject )
944: flexerror(
945: _( "REJECT cannot be used with -f or -F" ) );
946: else if ( do_yylineno )
947: flexerror(
948: _( "%option yylineno cannot be used with -f or -F" ) );
949: else
950: flexerror(
951: _( "variable trailing context rules cannot be used with -f or -F" ) );
952: }
953:
954: if ( reject )
955: outn( "\n#define YY_USES_REJECT" );
956:
957: if ( ! do_yywrap )
958: {
959: outn( "\n#define yywrap() 1" );
960: outn( "#define YY_SKIP_YYWRAP" );
961: }
962:
963: if ( ddebug )
964: outn( "\n#define FLEX_DEBUG" );
965:
966: if ( csize == 256 )
967: outn( "typedef unsigned char YY_CHAR;" );
968: else
969: outn( "typedef char YY_CHAR;" );
970:
971: if ( C_plus_plus )
972: {
973: outn( "#define yytext_ptr yytext" );
974:
975: if ( interactive )
976: outn( "#define YY_INTERACTIVE" );
977: }
978:
979: else
980: {
981: if ( do_stdinit )
982: {
983: outn( "#ifdef VMS" );
984: outn( "#ifndef __VMS_POSIX" );
985: outn( yy_nostdinit );
986: outn( "#else" );
987: outn( yy_stdinit );
988: outn( "#endif" );
989: outn( "#else" );
990: outn( yy_stdinit );
991: outn( "#endif" );
992: }
993:
994: else
995: outn( yy_nostdinit );
996: }
997:
998: if ( fullspd )
999: outn( "typedef yyconst struct yy_trans_info *yy_state_type;" );
1000: else if ( ! C_plus_plus )
1001: outn( "typedef int yy_state_type;" );
1002:
1003: if ( ddebug )
1004: outn( "\n#define FLEX_DEBUG" );
1005:
1006: if ( lex_compat )
1007: outn( "#define YY_FLEX_LEX_COMPAT" );
1008:
1009: if ( do_yylineno && ! C_plus_plus )
1010: {
1011: outn( "extern int yylineno;" );
1012: outn( "int yylineno = 1;" );
1013: }
1014:
1015: if ( C_plus_plus )
1016: {
1.10 espie 1017: outn( "\n#include <FlexLexer.h>" );
1.1 deraadt 1018:
1019: if ( yyclass )
1020: {
1021: outn( "int yyFlexLexer::yylex()" );
1022: outn( "\t{" );
1023: outn(
1024: "\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );" );
1025: outn( "\treturn 0;" );
1026: outn( "\t}" );
1027:
1028: out_str( "\n#define YY_DECL int %s::yylex()\n",
1029: yyclass );
1030: }
1031: }
1032:
1033: else
1034: {
1035: if ( yytext_is_array )
1036: outn( "extern char yytext[];\n" );
1037:
1038: else
1039: {
1040: outn( "extern char *yytext;" );
1041: outn( "#define yytext_ptr yytext" );
1042: }
1043:
1044: if ( yyclass )
1045: flexerror(
1046: _( "%option yyclass only meaningful for C++ scanners" ) );
1047: }
1048:
1049: if ( useecs )
1050: numecs = cre8ecs( nextecm, ecgroup, csize );
1051: else
1052: numecs = csize;
1053:
1054: /* Now map the equivalence class for NUL to its expected place. */
1055: ecgroup[0] = ecgroup[csize];
1056: NUL_ec = ABS( ecgroup[0] );
1057:
1058: if ( useecs )
1059: ccl2ecl();
1060: }
1061:
1062:
1063: /* set_up_initial_allocations - allocate memory for internal tables */
1064:
1065: void set_up_initial_allocations()
1066: {
1067: current_mns = INITIAL_MNS;
1068: firstst = allocate_integer_array( current_mns );
1069: lastst = allocate_integer_array( current_mns );
1070: finalst = allocate_integer_array( current_mns );
1071: transchar = allocate_integer_array( current_mns );
1072: trans1 = allocate_integer_array( current_mns );
1073: trans2 = allocate_integer_array( current_mns );
1074: accptnum = allocate_integer_array( current_mns );
1075: assoc_rule = allocate_integer_array( current_mns );
1076: state_type = allocate_integer_array( current_mns );
1077:
1078: current_max_rules = INITIAL_MAX_RULES;
1079: rule_type = allocate_integer_array( current_max_rules );
1080: rule_linenum = allocate_integer_array( current_max_rules );
1081: rule_useful = allocate_integer_array( current_max_rules );
1082:
1083: current_max_scs = INITIAL_MAX_SCS;
1084: scset = allocate_integer_array( current_max_scs );
1085: scbol = allocate_integer_array( current_max_scs );
1086: scxclu = allocate_integer_array( current_max_scs );
1087: sceof = allocate_integer_array( current_max_scs );
1088: scname = allocate_char_ptr_array( current_max_scs );
1089:
1090: current_maxccls = INITIAL_MAX_CCLS;
1091: cclmap = allocate_integer_array( current_maxccls );
1092: ccllen = allocate_integer_array( current_maxccls );
1093: cclng = allocate_integer_array( current_maxccls );
1094:
1095: current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
1096: ccltbl = allocate_Character_array( current_max_ccl_tbl_size );
1097:
1098: current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
1099:
1100: current_max_xpairs = INITIAL_MAX_XPAIRS;
1101: nxt = allocate_integer_array( current_max_xpairs );
1102: chk = allocate_integer_array( current_max_xpairs );
1103:
1104: current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
1105: tnxt = allocate_integer_array( current_max_template_xpairs );
1106:
1107: current_max_dfas = INITIAL_MAX_DFAS;
1108: base = allocate_integer_array( current_max_dfas );
1109: def = allocate_integer_array( current_max_dfas );
1110: dfasiz = allocate_integer_array( current_max_dfas );
1111: accsiz = allocate_integer_array( current_max_dfas );
1112: dhash = allocate_integer_array( current_max_dfas );
1113: dss = allocate_int_ptr_array( current_max_dfas );
1114: dfaacc = allocate_dfaacc_union( current_max_dfas );
1115:
1116: nultrans = (int *) 0;
1117: }
1118:
1119:
1120: void usage()
1121: {
1122: FILE *f = stdout;
1123:
1124: fprintf( f,
1.12 jmc 1125: _( "%s [-bdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton]\n" ),
1.1 deraadt 1126: program_name );
1127: fprintf( f, _( "\t[--help --version] [file ...]\n" ) );
1128:
1129: fprintf( f, _( "\t-b generate backing-up information to %s\n" ),
1130: backing_name );
1131: fprintf( f, _( "\t-d turn on debug mode in generated scanner\n" ) );
1132: fprintf( f, _( "\t-f generate fast, large scanner\n" ) );
1133: fprintf( f, _( "\t-h produce this help message\n" ) );
1134: fprintf( f, _( "\t-i generate case-insensitive scanner\n" ) );
1135: fprintf( f, _( "\t-l maximal compatibility with original lex\n" ) );
1136: fprintf( f, _( "\t-n do-nothing POSIX option\n" ) );
1137: fprintf( f, _( "\t-p generate performance report to stderr\n" ) );
1138: fprintf( f,
1139: _( "\t-s suppress default rule to ECHO unmatched text\n" ) );
1140:
1141: if ( ! did_outfilename )
1142: {
1.8 deraadt 1143: snprintf( outfile_path, sizeof outfile_path, outfile_template,
1.1 deraadt 1144: prefix, C_plus_plus ? "cc" : "c" );
1145: outfilename = outfile_path;
1146: }
1147:
1148: fprintf( f,
1149: _( "\t-t write generated scanner on stdout instead of %s\n" ),
1150: outfilename );
1151:
1152: fprintf( f,
1153: _( "\t-v write summary of scanner statistics to f\n" ) );
1154: fprintf( f, _( "\t-w do not generate warnings\n" ) );
1155: fprintf( f, _( "\t-B generate batch scanner (opposite of -I)\n" ) );
1156: fprintf( f,
1157: _( "\t-F use alternative fast scanner representation\n" ) );
1158: fprintf( f,
1159: _( "\t-I generate interactive scanner (opposite of -B)\n" ) );
1160: fprintf( f, _( "\t-L suppress #line directives in scanner\n" ) );
1161: fprintf( f, _( "\t-T %s should run in trace mode\n" ), program_name );
1162: fprintf( f, _( "\t-V report %s version\n" ), program_name );
1163: fprintf( f, _( "\t-7 generate 7-bit scanner\n" ) );
1164: fprintf( f, _( "\t-8 generate 8-bit scanner\n" ) );
1165: fprintf( f, _( "\t-+ generate C++ scanner class\n" ) );
1166: fprintf( f, _( "\t-? produce this help message\n" ) );
1167: fprintf( f,
1168: _( "\t-C specify degree of table compression (default is -Cem):\n" ) );
1169: fprintf( f,
1170: _( "\t\t-Ca trade off larger tables for better memory alignment\n" ) );
1171: fprintf( f, _( "\t\t-Ce construct equivalence classes\n" ) );
1172: fprintf( f,
1173: _( "\t\t-Cf do not compress scanner tables; use -f representation\n" ) );
1174: fprintf( f,
1175: _( "\t\t-CF do not compress scanner tables; use -F representation\n" ) );
1176: fprintf( f, _( "\t\t-Cm construct meta-equivalence classes\n" ) );
1177: fprintf( f,
1178: _( "\t\t-Cr use read() instead of stdio for scanner input\n" ) );
1179: fprintf( f, _( "\t-o specify output filename\n" ) );
1180: fprintf( f, _( "\t-P specify scanner prefix other than \"yy\"\n" ) );
1181: fprintf( f, _( "\t-S specify skeleton file\n" ) );
1182: fprintf( f, _( "\t--help produce this help message\n" ) );
1183: fprintf( f, _( "\t--version report %s version\n" ), program_name );
1184: }