PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_regress_ecpg.c File Reference
#include "postgres_fe.h"
#include "common/string.h"
#include "lib/stringinfo.h"
#include "pg_regress.h"
Include dependency graph for pg_regress_ecpg.c:

Go to the source code of this file.

Functions

static void ecpg_filter_source (const char *sourcefile, const char *outfile)
 
static void ecpg_filter_stderr (const char *resultfile, const char *tmpfile)
 
static PID_TYPE ecpg_start_test (const char *testname, _stringlist **resultfiles, _stringlist **expectfiles, _stringlist **tags)
 
static void ecpg_postprocess_result (const char *filename)
 
static void ecpg_init (int argc, char *argv[])
 
int main (int argc, char *argv[])
 

Function Documentation

◆ ecpg_filter_source()

static void ecpg_filter_source ( const char *  sourcefile,
const char *  outfile 
)
static

Definition at line 34 of file pg_regress_ecpg.c.

35{
36 FILE *s,
37 *t;
38 StringInfoData linebuf;
39
40 s = fopen(sourcefile, "r");
41 if (!s)
42 {
43 fprintf(stderr, "Could not open file %s for reading\n", sourcefile);
44 exit(2);
45 }
46 t = fopen(outfile, "w");
47 if (!t)
48 {
49 fprintf(stderr, "Could not open file %s for writing\n", outfile);
50 exit(2);
51 }
52
53 initStringInfo(&linebuf);
54
55 while (pg_get_line_buf(s, &linebuf))
56 {
57 /* check for "#line " in the beginning */
58 if (strstr(linebuf.data, "#line ") == linebuf.data)
59 {
60 char *p = strchr(linebuf.data, '"');
61 int plen = 1;
62
63 while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL))
64 {
65 plen++;
66 }
67 /* plen is one more than the number of . and / characters */
68 if (plen > 1)
69 {
70 memmove(p + 1, p + plen, strlen(p + plen) + 1);
71 /* we don't bother to fix up linebuf.len */
72 }
73 }
74 fputs(linebuf.data, t);
75 }
76
77 pfree(linebuf.data);
78 fclose(s);
79 fclose(t);
80}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
exit(1)
void pfree(void *pointer)
Definition: mcxt.c:1521
bool pg_get_line_buf(FILE *stream, StringInfo buf)
Definition: pg_get_line.c:95
static char * outfile
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56

References StringInfoData::data, exit(), fprintf, initStringInfo(), outfile, pfree(), and pg_get_line_buf().

Referenced by ecpg_start_test().

◆ ecpg_filter_stderr()

static void ecpg_filter_stderr ( const char *  resultfile,
const char *  tmpfile 
)
static

Definition at line 93 of file pg_regress_ecpg.c.

94{
95 FILE *s,
96 *t;
97 StringInfoData linebuf;
98
99 s = fopen(resultfile, "r");
100 if (!s)
101 {
102 fprintf(stderr, "Could not open file %s for reading\n", resultfile);
103 exit(2);
104 }
105 t = fopen(tmpfile, "w");
106 if (!t)
107 {
108 fprintf(stderr, "Could not open file %s for writing\n", tmpfile);
109 exit(2);
110 }
111
112 initStringInfo(&linebuf);
113
114 while (pg_get_line_buf(s, &linebuf))
115 {
116 char *p1 = strstr(linebuf.data, "connection to server ");
117
118 if (p1)
119 {
120 char *p2 = strstr(p1, "failed: ");
121
122 if (p2)
123 {
124 memmove(p1 + 21, p2, strlen(p2) + 1);
125 /* we don't bother to fix up linebuf.len */
126 }
127 }
128 fputs(linebuf.data, t);
129 }
130
131 pfree(linebuf.data);
132 fclose(s);
133 fclose(t);
134 if (rename(tmpfile, resultfile) != 0)
135 {
136 fprintf(stderr, "Could not overwrite file %s with %s\n",
137 resultfile, tmpfile);
138 exit(2);
139 }
140}

References StringInfoData::data, exit(), fprintf, initStringInfo(), p2, pfree(), and pg_get_line_buf().

Referenced by ecpg_postprocess_result().

◆ ecpg_init()

static void ecpg_init ( int  argc,
char *  argv[] 
)
static

Definition at line 254 of file pg_regress_ecpg.c.

255{
256 /* nothing to do here at the moment */
257}

Referenced by main().

◆ ecpg_postprocess_result()

static void ecpg_postprocess_result ( const char *  filename)
static

Definition at line 239 of file pg_regress_ecpg.c.

240{
241 int nlen = strlen(filename);
242
243 /* Only stderr files require filtering, at the moment */
244 if (nlen > 7 && strcmp(filename + nlen - 7, ".stderr") == 0)
245 {
246 char *tmpfile = psprintf("%s.tmp", filename);
247
249 pfree(tmpfile);
250 }
251}
static char * filename
Definition: pg_dumpall.c:119
static void ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References ecpg_filter_stderr(), filename, pfree(), and psprintf().

Referenced by main().

◆ ecpg_start_test()

static PID_TYPE ecpg_start_test ( const char *  testname,
_stringlist **  resultfiles,
_stringlist **  expectfiles,
_stringlist **  tags 
)
static

