From 336a1deaa57975f34cd732d656d1c0cbe3d5233a Mon Sep 17 00:00:00 2001 From: Mightyjo Date: Mon, 26 Oct 2015 20:35:00 -0700 Subject: [PATCH] Changed several pointers to istream (and ostream) to references in c++-only sections of the skeleton. Patched up a variety of expected errors caused by changing istream* to istream&. Added a stray 'make' at line 545. Oops. Changed the buffer_state struct to store std::streambuf* instead of std::istream* for C++ mode. Changed interfaces in FlexLexer.h to take std::istream& instead of *. Backward compatibility temporarily broken. Patched up backward compatibility with reasonable behavior in the presence of null pointers. Re-added backward-compatible versions of the yyFlexLexer methods that take iostream pointers. All tests passing. --- src/FlexLexer.h | 41 +++++++++++----- src/flex.skl | 123 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 127 insertions(+), 37 deletions(-) diff --git a/src/FlexLexer.h b/src/FlexLexer.h index bad4ce0..b725b1f 100644 --- a/src/FlexLexer.h +++ b/src/FlexLexer.h @@ -69,22 +69,33 @@ public: yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; virtual struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( FLEX_STD istream& s, int size ) = 0; virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; - virtual void yyrestart( FLEX_STD istream* s ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + virtual void yyrestart( FLEX_STD istream& s ) = 0; virtual int yylex() = 0; // Call yylex with new input/output sources. - int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) - { + int yylex( FLEX_STD istream& new_in, FLEX_STD ostream& new_out ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0) + { switch_streams( new_in, new_out ); return yylex(); - } + } // Switch to new input/output streams. A nil stream pointer // indicates "keep the current one". - virtual void switch_streams( FLEX_STD istream* new_in = 0, - FLEX_STD ostream* new_out = 0 ) = 0; + virtual void switch_streams( FLEX_STD istream* new_in, + FLEX_STD ostream* new_out ) = 0; + virtual void switch_streams( FLEX_STD istream& new_in, + FLEX_STD ostream& new_out ) = 0; int lineno() const { return yylineno; } @@ -113,20 +124,28 @@ class yyFlexLexer : public FlexLexer { public: // arg_yyin and arg_yyout default to the cin and cout, but we // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream& arg_yyin, FLEX_STD ostream& arg_yyout ); yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); +private: + void ctor_common(); + +public: virtual ~yyFlexLexer(); void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); - struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream& s, int size ); void yy_delete_buffer( struct yy_buffer_state* b ); void yyrestart( FLEX_STD istream* s ); + void yyrestart( FLEX_STD istream& s ); void yypush_buffer_state( struct yy_buffer_state* new_buffer ); void yypop_buffer_state(); virtual int yylex(); - virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ); + virtual void switch_streams( FLEX_STD istream& new_in, FLEX_STD ostream& new_out ); + virtual void switch_streams( FLEX_STD istream* new_in = 0, FLEX_STD ostream* new_out = 0 ); virtual int yywrap(); protected: @@ -138,7 +157,7 @@ protected: int yyinput(); void yy_load_buffer_state(); - void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); + void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream& s ); void yy_flush_buffer( struct yy_buffer_state* b ); int yy_start_stack_ptr; @@ -153,8 +172,8 @@ protected: yy_state_type yy_try_NUL_trans( yy_state_type current_state ); int yy_get_next_buffer(); - FLEX_STD istream* yyin; // input source for default LexerInput - FLEX_STD ostream* yyout; // output sink for default LexerOutput + FLEX_STD istream yyin; // input source for default LexerInput + FLEX_STD ostream yyout; // output sink for default LexerOutput // yy_hold_char holds the character lost when yytext is formed. char yy_hold_char; diff --git a/src/flex.skl b/src/flex.skl index a1f6db6..73a0b9e 100644 --- a/src/flex.skl +++ b/src/flex.skl @@ -556,7 +556,7 @@ struct yy_buffer_state %endif %if-c++-only - std::istream* yy_input_file; + std::streambuf* yy_input_file; %endif @@ -1338,7 +1338,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]], yyin = stdin; %endif %if-c++-only - yyin = & std::cin; + yyin.rdbuf(std::cin.rdbuf()); %endif if ( ! yyout ) @@ -1346,7 +1346,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]], yyout = stdout; %endif %if-c++-only - yyout = & std::cout; + yyout.rdbuf(std::cout.rdbuf()); %endif if ( ! YY_CURRENT_BUFFER ) { @@ -1412,7 +1412,12 @@ do_action: /* This label is used only to access EOF actions. */ * back-up) that will match for the new input source. */ YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +%if-c-only YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; +%endif +%if-c++-only + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin.rdbuf(); +%endif YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } @@ -1524,12 +1529,30 @@ do_action: /* This label is used only to access EOF actions. */ %if-c++-only %not-for-header +/* The contents of this function are C++ specific, so the YY_G macro is not used. + * This constructor simply maintains backward compatibility. + * DEPRECATED + */ +yyFlexLexer::yyFlexLexer( FLEX_STD istream* arg_yyin, FLEX_STD ostream* arg_yyout ): + yyin(arg_yyin ? arg_yyin->rdbuf() : std::cin.rdbuf()), + yyout(arg_yyout ? arg_yyout->rdbuf() : std::cout.rdbuf()) +{ + ctor_common(); +} + +/* The contents of this function are C++ specific, so the YY_G macro is not used. + */ +yyFlexLexer::yyFlexLexer( std::istream& arg_yyin, std::ostream& arg_yyout ): + yyin(arg_yyin.rdbuf()), + yyout(arg_yyout.rdbuf()) +{ + ctor_common(); +} + /* The contents of this function are C++ specific, so the YY_G macro is not used. */ -yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) +void yyFlexLexer::ctor_common() { - yyin = arg_yyin; - yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; @@ -1570,18 +1593,31 @@ yyFlexLexer::~yyFlexLexer() yyfree( yy_buffer_stack M4_YY_CALL_LAST_ARG ); } +/* The contents of this function are C++ specific, so the YY_G macro is not used. + */ +void yyFlexLexer::switch_streams( std::istream& new_in, std::ostream& new_out ) +{ + // was if( new_in ) + yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE M4_YY_CALL_LAST_ARG) M4_YY_CALL_LAST_ARG); + + // was if( new_out ) + yyout.rdbuf(new_out.rdbuf()); +} + /* The contents of this function are C++ specific, so the YY_G macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { - if ( new_in ) - { - yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG); - yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE M4_YY_CALL_LAST_ARG) M4_YY_CALL_LAST_ARG); - } + if( ! new_in ) { + new_in = &yyin; + } - if ( new_out ) - yyout = new_out; + if ( ! new_out ) { + new_out = &yyout; + } + + switch_streams(*new_in, *new_out); } #ifdef YY_INTERACTIVE @@ -1590,33 +1626,33 @@ int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) int yyFlexLexer::LexerInput( char* buf, int max_size ) #endif { - if ( yyin->eof() || yyin->fail() ) + if ( yyin.eof() || yyin.fail() ) return 0; #ifdef YY_INTERACTIVE - yyin->get( buf[0] ); + yyin.get( buf[0] ); - if ( yyin->eof() ) + if ( yyin.eof() ) return 0; - if ( yyin->bad() ) + if ( yyin.bad() ) return -1; return 1; #else - (void) yyin->read( buf, max_size ); + (void) yyin.read( buf, max_size ); - if ( yyin->bad() ) + if ( yyin.bad() ) return -1; else - return yyin->gcount(); + return yyin.gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, int size ) { - (void) yyout->write( buf, size ); + (void) yyout.write( buf, size ); } %ok-for-header %endif @@ -1973,7 +2009,7 @@ m4_ifdef( [[M4_YY_USE_LINENO]], void yyrestart YYFARGS1( FILE *,input_file) %endif %if-c++-only - void yyFlexLexer::yyrestart( std::istream* input_file ) + void yyFlexLexer::yyrestart( std::istream& input_file ) %endif { M4_YY_DECL_GUTS_VAR(); @@ -1988,6 +2024,18 @@ m4_ifdef( [[M4_YY_USE_LINENO]], yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); } +%if-c++-only +/** Delegate to the new version that takes an istream reference. + * @param input_file A readable stream. + * M4_YY_DOC_PARAM + * @note This function does not reset the start condition to @c INITIAL . + */ +void yyFlexLexer::yyrestart( std::istream* input_file ) +{ + yyrestart( *input_file ); +} +%endif + /** Switch to a different input buffer. * @param new_buffer The new input buffer. * M4_YY_DOC_PARAM @@ -2040,7 +2088,12 @@ static void yy_load_buffer_state YYFARGS0(void) M4_YY_DECL_GUTS_VAR(); YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_G(yytext_ptr) = YY_G(yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; +%if-c-only yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; +%endif +%if-c++-only + yyin.rdbuf(YY_CURRENT_BUFFER_LVALUE->yy_input_file); +%endif YY_G(yy_hold_char) = *YY_G(yy_c_buf_p); } @@ -2054,7 +2107,7 @@ static void yy_load_buffer_state YYFARGS0(void) YY_BUFFER_STATE yy_create_buffer YYFARGS2( FILE *,file, int ,size) %endif %if-c++-only - YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream& file, int size ) %endif { YY_BUFFER_STATE b; @@ -2080,6 +2133,19 @@ static void yy_load_buffer_state YYFARGS0(void) return b; } +%if-c++-only +/** Delegate creation of buffers to the new version that takes an istream reference. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * M4_YY_DOC_PARAM + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +{ + return yy_create_buffer( *file, size ); +} +%endif + /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * M4_YY_DOC_PARAM @@ -2114,7 +2180,7 @@ static void yy_load_buffer_state YYFARGS0(void) static void yy_init_buffer YYFARGS2( YY_BUFFER_STATE ,b, FILE *,file) %endif %if-c++-only - void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream& file ) %endif { @@ -2123,7 +2189,12 @@ static void yy_load_buffer_state YYFARGS0(void) yy_flush_buffer( b M4_YY_CALL_LAST_ARG); +%if-c-only b->yy_input_file = file; +%endif +%if-c++-only + b->yy_input_file = file.rdbuf(); +%endif b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ @@ -2279,7 +2350,7 @@ void yyFlexLexer::yyensure_buffer_stack(void) * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; + num_to_alloc = 1; // After all that talk, this was set to 1 anyways... YY_G(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) M4_YY_CALL_LAST_ARG); @@ -2862,7 +2933,7 @@ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) } %endif if-c-only - +%# Actually, that ended an if-rentrant section %if-c-only static int yy_init_globals YYFARGS0(void) -- 2.40.0