]> granicus.if.org Git - flex/commitdiff
-o option
authorVern Paxson <vern@ee.lbl.gov>
Sat, 11 Dec 1993 14:40:35 +0000 (14:40 +0000)
committerVern Paxson <vern@ee.lbl.gov>
Sat, 11 Dec 1993 14:40:35 +0000 (14:40 +0000)
Makefile.in
dfa.c
flexdef.h
gen.c
main.c
misc.c
nfa.c
parse.y
scan.l
sym.c

index 16ee54741fa8f713178311e58b46e32e57b728b2..c1a133d1ed3abd19de244e509c7ab831c1a091fe 100644 (file)
@@ -82,7 +82,7 @@ DIST_NAME = flex
 
 # which "flex" to use to generate scan.c from scan.l
 FLEX = ./flex
-FLEX_FLAGS = -ist $(PERF_REPORT)
+FLEX_FLAGS = -ist -oscan.c $(PERF_REPORT)
 COMPRESSION =
 PERF_REPORT = -p
 
diff --git a/dfa.c b/dfa.c
index 11bc44f0d5276a282115e80ede103c67af3d36ec..d427ca04b50834a626ad511e8a5962c282a5289e 100644 (file)
--- a/dfa.c
+++ b/dfa.c
@@ -531,7 +531,7 @@ void ntod()
                /* Unless -Ca, declare it "short" because it's a real
                 * long-shot that that won't be large enough.
                 */
-               printf( "static const %s yy_nxt[][%d] =\n    {\n",
+               out_str_dec( "static const %s yy_nxt[][%d] =\n    {\n",
                        /* '}' so vi doesn't get too confused */
                        long_align ? "long" : "short", num_full_table_rows );
 
index 74f075b48d5e4b473b8d4957d9c7d1f160262638..bfed07e4687f37dbb28f43da4b6bdd653486ea81 100644 (file)
--- a/flexdef.h
+++ b/flexdef.h
@@ -353,12 +353,14 @@ extern int yymore_really_used, reject_really_used;
  * dataline - number of contiguous lines of data in current data
  *     statement.  Used to generate readable -f output
  * linenum - current input line number
+ * out_linenum - current output line number
  * skelfile - the skeleton file
  * skel - compiled-in skeleton array
  * skel_ind - index into "skel" array, if skelfile is nil
  * yyin - input file
  * backing_up_file - file to summarize backing-up states to
  * infilename - name of input file
+ * outfilename - name of output file
  * input_files - array holding names of input files
  * num_input_files - size of input_files array
  * program_name - name with which program was invoked 
@@ -373,11 +375,11 @@ extern int yymore_really_used, reject_really_used;
  *     to "action_array"
  */
 
-extern int datapos, dataline, linenum;
+extern int datapos, dataline, linenum, out_linenum;
 extern FILE *skelfile, *yyin, *backing_up_file;
 extern char *skel[];
 extern int skel_ind;
-extern char *infilename;
+extern char *infilename, *outfilename;
 extern char **input_files;
 extern int num_input_files;
 extern char *program_name;
@@ -739,7 +741,7 @@ extern void lerrif PROTO((char[], int));
 extern void lerrsf PROTO((char[], char[]));
 
 /* Spit out a "# line" statement. */
-extern void line_directive_out PROTO((FILE*));
+extern void line_directive_out PROTO((FILE*, int));
 
 /* Mark the current position in the action array as the end of the section 1
  * user defs.
@@ -757,6 +759,21 @@ extern void mkdata PROTO((int));   /* generate a data statement */
 /* Return the integer represented by a string of digits. */
 extern int myctoi PROTO((char []));
 
+/* Convert an octal digit string to an integer value. */
+extern int otoi PROTO((Char [] ));
+
+/* Output a (possibly-formatted) string to the generated scanner. */
+extern void out PROTO((char []));
+extern void out_dec PROTO((char [], int));
+extern void out_dec2 PROTO((char [], int, int));
+extern void out_hex PROTO((char [], unsigned int));
+extern void out_line_count PROTO((char []));;
+extern void out_str PROTO((char [], char []));
+extern void out_str3 PROTO((char [], char [], char [], char []));
+extern void out_str_dec PROTO((char [], char [], int));
+extern void outc PROTO((int));
+extern void outn PROTO((char []));
+
 /* Return a printable version of the given character, which might be
  * 8-bit.
  */
diff --git a/gen.c b/gen.c
index fe847eb4d89fd4decda8dd4ebcee318b0a920ad4..846e76f47d2ce195581002f898a42fdcced3802b 100644 (file)
--- a/gen.c
+++ b/gen.c
@@ -65,13 +65,13 @@ void do_indent()
 
        while ( i >= 8 )
                {
-               putchar( '\t' );
+               outc( '\t' );
                i -= 8;
                }
 
        while ( i > 0 )
                {
-               putchar( ' ' );
+               outc( ' ' );
                --i;
                }
        }
