From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Fri, 19 Jan 2007 16:42:24 +0000 (+0000)
Subject: Change the sed rules in the regression test for pg_regress hackery to create
X-Git-Tag: REL8_3_BETA1~1499
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b4a08896bd6ee7d93f74c77f61d3518deda8fd5;p=postgresql

Change the sed rules in the regression test for pg_regress hackery to create
the generated files, to help Visual C++ to run these tests.  The tests still
pass in VPATH and normal builds.

Patch from Magnus Hagander, editorialized by me.
---

diff --git a/src/include/port.h b/src/include/port.h
index 305fe7c3c9..3056042660 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/port.h,v 1.108 2007/01/11 02:39:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/port.h,v 1.109 2007/01/19 16:42:24 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,6 +46,10 @@ extern void get_man_path(const char *my_exec_path, char *ret_path);
 extern bool get_home_path(char *ret_path);
 extern void get_parent_directory(char *path);
 
+/* port/dirmod.c */
+extern char **pgfnames(char *path);
+extern void pgfnames_cleanup(char **filenames);
+
 /*
  *	is_absolute_path
  *
diff --git a/src/port/dirmod.c b/src/port/dirmod.c
index 06f66305ca..e1f7527b33 100644
--- a/src/port/dirmod.c
+++ b/src/port/dirmod.c
@@ -10,7 +10,7 @@
  *	Win32 (NT, Win2k, XP).	replace() doesn't work on Win95/98/Me.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/port/dirmod.c,v 1.46 2007/01/05 22:20:02 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/port/dirmod.c,v 1.47 2007/01/19 16:42:24 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -287,12 +287,14 @@ pgsymlink(const char *oldpath, const char *newpath)
 
 
 /*
- * fnames
+ * pgfnames
  *
- * return a list of the names of objects in the argument directory
+ * return a list of the names of objects in the argument directory.  Caller
+ * must call pgfnames_cleanup later to free the memory allocated by this
+ * function.
  */
-static char **
-fnames(char *path)
+char **
+pgfnames(char *path)
 {
 	DIR		   *dir;
 	struct dirent *file;
@@ -357,12 +359,12 @@ fnames(char *path)
 
 
 /*
- *	fnames_cleanup
+ *	pgfnames_cleanup
  *
  *	deallocate memory used for filenames
  */
-static void
-fnames_cleanup(char **filenames)
+void
+pgfnames_cleanup(char **filenames)
 {
 	char	  **fn;
 
@@ -394,7 +396,7 @@ rmtree(char *path, bool rmtopdir)
 	 * we copy all the names out of the directory before we start modifying
 	 * it.
 	 */
-	filenames = fnames(path);
+	filenames = pgfnames(path);
 
 	if (filenames == NULL)
 		return false;
@@ -415,7 +417,7 @@ rmtree(char *path, bool rmtopdir)
 			if (!rmtree(filepath, true))
 			{
 				/* we already reported the error */
-				fnames_cleanup(filenames);
+				pgfnames_cleanup(filenames);
 				return false;
 			}
 		}
@@ -433,7 +435,7 @@ rmtree(char *path, bool rmtopdir)
 			goto report_and_fail;
 	}
 
-	fnames_cleanup(filenames);
+	pgfnames_cleanup(filenames);
 	return true;
 
 report_and_fail:
@@ -444,6 +446,6 @@ report_and_fail:
 	fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
 			filepath, strerror(errno));
 #endif
-	fnames_cleanup(filenames);
+	pgfnames_cleanup(filenames);
 	return false;
 }
diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile
index 80a7467929..5b194cb3d9 100644
--- a/src/test/regress/GNUmakefile
+++ b/src/test/regress/GNUmakefile
@@ -6,7 +6,7 @@
 # Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/test/regress/GNUmakefile,v 1.63 2007/01/05 22:20:03 momjian Exp $
+# $PostgreSQL: pgsql/src/test/regress/GNUmakefile,v 1.64 2007/01/19 16:42:24 alvherre Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -40,7 +40,8 @@ endif
 # stuff to pass into build of pg_regress
 EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \
 	'-DMAKEPROG="$(MAKE)"' \
-	'-DSHELLPROG="$(SHELL)"'
+	'-DSHELLPROG="$(SHELL)"' \
+	'-DDLSUFFIX="$(DLSUFFIX)"'
 
 ##
 ## Prepare for tests
@@ -83,14 +84,12 @@ $(NAME)$(DLSUFFIX): $(shlib)
 	rm -f $(NAME)$(DLSUFFIX)
 	$(LN_S) $(shlib) $(NAME)$(DLSUFFIX)
 
