1 /*-------------------------------------------------------------------------
2 *
3 * pg_regress_ecpg --- regression test driver for ecpg
4 *
5 * This is a C implementation of the previous shell script for running
6 * the regression tests, and should be mostly compatible with it.
7 * Initial author of C translation: Magnus Hagander
8 *
9 * This code is released under the terms of the PostgreSQL License.
10 *
11 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
13 *
14 * src/interfaces/ecpg/test/pg_regress_ecpg.c
15 *
16 *-------------------------------------------------------------------------
17 */
18
19 #include "pg_regress.h"
20
21 #define LINEBUFSIZE 300
22 static void
ecpg_filter(const char * sourcefile,const char * outfile)23 ecpg_filter(const char *sourcefile, const char *outfile)
24 {
25 /*
26 * Create a filtered copy of sourcefile, replacing #line x
27 * "./../bla/foo.h" with #line x "foo.h"
28 */
29 FILE *s,
30 *t;
31 char linebuf[LINEBUFSIZE];
32
33 s = fopen(sourcefile, "r");
34 if (!s)
35 {
36 fprintf(stderr, "Could not open file %s for reading\n", sourcefile);
37 exit(2);
38 }
39 t = fopen(outfile, "w");
40 if (!t)
41 {
42 fprintf(stderr, "Could not open file %s for writing\n", outfile);
43 exit(2);
44 }
45
46 while (fgets(linebuf, LINEBUFSIZE, s))
47 {
48 /* check for "#line " in the beginning */
49 if (strstr(linebuf, "#line ") == linebuf)
50 {
51 char *p = strchr(linebuf, '"');
52 char *n;
53 int plen = 1;
54
55 while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL))
56 {
57 plen++;
58 }
59 /* plen is one more than the number of . and / characters */
60 if (plen > 1)
61 {
62 n = (char *) malloc(plen);
63 StrNCpy(n, p + 1, plen);
64 replace_string(linebuf, n, "");
65 }
66 }
67 fputs(linebuf, t);
68 }
69 fclose(s);
70 fclose(t);
71 }
72
73 /*
74 * start an ecpg test process for specified file (including redirection),
75 * and return process ID
76 */
77
78 static PID_TYPE
ecpg_start_test(const char * testname,_stringlist ** resultfiles,_stringlist ** expectfiles,_stringlist ** tags)79 ecpg_start_test(const char *testname,
80 _stringlist **resultfiles,
81 _stringlist **expectfiles,
82 _stringlist **tags)
83 {
84 PID_TYPE pid;
85 char inprg[MAXPGPATH];
86 char insource[MAXPGPATH];
87 char *outfile_stdout,
88 expectfile_stdout[MAXPGPATH];
89 char *outfile_stderr,
90 expectfile_stderr[MAXPGPATH];
91 char *outfile_source,
92 expectfile_source[MAXPGPATH];
93 char cmd[MAXPGPATH * 3];
94 char *testname_dash;
95
96 snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
97
98 testname_dash = strdup(testname);
99 replace_string(testname_dash, "/", "-");
100 snprintf(expectfile_stdout, sizeof(expectfile_stdout),
101 "%s/expected/%s.stdout",
102 outputdir, testname_dash);
103 snprintf(expectfile_stderr, sizeof(expectfile_stderr),
104 "%s/expected/%s.stderr",
105 outputdir, testname_dash);
106 snprintf(expectfile_source, sizeof(expectfile_source),
107 "%s/expected/%s.c",
108 outputdir, testname_dash);
109
110 /*
111 * We can use replace_string() here because the replacement string does
112 * not occupy more space than the replaced one.
113 */
114 outfile_stdout = strdup(expectfile_stdout);
115 replace_string(outfile_stdout, "/expected/", "/results/");
116 outfile_stderr = strdup(expectfile_stderr);
117 replace_string(outfile_stderr, "/expected/", "/results/");
118 outfile_source = strdup(expectfile_source);
119 replace_string(outfile_source, "/expected/", "/results/");
120
121 add_stringlist_item(resultfiles, outfile_stdout);
122 add_stringlist_item(expectfiles, expectfile_stdout);
123 add_stringlist_item(tags, "stdout");
124
125 add_stringlist_item(resultfiles, outfile_stderr);
126 add_stringlist_item(expectfiles, expectfile_stderr);
127 add_stringlist_item(tags, "stderr");
128
129 add_stringlist_item(resultfiles, outfile_source);
130 add_stringlist_item(expectfiles, expectfile_source);
131 add_stringlist_item(tags, "source");
132
133 snprintf(insource, sizeof(insource), "%s.c", testname);
134 ecpg_filter(insource, outfile_source);
135
136 snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
137
138 snprintf(cmd, sizeof(cmd),
139 "\"%s\" >\"%s\" 2>\"%s\"",
140 inprg,
141 outfile_stdout,
142 outfile_stderr);
143
144 pid = spawn_process(cmd);
145
146 if (pid == INVALID_PID)
147 {
148 fprintf(stderr, _("could not start process for test %s\n"),
149 testname);
150 exit(2);
151 }
152
153 free(outfile_stdout);
154 free(outfile_stderr);
155 free(outfile_source);
156
157 return pid;
158 }
159
160 static void
ecpg_init(int argc,char * argv[])161 ecpg_init(int argc, char *argv[])
162 {
163 /* nothing to do here at the moment */
164 }
165
166 int
main(int argc,char * argv[])167 main(int argc, char *argv[])
168 {
169 return regression_main(argc, argv, ecpg_init, ecpg_start_test);
170 }
171