Thread: WIP: pg_regress updates for vc++ bulid
Hello! Per some previous discussion that I can't really recall if it was on or off list, here is a WIP patch to make pg_regress run completely outside of msys on win32. The change needed is that the processing of files from input/ and output/ into sql/ and expected/ is moved from the Makefile and into pg_regress itself. I have tested on Win32 non-MSVC and on Linux (non-VPATH), and it appears to work there. Still to be done is the "make install" part on MSVC build, currently #ifdef:ed out. While working on that, I'd appreciate some comments on the patch in general - if there are more things I need to fix before it can be considered. Particularly I'm concerned around the VPATH stuff, since I've never used that myself. //Magnus Index: src/include/port.h =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/include/port.h,v retrieving revision 1.106 diff -c -r1.106 port.h *** src/include/port.h 28 Nov 2006 01:12:33 -0000 1.106 --- src/include/port.h 29 Dec 2006 18:31:27 -0000 *************** *** 46,51 **** --- 46,56 ---- 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 * Index: src/port/dirmod.c =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/port/dirmod.c,v retrieving revision 1.45 diff -c -r1.45 dirmod.c *** src/port/dirmod.c 4 Dec 2006 22:23:40 -0000 1.45 --- src/port/dirmod.c 29 Dec 2006 18:32:36 -0000 *************** *** 287,298 **** /* ! * fnames * * return a list of the names of objects in the argument directory */ ! static char ** ! fnames(char *path) { DIR *dir; struct dirent *file; --- 287,298 ---- /* ! * pgfnames * * return a list of the names of objects in the argument directory */ ! char ** ! pgfnames(char *path) { DIR *dir; struct dirent *file; *************** *** 357,368 **** /* ! * fnames_cleanup * * deallocate memory used for filenames */ ! static void ! fnames_cleanup(char **filenames) { char **fn; --- 357,368 ---- /* ! * pgfnames_cleanup * * deallocate memory used for filenames */ ! void ! pgfnames_cleanup(char **filenames) { char **fn; *************** *** 394,400 **** * we copy all the names out of the directory before we start modifying * it. */ ! filenames = fnames(path); if (filenames == NULL) return false; --- 394,400 ---- * we copy all the names out of the directory before we start modifying * it. */ ! filenames = pgfnames(path); if (filenames == NULL) return false; *************** *** 415,421 **** if (!rmtree(filepath, true)) { /* we already reported the error */ ! fnames_cleanup(filenames); return false; } } --- 415,421 ---- if (!rmtree(filepath, true)) { /* we already reported the error */ ! pgfnames_cleanup(filenames); return false; } } *************** *** 433,439 **** goto report_and_fail; } ! fnames_cleanup(filenames); return true; report_and_fail: --- 433,439 ---- goto report_and_fail; } ! pgfnames_cleanup(filenames); return true; report_and_fail: *************** *** 444,449 **** fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif ! fnames_cleanup(filenames); return false; } --- 444,449 ---- fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif ! pgfnames_cleanup(filenames); return false; } Index: src/test/regress/GNUmakefile =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/GNUmakefile,v retrieving revision 1.62 diff -c -r1.62 GNUmakefile *** src/test/regress/GNUmakefile 21 Jul 2006 00:24:04 -0000 1.62 --- src/test/regress/GNUmakefile 29 Dec 2006 20:44:54 -0000 *************** *** 40,46 **** # stuff to pass into build of pg_regress EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ '-DMAKEPROG="$(MAKE)"' \ ! '-DSHELLPROG="$(SHELL)"' ## ## Prepare for tests --- 40,47 ---- # stuff to pass into build of pg_regress EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ '-DMAKEPROG="$(MAKE)"' \ ! '-DSHELLPROG="$(SHELL)"' \ ! '-DDLSUFFIX="$(DLSUFFIX)"' ## ## Prepare for tests *************** *** 83,96 **** 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 - 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) --- 84,89 ---- *************** *** 99,120 **** 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 --- 92,97 ---- *************** *** 148,154 **** 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) installcheck: all -rm -rf ./testtablespace --- 125,131 ---- check: all -rm -rf ./testtablespace mkdir ./testtablespace ! ./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 Index: src/test/regress/pg_regress.c =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/pg_regress.c,v retrieving revision 1.23 diff -c -r1.23 pg_regress.c *** src/test/regress/pg_regress.c 4 Oct 2006 00:30:14 -0000 1.23 --- src/test/regress/pg_regress.c 29 Dec 2006 20:48:04 -0000 *************** *** 62,68 **** --- 62,70 ---- static char *libdir = LIBDIR; static char *datadir = PGSHAREDIR; static char *host_platform = HOST_TUPLE; + #ifndef WIN32_ONLY_COMPILER static char *makeprog = MAKEPROG; + #endif #ifndef WIN32 /* not used in WIN32 case */ static char *shellprog = SHELLPROG; *************** *** 90,95 **** --- 92,98 ---- static char *hostname = NULL; static int port = -1; static char *user = NULL; + static char *srcdir = NULL; /* internal variables */ static const char *progname; *************** *** 106,111 **** --- 109,119 ---- 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 *************** *** 302,307 **** --- 310,436 ---- } /* + * Replace all occurances of a string in a string with a different stirng. + * 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 in input/ and output/ into actual files used by the + * regression tests in sql/ and expected/. + */ + static void + convert_sourcefiles_in(char *source, char *dest, char *suffix) + { + char abs_srcdir[MAXPGPATH]; + char abs_builddir[MAXPGPATH]; + char testtablespace[MAXPGPATH]; + char **name; + char **names = pgfnames(source); + #ifdef WIN32 + char *c; + #endif + + if (!names) + /* Error logged in pgfnames */ + exit_nicely(2); + + if (!getcwd(abs_builddir, sizeof(abs_builddir))) + { + fprintf(stderr, _("%s: could not get current directory: %s\n"), + progname, strerror(errno)); + exit_nicely(2); + } + if (srcdir) + strcpy(abs_srcdir, srcdir); + else + strcpy(abs_srcdir, abs_builddir); + #ifdef WIN32 + for (c = abs_builddir; *c; c++) + if (*c == '\\') + *c = '/'; + for (c = abs_srcdir; *c; c++) + if (*c == '\\') + *c = '/'; + #endif + + + snprintf(testtablespace, sizeof(testtablespace), "%s/testtablespace", abs_builddir); + if (directory_exists(testtablespace)) + rmtree(testtablespace, true); + make_directory(testtablespace); + + for (name = names; *name; name++) + { + char srcfile[MAXPGPATH]; + char destfile[MAXPGPATH]; + FILE *infile, *outfile; + char line[1024]; + + if (strlen(*name) < 8) + continue; + if (strcmp(*name+strlen(*name)-7,".source")) + continue; + + strcpy(srcfile,source); + strcat(srcfile, *name); + strcpy(destfile,dest); + strncat(destfile, *name, strlen(*name)-6); + strcat(destfile,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); + } + + 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. * * The format of each line of the file is *************** *** 564,569 **** --- 693,699 ---- printf(_("(using postmaster on Unix socket, default port)\n")); } + convert_sourcefiles(); load_resultmap(); } *************** *** 1293,1298 **** --- 1423,1429 ---- 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")); *************** *** 1340,1345 **** --- 1471,1477 ---- {"port", required_argument, NULL, 14}, {"user", required_argument, NULL, 15}, {"psqldir", required_argument, NULL, 16}, + {"srcdir", required_argument, NULL, 17}, {NULL, 0, NULL, 0} }; *************** *** 1432,1437 **** --- 1564,1572 ---- 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"), *************** *** 1487,1492 **** --- 1622,1628 ---- make_directory(buf); /* "make install" */ + #ifndef WIN32_ONLY_COMPILER snprintf(buf, sizeof(buf), SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/log/install.log\"2>&1" SYSTEMQUOTE, makeprog, top_builddir, temp_install, outputdir); *************** *** 1495,1500 **** --- 1631,1639 ---- fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was: %s\n"),progname, outputdir, buf); exit_nicely(2); } + #else + fprintf(stderr,"FIXME: can't install yet"); + #endif /* initdb */ header(_("initializing database system")); Index: src/test/regress/resultmap =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/resultmap,v retrieving revision 1.83 diff -c -r1.83 resultmap *** src/test/regress/resultmap 3 Aug 2006 17:04:00 -0000 1.83 --- src/test/regress/resultmap 29 Dec 2006 19:51:45 -0000 *************** *** 1,8 **** --- 1,11 ---- float4/i.86-pc-mingw32=float4-exp-three-digits + float4/i.86-pc-win32vc=float4-exp-three-digits float8/i.86-.*-freebsd=float8-small-is-zero float8/i.86-.*-openbsd=float8-small-is-zero float8/i.86-.*-netbsd=float8-small-is-zero float8/m68k-.*-netbsd=float8-small-is-zero float8/i.86-pc-mingw32=float8-exp-three-digits-win32 + float8/i.86-pc-win32vc=float8-exp-three-digits-win32 float8/i.86-pc-cygwin=float8-small-is-zero int8/i.86-pc-mingw32=int8-exp-three-digits + int8/i.86-pc-win32vc=int8-exp-three-digits Index: src/tools/msvc/mkvcbuild.pl =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/mkvcbuild.pl,v retrieving revision 1.8 diff -c -r1.8 mkvcbuild.pl *** src/tools/msvc/mkvcbuild.pl 21 Nov 2006 17:54:26 -0000 1.8 --- src/tools/msvc/mkvcbuild.pl 29 Dec 2006 19:50:59 -0000 *************** *** 255,264 **** } ! # Regression DLLs my $regress = $solution->AddProject('regress','dll','misc'); $regress->AddFile('src\test\regress\regress.c'); $regress->AddReference($postgres); $solution->Save(); --- 255,271 ---- } ! # Regression DLL and EXE my $regress = $solution->AddProject('regress','dll','misc'); $regress->AddFile('src\test\regress\regress.c'); $regress->AddReference($postgres); + + my $pgregress = $solution->AddProject('pg_regress','exe','misc'); + $pgregress->AddFile('src\test\regress\pg_regress.c'); + $pgregress->AddIncludeDir('src\port'); + $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); + $pgregress->AddDefine('FRONTEND'); + $pgregress->AddReference($libpgport); $solution->Save();
Magnus Hagander wrote: > Hello! > > Per some previous discussion that I can't really recall if it was on or > off list, here is a WIP patch to make pg_regress run completely outside > of msys on win32. > > The change needed is that the processing of files from input/ and > output/ into sql/ and expected/ is moved from the Makefile and into > pg_regress itself. > > I have tested on Win32 non-MSVC and on Linux (non-VPATH), and it appears > to work there. > > Still to be done is the "make install" part on MSVC build, currently > #ifdef:ed out. While working on that, I'd appreciate some comments on > the patch in general - if there are more things I need to fix before it > can be considered. Particularly I'm concerned around the VPATH stuff, > since I've never used that myself. Here's the patch without the WIP tag. It works for me per above, and also for a "check" (not just "installcheck") on msvc built without msys. Again, the vpath part is the one I'm most unsure about, but I'm sure there could be other parts. Hopefully this will make it possible to get the msvc build up on the buildfarm not too long from now. Also, as in the first patch but not noted, this one makes it possible to run the regression tests as an admin account "the proper way" on both mingw and msvc. //Magnus Index: src/include/port.h =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/include/port.h,v retrieving revision 1.107 diff -c -r1.107 port.h *** src/include/port.h 5 Jan 2007 22:19:50 -0000 1.107 --- src/include/port.h 7 Jan 2007 15:11:12 -0000 *************** *** 46,51 **** --- 46,56 ---- 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 * Index: src/port/dirmod.c =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/port/dirmod.c,v retrieving revision 1.46 diff -c -r1.46 dirmod.c *** src/port/dirmod.c 5 Jan 2007 22:20:02 -0000 1.46 --- src/port/dirmod.c 7 Jan 2007 15:13:27 -0000 *************** *** 287,298 **** /* ! * fnames * * return a list of the names of objects in the argument directory */ ! static char ** ! fnames(char *path) { DIR *dir; struct dirent *file; --- 287,298 ---- /* ! * pgfnames * * return a list of the names of objects in the argument directory */ ! char ** ! pgfnames(char *path) { DIR *dir; struct dirent *file; *************** *** 357,368 **** /* ! * fnames_cleanup * * deallocate memory used for filenames */ ! static void ! fnames_cleanup(char **filenames) { char **fn; --- 357,368 ---- /* ! * pgfnames_cleanup * * deallocate memory used for filenames */ ! void ! pgfnames_cleanup(char **filenames) { char **fn; *************** *** 394,400 **** * we copy all the names out of the directory before we start modifying * it. */ ! filenames = fnames(path); if (filenames == NULL) return false; --- 394,400 ---- * we copy all the names out of the directory before we start modifying * it. */ ! filenames = pgfnames(path); if (filenames == NULL) return false; *************** *** 415,421 **** if (!rmtree(filepath, true)) { /* we already reported the error */ ! fnames_cleanup(filenames); return false; } } --- 415,421 ---- if (!rmtree(filepath, true)) { /* we already reported the error */ ! pgfnames_cleanup(filenames); return false; } } *************** *** 433,439 **** goto report_and_fail; } ! fnames_cleanup(filenames); return true; report_and_fail: --- 433,439 ---- goto report_and_fail; } ! pgfnames_cleanup(filenames); return true; report_and_fail: *************** *** 444,449 **** fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif ! fnames_cleanup(filenames); return false; } --- 444,449 ---- fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif ! pgfnames_cleanup(filenames); return false; } Index: src/test/regress/GNUmakefile =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/GNUmakefile,v retrieving revision 1.63 diff -c -r1.63 GNUmakefile *** src/test/regress/GNUmakefile 5 Jan 2007 22:20:03 -0000 1.63 --- src/test/regress/GNUmakefile 7 Jan 2007 15:13:40 -0000 *************** *** 40,46 **** # stuff to pass into build of pg_regress EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ '-DMAKEPROG="$(MAKE)"' \ ! '-DSHELLPROG="$(SHELL)"' ## ## Prepare for tests --- 40,47 ---- # stuff to pass into build of pg_regress EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ '-DMAKEPROG="$(MAKE)"' \ ! '-DSHELLPROG="$(SHELL)"' \ ! '-DDLSUFFIX="$(DLSUFFIX)"' ## ## Prepare for tests *************** *** 83,96 **** 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 - 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) --- 84,89 ---- *************** *** 99,120 **** 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 --- 92,97 ---- *************** *** 148,154 **** 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) installcheck: all -rm -rf ./testtablespace --- 125,131 ---- check: all -rm -rf ./testtablespace mkdir ./testtablespace ! ./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 *************** *** 168,174 **** runtest-parallel: installcheck-parallel bigtest: ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --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 --- 145,151 ---- runtest-parallel: installcheck-parallel bigtest: ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --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 Index: src/test/regress/pg_regress.c =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/pg_regress.c,v retrieving revision 1.25 diff -c -r1.25 pg_regress.c *** src/test/regress/pg_regress.c 5 Jan 2007 22:20:03 -0000 1.25 --- src/test/regress/pg_regress.c 7 Jan 2007 15:13:41 -0000 *************** *** 67,73 **** --- 67,75 ---- static char *libdir = LIBDIR; static char *datadir = PGSHAREDIR; static char *host_platform = HOST_TUPLE; + #ifndef WIN32_ONLY_COMPILER static char *makeprog = MAKEPROG; + #endif #ifndef WIN32 /* not used in WIN32 case */ static char *shellprog = SHELLPROG; *************** *** 95,100 **** --- 97,103 ---- static char *hostname = NULL; static int port = -1; static char *user = NULL; + static char *srcdir = NULL; /* internal variables */ static const char *progname; *************** *** 111,116 **** --- 114,124 ---- 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 *************** *** 152,157 **** --- 160,169 ---- #endif + #ifdef WIN32 + typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES,DWORD, PSID_AND_ATTRIBUTES, PHANDLE); + #endif + /* * Add an item at the end of a stringlist. */ *************** *** 331,336 **** --- 343,468 ---- } /* + * Replace all occurances of a string in a string with a different stirng. + * 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 in input/ and output/ into actual files used by the + * regression tests in sql/ and expected/. + */ + static void + convert_sourcefiles_in(char *source, char *dest, char *suffix) + { + char abs_srcdir[MAXPGPATH]; + char abs_builddir[MAXPGPATH]; + char testtablespace[MAXPGPATH]; + char **name; + char **names = pgfnames(source); + #ifdef WIN32 + char *c; + #endif + + if (!names) + /* Error logged in pgfnames */ + exit_nicely(2); + + if (!getcwd(abs_builddir, sizeof(abs_builddir))) + { + fprintf(stderr, _("%s: could not get current directory: %s\n"), + progname, strerror(errno)); + exit_nicely(2); + } + if (srcdir) + strcpy(abs_srcdir, srcdir); + else + strcpy(abs_srcdir, abs_builddir); + #ifdef WIN32 + for (c = abs_builddir; *c; c++) + if (*c == '\\') + *c = '/'; + for (c = abs_srcdir; *c; c++) + if (*c == '\\') + *c = '/'; + #endif + + + snprintf(testtablespace, sizeof(testtablespace), "%s/testtablespace", abs_builddir); + if (directory_exists(testtablespace)) + rmtree(testtablespace, true); + make_directory(testtablespace); + + for (name = names; *name; name++) + { + char srcfile[MAXPGPATH]; + char destfile[MAXPGPATH]; + FILE *infile, *outfile; + char line[1024]; + + if (strlen(*name) < 8) + continue; + if (strcmp(*name+strlen(*name)-7,".source")) + continue; + + strcpy(srcfile,source); + strcat(srcfile, *name); + strcpy(destfile,dest); + strncat(destfile, *name, strlen(*name)-6); + strcat(destfile,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); + } + + 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. * * The format of each line of the file is *************** *** 593,598 **** --- 725,731 ---- printf(_("(using postmaster on Unix socket, default port)\n")); } + convert_sourcefiles(); load_resultmap(); } *************** *** 690,705 **** return pid; #else char *cmdline2; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); cmdline2 = malloc(strlen(cmdline) + 8); sprintf(cmdline2, "cmd /c %s", cmdline); ! if (!CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { fprintf(stderr, _("could not start process for \"%s\": %lu\n"), cmdline2, GetLastError()); --- 823,898 ---- return pid; #else char *cmdline2; + BOOL b; STARTUPINFO si; PROCESS_INFORMATION pi; + HANDLE origToken; + HANDLE restrictedToken; + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + SID_AND_ATTRIBUTES dropSids[2]; + __CreateRestrictedToken _CreateRestrictedToken = NULL; + HANDLE Advapi32Handle; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); + Advapi32Handle = LoadLibrary("ADVAPI32.DLL"); + if (Advapi32Handle != NULL) + { + _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken"); + } + + if (_CreateRestrictedToken == NULL) + { + fprintf(stderr, "WARNING: Unable to create restricted tokens on this platform\n"); + if (Advapi32Handle != NULL) + FreeLibrary(Advapi32Handle); + return 0; + } + + /* Open the current token to use as a base for the restricted one */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken)) + { + fprintf(stderr, "Failed to open process token: %lu\n", GetLastError()); + return 0; + } + + /* Allocate list of SIDs to remove */ + ZeroMemory(&dropSids, sizeof(dropSids)); + if (!AllocateAndInitializeSid(&NtAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, + 0, &dropSids[0].Sid) || + !AllocateAndInitializeSid(&NtAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, + 0, &dropSids[1].Sid)) + { + fprintf(stderr, "Failed to allocate SIDs: %lu\n", GetLastError()); + return 0; + } + + b = _CreateRestrictedToken(origToken, + DISABLE_MAX_PRIVILEGE, + sizeof(dropSids) / sizeof(dropSids[0]), + dropSids, + 0, NULL, + 0, NULL, + &restrictedToken); + + FreeSid(dropSids[1].Sid); + FreeSid(dropSids[0].Sid); + CloseHandle(origToken); + FreeLibrary(Advapi32Handle); + + if (!b) + { + fprintf(stderr, "Failed to create restricted token: %lu\n", GetLastError()); + return 0; + } + cmdline2 = malloc(strlen(cmdline) + 8); sprintf(cmdline2, "cmd /c %s", cmdline); ! if (!CreateProcessAsUser(restrictedToken, NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { fprintf(stderr, _("could not start process for \"%s\": %lu\n"), cmdline2, GetLastError()); *************** *** 1322,1327 **** --- 1515,1521 ---- 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,1374 **** --- 1563,1569 ---- {"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,1466 **** --- 1656,1664 ---- 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"), *************** *** 1520,1528 **** --- 1718,1732 ---- make_directory(buf); /* "make install" */ + #ifndef WIN32_ONLY_COMPILER snprintf(buf, sizeof(buf), SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/log/install.log\"2>&1" SYSTEMQUOTE, makeprog, top_builddir, temp_install, outputdir); + #else + snprintf(buf, sizeof(buf), + SYSTEMQUOTE "perl \"%s/src/tools/msvc/install.pl\" \"%s/install\" >\"%s/log/install.log\" 2>&1" SYSTEMQUOTE, + top_builddir, temp_install, outputdir); + #endif if (system(buf)) { fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was: %s\n"),progname, outputdir, buf); Index: src/test/regress/resultmap =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/resultmap,v retrieving revision 1.83 diff -c -r1.83 resultmap *** src/test/regress/resultmap 3 Aug 2006 17:04:00 -0000 1.83 --- src/test/regress/resultmap 29 Dec 2006 19:51:45 -0000 *************** *** 1,8 **** --- 1,11 ---- float4/i.86-pc-mingw32=float4-exp-three-digits + float4/i.86-pc-win32vc=float4-exp-three-digits float8/i.86-.*-freebsd=float8-small-is-zero float8/i.86-.*-openbsd=float8-small-is-zero float8/i.86-.*-netbsd=float8-small-is-zero float8/m68k-.*-netbsd=float8-small-is-zero float8/i.86-pc-mingw32=float8-exp-three-digits-win32 + float8/i.86-pc-win32vc=float8-exp-three-digits-win32 float8/i.86-pc-cygwin=float8-small-is-zero int8/i.86-pc-mingw32=int8-exp-three-digits + int8/i.86-pc-win32vc=int8-exp-three-digits Index: src/tools/msvc/Solution.pm =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/Solution.pm,v retrieving revision 1.5 diff -c -r1.5 Solution.pm *** src/tools/msvc/Solution.pm 29 Dec 2006 16:49:02 -0000 1.5 --- src/tools/msvc/Solution.pm 1 Jan 2007 14:57:21 -0000 *************** *** 197,213 **** print "Generating pg_config_paths.h...\n"; open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; print O <<EOF; ! #define PGBINDIR "/usr/local/pgsql/bin" ! #define PGSHAREDIR "/usr/local/pgsql/share" ! #define SYSCONFDIR "/usr/local/pgsql/etc" ! #define INCLUDEDIR "/usr/local/pgsql/include" ! #define PKGINCLUDEDIR "/usr/local/pgsql/include" ! #define INCLUDEDIRSERVER "/usr/local/pgsql/include/server" ! #define LIBDIR "/usr/local/pgsql/lib" ! #define PKGLIBDIR "/usr/local/pgsql/lib" ! #define LOCALEDIR "/usr/local/pgsql/share/locale" ! #define DOCDIR "/usr/local/pgsql/doc" ! #define MANDIR "/usr/local/pgsql/man" EOF close(O); } --- 197,213 ---- print "Generating pg_config_paths.h...\n"; open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; print O <<EOF; ! #define PGBINDIR "/bin" ! #define PGSHAREDIR "/share" ! #define SYSCONFDIR "/etc" ! #define INCLUDEDIR "/include" ! #define PKGINCLUDEDIR "/include" ! #define INCLUDEDIRSERVER "/include/server" ! #define LIBDIR "/lib" ! #define PKGLIBDIR "/lib" ! #define LOCALEDIR "/share/locale" ! #define DOCDIR "/doc" ! #define MANDIR "/man" EOF close(O); } Index: src/tools/msvc/install.pl =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/install.pl,v retrieving revision 1.1 diff -c -r1.1 install.pl *** src/tools/msvc/install.pl 29 Nov 2006 19:49:31 -0000 1.1 --- src/tools/msvc/install.pl 1 Jan 2007 14:53:42 -0000 *************** *** 70,78 **** open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; while (<$D>) { chomp; my $tgt = $target . basename($_); print "."; ! copy($_, $tgt) || croak "Could not copy $_\n"; } close($D); print "\n"; --- 70,79 ---- open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; while (<$D>) { chomp; + next if /regress/; # Skip temporary install in regression subdir my $tgt = $target . basename($_); print "."; ! copy($_, $tgt) || croak "Could not copy $_: $!\n"; } close($D); print "\n"; Index: src/tools/msvc/mkvcbuild.pl =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/mkvcbuild.pl,v retrieving revision 1.8 diff -c -r1.8 mkvcbuild.pl *** src/tools/msvc/mkvcbuild.pl 21 Nov 2006 17:54:26 -0000 1.8 --- src/tools/msvc/mkvcbuild.pl 29 Dec 2006 19:50:59 -0000 *************** *** 255,264 **** } ! # Regression DLLs my $regress = $solution->AddProject('regress','dll','misc'); $regress->AddFile('src\test\regress\regress.c'); $regress->AddReference($postgres); $solution->Save(); --- 255,271 ---- } ! # Regression DLL and EXE my $regress = $solution->AddProject('regress','dll','misc'); $regress->AddFile('src\test\regress\regress.c'); $regress->AddReference($postgres); + + my $pgregress = $solution->AddProject('pg_regress','exe','misc'); + $pgregress->AddFile('src\test\regress\pg_regress.c'); + $pgregress->AddIncludeDir('src\port'); + $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); + $pgregress->AddDefine('FRONTEND'); + $pgregress->AddReference($libpgport); $solution->Save();
Would you like this applied? --------------------------------------------------------------------------- Magnus Hagander wrote: > Magnus Hagander wrote: > > Hello! > > > > Per some previous discussion that I can't really recall if it was on or > > off list, here is a WIP patch to make pg_regress run completely outside > > of msys on win32. > > > > The change needed is that the processing of files from input/ and > > output/ into sql/ and expected/ is moved from the Makefile and into > > pg_regress itself. > > > > I have tested on Win32 non-MSVC and on Linux (non-VPATH), and it appears > > to work there. > > > > Still to be done is the "make install" part on MSVC build, currently > > #ifdef:ed out. While working on that, I'd appreciate some comments on > > the patch in general - if there are more things I need to fix before it > > can be considered. Particularly I'm concerned around the VPATH stuff, > > since I've never used that myself. > > > Here's the patch without the WIP tag. It works for me per above, and > also for a "check" (not just "installcheck") on msvc built without msys. > > Again, the vpath part is the one I'm most unsure about, but I'm sure > there could be other parts. > > Hopefully this will make it possible to get the msvc build up on the > buildfarm not too long from now. > > Also, as in the first patch but not noted, this one makes it possible to > run the regression tests as an admin account "the proper way" on both > mingw and msvc. > > //Magnus > Index: src/include/port.h > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/include/port.h,v > retrieving revision 1.107 > diff -c -r1.107 port.h > *** src/include/port.h 5 Jan 2007 22:19:50 -0000 1.107 > --- src/include/port.h 7 Jan 2007 15:11:12 -0000 > *************** > *** 46,51 **** > --- 46,56 ---- > 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 > * > Index: src/port/dirmod.c > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/port/dirmod.c,v > retrieving revision 1.46 > diff -c -r1.46 dirmod.c > *** src/port/dirmod.c 5 Jan 2007 22:20:02 -0000 1.46 > --- src/port/dirmod.c 7 Jan 2007 15:13:27 -0000 > *************** > *** 287,298 **** > > > /* > ! * fnames > * > * return a list of the names of objects in the argument directory > */ > ! static char ** > ! fnames(char *path) > { > DIR *dir; > struct dirent *file; > --- 287,298 ---- > > > /* > ! * pgfnames > * > * return a list of the names of objects in the argument directory > */ > ! char ** > ! pgfnames(char *path) > { > DIR *dir; > struct dirent *file; > *************** > *** 357,368 **** > > > /* > ! * fnames_cleanup > * > * deallocate memory used for filenames > */ > ! static void > ! fnames_cleanup(char **filenames) > { > char **fn; > > --- 357,368 ---- > > > /* > ! * pgfnames_cleanup > * > * deallocate memory used for filenames > */ > ! void > ! pgfnames_cleanup(char **filenames) > { > char **fn; > > *************** > *** 394,400 **** > * we copy all the names out of the directory before we start modifying > * it. > */ > ! filenames = fnames(path); > > if (filenames == NULL) > return false; > --- 394,400 ---- > * we copy all the names out of the directory before we start modifying > * it. > */ > ! filenames = pgfnames(path); > > if (filenames == NULL) > return false; > *************** > *** 415,421 **** > if (!rmtree(filepath, true)) > { > /* we already reported the error */ > ! fnames_cleanup(filenames); > return false; > } > } > --- 415,421 ---- > if (!rmtree(filepath, true)) > { > /* we already reported the error */ > ! pgfnames_cleanup(filenames); > return false; > } > } > *************** > *** 433,439 **** > goto report_and_fail; > } > > ! fnames_cleanup(filenames); > return true; > > report_and_fail: > --- 433,439 ---- > goto report_and_fail; > } > > ! pgfnames_cleanup(filenames); > return true; > > report_and_fail: > *************** > *** 444,449 **** > fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), > filepath, strerror(errno)); > #endif > ! fnames_cleanup(filenames); > return false; > } > --- 444,449 ---- > fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), > filepath, strerror(errno)); > #endif > ! pgfnames_cleanup(filenames); > return false; > } > Index: src/test/regress/GNUmakefile > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/GNUmakefile,v > retrieving revision 1.63 > diff -c -r1.63 GNUmakefile > *** src/test/regress/GNUmakefile 5 Jan 2007 22:20:03 -0000 1.63 > --- src/test/regress/GNUmakefile 7 Jan 2007 15:13:40 -0000 > *************** > *** 40,46 **** > # stuff to pass into build of pg_regress > EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ > '-DMAKEPROG="$(MAKE)"' \ > ! '-DSHELLPROG="$(SHELL)"' > > ## > ## Prepare for tests > --- 40,47 ---- > # stuff to pass into build of pg_regress > EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ > '-DMAKEPROG="$(MAKE)"' \ > ! '-DSHELLPROG="$(SHELL)"' \ > ! '-DDLSUFFIX="$(DLSUFFIX)"' > > ## > ## Prepare for tests > *************** > *** 83,96 **** > 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 > - 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) > --- 84,89 ---- > *************** > *** 99,120 **** > 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 > --- 92,97 ---- > *************** > *** 148,154 **** > 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) > > installcheck: all > -rm -rf ./testtablespace > --- 125,131 ---- > check: all > -rm -rf ./testtablespace > mkdir ./testtablespace > ! ./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 > *************** > *** 168,174 **** > runtest-parallel: installcheck-parallel > > bigtest: > ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --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 > --- 145,151 ---- > runtest-parallel: installcheck-parallel > > bigtest: > ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --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 > Index: src/test/regress/pg_regress.c > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/pg_regress.c,v > retrieving revision 1.25 > diff -c -r1.25 pg_regress.c > *** src/test/regress/pg_regress.c 5 Jan 2007 22:20:03 -0000 1.25 > --- src/test/regress/pg_regress.c 7 Jan 2007 15:13:41 -0000 > *************** > *** 67,73 **** > --- 67,75 ---- > static char *libdir = LIBDIR; > static char *datadir = PGSHAREDIR; > static char *host_platform = HOST_TUPLE; > + #ifndef WIN32_ONLY_COMPILER > static char *makeprog = MAKEPROG; > + #endif > > #ifndef WIN32 /* not used in WIN32 case */ > static char *shellprog = SHELLPROG; > *************** > *** 95,100 **** > --- 97,103 ---- > static char *hostname = NULL; > static int port = -1; > static char *user = NULL; > + static char *srcdir = NULL; > > /* internal variables */ > static const char *progname; > *************** > *** 111,116 **** > --- 114,124 ---- > 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 > *************** > *** 152,157 **** > --- 160,169 ---- > #endif > > > + #ifdef WIN32 > + typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES,DWORD, PSID_AND_ATTRIBUTES, PHANDLE); > + #endif > + > /* > * Add an item at the end of a stringlist. > */ > *************** > *** 331,336 **** > --- 343,468 ---- > } > > /* > + * Replace all occurances of a string in a string with a different stirng. > + * 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 in input/ and output/ into actual files used by the > + * regression tests in sql/ and expected/. > + */ > + static void > + convert_sourcefiles_in(char *source, char *dest, char *suffix) > + { > + char abs_srcdir[MAXPGPATH]; > + char abs_builddir[MAXPGPATH]; > + char testtablespace[MAXPGPATH]; > + char **name; > + char **names = pgfnames(source); > + #ifdef WIN32 > + char *c; > + #endif > + > + if (!names) > + /* Error logged in pgfnames */ > + exit_nicely(2); > + > + if (!getcwd(abs_builddir, sizeof(abs_builddir))) > + { > + fprintf(stderr, _("%s: could not get current directory: %s\n"), > + progname, strerror(errno)); > + exit_nicely(2); > + } > + if (srcdir) > + strcpy(abs_srcdir, srcdir); > + else > + strcpy(abs_srcdir, abs_builddir); > + #ifdef WIN32 > + for (c = abs_builddir; *c; c++) > + if (*c == '\\') > + *c = '/'; > + for (c = abs_srcdir; *c; c++) > + if (*c == '\\') > + *c = '/'; > + #endif > + > + > + snprintf(testtablespace, sizeof(testtablespace), "%s/testtablespace", abs_builddir); > + if (directory_exists(testtablespace)) > + rmtree(testtablespace, true); > + make_directory(testtablespace); > + > + for (name = names; *name; name++) > + { > + char srcfile[MAXPGPATH]; > + char destfile[MAXPGPATH]; > + FILE *infile, *outfile; > + char line[1024]; > + > + if (strlen(*name) < 8) > + continue; > + if (strcmp(*name+strlen(*name)-7,".source")) > + continue; > + > + strcpy(srcfile,source); > + strcat(srcfile, *name); > + strcpy(destfile,dest); > + strncat(destfile, *name, strlen(*name)-6); > + strcat(destfile,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); > + } > + > + 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. > * > * The format of each line of the file is > *************** > *** 593,598 **** > --- 725,731 ---- > printf(_("(using postmaster on Unix socket, default port)\n")); > } > > + convert_sourcefiles(); > load_resultmap(); > } > > *************** > *** 690,705 **** > return pid; > #else > char *cmdline2; > STARTUPINFO si; > PROCESS_INFORMATION pi; > > ZeroMemory(&si, sizeof(si)); > si.cb = sizeof(si); > > cmdline2 = malloc(strlen(cmdline) + 8); > sprintf(cmdline2, "cmd /c %s", cmdline); > > ! if (!CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) > { > fprintf(stderr, _("could not start process for \"%s\": %lu\n"), > cmdline2, GetLastError()); > --- 823,898 ---- > return pid; > #else > char *cmdline2; > + BOOL b; > STARTUPINFO si; > PROCESS_INFORMATION pi; > + HANDLE origToken; > + HANDLE restrictedToken; > + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; > + SID_AND_ATTRIBUTES dropSids[2]; > + __CreateRestrictedToken _CreateRestrictedToken = NULL; > + HANDLE Advapi32Handle; > > ZeroMemory(&si, sizeof(si)); > si.cb = sizeof(si); > > + Advapi32Handle = LoadLibrary("ADVAPI32.DLL"); > + if (Advapi32Handle != NULL) > + { > + _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken"); > + } > + > + if (_CreateRestrictedToken == NULL) > + { > + fprintf(stderr, "WARNING: Unable to create restricted tokens on this platform\n"); > + if (Advapi32Handle != NULL) > + FreeLibrary(Advapi32Handle); > + return 0; > + } > + > + /* Open the current token to use as a base for the restricted one */ > + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken)) > + { > + fprintf(stderr, "Failed to open process token: %lu\n", GetLastError()); > + return 0; > + } > + > + /* Allocate list of SIDs to remove */ > + ZeroMemory(&dropSids, sizeof(dropSids)); > + if (!AllocateAndInitializeSid(&NtAuthority, 2, > + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, > + 0, &dropSids[0].Sid) || > + !AllocateAndInitializeSid(&NtAuthority, 2, > + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, > + 0, &dropSids[1].Sid)) > + { > + fprintf(stderr, "Failed to allocate SIDs: %lu\n", GetLastError()); > + return 0; > + } > + > + b = _CreateRestrictedToken(origToken, > + DISABLE_MAX_PRIVILEGE, > + sizeof(dropSids) / sizeof(dropSids[0]), > + dropSids, > + 0, NULL, > + 0, NULL, > + &restrictedToken); > + > + FreeSid(dropSids[1].Sid); > + FreeSid(dropSids[0].Sid); > + CloseHandle(origToken); > + FreeLibrary(Advapi32Handle); > + > + if (!b) > + { > + fprintf(stderr, "Failed to create restricted token: %lu\n", GetLastError()); > + return 0; > + } > + > cmdline2 = malloc(strlen(cmdline) + 8); > sprintf(cmdline2, "cmd /c %s", cmdline); > > ! if (!CreateProcessAsUser(restrictedToken, NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) > { > fprintf(stderr, _("could not start process for \"%s\": %lu\n"), > cmdline2, GetLastError()); > *************** > *** 1322,1327 **** > --- 1515,1521 ---- > 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,1374 **** > --- 1563,1569 ---- > {"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,1466 **** > --- 1656,1664 ---- > 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"), > *************** > *** 1520,1528 **** > --- 1718,1732 ---- > make_directory(buf); > > /* "make install" */ > + #ifndef WIN32_ONLY_COMPILER > snprintf(buf, sizeof(buf), > SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/log/install.log\"2>&1" SYSTEMQUOTE, > makeprog, top_builddir, temp_install, outputdir); > + #else > + snprintf(buf, sizeof(buf), > + SYSTEMQUOTE "perl \"%s/src/tools/msvc/install.pl\" \"%s/install\" >\"%s/log/install.log\" 2>&1" SYSTEMQUOTE, > + top_builddir, temp_install, outputdir); > + #endif > if (system(buf)) > { > fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was: %s\n"),progname, outputdir, buf); > Index: src/test/regress/resultmap > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/resultmap,v > retrieving revision 1.83 > diff -c -r1.83 resultmap > *** src/test/regress/resultmap 3 Aug 2006 17:04:00 -0000 1.83 > --- src/test/regress/resultmap 29 Dec 2006 19:51:45 -0000 > *************** > *** 1,8 **** > --- 1,11 ---- > float4/i.86-pc-mingw32=float4-exp-three-digits > + float4/i.86-pc-win32vc=float4-exp-three-digits > float8/i.86-.*-freebsd=float8-small-is-zero > float8/i.86-.*-openbsd=float8-small-is-zero > float8/i.86-.*-netbsd=float8-small-is-zero > float8/m68k-.*-netbsd=float8-small-is-zero > float8/i.86-pc-mingw32=float8-exp-three-digits-win32 > + float8/i.86-pc-win32vc=float8-exp-three-digits-win32 > float8/i.86-pc-cygwin=float8-small-is-zero > int8/i.86-pc-mingw32=int8-exp-three-digits > + int8/i.86-pc-win32vc=int8-exp-three-digits > Index: src/tools/msvc/Solution.pm > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/Solution.pm,v > retrieving revision 1.5 > diff -c -r1.5 Solution.pm > *** src/tools/msvc/Solution.pm 29 Dec 2006 16:49:02 -0000 1.5 > --- src/tools/msvc/Solution.pm 1 Jan 2007 14:57:21 -0000 > *************** > *** 197,213 **** > print "Generating pg_config_paths.h...\n"; > open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; > print O <<EOF; > ! #define PGBINDIR "/usr/local/pgsql/bin" > ! #define PGSHAREDIR "/usr/local/pgsql/share" > ! #define SYSCONFDIR "/usr/local/pgsql/etc" > ! #define INCLUDEDIR "/usr/local/pgsql/include" > ! #define PKGINCLUDEDIR "/usr/local/pgsql/include" > ! #define INCLUDEDIRSERVER "/usr/local/pgsql/include/server" > ! #define LIBDIR "/usr/local/pgsql/lib" > ! #define PKGLIBDIR "/usr/local/pgsql/lib" > ! #define LOCALEDIR "/usr/local/pgsql/share/locale" > ! #define DOCDIR "/usr/local/pgsql/doc" > ! #define MANDIR "/usr/local/pgsql/man" > EOF > close(O); > } > --- 197,213 ---- > print "Generating pg_config_paths.h...\n"; > open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; > print O <<EOF; > ! #define PGBINDIR "/bin" > ! #define PGSHAREDIR "/share" > ! #define SYSCONFDIR "/etc" > ! #define INCLUDEDIR "/include" > ! #define PKGINCLUDEDIR "/include" > ! #define INCLUDEDIRSERVER "/include/server" > ! #define LIBDIR "/lib" > ! #define PKGLIBDIR "/lib" > ! #define LOCALEDIR "/share/locale" > ! #define DOCDIR "/doc" > ! #define MANDIR "/man" > EOF > close(O); > } > Index: src/tools/msvc/install.pl > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/install.pl,v > retrieving revision 1.1 > diff -c -r1.1 install.pl > *** src/tools/msvc/install.pl 29 Nov 2006 19:49:31 -0000 1.1 > --- src/tools/msvc/install.pl 1 Jan 2007 14:53:42 -0000 > *************** > *** 70,78 **** > open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; > while (<$D>) { > chomp; > my $tgt = $target . basename($_); > print "."; > ! copy($_, $tgt) || croak "Could not copy $_\n"; > } > close($D); > print "\n"; > --- 70,79 ---- > open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; > while (<$D>) { > chomp; > + next if /regress/; # Skip temporary install in regression subdir > my $tgt = $target . basename($_); > print "."; > ! copy($_, $tgt) || croak "Could not copy $_: $!\n"; > } > close($D); > print "\n"; > Index: src/tools/msvc/mkvcbuild.pl > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/mkvcbuild.pl,v > retrieving revision 1.8 > diff -c -r1.8 mkvcbuild.pl > *** src/tools/msvc/mkvcbuild.pl 21 Nov 2006 17:54:26 -0000 1.8 > --- src/tools/msvc/mkvcbuild.pl 29 Dec 2006 19:50:59 -0000 > *************** > *** 255,264 **** > } > > > ! # Regression DLLs > my $regress = $solution->AddProject('regress','dll','misc'); > $regress->AddFile('src\test\regress\regress.c'); > $regress->AddReference($postgres); > > $solution->Save(); > > --- 255,271 ---- > } > > > ! # Regression DLL and EXE > my $regress = $solution->AddProject('regress','dll','misc'); > $regress->AddFile('src\test\regress\regress.c'); > $regress->AddReference($postgres); > + > + my $pgregress = $solution->AddProject('pg_regress','exe','misc'); > + $pgregress->AddFile('src\test\regress\pg_regress.c'); > + $pgregress->AddIncludeDir('src\port'); > + $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); > + $pgregress->AddDefine('FRONTEND'); > + $pgregress->AddReference($libpgport); > > $solution->Save(); > > > ---------------------------(end of broadcast)--------------------------- > TIP 3: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faq -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
Yes, please. Provided there are no objections and that it looks ok, of course ;-) //Magnus On Tue, Jan 09, 2007 at 05:22:20PM -0500, Bruce Momjian wrote: > > Would you like this applied? > > --------------------------------------------------------------------------- > > Magnus Hagander wrote: > > Magnus Hagander wrote: > > > Hello! > > > > > > Per some previous discussion that I can't really recall if it was on or > > > off list, here is a WIP patch to make pg_regress run completely outside > > > of msys on win32. > > > > > > The change needed is that the processing of files from input/ and > > > output/ into sql/ and expected/ is moved from the Makefile and into > > > pg_regress itself. > > > > > > I have tested on Win32 non-MSVC and on Linux (non-VPATH), and it appears > > > to work there. > > > > > > Still to be done is the "make install" part on MSVC build, currently > > > #ifdef:ed out. While working on that, I'd appreciate some comments on > > > the patch in general - if there are more things I need to fix before it > > > can be considered. Particularly I'm concerned around the VPATH stuff, > > > since I've never used that myself. > > > > > > Here's the patch without the WIP tag. It works for me per above, and > > also for a "check" (not just "installcheck") on msvc built without msys. > > > > Again, the vpath part is the one I'm most unsure about, but I'm sure > > there could be other parts. > > > > Hopefully this will make it possible to get the msvc build up on the > > buildfarm not too long from now. > > > > Also, as in the first patch but not noted, this one makes it possible to > > run the regression tests as an admin account "the proper way" on both > > mingw and msvc. > > > > //Magnus >
A modified version of this was applied by Alvaro. --------------------------------------------------------------------------- Magnus Hagander wrote: > Magnus Hagander wrote: > > Hello! > > > > Per some previous discussion that I can't really recall if it was on or > > off list, here is a WIP patch to make pg_regress run completely outside > > of msys on win32. > > > > The change needed is that the processing of files from input/ and > > output/ into sql/ and expected/ is moved from the Makefile and into > > pg_regress itself. > > > > I have tested on Win32 non-MSVC and on Linux (non-VPATH), and it appears > > to work there. > > > > Still to be done is the "make install" part on MSVC build, currently > > #ifdef:ed out. While working on that, I'd appreciate some comments on > > the patch in general - if there are more things I need to fix before it > > can be considered. Particularly I'm concerned around the VPATH stuff, > > since I've never used that myself. > > > Here's the patch without the WIP tag. It works for me per above, and > also for a "check" (not just "installcheck") on msvc built without msys. > > Again, the vpath part is the one I'm most unsure about, but I'm sure > there could be other parts. > > Hopefully this will make it possible to get the msvc build up on the > buildfarm not too long from now. > > Also, as in the first patch but not noted, this one makes it possible to > run the regression tests as an admin account "the proper way" on both > mingw and msvc. > > //Magnus > Index: src/include/port.h > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/include/port.h,v > retrieving revision 1.107 > diff -c -r1.107 port.h > *** src/include/port.h 5 Jan 2007 22:19:50 -0000 1.107 > --- src/include/port.h 7 Jan 2007 15:11:12 -0000 > *************** > *** 46,51 **** > --- 46,56 ---- > 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 > * > Index: src/port/dirmod.c > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/port/dirmod.c,v > retrieving revision 1.46 > diff -c -r1.46 dirmod.c > *** src/port/dirmod.c 5 Jan 2007 22:20:02 -0000 1.46 > --- src/port/dirmod.c 7 Jan 2007 15:13:27 -0000 > *************** > *** 287,298 **** > > > /* > ! * fnames > * > * return a list of the names of objects in the argument directory > */ > ! static char ** > ! fnames(char *path) > { > DIR *dir; > struct dirent *file; > --- 287,298 ---- > > > /* > ! * pgfnames > * > * return a list of the names of objects in the argument directory > */ > ! char ** > ! pgfnames(char *path) > { > DIR *dir; > struct dirent *file; > *************** > *** 357,368 **** > > > /* > ! * fnames_cleanup > * > * deallocate memory used for filenames > */ > ! static void > ! fnames_cleanup(char **filenames) > { > char **fn; > > --- 357,368 ---- > > > /* > ! * pgfnames_cleanup > * > * deallocate memory used for filenames > */ > ! void > ! pgfnames_cleanup(char **filenames) > { > char **fn; > > *************** > *** 394,400 **** > * we copy all the names out of the directory before we start modifying > * it. > */ > ! filenames = fnames(path); > > if (filenames == NULL) > return false; > --- 394,400 ---- > * we copy all the names out of the directory before we start modifying > * it. > */ > ! filenames = pgfnames(path); > > if (filenames == NULL) > return false; > *************** > *** 415,421 **** > if (!rmtree(filepath, true)) > { > /* we already reported the error */ > ! fnames_cleanup(filenames); > return false; > } > } > --- 415,421 ---- > if (!rmtree(filepath, true)) > { > /* we already reported the error */ > ! pgfnames_cleanup(filenames); > return false; > } > } > *************** > *** 433,439 **** > goto report_and_fail; > } > > ! fnames_cleanup(filenames); > return true; > > report_and_fail: > --- 433,439 ---- > goto report_and_fail; > } > > ! pgfnames_cleanup(filenames); > return true; > > report_and_fail: > *************** > *** 444,449 **** > fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), > filepath, strerror(errno)); > #endif > ! fnames_cleanup(filenames); > return false; > } > --- 444,449 ---- > fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), > filepath, strerror(errno)); > #endif > ! pgfnames_cleanup(filenames); > return false; > } > Index: src/test/regress/GNUmakefile > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/GNUmakefile,v > retrieving revision 1.63 > diff -c -r1.63 GNUmakefile > *** src/test/regress/GNUmakefile 5 Jan 2007 22:20:03 -0000 1.63 > --- src/test/regress/GNUmakefile 7 Jan 2007 15:13:40 -0000 > *************** > *** 40,46 **** > # stuff to pass into build of pg_regress > EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ > '-DMAKEPROG="$(MAKE)"' \ > ! '-DSHELLPROG="$(SHELL)"' > > ## > ## Prepare for tests > --- 40,47 ---- > # stuff to pass into build of pg_regress > EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ > '-DMAKEPROG="$(MAKE)"' \ > ! '-DSHELLPROG="$(SHELL)"' \ > ! '-DDLSUFFIX="$(DLSUFFIX)"' > > ## > ## Prepare for tests > *************** > *** 83,96 **** > 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 > - 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) > --- 84,89 ---- > *************** > *** 99,120 **** > 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 > --- 92,97 ---- > *************** > *** 148,154 **** > 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) > > installcheck: all > -rm -rf ./testtablespace > --- 125,131 ---- > check: all > -rm -rf ./testtablespace > mkdir ./testtablespace > ! ./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 > *************** > *** 168,174 **** > runtest-parallel: installcheck-parallel > > bigtest: > ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --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 > --- 145,151 ---- > runtest-parallel: installcheck-parallel > > bigtest: > ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --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 > Index: src/test/regress/pg_regress.c > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/pg_regress.c,v > retrieving revision 1.25 > diff -c -r1.25 pg_regress.c > *** src/test/regress/pg_regress.c 5 Jan 2007 22:20:03 -0000 1.25 > --- src/test/regress/pg_regress.c 7 Jan 2007 15:13:41 -0000 > *************** > *** 67,73 **** > --- 67,75 ---- > static char *libdir = LIBDIR; > static char *datadir = PGSHAREDIR; > static char *host_platform = HOST_TUPLE; > + #ifndef WIN32_ONLY_COMPILER > static char *makeprog = MAKEPROG; > + #endif > > #ifndef WIN32 /* not used in WIN32 case */ > static char *shellprog = SHELLPROG; > *************** > *** 95,100 **** > --- 97,103 ---- > static char *hostname = NULL; > static int port = -1; > static char *user = NULL; > + static char *srcdir = NULL; > > /* internal variables */ > static const char *progname; > *************** > *** 111,116 **** > --- 114,124 ---- > 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 > *************** > *** 152,157 **** > --- 160,169 ---- > #endif > > > + #ifdef WIN32 > + typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES,DWORD, PSID_AND_ATTRIBUTES, PHANDLE); > + #endif > + > /* > * Add an item at the end of a stringlist. > */ > *************** > *** 331,336 **** > --- 343,468 ---- > } > > /* > + * Replace all occurances of a string in a string with a different stirng. > + * 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 in input/ and output/ into actual files used by the > + * regression tests in sql/ and expected/. > + */ > + static void > + convert_sourcefiles_in(char *source, char *dest, char *suffix) > + { > + char abs_srcdir[MAXPGPATH]; > + char abs_builddir[MAXPGPATH]; > + char testtablespace[MAXPGPATH]; > + char **name; > + char **names = pgfnames(source); > + #ifdef WIN32 > + char *c; > + #endif > + > + if (!names) > + /* Error logged in pgfnames */ > + exit_nicely(2); > + > + if (!getcwd(abs_builddir, sizeof(abs_builddir))) > + { > + fprintf(stderr, _("%s: could not get current directory: %s\n"), > + progname, strerror(errno)); > + exit_nicely(2); > + } > + if (srcdir) > + strcpy(abs_srcdir, srcdir); > + else > + strcpy(abs_srcdir, abs_builddir); > + #ifdef WIN32 > + for (c = abs_builddir; *c; c++) > + if (*c == '\\') > + *c = '/'; > + for (c = abs_srcdir; *c; c++) > + if (*c == '\\') > + *c = '/'; > + #endif > + > + > + snprintf(testtablespace, sizeof(testtablespace), "%s/testtablespace", abs_builddir); > + if (directory_exists(testtablespace)) > + rmtree(testtablespace, true); > + make_directory(testtablespace); > + > + for (name = names; *name; name++) > + { > + char srcfile[MAXPGPATH]; > + char destfile[MAXPGPATH]; > + FILE *infile, *outfile; > + char line[1024]; > + > + if (strlen(*name) < 8) > + continue; > + if (strcmp(*name+strlen(*name)-7,".source")) > + continue; > + > + strcpy(srcfile,source); > + strcat(srcfile, *name); > + strcpy(destfile,dest); > + strncat(destfile, *name, strlen(*name)-6); > + strcat(destfile,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); > + } > + > + 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. > * > * The format of each line of the file is > *************** > *** 593,598 **** > --- 725,731 ---- > printf(_("(using postmaster on Unix socket, default port)\n")); > } > > + convert_sourcefiles(); > load_resultmap(); > } > > *************** > *** 690,705 **** > return pid; > #else > char *cmdline2; > STARTUPINFO si; > PROCESS_INFORMATION pi; > > ZeroMemory(&si, sizeof(si)); > si.cb = sizeof(si); > > cmdline2 = malloc(strlen(cmdline) + 8); > sprintf(cmdline2, "cmd /c %s", cmdline); > > ! if (!CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) > { > fprintf(stderr, _("could not start process for \"%s\": %lu\n"), > cmdline2, GetLastError()); > --- 823,898 ---- > return pid; > #else > char *cmdline2; > + BOOL b; > STARTUPINFO si; > PROCESS_INFORMATION pi; > + HANDLE origToken; > + HANDLE restrictedToken; > + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; > + SID_AND_ATTRIBUTES dropSids[2]; > + __CreateRestrictedToken _CreateRestrictedToken = NULL; > + HANDLE Advapi32Handle; > > ZeroMemory(&si, sizeof(si)); > si.cb = sizeof(si); > > + Advapi32Handle = LoadLibrary("ADVAPI32.DLL"); > + if (Advapi32Handle != NULL) > + { > + _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken"); > + } > + > + if (_CreateRestrictedToken == NULL) > + { > + fprintf(stderr, "WARNING: Unable to create restricted tokens on this platform\n"); > + if (Advapi32Handle != NULL) > + FreeLibrary(Advapi32Handle); > + return 0; > + } > + > + /* Open the current token to use as a base for the restricted one */ > + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken)) > + { > + fprintf(stderr, "Failed to open process token: %lu\n", GetLastError()); > + return 0; > + } > + > + /* Allocate list of SIDs to remove */ > + ZeroMemory(&dropSids, sizeof(dropSids)); > + if (!AllocateAndInitializeSid(&NtAuthority, 2, > + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, > + 0, &dropSids[0].Sid) || > + !AllocateAndInitializeSid(&NtAuthority, 2, > + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, > + 0, &dropSids[1].Sid)) > + { > + fprintf(stderr, "Failed to allocate SIDs: %lu\n", GetLastError()); > + return 0; > + } > + > + b = _CreateRestrictedToken(origToken, > + DISABLE_MAX_PRIVILEGE, > + sizeof(dropSids) / sizeof(dropSids[0]), > + dropSids, > + 0, NULL, > + 0, NULL, > + &restrictedToken); > + > + FreeSid(dropSids[1].Sid); > + FreeSid(dropSids[0].Sid); > + CloseHandle(origToken); > + FreeLibrary(Advapi32Handle); > + > + if (!b) > + { > + fprintf(stderr, "Failed to create restricted token: %lu\n", GetLastError()); > + return 0; > + } > + > cmdline2 = malloc(strlen(cmdline) + 8); > sprintf(cmdline2, "cmd /c %s", cmdline); > > ! if (!CreateProcessAsUser(restrictedToken, NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) > { > fprintf(stderr, _("could not start process for \"%s\": %lu\n"), > cmdline2, GetLastError()); > *************** > *** 1322,1327 **** > --- 1515,1521 ---- > 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,1374 **** > --- 1563,1569 ---- > {"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,1466 **** > --- 1656,1664 ---- > 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"), > *************** > *** 1520,1528 **** > --- 1718,1732 ---- > make_directory(buf); > > /* "make install" */ > + #ifndef WIN32_ONLY_COMPILER > snprintf(buf, sizeof(buf), > SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/log/install.log\"2>&1" SYSTEMQUOTE, > makeprog, top_builddir, temp_install, outputdir); > + #else > + snprintf(buf, sizeof(buf), > + SYSTEMQUOTE "perl \"%s/src/tools/msvc/install.pl\" \"%s/install\" >\"%s/log/install.log\" 2>&1" SYSTEMQUOTE, > + top_builddir, temp_install, outputdir); > + #endif > if (system(buf)) > { > fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was: %s\n"),progname, outputdir, buf); > Index: src/test/regress/resultmap > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/resultmap,v > retrieving revision 1.83 > diff -c -r1.83 resultmap > *** src/test/regress/resultmap 3 Aug 2006 17:04:00 -0000 1.83 > --- src/test/regress/resultmap 29 Dec 2006 19:51:45 -0000 > *************** > *** 1,8 **** > --- 1,11 ---- > float4/i.86-pc-mingw32=float4-exp-three-digits > + float4/i.86-pc-win32vc=float4-exp-three-digits > float8/i.86-.*-freebsd=float8-small-is-zero > float8/i.86-.*-openbsd=float8-small-is-zero > float8/i.86-.*-netbsd=float8-small-is-zero > float8/m68k-.*-netbsd=float8-small-is-zero > float8/i.86-pc-mingw32=float8-exp-three-digits-win32 > + float8/i.86-pc-win32vc=float8-exp-three-digits-win32 > float8/i.86-pc-cygwin=float8-small-is-zero > int8/i.86-pc-mingw32=int8-exp-three-digits > + int8/i.86-pc-win32vc=int8-exp-three-digits > Index: src/tools/msvc/Solution.pm > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/Solution.pm,v > retrieving revision 1.5 > diff -c -r1.5 Solution.pm > *** src/tools/msvc/Solution.pm 29 Dec 2006 16:49:02 -0000 1.5 > --- src/tools/msvc/Solution.pm 1 Jan 2007 14:57:21 -0000 > *************** > *** 197,213 **** > print "Generating pg_config_paths.h...\n"; > open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; > print O <<EOF; > ! #define PGBINDIR "/usr/local/pgsql/bin" > ! #define PGSHAREDIR "/usr/local/pgsql/share" > ! #define SYSCONFDIR "/usr/local/pgsql/etc" > ! #define INCLUDEDIR "/usr/local/pgsql/include" > ! #define PKGINCLUDEDIR "/usr/local/pgsql/include" > ! #define INCLUDEDIRSERVER "/usr/local/pgsql/include/server" > ! #define LIBDIR "/usr/local/pgsql/lib" > ! #define PKGLIBDIR "/usr/local/pgsql/lib" > ! #define LOCALEDIR "/usr/local/pgsql/share/locale" > ! #define DOCDIR "/usr/local/pgsql/doc" > ! #define MANDIR "/usr/local/pgsql/man" > EOF > close(O); > } > --- 197,213 ---- > print "Generating pg_config_paths.h...\n"; > open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; > print O <<EOF; > ! #define PGBINDIR "/bin" > ! #define PGSHAREDIR "/share" > ! #define SYSCONFDIR "/etc" > ! #define INCLUDEDIR "/include" > ! #define PKGINCLUDEDIR "/include" > ! #define INCLUDEDIRSERVER "/include/server" > ! #define LIBDIR "/lib" > ! #define PKGLIBDIR "/lib" > ! #define LOCALEDIR "/share/locale" > ! #define DOCDIR "/doc" > ! #define MANDIR "/man" > EOF > close(O); > } > Index: src/tools/msvc/install.pl > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/install.pl,v > retrieving revision 1.1 > diff -c -r1.1 install.pl > *** src/tools/msvc/install.pl 29 Nov 2006 19:49:31 -0000 1.1 > --- src/tools/msvc/install.pl 1 Jan 2007 14:53:42 -0000 > *************** > *** 70,78 **** > open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; > while (<$D>) { > chomp; > my $tgt = $target . basename($_); > print "."; > ! copy($_, $tgt) || croak "Could not copy $_\n"; > } > close($D); > print "\n"; > --- 70,79 ---- > open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; > while (<$D>) { > chomp; > + next if /regress/; # Skip temporary install in regression subdir > my $tgt = $target . basename($_); > print "."; > ! copy($_, $tgt) || croak "Could not copy $_: $!\n"; > } > close($D); > print "\n"; > Index: src/tools/msvc/mkvcbuild.pl > =================================================================== > RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/mkvcbuild.pl,v > retrieving revision 1.8 > diff -c -r1.8 mkvcbuild.pl > *** src/tools/msvc/mkvcbuild.pl 21 Nov 2006 17:54:26 -0000 1.8 > --- src/tools/msvc/mkvcbuild.pl 29 Dec 2006 19:50:59 -0000 > *************** > *** 255,264 **** > } > > > ! # Regression DLLs > my $regress = $solution->AddProject('regress','dll','misc'); > $regress->AddFile('src\test\regress\regress.c'); > $regress->AddReference($postgres); > > $solution->Save(); > > --- 255,271 ---- > } > > > ! # Regression DLL and EXE > my $regress = $solution->AddProject('regress','dll','misc'); > $regress->AddFile('src\test\regress\regress.c'); > $regress->AddReference($postgres); > + > + my $pgregress = $solution->AddProject('pg_regress','exe','misc'); > + $pgregress->AddFile('src\test\regress\pg_regress.c'); > + $pgregress->AddIncludeDir('src\port'); > + $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); > + $pgregress->AddDefine('FRONTEND'); > + $pgregress->AddReference($libpgport); > > $solution->Save(); > > > ---------------------------(end of broadcast)--------------------------- > TIP 3: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faq -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
Bruce Momjian wrote: > > A modified version of this was applied by Alvaro. But note that the patch I applied was only the part of this that was not Windows-specific. The rest is still needed to be able to use VC++ builds as buildfarm members. I'm not in a position to build that however, but it should be considerably thinner than what was in the queue. -- Alvaro Herrera http://www.CommandPrompt.com/ The PostgreSQL Company - Command Prompt, Inc.
Alvaro Herrera wrote: > Bruce Momjian wrote: >> A modified version of this was applied by Alvaro. > > But note that the patch I applied was only the part of this that was not > Windows-specific. The rest is still needed to be able to use VC++ > builds as buildfarm members. I'm not in a position to build that > however, but it should be considerably thinner than what was in the > queue. > Right. Thanks for what you did apply. I will pull that one from cvs and send an updated patch with just the win32 stuff. //Magnus