From 1d66a1cca1e0ad649beba720466461b4af7fddd4 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Sun, 21 Mar 2010 10:49:52 +0000
Subject: [PATCH] ECPG only copied #include statements instead of processing
 them according to commandline option "-i". This change fixes this and adds a
 test case. It also honors #include_next, although this is probably never used
 for embedded SQL.

---
 src/interfaces/ecpg/preproc/pgc.l             | 39 ++++++++++++++++---
 .../ecpg/test/compat_informix/rnull.pgc       |  2 +-
 .../test/compat_informix/test_informix.pgc    |  2 +-
 .../test/expected/compat_informix-rnull.c     |  2 +-
 .../expected/compat_informix-test_informix.c  |  2 +-
 .../ecpg/test/expected/preproc-strings.c      | 21 +++++-----
 .../ecpg/test/expected/preproc-strings.stderr | 36 ++++++++---------
 src/interfaces/ecpg/test/preproc/Makefile     |  2 +
 src/interfaces/ecpg/test/preproc/strings.h    |  1 +
 src/interfaces/ecpg/test/preproc/strings.pgc  |  8 ++--
 10 files changed, 72 insertions(+), 43 deletions(-)
 create mode 100644 src/interfaces/ecpg/test/preproc/strings.h

diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index 7a61b0f49f3..cb00408752a 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.172 2010/01/26 09:07:31 meskes Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.173 2010/03/21 10:49:51 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,6 +44,9 @@ static int		literalalloc;			/* current allocated buffer size */
 /* Used for detecting global state together with braces_open */
 static int		parenths_open;
 
+/* Used to tell parse_include() whether the command was #include or #include_next */
+static bool		include_next;
+
 #define startlit()	(literalbuf[0] = '\0', literallen = 0)
 static void addlit(char *ytext, int yleng);
 static void addlitchar (unsigned char);
@@ -310,11 +313,14 @@ other			.
 
 /* some stuff needed for ecpg */
 exec			[eE][xX][eE][cC]
-sql				[sS][qQ][lL]
+sql			[sS][qQ][lL]
 define			[dD][eE][fF][iI][nN][eE]
 include 		[iI][nN][cC][lL][uU][dD][eE]
+include_next 		[iI][nN][cC][lL][uU][dD][eE]_[nN][eE][xX][tT]
+import	 		[iI][mM][pP][oO][rR][tT]
 undef			[uU][nN][dD][eE][fF]
 
+if			[iI][fF]
 ifdef			[iI][fF][dD][eE][fF]
 ifndef			[iI][fF][nN][dD][eE][fF]
 else			[eE][lL][sS][eE]
@@ -325,13 +331,17 @@ struct			[sS][tT][rR][uU][cC][tT]
 
 exec_sql		{exec}{space}*{sql}{space}*
 ipdigit			({digit}|{digit}{digit}|{digit}{digit}{digit})
-ip				{ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit}
+ip			{ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit}
 
 /* we might want to parse all cpp include files */
 cppinclude 		{space}*#{include}{space}*
+cppinclude_next		{space}*#{include_next}{space}*
 
-/* Take care of cpp lines, they may also be continuated */
-cppline			{space}*#(.*\\{space})*.*{newline}
+/* take care of cpp lines, they may also be continuated */
+/* first a general line for all commands not starting with "i" */
+/* and then the other commands starting with "i", we have to add these
+ * seperately because the cppline production would match on "include" too */
+cppline			{space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})(.*\\{space})*.*{newline}
 
 /*
  * Dollar quoted strings are totally opaque, and no escaping is done on them.
@@ -777,6 +787,19 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 <C>{cppinclude}		{
 						if (system_includes)
 						{
+							include_next = false;
+							BEGIN(incl);
+						}
+						else
+					 	{
+							yylval.str = mm_strdup(yytext);
+							return(CPP_LINE);
+					  	}
+					}
+<C>{cppinclude_next}		{
+						if (system_includes)
+						{
+							include_next = true;
 							BEGIN(incl);
 						}
 						else
@@ -1322,6 +1345,12 @@ parse_include(void)
 					yyin = fopen( inc_file, "r" );
 				}
 			}
+			/* if the command was "include_next" we have to disregard the first hit */
+			if (yyin && include_next)
+			{
+				yyin = NULL;
+				include_next = false;
+			}
 		}
 	}
 	if (!yyin)
