diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2020-11-11 07:29:05 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2020-11-11 18:13:15 -0500 |
commit | 01850d3ba1f1d0bbfe45a24331fba2192da1f321 (patch) | |
tree | f94169fa34af115c1e1e0364e23810901ecc3329 | |
parent | 3854cd2c67e31ddfacfe5a6b3aba1347e63be420 (diff) | |
download | flex-git-01850d3ba1f1d0bbfe45a24331fba2192da1f321.tar.gz |
Eliminate almost all forward declarations from C99.
One less C-ism to deal wit h when porting to a new target languages.
-rw-r--r-- | src/c99-flex.skl | 1512 | ||||
-rw-r--r-- | tests/alloc_extra_c99.l | 19 |
2 files changed, 710 insertions, 821 deletions
diff --git a/src/c99-flex.skl b/src/c99-flex.skl index 8e55384..ed605a3 100644 --- a/src/c99-flex.skl +++ b/src/c99-flex.skl @@ -336,23 +336,9 @@ struct yy_buffer_state { int yy_buffer_status; }; -void yyrestart ( FILE *input_file, yyscan_t yyscanner ); -void yy_switch_to_buffer ( yybuffer new_buffer, yyscan_t yyscanner ); -yybuffer yy_create_buffer ( FILE *file, int size, yyscan_t yyscanner ); -void yy_delete_buffer ( yybuffer b, yyscan_t yyscanner ); -void yy_flush_buffer ( yybuffer b, yyscan_t yyscanner ); -void yypush_buffer_state ( yybuffer new_buffer, yyscan_t yyscanner ); -void yypop_buffer_state ( yyscan_t yyscanner ); - -static void yyensure_buffer_stack ( yyscan_t yyscanner ); -static void yy_load_buffer_state ( yyscan_t yyscanner ); -static void yy_init_buffer ( yybuffer b, FILE *file, yyscan_t yyscanner ); -static void yybumpline ( yyscan_t yyscanner ); - -yybuffer yy_scan_buffer ( char *base, yy_size_t size, yyscan_t yyscanner ); -yybuffer yy_scan_string ( const char *yy_str, yyscan_t yyscanner ); -yybuffer yy_scan_bytes ( const char *bytes, int len, yyscan_t yyscanner ); - +/* These forwards can simply deleted when poerting to a target language + * with two-pass name resoltion. + */ void *yyalloc ( yy_size_t, yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t, yyscan_t yyscanner ); void yyfree ( void *, yyscan_t yyscanner ); @@ -384,10 +370,7 @@ m4_define([[yytext_ptr]], [[yytext_r]]) %% [1.0] DFA -static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); -static void yynoreturn yypanic ( const char* msg, yyscan_t yyscanner ); struct yy_trans_info { /* We require that yy_verify and yy_nxt must be of the same size int. */ @@ -659,107 +642,274 @@ m4_ifdef([[M4_MODE_EXTRA_TYPE]], [[m4_dnl int yylex_init_extra ( M4_MODE_EXTRA_TYPE user_defined, yyscan_t* scanner); ]]) -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ +/* Helpers for special functions, also part of public API */ -m4_ifdef( [[M4_YY_NO_DESTROY]],, -[[ -int yylex_destroy ( yyscan_t yyscanner ); -]]) +/* Returns the top of the stack, or NULL. */ +yybuffer yy_current_buffer(yyscan_t yyscanner) { + return ( yyscanner->yy_buffer_stack \ + ? yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] \ + : NULL); +} -m4_ifdef( [[M4_YY_NO_GET_DEBUG]],, -[[ -int yyget_debug ( yyscan_t yyscanner ); -]]) +static void yy_load_buffer_state (yyscan_t yyscanner) +{ + yyscanner->yy_n_chars = yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_n_chars; + yyscanner->yytext_ptr = yyscanner->yy_c_buf_p = yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_buf_pos; + yyscanner->yyin_r = yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_input_file; + yyscanner->yy_hold_char = *yyscanner->yy_c_buf_p; +} -m4_ifdef( [[M4_YY_NO_SET_DEBUG]],, -[[ -void yyset_debug ( int debug_flag, yyscan_t yyscanner ); -]]) +/** Discard all buffered characters. On the next scan, yyread() will be called. + * @param b the buffer state to be flushed, usually @c yy_current_buffer(yyscanner). + * @param yyscanner The scanner object. + */ +void yy_flush_buffer(yybuffer b, yyscan_t yyscanner) +{ + if ( b == NULL ) { + return; + } + b->yy_n_chars = 0; -m4_ifdef([[M4_MODE_EXTRA_TYPE]], [[m4_dnl -m4_ifdef( [[M4_YY_NO_GET_EXTRA]],, -[[ -M4_MODE_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); -]]) + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; -m4_ifdef( [[M4_YY_NO_SET_EXTRA]],, -[[ -void yyset_extra ( M4_MODE_EXTRA_TYPE user_defined, yyscan_t yyscanner ); -]]) -]]) + b->yy_buf_pos = &b->yy_ch_buf[0]; -m4_ifdef( [[M4_YY_NO_GET_IN]],, -[[ -FILE *yyget_in ( yyscan_t yyscanner ); -]]) + b->yyatbol_flag = true; + b->yy_buffer_status = YY_BUFFER_NEW; -m4_ifdef( [[M4_YY_NO_SET_IN]],, -[[ -void yyset_in ( FILE * _in_str, yyscan_t yyscanner ); -]]) + if ( b == yy_current_buffer(yyscanner) ) { + yy_load_buffer_state( yyscanner ); + } +} -m4_ifdef( [[M4_YY_NO_GET_OUT]],, -[[ -FILE *yyget_out ( yyscan_t yyscanner ); -]]) +void yy_flush_current_buffer(yyscan_t yyscanner) { + yy_flush_buffer( yy_current_buffer(yyscanner), yyscanner); +} -m4_ifdef( [[M4_YY_NO_SET_OUT]],, -[[ -void yyset_out ( FILE * _out_str, yyscan_t yyscanner ); -]]) +const int YY_EXIT_FAILURE = 2; -m4_ifdef( [[M4_YY_NO_GET_LENG]],, -[[ - int yyget_leng ( yyscan_t yyscanner ); +m4_ifdef( [[M4_MODE_YY_NO_YYPANIC]],, [[ +/* This gfunction has a magic rewrite rule */ +static void yynoreturn yypanic(const char* msg, yyscan_t yyscanner) { + (void)yyscanner; /* forestall unused-argument warning */ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} ]]) -m4_ifdef( [[M4_YY_NO_GET_TEXT]],, -[[ -char *yyget_text ( yyscan_t yyscanner ); -]]) +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (yyscan_t yyscanner) +{ + yy_size_t num_to_alloc; -m4_ifdef( [[M4_YY_NO_GET_LINENO]],, -[[ -int yyget_lineno ( yyscan_t yyscanner ); -]]) + if (yyscanner->yy_buffer_stack == NULL) { + /* First allocation is just for 2 elements, since we don't know if this + * 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; /* After all that talk, this was set to 1 anyways... */ + yyscanner->yy_buffer_stack = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*), yyscanner); + if ( yyscanner->yy_buffer_stack == NULL ) { + yypanic( "out of dynamic memory in yyensure_buffer_stack()", yyscanner ); + } -m4_ifdef( [[M4_YY_NO_SET_LINENO]],, -[[ -void yyset_lineno ( int _line_number, yyscan_t yyscanner ); -]]) + memset(yyscanner->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); -m4_ifdef( [[M4_YY_NO_GET_COLUMN]],, -[[ -int yyget_column ( yyscan_t yyscanner ); -]]) + yyscanner->yy_buffer_stack_max = num_to_alloc; + yyscanner->yy_buffer_stack_top = 0; + return; + } -m4_ifdef( [[M4_YY_NO_SET_COLUMN]],, -[[ -void yyset_column ( int _column_no, yyscan_t yyscanner ); -]]) + if (yyscanner->yy_buffer_stack_top >= (yyscanner->yy_buffer_stack_max) - 1) { + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; -m4_ifdef([[M4_YY_BISON_LVAL]], [[ -m4_ifdef( [[M4_YY_NO_GET_LVAL]],, -[[ -YYSTYPE * yyget_lval ( yyscan_t yyscanner ); -]]) + num_to_alloc = yyscanner->yy_buffer_stack_max + grow_size; + yyscanner->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc + (yyscanner->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*), + yyscanner); + if (yyscanner->yy_buffer_stack == NULL) { + yypanic( "out of dynamic memory in yyensure_buffer_stack()", yyscanner ); + } + /* zero only the new slots.*/ + memset(yyscanner->yy_buffer_stack + yyscanner->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyscanner->yy_buffer_stack_max = num_to_alloc; + } +} -void yyset_lval ( YYSTYPE * yylval_param, yyscan_t yyscanner ); +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +static void yy_init_buffer(yybuffer b, FILE * file, yyscan_t yyscanner) +{ + int oerrno = errno; -m4_ifdef( [[<M4_YY_BISON_LLOC>]], + yy_flush_buffer( b, yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = true; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != yy_current_buffer(yyscanner)) { + b->bs_yylineno = 1; + b->bs_yycolumn = 0; + } + +m4_ifdef( [[M4_YY_ALWAYS_INTERACTIVE]], +[[ + b->yy_is_interactive = 1; +]], [[ - m4_ifdef( [[M4_YY_NO_GET_LLOC]],, + m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]], [[ - YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); - ]]) - - m4_ifdef( [[M4_YY_NO_SET_LLOC]],, + b->yy_is_interactive = 0; + ]], [[ - void yyset_lloc ( YYLTYPE * yylloc_param, yyscan_t yyscanner ); + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; ]]) ]]) -]]) + errno = oerrno; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ +yybuffer yy_create_buffer(FILE * file, int size, yyscan_t yyscanner) +{ + yybuffer b; + + b = (yybuffer) yyalloc( sizeof( struct yy_buffer_state ), yyscanner ); + if ( b == NULL ) { + yypanic( "out of dynamic memory in yy_create_buffer()", yyscanner ); + } + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2), yyscanner ); + if ( b->yy_ch_buf == NULL ) { + yypanic( "out of dynamic memory in yy_create_buffer()", yyscanner ); + } + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file, yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * @param yyscanner The scanner object. + */ +void yy_delete_buffer(yybuffer b, yyscan_t yyscanner) +{ + + if ( b == NULL ) { + return; + } + if ( b == yy_current_buffer(yyscanner) ) { /* Not sure if we should pop here. */ + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = (yybuffer) 0; + } + if ( b->yy_is_our_buffer ) { + yyfree( (void *) b->yy_ch_buf, yyscanner ); + } + yyfree( (void *) b, yyscanner ); +} + + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void yypush_buffer_state(yybuffer new_buffer, yyscan_t yyscanner) +{ + if (new_buffer == NULL) { + return; + } + yyensure_buffer_stack(yyscanner); + + /* This block is copied from yy_switch_to_buffer. */ + if ( yy_current_buffer(yyscanner) != NULL ) { + /* Flush out information for old buffer. */ + *yyscanner->yy_c_buf_p = yyscanner->yy_hold_char; + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_buf_pos = yyscanner->yy_c_buf_p; + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_n_chars = yyscanner->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (yy_current_buffer(yyscanner)) { + yyscanner->yy_buffer_stack_top++; + } + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( yyscanner ); + yyscanner->yy_did_buffer_switch_on_eof = true; +} + + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void yypop_buffer_state (yyscan_t yyscanner) +{ + if (yy_current_buffer(yyscanner) == NULL) { + return; + } + yy_delete_buffer(yy_current_buffer(yyscanner), yyscanner); + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = NULL; + if (yyscanner->yy_buffer_stack_top > 0) { + --yyscanner->yy_buffer_stack_top; + } + if (yy_current_buffer(yyscanner) != NULL) { + yy_load_buffer_state( yyscanner ); + yyscanner->yy_did_buffer_switch_on_eof = true; + } +} + + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ +void yyrestart(FILE * input_file, yyscan_t yyscanner) +{ + + if ( yy_current_buffer(yyscanner) == NULL ) { + yyensure_buffer_stack (yyscanner); + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = + yy_create_buffer( yyscanner->yyin_r, YY_BUF_SIZE, yyscanner); + } + + yy_init_buffer( yy_current_buffer(yyscanner), input_file, yyscanner); + yy_load_buffer_state( yyscanner ); +} + +static void yybumpline( yyscan_t yyscanner) { + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->bs_yylineno++; + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->bs_yycolumn=0; +} /* START special functions * @@ -939,16 +1089,6 @@ m4_define( [[M4_YY_NO_POP_STATE]]) m4_define( [[M4_YY_NO_TOP_STATE]]) ]]) -const int YY_EXIT_FAILURE = 2; - -m4_ifdef( [[M4_MODE_YY_NO_YYPANIC]],, [[ -static void yynoreturn yypanic(const char* msg, yyscan_t yyscanner) { - (void)yyscanner; /* forestall unused-argument warning */ - fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} -]]) - m4_ifdef( [[M4_MODE_USER_YYREAD]],, [[ /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". @@ -997,6 +1137,208 @@ m4_ifdef( [[M4_MODE_NO_CPP_USE_READ]], [[ } ]]) +/* STARTS Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +m4_ifdef([[M4_MODE_EXTRA_TYPE]], [[m4_dnl +m4_ifdef([[M4_YY_NO_GET_EXTRA]],, [[m4_dnl +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +M4_MODE_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { + return yyscanner->yyextra_r; +} +]]) +]]) + +m4_ifdef( [[M4_YY_NO_GET_LINENO]],, +[[ +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int yyget_lineno (yyscan_t yyscanner) { + yybuffer cb = yy_current_buffer(yyscanner); + + if (cb == NULL) { + return 0; + } + return cb->bs_yylineno; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_COLUMN]],, +[[ +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int yyget_column (yyscan_t yyscanner) { + yybuffer cb = yy_current_buffer(yyscanner); + + if (cb == NULL) { + return 0; + } + return cb->bs_yycolumn; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_IN]],, +[[ +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_in (yyscan_t yyscanner) { + return yyscanner->yyin_r; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_OUT]],, +[[ +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_out (yyscan_t yyscanner) { + return yyscanner->yyout_r; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_LENG]],, +[[ +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int yyget_leng (yyscan_t yyscanner) { + return yyscanner->yyleng_r; +} +]]) + +/** Get the current token. + * @param yyscanner The scanner object. + */ +m4_ifdef( [[M4_YY_NO_GET_TEXT]],, +[[ +char *yyget_text (yyscan_t yyscanner) { + return yyscanner->yytext_r; +} +]]) + +m4_ifdef([[M4_MODE_EXTRA_TYPE]], [[m4_dnl +m4_ifdef( [[M4_YY_NO_SET_EXTRA]],, +[[ +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void yyset_extra(M4_MODE_EXTRA_TYPE user_defined, yyscan_t yyscanner) { + yyscanner->yyextra_r = user_defined ; +} +]]) +]]) + +m4_ifdef( [[M4_YY_NO_SET_LINENO]],, +[[ +/** Set the current line number. + * @param _line_number line number + * @param yyscanner The scanner object. + */ +void yyset_lineno(int _line_number, yyscan_t yyscanner) { + yybuffer cb = yy_current_buffer(yyscanner); + + /* lineno is only valid if an input buffer exists. */ + if (cb == NULL ) { + yypanic( "yyset_lineno called with no buffer", yyscanner ); + } + cb->bs_yylineno = _line_number; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_COLUMN]],, +[[ +/** Set the current column. + * @param _column_no column number + * @param yyscanner The scanner object. + */ +void yyset_column(int _column_no, yyscan_t yyscanner) { + yybuffer cb = yy_current_buffer(yyscanner); + + /* column is only valid if an input buffer exists. */ + if (cb == NULL ) { + yypanic( "yyset_column called with no buffer", yyscanner ); + } + cb->bs_yycolumn = _column_no; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_IN]],, +[[ +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * @param yyscanner The scanner object. + * @see yy_switch_to_buffer + */ +void yyset_in(FILE * _in_str, yyscan_t yyscanner) { + yyscanner->yyin_r = _in_str ; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_OUT]],, +[[ +void yyset_out( FILE * _out_str, yyscan_t yyscanner) { + yyscanner->yyout_r = _out_str ; +} +]]) + + +m4_ifdef( [[M4_YY_NO_GET_DEBUG]],, +[[ +int yyget_debug (yyscan_t yyscanner) { + return yyscanner->yyflexdebug_r; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_DEBUG]],, +[[ +void yyset_debug(int _bdebug, yyscan_t yyscanner) { + yyscanner->yyflexdebug_r = _bdebug ; +} +]]) + +m4_ifdef([[M4_YY_BISON_LVAL]], [[ +m4_ifdef( [[M4_YY_NO_GET_LVAL]],, +[[ +YYSTYPE * yyget_lval (yyscan_t yyscanner) { + return yylval; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_LVAL]],, +[[ +void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner) { + yylval = yylval_param; +} +]]) + +m4_ifdef( [[<M4_YY_BISON_LLOC>]], +[[ +m4_ifdef( [[M4_YY_NO_GET_LLOC]],, +[[ +YYLTYPE *yyget_lloc (yyscan_t yyscanner) { + return yylloc; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_LLOC]],, +[[ +void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner) { + yylloc = yylloc_param; +} +]]) +]]) + +]]) + +/* ENDS public accessor functions */ + /* Number of entries by which start-condition stack grows. */ const int YY_START_STACK_INCR = 25; @@ -1090,17 +1432,6 @@ static void yy_lineno_rewind_to(char *yy_cp, char *dst, yyscan_t yyscanner) { } ]]) -/* Returns the top of the stack, or NULL. */ -yybuffer yy_current_buffer(yyscan_t yyscanner) { - return ( yyscanner->yy_buffer_stack \ - ? yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] \ - : NULL); -} - -void yy_flush_current_buffer(yyscan_t yyscanner) { - yy_flush_buffer( yy_current_buffer(yyscanner), yyscanner); -} - void yy_set_interactive(bool is_interactive, yyscan_t yyscanner) { if ( yy_current_buffer(yyscanner) == NULL ) { yyensure_buffer_stack (yyscanner); @@ -1111,11 +1442,6 @@ void yy_set_interactive(bool is_interactive, yyscan_t yyscanner) { } -static void yybumpline( yyscan_t yyscanner) { - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->bs_yylineno++; - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->bs_yycolumn=0; -} - m4_ifdef([[M4_MODE_YYMORE_USED]], [[ m4_ifdef( [[M4_MODE_YYTEXT_IS_ARRAY]], [[ void yymore(yyscan_t yyscanner) {yyscanner->yy_more_offset = strlen(yyscanner->yytext_r);} @@ -1151,6 +1477,134 @@ bool yyatbol(yyscan_t yyscanner) { return (yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yyatbol_flag); } +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ +void yy_switch_to_buffer(yybuffer new_buffer, yyscan_t yyscanner) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (yyscanner); + if ( yy_current_buffer(yyscanner) == new_buffer ) { + return; + } + if ( yy_current_buffer(yyscanner) ) { + /* Flush out information for old buffer. */ + *yyscanner->yy_c_buf_p = yyscanner->yy_hold_char; + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_buf_pos = yyscanner->yy_c_buf_p; + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_n_chars = yyscanner->yy_n_chars; + } + + yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = new_buffer; + yy_load_buffer_state( yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yyscanner->yy_did_buffer_switch_on_eof = true; +} + + +m4_ifdef( [[M4_YY_NO_SCAN_BUFFER]],, +[[ +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +yybuffer yy_scan_buffer(char * base, yy_size_t size, yyscan_t yyscanner) +{ + yybuffer b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) { + /* They forgot to leave room for the EOB's. */ + return NULL; + } + b = (yybuffer) yyalloc( sizeof( struct yy_buffer_state ), yyscanner ); + if ( b == NULL ) { + yypanic( "out of dynamic memory in yy_scan_buffer()", yyscanner ); + } + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yyatbol_flag = true; + b->yy_fill_buffer = false; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b, yyscanner ); + + return b; +} +]]) + +m4_ifdef( [[M4_YY_NO_SCAN_BYTES]],, +[[ +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +yybuffer yy_scan_bytes(const char * yybytes, int _yybytes_len, yyscan_t yyscanner) { + yybuffer b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n, yyscanner ); + if ( buf == 0 ) { + yypanic( "out of dynamic memory in yy_scan_bytes()", yyscanner ); + } + for ( i = 0; i < _yybytes_len; ++i ) { + buf[i] = yybytes[i]; + } + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n, yyscanner); + if ( b == NULL ) { + yypanic( "bad buffer in yy_scan_bytes()", yyscanner ); + } + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} +]]) + +m4_ifdef( [[M4_YY_NO_SCAN_STRING]],, +[[ +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +yybuffer yy_scan_string(const char * yystr, yyscan_t yyscanner) +{ + return yy_scan_bytes( yystr, (int) strlen(yystr), yyscanner); +} +]]) + %# Code snippets used in various cases of code generation in the main scanner. m4_define([[M4_GEN_BACKING_UP]], [[ @@ -1241,6 +1695,129 @@ m4_define([[M4_GEN_NEXT_MATCH_FULLSPD]], [[ } ]]) +/* + * Helpers for yylex() + */ + +%# Conditional indirection through an equivalence map +m4_ifdef([[M4_MODE_USEECS]], m4_define([[M4_EC]], [[*(yy_ec+$1)]])) +m4_ifdef([[M4_MODE_NO_USEECS]], [[m4_define([[M4_EC]], [[$1]])]]) + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { + yy_state_type yy_current_state; + char *yy_cp; + + M4_GEN_START_STATE + for ( yy_cp = yyscanner->yytext_ptr + YY_MORE_ADJ; yy_cp < yyscanner->yy_c_buf_p; ++yy_cp ) { + /* Generate the code to find the next state. */ + m4_ifdef([[M4_MODE_NO_NULTRANS]], [[m4_define([[CHAR_MAP_3]], [[(*yy_cp ? M4_EC(YY_SC_TO_UI(*yy_cp)) : YY_NUL_EC)]])]]) + m4_ifdef([[M4_MODE_NULTRANS]], [[m4_define([[CHAR_MAP_3]], [[M4_EC(YY_SC_TO_UI(*yy_cp))]])]]) + + m4_ifdef([[M4_MODE_NULTRANS]], [[ + /* Compressed tables back up *before* they match. */ + m4_ifdef([[M4_MODE_NO_FULLSPD_OR_FULLTBL]], [[M4_GEN_BACKING_UP]]) + if ( *yy_cp ) { + ]]) + + m4_ifdef([[M4_MODE_FIND_ACTION_FULLTBL]], [[ + m4_ifdef([[M4_MODE_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state][CHAR_MAP_3];]]) + m4_ifdef([[M4_MODE_NO_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + CHAR_MAP_3];]]) + ]]) + + m4_ifdef([[M4_MODE_FULLSPD]], [[yy_current_state += yy_current_state[CHAR_MAP_3].yy_nxt;]]) + m4_ifdef([[M4_MODE_NO_FULLSPD_OR_FULLTBL]], [[M4_GEN_NEXT_COMPRESSED_STATE(CHAR_MAP_3)]]) + +m4_ifdef([[M4_MODE_NULTRANS]], [[ + } else { + yy_current_state = yy_NUL_trans[yy_current_state]; + } +]]) + + m4_ifdef([[M4_MODE_FIND_ACTION_FULLTBL]], [[M4_GEN_BACKING_UP]]) + m4_ifdef([[M4_MODE_FULLSPD]], [[M4_GEN_BACKING_UP]]) + m4_ifdef([[M4_MODE_USES_REJECT]], [[*yyscanner->yy_state_ptr++ = yy_current_state;]]) + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state, yyscan_t yyscanner) +{ + bool yy_is_jam; + /* Generate code for handling NUL's, if needed. */ + + /* First, deal with backing up and setting up yy_cp if the scanner + * finds that it should JAM on the NUL. + * + * Only generate a definition for "yy_cp" if we'll generate code + * that uses it. Otherwise lint and the like complain. + */ + m4_ifdef([[M4_MODE_NEED_YY_CP]], [[char *yy_cp = yyscanner->yy_c_buf_p;]]) + +%# Note that this statement block and the following three are +%# not executed serially but are an if-then-else cascade +%# for different table modes. +m4_ifdef([[M4_MODE_NULTRANS]], [[ + yy_current_state = yy_NUL_trans[yy_current_state]; + yy_is_jam = (yy_current_state == 0); +]]) + +m4_ifdef([[M4_MODE_NO_NULTRANS]], [[ +m4_ifdef([[M4_MODE_NULTRANS_FULLTBL]], [[ +m4_ifdef([[M4_MODE_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state][YY_NUL_EC];]]) +m4_ifdef([[M4_MODE_NO_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + YY_NUL_EC];]]) + yy_is_jam = (yy_current_state <= 0); +]]) + +m4_ifdef([[M4_MODE_NO_NULTRANS_FULLTBL]], [[ +m4_ifdef([[M4_MODE_NULTRANS_FULLSPD]], [[ + int yy_c = YY_NUL_EC; + + const struct yy_trans_info *yy_trans_info; + + yy_trans_info = &yy_current_state[(unsigned int) yy_c]; + yy_current_state += yy_trans_info->yy_nxt; + yy_is_jam = (yy_trans_info->yy_verify != yy_c); +]]) + +m4_ifdef([[M4_MODE_NO_NULTRANS_FULLSPD]], [[ +M4_GEN_NEXT_COMPRESSED_STATE(YY_NUL_EC) +yy_is_jam = (yy_current_state == YY_JAMSTATE); +m4_ifdef([[M4_MODE_USES_REJECT]], [[ + /* Only stack this state if it's a transition we + * actually make. If we stack it on a jam, then + * the state stack and yy_c_buf_p get out of sync. + */ + if ( ! yy_is_jam ) { + *yyscanner->yy_state_ptr++ = yy_current_state; + } + ]]) +]]) +]]) +]]) +%# End of if-else cascade + +m4_ifdef([[M4_MODE_NULTRANS_WRAP]], [[ + /* If we've entered an accepting state, back up; note that + * compressed tables have *already* done such backing up, so + * we needn't bother with it again. + */ + if ( ! yy_is_jam ) { + M4_GEN_BACKING_UP + } +]]) + + (void)yyscanner; /* forestall unused-argument warning */ + return yy_is_jam ? 0 : yy_current_state; +} + /** The main scanner function which does all the work. */ YY_DECL { @@ -1320,10 +1897,6 @@ M4_GEN_START_STATE yy_match: /* Generate the code to find the next match. */ -%# Conditional indirection through an equivalence map -m4_ifdef([[M4_MODE_USEECS]], m4_define([[M4_EC]], [[*(yy_ec+$1)]])) -m4_ifdef([[M4_MODE_NO_USEECS]], [[m4_define([[M4_EC]], [[$1]])]]) - m4_ifdef([[M4_MODE_FIND_ACTION_FULLTBL]], [[m4_dnl m4_ifdef([[M4_MODE_GENTABLES]], [[m4_dnl while ((yy_current_state = yy_nxt[yy_current_state][ M4_EC(YY_SC_TO_UI(*yy_cp)) ]) > 0) { @@ -1748,492 +2321,6 @@ m4_ifdef( [[M4_MODE_USES_REJECT]], return ret_val; } -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - yy_state_type yy_current_state; - char *yy_cp; - - M4_GEN_START_STATE - for ( yy_cp = yyscanner->yytext_ptr + YY_MORE_ADJ; yy_cp < yyscanner->yy_c_buf_p; ++yy_cp ) { - /* Generate the code to find the next state. */ - m4_ifdef([[M4_MODE_NO_NULTRANS]], [[m4_define([[CHAR_MAP_3]], [[(*yy_cp ? M4_EC(YY_SC_TO_UI(*yy_cp)) : YY_NUL_EC)]])]]) - m4_ifdef([[M4_MODE_NULTRANS]], [[m4_define([[CHAR_MAP_3]], [[M4_EC(YY_SC_TO_UI(*yy_cp))]])]]) - - m4_ifdef([[M4_MODE_NULTRANS]], [[ - /* Compressed tables back up *before* they match. */ - m4_ifdef([[M4_MODE_NO_FULLSPD_OR_FULLTBL]], [[M4_GEN_BACKING_UP]]) - if ( *yy_cp ) { - ]]) - - m4_ifdef([[M4_MODE_FIND_ACTION_FULLTBL]], [[ - m4_ifdef([[M4_MODE_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state][CHAR_MAP_3];]]) - m4_ifdef([[M4_MODE_NO_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + CHAR_MAP_3];]]) - ]]) - - m4_ifdef([[M4_MODE_FULLSPD]], [[yy_current_state += yy_current_state[CHAR_MAP_3].yy_nxt;]]) - m4_ifdef([[M4_MODE_NO_FULLSPD_OR_FULLTBL]], [[M4_GEN_NEXT_COMPRESSED_STATE(CHAR_MAP_3)]]) - -m4_ifdef([[M4_MODE_NULTRANS]], [[ - } else { - yy_current_state = yy_NUL_trans[yy_current_state]; - } -]]) - - m4_ifdef([[M4_MODE_FIND_ACTION_FULLTBL]], [[M4_GEN_BACKING_UP]]) - m4_ifdef([[M4_MODE_FULLSPD]], [[M4_GEN_BACKING_UP]]) - m4_ifdef([[M4_MODE_USES_REJECT]], [[*yyscanner->yy_state_ptr++ = yy_current_state;]]) - } - - return yy_current_state; -} - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ -static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state, yyscan_t yyscanner) -{ - bool yy_is_jam; - /* Generate code for handling NUL's, if needed. */ - - /* First, deal with backing up and setting up yy_cp if the scanner - * finds that it should JAM on the NUL. - * - * Only generate a definition for "yy_cp" if we'll generate code - * that uses it. Otherwise lint and the like complain. - */ - m4_ifdef([[M4_MODE_NEED_YY_CP]], [[char *yy_cp = yyscanner->yy_c_buf_p;]]) - -%# Note that this statement block and the following three are -%# not executed serially but are an if-then-else cascade -%# for different table modes. -m4_ifdef([[M4_MODE_NULTRANS]], [[ - yy_current_state = yy_NUL_trans[yy_current_state]; - yy_is_jam = (yy_current_state == 0); -]]) - -m4_ifdef([[M4_MODE_NO_NULTRANS]], [[ -m4_ifdef([[M4_MODE_NULTRANS_FULLTBL]], [[ -m4_ifdef([[M4_MODE_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state][YY_NUL_EC];]]) -m4_ifdef([[M4_MODE_NO_GENTABLES]], [[yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + YY_NUL_EC];]]) - yy_is_jam = (yy_current_state <= 0); -]]) - -m4_ifdef([[M4_MODE_NO_NULTRANS_FULLTBL]], [[ -m4_ifdef([[M4_MODE_NULTRANS_FULLSPD]], [[ - int yy_c = YY_NUL_EC; - - const struct yy_trans_info *yy_trans_info; - - yy_trans_info = &yy_current_state[(unsigned int) yy_c]; - yy_current_state += yy_trans_info->yy_nxt; - yy_is_jam = (yy_trans_info->yy_verify != yy_c); -]]) - -m4_ifdef([[M4_MODE_NO_NULTRANS_FULLSPD]], [[ -M4_GEN_NEXT_COMPRESSED_STATE(YY_NUL_EC) -yy_is_jam = (yy_current_state == YY_JAMSTATE); -m4_ifdef([[M4_MODE_USES_REJECT]], [[ - /* Only stack this state if it's a transition we - * actually make. If we stack it on a jam, then - * the state stack and yy_c_buf_p get out of sync. - */ - if ( ! yy_is_jam ) { - *yyscanner->yy_state_ptr++ = yy_current_state; - } - ]]) -]]) -]]) -]]) -%# End of if-else cascade - -m4_ifdef([[M4_MODE_NULTRANS_WRAP]], [[ - /* If we've entered an accepting state, back up; note that - * compressed tables have *already* done such backing up, so - * we needn't bother with it again. - */ - if ( ! yy_is_jam ) { - M4_GEN_BACKING_UP - } -]]) - - (void)yyscanner; /* forestall unused-argument warning */ - return yy_is_jam ? 0 : yy_current_state; -} - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ -void yyrestart(FILE * input_file, yyscan_t yyscanner) -{ - - if ( yy_current_buffer(yyscanner) == NULL ) { - yyensure_buffer_stack (yyscanner); - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = - yy_create_buffer( yyscanner->yyin_r, YY_BUF_SIZE, yyscanner); - } - - yy_init_buffer( yy_current_buffer(yyscanner), input_file, yyscanner); - yy_load_buffer_state( yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ -void yy_switch_to_buffer(yybuffer new_buffer, yyscan_t yyscanner) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (yyscanner); - if ( yy_current_buffer(yyscanner) == new_buffer ) { - return; - } - if ( yy_current_buffer(yyscanner) ) { - /* Flush out information for old buffer. */ - *yyscanner->yy_c_buf_p = yyscanner->yy_hold_char; - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_buf_pos = yyscanner->yy_c_buf_p; - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_n_chars = yyscanner->yy_n_chars; - } - - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = new_buffer; - yy_load_buffer_state( yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yyscanner->yy_did_buffer_switch_on_eof = true; -} - - -static void yy_load_buffer_state (yyscan_t yyscanner) -{ - yyscanner->yy_n_chars = yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_n_chars; - yyscanner->yytext_ptr = yyscanner->yy_c_buf_p = yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_buf_pos; - yyscanner->yyin_r = yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_input_file; - yyscanner->yy_hold_char = *yyscanner->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ -yybuffer yy_create_buffer(FILE * file, int size, yyscan_t yyscanner) -{ - yybuffer b; - - b = (yybuffer) yyalloc( sizeof( struct yy_buffer_state ), yyscanner ); - if ( b == NULL ) { - yypanic( "out of dynamic memory in yy_create_buffer()", yyscanner ); - } - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2), yyscanner ); - if ( b->yy_ch_buf == NULL ) { - yypanic( "out of dynamic memory in yy_create_buffer()", yyscanner ); - } - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file, yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * @param yyscanner The scanner object. - */ -void yy_delete_buffer(yybuffer b, yyscan_t yyscanner) -{ - - if ( b == NULL ) { - return; - } - if ( b == yy_current_buffer(yyscanner) ) { /* Not sure if we should pop here. */ - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = (yybuffer) 0; - } - if ( b->yy_is_our_buffer ) { - yyfree( (void *) b->yy_ch_buf, yyscanner ); - } - yyfree( (void *) b, yyscanner ); -} - - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ -static void yy_init_buffer(yybuffer b, FILE * file, yyscan_t yyscanner) -{ - int oerrno = errno; - - yy_flush_buffer( b, yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = true; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != yy_current_buffer(yyscanner)) { - b->bs_yylineno = 1; - b->bs_yycolumn = 0; - } - -m4_ifdef( [[M4_YY_ALWAYS_INTERACTIVE]], -[[ - b->yy_is_interactive = 1; -]], -[[ - m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]], - [[ - b->yy_is_interactive = 0; - ]], - [[ - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - ]]) -]]) - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, yyread() will be called. - * @param b the buffer state to be flushed, usually @c yy_current_buffer(yyscanner). - * @param yyscanner The scanner object. - */ -void yy_flush_buffer(yybuffer b, yyscan_t yyscanner) -{ - if ( b == NULL ) { - return; - } - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yyatbol_flag = true; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer(yyscanner) ) { - yy_load_buffer_state( yyscanner ); - } -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void yypush_buffer_state(yybuffer new_buffer, yyscan_t yyscanner) -{ - if (new_buffer == NULL) { - return; - } - yyensure_buffer_stack(yyscanner); - - /* This block is copied from yy_switch_to_buffer. */ - if ( yy_current_buffer(yyscanner) != NULL ) { - /* Flush out information for old buffer. */ - *yyscanner->yy_c_buf_p = yyscanner->yy_hold_char; - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_buf_pos = yyscanner->yy_c_buf_p; - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top]->yy_n_chars = yyscanner->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (yy_current_buffer(yyscanner)) { - yyscanner->yy_buffer_stack_top++; - } - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( yyscanner ); - yyscanner->yy_did_buffer_switch_on_eof = true; -} - - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void yypop_buffer_state (yyscan_t yyscanner) -{ - if (yy_current_buffer(yyscanner) == NULL) { - return; - } - yy_delete_buffer(yy_current_buffer(yyscanner), yyscanner); - yyscanner->yy_buffer_stack[yyscanner->yy_buffer_stack_top] = NULL; - if (yyscanner->yy_buffer_stack_top > 0) { - --yyscanner->yy_buffer_stack_top; - } - if (yy_current_buffer(yyscanner) != NULL) { - yy_load_buffer_state( yyscanner ); - yyscanner->yy_did_buffer_switch_on_eof = true; - } -} - - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (yyscan_t yyscanner) -{ - yy_size_t num_to_alloc; - - if (yyscanner->yy_buffer_stack == NULL) { - /* First allocation is just for 2 elements, since we don't know if this - * 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; /* After all that talk, this was set to 1 anyways... */ - yyscanner->yy_buffer_stack = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*), yyscanner); - if ( yyscanner->yy_buffer_stack == NULL ) { - yypanic( "out of dynamic memory in yyensure_buffer_stack()", yyscanner ); - } - - memset(yyscanner->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyscanner->yy_buffer_stack_max = num_to_alloc; - yyscanner->yy_buffer_stack_top = 0; - return; - } - - if (yyscanner->yy_buffer_stack_top >= (yyscanner->yy_buffer_stack_max) - 1) { - /* Increase the buffer to prepare for a possible push. */ - yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyscanner->yy_buffer_stack_max + grow_size; - yyscanner->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc - (yyscanner->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*), - yyscanner); - if (yyscanner->yy_buffer_stack == NULL) { - yypanic( "out of dynamic memory in yyensure_buffer_stack()", yyscanner ); - } - /* zero only the new slots.*/ - memset(yyscanner->yy_buffer_stack + yyscanner->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyscanner->yy_buffer_stack_max = num_to_alloc; - } -} - -m4_ifdef( [[M4_YY_NO_SCAN_BUFFER]],, -[[ -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -yybuffer yy_scan_buffer(char * base, yy_size_t size, yyscan_t yyscanner) -{ - yybuffer b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) { - /* They forgot to leave room for the EOB's. */ - return NULL; - } - b = (yybuffer) yyalloc( sizeof( struct yy_buffer_state ), yyscanner ); - if ( b == NULL ) { - yypanic( "out of dynamic memory in yy_scan_buffer()", yyscanner ); - } - b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = NULL; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yyatbol_flag = true; - b->yy_fill_buffer = false; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b, yyscanner ); - - return b; -} -]]) - -m4_ifdef( [[M4_YY_NO_SCAN_STRING]],, -[[ -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -yybuffer yy_scan_string(const char * yystr, yyscan_t yyscanner) -{ - return yy_scan_bytes( yystr, (int) strlen(yystr), yyscanner); -} -]]) - -m4_ifdef( [[M4_YY_NO_SCAN_BYTES]],, -[[ -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -yybuffer yy_scan_bytes(const char * yybytes, int _yybytes_len, yyscan_t yyscanner) { - yybuffer b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = (yy_size_t) (_yybytes_len + 2); - buf = (char *) yyalloc( n, yyscanner ); - if ( buf == 0 ) { - yypanic( "out of dynamic memory in yy_scan_bytes()", yyscanner ); - } - for ( i = 0; i < _yybytes_len; ++i ) { - buf[i] = yybytes[i]; - } - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n, yyscanner); - if ( b == NULL ) { - yypanic( "bad buffer in yy_scan_bytes()", yyscanner ); - } - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} -]]) - - m4_ifdef( [[M4_YY_NO_PUSH_STATE]],, [[ static void yy_push_state(int _new_state, yyscan_t yyscanner) @@ -2296,205 +2383,6 @@ void yyless(int n, yyscan_t yyscanner) { yyscanner->yyleng_r = n; } -/* Accessor methods (get/set functions) to struct members. */ - -m4_ifdef([[M4_MODE_EXTRA_TYPE]], [[m4_dnl -m4_ifdef([[M4_YY_NO_GET_EXTRA]],, [[m4_dnl -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -M4_MODE_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { - return yyscanner->yyextra_r; -} -]]) -]]) - -m4_ifdef( [[M4_YY_NO_GET_LINENO]],, -[[ -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int yyget_lineno (yyscan_t yyscanner) { - yybuffer cb = yy_current_buffer(yyscanner); - - if (cb == NULL) { - return 0; - } - return cb->bs_yylineno; -} -]]) - -m4_ifdef( [[M4_YY_NO_GET_COLUMN]],, -[[ -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int yyget_column (yyscan_t yyscanner) { - yybuffer cb = yy_current_buffer(yyscanner); - - if (cb == NULL) { - return 0; - } - return cb->bs_yycolumn; -} -]]) - -m4_ifdef( [[M4_YY_NO_GET_IN]],, -[[ -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_in (yyscan_t yyscanner) { - return yyscanner->yyin_r; -} -]]) - -m4_ifdef( [[M4_YY_NO_GET_OUT]],, -[[ -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_out (yyscan_t yyscanner) { - return yyscanner->yyout_r; -} -]]) - -m4_ifdef( [[M4_YY_NO_GET_LENG]],, -[[ -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int yyget_leng (yyscan_t yyscanner) { - return yyscanner->yyleng_r; -} -]]) - -/** Get the current token. - * @param yyscanner The scanner object. - */ -m4_ifdef( [[M4_YY_NO_GET_TEXT]],, -[[ -char *yyget_text (yyscan_t yyscanner) { - return yyscanner->yytext_r; -} -]]) - -m4_ifdef([[M4_MODE_EXTRA_TYPE]], [[m4_dnl -m4_ifdef( [[M4_YY_NO_SET_EXTRA]],, -[[ -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void yyset_extra(M4_MODE_EXTRA_TYPE user_defined, yyscan_t yyscanner) { - yyscanner->yyextra_r = user_defined ; -} -]]) -]]) - -m4_ifdef( [[M4_YY_NO_SET_LINENO]],, -[[ -/** Set the current line number. - * @param _line_number line number - * @param yyscanner The scanner object. - */ -void yyset_lineno(int _line_number, yyscan_t yyscanner) { - yybuffer cb = yy_current_buffer(yyscanner); - - /* lineno is only valid if an input buffer exists. */ - if (cb == NULL ) { - yypanic( "yyset_lineno called with no buffer", yyscanner ); - } - cb->bs_yylineno = _line_number; -} -]]) - -m4_ifdef( [[M4_YY_NO_SET_COLUMN]],, -[[ -/** Set the current column. - * @param _column_no column number - * @param yyscanner The scanner object. - */ -void yyset_column(int _column_no, yyscan_t yyscanner) { - yybuffer cb = yy_current_buffer(yyscanner); - - /* column is only valid if an input buffer exists. */ - if (cb == NULL ) { - yypanic( "yyset_column called with no buffer", yyscanner ); - } - cb->bs_yycolumn = _column_no; -} -]]) - -m4_ifdef( [[M4_YY_NO_SET_IN]],, -[[ -/** Set the input stream. This does not discard the current - * input buffer. - * @param _in_str A readable stream. - * @param yyscanner The scanner object. - * @see yy_switch_to_buffer - */ -void yyset_in(FILE * _in_str, yyscan_t yyscanner) { - yyscanner->yyin_r = _in_str ; -} -]]) - -m4_ifdef( [[M4_YY_NO_SET_OUT]],, -[[ -void yyset_out( FILE * _out_str, yyscan_t yyscanner) { - yyscanner->yyout_r = _out_str ; -} -]]) - - -m4_ifdef( [[M4_YY_NO_GET_DEBUG]],, -[[ -int yyget_debug (yyscan_t yyscanner) { - return yyscanner->yyflexdebug_r; -} -]]) - -m4_ifdef( [[M4_YY_NO_SET_DEBUG]],, -[[ -void yyset_debug(int _bdebug, yyscan_t yyscanner) { - yyscanner->yyflexdebug_r = _bdebug ; -} -]]) - -m4_ifdef([[M4_YY_BISON_LVAL]], [[ -m4_ifdef( [[M4_YY_NO_GET_LVAL]],, -[[ -YYSTYPE * yyget_lval (yyscan_t yyscanner) { - return yylval; -} -]]) - -m4_ifdef( [[M4_YY_NO_SET_LVAL]],, -[[ -void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner) { - yylval = yylval_param; -} -]]) - -m4_ifdef( [[<M4_YY_BISON_LLOC>]], -[[ -m4_ifdef( [[M4_YY_NO_GET_LLOC]],, -[[ -YYLTYPE *yyget_lloc (yyscan_t yyscanner) { - return yylloc; -} -]]) - -m4_ifdef( [[M4_YY_NO_SET_LLOC]],, -[[ -void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner) { - yylloc = yylloc_param; -} -]]) -]]) - -]]) - /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is diff --git a/tests/alloc_extra_c99.l b/tests/alloc_extra_c99.l index ccc035d..67c3526 100644 --- a/tests/alloc_extra_c99.l +++ b/tests/alloc_extra_c99.l @@ -46,7 +46,7 @@ static void check_extra ( yyscan_t scanner ); %} %option emit="c99" -%option 8bit prefix="test" +%option 8bit %option nounput nomain noyywrap nodefault noinput %option warn %option extra-type="struct Check *" @@ -71,25 +71,26 @@ main (void) check.bar = NULL; check.qux = 'z'; - testlex_init_extra(&check, &scanner); - testset_in(stdin, scanner); - testset_out(stdout, scanner); + yylex_init_extra(&check, &scanner); + yyset_in(stdin, scanner); + yyset_out(stdout, scanner); /* Test to confirm that testalloc was called from * testlex_init_extra with the testextra argument. */ check_extra(scanner); - testlex(scanner); + yylex(scanner); - testlex_destroy(scanner); + yylex_destroy(scanner); return 0; } -void *testalloc(size_t size, yyscan_t scanner) +/* Replaces the stock yyalloc */ +void *yyalloc(size_t size, yyscan_t scanner) { struct Check *check; - check = testget_extra(scanner); + check = yyget_extra(scanner); if (!check->bar) check->bar = "Hello World"; @@ -103,7 +104,7 @@ void *testalloc(size_t size, yyscan_t scanner) static void check_extra(yyscan_t scanner) { struct Check *check; - check = testget_extra(scanner); + check = yyget_extra(scanner); if (check->foo != 'a') { fprintf(stderr, "foo is not 'a'\n"); |