PostgreSQL Source Code  git master
pg_regress_ecpg.c File Reference
#include "postgres_fe.h"
#include "pg_regress.h"
#include "common/string.h"
#include "lib/stringinfo.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.

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

Referenced by ecpg_start_test().

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 }
bool pg_get_line_buf(FILE *stream, StringInfo buf)
Definition: pg_get_line.c:88
#define fprintf
Definition: port.h:220
void pfree(void *pointer)
Definition: mcxt.c:1169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
static char * outfile

◆ 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.

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

Referenced by ecpg_postprocess_result().

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 }
bool pg_get_line_buf(FILE *stream, StringInfo buf)
Definition: pg_get_line.c:88
#define fprintf
Definition: port.h:220
void pfree(void *pointer)
Definition: mcxt.c:1169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

◆ ecpg_init()

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

Definition at line 249 of file pg_regress_ecpg.c.

Referenced by main().

250 {
251  /* nothing to do here at the moment */
252 }

◆ ecpg_postprocess_result()

static void ecpg_postprocess_result ( const char *  filename)
static

Definition at line 234 of file pg_regress_ecpg.c.

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

Referenced by main().

235 {
236  int nlen = strlen(filename);
237 
238  /* Only stderr files require filtering, at the moment */
239  if (nlen > 7 && strcmp(filename + nlen - 7, ".stderr") == 0)
240  {
241  char *tmpfile = psprintf("%s.tmp", filename);
242 
243  ecpg_filter_stderr(filename, tmpfile);
244  pfree(tmpfile);
245  }
246 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void pfree(void *pointer)
Definition: mcxt.c:1169
static void ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
static char * filename
Definition: pg_dumpall.c:92

◆ 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.

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

Referenced by main().

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.c", testname);
168 
169  initStringInfo(&testname_dash);
170  appendStringInfoString(&testname_dash, testname);
171  replace_string(&testname_dash, "/", "-");
172 
173  snprintf(expectfile_stdout, sizeof(expectfile_stdout),
174  "%s/expected/%s.stdout",
175  outputdir, testname_dash.data);
176  snprintf(expectfile_stderr, sizeof(expectfile_stderr),
177  "%s/expected/%s.stderr",
178  outputdir, testname_dash.data);
179  snprintf(expectfile_source, sizeof(expectfile_source),
180  "%s/expected/%s.c",
181  outputdir, testname_dash.data);
182 
183  snprintf(outfile_stdout, sizeof(outfile_stdout),
184  "%s/results/%s.stdout",
185  outputdir, testname_dash.data);
186  snprintf(outfile_stderr, sizeof(outfile_stderr),
187  "%s/results/%s.stderr",
188  outputdir, testname_dash.data);
189  snprintf(outfile_source, sizeof(outfile_source),
190  "%s/results/%s.c",
191  outputdir, testname_dash.data);
192 
193  add_stringlist_item(resultfiles, outfile_stdout);
194  add_stringlist_item(expectfiles, expectfile_stdout);
195  add_stringlist_item(tags, "stdout");
196 
197  add_stringlist_item(resultfiles, outfile_stderr);
198  add_stringlist_item(expectfiles, expectfile_stderr);
199  add_stringlist_item(tags, "stderr");
200 
201  add_stringlist_item(resultfiles, outfile_source);
202  add_stringlist_item(expectfiles, expectfile_source);
203  add_stringlist_item(tags, "source");
204 
205  ecpg_filter_source(insource, outfile_source);
206 
207  snprintf(cmd, sizeof(cmd),
208  "\"%s\" >\"%s\" 2>\"%s\"",
209  inprg,
210  outfile_stdout,
211  outfile_stderr);
212 
213  appnameenv = psprintf("ecpg/%s", testname_dash.data);
214  setenv("PGAPPNAME", appnameenv, 1);
215  free(appnameenv);
216 
217  pid = spawn_process(cmd);
218 
219  if (pid == INVALID_PID)
220  {
221  fprintf(stderr, _("could not start process for test %s\n"),
222  testname);
223  exit(2);
224  }
225 
226  unsetenv("PGAPPNAME");
227 
228  free(testname_dash.data);
229 
230  return pid;
231 }
static void static void static void void add_stringlist_item(_stringlist **listhead, const char *str)
Definition: pg_regress.c:157
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define PID_TYPE
Definition: pg_regress.h:14
#define fprintf
Definition: port.h:220
PID_TYPE spawn_process(const char *cmdline)
Definition: pg_regress.c:1190
#define setenv(x, y, z)
Definition: win32_port.h:497
static void ecpg_filter_source(const char *sourcefile, const char *outfile)
#define MAXPGPATH
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define INVALID_PID
Definition: pg_regress.h:15
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char * outputdir
Definition: pg_regress.c:78
char * inputdir
Definition: pg_regress.c:77
#define free(a)
Definition: header.h:65
void replace_string(StringInfo string, const char *replace, const char *replacement)
Definition: pg_regress.c:447
#define snprintf
Definition: port.h:216
#define _(x)
Definition: elog.c:89
#define unsetenv(x)
Definition: win32_port.h:498

◆ main()

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

Definition at line 255 of file pg_regress_ecpg.c.

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

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