diff --git a/src/interfaces/ecpg/test/compat_informix/rnull.pgc b/src/interfaces/ecpg/test/compat_informix/rnull.pgc
index aa3e0823c55..a6ad35e3bc9 100644
--- a/src/interfaces/ecpg/test/compat_informix/rnull.pgc
+++ b/src/interfaces/ecpg/test/compat_informix/rnull.pgc
@@ -1,6 +1,6 @@
 #include "sqltypes.h"
 #include <stdlib.h>
-#
+
 $include ../regression;
 $define NUMBER 12;
 
diff --git a/src/interfaces/ecpg/test/compat_informix/test_informix.pgc b/src/interfaces/ecpg/test/compat_informix/test_informix.pgc
index f04954bd90f..da9115e5ba1 100644
--- a/src/interfaces/ecpg/test/compat_informix/test_informix.pgc
+++ b/src/interfaces/ecpg/test/compat_informix/test_informix.pgc
@@ -1,6 +1,6 @@
 #include "sqltypes.h"
 #include <stdlib.h>
-#
+
 $include ../regression;
 $define NUMBER 12;
 
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-rnull.c b/src/interfaces/ecpg/test/expected/compat_informix-rnull.c
index 8ae62933b5a..e90a291e3d9 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-rnull.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-rnull.c
@@ -11,7 +11,7 @@
 #line 1 "rnull.pgc"
 #include "sqltypes.h"
 #include <stdlib.h>
-#
+
 
 #line 1 "regression.h"
 
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
index c19c2e5aff6..4d5ffa825b5 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
@@ -11,7 +11,7 @@
 #line 1 "test_informix.pgc"
 #include "sqltypes.h"
 #include <stdlib.h>
-#
+
 
 #line 1 "regression.h"
 
diff --git a/src/interfaces/ecpg/test/expected/preproc-strings.c b/src/interfaces/ecpg/test/expected/preproc-strings.c
index b72d9eeadd0..dd13cf36cf0 100644
--- a/src/interfaces/ecpg/test/expected/preproc-strings.c
+++ b/src/interfaces/ecpg/test/expected/preproc-strings.c
@@ -7,8 +7,6 @@
 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
 
 #line 1 "strings.pgc"
-#include <stdlib.h>
-
 
 #line 1 "regression.h"
 
@@ -18,15 +16,16 @@
 
 
 #line 3 "strings.pgc"
-
-
 /* exec sql begin declare section */
+#line 1 "strings.h"
       
 
-#line 6 "strings.pgc"
+#line 5 "strings.pgc"
+
+#line 1 "strings.h"
  char * s1 , * s2 , * s3 , * s4 , * s5 , * s6 ;
 /* exec sql end declare section */
-#line 7 "strings.pgc"
+#line 5 "strings.pgc"
 
 
 int main(void)
@@ -34,11 +33,11 @@ int main(void)
   ECPGdebug(1, stderr);
 
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 13 "strings.pgc"
+#line 11 "strings.pgc"
 
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set standard_conforming_strings to on", ECPGt_EOIT, ECPGt_EORT);}
-#line 15 "strings.pgc"
+#line 13 "strings.pgc"
 
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select 'abcdef' , N'abcdef' as foo , E'abc\\bdef' as \"foo\" , U&'d\\0061t\\0061' as U&\"foo\" , U&'d!+000061t!+000061' uescape '!' , $foo$abc$def$foo$", ECPGt_EOIT, 
@@ -54,13 +53,13 @@ int main(void)
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(s6),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 23 "strings.pgc"
+#line 21 "strings.pgc"
 
 
   printf("%s %s %s %s %s %s\n", s1, s2, s3, s4, s5, s6);
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 27 "strings.pgc"
+#line 25 "strings.pgc"
 
