From: Andre Noll Date: Wed, 12 Jul 2017 09:43:25 +0000 (+0200) Subject: config_file.l: Instruct flex to create a reentrant scanner. X-Git-Tag: v1.0.1~1 X-Git-Url: http://git.tuebingen.mpg.de/?p=lopsub.git;a=commitdiff_plain;h=427af673591a006e351dcf76e5957ed67d4e0477 config_file.l: Instruct flex to create a reentrant scanner. This requires some modifications: * Most functions take an additional yyscan_t argument. * We must call yylex_init and yylex_destroy(). * Accessor methods must be used to get yytext and yylen. We used to set the initial start condition in lls_convert_config(), before the call to yylex(). For reentrant scanners, however, the BEGIN macro can not be used in the user code section where lls_convert_config() is located. But pushing a state works and should be equivalent. The generated scanner is not reentrant yet because it still has global variables. This issue will be addressed in a subsequent patch. --- diff --git a/config_file.l b/config_file.l index f6fff31..d055599 100644 --- a/config_file.l +++ b/config_file.l @@ -7,6 +7,9 @@ /* We don't want symbols to clash with those of other flex users. */ %option prefix="lls_yy" + /* Generate a scanner which is safe to use in multithreaded programs. */ +%option reentrant + %option stack %option never-interactive %option yylineno @@ -31,9 +34,9 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* static char **rargv; static const char *subcommand; - static int add_option(void); - static int parse_arg(char **result); - static int yywrap(void) {return 1;} + static int add_option(yyscan_t yyscanner); + static int parse_arg(char **result, yyscan_t yyscanner); + static int yywrap(yyscan_t yyscanner) {return 1;} %} %% @@ -62,10 +65,10 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* BEGIN(SC_SCANNING); } -{OPTION}[[:space:]]*\n add_option(); +{OPTION}[[:space:]]*\n add_option(yyscanner); {OPTION}({EQUALS}|[[:space:]]+) { - int ret = add_option(); + int ret = add_option(yyscanner); if (ret < 0) return ret; @@ -76,7 +79,7 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* const char *opt = rargv[rargc - 1]; char *arg, *result; size_t opt_len = strlen(opt), arg_len; - int ret = parse_arg(&arg); + int ret = parse_arg(&arg, yyscanner); if (ret < 0) return ret; @@ -118,13 +121,15 @@ static int expand_result(void) return 1; } -static int add_option(void) +static int add_option(yyscan_t yyscanner) { int ret; unsigned n; + int len = yyget_leng(yyscanner); + char *text = yyget_text(yyscanner); - for (n = 0; n < yyleng; n++) - if (!isalnum(yytext[n]) && !(yytext[n] == '-')) + for (n = 0; n < len; n++) + if (!isalnum(text[n]) && !(text[n] == '-')) break; assert(n > 0); ret = expand_result(); @@ -134,22 +139,24 @@ static int add_option(void) if (!rargv[rargc - 1]) return -E_LLS_NOMEM; rargv[rargc - 1][0] = rargv[rargc - 1][1] = '-'; - memcpy(rargv[rargc - 1] + 2, yytext, n); + memcpy(rargv[rargc - 1] + 2, text, n); rargv[rargc - 1][n + 2] = '\0'; return 1; } -static int parse_arg(char **result) +static int parse_arg(char **result, yyscan_t yyscanner) { bool backslash = false, quote = false; const char *in; char *out; int ret; + int len = yyget_leng(yyscanner); + char *text = yyget_text(yyscanner); - *result = malloc(yyleng + 1); + *result = malloc(len + 1); if (!*result) return -E_LLS_NOMEM; - for (in = yytext, out = *result; *in; in++) { + for (in = text, out = *result; *in; in++) { if (*in == '\\') { if (!backslash) { backslash = true; @@ -204,16 +211,16 @@ int lls_convert_config(const char *buf, size_t nbytes, const char *subcmd, { int ret; YY_BUFFER_STATE yybs; + yyscan_t yyscanner; *result = NULL; if (errctx) *errctx = NULL; + ret = yylex_init(&yyscanner); + assert(ret == 0); subcommand = subcmd; - if (!subcmd) - BEGIN(SC_SCANNING); - else - BEGIN(INITIAL); - yybs = yy_scan_bytes(buf, nbytes); + yy_push_state(subcmd? INITIAL : SC_SCANNING, yyscanner); + yybs = yy_scan_bytes(buf, nbytes, yyscanner); if (!yybs) return -E_LLS_YY_SCAN; rargc = 1; @@ -226,8 +233,9 @@ int lls_convert_config(const char *buf, size_t nbytes, const char *subcmd, return -E_LLS_NOMEM; } rargv[1] = NULL; - ret = yylex(); - yy_delete_buffer(yybs); + ret = yylex(yyscanner); + yy_delete_buffer(yybs, yyscanner); + yylex_destroy(yyscanner); if (ret >= 0) { *result = rargv; return rargc; @@ -235,7 +243,8 @@ int lls_convert_config(const char *buf, size_t nbytes, const char *subcmd, if (errctx) { *errctx = malloc(100); if (*errctx) - sprintf(*errctx, "error at line %d", yyget_lineno()); + sprintf(*errctx, "error at line %d", + yyget_lineno(yyscanner)); } for (; rargc >= 0; rargc--) free(rargv[rargc]);