From 697b7d18f59b51ebc40672e18791b8deccc3733c Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sat, 13 Aug 2022 12:35:55 +0700
Subject: [PATCH v4 11/11] Build jsonpath_scan.c standalone

---
 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/tools/pginclude/headerscheck          |  1 +
 6 files changed, 63 insertions(+), 38 deletions(-)
 create mode 100644 src/backend/utils/adt/jsonpath_internal.h

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}
 
 <xnq,xq,xvq>{hex_char}		{ parseHexChar(yytext); }
 
-<xnq,xq,xvq>{unicode}*{unicodefail}	{ yyerror(NULL, "invalid unicode sequence"); }
+<xnq,xq,xvq>{unicode}*{unicodefail}	{ jsonpath_yyerror(NULL, "invalid unicode sequence"); }
 
-<xnq,xq,xvq>{hex_fail}		{ yyerror(NULL, "invalid hex character sequence"); }
+<xnq,xq,xvq>{hex_fail}		{ jsonpath_yyerror(NULL, "invalid hex character sequence"); }
 
 <xnq,xq,xvq>{unicode}+\\	{
 								/* throw back the \\, and treat as unicode */
@@ -154,9 +163,9 @@ hex_fail	\\x{hex_dig}{0,1}
 
 <xnq,xq,xvq>\\.				{ addchar(false, yytext[1]); }
 
-<xnq,xq,xvq>\\				{ yyerror(NULL, "unexpected end after backslash"); }
+<xnq,xq,xvq>\\				{ jsonpath_yyerror(NULL, "unexpected end after backslash"); }
 
-<xq,xvq><<EOF>>				{ yyerror(NULL, "unexpected end of quoted string"); }
+<xq,xvq><<EOF>>				{ jsonpath_yyerror(NULL, "unexpected end of quoted string"); }
 
 <xq>\"							{
 									yylval->str = scanstring;
@@ -178,7 +187,7 @@ hex_fail	\\x{hex_dig}{0,1}
 
 <xc>\*							{ }
 
-<xc><<EOF>>						{ yyerror(NULL, "unexpected end of comment"); }
+<xc><<EOF>>						{ 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/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index 7022ac6c39..1db0096758 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -124,6 +124,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/backend/utils/adt/jsonpath_gram.h && continue
 	test "$f" = src/test/isolation/specparse.h && continue
 	test "$f" = src/bin/pgbench/exprparse.h && continue
 	test "$f" = src/pl/plpgsql/src/pl_gram.h && continue
-- 
2.36.1

