aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/nls.mk2
-rw-r--r--src/backend/replication/syncrep.c7
-rw-r--r--src/backend/replication/syncrep_gram.y12
-rw-r--r--src/backend/replication/syncrep_scanner.l105
-rw-r--r--src/include/replication/syncrep.h15
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 */