Header And Logo

PostgreSQL
| The world's most advanced open source database.

pg_regress_ecpg.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * pg_regress_ecpg --- regression test driver for ecpg
00004  *
00005  * This is a C implementation of the previous shell script for running
00006  * the regression tests, and should be mostly compatible with it.
00007  * Initial author of C translation: Magnus Hagander
00008  *
00009  * This code is released under the terms of the PostgreSQL License.
00010  *
00011  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00012  * Portions Copyright (c) 1994, Regents of the University of California
00013  *
00014  * src/interfaces/ecpg/test/pg_regress_ecpg.c
00015  *
00016  *-------------------------------------------------------------------------
00017  */
00018 
00019 #include "pg_regress.h"
00020 
00021 #define LINEBUFSIZE 300
00022 static void
00023 ecpg_filter(const char *sourcefile, const char *outfile)
00024 {
00025     /*
00026      * Create a filtered copy of sourcefile, replacing #line x
00027      * "./../bla/foo.h" with #line x "foo.h"
00028      */
00029     FILE       *s,
00030                *t;
00031     char        linebuf[LINEBUFSIZE];
00032 
00033     s = fopen(sourcefile, "r");
00034     if (!s)
00035     {
00036         fprintf(stderr, "Could not open file %s for reading\n", sourcefile);
00037         exit(2);
00038     }
00039     t = fopen(outfile, "w");
00040     if (!t)
00041     {
00042         fprintf(stderr, "Could not open file %s for writing\n", outfile);
00043         exit(2);
00044     }
00045 
00046     while (fgets(linebuf, LINEBUFSIZE, s))
00047     {
00048         /* check for "#line " in the beginning */
00049         if (strstr(linebuf, "#line ") == linebuf)
00050         {
00051             char       *p = strchr(linebuf, '"');
00052             char       *n;
00053             int         plen = 1;
00054 
00055             while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL))
00056             {
00057                 plen++;
00058             }
00059             /* plen is one more than the number of . and / characters */
00060             if (plen > 1)
00061             {
00062                 n = (char *) malloc(plen);
00063                 strncpy(n, p + 1, plen - 1);
00064                 n[plen - 1] = '\0';
00065                 replace_string(linebuf, n, "");
00066             }
00067         }
00068         fputs(linebuf, t);
00069     }
00070     fclose(s);
00071     fclose(t);
00072 }
00073 
00074 /*
00075  * start an ecpg test process for specified file (including redirection),
00076  * and return process ID
00077  */
00078 
00079 static PID_TYPE
00080 ecpg_start_test(const char *testname,
00081                 _stringlist ** resultfiles,
00082                 _stringlist ** expectfiles,
00083                 _stringlist ** tags)
00084 {
00085     PID_TYPE    pid;
00086     char        inprg[MAXPGPATH];
00087     char        insource[MAXPGPATH];
00088     char       *outfile_stdout,
00089                 expectfile_stdout[MAXPGPATH];
00090     char       *outfile_stderr,
00091                 expectfile_stderr[MAXPGPATH];
00092     char       *outfile_source,
00093                 expectfile_source[MAXPGPATH];
00094     char        cmd[MAXPGPATH * 3];
00095     char       *testname_dash;
00096 
00097     snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
00098 
00099     testname_dash = strdup(testname);
00100     replace_string(testname_dash, "/", "-");
00101     snprintf(expectfile_stdout, sizeof(expectfile_stdout),
00102              "%s/expected/%s.stdout",
00103              outputdir, testname_dash);
00104     snprintf(expectfile_stderr, sizeof(expectfile_stderr),
00105              "%s/expected/%s.stderr",
00106              outputdir, testname_dash);
00107     snprintf(expectfile_source, sizeof(expectfile_source),
00108              "%s/expected/%s.c",
00109              outputdir, testname_dash);
00110 
00111     /*
00112      * We can use replace_string() here because the replacement string does
00113      * not occupy more space than the replaced one.
00114      */
00115     outfile_stdout = strdup(expectfile_stdout);
00116     replace_string(outfile_stdout, "/expected/", "/results/");
00117     outfile_stderr = strdup(expectfile_stderr);
00118     replace_string(outfile_stderr, "/expected/", "/results/");
00119     outfile_source = strdup(expectfile_source);
00120     replace_string(outfile_source, "/expected/", "/results/");
00121 
00122     add_stringlist_item(resultfiles, outfile_stdout);
00123     add_stringlist_item(expectfiles, expectfile_stdout);
00124     add_stringlist_item(tags, "stdout");
00125 
00126     add_stringlist_item(resultfiles, outfile_stderr);
00127     add_stringlist_item(expectfiles, expectfile_stderr);
00128     add_stringlist_item(tags, "stderr");
00129 
00130     add_stringlist_item(resultfiles, outfile_source);
00131     add_stringlist_item(expectfiles, expectfile_source);
00132     add_stringlist_item(tags, "source");
00133 
00134     snprintf(insource, sizeof(insource), "%s.c", testname);
00135     ecpg_filter(insource, outfile_source);
00136 
00137     snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
00138 
00139     snprintf(cmd, sizeof(cmd),
00140              SYSTEMQUOTE "\"%s\" >\"%s\" 2>\"%s\"" SYSTEMQUOTE,
00141              inprg,
00142              outfile_stdout,
00143              outfile_stderr);
00144 
00145     pid = spawn_process(cmd);
00146 
00147     if (pid == INVALID_PID)
00148     {
00149         fprintf(stderr, _("could not start process for test %s\n"),
00150                 testname);
00151         exit(2);
00152     }
00153 
00154     free(outfile_stdout);
00155     free(outfile_stderr);
00156     free(outfile_source);
00157 
00158     return pid;
00159 }
00160 
00161 static void
00162 ecpg_init(void)
00163 {
00164     /* nothing to do here at the moment */
00165 }
00166 
00167 int
00168 main(int argc, char *argv[])
00169 {
00170     return regression_main(argc, argv, ecpg_init, ecpg_start_test);
00171 }