-# Build test input and expected files
-
-file_list := copy create_function_1 create_function_2 misc constraints tablespace
+# Test input and expected files.  These are created by pg_regress itself, so we
+# don't have a rule to create them.  We do need rules to clean them however.
+file_list := $(subst .source,, $(notdir $(wildcard $(top_srcdir)/$(subdir)/input/*.source)))
 input_files  := $(foreach file, $(file_list), sql/$(file).sql)
 output_files := $(foreach file, $(file_list), expected/$(file).out)
 
-all: $(input_files) $(output_files)
-
 ifneq ($(PORTNAME),win32)
 abs_srcdir := $(shell cd $(srcdir) && pwd)
 abs_builddir := $(shell pwd)
@@ -99,22 +98,6 @@ abs_srcdir := $(shell cd $(srcdir) && pwd -W)
 abs_builddir := $(shell pwd -W)
 endif
 
-testtablespace := $(abs_builddir)/testtablespace
-
-
-define sed-command
-sed -e 's,@abs_srcdir@,$(abs_srcdir),g' \
-    -e 's,@abs_builddir@,$(abs_builddir),g' \
-    -e 's,@testtablespace@,$(testtablespace),g' \
-    -e 's/@DLSUFFIX@/$(DLSUFFIX)/g' $< >$@
-endef
-
-$(input_files): sql/%.sql: input/%.source
-	$(sed-command)
-
-$(output_files): expected/%.out: output/%.source
-	$(sed-command)
-
 # When doing a VPATH build, copy over the remaining .sql and .out
 # files so that the driver script can find them.  We have to use an
 # absolute path for the targets, because otherwise make will try to
@@ -148,17 +131,17 @@ all-spi:
 check: all
 	-rm -rf ./testtablespace
 	mkdir ./testtablespace
-	./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE)
+	./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --srcdir=$(abs_srcdir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE)
 
 installcheck: all
 	-rm -rf ./testtablespace
 	mkdir ./testtablespace
-	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE)
+	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --srcdir=$(abs_srcdir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE)
 
 installcheck-parallel: all
 	-rm -rf ./testtablespace
 	mkdir ./testtablespace
-	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE)
+	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/parallel_schedule --srcdir=$(abs_srcdir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE)
 
 
 # old interfaces follow...
@@ -168,10 +151,10 @@ runtest: installcheck
 runtest-parallel: installcheck-parallel
 
 bigtest:
-	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) numeric_big 
+	./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --srcdir=$(abs_srcdir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) numeric_big 
 
 bigcheck:
-	./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) numeric_big
+	./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --srcdir=$(abs_srcdir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) numeric_big
 
 
 ##
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index c9457324ec..da10cda9dd 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.25 2007/01/05 22:20:03 momjian Exp $
+ * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.26 2007/01/19 16:42:24 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -95,6 +95,7 @@ static char *psqldir = NULL;
 static char *hostname = NULL;
 static int	port = -1;
 static char *user = NULL;
+static char *srcdir = NULL;
 
 /* internal variables */
 static const char *progname;
@@ -111,6 +112,11 @@ static int	success_count = 0;
 static int	fail_count = 0;
 static int	fail_ignore_count = 0;
 
+static bool
+directory_exists(const char *dir);
+static void
+make_directory(const char *dir);
+
 static void
 header(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
@@ -330,6 +336,155 @@ string_matches_pattern(const char *str, const char *pattern)
 	return false;
 }
 
+/*
+ * Replace all occurances of a string in a string with a different string.
+ * NOTE: Assumes there is enough room in the target buffer!
+ */
+static void
+replace_string(char *string, char *replace, char *replacement)
+{
+	char *ptr;
+
+	while ((ptr = strstr(string, replace)) != NULL) 
+	{
+		char *dup = strdup(string);
+
+		strncpy(string, dup, ptr - string);
+		string[ptr - string] = 0;
+		strcat(string, replacement);
+		strcat(string, dup + (ptr - string) + strlen(replace));
+		free(dup);
+	}
+}
+
+/*
+ * Convert *.source found in the "source" directory, replacing certain tokens
+ * in the file contents with their intended values, and put the resulting files
+ * in the "dest" directory, replacing the ".source" prefix in their names with
+ * the given suffix.
+ */
+static void
+convert_sourcefiles_in(char *source, char *dest, char *suffix)
+{
+	char	abs_srcdir[MAXPGPATH];
+	char	abs_builddir[MAXPGPATH];
+	char	testtablespace[MAXPGPATH];
+	char	indir[MAXPGPATH];
+	char  **name;
+	char  **names;
+	int		count = 0;
+#ifdef WIN32
+	char *c;
+#endif
+
+	if (!getcwd(abs_builddir, sizeof(abs_builddir)))
+	{
+		fprintf(stderr, _("%s: could not get current directory: %s\n"),
+			progname, strerror(errno));
+		exit_nicely(2);
+	}
+
+	/*
+	 * in a VPATH build, use the provided source directory; otherwise, use
+	 * the current directory.
+	 */
+	if (srcdir)
+		strcpy(abs_srcdir, srcdir);
+	else
+		strcpy(abs_srcdir, abs_builddir);
+
+	snprintf(indir, MAXPGPATH, "%s/%s", abs_srcdir, source);
+	names = pgfnames(indir);
+	if (!names)
+		/* Error logged in pgfnames */
+		exit_nicely(2);
+
+#ifdef WIN32
+	/* in Win32, replace backslashes with forward slashes */
+	for (c = abs_builddir; *c; c++)
+		if (*c == '\\')
+			*c = '/';
+	for (c = abs_srcdir; *c; c++)
+		if (*c == '\\')
+			*c = '/';
+#endif
+
+	/* try to create the test tablespace dir if it doesn't exist */
+	snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", abs_builddir);
+	if (directory_exists(testtablespace))
+		rmtree(testtablespace, true);
+	make_directory(testtablespace);
+
+	/* finally loop on each file and do the replacement */
+	for (name = names; *name; name++)
+	{
+		char	srcfile[MAXPGPATH];
+		char	destfile[MAXPGPATH];
+		char	prefix[MAXPGPATH];
+		FILE   *infile,
+			   *outfile;
+		char	line[1024];
+
+		/* reject filenames not finishing in ".source" */
+		if (strlen(*name) < 8)
+			continue;
+		if (strcmp(*name + strlen(*name) - 7, ".source") != 0)
+			continue;
+
+		count++;
+
+		/* build the full actual paths to open */
+		snprintf(prefix, strlen(*name) - 6, "%s", *name);
+		snprintf(srcfile, MAXPGPATH, "%s/%s", indir, *name);
+		snprintf(destfile, MAXPGPATH, "%s/%s.%s", dest, prefix, suffix);
+
+		infile = fopen(srcfile, "r");
+		if (!infile)
+		{
+			fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
+					progname, srcfile, strerror(errno));
+			exit_nicely(2);
+		}
+		outfile = fopen(destfile, "w");
+		if (!outfile)
+		{
+			fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
+				progname, destfile, strerror(errno));
+			exit_nicely(2);
+		}
+		while (fgets(line, sizeof(line), infile))
+		{
+			replace_string(line, "@abs_srcdir@", abs_srcdir);
+			replace_string(line, "@abs_builddir@", abs_builddir);
+			replace_string(line, "@testtablespace@", testtablespace);
+			replace_string(line, "@DLSUFFIX@", DLSUFFIX);
+			fputs(line, outfile);
+		}
+		fclose(infile);
+		fclose(outfile);
+	}
+
+	/*
+	 * If we didn't process any files, complain because it probably means
+	 * somebody neglected to pass the needed --srcdir argument.
+	 */
+	if (count <= 0)
+	{
+		fprintf(stderr, _("%s: no *.source files found in %s\n"),
+				progname, indir);
+		exit_nicely(2);
+	}
+	
+    pgfnames_cleanup(names);
+}
+
+static void
+convert_sourcefiles(void)
+{
+	convert_sourcefiles_in("input", "sql", "sql");
+	convert_sourcefiles_in("output", "expected", "out");
+}
+
 /*
  * Scan resultmap file to find which platform-specific expected files to use.
  *
@@ -593,6 +748,7 @@ initialize_environment(void)
 			printf(_("(using postmaster on Unix socket, default port)\n"));
 	}
 
+	convert_sourcefiles();
 	load_resultmap();
 }
 
@@ -1322,6 +1478,7 @@ help(void)
 	printf(_("  --outputdir=DIR           place output files in DIR (default \".\")\n"));
 	printf(_("  --schedule=FILE           use test ordering schedule from FILE\n"));
 	printf(_("                            (may be used multiple times to concatenate)\n"));
+	printf(_("  --srcdir=DIR              absolute path to source directory (for VPATH builds)\n"));
 	printf(_("  --temp-install=DIR        create a temporary installation in DIR\n"));
 	printf(_("  --no-locale               use C locale\n"));
 	printf(_("\n"));
@@ -1369,6 +1526,7 @@ main(int argc, char *argv[])
 		{"port", required_argument, NULL, 14},
 		{"user", required_argument, NULL, 15},
 		{"psqldir", required_argument, NULL, 16},
+		{"srcdir", required_argument, NULL, 17},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -1461,6 +1619,9 @@ main(int argc, char *argv[])
 				if (strlen(optarg))
 					psqldir = strdup(optarg);
 				break;
+			case 17:
+				srcdir = strdup(optarg);
+				break;
 			default:
 				/* getopt_long already emitted a complaint */
 				fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"),