guc: reentrant scanner
Use the flex %option reentrant to make the generated scanner reentrant, and perhaps eventually thread-safe, but that will require additional work. Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Andreas Karlsson <andreas@proxel.se> Discussion: https://www.postgresql.org/message-id/flat/eb6faeac-2a8a-4b69-9189-c33c520e5b7b@eisentraut.org
This commit is contained in:
parent
2a7425d7ee
commit
d663f150b5
@ -57,6 +57,7 @@ static int GUC_flex_fatal(const char *msg);
|
|||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%option reentrant
|
||||||
%option 8bit
|
%option 8bit
|
||||||
%option never-interactive
|
%option never-interactive
|
||||||
%option nodefault
|
%option nodefault
|
||||||
@ -353,6 +354,8 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
unsigned int save_ConfigFileLineno = ConfigFileLineno;
|
unsigned int save_ConfigFileLineno = ConfigFileLineno;
|
||||||
sigjmp_buf *save_GUC_flex_fatal_jmp = GUC_flex_fatal_jmp;
|
sigjmp_buf *save_GUC_flex_fatal_jmp = GUC_flex_fatal_jmp;
|
||||||
sigjmp_buf flex_fatal_jmp;
|
sigjmp_buf flex_fatal_jmp;
|
||||||
|
yyscan_t scanner;
|
||||||
|
struct yyguts_t *yyg; /* needed for yytext macro */
|
||||||
volatile YY_BUFFER_STATE lex_buffer = NULL;
|
volatile YY_BUFFER_STATE lex_buffer = NULL;
|
||||||
int errorcount;
|
int errorcount;
|
||||||
int token;
|
int token;
|
||||||
@ -381,11 +384,15 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
ConfigFileLineno = 1;
|
ConfigFileLineno = 1;
|
||||||
errorcount = 0;
|
errorcount = 0;
|
||||||
|
|
||||||
lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE);
|
if (yylex_init(&scanner) != 0)
|
||||||
yy_switch_to_buffer(lex_buffer);
|
elog(elevel, "yylex_init() failed: %m");
|
||||||
|
yyg = (struct yyguts_t *) scanner;
|
||||||
|
|
||||||
|
lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE, scanner);
|
||||||
|
yy_switch_to_buffer(lex_buffer, scanner);
|
||||||
|
|
||||||
/* This loop iterates once per logical line */
|
/* This loop iterates once per logical line */
|
||||||
while ((token = yylex()))
|
while ((token = yylex(scanner)))
|
||||||
{
|
{
|
||||||
char *opt_name = NULL;
|
char *opt_name = NULL;
|
||||||
char *opt_value = NULL;
|
char *opt_value = NULL;
|
||||||
@ -400,9 +407,9 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
opt_name = pstrdup(yytext);
|
opt_name = pstrdup(yytext);
|
||||||
|
|
||||||
/* next we have an optional equal sign; discard if present */
|
/* next we have an optional equal sign; discard if present */
|
||||||
token = yylex();
|
token = yylex(scanner);
|
||||||
if (token == GUC_EQUALS)
|
if (token == GUC_EQUALS)
|
||||||
token = yylex();
|
token = yylex(scanner);
|
||||||
|
|
||||||
/* now we must have the option value */
|
/* now we must have the option value */
|
||||||
if (token != GUC_ID &&
|
if (token != GUC_ID &&
|
||||||
@ -417,7 +424,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
opt_value = pstrdup(yytext);
|
opt_value = pstrdup(yytext);
|
||||||
|
|
||||||
/* now we'd like an end of line, or possibly EOF */
|
/* now we'd like an end of line, or possibly EOF */
|
||||||
token = yylex();
|
token = yylex(scanner);
|
||||||
if (token != GUC_EOL)
|
if (token != GUC_EOL)
|
||||||
{
|
{
|
||||||
if (token != 0)
|
if (token != 0)
|
||||||
@ -438,7 +445,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
depth + 1, elevel,
|
depth + 1, elevel,
|
||||||
head_p, tail_p))
|
head_p, tail_p))
|
||||||
OK = false;
|
OK = false;
|
||||||
yy_switch_to_buffer(lex_buffer);
|
yy_switch_to_buffer(lex_buffer, scanner);
|
||||||
pfree(opt_name);
|
pfree(opt_name);
|
||||||
pfree(opt_value);
|
pfree(opt_value);
|
||||||
}
|
}
|
||||||
@ -453,7 +460,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
depth + 1, elevel,
|
depth + 1, elevel,
|
||||||
head_p, tail_p))
|
head_p, tail_p))
|
||||||
OK = false;
|
OK = false;
|
||||||
yy_switch_to_buffer(lex_buffer);
|
yy_switch_to_buffer(lex_buffer, scanner);
|
||||||
pfree(opt_name);
|
pfree(opt_name);
|
||||||
pfree(opt_value);
|
pfree(opt_value);
|
||||||
}
|
}
|
||||||
@ -468,7 +475,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
|
|||||||
depth + 1, elevel,
|
depth + 1, elevel,
|
||||||
head_p, tail_p))
|
head_p, tail_p))
|
||||||
OK = false;
|
OK = false;
|
||||||
yy_switch_to_buffer(lex_buffer);
|
yy_switch_to_buffer(lex_buffer, scanner);
|
||||||
pfree(opt_name);
|
pfree(opt_name);
|
||||||
pfree(opt_value);
|
pfree(opt_value);
|
||||||
}
|
}
|
||||||
@ -545,14 +552,15 @@ parse_error:
|
|||||||
|
|
||||||
/* resync to next end-of-line or EOF */
|
/* resync to next end-of-line or EOF */
|
||||||
while (token != GUC_EOL && token != 0)
|
while (token != GUC_EOL && token != 0)
|
||||||
token = yylex();
|
token = yylex(scanner);
|
||||||
/* break out of loop on EOF */
|
/* break out of loop on EOF */
|
||||||
if (token == 0)
|
if (token == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
yy_delete_buffer(lex_buffer);
|
yy_delete_buffer(lex_buffer, scanner);
|
||||||
|
yylex_destroy(scanner);
|
||||||
/* Each recursion level must save and restore these static variables. */
|
/* Each recursion level must save and restore these static variables. */
|
||||||
ConfigFileLineno = save_ConfigFileLineno;
|
ConfigFileLineno = save_ConfigFileLineno;
|
||||||
GUC_flex_fatal_jmp = save_GUC_flex_fatal_jmp;
|
GUC_flex_fatal_jmp = save_GUC_flex_fatal_jmp;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user