From 5b4a08896bd6ee7d93f74c77f61d3518deda8fd5 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 19 Jan 2007 16:42:24 +0000 Subject: [PATCH] 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. --- src/include/port.h | 6 +- src/port/dirmod.c | 26 +++--- src/test/regress/GNUmakefile | 39 +++----- src/test/regress/pg_regress.c | 163 +++++++++++++++++++++++++++++++++- 4 files changed, 192 insertions(+), 42 deletions(-) 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"), -- 2.40.0