8000 guc: reentrant scanner · postgres/postgres@d663f15 · GitHub
[go: up one dir, main page]

Skip to content

Commit d663f15

Browse files
committed
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
1 parent 2a7425d commit d663f15

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/backend/utils/misc/guc-file.l

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static int GUC_flex_fatal(const char *msg);
5757

5858
%}
5959

60+
%option reentrant
6061
%option 8bit
6162
%option never-interactive
6263
%option nodefault
@@ -353,6 +354,8 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
353354
unsigned int save_ConfigFileLineno = ConfigFileLineno;
354355
sigjmp_buf *save_GUC_flex_fatal_jmp = GUC_flex_fatal_jmp;
355356
sigjmp_buf flex_fatal_jmp;
357+
yyscan_t scanner;
358+
struct yyguts_t *yyg; /* needed for yytext macro */
356359
volatile YY_BUFFER_STATE lex_buffer = NULL;
357360
int errorcount;
358361
int token;
@@ -381,11 +384,15 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
381384
ConfigFileLineno = 1;
382385
errorcount = 0;
383386

384-
lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE);
385-
yy_switch_to_buffer(lex_buffer);
387+
if (yylex_init(&scanner) != 0)
388+
elog(elevel, "yylex_init() failed: %m");
389+
yyg = (struct yyguts_t *) scanner;
390+
391+
lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE, scanner);
392+
yy_switch_to_buffer(lex_buffer, scanner);
386393

387394
/* This loop iterates once per logical line */
388-
while ((token = yylex()))
395+
while ((token = yylex(scanner)))
389396
{
390397
char *opt_name = NULL;
391398
char *opt_value = NULL;
@@ -400,9 +407,9 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
400407
opt_name = pstrdup(yytext);
401408

402409
/* next we have an optional equal sign; discard if present */
403-
token = yylex();
410+
token = yylex(scanner);
404411
if (token == GUC_EQUALS)
405-
token = yylex();
412+
token = yylex(scanner);
406413

407414
/* now we must have the option value */
408415
if (token != GUC_ID &&
@@ -417,7 +424,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
417424
opt_value = pstrdup(yytext);
418425

419426
/* now we'd like an end of line, or possibly EOF */
420-
token = yylex();
427+
token = yylex(scanner);
421428
if (token != GUC_EOL)
422429
{
423430
if (token != 0)
@@ -438,7 +445,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
438445
depth + 1, elevel,
439446
head_p, tail_p))
440447
OK = false;
441-
yy_switch_to_buffer(lex_buffer);
448+
yy_switch_to_buffer(lex_buffer, scanner);
442449
pfree(opt_name);
443450
pfree(opt_value);
444451
}
@@ -453,7 +460,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
453460
depth + 1, elevel,
454461
head_p, tail_p))
455462
OK = false;
456-
yy_switch_to_buffer(lex_buffer);
463+
yy_switch_to_buffer(lex_buffer, scanner);
457464
pfree(opt_name);
458465
pfree(opt_value);
459466
}
@@ -468,7 +475,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
468475
depth + 1, elevel,
469476
head_p, tail_p))
470477
OK = false;
471-
yy_switch_to_buffer(lex_buffer);
478+
yy_switch_to_buffer(lex_buffer, scanner);
472479
pfree(opt_name);
473480
pfree(opt_value);
474481
}
@@ -545,14 +552,15 @@ parse_error:
545552

546553
/* r 8629 esync to next end-of-line or EOF */
547554
while (token != GUC_EOL && token != 0)
548-
token = yylex();
555+
token = yylex(scanner);
549556
/* break out of loop on EOF */
550557
if (token == 0)
551558
break;
552559
}
553560

554561
cleanup:
555-
yy_delete_buffer(lex_buffer);
562+
yy_delete_buffer(lex_buffer, scanner);
563+
yylex_destroy(scanner);
556564
/* Each recursion level must save and restore these static variables. */
557565
ConfigFileLineno = save_ConfigFileLineno;
558566
GUC_flex_fatal_jmp = save_GUC_flex_fatal_jmp;

0 commit comments

Comments
 (0)
0