From 829925b21f94ed70c33882490e6fe3351f16697e Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sat, 13 Aug 2022 09:34:17 +0700
Subject: [PATCH v3 07/11] Build specscanner.c standalone

---
 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 |  1 +
 5 files changed, 32 insertions(+), 15 deletions(-)

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; }
 <qident>\"\"	{ addlitchar(yytext[0]); }
 <qident>\"		{
 					litbuf[litbufpos] = '\0';
-					yylval.str = pg_strdup(litbuf);
+					spec_yylval.str = pg_strdup(litbuf);
 					BEGIN(INITIAL);
 					return(identifier);
 				}
 <qident>.		{ addlitchar(yytext[0]); }
-<qident>\n		{ yyerror("unexpected newline in quoted identifier"); }
-<qident><<EOF>>	{ yyerror("unterminated quoted identifier"); }
+<qident>\n		{ spec_yyerror("unexpected newline in quoted identifier"); }
+<qident><<EOF>>	{ spec_yyerror("unterminated quoted identifier"); }
 
  /* SQL blocks: { UPDATE ... } */
  /* We trim leading/trailing whitespace, otherwise they're unprocessed */
@@ -104,7 +114,7 @@ teardown		{ return TEARDOWN; }
 				}
 <sql>{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]);
 				}
 <sql><<EOF>>	{
-					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 77b697e293..cf75e93943 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -120,6 +120,7 @@ do
 	test "$f" = src/backend/bootstrap/bootparse.h && continue
 	test "$f" = src/backend/replication/repl_gram.h && continue
 	test "$f" = src/backend/replication/syncrep_gram.h && continue
+	test "$f" = src/test/isolation/specparse.h && continue
 	test "$f" = src/pl/plpgsql/src/pl_gram.h && continue
 	test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue
 
-- 
2.36.1