Definition at line 148 of file pg_regress_ecpg.c.

152{
153 PID_TYPE pid;
154 char inprg[MAXPGPATH];
155 char insource[MAXPGPATH];
156 StringInfoData testname_dash;
157 char outfile_stdout[MAXPGPATH],
158 expectfile_stdout[MAXPGPATH];
159 char outfile_stderr[MAXPGPATH],
160 expectfile_stderr[MAXPGPATH];
161 char outfile_source[MAXPGPATH],
162 expectfile_source[MAXPGPATH];
163 char cmd[MAXPGPATH * 3];
164 char *appnameenv;
165
166 snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
167 snprintf(insource, sizeof(insource), "%s/%s.c", inputdir, testname);
168
169 /* make a version of the test name that has dashes in place of slashes */
170 initStringInfo(&testname_dash);
171 appendStringInfoString(&testname_dash, testname);
172 for (char *c = testname_dash.data; *c != '\0'; c++)
173 {
174 if (*c == '/')
175 *c = '-';
176 }
177
178 snprintf(expectfile_stdout, sizeof(expectfile_stdout),
179 "%s/expected/%s.stdout",
180 expecteddir, testname_dash.data);
181 snprintf(expectfile_stderr, sizeof(expectfile_stderr),
182 "%s/expected/%s.stderr",
183 expecteddir, testname_dash.data);
184 snprintf(expectfile_source, sizeof(expectfile_source),
185 "%s/expected/%s.c",
186 expecteddir, testname_dash.data);
187
188 snprintf(outfile_stdout, sizeof(outfile_stdout),
189 "%s/results/%s.stdout",
190 outputdir, testname_dash.data);
191 snprintf(outfile_stderr, sizeof(outfile_stderr),
192 "%s/results/%s.stderr",
193 outputdir, testname_dash.data);
194 snprintf(outfile_source, sizeof(outfile_source),
195 "%s/results/%s.c",
196 outputdir, testname_dash.data);
197
198 add_stringlist_item(resultfiles, outfile_stdout);
199 add_stringlist_item(expectfiles, expectfile_stdout);
200 add_stringlist_item(tags, "stdout");
201
202 add_stringlist_item(resultfiles, outfile_stderr);
203 add_stringlist_item(expectfiles, expectfile_stderr);
204 add_stringlist_item(tags, "stderr");
205
206 add_stringlist_item(resultfiles, outfile_source);
207 add_stringlist_item(expectfiles, expectfile_source);
208 add_stringlist_item(tags, "source");
209
210 ecpg_filter_source(insource, outfile_source);
211
212 snprintf(cmd, sizeof(cmd),
213 "\"%s\" >\"%s\" 2>\"%s\"",
214 inprg,
215 outfile_stdout,
216 outfile_stderr);
217
218 appnameenv = psprintf("ecpg/%s", testname_dash.data);
219 setenv("PGAPPNAME", appnameenv, 1);
220 free(appnameenv);
221
222 pid = spawn_process(cmd);
223
224 if (pid == INVALID_PID)
225 {
226 fprintf(stderr, _("could not start process for test %s\n"),
227 testname);
228 exit(2);
229 }
230
231 unsetenv("PGAPPNAME");
232
233 free(testname_dash.data);
234
235 return pid;
236}
#define _(x)
Definition: elog.c:90
#define free(a)
Definition: header.h:65
static void add_stringlist_item(_stringlist **listhead, const char *str)
Definition: initdb.c:444
#define MAXPGPATH
char * outputdir
Definition: pg_regress.c:100
char * inputdir
Definition: pg_regress.c:99
char * expecteddir
Definition: pg_regress.c:101
PID_TYPE spawn_process(const char *cmdline)
Definition: pg_regress.c:1200
#define PID_TYPE
Definition: pg_regress.h:14
#define INVALID_PID
Definition: pg_regress.h:15
static void ecpg_filter_source(const char *sourcefile, const char *outfile)
#define snprintf
Definition: port.h:238
char * c
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:179
#define unsetenv(x)
Definition: win32_port.h:556
#define setenv(x, y, z)
Definition: win32_port.h:555

References _, add_stringlist_item(), appendStringInfoString(), StringInfoData::data, ecpg_filter_source(), exit(), expecteddir, fprintf, free, initStringInfo(), inputdir, INVALID_PID, MAXPGPATH, outputdir, PID_TYPE, psprintf(), setenv, snprintf, spawn_process(), and unsetenv.

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 260 of file pg_regress_ecpg.c.

261{
262 return regression_main(argc, argv,
263 ecpg_init,
266}
int regression_main(int argc, char *argv[], init_function ifunc, test_start_function startfunc, postprocess_result_function postfunc)
Definition: pg_regress.c:2065
static void ecpg_init(int argc, char *argv[])
static void ecpg_postprocess_result(const char *filename)
static PID_TYPE ecpg_start_test(const char *testname, _stringlist **resultfiles, _stringlist **expectfiles, _stringlist **tags)

References ecpg_init(), ecpg_postprocess_result(), ecpg_start_test(), and regression_main().