diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/nls.mk | 2 | ||||
-rw-r--r-- | src/backend/replication/syncrep.c | 7 | ||||
-rw-r--r-- | src/backend/replication/syncrep_gram.y | 12 | ||||
-rw-r--r-- | src/backend/replication/syncrep_scanner.l | 105 | ||||
-rw-r--r-- | src/include/replication/syncrep.h | 15 |
5 files changed, 90 insertions, 51 deletions
diff --git a/src/backend/nls.mk b/src/backend/nls.mk index 3fa1833b76a..0a2ef3ac909 100644 --- a/src/backend/nls.mk +++ b/src/backend/nls.mk @@ -11,7 +11,7 @@ GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \ parser_yyerror \ replication_yyerror:2 \ scanner_yyerror \ - syncrep_yyerror \ + syncrep_yyerror:2 \ report_invalid_record:2 \ ereport_startup_progress \ json_token_error:2 \ diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e1126734ef5..22a2c7fc409 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -992,6 +992,7 @@ check_synchronous_standby_names(char **newval, void **extra, GucSource source) { if (*newval != NULL && (*newval)[0] != '\0') { + yyscan_t scanner; int parse_rc; SyncRepConfigData *pconf; @@ -1000,9 +1001,9 @@ check_synchronous_standby_names(char **newval, void **extra, GucSource source) syncrep_parse_error_msg = NULL; /* Parse the synchronous_standby_names string */ - syncrep_scanner_init(*newval); - parse_rc = syncrep_yyparse(); - syncrep_scanner_finish(); + syncrep_scanner_init(*newval, &scanner); + parse_rc = syncrep_yyparse(scanner); + syncrep_scanner_finish(scanner); if (parse_rc != 0 || syncrep_parse_result == NULL) { diff --git a/src/backend/replication/syncrep_gram.y b/src/backend/replication/syncrep_gram.y index e4d9962226c..00b5bf0e522 100644 --- a/src/backend/replication/syncrep_gram.y +++ b/src/backend/replication/syncrep_gram.y @@ -26,10 +26,6 @@ char *syncrep_parse_error_msg; static SyncRepConfigData *create_syncrep_config(const char *num_sync, List *members, uint8 syncrep_method); -/* silence -Wmissing-variable-declarations */ -extern int syncrep_yychar; -extern int syncrep_yynerrs; - /* * Bison doesn't allocate anything that needs to live across parser calls, * so we can easily have it use palloc instead of malloc. This prevents @@ -40,6 +36,9 @@ extern int syncrep_yynerrs; %} +%parse-param {yyscan_t yyscanner} +%lex-param {yyscan_t yyscanner} +%pure-parser %expect 0 %name-prefix="syncrep_yy" @@ -60,7 +59,10 @@ extern int syncrep_yynerrs; %% result: - standby_config { syncrep_parse_result = $1; } + standby_config { + syncrep_parse_result = $1; + (void) yynerrs; /* suppress compiler warning */ + } ; standby_config: diff --git a/src/backend/replication/syncrep_scanner.l b/src/backend/replication/syncrep_scanner.l index 6defb90f13b..42e6852ea15 100644 --- a/src/backend/replication/syncrep_scanner.l +++ b/src/backend/replication/syncrep_scanner.l @@ -37,21 +37,27 @@ fprintf_to_ereport(const char *fmt, const char *msg) ereport(ERROR, (errmsg_internal("%s", msg))); } -/* Handles to the buffer that the lexer uses internally */ -static YY_BUFFER_STATE scanbufhandle; - -static StringInfoData xdbuf; +struct syncrep_yy_extra_type +{ + StringInfoData xdbuf; +}; +#define YY_EXTRA_TYPE struct syncrep_yy_extra_type * /* LCOV_EXCL_START */ %} +%option reentrant +%option bison-bridge %option 8bit %option never-interactive %option nodefault %option noinput %option nounput %option noyywrap +%option noyyalloc +%option noyyrealloc +%option noyyfree %option warn %option prefix="syncrep_yy" @@ -82,38 +88,38 @@ xdinside [^"]+ [Ff][Ii][Rr][Ss][Tt] { return FIRST; } {xdstart} { - initStringInfo(&xdbuf); + initStringInfo(&yyextra->xdbuf); BEGIN(xd); } <xd>{xddouble} { - appendStringInfoChar(&xdbuf, '"'); + appendStringInfoChar(&yyextra->xdbuf, '"'); } <xd>{xdinside} { - appendStringInfoString(&xdbuf, yytext); + appendStringInfoString(&yyextra->xdbuf, yytext); } <xd>{xdstop} { - syncrep_yylval.str = xdbuf.data; - xdbuf.data = NULL; + yylval->str = yyextra->xdbuf.data; + yyextra->xdbuf.data = NULL; BEGIN(INITIAL); return NAME; } <xd><<EOF>> { - syncrep_yyerror("unterminated quoted identifier"); + syncrep_yyerror(yyscanner, "unterminated quoted identifier"); return JUNK; } {identifier} { - syncrep_yylval.str = pstrdup(yytext); + yylval->str = pstrdup(yytext); return NAME; } {digit}+ { - syncrep_yylval.str = pstrdup(yytext); + yylval->str = pstrdup(yytext); return NUM; } "*" { - syncrep_yylval.str = "*"; + yylval->str = "*"; return NAME; } @@ -126,10 +132,16 @@ xdinside [^"]+ /* LCOV_EXCL_STOP */ +/* see scan.l */ +#undef yyextra +#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r) + /* Needs to be here for access to yytext */ void -syncrep_yyerror(const char *message) +syncrep_yyerror(yyscan_t yyscanner, const char *message) { + struct yyguts_t * yyg = (struct yyguts_t *) yyscanner; /* needed for yytext macro */ + /* report only the first error in a parse operation */ if (syncrep_parse_error_msg) return; @@ -142,32 +154,51 @@ syncrep_yyerror(const char *message) } void -syncrep_scanner_init(const char *str) +syncrep_scanner_init(const char *str, yyscan_t *yyscannerp) +{ + yyscan_t yyscanner; + struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type); + + if (yylex_init(yyscannerp) != 0) + elog(ERROR, "yylex_init() failed: %m"); + + yyscanner = *yyscannerp; + + yyset_extra(yyext, yyscanner); + + yy_scan_string(str, yyscanner); +} + +void +syncrep_scanner_finish(yyscan_t yyscanner) { - Size slen = strlen(str); - char *scanbuf; - - /* - * Might be left over after ereport() - */ - if (YY_CURRENT_BUFFER) - yy_delete_buffer(YY_CURRENT_BUFFER); - - /* - * Make a scan buffer with special termination needed by flex. - */ - scanbuf = (char *) palloc(slen + 2); - memcpy(scanbuf, str, slen); - scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; - scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); - - /* Make sure we start in proper state */ - BEGIN(INITIAL); + pfree(yyextra); + yylex_destroy(yyscanner); +} + +/* + * Interface functions to make flex use palloc() instead of malloc(). + * It'd be better to make these static, but flex insists otherwise. + */ + +void * +yyalloc(yy_size_t size, yyscan_t yyscanner) +{ + return palloc(size); +} + +void * +yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner) +{ + if (ptr) + return repalloc(ptr, size); + else + return palloc(size); } void -syncrep_scanner_finish(void) +yyfree(void *ptr, yyscan_t yyscanner) { - yy_delete_buffer(scanbufhandle); - scanbufhandle = NULL; + if (ptr) + pfree(ptr); } diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h index ea439e6da60..3fe44a880cf 100644 --- a/src/include/replication/syncrep.h +++ b/src/include/replication/syncrep.h @@ -100,10 +100,15 @@ extern void SyncRepUpdateSyncStandbysDefined(void); * Internal functions for parsing synchronous_standby_names grammar, * in syncrep_gram.y and syncrep_scanner.l */ -extern int syncrep_yyparse(void); -extern int syncrep_yylex(void); -extern void syncrep_yyerror(const char *str); -extern void syncrep_scanner_init(const char *str); -extern void syncrep_scanner_finish(void); +union YYSTYPE; +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void *yyscan_t; +#endif +extern int syncrep_yyparse(yyscan_t yyscanner); +extern int syncrep_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner); +extern void syncrep_yyerror(yyscan_t yyscanner, const char *str); +extern void syncrep_scanner_init(const char *str, yyscan_t *yyscannerp); +extern void syncrep_scanner_finish(yyscan_t yyscanner); #endif /* _SYNCREP_H */ |