@@ -121,7 +121,7 @@ void gen_bu_action()
 
        indent_puts( "yy_current_state = yy_last_accepting_state;" );
        indent_puts( "goto yy_find_action;" );
-       putchar( '\n' );
+       outc( '\n' );
 
        set_indent( 0 );
        }
@@ -135,9 +135,9 @@ void genctbl()
        int end_of_buffer_action = num_rules + 1;
 
        /* Table of verify for transition and offset to next state. */
-       printf( "static const struct yy_trans_info yy_transition[%d] =\n",
+       out_dec( "static const struct yy_trans_info yy_transition[%d] =\n",
                tblend + numecs + 1 );
-       printf( "    {\n" );
+       outn( "    {" );
 
        /* We want the transition to be represented as the offset to the
         * next state, not the actual state number, which is what it currently
@@ -205,17 +205,16 @@ void genctbl()
        transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
        transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
 
-       printf( "    };\n" );
-       printf( "\n" );
+       outn( "    };\n" );
 
        /* Table of pointers to start states. */
-       printf(
+       out_dec(
        "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
                lastsc * 2 + 1 );
-       printf( "    {\n" );    /* } so vi doesn't get confused */
+       outn( "    {" );        /* } so vi doesn't get confused */
 
        for ( i = 0; i <= lastsc * 2; ++i )
-               printf( "    &yy_transition[%d],\n", base[i] );
+               out_dec( "    &yy_transition[%d],\n", base[i] );
 
        dataend();
 
@@ -232,7 +231,7 @@ void genecs()
        register int i, j;
        int numrows;
 
-       printf( C_int_decl, "yy_ec", csize );
+       out_str_dec( C_int_decl, "yy_ec", csize );
 
        for ( i = 1; i < csize; ++i )
                {
@@ -282,7 +281,7 @@ void gen_find_action()
                indent_puts( "yy_current_state = *--yy_state_ptr;" );
                indent_puts( "yy_lp = yy_accept[yy_current_state];" );
 
-               puts(
+               outn(
                "find_rule: /* we branch to this label when backing up */" );
 
                indent_puts(
@@ -396,7 +395,7 @@ void genftbl()
        register int i;
        int end_of_buffer_action = num_rules + 1;
 
-       printf( long_align ? C_long_decl : C_short_decl,
+       out_str_dec( long_align ? C_long_decl : C_short_decl,
                "yy_accept", lastdfa + 1 );
 
        dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
@@ -454,7 +453,7 @@ char *char_map;
                do_indent();
 
                /* lastdfa + 2 is the beginning of the templates */
-               printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
+               out_dec( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
 
                indent_up();
                indent_puts( "yy_c = yy_meta[(unsigned int) yy_c];" );
@@ -496,7 +495,7 @@ void gen_next_match()
                        {
                        indent_puts( "{" );     /* } for vi */
                        gen_backing_up();
-                       putchar( '\n' );
+                       outc( '\n' );
                        }
 
                indent_puts( "++yy_cp;" );
@@ -507,7 +506,7 @@ void gen_next_match()
 
                indent_down();
 
-               putchar( '\n' );
+               outc( '\n' );
                indent_puts( "yy_current_state = -yy_current_state;" );
                }
 
@@ -532,7 +531,7 @@ void gen_next_match()
 
                if ( num_backing_up > 0 )
                        {
-                       putchar( '\n' );
+                       outc( '\n' );
                        gen_backing_up();       /* { for vi */
                        indent_puts( "}" );
                        }
@@ -559,10 +558,10 @@ void gen_next_match()
                do_indent();
 
                if ( interactive )
-                       printf( "while ( yy_base[yy_current_state] != %d );\n",
+                       out_dec( "while ( yy_base[yy_current_state] != %d );\n",
                                jambase );
                else
-                       printf( "while ( yy_current_state != %d );\n",
+                       out_dec( "while ( yy_current_state != %d );\n",
                                jamstate );
 
                if ( ! reject && ! interactive )
@@ -655,7 +654,7 @@ void gen_NUL_trans()
                /* We'll need yy_cp lying around for the gen_backing_up(). */
                indent_puts( "register char *yy_cp = yy_c_buf_p;" );
 
-       putchar( '\n' );
+       outc( '\n' );
 
        if ( nultrans )
                {
@@ -667,7 +666,7 @@ void gen_NUL_trans()
        else if ( fulltbl )
                {
                do_indent();
-               printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
+               out_dec( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
                        NUL_ec );
                indent_puts( "yy_is_jam = (yy_current_state <= 0);" );
                }
@@ -675,7 +674,7 @@ void gen_NUL_trans()
        else if ( fullspd )
                {
                do_indent();
-               printf( "register int yy_c = %d;\n", NUL_ec );
+               out_dec( "register int yy_c = %d;\n", NUL_ec );
 
                indent_puts(
                "register const struct yy_trans_info *yy_trans_info;\n" );
@@ -699,7 +698,7 @@ void gen_NUL_trans()
 
                do_indent();
 
-               printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
+               out_dec( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
                }
 
        /* If we've entered an accepting state, back up; note that
@@ -708,7 +707,7 @@ void gen_NUL_trans()
         */
        if ( need_backing_up && (fullspd || fulltbl) )
                {
-               putchar( '\n' );
+               outc( '\n' );
                indent_puts( "if ( ! yy_is_jam )" );
                indent_up();
                indent_puts( "{" );
@@ -783,7 +782,7 @@ void gentabs()
                accsiz[end_of_buffer_state] = 1;
                dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
 
-               printf( long_align ? C_long_decl : C_short_decl,
+               out_str_dec( long_align ? C_long_decl : C_short_decl,
                        "yy_acclist", MAX( numas, 1 ) + 1 );
 
                j = 1;  /* index into "yy_acclist" array */
@@ -870,7 +869,7 @@ void gentabs()
                 */
                ++k;
 
-       printf( long_align ? C_long_decl : C_short_decl, "yy_accept", k );
+       out_str_dec( long_align ? C_long_decl : C_short_decl, "yy_accept", k );
 
        for ( i = 1; i <= lastdfa; ++i )
                {
@@ -902,7 +901,7 @@ void gentabs()
                if ( trace )
                        fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
 
-               printf( C_int_decl, "yy_meta", numecs + 1 );
+               out_str_dec( C_int_decl, "yy_meta", numecs + 1 );
 
                for ( i = 1; i <= numecs; ++i )
                        {
@@ -918,7 +917,7 @@ void gentabs()
 
        total_states = lastdfa + numtemps;
 
-       printf( (tblend >= MAX_SHORT || long_align) ?
+       out_str_dec( (tblend >= MAX_SHORT || long_align) ?
                        C_long_decl : C_short_decl,
                "yy_base", total_states + 1 );
 
@@ -953,7 +952,7 @@ void gentabs()
 
        dataend();
 
-       printf( (total_states >= MAX_SHORT || long_align) ?
+       out_str_dec( (total_states >= MAX_SHORT || long_align) ?
                        C_long_decl : C_short_decl,
                "yy_def", total_states + 1 );
 
@@ -962,7 +961,7 @@ void gentabs()
 
        dataend();
 
-       printf( (total_states >= MAX_SHORT || long_align) ?
+       out_str_dec( (total_states >= MAX_SHORT || long_align) ?
                        C_long_decl : C_short_decl,
                "yy_nxt", tblend + 1 );
 
@@ -976,7 +975,7 @@ void gentabs()
 
        dataend();
 
-       printf( (total_states >= MAX_SHORT || long_align) ?
+       out_str_dec( (total_states >= MAX_SHORT || long_align) ?
                        C_long_decl : C_short_decl,
                "yy_chk", tblend + 1 );
 
@@ -1000,8 +999,8 @@ void indent_put2s( fmt, arg )
 char fmt[], arg[];
        {
        do_indent();
-       printf( fmt, arg );
-       putchar( '\n' );
+       out_str( fmt, arg );
+       outn( "" );
        }
 
 
@@ -1013,7 +1012,7 @@ void indent_puts( str )
 char str[];
        {
        do_indent();
-       puts( str );
+       outn( str );
        }
 
 
@@ -1058,7 +1057,7 @@ void make_tables()
        skelout();
 
 
-       printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
+       out_dec( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
 
        if ( fullspd )
                {
@@ -1117,12 +1116,12 @@ void make_tables()
 
        if ( nultrans )
                {
-               printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 );
+               out_str_dec( C_state_decl, "yy_NUL_trans", lastdfa + 1 );
 
                for ( i = 1; i <= lastdfa; ++i )
                        {
                        if ( fullspd )
-                               printf( "    &yy_transition[%d],\n", base[i] );
+                               out_dec( "    &yy_transition[%d],\n", base[i] );
                        else
                                mkdata( nultrans[i] );
                        }
@@ -1135,7 +1134,7 @@ void make_tables()
                indent_puts( "extern int yy_flex_debug;" );
                indent_puts( "int yy_flex_debug = 1;\n" );
 
-               printf( long_align ? C_long_decl : C_short_decl,
+               out_str_dec( long_align ? C_long_decl : C_short_decl,
                        "yy_rule_linenum", num_rules );
                for ( i = 1; i < num_rules; ++i )
                        mkdata( rule_linenum[i] );
@@ -1147,58 +1146,58 @@ void make_tables()
                /* Declare state buffer variables. */
                if ( ! C_plus_plus )
                        {
-                       puts(
+                       outn(
        "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
-                       puts( "static char *yy_full_match;" );
-                       puts( "static int yy_lp;" );
+                       outn( "static char *yy_full_match;" );
+                       outn( "static int yy_lp;" );
                        }
 
                if ( variable_trailing_context_rules )
                        {
                        if ( ! C_plus_plus )
                                {
-                               puts(
+                               outn(
                                "static int yy_looking_for_trail_begin = 0;" );
-                               puts( "static int yy_full_lp;" );
-                               puts( "static int *yy_full_state;" );
+                               outn( "static int yy_full_lp;" );
+                               outn( "static int *yy_full_state;" );
                                }
 
-                       printf( "#define YY_TRAILING_MASK 0x%x\n",
+                       out_hex( "#define YY_TRAILING_MASK 0x%x\n",
                                (unsigned int) YY_TRAILING_MASK );
-                       printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
+                       out_hex( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
                                (unsigned int) YY_TRAILING_HEAD_MASK );
                        }
 
-               puts( "#define REJECT \\" );
-               puts( "{ \\" );         /* } for vi */
-               puts(
+               outn( "#define REJECT \\" );
+               outn( "{ \\" );         /* } for vi */
+               outn(
        "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
-               puts(
+               outn(
        "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
 
                if ( variable_trailing_context_rules )
                        {
-                       puts(
+                       outn(
                "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
-                       puts(
+                       outn(
                "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
-                       puts(
+                       outn(
        "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
                        }
 
-               puts( "++yy_lp; \\" );
-               puts( "goto find_rule; \\" );
+               outn( "++yy_lp; \\" );
+               outn( "goto find_rule; \\" );
                /* { for vi */
-               puts( "}" );
+               outn( "}" );
                }
 
        else
                {
-               puts(
+               outn(
                "/* The intent behind this definition is that it'll catch" );
-               puts( " * any uses of REJECT which flex missed." );
-               puts( " */" );
-               puts( "#define REJECT reject_used_but_not_detected" );
+               outn( " * any uses of REJECT which flex missed." );
+               outn( " */" );
+               outn( "#define REJECT reject_used_but_not_detected" );
                }
 
        if ( yymore_used )
@@ -1223,18 +1222,20 @@ void make_tables()
                {
                if ( yytext_is_array )
                        {
-                       puts( "#ifndef YYLMAX" );
-                       puts( "#define YYLMAX 8192" );
-                       puts( "#endif\n" );
-                       puts( "char yytext[YYLMAX];" );
-                       puts( "char *yytext_ptr;" );
+                       outn( "#ifndef YYLMAX" );
+                       outn( "#define YYLMAX 8192" );
+                       outn( "#endif\n" );
+                       outn( "char yytext[YYLMAX];" );
+                       outn( "char *yytext_ptr;" );
                        }
 
                else
-                       puts( "char *yytext;" );
+                       outn( "char *yytext;" );
                }
 
-       fputs( &action_array[defs1_offset], stdout );
+       out( &action_array[defs1_offset] );
+
+       line_directive_out( stdout, 0 );
 
        skelout();
 
@@ -1242,33 +1243,35 @@ void make_tables()
                {
                if ( use_read )
                        {
-                       printf(
-"\tif ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\\n" );
-                       printf(
-               "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );\n" );
+                       outn(
+"\tif ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\" );
+                       outn(
+               "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" );
                        }
 
                else
                        {
-                       printf(
-                       "\tif ( yy_current_buffer->yy_is_interactive ) \\\n" );
-                       printf( "\t\t{ \\\n" );
-                       printf( "\t\tint c = getc( yyin ); \\\n" );
-                       printf( "\t\tresult = c == EOF ? 0 : 1; \\\n" );
-                       printf( "\t\tbuf[0] = (char) c; \\\n" );
-                       printf( "\t\t} \\\n" );
-                       printf(
-       "\telse if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\\n" );
-                       printf( "\t\t  && ferror( yyin ) ) \\\n" );
-                       printf(
-               "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );\n" );
+                       outn(
+                       "\tif ( yy_current_buffer->yy_is_interactive ) \\" );
+                       outn( "\t\t{ \\" );
+                       outn( "\t\tint c = getc( yyin ); \\" );
+                       outn( "\t\tresult = c == EOF ? 0 : 1; \\" );
+                       outn( "\t\tbuf[0] = (char) c; \\" );
+                       outn( "\t\t} \\" );
+                       outn(
+       "\telse if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\" );
+                       outn( "\t\t  && ferror( yyin ) ) \\" );
+                       outn(
+               "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" );
                        }
                }
 
        skelout();
 
        /* Copy prolog to output file. */
-       fputs( &action_array[prolog_offset], stdout );
+       out( &action_array[prolog_offset] );
+
+       line_directive_out( stdout, 0 );
 
        skelout();
 
@@ -1291,7 +1294,7 @@ void make_tables()
        gen_start_state();
 
        /* Note, don't use any indentation. */
-       puts( "yy_match:" );
+       outn( "yy_match:" );
        gen_next_match();
 
        skelout();
@@ -1330,7 +1333,7 @@ void make_tables()
                indent_down();
 
                do_indent();
-               printf( "else if ( yy_act < %d )\n", num_rules );
+               out_dec( "else if ( yy_act < %d )\n", num_rules );
                indent_up();
                indent_puts(
        "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," );
@@ -1338,7 +1341,7 @@ void make_tables()
                indent_down();
 
                do_indent();
-               printf( "else if ( yy_act == %d )\n", num_rules );
+               out_dec( "else if ( yy_act == %d )\n", num_rules );
                indent_up();
                indent_puts(
        "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," );
@@ -1346,14 +1349,14 @@ void make_tables()
                indent_down();
 
                do_indent();
-               printf( "else if ( yy_act == %d )\n", num_rules + 1 );
+               out_dec( "else if ( yy_act == %d )\n", num_rules + 1 );
                indent_up();
                indent_puts(
        "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" );
                indent_down();
 
                do_indent();
-               printf( "else\n" );
+               outn( "else" );
                indent_up();
                indent_puts(
        "fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );" );
@@ -1367,14 +1370,16 @@ void make_tables()
        skelout();
        indent_up();
        gen_bu_action();
-       fputs( &action_array[action_offset], stdout );
+       out( &action_array[action_offset] );
+
+       line_directive_out( stdout, 0 );
 
        /* generate cases for any missing EOF rules */
        for ( i = 1; i <= lastsc; ++i )
                if ( ! sceof[i] )
                        {
                        do_indent();
-                       printf( "case YY_STATE_EOF(%s):\n", scname[i] );
+                       out_str( "case YY_STATE_EOF(%s):\n", scname[i] );
                        did_eof_rule = true;
                        }
 
@@ -1441,7 +1446,7 @@ void make_tables()
 
        /* Copy remainder of input to output. */
 
-       line_directive_out( stdout );
+       line_directive_out( stdout, 1 );
 
        if ( sectnum == 3 )
                (void) flexscan(); /* copy remainder of input to output */
diff --git a/main.c b/main.c
index d82c1d6f2440955eec22c94e4f4045f924881508..a448d543eccaeb021af406b81261c9c69d19428a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -55,12 +55,12 @@ int fullspd, gen_line_dirs, performance_report, backing_up_report;
 int C_plus_plus, long_align, use_read, yytext_is_array, csize;
 int yymore_used, reject, real_reject, continued_action;
 int yymore_really_used, reject_really_used;
-int datapos, dataline, linenum;
+int datapos, dataline, linenum, out_linenum;
 FILE *skelfile = NULL;
 int skel_ind = 0;
 char *action_array;
 int action_size, defs1_offset, prolog_offset, action_offset, action_index;
-char *infilename = NULL;
+char *infilename = NULL, *outfilename = NULL;
 int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
 int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
 int current_mns, num_rules, num_eof_rules, default_rule;
@@ -101,9 +101,9 @@ static char *outfile_template = "lex.%s.%s";
 #else
 static char *outfile_template = "lex%s.%s";
 #endif
-static char outfile_path[64];
 
 static int outfile_created = 0;
+static int did_outfilename = 0;
 static int use_stdout;
 static char *skelname = NULL;
 static char *prefix = "yy";
@@ -174,7 +174,7 @@ int exit_status;
                else if ( fclose( stdout ) )
                        flexfatal( "error occurred when closing output file" );
 
-               else if ( unlink( outfile_path ) )
+               else if ( unlink( outfilename ) )
                        flexfatal( "error occurred when deleting output file" );
                }
 
@@ -254,6 +254,9 @@ int exit_status;
                if ( use_read )
                        putc( 'r', stderr );
 
+               if ( did_outfilename )
+                       fprintf( stderr, " -o%s", outfilename );
+
                if ( skelname )
                        fprintf( stderr, " -S%s", skelname );
 
@@ -516,6 +519,15 @@ char **argv;
                                         */
                                        break;
 
+                               case 'o':
+                                       if ( i != 1 )
+                                               flexerror(
+                                       "-o flag must be given separately" );
+
+                                       outfilename = arg + i + 1;
+                                       did_outfilename = 1;
+                                       goto get_next_arg;
+
                                case 'P':
                                        if ( i != 1 )
                                                flexerror(
@@ -579,7 +591,7 @@ char **argv;
                                        exit( 1 );
                                }
 
-               /* Used by -C, -S and -P flags in lieu of a "continue 2"
+               /* Used by -C, -S, -o, and -P flags in lieu of a "continue 2"
                 * control.
                 */
                get_next_arg: ;
@@ -633,19 +645,27 @@ char **argv;
        if ( ! use_stdout )
                {
                FILE *prev_stdout;
-               char *suffix;
 
-               if ( C_plus_plus )
-                       suffix = "cc";
-               else
-                       suffix = "c";
+               if ( ! did_outfilename )
+                       {
+                       static char outfile_path[64];
+                       char *suffix;
+
+                       if ( C_plus_plus )
+                               suffix = "cc";
+                       else
+                               suffix = "c";
 
-               sprintf( outfile_path, outfile_template, prefix, suffix );
+                       sprintf( outfile_path, outfile_template,
+                               prefix, suffix );
 
-               prev_stdout = freopen( outfile_path, "w", stdout );
+                       outfilename = outfile_path;
+                       }
+
+               prev_stdout = freopen( outfilename, "w", stdout );
 
                if ( prev_stdout == NULL )
-                       lerrsf( "could not create %s", outfile_path );
+                       lerrsf( "could not create %s", outfilename );
 
                outfile_created = 1;
                }
@@ -678,7 +698,7 @@ char **argv;
 
        if ( yy_strcmp( prefix, "yy" ) )
                {
-#define GEN_PREFIX(name) printf( "#define yy%s %s%s\n", name, prefix, name );
+#define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name );
                GEN_PREFIX( "FlexLexer" );
                GEN_PREFIX( "_create_buffer" );
                GEN_PREFIX( "_delete_buffer" );
@@ -693,7 +713,7 @@ char **argv;
                GEN_PREFIX( "restart" );
                GEN_PREFIX( "text" );
                GEN_PREFIX( "wrap" );
-               printf( "\n" );
+               outn( "" );
                }
 
 
@@ -705,7 +725,7 @@ char **argv;
        num_backing_up = onesp = numprots = 0;
        variable_trailing_context_rules = bol_needed = false;
 
-       linenum = sectnum = 1;
+       out_linenum = linenum = sectnum = 1;
        firstprot = NIL;
 
        /* Used in mkprot() so that the first proto goes in slot 1
@@ -749,9 +769,12 @@ char **argv;
 
 void readin()
        {
+       if ( did_outfilename )
+               line_directive_out( stdout, 0 );
+
        skelout();
 
-       line_directive_out( (FILE *) 0 );
+       line_directive_out( (FILE *) 0, 1 );
 
        if ( yyparse() )
                {
@@ -818,51 +841,50 @@ void readin()
                }
 
        if ( csize == 256 )
-               puts( "typedef unsigned char YY_CHAR;" );
+               outn( "typedef unsigned char YY_CHAR;" );
        else
-               puts( "typedef char YY_CHAR;" );
+               outn( "typedef char YY_CHAR;" );
 
        if ( C_plus_plus )
                {
-               puts( "#define yytext_ptr yytext" );
+               outn( "#define yytext_ptr yytext" );
 
                if ( interactive )
-                       puts( "#define YY_INTERACTIVE" );
+                       outn( "#define YY_INTERACTIVE" );
                }
 
        if ( fullspd )
-               printf(
-               "typedef const struct yy_trans_info *yy_state_type;\n" );
+               outn( "typedef const struct yy_trans_info *yy_state_type;" );
        else if ( ! C_plus_plus )
-               printf( "typedef int yy_state_type;\n" );
+               outn( "typedef int yy_state_type;" );
 
        if ( reject )
-               printf( "\n#define YY_USES_REJECT\n" );
+               outn( "\n#define YY_USES_REJECT" );
 
        if ( ddebug )
-               puts( "\n#define FLEX_DEBUG" );
+               outn( "\n#define FLEX_DEBUG" );
 
        if ( lex_compat )
                {
-               printf( "FILE *yyin = stdin, *yyout = stdout;\n" );
-               printf( "extern int yylineno;\n" );
-               printf( "int yylineno = 1;\n" );
+               outn( "FILE *yyin = stdin, *yyout = stdout;" );
+               outn( "extern int yylineno;" );
+               outn( "int yylineno = 1;" );
                }
        else if ( ! C_plus_plus )
-               printf( "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;\n" );
+               outn( "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;" );
 
        if ( C_plus_plus )
-               printf( "\n#include <FlexLexer.h>\n" );
+               outn( "\n#include <FlexLexer.h>" );
 
        else
                {
                if ( yytext_is_array )
-                       puts( "extern char yytext[];\n" );
+                       outn( "extern char yytext[];\n" );
 
                else
                        {
-                       puts( "extern char *yytext;" );
-                       puts( "#define yytext_ptr yytext" );
+                       outn( "extern char *yytext;" );
+                       outn( "#define yytext_ptr yytext" );
                        }
                }
 
@@ -984,6 +1006,7 @@ void usage()
        fprintf( stderr, "\t\t-Cm  construct meta-equivalence classes\n" );
        fprintf( stderr,
                "\t\t-Cr  use read() instead of stdio for scanner input\n" );
+       fprintf( stderr, "\t-o  specify output filename\n" );
        fprintf( stderr, "\t-P  specify scanner prefix other than \"yy\"\n" );
        fprintf( stderr, "\t-S  specify skeleton file\n" );
        }
diff --git a/misc.c b/misc.c
index bcc75f303611d09ec12a2b6a984f1f73847af19e..2b513cb30793a77d27f4ed47fe6ff0d755f05a52 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -275,7 +275,7 @@ void dataend()
                dataflush();
 
        /* add terminator for initialization; { for vi */
-       puts( "    } ;\n" );
+       outn( "    } ;\n" );
 
        dataline = 0;
        datapos = 0;
@@ -286,14 +286,14 @@ void dataend()
 
 void dataflush()
        {
-       putchar( '\n' );
+       outc( '\n' );
 
        if ( ++dataline >= NUMDATALINES )
                {
                /* Put out a blank line so that the table is grouped into
                 * large blocks that enable the user to find elements easily.
                 */
-               putchar( '\n' );
+               outc( '\n' );
                dataline = 0;
                }
 
@@ -387,22 +387,40 @@ int ch;
 
 /* line_directive_out - spit out a "# line" statement */
 
-void line_directive_out( output_file )
+void line_directive_out( output_file, do_infile )
 FILE *output_file;
+int do_infile;
        {
-       if ( infilename && gen_line_dirs )
+       char directive[MAXLINE];
+       static char line_fmt[] = "# line %d \"%s\"\n";
+
+       if ( ! gen_line_dirs )
+               return;
+
+       if ( (do_infile && ! infilename) || (! do_infile && ! outfilename) )
+               /* don't know the filename to use, skip */
+               return;
+
+       if ( do_infile )
+               sprintf( directive, line_fmt, linenum, infilename );
+       else
                {
-               char directive[MAXLINE];
-               sprintf( directive, "# line %d \"%s\"\n", linenum, infilename );
+               if ( output_file == stdout )
+                       /* Account for the line directive itself. */
+                       ++out_linenum;
 
-               /* If output_file is nil then we should put the directive in
-                * the accumulated actions.
-                */
-               if ( output_file )
-                       fputs( directive, output_file );
-               else
-                       add_action( directive );
+               sprintf( directive, line_fmt, out_linenum, outfilename );
+               }
+
+       /* If output_file is nil then we should put the directive in
+        * the accumulated actions.
+        */
+       if ( output_file )
+               {
+               fputs( directive, output_file );
                }
+       else
+               add_action( directive );
        }
 
 
@@ -439,20 +457,20 @@ int value;
        {
        if ( datapos >= NUMDATAITEMS )
                {
-               putchar( ',' );
+               outc( ',' );
                dataflush();
                }
 
        if ( datapos == 0 )
                /* Indent. */
-               fputs( "    ", stdout );
+               out( "    " );
 
        else
-               putchar( ',' );
+               outc( ',' );
 
        ++datapos;
 
-       printf( "%5d", value );
+       out_dec( "%5d", value );
        }
 
 
@@ -466,19 +484,19 @@ int value;
        {
        if ( datapos >= NUMDATAITEMS )
                {
-               putchar( ',' );
+               outc( ',' );
                dataflush();
                }
 
        if ( datapos == 0 )
                /* Indent. */
-               fputs( "    ", stdout );
+               out( "    " );
        else
-               putchar( ',' );
+               outc( ',' );
 
        ++datapos;
 
-       printf( "%5d", value );
+       out_dec( "%5d", value );
        }
 
 
@@ -589,6 +607,96 @@ Char str[];
        }
 
 
+/* out - various flavors of outputing a (possibly formatted) string for the
+ *      generated scanner, keeping track of the line count.
+ */
+
+void out( str )
+char str[];
+       {
+       fputs( str, stdout );
+       out_line_count( str );
+       }
+
+void out_dec( fmt, n )
+char fmt[];
+int n;
+       {
+       printf( fmt, n );
+       out_line_count( fmt );
+       }
+
+void out_dec2( fmt, n1, n2 )
+char fmt[];
+int n1, n2;
+       {
+       printf( fmt, n1, n2 );
+       out_line_count( fmt );
+       }
+
+void out_hex( fmt, x )
+char fmt[];
+unsigned int x;
+       {
+       printf( fmt, x );
+       out_line_count( fmt );
+       }
+
+void out_line_count( str )
+char str[];
+       {
+       register int i;
+
+       for ( i = 0; str[i]; ++i )
+               if ( str[i] == '\n' )
+                       ++out_linenum;
+       }
+
+void out_str( fmt, str )
+char fmt[], str[];
+       {
+       printf( fmt, str );
+       out_line_count( fmt );
+       out_line_count( str );
+       }
+
+void out_str3( fmt, s1, s2, s3 )
+char fmt[], s1[], s2[], s3[];
+       {
+       printf( fmt, s1, s2, s3 );
+       out_line_count( fmt );
+       out_line_count( s1 );
+       out_line_count( s2 );
+       out_line_count( s3 );
+       }
+
+void out_str_dec( fmt, str, n )
+char fmt[], str[];
+int n;
+       {
+       printf( fmt, str, n );
+       out_line_count( fmt );
+       out_line_count( str );
+       }
+
+void outc( c )
+int c;
+       {
+       putc( c, stdout );
+
+       if ( c == '\n' )
+               ++out_linenum;
+       }
+
+void outn( str )
+char str[];
+       {
+       puts( str );
+       out_line_count( str );
+       ++out_linenum;
+       }
+
+
 /* readable_form - return the the human-readable form of a character
  *
  * The returned string is in static storage.
@@ -706,9 +814,9 @@ void skelout()
                                /* Skeleton file reads include final
                                 * newline, skel[] array does not.
                                 */
-                               fputs( buf, stdout );
+                               out( buf );
                        else
-                               printf( "%s\n", buf );
+                               outn( buf );
                        }
                }
        }
@@ -723,16 +831,16 @@ void skelout()
 void transition_struct_out( element_v, element_n )
 int element_v, element_n;
        {
-       printf( "%7d, %5d,", element_v, element_n );
+       out_dec2( "%7d, %5d,", element_v, element_n );
 
        datapos += TRANS_STRUCT_PRINT_LENGTH;
 
        if ( datapos >= 75 )
                {
-               putchar( '\n' );
+               outc( '\n' );
 
                if ( ++dataline % 10 == 0 )
-                       putchar( '\n' );
+                       outc( '\n' );
 
                datapos = 0;
                }
diff --git a/nfa.c b/nfa.c
index 44e893d3f1e6de9dc816490942dcd1eb0eb73e8f..2f104f1171d6cd512d8d0bb6095bf07c0d429b65 100644 (file)
--- a/nfa.c
+++ b/nfa.c
@@ -268,7 +268,7 @@ int mach, variable_trail_rule, headcnt, trailcnt;
         */
        add_action( "YY_USER_ACTION\n" );
 
-       line_directive_out( (FILE *) 0 );
+       line_directive_out( (FILE *) 0, 1 );
        }
 
 
diff --git a/parse.y b/parse.y
index b3f517faa150cd587d2cd63a9c8c25f7a791873b..841a37990660e6ecf7b178b57523da44446aa52c 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -716,7 +716,7 @@ void build_eof_action()
                        }
                }
 
-       line_directive_out( (FILE *) 0 );
+       line_directive_out( (FILE *) 0, 1 );
 
        /* This isn't a normal rule after all - don't count it as
         * such, so we don't have any holes in the rule numbering
diff --git a/scan.l b/scan.l
index 7392714179b2376ad314dbce14ed5285be103f0d..7aa864dbb75752472201a88a5ed146dba2305847 100644 (file)
--- a/scan.l
+++ b/scan.l
@@ -93,7 +93,7 @@ CCL_CHAR      ([^\\\n\]]|{ESCSEQ})
 ^"%x"{NAME}?           return XSCDECL;
 ^"%{".*{NL}            {
                        ++linenum;
-                       line_directive_out( (FILE *) 0 );
+                       line_directive_out( (FILE *) 0, 1 );
                        indented_code = false;
                        BEGIN(CODEBLOCK);
                        }
@@ -104,7 +104,7 @@ CCL_CHAR    ([^\\\n\]]|{ESCSEQ})
                        sectnum = 2;
                        bracelevel = 0;
                        mark_defs1();
-                       line_directive_out( (FILE *) 0 );
+                       line_directive_out( (FILE *) 0, 1 );
                        BEGIN(SECT2PROLOG);
                        return SECTEND;
                        }
diff --git a/sym.c b/sym.c
index 29c0f30a3e8dec9dddafd95c5418eb14f66590d7..4058332d33e65729d055dc12f8d55bbcbda12f3d 100644 (file)
--- a/sym.c
+++ b/sym.c
@@ -231,7 +231,7 @@ int xcluflg;
        char *copy_string();
 
        /* Generate start condition definition, for use in BEGIN et al. */
-       printf( "#define %s %d\n", str, lastsc );
+       out_str_dec( "#define %s %d\n", str, lastsc );
 
        if ( ++lastsc >= current_max_scs )
                scextend();