void check_char(int c) { if ( c >= CSIZE ) lerrsf( _( "bad character '%s' detected in check_char()" ), readable_form( c ) ); if ( c >= csize ) lerrsf( _( "scanner requires -8 flag to use the character %s" ), readable_form( c ) ); }
void readin(void) { static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; static char yy_nostdinit[] = "FILE *yyin = NULL, *yyout = NULL;"; line_directive_out( NULL, 1 ); if ( yyparse() ) { pinpoint_message( _( "fatal parse error" ) ); flexend( 1 ); } if ( syntaxerror ) flexend( 1 ); if ( backing_up_report ) { backing_up_file = fopen( backing_name, "w" ); if ( backing_up_file == NULL ) lerrsf( _( "could not create backing-up info file %s" ), backing_name ); } else backing_up_file = NULL; if ( yymore_really_used == true ) yymore_used = true; else if ( yymore_really_used == false ) yymore_used = false; if ( reject_really_used == true ) reject = true; else if ( reject_really_used == false ) reject = false; if ( performance_report > 0 ) { if ( lex_compat ) { fprintf( stderr, _( "-l AT&T lex compatibility option entails a large performance penalty\n" ) ); fprintf( stderr, _( " and may be the actual source of other reported performance penalties\n" ) ); } else if ( do_yylineno ) { fprintf( stderr, _( "%%option yylineno entails a large performance penalty\n" ) ); } if ( performance_report > 1 ) { if ( interactive ) fprintf( stderr, _( "-I (interactive) entails a minor performance penalty\n" ) ); if ( yymore_used ) fprintf( stderr, _( "yymore() entails a minor performance penalty\n" ) ); } if ( reject ) fprintf( stderr, _( "REJECT entails a large performance penalty\n" ) ); if ( variable_trailing_context_rules ) fprintf( stderr, _( "Variable trailing context rules entail a large performance penalty\n" ) ); } if ( reject ) real_reject = true; if ( variable_trailing_context_rules ) reject = true; if ( (fulltbl || fullspd) && reject ) { if ( real_reject ) flexerror( _( "REJECT cannot be used with -f or -F" ) ); else if ( do_yylineno ) flexerror( _( "%option yylineno cannot be used with -f or -F" ) ); else flexerror( _( "variable trailing context rules cannot be used with -f or -F" ) ); } if ( reject ) outn( "\n#define YY_USES_REJECT" ); if ( ! do_yywrap ) { outn( "\n#define yywrap() 1" ); outn( "#define YY_SKIP_YYWRAP" ); } if ( ddebug ) outn( "\n#define FLEX_DEBUG" ); if ( csize == 256 ) outn( "typedef unsigned char YY_CHAR;" ); else outn( "typedef char YY_CHAR;" ); if ( C_plus_plus ) { outn( "#define yytext_ptr yytext" ); if ( interactive ) outn( "#define YY_INTERACTIVE" ); } else { if ( do_stdinit ) { outn( yy_stdinit ); } else outn( yy_nostdinit ); } if ( fullspd ) outn( "typedef yyconst struct yy_trans_info *yy_state_type;" ); else if ( ! C_plus_plus ) outn( "typedef int yy_state_type;" ); if ( ddebug ) outn( "\n#define FLEX_DEBUG" ); if ( lex_compat ) outn( "#define YY_FLEX_LEX_COMPAT" ); if ( do_yylineno && ! C_plus_plus ) { outn( "extern int yylineno;" ); outn( "int yylineno = 1;" ); } if ( C_plus_plus ) { outn( "\n#include <FlexLexer.h>" ); if ( yyclass ) { outn( "int yyFlexLexer::yylex()" ); outn( "\t{" ); outn( "\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );" ); outn( "\treturn 0;" ); outn( "\t}" ); out_str( "\n#define YY_DECL int %s::yylex()\n", yyclass ); } } else { if ( yytext_is_array ) outn( "extern char yytext[];\n" ); else { outn( "extern char *yytext;" ); outn( "#define yytext_ptr yytext" ); } if ( yyclass ) flexerror( _( "%option yyclass only meaningful for C++ scanners" ) ); } if ( useecs ) numecs = cre8ecs( nextecm, ecgroup, csize ); else numecs = csize; /* Now map the equivalence class for NUL to its expected place. */ ecgroup[0] = ecgroup[csize]; NUL_ec = ABS( ecgroup[0] ); if ( useecs ) ccl2ecl(); }
/** Adjust the line numbers in the #line directives of the generated scanner. * After the m4 expansion, the line numbers are incorrect since the m4 macros * can add or remove lines. This only adjusts line numbers for generated code, * not user code. This also happens to be a good place to squeeze multiple * blank lines into a single blank line. */ int filter_postprocess_output (struct filter *chain) { char *buf; const int readsz = 512; int lineno = 1; bool in_gen = true; /* in generated code */ bool last_was_blank = true; if (!chain) return 0; buf = (char *) flex_alloc (readsz); while (fgets (buf, readsz, stdin)) { char *p, *q; int is_blank = true; if (strncmp (buf, "#line ", 6) == 0) in_gen = false; if (strncmp (buf, "@output(", 8) == 0) { char *filename = strdup (buf); FILE *prev_stdout; /* Remove "@)\n". */ filename[strlen (filename) - 3] = '\0'; prev_stdout = freopen (filename + 8, "w+", stdout); if (prev_stdout == NULL) lerrsf (_("could not create %s"), filename + 8); free (filename); lineno = 1; outfile_created = 1; last_was_blank = true; continue; } for (p = q = buf; *p; ) { if (!isspace (*p)) is_blank = false; if (*p == '@') { if (p[1] == '@') *q++ = p[1], p += 2; else if (p[1] == '{') *q++ = '[', p += 2; else if (p[1] == '}') *q++ = ']', p += 2; else if (strncmp (p, "@oline@", 7) == 0) in_gen = true, q += sprintf (q, "%d", lineno + 1), p += 7; } else *q++ = *p++; } *q = '\0'; /* squeeze blank lines from generated code */ if (in_gen && is_blank && last_was_blank) continue; last_was_blank = is_blank; fputs (buf, stdout); lineno++; } fflush (stdout); if (ferror (stdout)) lerrsf (_("error writing output file %s"), outfilename ? outfilename : "<stdout>"); else if (fclose (stdout)) lerrsf (_("error closing output file %s"), outfilename ? outfilename : "<stdout>"); return 0; }
void flexend(int exit_status) { int tblsiz; int unlink(); if ( skelfile != NULL ) { if ( ferror( skelfile ) ) lerrsf( _( "input error reading skeleton file %s" ), skelname ); else if ( fclose( skelfile ) ) lerrsf( _( "error closing skeleton file %s" ), skelname ); } if ( exit_status != 0 && outfile_created ) { if ( ferror( stdout ) ) lerrsf( _( "error writing output file %s" ), outfilename ); else if ( fclose( stdout ) ) lerrsf( _( "error closing output file %s" ), outfilename ); else if ( unlink( outfilename ) ) lerrsf( _( "error deleting output file %s" ), outfilename ); } if ( backing_up_report && backing_up_file ) { if ( num_backing_up == 0 ) fprintf( backing_up_file, _( "No backing up.\n" ) ); else if ( fullspd || fulltbl ) fprintf( backing_up_file, _( "%d backing up (non-accepting) states.\n" ), num_backing_up ); else fprintf( backing_up_file, _( "Compressed tables always back up.\n" ) ); if ( ferror( backing_up_file ) ) lerrsf( _( "error writing backup file %s" ), backing_name ); else if ( fclose( backing_up_file ) ) lerrsf( _( "error closing backup file %s" ), backing_name ); } if ( printstats ) { fprintf( stderr, _( "%s version %s usage statistics:\n" ), program_name, flex_version ); fprintf( stderr, _( " scanner options: -" ) ); if ( C_plus_plus ) putc( '+', stderr ); if ( backing_up_report ) putc( 'b', stderr ); if ( ddebug ) putc( 'd', stderr ); if ( caseins ) putc( 'i', stderr ); if ( lex_compat ) putc( 'l', stderr ); if ( performance_report > 0 ) putc( 'p', stderr ); if ( performance_report > 1 ) putc( 'p', stderr ); if ( spprdflt ) putc( 's', stderr ); if ( use_stdout ) putc( 't', stderr ); if ( printstats ) putc( 'v', stderr ); /* always true! */ if ( nowarn ) putc( 'w', stderr ); if ( interactive == false ) putc( 'B', stderr ); if ( interactive == true ) putc( 'I', stderr ); if ( ! gen_line_dirs ) putc( 'L', stderr ); if ( trace ) putc( 'T', stderr ); if ( csize == unspecified ) /* We encountered an error fairly early on, so csize * never got specified. Define it now, to prevent * bogus table sizes being written out below. */ csize = 256; if ( csize == 128 ) putc( '7', stderr ); else putc( '8', stderr ); fprintf( stderr, " -C" ); if ( long_align ) putc( 'a', stderr ); if ( fulltbl ) putc( 'f', stderr ); if ( fullspd ) putc( 'F', stderr ); if ( useecs ) putc( 'e', stderr ); if ( usemecs ) putc( 'm', stderr ); if ( use_read ) putc( 'r', stderr ); if ( did_outfilename ) fprintf( stderr, " -o%s", outfilename ); if ( skelname ) fprintf( stderr, " -S%s", skelname ); if ( strcmp( prefix, "yy" ) ) fprintf( stderr, " -P%s", prefix ); putc( '\n', stderr ); fprintf( stderr, _( " %d/%d NFA states\n" ), lastnfa, current_mns ); fprintf( stderr, _( " %d/%d DFA states (%d words)\n" ), lastdfa, current_max_dfas, totnst ); fprintf( stderr, _( " %d rules\n" ), num_rules + num_eof_rules - 1 /* - 1 for def. rule */ ); if ( num_backing_up == 0 ) fprintf( stderr, _( " No backing up\n" ) ); else if ( fullspd || fulltbl ) fprintf( stderr, _( " %d backing-up (non-accepting) states\n" ), num_backing_up ); else fprintf( stderr, _( " Compressed tables always back-up\n" ) ); if ( bol_needed ) fprintf( stderr, _( " Beginning-of-line patterns used\n" ) ); fprintf( stderr, _( " %d/%d start conditions\n" ), lastsc, current_max_scs ); fprintf( stderr, _( " %d epsilon states, %d double epsilon states\n" ), numeps, eps2 ); if ( lastccl == 0 ) fprintf( stderr, _( " no character classes\n" ) ); else fprintf( stderr, _( " %d/%d character classes needed %d/%d words of storage, %d reused\n" ), lastccl, current_maxccls, cclmap[lastccl] + ccllen[lastccl], current_max_ccl_tbl_size, cclreuse ); fprintf( stderr, _( " %d state/nextstate pairs created\n" ), numsnpairs ); fprintf( stderr, _( " %d/%d unique/duplicate transitions\n" ), numuniq, numdup ); if ( fulltbl ) { tblsiz = lastdfa * numecs; fprintf( stderr, _( " %d table entries\n" ), tblsiz ); } else { tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; fprintf( stderr, _( " %d/%d base-def entries created\n" ), lastdfa + numtemps, current_max_dfas ); fprintf( stderr, _( " %d/%d (peak %d) nxt-chk entries created\n" ), tblend, current_max_xpairs, peakpairs ); fprintf( stderr, _( " %d/%d (peak %d) template nxt-chk entries created\n" ), numtemps * nummecs, current_max_template_xpairs, numtemps * numecs ); fprintf( stderr, _( " %d empty table entries\n" ), nummt ); fprintf( stderr, _( " %d protos created\n" ), numprots ); fprintf( stderr, _( " %d templates created, %d uses\n" ), numtemps, tmpuses ); } if ( useecs ) { tblsiz = tblsiz + csize; fprintf( stderr, _( " %d/%d equivalence classes created\n" ), numecs, csize ); } if ( usemecs ) { tblsiz = tblsiz + numecs; fprintf( stderr, _( " %d/%d meta-equivalence classes created\n" ), nummecs, csize ); } fprintf( stderr, _( " %d (%d saved) hash collisions, %d DFAs equal\n" ), hshcol, hshsave, dfaeql ); fprintf( stderr, _( " %d sets of reallocations needed\n" ), num_reallocs ); fprintf( stderr, _( " %d total table entries needed\n" ), tblsiz ); } exit( exit_status ); }
void check_options(void) { int i; if ( lex_compat ) { if ( C_plus_plus ) flexerror( _( "Can't use -+ with -l option" ) ); if ( fulltbl || fullspd ) flexerror( _( "Can't use -f or -F with -l option" ) ); /* Don't rely on detecting use of yymore() and REJECT, * just assume they'll be used. */ yymore_really_used = reject_really_used = true; yytext_is_array = true; do_yylineno = true; use_read = false; } if ( do_yylineno ) /* This should really be "maintain_backup_tables = true" */ reject_really_used = true; if ( csize == unspecified ) { if ( (fulltbl || fullspd) && ! useecs ) csize = DEFAULT_CSIZE; else csize = CSIZE; } if ( interactive == unspecified ) { if ( fulltbl || fullspd ) interactive = false; else interactive = true; } if ( fulltbl || fullspd ) { if ( usemecs ) flexerror( _( "-Cf/-CF and -Cm don't make sense together" ) ); if ( interactive ) flexerror( _( "-Cf/-CF and -I are incompatible" ) ); if ( lex_compat ) flexerror( _( "-Cf/-CF are incompatible with lex-compatibility mode" ) ); if ( do_yylineno ) flexerror( _( "-Cf/-CF and %option yylineno are incompatible" ) ); if ( fulltbl && fullspd ) flexerror( _( "-Cf and -CF are mutually exclusive" ) ); } if ( C_plus_plus && fullspd ) flexerror( _( "Can't use -+ with -CF option" ) ); if ( C_plus_plus && yytext_is_array ) { warn( _( "%array incompatible with -+ option" ) ); yytext_is_array = false; } if ( useecs ) { /* Set up doubly-linked equivalence classes. */ /* We loop all the way up to csize, since ecgroup[csize] is * the position used for NUL characters. */ ecgroup[1] = NIL; for ( i = 2; i <= csize; ++i ) { ecgroup[i] = i - 1; nextecm[i - 1] = i; } nextecm[csize] = NIL; } else { /* Put everything in its own equivalence class. */ for ( i = 1; i <= csize; ++i ) { ecgroup[i] = i; nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ } } if ( ! use_stdout ) { FILE *prev_stdout; if ( ! did_outfilename ) { char *suffix; if ( C_plus_plus ) suffix = "cc"; else suffix = "c"; sprintf( outfile_path, outfile_template, prefix, suffix ); outfilename = outfile_path; } prev_stdout = freopen( outfilename, "w", stdout ); if ( prev_stdout == NULL ) lerrsf( _( "could not create %s" ), outfilename ); outfile_created = 1; } if ( skelname && (skelfile = fopen( skelname, "r" )) == NULL ) lerrsf( _( "can't open skeleton file %s" ), skelname ); if ( strcmp( prefix, "yy" ) ) { #define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name ) if ( C_plus_plus ) GEN_PREFIX( "FlexLexer" ); else { GEN_PREFIX( "_create_buffer" ); GEN_PREFIX( "_delete_buffer" ); GEN_PREFIX( "_scan_buffer" ); GEN_PREFIX( "_scan_string" ); GEN_PREFIX( "_scan_bytes" ); GEN_PREFIX( "_flex_debug" ); GEN_PREFIX( "_init_buffer" ); GEN_PREFIX( "_flush_buffer" ); GEN_PREFIX( "_load_buffer_state" ); GEN_PREFIX( "_switch_to_buffer" ); GEN_PREFIX( "in" ); GEN_PREFIX( "leng" ); GEN_PREFIX( "lex" ); GEN_PREFIX( "out" ); GEN_PREFIX( "restart" ); GEN_PREFIX( "text" ); if ( do_yylineno ) GEN_PREFIX( "lineno" ); } if ( do_yywrap ) GEN_PREFIX( "wrap" ); outn( "" ); } if ( did_outfilename ) line_directive_out( stdout, 0 ); skelout(); }
/** Adjust the line numbers in the #line directives of the generated scanner. * After the m4 expansion, the line numbers are incorrect since the m4 macros * can add or remove lines. This only adjusts line numbers for generated code, * not user code. This also happens to be a good place to squeeze multiple * blank lines into a single blank line. */ int filter_fix_linedirs(struct filter * chain) { char *buf; const int readsz = 512; int lineno = 1; bool in_gen = true; /* in generated code */ bool last_was_blank = false; if (!chain) return 0; buf = malloc(readsz); if (!buf) flexerror(_("malloc failed in filter_fix_linedirs")); while (fgets(buf, readsz, stdin)) { regmatch_t m[10]; /* Check for #line directive. */ if (buf[0] == '#' && regexec(®ex_linedir, buf, 3, m, 0) == 0) { int num; char *fname; /* extract the line number and filename */ num = regmatch_strtol(&m[1], buf, NULL, 0); fname = regmatch_dup(&m[2], buf); if (strcmp(fname, outfilename ? outfilename : "<stdout>") == 0 || strcmp(fname, headerfilename ? headerfilename : "<stdout>") == 0) { char *s1, *s2; char filename[MAXLINE]; s1 = fname; s2 = filename; while ((s2 - filename) < (MAXLINE - 1) && *s1) { /* Escape the backslash */ if (*s1 == '\\') *s2++ = '\\'; /* Escape the double quote */ if (*s1 == '\"') *s2++ = '\\'; /* Copy the character as usual */ *s2++ = *s1++; } *s2 = '\0'; /* Adjust the line directives. */ in_gen = true; snprintf(buf, readsz, "#line %d \"%s\"\n", lineno + 1, filename); } else { /* * it's a #line directive for code we didn't * write */ in_gen = false; } free(fname); last_was_blank = false; } /* squeeze blank lines from generated code */ else if (in_gen && regexec(®ex_blank_line, buf, 0, NULL, 0) == 0) { if (last_was_blank) continue; else last_was_blank = true; } else { /* it's a line of normal, non-empty code. */ last_was_blank = false; } fputs(buf, stdout); lineno++; } fflush(stdout); if (ferror(stdout)) lerrsf(_("error writing output file %s"), outfilename ? outfilename : "<stdout>"); else if (fclose(stdout)) lerrsf(_("error closing output file %s"), outfilename ? outfilename : "<stdout>"); return 0; }
/** Splits the chain in order to write to a header file. * Similar in spirit to the 'tee' program. * The header file name is in extra. * @return 0 (zero) on success, and -1 on failure. */ int filter_tee_header(struct filter * chain) { /* * This function reads from stdin and writes to both the C file and * the header file at the same time. */ const int readsz = 512; char *buf; int to_cfd = -1; FILE *to_c = NULL, *to_h = NULL; bool write_header; write_header = (chain->extra != NULL); /* * Store a copy of the stdout pipe, which is already piped to C file * through the running chain. Then create a new pipe to the H file as * stdout, and fork the rest of the chain again. */ if ((to_cfd = dup(1)) == -1) flexfatal(_("dup(1) failed")); to_c = fdopen(to_cfd, "w"); if (write_header) { if (freopen((char *) chain->extra, "w", stdout) == NULL) flexfatal(_("freopen(headerfilename) failed")); filter_apply_chain(chain->next); to_h = stdout; } /* * Now to_c is a pipe to the C branch, and to_h is a pipe to the H * branch. */ if (write_header) { fputs(check_4_gnu_m4, to_h); fputs("m4_changecom`'m4_dnl\n", to_h); fputs("m4_changequote`'m4_dnl\n", to_h); fputs("m4_changequote([[,]])[[]]m4_dnl\n", to_h); fputs("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_h); fputs("m4_define( [[M4_YY_IN_HEADER]],[[]])m4_dnl\n", to_h); fprintf(to_h, "#ifndef %sHEADER_H\n", prefix); fprintf(to_h, "#define %sHEADER_H 1\n", prefix); fprintf(to_h, "#define %sIN_HEADER 1\n\n", prefix); fprintf(to_h, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", headerfilename ? headerfilename : "<stdout>"); } fputs(check_4_gnu_m4, to_c); fputs("m4_changecom`'m4_dnl\n", to_c); fputs("m4_changequote`'m4_dnl\n", to_c); fputs("m4_changequote([[,]])[[]]m4_dnl\n", to_c); fputs("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_c); fprintf(to_c, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", outfilename ? outfilename : "<stdout>"); buf = malloc(readsz); if (!buf) flexerror(_("malloc failed in filter_tee_header")); while (fgets(buf, readsz, stdin)) { fputs(buf, to_c); if (write_header) fputs(buf, to_h); } if (write_header) { fprintf(to_h, "\n"); /* * write a fake line number. It will get fixed by the linedir * filter. */ fprintf(to_h, "#line 4000 \"M4_YY_OUTFILE_NAME\"\n"); fprintf(to_h, "#undef %sIN_HEADER\n", prefix); fprintf(to_h, "#endif /* %sHEADER_H */\n", prefix); fputs("m4_undefine( [[M4_YY_IN_HEADER]])m4_dnl\n", to_h); fflush(to_h); if (ferror(to_h)) lerrsf(_("error writing output file %s"), (char *) chain->extra); else if (fclose(to_h)) lerrsf(_("error closing output file %s"), (char *) chain->extra); } fflush(to_c); if (ferror(to_c)) lerrsf(_("error writing output file %s"), outfilename ? outfilename : "<stdout>"); else if (fclose(to_c)) lerrsf(_("error closing output file %s"), outfilename ? outfilename : "<stdout>"); while (wait(0) > 0); exit(0); return 0; }
void flexinit(int argc, char **argv) { int i, sawcmpflag; char *arg, *flex_gettime(), *mktemp(); printstats = syntaxerror = trace = spprdflt = interactive = caseins = false; backtrack_report = performance_report = ddebug = fulltbl = fullspd = false; yymore_used = continued_action = reject = false; yymore_really_used = reject_really_used = false; gen_line_dirs = usemecs = useecs = true; sawcmpflag = false; use_stdout = false; csize = DEFAULT_CSIZE; program_name = argv[0]; /* read flags */ for ( --argc, ++argv; argc ; --argc, ++argv ) { if ( argv[0][0] != '-' || argv[0][1] == '\0' ) break; arg = argv[0]; for ( i = 1; arg[i] != '\0'; ++i ) switch ( arg[i] ) { case 'b': backtrack_report = true; break; case 'c': fprintf( stderr, "%s: Assuming use of deprecated -c flag is really intended to be -C\n", program_name ); /* fall through */ case 'C': if ( i != 1 ) flexerror( "-C flag must be given separately" ); if ( ! sawcmpflag ) { useecs = false; usemecs = false; fulltbl = false; sawcmpflag = true; } for ( ++i; arg[i] != '\0'; ++i ) switch ( arg[i] ) { case 'e': useecs = true; break; case 'F': fullspd = true; break; case 'f': fulltbl = true; break; case 'm': usemecs = true; break; default: lerrif( "unknown -C option '%c'", (int) arg[i] ); break; } goto get_next_arg; case 'd': ddebug = true; break; case 'f': useecs = usemecs = false; fulltbl = true; break; case 'F': useecs = usemecs = false; fullspd = true; break; case 'I': interactive = true; break; case 'i': caseins = true; break; case 'L': gen_line_dirs = false; break; case 'n': /* stupid do-nothing deprecated option */ break; case 'p': performance_report = true; break; case 'S': if ( i != 1 ) flexerror( "-S flag must be given separately" ); skelname = arg + i + 1; goto get_next_arg; case 's': spprdflt = true; break; case 't': use_stdout = true; break; case 'T': trace = true; break; case 'v': printstats = true; break; case '8': csize = CSIZE; break; default: lerrif( "unknown flag '%c'", (int) arg[i] ); break; } get_next_arg: /* used by -C and -S flags in lieu of a "continue 2" control */ ; } if ( (fulltbl || fullspd) && usemecs ) flexerror( "full table and -Cm don't make sense together" ); if ( (fulltbl || fullspd) && interactive ) flexerror( "full table and -I are (currently) incompatible" ); if ( fulltbl && fullspd ) flexerror( "full table and -F are mutually exclusive" ); if ( ! skelname ) { static char skeleton_name_storage[400]; skelname = skeleton_name_storage; (void) strcpy( skelname, ENQUOTE(DEFAULT_SKELETON_FILE) ); } if ( ! use_stdout ) { FILE *prev_stdout = freopen( outfile, "w", stdout ); if ( prev_stdout == NULL ) lerrsf( "could not create %s", outfile ); outfile_created = 1; } num_input_files = argc; input_files = argv; set_input_file( num_input_files > 0 ? input_files[0] : NULL ); if ( backtrack_report ) { #ifndef SHORT_FILE_NAMES backtrack_file = fopen( "lex.backtrack", "w" ); #else backtrack_file = fopen( "lex.bck", "w" ); #endif if ( backtrack_file == NULL ) flexerror( "could not create lex.backtrack" ); } else backtrack_file = NULL; lastccl = 0; lastsc = 0; /* initialize the statistics */ starttime = flex_gettime(); if ( (skelfile = fopen( skelname, "r" )) == NULL ) lerrsf( "can't open skeleton file %s", skelname ); epicsTempName ( action_file_name, sizeof ( action_file_name ) ); if ( action_file_name[0] == '\0' ) { lerrsf( "can't create temporary file name", "" ); } if ( ( temp_action_file = fopen ( action_file_name, "w" ) ) == NULL ) lerrsf( "can't open temporary action file %s", action_file_name ); lastdfa = lastnfa = num_rules = numas = numsnpairs = tmpuses = 0; numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0; numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; num_backtracking = onesp = numprots = 0; variable_trailing_context_rules = bol_needed = false; linenum = sectnum = 1; firstprot = NIL; /* used in mkprot() so that the first proto goes in slot 1 * of the proto queue */ lastprot = 1; if ( useecs ) { /* set up doubly-linked equivalence classes */ /* We loop all the way up to csize, since ecgroup[csize] is the * position used for NUL characters */ ecgroup[1] = NIL; for ( i = 2; i <= csize; ++i ) { ecgroup[i] = i - 1; nextecm[i - 1] = i; } nextecm[csize] = NIL; } else { /* put everything in its own equivalence class */ for ( i = 1; i <= csize; ++i ) { ecgroup[i] = i; nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ } } set_up_initial_allocations(); }