aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/ecpg/test/pg_regress_ecpg.c76
-rw-r--r--src/test/regress/pg_regress.c52
-rw-r--r--src/test/regress/pg_regress.h5
3 files changed, 77 insertions, 56 deletions
diff --git a/src/interfaces/ecpg/test/pg_regress_ecpg.c b/src/interfaces/ecpg/test/pg_regress_ecpg.c
index 46b9e78fe59..a2d7b70d9a3 100644
--- a/src/interfaces/ecpg/test/pg_regress_ecpg.c
+++ b/src/interfaces/ecpg/test/pg_regress_ecpg.c
@@ -19,8 +19,9 @@
#include "postgres_fe.h"
#include "pg_regress.h"
+#include "common/string.h"
+#include "lib/stringinfo.h"
-#define LINEBUFSIZE 300
static void
ecpg_filter(const char *sourcefile, const char *outfile)
@@ -31,7 +32,7 @@ ecpg_filter(const char *sourcefile, const char *outfile)
*/
FILE *s,
*t;
- char linebuf[LINEBUFSIZE];
+ StringInfoData linebuf;
s = fopen(sourcefile, "r");
if (!s)
@@ -46,13 +47,14 @@ ecpg_filter(const char *sourcefile, const char *outfile)
exit(2);
}
- while (fgets(linebuf, LINEBUFSIZE, s))
+ initStringInfo(&linebuf);
+
+ while (pg_get_line_append(s, &linebuf))
{
/* check for "#line " in the beginning */
- if (strstr(linebuf, "#line ") == linebuf)
+ if (strstr(linebuf.data, "#line ") == linebuf.data)
{
- char *p = strchr(linebuf, '"');
- char *n;
+ char *p = strchr(linebuf.data, '"');
int plen = 1;
while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL))
@@ -62,13 +64,15 @@ ecpg_filter(const char *sourcefile, const char *outfile)
/* plen is one more than the number of . and / characters */
if (plen > 1)
{
- n = (char *) malloc(plen);
- strlcpy(n, p + 1, plen);
- replace_string(linebuf, n, "");
+ memmove(p + 1, p + plen, strlen(p + plen) + 1);
+ /* we don't bother to fix up linebuf.len */
}
}
- fputs(linebuf, t);
+ fputs(linebuf.data, t);
+ resetStringInfo(&linebuf);
}
+
+ pfree(linebuf.data);
fclose(s);
fclose(t);
}
@@ -87,40 +91,42 @@ ecpg_start_test(const char *testname,
PID_TYPE pid;
char inprg[MAXPGPATH];
char insource[MAXPGPATH];
- char *outfile_stdout,
+ StringInfoData testname_dash;
+ char outfile_stdout[MAXPGPATH],
expectfile_stdout[MAXPGPATH];
- char *outfile_stderr,
+ char outfile_stderr[MAXPGPATH],
expectfile_stderr[MAXPGPATH];
- char *outfile_source,
+ char outfile_source[MAXPGPATH],
expectfile_source[MAXPGPATH];
char cmd[MAXPGPATH * 3];
- char *testname_dash;
char *appnameenv;
snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
+ snprintf(insource, sizeof(insource), "%s.c", testname);
+
+ initStringInfo(&testname_dash);
+ appendStringInfoString(&testname_dash, testname);
+ replace_string(&testname_dash, "/", "-");
- testname_dash = strdup(testname);
- replace_string(testname_dash, "/", "-");
snprintf(expectfile_stdout, sizeof(expectfile_stdout),
"%s/expected/%s.stdout",
- outputdir, testname_dash);
+ outputdir, testname_dash.data);
snprintf(expectfile_stderr, sizeof(expectfile_stderr),
"%s/expected/%s.stderr",
- outputdir, testname_dash);
+ outputdir, testname_dash.data);
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/");
+ outputdir, testname_dash.data);
+
+ snprintf(outfile_stdout, sizeof(outfile_stdout),
+ "%s/results/%s.stdout",
+ outputdir, testname_dash.data);
+ snprintf(outfile_stderr, sizeof(outfile_stderr),
+ "%s/results/%s.stderr",
+ outputdir, testname_dash.data);
+ snprintf(outfile_source, sizeof(outfile_source),
+ "%s/results/%s.c",
+ outputdir, testname_dash.data);
add_stringlist_item(resultfiles, outfile_stdout);
add_stringlist_item(expectfiles, expectfile_stdout);
@@ -134,18 +140,15 @@ ecpg_start_test(const char *testname,
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);
- appnameenv = psprintf("PGAPPNAME=ecpg/%s", testname_dash);
+ appnameenv = psprintf("PGAPPNAME=ecpg/%s", testname_dash.data);
putenv(appnameenv);
pid = spawn_process(cmd);
@@ -160,10 +163,7 @@ ecpg_start_test(const char *testname,
unsetenv("PGAPPNAME");
free(appnameenv);
- free(testname_dash);
- free(outfile_stdout);
- free(outfile_stderr);
- free(outfile_source);
+ free(testname_dash.data);
return pid;
}
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index d82e0189dcf..74fd026856e 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -31,8 +31,10 @@
#include "common/logging.h"
#include "common/restricted_token.h"
+#include "common/string.h"
#include "common/username.h"
#include "getopt_long.h"
+#include "lib/stringinfo.h"
#include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */
#include "pg_config_paths.h"
#include "pg_regress.h"
@@ -435,22 +437,32 @@ string_matches_pattern(const char *str, const char *pattern)
}
/*
- * Replace all occurrences of a string in a string with a different string.
- * NOTE: Assumes there is enough room in the target buffer!
+ * Replace all occurrences of "replace" in "string" with "replacement".
+ * The StringInfo will be suitably enlarged if necessary.
+ *
+ * Note: this is optimized on the assumption that most calls will find
+ * no more than one occurrence of "replace", and quite likely none.
*/
void
-replace_string(char *string, const char *replace, const char *replacement)
+replace_string(StringInfo string, const char *replace, const char *replacement)
{
+ int pos = 0;
char *ptr;
- while ((ptr = strstr(string, replace)) != NULL)
+ while ((ptr = strstr(string->data + pos, replace)) != NULL)
{
- char *dup = pg_strdup(string);
+ /* Must copy the remainder of the string out of the StringInfo */
+ char *suffix = pg_strdup(ptr + strlen(replace));
- strlcpy(string, dup, ptr - string + 1);
- strcat(string, replacement);
- strcat(string, dup + (ptr - string) + strlen(replace));
- free(dup);
+ /* Truncate StringInfo at start of found string ... */
+ string->len = ptr - string->data;
+ /* ... and append the replacement (this restores the trailing '\0') */
+ appendStringInfoString(string, replacement);
+ /* Next search should start after the replacement */
+ pos = string->len;
+ /* Put back the remainder of the string */
+ appendStringInfoString(string, suffix);
+ free(suffix);
}
}
@@ -521,7 +533,7 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch
char prefix[MAXPGPATH];
FILE *infile,
*outfile;
- char line[1024];
+ StringInfoData line;
/* reject filenames not finishing in ".source" */
if (strlen(*name) < 8)
@@ -551,15 +563,21 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch
progname, destfile, strerror(errno));
exit(2);
}
- while (fgets(line, sizeof(line), infile))
+
+ initStringInfo(&line);
+
+ while (pg_get_line_append(infile, &line))
{
- replace_string(line, "@abs_srcdir@", inputdir);
- replace_string(line, "@abs_builddir@", outputdir);
- replace_string(line, "@testtablespace@", testtablespace);
- replace_string(line, "@libdir@", dlpath);
- replace_string(line, "@DLSUFFIX@", DLSUFFIX);
- fputs(line, outfile);
+ replace_string(&line, "@abs_srcdir@", inputdir);
+ replace_string(&line, "@abs_builddir@", outputdir);
+ replace_string(&line, "@testtablespace@", testtablespace);
+ replace_string(&line, "@libdir@", dlpath);
+ replace_string(&line, "@DLSUFFIX@", DLSUFFIX);
+ fputs(line.data, outfile);
+ resetStringInfo(&line);
}
+
+ pfree(line.data);
fclose(infile);
fclose(outfile);
}
diff --git a/src/test/regress/pg_regress.h b/src/test/regress/pg_regress.h
index ee6e0d42f40..726f9c90489 100644
--- a/src/test/regress/pg_regress.h
+++ b/src/test/regress/pg_regress.h
@@ -18,6 +18,8 @@
#define INVALID_PID INVALID_HANDLE_VALUE
#endif
+struct StringInfoData; /* avoid including stringinfo.h here */
+
/* simple list of strings */
typedef struct _stringlist
{
@@ -49,5 +51,6 @@ int regression_main(int argc, char *argv[],
init_function ifunc, test_function tfunc);
void add_stringlist_item(_stringlist **listhead, const char *str);
PID_TYPE spawn_process(const char *cmdline);
-void replace_string(char *string, const char *replace, const char *replacement);
+void replace_string(struct StringInfoData *string,
+ const char *replace, const char *replacement);
bool file_exists(const char *file);