summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Millaway <john43@users.sourceforge.net>2006-02-15 18:06:21 +0000
committerJohn Millaway <john43@users.sourceforge.net>2006-02-15 18:06:21 +0000
commita70cd6d676201a9c8a827e882c7fb4ee2b6f18f2 (patch)
tree5065b4795f14907dc645c72c1d368e7d886b357a
parentdbf9f014899fb78cca1192c39585cbc7220c20fe (diff)
yy_lex_destroy calls yy_init_globals to reset everything for next call to yylex.
Added two new tests for reusing scanners.
-rw-r--r--configure.in2
-rw-r--r--flex.skl110
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/descriptions2
4 files changed, 72 insertions, 46 deletions
diff --git a/configure.in b/configure.in
index b569776..795132d 100644
--- a/configure.in
+++ b/configure.in
@@ -143,6 +143,8 @@ tests/test-bison-nr/Makefile
tests/test-reject/Makefile
tests/test-c++-multiple-scanners/Makefile
tests/test-top/Makefile
+tests/test-rescan-nr/Makefile
+tests/test-rescan-r/Makefile
dnl --new-test-here-- This line is processed by tests/create-test.
)
diff --git a/flex.skl b/flex.skl
index 52359de..7f32501 100644
--- a/flex.skl
+++ b/flex.skl
@@ -66,6 +66,10 @@ m4_changequote([[, ]])
m4_ifdef( [[M4_YY_IN_HEADER]], , [[m4_define([[M4_YY_NOT_IN_HEADER]], [[]])]])
m4_ifdef( [[M4_YY_REENTRANT]], , [[m4_define([[M4_YY_NOT_REENTRANT]], [[]])]])
+%# This is the m4 way to say "(stack_used || is_reentrant)
+m4_ifdef( [[M4_YY_STACK_USED]], [[m4_define([[M4_YY_HAS_START_STACK_VARS]])]])
+m4_ifdef( [[M4_YY_REENTRANT]], [[m4_define([[M4_YY_HAS_START_STACK_VARS]])]])
+
%# Prefixes.
%# The complexity here is necessary so that m4 preserves
%# the argument lists to each C function.
@@ -610,7 +614,7 @@ int yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
+static int yy_init = 0; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
/* Flag which is used to allow yywrap()'s to do buffer switches
@@ -811,10 +815,12 @@ m4_ifdef( [[<M4_YY_BISON_LLOC>]],
]])
+%if-c-only
m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
[[
static int yy_init_globals M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
]])
+%endif
%if-reentrant
@@ -978,7 +984,7 @@ m4_ifdef( [[M4_YY_NOT_REENTRANT]],
[[
static int yy_start_stack_ptr = 0;
static int yy_start_stack_depth = 0;
- static int *yy_start_stack = 0;
+ static int *yy_start_stack = NULL;
]])
]])
@@ -1209,9 +1215,9 @@ m4_ifdef( [[<M4_YY_BISON_LLOC>]],
yylloc = yylloc_param;
]])
- if ( YY_G(yy_init) )
+ if ( !YY_G(yy_init) )
{
- YY_G(yy_init) = 0;
+ YY_G(yy_init) = 1;
#ifdef YY_USER_INIT
YY_USER_INIT;
@@ -1418,7 +1424,7 @@ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
yyin = arg_yyin;
yyout = arg_yyout;
yy_c_buf_p = 0;
- yy_init = 1;
+ yy_init = 0;
yy_start = 0;
yy_flex_debug = 0;
yylineno = 1; // this will only get updated if %option yylineno
@@ -1431,7 +1437,7 @@ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
yy_more_offset = yy_prev_more_offset = 0;
yy_start_stack_ptr = yy_start_stack_depth = 0;
- yy_start_stack = 0;
+ yy_start_stack = NULL;
YY_G(yy_buffer_stack) = 0;
YY_G(yy_buffer_stack_top) = 0;
@@ -2669,11 +2675,48 @@ void yyset_lloc YYFARGS1( YYLTYPE * ,yylloc_param)
%endif
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
+[[
+int yylex_init( ptr_yy_globals )
+ yyscan_t* ptr_yy_globals;
+]],
+[[
+int yylex_init(yyscan_t* ptr_yy_globals)
+]])
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+%endif
+
+%if-c-only
static int yy_init_globals YYFARGS0(void)
{
M4_YY_DECL_GUTS_VAR();
/* Initialization is the same as for the non-reentrant scanner.
- This function is called once per scanner lifetime. */
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
m4_ifdef( [[M4_YY_USE_LINENO]],
[[
@@ -2687,11 +2730,15 @@ m4_ifdef( [[M4_YY_USE_LINENO]],
YY_G(yy_buffer_stack_top) = 0;
YY_G(yy_buffer_stack_max) = 0;
YY_G(yy_c_buf_p) = (char *) 0;
- YY_G(yy_init) = 1;
+ YY_G(yy_init) = 0;
YY_G(yy_start) = 0;
+
+m4_ifdef( [[M4_YY_HAS_START_STACK_VARS]],
+[[
YY_G(yy_start_stack_ptr) = 0;
YY_G(yy_start_stack_depth) = 0;
- YY_G(yy_start_stack) = (int *) 0;
+ YY_G(yy_start_stack) = NULL;
+]])
m4_ifdef( [[M4_YY_USES_REJECT]],
[[
@@ -2722,41 +2769,9 @@ m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],
*/
return 0;
}
-
-/* User-visible API */
-
-/* yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
-[[
-int yylex_init( ptr_yy_globals )
- yyscan_t* ptr_yy_globals;
-]],
-[[
-int yylex_init(yyscan_t* ptr_yy_globals)
-]])
-{
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- memset(*ptr_yy_globals,0,sizeof(struct yyguts_t));
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
%endif
+
%if-c-only SNIP! this currently causes conflicts with the c++ scanner
/* yylex_destroy is for both reentrant and non-reentrant scanners. */
int yylex_destroy YYFARGS0(void)
@@ -2774,10 +2789,7 @@ int yylex_destroy YYFARGS0(void)
yyfree(YY_G(yy_buffer_stack) M4_YY_CALL_LAST_ARG);
YY_G(yy_buffer_stack) = NULL;
-%# This is the m4 way to say "if (stack_used || is_reentrant){ destroy_stack }"
-m4_ifdef( [[M4_YY_STACK_USED]], [[m4_define([[M4_YY_DESTROY_START_STACK]])]])
-m4_ifdef( [[M4_YY_REENTRANT]], [[m4_define([[M4_YY_DESTROY_START_STACK]])]])
-m4_ifdef( [[M4_YY_DESTROY_START_STACK]],
+m4_ifdef( [[M4_YY_HAS_START_STACK_VARS]],
[[
/* Destroy the start condition stack. */
yyfree( YY_G(yy_start_stack) M4_YY_CALL_LAST_ARG );
@@ -2787,11 +2799,17 @@ m4_ifdef( [[M4_YY_DESTROY_START_STACK]],
m4_ifdef( [[M4_YY_USES_REJECT]],
[[
yyfree ( YY_G(yy_state_buf) M4_YY_CALL_LAST_ARG);
+ YY_G(yy_state_buf) = NULL;
]])
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( M4_YY_CALL_ONLY_ARG);
+
%if-reentrant
/* Destroy the main struct (reentrant only). */
yyfree ( yyscanner M4_YY_CALL_LAST_ARG );
+ yyscanner = NULL;
%endif
return 0;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f3b78ef..ef8b473 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -26,6 +26,8 @@ dist_noinst_SCRIPTS = \
create-test
DIST_SUBDIRS = \
+ test-rescan-r \
+ test-rescan-nr \
test-basic-nr \
test-basic-r \
test-bison-yylloc \
@@ -67,6 +69,8 @@ DIST_SUBDIRS = \
test-table-opts
SUBDIRS = \
+ test-rescan-r \
+ test-rescan-nr \
test-basic-nr \
test-basic-r \
test-bison-yylloc \
diff --git a/tests/descriptions b/tests/descriptions
index 6dc76c4..9c6b585 100644
--- a/tests/descriptions
+++ b/tests/descriptions
@@ -34,6 +34,8 @@ prefix-nr - Verify prefixes are working, nonreentrant.
prefix-r - Verify prefixes are working, reentrant.
pthread - Pthreads test. A NO-OP if libpthread not found.
reject - Check REJECT code.
+rescan-nr - Reuse same scanner several times, nonreentrant.
+rescan-r - Reuse same scanner several times, reentrant.
string-nr - Scan strings, non-reentrant.
string-r - Scan strings, reentrant.
table-opts - Try every table compression option.