-  exit (0);
+  return (0);
 }
diff --git a/src/interfaces/ecpg/test/expected/preproc-strings.stderr b/src/interfaces/ecpg/test/expected/preproc-strings.stderr
index 6dc59b84f59..86dc3d69840 100644
--- a/src/interfaces/ecpg/test/expected/preproc-strings.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-strings.stderr
@@ -2,41 +2,41 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 15: query: set standard_conforming_strings to on; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 13: query: set standard_conforming_strings to on; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 15: using PQexec
+[NO_PID]: ecpg_execute on line 13: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 15: OK: SET
+[NO_PID]: ecpg_execute on line 13: OK: SET
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 17: query: select 'abcdef' , N'abcdef' as foo , E'abc\bdef' as "foo" , U&'d\0061t\0061' as U&"foo" , U&'d!+000061t!+000061' uescape '!' , $foo$abc$def$foo$; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 15: query: select 'abcdef' , N'abcdef' as foo , E'abc\bdef' as "foo" , U&'d\0061t\0061' as U&"foo" , U&'d!+000061t!+000061' uescape '!' , $foo$abc$def$foo$; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 17: using PQexec
+[NO_PID]: ecpg_execute on line 15: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 17: correctly got 1 tuples with 6 fields
+[NO_PID]: ecpg_execute on line 15: correctly got 1 tuples with 6 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 17: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 15: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 17: RESULT: abcdef offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 15: RESULT: abcdef offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 17: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 15: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 17: RESULT: abcdef offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 15: RESULT: abcdef offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 17: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 15: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 17: RESULT: abcdef offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 15: RESULT: abcdef offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 17: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 15: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 17: RESULT: data offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 15: RESULT: data offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 17: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 15: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 17: RESULT: data offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 15: RESULT: data offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 17: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 15: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 17: RESULT: abc$def offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 15: RESULT: abc$def offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile
index 6d1d6294f54..3bcb63a0bab 100644
--- a/src/interfaces/ecpg/test/preproc/Makefile
+++ b/src/interfaces/ecpg/test/preproc/Makefile
@@ -24,3 +24,5 @@ array_of_struct.c:	array_of_struct.pgc ../regression.h
 autoprep.c:     autoprep.pgc ../regression.h
 	$(ECPG) -r prepare -o $@ -I$(srcdir) $<
 
+strings.c:     strings.pgc strings.h ../regression.h
+	$(ECPG) -i -o $@ -I$(srcdir) $<
diff --git a/src/interfaces/ecpg/test/preproc/strings.h b/src/interfaces/ecpg/test/preproc/strings.h
new file mode 100644
index 00000000000..4779af9881d
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/strings.h
@@ -0,0 +1 @@
+char *s1, *s2, *s3, *s4, *s5, *s6;
diff --git a/src/interfaces/ecpg/test/preproc/strings.pgc b/src/interfaces/ecpg/test/preproc/strings.pgc
index cfea7aa034e..7d853626079 100644
--- a/src/interfaces/ecpg/test/preproc/strings.pgc
+++ b/src/interfaces/ecpg/test/preproc/strings.pgc
@@ -1,9 +1,7 @@
-#include <stdlib.h>
-
-exec sql include ../regression;
+#include "../regression.h"
 
 exec sql begin declare section;
-char *s1, *s2, *s3, *s4, *s5, *s6;
+#include "strings.h"
 exec sql end declare section;
 
 int main(void)
@@ -25,5 +23,5 @@ int main(void)
   printf("%s %s %s %s %s %s\n", s1, s2, s3, s4, s5, s6);
 
   exec sql disconnect;
-  exit (0);
+  return (0);
 }
-- 
GitLab