From dac048f71ebbcf2f980d280711f8ff8001331c5d Mon Sep 17 00:00:00 2001 From: John Naylor Date: Sun, 4 Sep 2022 11:33:31 +0700 Subject: [PATCH] Build all Flex files standalone The proposed Meson build system will need a way to ignore certain generated files in order to coexist with the autoconf build system, and C files generated by Flex which are #include'd into .y files make this more difficult. In similar vein to 72b1e3a21, arrange for all Flex C files to compile to their own .o targets. Reviewed by Andres Freund Discussion: https://www.postgresql.org/message-id/20220810171935.7k5zgnjwqzalzmtm%40awork3.anarazel.de Discussion: https://www.postgresql.org/message-id/CAFBsxsF8Gc2StS3haXofshHCzqNMRXiSxvQEYGwnFsTmsdwNeg@mail.gmail.com --- contrib/cube/.gitignore | 1 + contrib/cube/Makefile | 16 +++--- contrib/cube/cube.c | 6 +-- contrib/cube/cubedata.h | 6 +-- contrib/cube/cubeparse.y | 6 +-- contrib/cube/cubescan.l | 44 ++++++++++------- contrib/seg/.gitignore | 1 + contrib/seg/Makefile | 15 ++++-- contrib/seg/segparse.y | 3 -- contrib/seg/segscan.l | 28 +++++++---- src/backend/Makefile | 7 ++- src/backend/bootstrap/.gitignore | 1 + src/backend/bootstrap/Makefile | 11 ++++- src/backend/bootstrap/bootparse.y | 2 - src/backend/bootstrap/bootscanner.l | 60 +++++++++++++---------- src/backend/replication/.gitignore | 2 + src/backend/replication/Makefile | 22 +++++++-- src/backend/replication/repl_gram.y | 2 - src/backend/replication/repl_scanner.l | 31 +++++++----- src/backend/replication/syncrep_gram.y | 2 - src/backend/replication/syncrep_scanner.l | 21 +++++--- src/backend/utils/adt/.gitignore | 1 + src/backend/utils/adt/Makefile | 11 ++++- src/backend/utils/adt/jsonpath_gram.y | 27 +--------- src/backend/utils/adt/jsonpath_internal.h | 32 ++++++++++++ src/backend/utils/adt/jsonpath_scan.l | 29 +++++++---- src/backend/utils/misc/Makefile | 5 +- src/backend/utils/misc/guc-file.l | 8 +-- src/backend/utils/misc/guc.c | 2 - src/bin/pgbench/.gitignore | 1 + src/bin/pgbench/Makefile | 13 +++-- src/bin/pgbench/exprparse.y | 15 ------ src/bin/pgbench/exprscan.l | 12 ++++- src/test/isolation/.gitignore | 1 + src/test/isolation/Makefile | 15 ++++-- src/test/isolation/specparse.y | 2 - src/test/isolation/specscanner.l | 28 +++++++---- src/tools/pginclude/headerscheck | 8 +++ 38 files changed, 307 insertions(+), 190 deletions(-) create mode 100644 src/backend/utils/adt/jsonpath_internal.h diff --git a/contrib/cube/.gitignore b/contrib/cube/.gitignore index cb4c989fff..f788440c79 100644 --- a/contrib/cube/.gitignore +++ b/contrib/cube/.gitignore @@ -1,3 +1,4 @@ +/cubeparse.h /cubeparse.c /cubescan.c # Generated subdirectories diff --git a/contrib/cube/Makefile b/contrib/cube/Makefile index cf195506c7..4fd19aac35 100644 --- a/contrib/cube/Makefile +++ b/contrib/cube/Makefile @@ -4,7 +4,8 @@ MODULE_big = cube OBJS = \ $(WIN32RES) \ cube.o \ - cubeparse.o + cubeparse.o \ + cubescan.o EXTENSION = cube DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql cube--1.4--1.5.sql \ @@ -15,8 +16,6 @@ HEADERS = cubedata.h REGRESS = cube cube_sci -EXTRA_CLEAN = y.tab.c y.tab.h - SHLIB_LINK += $(filter -lm, $(LIBS)) ifdef USE_PGXS @@ -30,11 +29,16 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif +# See notes in src/backend/parser/Makefile about the following two rules +cubeparse.h: cubeparse.c + touch $@ -# cubescan is compiled as part of cubeparse -cubeparse.o: cubescan.c +cubeparse.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +cubeparse.o cubescan.o: cubeparse.h distprep: cubeparse.c cubescan.c maintainer-clean: - rm -f cubeparse.c cubescan.c + rm -f cubeparse.h cubeparse.c cubescan.c diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index a5d1ba6733..6e01800a4a 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -119,11 +119,11 @@ cube_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); NDBOX *result; + Size scanbuflen; - cube_scanner_init(str); + cube_scanner_init(str, &scanbuflen); - if (cube_yyparse(&result) != 0) - cube_yyerror(&result, "cube parser failed"); + cube_yyparse(&result, scanbuflen); cube_scanner_finish(); diff --git a/contrib/cube/cubedata.h b/contrib/cube/cubedata.h index dbe7d4f742..640a7ca580 100644 --- a/contrib/cube/cubedata.h +++ b/contrib/cube/cubedata.h @@ -61,9 +61,9 @@ typedef struct NDBOX /* in cubescan.l */ extern int cube_yylex(void); -extern void cube_yyerror(NDBOX **result, const char *message) pg_attribute_noreturn(); -extern void cube_scanner_init(const char *str); +extern void cube_yyerror(NDBOX **result, Size scanbuflen, const char *message) pg_attribute_noreturn(); +extern void cube_scanner_init(const char *str, Size *scanbuflen); extern void cube_scanner_finish(void); /* in cubeparse.y */ -extern int cube_yyparse(NDBOX **result); +extern int cube_yyparse(NDBOX **result, Size scanbuflen); diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y index 7577c4515c..6cceae8e99 100644 --- a/contrib/cube/cubeparse.y +++ b/contrib/cube/cubeparse.y @@ -23,9 +23,6 @@ #define YYMALLOC palloc #define YYFREE pfree -static char *scanbuf; -static int scanbuflen; - static int item_count(const char *s, char delim); static NDBOX *write_box(int dim, char *str1, char *str2); static NDBOX *write_point_as_box(int dim, char *str); @@ -34,6 +31,7 @@ static NDBOX *write_point_as_box(int dim, char *str); /* BISON Declarations */ %parse-param {NDBOX **result} +%parse-param {Size scanbuflen} %expect 0 %name-prefix="cube_yy" @@ -265,5 +263,3 @@ write_point_as_box(int dim, char *str) return bp; } - -#include "cubescan.c" diff --git a/contrib/cube/cubescan.l b/contrib/cube/cubescan.l index bd400e3684..6b316f2d54 100644 --- a/contrib/cube/cubescan.l +++ b/contrib/cube/cubescan.l @@ -1,9 +1,21 @@ -%{ +%top{ /* * A scanner for EMP-style numeric ranges * contrib/cube/cubescan.l */ +#include "postgres.h" + +/* + * NB: include cubeparse.h only AFTER defining YYSTYPE (to match cubeparse.y) + * and cubedata.h for NDBOX. + */ +#include "cubedata.h" +#define YYSTYPE char * +#include "cubeparse.h" +} + +%{ /* LCOV_EXCL_START */ /* No reason to constrain amount of data slurped */ @@ -21,9 +33,7 @@ fprintf_to_ereport(const char *fmt, const char *msg) /* Handles to the buffer that the lexer uses internally */ static YY_BUFFER_STATE scanbufhandle; -/* this is now declared in cubeparse.y: */ -/* static char *scanbuf; */ -/* static int scanbuflen; */ +static char *scanbuf; %} %option 8bit @@ -45,14 +55,14 @@ NaN [nN][aA][nN] %% -{float} yylval = yytext; return CUBEFLOAT; -{infinity} yylval = yytext; return CUBEFLOAT; -{NaN} yylval = yytext; return CUBEFLOAT; -\[ yylval = "("; return O_BRACKET; -\] yylval = ")"; return C_BRACKET; -\( yylval = "("; return O_PAREN; -\) yylval = ")"; return C_PAREN; -\, yylval = ","; return COMMA; +{float} cube_yylval = yytext; return CUBEFLOAT; +{infinity} cube_yylval = yytext; return CUBEFLOAT; +{NaN} cube_yylval = yytext; return CUBEFLOAT; +\[ cube_yylval = "("; return O_BRACKET; +\] cube_yylval = ")"; return C_BRACKET; +\( cube_yylval = "("; return O_PAREN; +\) cube_yylval = ")"; return C_PAREN; +\, cube_yylval = ","; return COMMA; [ \t\n\r\f]+ /* discard spaces */ . return yytext[0]; /* alert parser of the garbage */ @@ -60,9 +70,9 @@ NaN [nN][aA][nN] /* LCOV_EXCL_STOP */ -/* result is not used, but Bison expects this signature */ +/* result and scanbuflen are not used, but Bison expects this signature */ void -yyerror(NDBOX **result, const char *message) +cube_yyerror(NDBOX **result, Size scanbuflen, const char *message) { if (*yytext == YY_END_OF_BUFFER_CHAR) { @@ -87,9 +97,9 @@ yyerror(NDBOX **result, const char *message) * Called before any actual parsing is done */ void -cube_scanner_init(const char *str) +cube_scanner_init(const char *str, Size *scanbuflen) { - Size slen = strlen(str); + Size slen = strlen(str); /* * Might be left over after ereport() @@ -100,7 +110,7 @@ cube_scanner_init(const char *str) /* * Make a scan buffer with special termination needed by flex. */ - scanbuflen = slen; + *scanbuflen = slen; scanbuf = palloc(slen + 2); memcpy(scanbuf, str, slen); scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; diff --git a/contrib/seg/.gitignore b/contrib/seg/.gitignore index 69e73d2096..fa247a4e67 100644 --- a/contrib/seg/.gitignore +++ b/contrib/seg/.gitignore @@ -1,3 +1,4 @@ +/segparse.h /segparse.c /segscan.c # Generated subdirectories diff --git a/contrib/seg/Makefile b/contrib/seg/Makefile index bb63e83506..c6c134b8f1 100644 --- a/contrib/seg/Makefile +++ b/contrib/seg/Makefile @@ -4,7 +4,8 @@ MODULE_big = seg OBJS = \ $(WIN32RES) \ seg.o \ - segparse.o + segparse.o \ + segscan.o EXTENSION = seg DATA = seg--1.1.sql seg--1.1--1.2.sql seg--1.2--1.3.sql seg--1.3--1.4.sql \ @@ -29,10 +30,16 @@ include $(top_srcdir)/contrib/contrib-global.mk endif -# segscan is compiled as part of segparse -segparse.o: segscan.c +# See notes in src/backend/parser/Makefile about the following two rules +segparse.h: segparse.c + touch $@ + +segparse.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +segparse.o segscan.o: segparse.h distprep: segparse.c segscan.c maintainer-clean: - rm -f segparse.c segscan.c + rm -f segparse.h segparse.c segscan.c diff --git a/contrib/seg/segparse.y b/contrib/seg/segparse.y index 33e3a9f35f..637eacd1a6 100644 --- a/contrib/seg/segparse.y +++ b/contrib/seg/segparse.y @@ -160,6 +160,3 @@ seg_atof(const char *value) datum = DirectFunctionCall1(float4in, CStringGetDatum(value)); return DatumGetFloat4(datum); } - - -#include "segscan.c" diff --git a/contrib/seg/segscan.l b/contrib/seg/segscan.l index 5f6595e9eb..4744fd5e9e 100644 --- a/contrib/seg/segscan.l +++ b/contrib/seg/segscan.l @@ -1,8 +1,18 @@ -%{ +%top{ /* * A scanner for EMP-style numeric ranges */ +#include "postgres.h" +/* + * NB: include segparse.h only AFTER including segdata.h, because segdata.h + * contains the definition for SEG. + */ +#include "segdata.h" +#include "segparse.h" +} + +%{ /* LCOV_EXCL_START */ /* No reason to constrain amount of data slurped */ @@ -21,7 +31,6 @@ fprintf_to_ereport(const char *fmt, const char *msg) /* Handles to the buffer that the lexer uses internally */ static YY_BUFFER_STATE scanbufhandle; static char *scanbuf; -static int scanbuflen; %} %option 8bit @@ -42,12 +51,12 @@ float ({integer}|{real})([eE]{integer})? %% -{range} yylval.text = yytext; return RANGE; -{plumin} yylval.text = yytext; return PLUMIN; -{float} yylval.text = yytext; return SEGFLOAT; -\< yylval.text = "<"; return EXTENSION; -\> yylval.text = ">"; return EXTENSION; -\~ yylval.text = "~"; return EXTENSION; +{range} seg_yylval.text = yytext; return RANGE; +{plumin} seg_yylval.text = yytext; return PLUMIN; +{float} seg_yylval.text = yytext; return SEGFLOAT; +\< seg_yylval.text = "<"; return EXTENSION; +\> seg_yylval.text = ">"; return EXTENSION; +\~ seg_yylval.text = "~"; return EXTENSION; [ \t\n\r\f]+ /* discard spaces */ . return yytext[0]; /* alert parser of the garbage */ @@ -56,7 +65,7 @@ float ({integer}|{real})([eE]{integer})? /* LCOV_EXCL_STOP */ void -yyerror(SEG *result, const char *message) +seg_yyerror(SEG *result, const char *message) { if (*yytext == YY_END_OF_BUFFER_CHAR) { @@ -94,7 +103,6 @@ seg_scanner_init(const char *str) /* * Make a scan buffer with special termination needed by flex. */ - scanbuflen = slen; scanbuf = palloc(slen + 2); memcpy(scanbuf, str, slen); scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; diff --git a/src/backend/Makefile b/src/backend/Makefile index f498cfd593..4ac9f8f180 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -174,10 +174,10 @@ utils/probes.o: utils/probes.d $(SUBDIROBJS) # Be sure that these files get removed by the maintainer-clean target distprep: $(MAKE) -C parser gram.c gram.h scan.c - $(MAKE) -C bootstrap bootparse.c bootscanner.c + $(MAKE) -C bootstrap bootparse.c bootparse.h bootscanner.c $(MAKE) -C catalog distprep $(MAKE) -C nodes distprep - $(MAKE) -C replication repl_gram.c repl_scanner.c syncrep_gram.c syncrep_scanner.c + $(MAKE) -C replication repl_gram.c repl_gram.h repl_scanner.c syncrep_gram.c syncrep_gram.h syncrep_scanner.c $(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c $(MAKE) -C utils distprep $(MAKE) -C utils/adt jsonpath_gram.c jsonpath_scan.c @@ -292,13 +292,16 @@ maintainer-clean: distclean $(MAKE) -C nodes $@ $(MAKE) -C utils $@ rm -f bootstrap/bootparse.c \ + bootstrap/bootparse.h \ bootstrap/bootscanner.c \ parser/gram.c \ parser/gram.h \ parser/scan.c \ replication/repl_gram.c \ + replication/repl_gram.h \ replication/repl_scanner.c \ replication/syncrep_gram.c \ + replication/syncrep_gram.h \ replication/syncrep_scanner.c \ storage/lmgr/lwlocknames.c \ storage/lmgr/lwlocknames.h \ diff --git a/src/backend/bootstrap/.gitignore b/src/backend/bootstrap/.gitignore index 1ffe8ca39e..6351b920fd 100644 --- a/src/backend/bootstrap/.gitignore +++ b/src/backend/bootstrap/.gitignore @@ -1,2 +1,3 @@ +/bootparse.h /bootparse.c /bootscanner.c diff --git a/src/backend/bootstrap/Makefile b/src/backend/bootstrap/Makefile index 6421efb227..606c8021e7 100644 --- a/src/backend/bootstrap/Makefile +++ b/src/backend/bootstrap/Makefile @@ -14,12 +14,19 @@ override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) OBJS = \ bootparse.o \ + bootscanner.o \ bootstrap.o include $(top_srcdir)/src/backend/common.mk -# bootscanner is compiled as part of bootparse -bootparse.o: bootscanner.c +# See notes in src/backend/parser/Makefile about the following two rules +bootparse.h: bootparse.c + touch $@ + +bootparse.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +bootparse.o bootscanner.o: bootparse.h # bootparse.c and bootscanner.c are in the distribution tarball, so # they are not cleaned here. diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 7d7655d295..c45ddde67f 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -488,5 +488,3 @@ boot_ident: | XNULL { $$ = pstrdup($1); } ; %% - -#include "bootscanner.c" diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index 3094ccb93f..d6eae84816 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -1,4 +1,4 @@ -%{ +%top{ /*------------------------------------------------------------------------- * * bootscanner.l @@ -15,11 +15,17 @@ */ #include "postgres.h" +/* + * NB: include bootparse.h only AFTER including bootstrap.h, because bootstrap.h + * includes node definitions needed for YYSTYPE. + */ #include "bootstrap/bootstrap.h" +#include "bootparse.h" #include "utils/guc.h" -/* Not needed now that this file is compiled as part of bootparse. */ -/* #include "bootparse.h" */ +} + +%{ /* LCOV_EXCL_START */ @@ -52,7 +58,7 @@ id [-A-Za-z0-9_]+ sid \'([^']|\'\')*\' /* - * Keyword tokens return the keyword text (as a constant string) in yylval.kw, + * Keyword tokens return the keyword text (as a constant string) in boot_yylval.kw, * just in case that's needed because we want to treat the keyword as an * unreserved identifier. Note that _null_ is not treated as a keyword * for this purpose; it's the one "reserved word" in the bootstrap syntax. @@ -60,23 +66,23 @@ sid \'([^']|\'\')*\' * Notice that all the keywords are case-sensitive, and for historical * reasons some must be upper case. * - * String tokens return a palloc'd string in yylval.str. + * String tokens return a palloc'd string in boot_yylval.str. */ %% -open { yylval.kw = "open"; return OPEN; } +open { boot_yylval.kw = "open"; return OPEN; } -close { yylval.kw = "close"; return XCLOSE; } +close { boot_yylval.kw = "close"; return XCLOSE; } -create { yylval.kw = "create"; return XCREATE; } +create { boot_yylval.kw = "create"; return XCREATE; } -OID { yylval.kw = "OID"; return OBJ_ID; } -bootstrap { yylval.kw = "bootstrap"; return XBOOTSTRAP; } -shared_relation { yylval.kw = "shared_relation"; return XSHARED_RELATION; } -rowtype_oid { yylval.kw = "rowtype_oid"; return XROWTYPE_OID; } +OID { boot_yylval.kw = "OID"; return OBJ_ID; } +bootstrap { boot_yylval.kw = "bootstrap"; return XBOOTSTRAP; } +shared_relation { boot_yylval.kw = "shared_relation"; return XSHARED_RELATION; } +rowtype_oid { boot_yylval.kw = "rowtype_oid"; return XROWTYPE_OID; } -insert { yylval.kw = "insert"; return INSERT_TUPLE; } +insert { boot_yylval.kw = "insert"; return INSERT_TUPLE; } _null_ { return NULLVAL; } @@ -90,25 +96,25 @@ _null_ { return NULLVAL; } ^\#[^\n]* ; /* drop everything after "#" for comments */ -declare { yylval.kw = "declare"; return XDECLARE; } -build { yylval.kw = "build"; return XBUILD; } -indices { yylval.kw = "indices"; return INDICES; } -unique { yylval.kw = "unique"; return UNIQUE; } -index { yylval.kw = "index"; return INDEX; } -on { yylval.kw = "on"; return ON; } -using { yylval.kw = "using"; return USING; } -toast { yylval.kw = "toast"; return XTOAST; } -FORCE { yylval.kw = "FORCE"; return XFORCE; } -NOT { yylval.kw = "NOT"; return XNOT; } -NULL { yylval.kw = "NULL"; return XNULL; } +declare { boot_yylval.kw = "declare"; return XDECLARE; } +build { boot_yylval.kw = "build"; return XBUILD; } +indices { boot_yylval.kw = "indices"; return INDICES; } +unique { boot_yylval.kw = "unique"; return UNIQUE; } +index { boot_yylval.kw = "index"; return INDEX; } +on { boot_yylval.kw = "on"; return ON; } +using { boot_yylval.kw = "using"; return USING; } +toast { boot_yylval.kw = "toast"; return XTOAST; } +FORCE { boot_yylval.kw = "FORCE"; return XFORCE; } +NOT { boot_yylval.kw = "NOT"; return XNOT; } +NULL { boot_yylval.kw = "NULL"; return XNULL; } {id} { - yylval.str = pstrdup(yytext); + boot_yylval.str = pstrdup(yytext); return ID; } {sid} { /* strip quotes and escapes */ - yylval.str = DeescapeQuotedString(yytext); + boot_yylval.str = DeescapeQuotedString(yytext); return ID; } @@ -121,7 +127,7 @@ NULL { yylval.kw = "NULL"; return XNULL; } /* LCOV_EXCL_STOP */ void -yyerror(const char *message) +boot_yyerror(const char *message) { elog(ERROR, "%s at line %d", message, yyline); } diff --git a/src/backend/replication/.gitignore b/src/backend/replication/.gitignore index d1df6147bd..77d5a51068 100644 --- a/src/backend/replication/.gitignore +++ b/src/backend/replication/.gitignore @@ -1,4 +1,6 @@ +/repl_gram.h /repl_gram.c /repl_scanner.c +/syncrep_gram.h /syncrep_gram.c /syncrep_scanner.c diff --git a/src/backend/replication/Makefile b/src/backend/replication/Makefile index 2bffac58c0..23f29ba545 100644 --- a/src/backend/replication/Makefile +++ b/src/backend/replication/Makefile @@ -16,10 +16,12 @@ override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) OBJS = \ repl_gram.o \ + repl_scanner.o \ slot.o \ slotfuncs.o \ syncrep.o \ syncrep_gram.o \ + syncrep_scanner.o \ walreceiver.o \ walreceiverfuncs.o \ walsender.o @@ -28,11 +30,23 @@ SUBDIRS = logical include $(top_srcdir)/src/backend/common.mk -# repl_scanner is compiled as part of repl_gram -repl_gram.o: repl_scanner.c +# See notes in src/backend/parser/Makefile about the following two rules +repl_gram.h: repl_gram.c + touch $@ -# syncrep_scanner is compiled as part of syncrep_gram -syncrep_gram.o: syncrep_scanner.c +repl_gram.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +repl_gram.o repl_scanner.o: repl_gram.h + +# See notes in src/backend/parser/Makefile about the following two rules +syncrep_gram.h: syncrep_gram.c + touch $@ + +syncrep_gram.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +syncrep_gram.o syncrep_scanner.o: syncrep_gram.h # repl_gram.c, repl_scanner.c, syncrep_gram.c and syncrep_scanner.c # are in the distribution tarball, so they are not cleaned here. diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index 4cf087e602..b343f108d3 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -416,5 +416,3 @@ ident_or_keyword: ; %% - -#include "repl_scanner.c" diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 586f0d3a5c..23fcb2a11d 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -1,4 +1,4 @@ -%{ +%top{ /*------------------------------------------------------------------------- * * repl_scanner.l @@ -18,6 +18,15 @@ #include "utils/builtins.h" #include "parser/scansup.h" +/* + * NB: include repl_gram.h only AFTER including walsender_private.h, because + * walsender_private includes headers that define XLogRecPtr. + */ +#include "replication/walsender_private.h" +#include "repl_gram.h" +} + +%{ /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ #undef fprintf #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) @@ -130,7 +139,7 @@ WAIT { return K_WAIT; } {space}+ { /* do nothing */ } {digit}+ { - yylval.uintval = strtoul(yytext, NULL, 10); + replication_yylval.uintval = strtoul(yytext, NULL, 10); return UCONST; } @@ -138,8 +147,8 @@ WAIT { return K_WAIT; } uint32 hi, lo; if (sscanf(yytext, "%X/%X", &hi, &lo) != 2) - yyerror("invalid streaming start location"); - yylval.recptr = ((uint64) hi) << 32 | lo; + replication_yyerror("invalid streaming start location"); + replication_yylval.recptr = ((uint64) hi) << 32 | lo; return RECPTR; } @@ -151,7 +160,7 @@ WAIT { return K_WAIT; } {quotestop} { yyless(1); BEGIN(INITIAL); - yylval.str = litbufdup(); + replication_yylval.str = litbufdup(); return SCONST; } @@ -173,9 +182,9 @@ WAIT { return K_WAIT; } yyless(1); BEGIN(INITIAL); - yylval.str = litbufdup(); - len = strlen(yylval.str); - truncate_identifier(yylval.str, len, true); + replication_yylval.str = litbufdup(); + len = strlen(replication_yylval.str); + truncate_identifier(replication_yylval.str, len, true); return IDENT; } @@ -186,7 +195,7 @@ WAIT { return K_WAIT; } {identifier} { int len = strlen(yytext); - yylval.str = downcase_truncate_identifier(yytext, len, true); + replication_yylval.str = downcase_truncate_identifier(yytext, len, true); return IDENT; } @@ -195,7 +204,7 @@ WAIT { return K_WAIT; } return yytext[0]; } -<> { yyerror("unterminated quoted string"); } +<> { replication_yyerror("unterminated quoted string"); } <> { @@ -231,7 +240,7 @@ addlitchar(unsigned char ychar) } void -yyerror(const char *message) +replication_yyerror(const char *message) { ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), diff --git a/src/backend/replication/syncrep_gram.y b/src/backend/replication/syncrep_gram.y index d932f2cda3..4fc3647da1 100644 --- a/src/backend/replication/syncrep_gram.y +++ b/src/backend/replication/syncrep_gram.y @@ -112,5 +112,3 @@ create_syncrep_config(const char *num_sync, List *members, uint8 syncrep_method) return config; } - -#include "syncrep_scanner.c" diff --git a/src/backend/replication/syncrep_scanner.l b/src/backend/replication/syncrep_scanner.l index 1952c8c6e0..bdb1a3391c 100644 --- a/src/backend/replication/syncrep_scanner.l +++ b/src/backend/replication/syncrep_scanner.l @@ -1,4 +1,4 @@ -%{ +%top{ /*------------------------------------------------------------------------- * * syncrep_scanner.l @@ -17,6 +17,15 @@ #include "lib/stringinfo.h" +/* + * NB: include syncrep_gram.h only AFTER including syncrep.h, because syncrep.h + * includes node definitions needed for YYSTYPE. + */ +#include "replication/syncrep.h" +#include "syncrep_gram.h" +} + +%{ /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ #undef fprintf #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) @@ -82,28 +91,28 @@ xdinside [^"]+ appendStringInfoString(&xdbuf, yytext); } {xdstop} { - yylval.str = xdbuf.data; + syncrep_yylval.str = xdbuf.data; xdbuf.data = NULL; BEGIN(INITIAL); return NAME; } <> { - yyerror("unterminated quoted identifier"); + syncrep_yyerror("unterminated quoted identifier"); return JUNK; } {identifier} { - yylval.str = pstrdup(yytext); + syncrep_yylval.str = pstrdup(yytext); return NAME; } {digit}+ { - yylval.str = pstrdup(yytext); + syncrep_yylval.str = pstrdup(yytext); return NUM; } "*" { - yylval.str = "*"; + syncrep_yylval.str = "*"; return NAME; } diff --git a/src/backend/utils/adt/.gitignore b/src/backend/utils/adt/.gitignore index 48cf941a52..7fab054407 100644 --- a/src/backend/utils/adt/.gitignore +++ b/src/backend/utils/adt/.gitignore @@ -1,2 +1,3 @@ +/jsonpath_gram.h /jsonpath_gram.c /jsonpath_scan.c diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 7c722ea2ce..0de0bbb1b8 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -57,6 +57,7 @@ OBJS = \ jsonpath.o \ jsonpath_exec.o \ jsonpath_gram.o \ + jsonpath_scan.o \ like.o \ like_support.o \ lockfuncs.o \ @@ -119,11 +120,17 @@ OBJS = \ xid8funcs.o \ xml.o +# See notes in src/backend/parser/Makefile about the following two rules +jsonpath_gram.h: jsonpath_gram.c + touch $@ + +jsonpath_gram.c: BISONFLAGS += -d + jsonpath_scan.c: FLEXFLAGS = -CF -p -p jsonpath_scan.c: FLEX_NO_BACKUP=yes -# jsonpath_scan is compiled as part of jsonpath_gram -jsonpath_gram.o: jsonpath_scan.c +# Force these dependencies to be known even without dependency info built: +jsonpath_gram.o jsonpath_scan.o: jsonpath_gram.h # jsonpath_gram.c and jsonpath_scan.c are in the distribution tarball, # so they are not cleaned here. diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y index ce5d5af891..35a79ca965 100644 --- a/src/backend/utils/adt/jsonpath_gram.y +++ b/src/backend/utils/adt/jsonpath_gram.y @@ -18,26 +18,11 @@ #include "catalog/pg_collation.h" #include "fmgr.h" +#include "jsonpath_internal.h" #include "miscadmin.h" #include "nodes/pg_list.h" #include "regex/regex.h" #include "utils/builtins.h" -#include "utils/jsonpath.h" - -/* struct JsonPathString is shared between scan and gram */ -typedef struct JsonPathString -{ - char *val; - int len; - int total; -} JsonPathString; - -union YYSTYPE; - -/* flex 2.5.4 doesn't bother with a decl for this */ -int jsonpath_yylex(union YYSTYPE *yylval_param); -int jsonpath_yyparse(JsonPathParseResult **result); -void jsonpath_yyerror(JsonPathParseResult **result, const char *message); static JsonPathParseItem *makeItemType(JsonPathItemType type); static JsonPathParseItem *makeItemString(JsonPathString *s); @@ -593,13 +578,3 @@ jspConvertRegexFlags(uint32 xflags) return cflags; } - -/* - * jsonpath_scan.l is compiled as part of jsonpath_gram.y. Currently, this is - * unavoidable because jsonpath_gram does not create a .h file to export its - * token symbols. If these files ever grow large enough to be worth compiling - * separately, that could be fixed; but for now it seems like useless - * complication. - */ - -#include "jsonpath_scan.c" diff --git a/src/backend/utils/adt/jsonpath_internal.h b/src/backend/utils/adt/jsonpath_internal.h new file mode 100644 index 0000000000..edfc6191a0 --- /dev/null +++ b/src/backend/utils/adt/jsonpath_internal.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * jsonpath_internal.h + * Private definitions for jsonpath scanner & parser + * + * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/utils/adt/jsonpath_internal.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONPATH_INTERNAL_H +#define JSONPATH_INTERNAL_H + +/* struct JsonPathString is shared between scan and gram */ +typedef struct JsonPathString +{ + char *val; + int len; + int total; +} JsonPathString; + +#include "utils/jsonpath.h" +#include "jsonpath_gram.h" + +extern int jsonpath_yylex(YYSTYPE *yylval_param); +extern int jsonpath_yyparse(JsonPathParseResult **result); +extern void jsonpath_yyerror(JsonPathParseResult **result, const char *message); + +#endif /* JSONPATH_INTERNAL_H */ diff --git a/src/backend/utils/adt/jsonpath_scan.l b/src/backend/utils/adt/jsonpath_scan.l index 4351f6ec98..ea824bae73 100644 --- a/src/backend/utils/adt/jsonpath_scan.l +++ b/src/backend/utils/adt/jsonpath_scan.l @@ -1,4 +1,4 @@ -%{ +%top{ /*------------------------------------------------------------------------- * * jsonpath_scan.l @@ -17,9 +17,18 @@ #include "postgres.h" +/* + * NB: include jsonpath_gram.h only AFTER including jsonpath_internal.h, + * because jsonpath_internal.h contains the declaration for JsonPathString. + */ +#include "jsonpath_internal.h" +#include "jsonpath_gram.h" + #include "mb/pg_wchar.h" #include "nodes/pg_list.h" +} +%{ static JsonPathString scanstring; /* Handles to the buffer that the lexer uses internally */ @@ -142,9 +151,9 @@ hex_fail \\x{hex_dig}{0,1} {hex_char} { parseHexChar(yytext); } -{unicode}*{unicodefail} { yyerror(NULL, "invalid unicode sequence"); } +{unicode}*{unicodefail} { jsonpath_yyerror(NULL, "invalid unicode sequence"); } -{hex_fail} { yyerror(NULL, "invalid hex character sequence"); } +{hex_fail} { jsonpath_yyerror(NULL, "invalid hex character sequence"); } {unicode}+\\ { /* throw back the \\, and treat as unicode */ @@ -154,9 +163,9 @@ hex_fail \\x{hex_dig}{0,1} \\. { addchar(false, yytext[1]); } -\\ { yyerror(NULL, "unexpected end after backslash"); } +\\ { jsonpath_yyerror(NULL, "unexpected end after backslash"); } -<> { yyerror(NULL, "unexpected end of quoted string"); } +<> { jsonpath_yyerror(NULL, "unexpected end of quoted string"); } \" { yylval->str = scanstring; @@ -178,7 +187,7 @@ hex_fail \\x{hex_dig}{0,1} \* { } -<> { yyerror(NULL, "unexpected end of comment"); } +<> { jsonpath_yyerror(NULL, "unexpected end of comment"); } \&\& { return AND_P; } @@ -244,10 +253,10 @@ hex_fail \\x{hex_dig}{0,1} return INT_P; } -{realfail} { yyerror(NULL, "invalid numeric literal"); } -{integer_junk} { yyerror(NULL, "trailing junk after numeric literal"); } -{decimal_junk} { yyerror(NULL, "trailing junk after numeric literal"); } -{real_junk} { yyerror(NULL, "trailing junk after numeric literal"); } +{realfail} { jsonpath_yyerror(NULL, "invalid numeric literal"); } +{integer_junk} { jsonpath_yyerror(NULL, "trailing junk after numeric literal"); } +{decimal_junk} { jsonpath_yyerror(NULL, "trailing junk after numeric literal"); } +{real_junk} { jsonpath_yyerror(NULL, "trailing junk after numeric literal"); } \" { addchar(true, '\0'); diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile index 1d5327cf64..cf7ce9bc83 100644 --- a/src/backend/utils/misc/Makefile +++ b/src/backend/utils/misc/Makefile @@ -16,6 +16,7 @@ override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) OBJS = \ guc.o \ + guc-file.o \ help_config.o \ pg_config.o \ pg_controldata.o \ @@ -37,10 +38,6 @@ endif include $(top_srcdir)/src/backend/common.mk -# guc-file is compiled as part of guc -guc.o: guc-file.c - # Note: guc-file.c is not deleted by 'make clean', # since we want to ship it in distribution tarballs. clean: - @rm -f lex.yy.c diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index 8b5b299efd..4f43430db4 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -1,4 +1,4 @@ -/* -*-pgsql-c-*- */ +%top{ /* * Scanner for the configuration file * @@ -7,8 +7,6 @@ * src/backend/utils/misc/guc-file.l */ -%{ - #include "postgres.h" #include @@ -19,8 +17,12 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" #include "storage/fd.h" +#include +#include "utils/memutils.h" +} +%{ /* * flex emits a yy_fatal_error() function that it calls in response to * critical errors like malloc failure, file I/O errors, and detection of diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0e6c13fa2a..c336698ad5 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -13333,5 +13333,3 @@ check_default_with_oids(bool *newval, void **extra, GucSource source) return true; } - -#include "guc-file.c" diff --git a/src/bin/pgbench/.gitignore b/src/bin/pgbench/.gitignore index 983a3cd7a6..07492a993c 100644 --- a/src/bin/pgbench/.gitignore +++ b/src/bin/pgbench/.gitignore @@ -1,3 +1,4 @@ +/exprparse.h /exprparse.c /exprscan.c /pgbench diff --git a/src/bin/pgbench/Makefile b/src/bin/pgbench/Makefile index f402fe7b91..6647c9fe97 100644 --- a/src/bin/pgbench/Makefile +++ b/src/bin/pgbench/Makefile @@ -10,6 +10,7 @@ include $(top_builddir)/src/Makefile.global OBJS = \ $(WIN32RES) \ exprparse.o \ + exprscan.o \ pgbench.o override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS) @@ -26,8 +27,14 @@ all: pgbench pgbench: $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) -# exprscan is compiled as part of exprparse -exprparse.o: exprscan.c +# See notes in src/backend/parser/Makefile about the following two rules +exprparse.h: exprparse.c + touch $@ + +exprparse.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +exprparse.o exprscan.o: exprparse.h distprep: exprparse.c exprscan.c @@ -45,7 +52,7 @@ clean distclean: rm -rf tmp_check maintainer-clean: distclean - rm -f exprparse.c exprscan.c + rm -f exprparse.h exprparse.c exprscan.c check: $(prove_check) diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y index b5592d4b97..ade2ecdaab 100644 --- a/src/bin/pgbench/exprparse.y +++ b/src/bin/pgbench/exprparse.y @@ -526,18 +526,3 @@ make_case(yyscan_t yyscanner, PgBenchExprList *when_then_list, PgBenchExpr *else find_func(yyscanner, "!case_end"), make_elist(else_part, when_then_list)); } - -/* - * exprscan.l is compiled as part of exprparse.y. Currently, this is - * unavoidable because exprparse does not create a .h file to export - * its token symbols. If these files ever grow large enough to be - * worth compiling separately, that could be fixed; but for now it - * seems like useless complication. - */ - -/* First, get rid of "#define yyscan_t" from pgbench.h */ -#undef yyscan_t -/* ... and the yylval macro, which flex will have its own definition for */ -#undef yylval - -#include "exprscan.c" diff --git a/src/bin/pgbench/exprscan.l b/src/bin/pgbench/exprscan.l index 4f63818606..fe8e32838a 100644 --- a/src/bin/pgbench/exprscan.l +++ b/src/bin/pgbench/exprscan.l @@ -1,4 +1,4 @@ -%{ +%top{ /*------------------------------------------------------------------------- * * exprscan.l @@ -22,9 +22,19 @@ * *------------------------------------------------------------------------- */ +#include "postgres_fe.h" +/* + * NB: include exprparse.h only AFTER including pgbench.h, because pgbench.h + * contains definitions needed for YYSTYPE. Likewise, pgbench.h must come after + * psqlscan_int.h for yyscan_t. + */ #include "fe_utils/psqlscan_int.h" +#include "pgbench.h" +#include "exprparse.h" +} +%{ /* context information for reporting errors in expressions */ static const char *expr_source = NULL; static int expr_lineno = 0; diff --git a/src/test/isolation/.gitignore b/src/test/isolation/.gitignore index 870dac4d28..2c13b4bf98 100644 --- a/src/test/isolation/.gitignore +++ b/src/test/isolation/.gitignore @@ -3,6 +3,7 @@ /pg_isolation_regress # Local generated source files +/specparse.h /specparse.c /specscanner.c diff --git a/src/test/isolation/Makefile b/src/test/isolation/Makefile index 0d452c89d4..b8738b7c1b 100644 --- a/src/test/isolation/Makefile +++ b/src/test/isolation/Makefile @@ -15,7 +15,8 @@ override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) \ OBJS = \ $(WIN32RES) \ isolationtester.o \ - specparse.o + specparse.o \ + specscanner.o all: isolationtester$(X) pg_isolation_regress$(X) @@ -44,8 +45,14 @@ isolationtester$(X): $(OBJS) | submake-libpq submake-libpgport distprep: specparse.c specscanner.c -# specscanner is compiled as part of specparse -specparse.o: specscanner.c +# See notes in src/backend/parser/Makefile about the following two rules +specparse.h: specparse.c + touch $@ + +specparse.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +specparse.o specscanner.o: specparse.h # specparse.c and specscanner.c are in the distribution tarball, # so do not clean them here @@ -55,7 +62,7 @@ clean distclean: rm -rf $(pg_regress_clean_files) maintainer-clean: distclean - rm -f specparse.c specscanner.c + rm -f specparse.h specparse.c specscanner.c installcheck: all $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y index eb368184b8..657285cc23 100644 --- a/src/test/isolation/specparse.y +++ b/src/test/isolation/specparse.y @@ -276,5 +276,3 @@ blocker: ; %% - -#include "specscanner.c" diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l index aa6e89268e..b04696f52d 100644 --- a/src/test/isolation/specscanner.l +++ b/src/test/isolation/specscanner.l @@ -1,4 +1,4 @@ -%{ +%top{ /*------------------------------------------------------------------------- * * specscanner.l @@ -9,7 +9,17 @@ * *------------------------------------------------------------------------- */ +#include "postgres_fe.h" +/* + * NB: include specparse.h only AFTER including isolationtester.h, because + * isolationtester.h includes node definitions needed for YYSTYPE. + */ +#include "isolationtester.h" +#include "specparse.h" +} + +%{ static int yyline = 1; /* line number for error reporting */ #define LITBUF_INIT 1024 /* initial size of litbuf */ @@ -75,7 +85,7 @@ teardown { return TEARDOWN; } /* Plain identifiers */ {identifier} { - yylval.str = pg_strdup(yytext); + spec_yylval.str = pg_strdup(yytext); return(identifier); } @@ -87,13 +97,13 @@ teardown { return TEARDOWN; } \"\" { addlitchar(yytext[0]); } \" { litbuf[litbufpos] = '\0'; - yylval.str = pg_strdup(litbuf); + spec_yylval.str = pg_strdup(litbuf); BEGIN(INITIAL); return(identifier); } . { addlitchar(yytext[0]); } -\n { yyerror("unexpected newline in quoted identifier"); } -<> { yyerror("unterminated quoted identifier"); } +\n { spec_yyerror("unexpected newline in quoted identifier"); } +<> { spec_yyerror("unterminated quoted identifier"); } /* SQL blocks: { UPDATE ... } */ /* We trim leading/trailing whitespace, otherwise they're unprocessed */ @@ -104,7 +114,7 @@ teardown { return TEARDOWN; } } {space}*"}" { litbuf[litbufpos] = '\0'; - yylval.str = pg_strdup(litbuf); + spec_yylval.str = pg_strdup(litbuf); BEGIN(INITIAL); return(sqlblock); } @@ -116,12 +126,12 @@ teardown { return TEARDOWN; } addlitchar(yytext[0]); } <> { - yyerror("unterminated sql block"); + spec_yyerror("unterminated sql block"); } /* Numbers and punctuation */ {digit}+ { - yylval.integer = atoi(yytext); + spec_yylval.integer = atoi(yytext); return INTEGER; } @@ -150,7 +160,7 @@ addlitchar(char c) } void -yyerror(const char *message) +spec_yyerror(const char *message) { fprintf(stderr, "%s at line %d\n", message, yyline); exit(1); diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck index b8419e46a4..2a88bd9f00 100755 --- a/src/tools/pginclude/headerscheck +++ b/src/tools/pginclude/headerscheck @@ -117,10 +117,18 @@ do # We can't make these Bison output files compilable standalone # without using "%code require", which old Bison versions lack. # parser/gram.h will be included by parser/gramparse.h anyway. + test "$f" = contrib/cube/cubeparse.h && continue + test "$f" = contrib/seg/segparse.h && continue + test "$f" = src/backend/bootstrap/bootparse.h && continue test "$f" = src/include/parser/gram.h && continue test "$f" = src/backend/parser/gram.h && continue + test "$f" = src/backend/replication/repl_gram.h && continue + test "$f" = src/backend/replication/syncrep_gram.h && continue + test "$f" = src/backend/utils/adt/jsonpath_gram.h && continue + test "$f" = src/bin/pgbench/exprparse.h && continue test "$f" = src/pl/plpgsql/src/pl_gram.h && continue test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue + test "$f" = src/test/isolation/specparse.h && continue # This produces a "no previous prototype" warning. test "$f" = src/include/storage/checksum_impl.h && continue