From ba67b6b8e5c26631d89d4a188a6b06c24bcc5f39 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Fri, 12 Aug 2022 15:45:24 +0700
Subject: [PATCH v3 04/11] Build bootscanner.c standalone

---
 src/backend/Makefile                |  3 +-
 src/backend/bootstrap/.gitignore    |  1 +
 src/backend/bootstrap/Makefile      | 11 +++++-
 src/backend/bootstrap/bootparse.y   |  2 -
 src/backend/bootstrap/bootscanner.l | 60 ++++++++++++++++-------------
 src/tools/pginclude/headerscheck    |  1 +
 6 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/src/backend/Makefile b/src/backend/Makefile
index 3f01c65592..5a12666918 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -180,7 +180,7 @@ 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
@@ -298,6 +298,7 @@ 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 \
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/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index 3f8640a03d..96a95cad9b 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -117,6 +117,7 @@ do
 	# parser/gram.h will be included by parser/gramparse.h anyway.
 	test "$f" = src/include/parser/gram.h && continue
 	test "$f" = src/backend/parser/gram.h && continue
+	test "$f" = src/backend/bootstrap/bootparse.h && continue
 	test "$f" = src/pl/plpgsql/src/pl_gram.h && continue
 	test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue
 
-- 
2.36.1

