/*------------------------------------------------------------------------- * * pg_regress_ecpg --- regression test driver for ecpg * * This is a C implementation of the previous shell script for running * the regression tests, and should be mostly compatible with it. * Initial author of C translation: Magnus Hagander * * This code is released under the terms of the PostgreSQL License. * * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/interfaces/ecpg/test/pg_regress_ecpg.c * *------------------------------------------------------------------------- */ #include "pg_regress.h" #define LINEBUFSIZE 300 static void ecpg_filter(const char *sourcefile, const char *outfile) { /* * Create a filtered copy of sourcefile, replacing #line x * "./../bla/foo.h" with #line x "foo.h" */ FILE *s, *t; char linebuf[LINEBUFSIZE]; s = fopen(sourcefile, "r"); if (!s) { fprintf(stderr, "Could not open file %s for reading\n", sourcefile); exit(2); } t = fopen(outfile, "w"); if (!t) { fprintf(stderr, "Could not open file %s for writing\n", outfile); exit(2); } while (fgets(linebuf, LINEBUFSIZE, s)) { /* check for "#line " in the beginning */ if (strstr(linebuf, "#line ") == linebuf) { char *p = strchr(linebuf, '"'); char *n; int plen = 1; while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL)) { plen++; } /* plen is one more than the number of . and / characters */ if (plen > 1) { n = (char *) malloc(plen); StrNCpy(n, p + 1, plen); replace_string(linebuf, n, ""); } } fputs(linebuf, t); } fclose(s); fclose(t); } /* * start an ecpg test process for specified file (including redirection), * and return process ID */ static PID_TYPE ecpg_start_test(const char *testname, _stringlist **resultfiles, _stringlist **expectfiles, _stringlist **tags) { PID_TYPE pid; char inprg[MAXPGPATH]; char insource[MAXPGPATH]; char *outfile_stdout, expectfile_stdout[MAXPGPATH]; char *outfile_stderr, expectfile_stderr[MAXPGPATH]; char *outfile_source, expectfile_source[MAXPGPATH]; char cmd[MAXPGPATH * 3]; char *testname_dash; snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname); testname_dash = strdup(testname); replace_string(testname_dash, "/", "-"); snprintf(expectfile_stdout, sizeof(expectfile_stdout), "%s/expected/%s.stdout", outputdir, testname_dash); snprintf(expectfile_stderr, sizeof(expectfile_stderr), "%s/expected/%s.stderr", outputdir, testname_dash); snprintf(expectfile_source, sizeof(expectfile_source), "%s/expected/%s.c", outputdir, testname_dash); /* * We can use replace_string() here because the replacement string does * not occupy more space than the replaced one. */ outfile_stdout = strdup(expectfile_stdout); replace_string(outfile_stdout, "/expected/", "/results/"); outfile_stderr = strdup(expectfile_stderr); replace_string(outfile_stderr, "/expected/", "/results/"); outfile_source = strdup(expectfile_source); replace_string(outfile_source, "/expected/", "/results/"); add_stringlist_item(resultfiles, outfile_stdout); add_stringlist_item(expectfiles, expectfile_stdout); add_stringlist_item(tags, "stdout"); add_stringlist_item(resultfiles, outfile_stderr); add_stringlist_item(expectfiles, expectfile_stderr); add_stringlist_item(tags, "stderr"); add_stringlist_item(resultfiles, outfile_source); add_stringlist_item(expectfiles, expectfile_source); add_stringlist_item(tags, "source"); snprintf(insource, sizeof(insource), "%s.c", testname); ecpg_filter(insource, outfile_source); snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname); snprintf(cmd, sizeof(cmd), "\"%s\" >\"%s\" 2>\"%s\"", inprg, outfile_stdout, outfile_stderr); pid = spawn_process(cmd); if (pid == INVALID_PID) { fprintf(stderr, _("could not start process for test %s\n"), testname); exit(2); } free(outfile_stdout); free(outfile_stderr); free(outfile_source); return pid; } static void ecpg_init(int argc, char *argv[]) { /* nothing to do here at the moment */ } int main(int argc, char *argv[]) { return regression_main(argc, argv, ecpg_init, ecpg_start_test); }