[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Annotation of src/usr.bin/lex/main.c, Revision 1.4

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