1214 lines
39 KiB
Diff
1214 lines
39 KiB
Diff
diff --git a/src/config.h.W32 b/src/config.h.W32
|
||
index 1a03a041..369e897d 100644
|
||
--- a/src/config.h.W32
|
||
+++ b/src/config.h.W32
|
||
@@ -344,6 +344,14 @@ this program. If not, see <https://www.gnu.org/licenses/>. */
|
||
|
||
/* Define to 1 if you have the `strtoll' function. */
|
||
#define HAVE_STRTOLL 1
|
||
+#ifdef __TINYC__
|
||
+# ifndef strtoll
|
||
+# define strtoll _strtoi64
|
||
+# endif
|
||
+# ifndef strtoull
|
||
+# define strtoull _strtoui64
|
||
+# endif
|
||
+#endif
|
||
|
||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||
/* SV 57152: MinGW64 version of dirent doesn't support d_type. */
|
||
diff --git a/src/dir.c b/src/dir.c
|
||
index b47e94fe..1e6e7397 100644
|
||
--- a/src/dir.c
|
||
+++ b/src/dir.c
|
||
@@ -456,7 +456,7 @@ dirfile_hash_cmp (const void *xv, const void *yv)
|
||
#define DIRFILE_BUCKETS 107
|
||
#endif
|
||
|
||
-static int dir_contents_file_exists_p (struct directory_contents *dir,
|
||
+static int dir_contents_file_exists_p (struct directory *dir,
|
||
const char *filename);
|
||
static struct directory *find_directory (const char *name);
|
||
|
||
@@ -623,7 +623,7 @@ find_directory (const char *name)
|
||
if (open_directories == MAX_OPEN_DIRECTORIES)
|
||
/* We have too many directories open already.
|
||
Read the entire directory and then close it. */
|
||
- dir_contents_file_exists_p (dc, 0);
|
||
+ dir_contents_file_exists_p (dir, 0);
|
||
}
|
||
}
|
||
|
||
@@ -634,17 +634,18 @@ find_directory (const char *name)
|
||
FILENAME must contain no slashes. */
|
||
|
||
static int
|
||
-dir_contents_file_exists_p (struct directory_contents *dir,
|
||
+dir_contents_file_exists_p (struct directory *dir,
|
||
const char *filename)
|
||
{
|
||
struct dirfile *df;
|
||
struct dirent *d;
|
||
+ struct directory_contents *dc = dir->contents;
|
||
#ifdef WINDOWS32
|
||
struct stat st;
|
||
int rehash = 0;
|
||
#endif
|
||
|
||
- if (dir == 0 || dir->dirfiles.ht_vec == 0)
|
||
+ if (dc == 0 || dc->dirfiles.ht_vec == 0)
|
||
/* The directory could not be stat'd or opened. */
|
||
return 0;
|
||
|
||
@@ -671,7 +672,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
}
|
||
dirfile_key.name = filename;
|
||
dirfile_key.length = strlen (filename);
|
||
- df = hash_find_item (&dir->dirfiles, &dirfile_key);
|
||
+ df = hash_find_item (&dc->dirfiles, &dirfile_key);
|
||
if (df)
|
||
return !df->impossible;
|
||
}
|
||
@@ -679,7 +680,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
/* The file was not found in the hashed list.
|
||
Try to read the directory further. */
|
||
|
||
- if (dir->dirstream == 0)
|
||
+ if (dc->dirstream == 0)
|
||
{
|
||
#ifdef WINDOWS32
|
||
/*
|
||
@@ -687,17 +688,17 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
* filesystems force a rehash always as mtime does not change
|
||
* on directories (ugh!).
|
||
*/
|
||
- if (dir->path_key)
|
||
+ if (dc->path_key)
|
||
{
|
||
- if ((dir->fs_flags & FS_FAT) != 0)
|
||
+ if ((dc->fs_flags & FS_FAT) != 0)
|
||
{
|
||
- dir->mtime = time ((time_t *) 0);
|
||
+ dc->mtime = time ((time_t *) 0);
|
||
rehash = 1;
|
||
}
|
||
- else if (stat (dir->path_key, &st) == 0 && st.st_mtime > dir->mtime)
|
||
+ else if (stat (dc->path_key, &st) == 0 && st.st_mtime > dc->mtime)
|
||
{
|
||
/* reset date stamp to show most recent re-process. */
|
||
- dir->mtime = st.st_mtime;
|
||
+ dc->mtime = st.st_mtime;
|
||
rehash = 1;
|
||
}
|
||
|
||
@@ -706,8 +707,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
return 0;
|
||
|
||
/* make sure directory can still be opened; if not return. */
|
||
- dir->dirstream = opendir (dir->path_key);
|
||
- if (!dir->dirstream)
|
||
+ dc->dirstream = opendir (dc->path_key);
|
||
+ if (!dc->dirstream)
|
||
return 0;
|
||
}
|
||
else
|
||
@@ -723,11 +724,11 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
struct dirfile dirfile_key;
|
||
struct dirfile **dirfile_slot;
|
||
|
||
- ENULLLOOP (d, readdir (dir->dirstream));
|
||
+ ENULLLOOP (d, readdir (dc->dirstream));
|
||
if (d == 0)
|
||
{
|
||
if (errno)
|
||
- pfatal_with_name ("INTERNAL: readdir");
|
||
+ OSS (fatal, NILF, "readdir %s: %s", dir->name, strerror (errno));
|
||
break;
|
||
}
|
||
|
||
@@ -747,7 +748,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
len = NAMLEN (d);
|
||
dirfile_key.name = d->d_name;
|
||
dirfile_key.length = len;
|
||
- dirfile_slot = (struct dirfile **) hash_find_slot (&dir->dirfiles, &dirfile_key);
|
||
+ dirfile_slot = (struct dirfile **) hash_find_slot (&dc->dirfiles, &dirfile_key);
|
||
#ifdef WINDOWS32
|
||
/*
|
||
* If re-reading a directory, don't cache files that have
|
||
@@ -768,7 +769,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
#endif
|
||
df->length = len;
|
||
df->impossible = 0;
|
||
- hash_insert_at (&dir->dirfiles, df, dirfile_slot);
|
||
+ hash_insert_at (&dc->dirfiles, df, dirfile_slot);
|
||
}
|
||
/* Check if the name matches the one we're searching for. */
|
||
if (filename != 0 && patheq (d->d_name, filename))
|
||
@@ -777,12 +778,13 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||
|
||
/* If the directory has been completely read in,
|
||
close the stream and reset the pointer to nil. */
|
||
- if (d == 0)
|
||
+ if (d == NULL)
|
||
{
|
||
--open_directories;
|
||
- closedir (dir->dirstream);
|
||
- dir->dirstream = 0;
|
||
+ closedir (dc->dirstream);
|
||
+ dc->dirstream = NULL;
|
||
}
|
||
+
|
||
return 0;
|
||
}
|
||
|
||
@@ -794,15 +796,10 @@ int
|
||
dir_file_exists_p (const char *dirname, const char *filename)
|
||
{
|
||
#ifdef VMS
|
||
- if ((filename != NULL) && (dirname != NULL))
|
||
- {
|
||
- int want_vmsify;
|
||
- want_vmsify = (strpbrk (dirname, ":<[") != NULL);
|
||
- if (want_vmsify)
|
||
- filename = vmsify (filename, 0);
|
||
- }
|
||
+ if (filename && dirname && strpbrk (dirname, ":<[") != NULL)
|
||
+ filename = vmsify (filename, 0);
|
||
#endif
|
||
- return dir_contents_file_exists_p (find_directory (dirname)->contents,
|
||
+ return dir_contents_file_exists_p (find_directory (dirname),
|
||
filename);
|
||
}
|
||
|
||
@@ -1225,7 +1222,7 @@ open_dirstream (const char *directory)
|
||
/* Read all the contents of the directory now. There is no benefit
|
||
in being lazy, since glob will want to see every file anyway. */
|
||
|
||
- dir_contents_file_exists_p (dir->contents, 0);
|
||
+ dir_contents_file_exists_p (dir, 0);
|
||
|
||
new = xmalloc (sizeof (struct dirstream));
|
||
new->contents = dir->contents;
|
||
diff --git a/src/function.c b/src/function.c
|
||
index f0ef3434..e4a3af86 100644
|
||
--- a/src/function.c
|
||
+++ b/src/function.c
|
||
@@ -2801,7 +2801,7 @@ define_new_function (const floc *flocp, const char *name,
|
||
_("Invalid maximum argument count (%u) for function %s"), max, name);
|
||
|
||
ent = xmalloc (sizeof (struct function_table_entry));
|
||
- ent->name = name;
|
||
+ ent->name = strcache_add (name);
|
||
ent->len = (unsigned char) len;
|
||
ent->minimum_args = (unsigned char) min;
|
||
ent->maximum_args = (unsigned char) max;
|
||
diff --git a/src/hash.c b/src/hash.c
|
||
index 5d7ea81b..d1652f84 100644
|
||
--- a/src/hash.c
|
||
+++ b/src/hash.c
|
||
@@ -361,7 +361,7 @@ round_up_2 (unsigned long n)
|
||
#define sum_get_unaligned_32(r, p) \
|
||
do { \
|
||
unsigned int val; \
|
||
- memcpy(&val, (p), 4); \
|
||
+ memcpy (&val, (p), 4); \
|
||
r += val; \
|
||
} while(0);
|
||
|
||
@@ -413,13 +413,16 @@ jhash(unsigned const char *k, int length)
|
||
#define UINTSZ sizeof (unsigned int)
|
||
|
||
#ifdef WORDS_BIGENDIAN
|
||
-/* The ifs are ordered from the first byte in memory to the last. */
|
||
+/* The ifs are ordered from the first byte in memory to the last.
|
||
+ Help the compiler optimize by using static memcpy length. */
|
||
#define sum_up_to_nul(r, p, plen, flag) \
|
||
do { \
|
||
unsigned int val = 0; \
|
||
size_t pn = (plen); \
|
||
- size_t n = pn < UINTSZ ? pn : UINTSZ; \
|
||
- memcpy (&val, (p), n); \
|
||
+ if (pn >= UINTSZ) \
|
||
+ memcpy (&val, (p), UINTSZ); \
|
||
+ else \
|
||
+ memcpy (&val, (p), pn); \
|
||
if ((val & 0xFF000000) == 0) \
|
||
flag = 1; \
|
||
else if ((val & 0xFF0000) == 0) \
|
||
@@ -432,13 +435,16 @@ jhash(unsigned const char *k, int length)
|
||
#else
|
||
/* First detect the presence of zeroes. If there is none, we can
|
||
sum the 4 bytes directly. Otherwise, the ifs are ordered as in the
|
||
- big endian case, from the first byte in memory to the last. */
|
||
+ big endian case, from the first byte in memory to the last.
|
||
+ Help the compiler optimize by using static memcpy length. */
|
||
#define sum_up_to_nul(r, p, plen, flag) \
|
||
do { \
|
||
unsigned int val = 0; \
|
||
size_t pn = (plen); \
|
||
- size_t n = pn < UINTSZ ? pn : UINTSZ; \
|
||
- memcpy (&val, (p), n); \
|
||
+ if (pn >= UINTSZ) \
|
||
+ memcpy (&val, (p), UINTSZ); \
|
||
+ else \
|
||
+ memcpy (&val, (p), pn); \
|
||
flag = ((val - 0x01010101) & ~val) & 0x80808080; \
|
||
if (!flag) \
|
||
r += val; \
|
||
diff --git a/src/main.c b/src/main.c
|
||
index eec93656..b31ddd4d 100644
|
||
--- a/src/main.c
|
||
+++ b/src/main.c
|
||
@@ -1182,11 +1182,6 @@ main (int argc, char **argv, char **envp)
|
||
/* Useful for attaching debuggers, etc. */
|
||
SPIN ("main-entry");
|
||
|
||
- /* Don't die if our stdout sends us SIGPIPE. */
|
||
-#ifdef SIGPIPE
|
||
- bsd_signal (SIGPIPE, SIG_IGN);
|
||
-#endif
|
||
-
|
||
#ifdef HAVE_ATEXIT
|
||
if (ANY_SET (check_io_state (), IO_STDOUT_OK))
|
||
atexit (close_stdout);
|
||
@@ -1264,6 +1259,9 @@ main (int argc, char **argv, char **envp)
|
||
#endif
|
||
#ifdef SIGQUIT
|
||
FATAL_SIG (SIGQUIT);
|
||
+#endif
|
||
+#ifdef SIGPIPE
|
||
+ FATAL_SIG (SIGPIPE);
|
||
#endif
|
||
FATAL_SIG (SIGINT);
|
||
FATAL_SIG (SIGTERM);
|
||
@@ -1505,7 +1503,7 @@ main (int argc, char **argv, char **envp)
|
||
|
||
/* If this is MAKE_RESTARTS, check to see if the "already printed
|
||
the enter statement" flag is set. */
|
||
- if (len == 13 && memcmp (envp[i], STRING_SIZE_TUPLE ("MAKE_RESTARTS")) == 0)
|
||
+ if (len == 13 && memcmp (envp[i], "MAKE_RESTARTS", CSTRLEN ("MAKE_RESTARTS")) == 0)
|
||
{
|
||
if (*ep == '-')
|
||
{
|
||
@@ -1930,6 +1928,9 @@ main (int argc, char **argv, char **envp)
|
||
_("Makefile from standard input specified twice"));
|
||
|
||
outfile = get_tmpfile (&newnm);
|
||
+ if (!outfile)
|
||
+ O (fatal, NILF,
|
||
+ _("cannot store makefile from stdin to a temporary file"));
|
||
|
||
while (!feof (stdin) && ! ferror (stdin))
|
||
{
|
||
diff --git a/src/misc.c b/src/misc.c
|
||
index 8264fe9f..00dce749 100644
|
||
--- a/src/misc.c
|
||
+++ b/src/misc.c
|
||
@@ -20,8 +20,7 @@ this program. If not, see <https://www.gnu.org/licenses/>. */
|
||
#include "os.h"
|
||
#include "debug.h"
|
||
|
||
-/* GNU make no longer supports pre-ANSI89 environments. */
|
||
-
|
||
+#include <assert.h>
|
||
#include <stdarg.h>
|
||
|
||
#ifdef WINDOWS32
|
||
@@ -650,11 +649,19 @@ get_tmppath ()
|
||
# ifdef HAVE_MKTEMP
|
||
path = get_tmptemplate ();
|
||
if (*mktemp (path) == '\0')
|
||
- pfatal_with_name ("mktemp");
|
||
+ {
|
||
+ OSS (error, NILF,
|
||
+ _("cannot generate temp path from %s: %s"), path, strerror (errno));
|
||
+ return NULL;
|
||
+ }
|
||
# else
|
||
path = xmalloc (L_tmpnam + 1);
|
||
if (tmpnam (path) == NULL)
|
||
- pfatal_with_name ("tmpnam");
|
||
+ {
|
||
+ OS (error, NILF,
|
||
+ _("cannot generate temp name: %s"), strerror (errno));
|
||
+ return NULL;
|
||
+ }
|
||
# endif
|
||
|
||
return path;
|
||
@@ -662,7 +669,9 @@ get_tmppath ()
|
||
#endif
|
||
|
||
/* Generate a temporary file and return an fd for it. If name is NULL then
|
||
- the temp file is anonymous and will be deleted when the process exits. */
|
||
+ the temp file is anonymous and will be deleted when the process exits. If
|
||
+ name is not null then *name will point to an allocated buffer, or set to
|
||
+ NULL on failure. */
|
||
int
|
||
get_tmpfd (char **name)
|
||
{
|
||
@@ -670,9 +679,11 @@ get_tmpfd (char **name)
|
||
char *tmpnm;
|
||
mode_t mask;
|
||
|
||
- /* If there's an os-specific way to get an anoymous temp file use it. */
|
||
- if (!name)
|
||
+ if (name)
|
||
+ *name = NULL;
|
||
+ else
|
||
{
|
||
+ /* If there's an os-specific way to get an anoymous temp file use it. */
|
||
fd = os_anontmp ();
|
||
if (fd >= 0)
|
||
return fd;
|
||
@@ -689,13 +700,19 @@ get_tmpfd (char **name)
|
||
EINTRLOOP (fd, mkstemp (tmpnm));
|
||
#else
|
||
tmpnm = get_tmppath ();
|
||
+ if (!tmpnm)
|
||
+ return -1;
|
||
|
||
/* Can't use mkstemp(), but try to guard against a race condition. */
|
||
EINTRLOOP (fd, open (tmpnm, O_CREAT|O_EXCL|O_RDWR, 0600));
|
||
#endif
|
||
if (fd < 0)
|
||
- OSS (fatal, NILF,
|
||
- _("create temporary file %s: %s"), tmpnm, strerror (errno));
|
||
+ {
|
||
+ OSS (error, NILF,
|
||
+ _("cannot create temporary file %s: %s"), tmpnm, strerror (errno));
|
||
+ free (tmpnm);
|
||
+ return -1;
|
||
+ }
|
||
|
||
if (name)
|
||
*name = tmpnm;
|
||
@@ -704,8 +721,8 @@ get_tmpfd (char **name)
|
||
int r;
|
||
EINTRLOOP (r, unlink (tmpnm));
|
||
if (r < 0)
|
||
- OSS (fatal, NILF,
|
||
- _("unlink temporary file %s: %s"), tmpnm, strerror (errno));
|
||
+ OSS (error, NILF,
|
||
+ _("cannot unlink temporary file %s: %s"), tmpnm, strerror (errno));
|
||
free (tmpnm);
|
||
}
|
||
|
||
@@ -715,8 +732,8 @@ get_tmpfd (char **name)
|
||
}
|
||
|
||
/* Return a FILE* for a temporary file, opened in the safest way possible.
|
||
- Set name to point to an allocated buffer containing the name of the file.
|
||
- Note, this cannot be NULL! */
|
||
+ Set name to point to an allocated buffer containing the name of the file,
|
||
+ or NULL on failure. Note, name cannot be NULL! */
|
||
FILE *
|
||
get_tmpfile (char **name)
|
||
{
|
||
@@ -725,26 +742,37 @@ get_tmpfile (char **name)
|
||
FILE *file;
|
||
|
||
#if defined(HAVE_FDOPEN)
|
||
- int fd = get_tmpfd (name);
|
||
+ int fd;
|
||
+ assert (name);
|
||
+ fd = get_tmpfd (name);
|
||
+ if (fd < 0)
|
||
+ return NULL;
|
||
+ assert (*name);
|
||
|
||
ENULLLOOP (file, fdopen (fd, tmpfile_mode));
|
||
if (file == NULL)
|
||
- OSS (fatal, NILF,
|
||
+ OSS (error, NILF,
|
||
_("fdopen: temporary file %s: %s"), *name, strerror (errno));
|
||
#else
|
||
/* Preserve the current umask, and set a restrictive one for temp files. */
|
||
mode_t mask = umask (0077);
|
||
- int err;
|
||
|
||
+ assert (name);
|
||
*name = get_tmppath ();
|
||
+ if (!*name)
|
||
+ return NULL;
|
||
|
||
/* Although this fopen is insecure, it is executed only on non-fdopen
|
||
platforms, which should be a rarity nowadays. */
|
||
|
||
ENULLLOOP (file, fopen (*name, tmpfile_mode));
|
||
if (file == NULL)
|
||
- OSS (fatal, NILF,
|
||
- _("fopen: temporary file %s: %s"), *name, strerror (errno));
|
||
+ {
|
||
+ OSS (error, NILF,
|
||
+ _("fopen: temporary file %s: %s"), *name, strerror (errno));
|
||
+ free (*name);
|
||
+ *name = NULL;
|
||
+ }
|
||
|
||
umask (mask);
|
||
#endif
|
||
diff --git a/src/output.c b/src/output.c
|
||
index 43eb2f06..22387dff 100644
|
||
--- a/src/output.c
|
||
+++ b/src/output.c
|
||
@@ -248,6 +248,9 @@ setup_tmpfile (struct output *out)
|
||
|
||
/* If we failed to create a temp file, disable output sync going forward. */
|
||
error:
|
||
+ O (error, NILF,
|
||
+ _("cannot open output-sync lock file, suppressing output-sync."));
|
||
+
|
||
output_close (out);
|
||
output_sync = OUTPUT_SYNC_NONE;
|
||
osync_clear ();
|
||
diff --git a/src/posixos.c b/src/posixos.c
|
||
index 44aeb346..78358dd8 100644
|
||
--- a/src/posixos.c
|
||
+++ b/src/posixos.c
|
||
@@ -167,12 +167,12 @@ jobserver_setup (int slots, const char *style)
|
||
hang until the write side is open. */
|
||
EINTRLOOP (job_fds[0], open (fifo_name, O_RDONLY|O_NONBLOCK));
|
||
if (job_fds[0] < 0)
|
||
- OSS (fatal, NILF, _("Cannot open jobserver %s: %s"),
|
||
+ OSS (fatal, NILF, _("cannot open jobserver %s: %s"),
|
||
fifo_name, strerror (errno));
|
||
|
||
EINTRLOOP (job_fds[1], open (fifo_name, O_WRONLY));
|
||
if (job_fds[0] < 0)
|
||
- OSS (fatal, NILF, _("Cannot open jobserver %s: %s"),
|
||
+ OSS (fatal, NILF, _("cannot open jobserver %s: %s"),
|
||
fifo_name, strerror (errno));
|
||
|
||
js_type = js_fifo;
|
||
@@ -183,7 +183,7 @@ jobserver_setup (int slots, const char *style)
|
||
if (js_type == js_none)
|
||
{
|
||
if (style && strcmp (style, "pipe") != 0)
|
||
- OS (fatal, NILF, _("Unknown jobserver auth style '%s'"), style);
|
||
+ OS (fatal, NILF, _("unknown jobserver auth style '%s'"), style);
|
||
|
||
EINTRLOOP (r, pipe (job_fds));
|
||
if (r < 0)
|
||
@@ -229,14 +229,19 @@ jobserver_parse_auth (const char *auth)
|
||
|
||
EINTRLOOP (job_fds[0], open (fifo_name, O_RDONLY));
|
||
if (job_fds[0] < 0)
|
||
- OSS (fatal, NILF,
|
||
- _("Cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||
+ {
|
||
+ OSS (error, NILF,
|
||
+ _("cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||
+ return 0;
|
||
+ }
|
||
|
||
EINTRLOOP (job_fds[1], open (fifo_name, O_WRONLY));
|
||
- if (job_fds[0] < 0)
|
||
- OSS (fatal, NILF,
|
||
- _("Cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||
-
|
||
+ if (job_fds[1] < 0)
|
||
+ {
|
||
+ OSS (error, NILF,
|
||
+ _("cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||
+ return 0;
|
||
+ }
|
||
js_type = js_fifo;
|
||
}
|
||
/* If not, it must be a simple pipe. */
|
||
@@ -867,12 +872,15 @@ os_anontmp ()
|
||
FILE *tfile;
|
||
ENULLLOOP (tfile, tmpfile ());
|
||
if (!tfile)
|
||
- pfatal_with_name ("tmpfile");
|
||
+ {
|
||
+ OS (error, NILF, "tmpfile: %s", strerror (errno));
|
||
+ return -1;
|
||
+ }
|
||
umask (mask);
|
||
|
||
EINTRLOOP (fd, dup (fileno (tfile)));
|
||
if (fd < 0)
|
||
- pfatal_with_name ("dup");
|
||
+ OS (error, NILF, "dup: %s", strerror (errno));
|
||
fclose (tfile);
|
||
}
|
||
#endif
|
||
diff --git a/src/read.c b/src/read.c
|
||
index 07431240..15f58ecf 100644
|
||
--- a/src/read.c
|
||
+++ b/src/read.c
|
||
@@ -1140,20 +1140,29 @@ eval (struct ebuffer *ebuf, int set_default)
|
||
|
||
p2 = next_token (variable_buffer);
|
||
|
||
- /* If the word we're looking at is EOL, see if there's _anything_
|
||
- on the line. If not, a variable expanded to nothing, so ignore
|
||
- it. If so, we can't parse this line so punt. */
|
||
+ /* If we're at EOL we didn't find a separator so we don't know what
|
||
+ kind of line this is. */
|
||
if (wtype == w_eol)
|
||
{
|
||
+ /* Ignore an empty line. */
|
||
if (*p2 == '\0')
|
||
continue;
|
||
|
||
- /* There's no need to be ivory-tower about this: check for
|
||
- one of the most common bugs found in makefiles... */
|
||
+ /* Check for spaces instead of TAB. */
|
||
if (cmd_prefix == '\t' && strneq (line, " ", 8))
|
||
O (fatal, fstart, _("missing separator (did you mean TAB instead of 8 spaces?)"));
|
||
- else
|
||
- O (fatal, fstart, _("missing separator"));
|
||
+
|
||
+ /* Check for conditionals without whitespace afterward.
|
||
+ We don't check ifdef/ifndef because there's no real way to miss
|
||
+ whitespace there. */
|
||
+ p2 = next_token (line);
|
||
+ if (strneq (p2, "if", 2) &&
|
||
+ ((strneq (&p2[2], "neq", 3) && !STOP_SET (p2[5], MAP_BLANK))
|
||
+ || (strneq (&p2[2], "eq", 2) && !STOP_SET (p2[4], MAP_BLANK))))
|
||
+ O (fatal, fstart, _("missing separator (ifeq/ifneq must be followed by whitespace)"));
|
||
+
|
||
+ /* No idea... */
|
||
+ O (fatal, fstart, _("missing separator"));
|
||
}
|
||
|
||
{
|
||
diff --git a/src/w32/w32os.c b/src/w32/w32os.c
|
||
index 9c5dec24..213bbf12 100644
|
||
--- a/src/w32/w32os.c
|
||
+++ b/src/w32/w32os.c
|
||
@@ -216,12 +216,12 @@ jobserver_setup (int slots, const char *style)
|
||
/* sub_proc.c is limited in the number of objects it can wait for. */
|
||
|
||
if (style && strcmp (style, "sem") != 0)
|
||
- OS (fatal, NILF, _("Unknown jobserver auth style '%s'"), style);
|
||
+ OS (fatal, NILF, _("unknown jobserver auth style '%s'"), style);
|
||
|
||
if (slots > process_table_usable_size())
|
||
{
|
||
slots = process_table_usable_size();
|
||
- DB (DB_JOBS, (_("Jobserver slots limited to %d\n"), slots));
|
||
+ DB (DB_JOBS, (_("jobserver slots limited to %d\n"), slots));
|
||
}
|
||
|
||
sprintf (jobserver_semaphore_name, "gmake_semaphore_%d", _getpid ());
|
||
@@ -255,10 +255,12 @@ jobserver_parse_auth (const char *auth)
|
||
{
|
||
DWORD err = GetLastError ();
|
||
const char *estr = map_windows32_error_to_string (err);
|
||
- fatal (NILF, strlen (auth) + INTSTR_LENGTH + strlen (estr),
|
||
- _("internal error: unable to open jobserver semaphore '%s': (Error %ld: %s)"),
|
||
+ error (NILF, strlen (auth) + INTSTR_LENGTH + strlen (estr),
|
||
+ _("unable to open jobserver semaphore '%s': (Error %ld: %s)"),
|
||
auth, err, estr);
|
||
+ return 0;
|
||
}
|
||
+
|
||
DB (DB_JOBS, (_("Jobserver client (semaphore %s)\n"), auth));
|
||
|
||
return 1;
|
||
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
|
||
index 70dd1821..5fc37595 100644
|
||
--- a/tests/run_make_tests.pl
|
||
+++ b/tests/run_make_tests.pl
|
||
@@ -185,7 +185,6 @@ sub subst_make_string
|
||
s/#PERL#/$perl_name/g;
|
||
s/#PWD#/$cwdpath/g;
|
||
s/#WORK#/$workdir/g;
|
||
- # If we're using a shell
|
||
s/#HELPER#/$perl_name $helptool/g;
|
||
return $_;
|
||
}
|
||
diff --git a/tests/scripts/features/jobserver b/tests/scripts/features/jobserver
|
||
index 8ecbe345..e12facf0 100644
|
||
--- a/tests/scripts/features/jobserver
|
||
+++ b/tests/scripts/features/jobserver
|
||
@@ -14,6 +14,7 @@ if (!$parallel_jobs) {
|
||
|
||
# Shorthand
|
||
my $np = '--no-print-directory';
|
||
+my $j1err = "warning: jobserver unavailable: using -j1. Add '+' to parent make rule.";
|
||
|
||
# Simple test of MAKEFLAGS settings
|
||
run_make_test(q!
|
||
@@ -90,7 +91,7 @@ if ($port_type ne 'W32') {
|
||
default: ; @ #MAKEPATH# -f Makefile2
|
||
!,
|
||
"--jobserver-style=pipe -j2 $np",
|
||
-"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
|
||
+"#MAKE#[1]: $j1err
|
||
#MAKE#[1]: Nothing to be done for 'foo'.");
|
||
|
||
rmfiles('Makefile2');
|
||
@@ -98,15 +99,15 @@ default: ; @ #MAKEPATH# -f Makefile2
|
||
|
||
# For Windows and named pipes, we don't need to worry about recursion
|
||
if ($port_type eq 'W32' || exists $FEATURES{'jobserver-fifo'}) {
|
||
- create_file('Makefile2', "vpath %.c ../\n", "foo:\n");
|
||
+ create_file('Makefile2', "vpath %.c ../\n", "foo:\n");
|
||
|
||
- run_make_test(q!
|
||
+ run_make_test(q!
|
||
default: ; @ #MAKEPATH# -f Makefile2
|
||
!,
|
||
"-j2 $np",
|
||
"#MAKE#[1]: Nothing to be done for 'foo'.");
|
||
|
||
- rmfiles('Makefile2');
|
||
+ rmfiles('Makefile2');
|
||
}
|
||
|
||
# Ensure enter/leave directory messages appear before jobserver warnings
|
||
@@ -129,17 +130,17 @@ all: a
|
||
all a: ; @echo $@
|
||
!,
|
||
'--jobserver-style=foo -j8',
|
||
- "#MAKE#: *** Unknown jobserver auth style 'foo'. Stop.", 512);
|
||
-
|
||
-# sv 62908.
|
||
-# Test that when mkfifo fails, make switches to pipe and succeeds.
|
||
-# Force mkfifo to fail by attempting to create a fifo in a non existent
|
||
-# directory.
|
||
-# run_make_test does not allow matching a multiline pattern, therefore run the
|
||
-# test twice.
|
||
-# First time look for /$ERR_no_such_file/ to ensure mkfifo failed.
|
||
-# Second time look for /Nothing to be done/ to ensure make succeeded.
|
||
+ "#MAKE#: *** unknown jobserver auth style 'foo'. Stop.", 512);
|
||
+
|
||
if (exists $FEATURES{'jobserver-fifo'}) {
|
||
+ # sv 62908.
|
||
+ # Test that when mkfifo fails, make switches to pipe and succeeds.
|
||
+ # Force mkfifo to fail by attempting to create a fifo in a non existent
|
||
+ # directory.
|
||
+ # run_make_test does not allow matching a multiline pattern, therefore run
|
||
+ # the test twice.
|
||
+ # First time look for /$ERR_no_such_file/ to ensure mkfifo failed.
|
||
+ # Second time look for /Nothing to be done/ to ensure make succeeded.
|
||
$ENV{TMPDIR} = "nosuchdir";
|
||
run_make_test("all:\n", '-j2', "/$ERR_no_such_file/");
|
||
|
||
@@ -155,6 +156,10 @@ recurse: ; @$(MAKE) -f #MAKEFILE# all
|
||
all:;@echo "$$MAKEFLAGS"
|
||
!,
|
||
"-j2 --no-print-directory", "/--jobserver-auth=fifo:\\./");
|
||
+
|
||
+ # Verify we fall back to -j1 but continue, of the auth is bad.
|
||
+ $ENV{MAKEFLAGS} = '-j2 --jobserver-auth=fifo:nosuchfile';
|
||
+ run_make_test(q!all:;@echo hi!, "", "#MAKE#: cannot open jobserver nosuchfile: $ERR_no_such_file\n#MAKE#: $j1err\nhi\n");
|
||
}
|
||
|
||
1;
|
||
diff --git a/tests/scripts/features/output-sync b/tests/scripts/features/output-sync
|
||
index 13a54ca0..18c85c0a 100644
|
||
--- a/tests/scripts/features/output-sync
|
||
+++ b/tests/scripts/features/output-sync
|
||
@@ -360,11 +360,27 @@ use POSIX ();
|
||
# file.
|
||
run_make_test(q!
|
||
pid:=$(shell echo $$PPID)
|
||
-all:; @kill -TERM $(pid) && sleep 16
|
||
+all:; @#HELPER# term $(pid) sleep 10
|
||
!, '-O -j2', '/#MAKE#: \*\*\* \[#MAKEFILE#:3: all] Terminated/', POSIX::SIGTERM);
|
||
}
|
||
-
|
||
unlink($fout);
|
||
+
|
||
+# SV 63333. Test that make continues to run without output sync when we
|
||
+# cannot create a temporary file.
|
||
+# Create a non-writable temporary directory.
|
||
+# Run the test twice, because run_make_test cannot match a regex againt a
|
||
+# multiline input.
|
||
+my $tdir = 'test_tmp_dir';
|
||
+mkdir($tdir, 0500);
|
||
+$ENV{'TMPDIR'} = $tdir;
|
||
+
|
||
+run_make_test(q!
|
||
+all:; $(info hello, world)
|
||
+!, '-Orecurse', "/suppressing output-sync/");
|
||
+
|
||
+run_make_test(undef, '-Orecurse', "/#MAKE#: 'all' is up to date./");
|
||
+
|
||
+rmdir($tdir);
|
||
}
|
||
|
||
# This tells the test driver that the perl test script executed properly.
|
||
diff --git a/tests/scripts/features/temp_stdin b/tests/scripts/features/temp_stdin
|
||
index b06df53e..3bd53e02 100644
|
||
--- a/tests/scripts/features/temp_stdin
|
||
+++ b/tests/scripts/features/temp_stdin
|
||
@@ -71,7 +71,7 @@ run_make_test(q!
|
||
include bye.mk
|
||
pid:=$(shell echo $$PPID)
|
||
all:;
|
||
-bye.mk: force; @kill -TERM $(pid) && sleep 16
|
||
+bye.mk: force; @#HELPER# term $(pid) sleep 10
|
||
force:
|
||
!, '-f-', '/#MAKE#: \*\*\* \[#MAKEFILE#:5: bye.mk] Terminated/', POSIX::SIGTERM);
|
||
}
|
||
@@ -109,6 +109,21 @@ force:
|
||
@make_command = @make_orig;
|
||
unlink($makecopy);
|
||
rmdir($tmakedir);
|
||
+
|
||
+# SV 63333. Test that make exits with an error message if we cannot store a
|
||
+# makefile from stdin to a temporary file.
|
||
+# Create a non-writable temporary directory.
|
||
+
|
||
+my $tdir = 'test_tmp_dir';
|
||
+mkdir($tdir, 0500);
|
||
+$ENV{'TMPDIR'} = $tdir;
|
||
+close(STDIN);
|
||
+open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
|
||
+
|
||
+run_make_test(q!
|
||
+all:; $(info hello, world)
|
||
+!, '-f-', '/cannot store makefile from stdin to a temporary file. Stop./', 512);
|
||
+rmdir($tdir);
|
||
}
|
||
|
||
close(STDIN);
|
||
diff --git a/tests/scripts/misc/failure b/tests/scripts/misc/failure
|
||
new file mode 100644
|
||
index 00000000..edd90fbb
|
||
--- /dev/null
|
||
+++ b/tests/scripts/misc/failure
|
||
@@ -0,0 +1,49 @@
|
||
+# -*-perl-*-
|
||
+
|
||
+$description = "Test miscellaneous failures.";
|
||
+
|
||
+
|
||
+# Test that the "did you mean TAB" message is printed properly
|
||
+
|
||
+run_make_test(q!
|
||
+$x.
|
||
+!,
|
||
+ '', '#MAKEFILE#:2: *** missing separator. Stop.', 512);
|
||
+
|
||
+run_make_test(q!
|
||
+foo:
|
||
+ bar
|
||
+!,
|
||
+ '', '#MAKEFILE#:3: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.', 512);
|
||
+
|
||
+run_make_test(q!
|
||
+.RECIPEPREFIX = :
|
||
+foo:
|
||
+ bar
|
||
+!,
|
||
+ '', '#MAKEFILE#:4: *** missing separator. Stop.', 512);
|
||
+
|
||
+for my $kw ('eq', 'neq') {
|
||
+run_make_test(qq!
|
||
+if$kw(foo,bar)
|
||
+\$(error ouch)
|
||
+endif
|
||
+!,
|
||
+ '', '#MAKEFILE#:2: *** missing separator (ifeq/ifneq must be followed by whitespace). Stop.', 512);
|
||
+
|
||
+run_make_test(qq!
|
||
+if$kw
|
||
+\$(error ouch)
|
||
+endif
|
||
+!,
|
||
+ '', '#MAKEFILE#:2: *** invalid syntax in conditional. Stop.', 512);
|
||
+
|
||
+run_make_test(qq!
|
||
+if$kw blah
|
||
+\$(error ouch)
|
||
+endif
|
||
+!,
|
||
+ '', '#MAKEFILE#:2: *** invalid syntax in conditional. Stop.', 512);
|
||
+}
|
||
+
|
||
+1;
|
||
diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special
|
||
index 68f3128c..abe9fc0c 100644
|
||
--- a/tests/scripts/variables/special
|
||
+++ b/tests/scripts/variables/special
|
||
@@ -122,26 +122,6 @@ reset-four \
|
||
: foo-three
|
||
: foo-four');
|
||
|
||
-# Test that the "did you mean TAB" message is printed properly
|
||
-
|
||
-run_make_test(q!
|
||
-$x.
|
||
-!,
|
||
- '', '#MAKEFILE#:2: *** missing separator. Stop.', 512);
|
||
-
|
||
-run_make_test(q!
|
||
-foo:
|
||
- bar
|
||
-!,
|
||
- '', '#MAKEFILE#:3: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.', 512);
|
||
-
|
||
-run_make_test(q!
|
||
-.RECIPEPREFIX = :
|
||
-foo:
|
||
- bar
|
||
-!,
|
||
- '', '#MAKEFILE#:4: *** missing separator. Stop.', 512);
|
||
-
|
||
1;
|
||
|
||
### Local Variables:
|
||
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
|
||
index b64fffb6..efe4981d 100644
|
||
--- a/tests/test_driver.pl
|
||
+++ b/tests/test_driver.pl
|
||
@@ -806,12 +806,135 @@ sub error
|
||
die "$caller: $message";
|
||
}
|
||
|
||
+sub compare_answer_vms
|
||
+{
|
||
+ my ($kgo, $log) = @_;
|
||
+
|
||
+ # VMS has extra blank lines in output sometimes.
|
||
+ # Ticket #41760
|
||
+ $log =~ s/\n\n+/\n/gm;
|
||
+ $log =~ s/\A\n+//g;
|
||
+ return 1 if ($kgo eq $log);
|
||
+
|
||
+ # VMS adding a "Waiting for unfinished jobs..."
|
||
+ # Remove it for now to see what else is going on.
|
||
+ $log =~ s/^.+\*\*\* Waiting for unfinished jobs.+$//m;
|
||
+ $log =~ s/\n\n/\n/gm;
|
||
+ $log =~ s/^\n+//gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS wants target device to exist or generates an error,
|
||
+ # Some test tagets look like VMS devices and trip this.
|
||
+ $log =~ s/^.+\: no such device or address.*$//gim;
|
||
+ $log =~ s/\n\n/\n/gm;
|
||
+ $log =~ s/^\n+//gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS error message has a different case
|
||
+ $log =~ s/no such file /No such file /gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS is putting comas instead of spaces in output
|
||
+ $log =~ s/,/ /gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS Is sometimes adding extra leading spaces to output?
|
||
+ {
|
||
+ (my $mlog = $log) =~ s/^ +//gm;
|
||
+ return 1 if ($mlog eq $kgo);
|
||
+ }
|
||
+
|
||
+ # VMS port not handling POSIX encoded child status
|
||
+ # Translate error case it for now.
|
||
+ $log =~ s/0x1035a00a/1/gim;
|
||
+ return 1 if ($log =~ /\Q$kgo\E/i);
|
||
+
|
||
+ $log =~ s/0x1035a012/2/gim;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # Tests are using a UNIX null command, temp hack
|
||
+ # until this can be handled by the VMS port.
|
||
+ # ticket # 41761
|
||
+ $log =~ s/^.+DCL-W-NOCOMD.*$//gim;
|
||
+ $log =~ s/\n\n+/\n/gm;
|
||
+ $log =~ s/^\n+//gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # Tests are using exit 0;
|
||
+ # this generates a warning that should stop the make, but does not
|
||
+ $log =~ s/^.+NONAME-W-NOMSG.*$//gim;
|
||
+ $log =~ s/\n\n+/\n/gm;
|
||
+ $log =~ s/^\n+//gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS is sometimes adding single quotes to output?
|
||
+ $log =~ s/\'//gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # And missing an extra space in output
|
||
+ $kgo =~ s/\h\h+/ /gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS adding ; to end of some lines.
|
||
+ $log =~ s/;\n/\n/gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS adding trailing space to end of some quoted lines.
|
||
+ $log =~ s/\h+\n/\n/gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # And VMS missing leading blank line
|
||
+ $kgo =~ s/\A\n//g;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # Unix double quotes showing up as single quotes on VMS.
|
||
+ $kgo =~ s/\"//g;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+sub compare_answer
|
||
+{
|
||
+ my ($kgo, $log) = @_;
|
||
+ my ($mkgo, $mlog);
|
||
+
|
||
+ # For make, get rid of any time skew error before comparing--too bad this
|
||
+ # has to go into the "generic" driver code :-/
|
||
+ $log =~ s/^.*modification time .*in the future.*\n//gm;
|
||
+ $log =~ s/^.*Clock skew detected.*\n//gm;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # Get rid of newline differences, forever
|
||
+ $kgo =~ s,\r\n,\n,gs;
|
||
+ $log =~ s,\r\n,\n,gs;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # See if it is a backslash problem (only on W32?)
|
||
+ ($mkgo = $kgo) =~ tr,\\,/,;
|
||
+ ($mlog = $log) =~ tr,\\,/,;
|
||
+ return 1 if ($log eq $kgo);
|
||
+
|
||
+ # VMS is a whole thing...
|
||
+ return 1 if ($^O eq 'VMS' && compare_answer_vms($mkgo, $mlog));
|
||
+
|
||
+ # See if the answer might be a regex.
|
||
+ if ($kgo =~ m,^/(.+)/$,) {
|
||
+ return 1 if ($log =~ /$1/);
|
||
+
|
||
+ # We can't test with backslashes converted to forward slashes, because
|
||
+ # backslashes could be escaping RE special characters!
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
my %old_tempfiles = ();
|
||
|
||
sub compare_output
|
||
{
|
||
my ($answer, $logfile) = @_;
|
||
- my ($slurp, $answer_matched, $extra) = ('', 0, 0);
|
||
+ my ($slurp, $matched, $extra) = ('', 0, 0);
|
||
|
||
++$tests_run;
|
||
|
||
@@ -831,169 +954,25 @@ sub compare_output
|
||
|
||
if (! defined $answer) {
|
||
print "Ignoring output ........ " if $debug;
|
||
- $answer_matched = 1;
|
||
+ $matched = 1;
|
||
} else {
|
||
print "Comparing output ........ " if $debug;
|
||
|
||
- $slurp = &read_file_into_string ($logfile);
|
||
-
|
||
- # For make, get rid of any time skew error before comparing--too bad this
|
||
- # has to go into the "generic" driver code :-/
|
||
- $slurp =~ s/^.*modification time .*in the future.*\n//gm;
|
||
- $slurp =~ s/^.*Clock skew detected.*\n//gm;
|
||
-
|
||
- if ($slurp eq $answer) {
|
||
- $answer_matched = 1;
|
||
- } else {
|
||
- # See if it is a slash or CRLF problem
|
||
- my ($answer_mod, $slurp_mod) = ($answer, $slurp);
|
||
-
|
||
- $answer_mod =~ tr,\\,/,;
|
||
- $answer_mod =~ s,\r\n,\n,gs;
|
||
-
|
||
- $slurp_mod =~ tr,\\,/,;
|
||
- $slurp_mod =~ s,\r\n,\n,gs;
|
||
-
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
-
|
||
- if (!$answer_matched && $^O eq 'VMS') {
|
||
-
|
||
- # VMS has extra blank lines in output sometimes.
|
||
- # Ticket #41760
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/\n\n+/\n/gm;
|
||
- $slurp_mod =~ s/\A\n+//g;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS adding a "Waiting for unfinished jobs..."
|
||
- # Remove it for now to see what else is going on.
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/^.+\*\*\* Waiting for unfinished jobs.+$//m;
|
||
- $slurp_mod =~ s/\n\n/\n/gm;
|
||
- $slurp_mod =~ s/^\n+//gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS wants target device to exist or generates an error,
|
||
- # Some test tagets look like VMS devices and trip this.
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/^.+\: no such device or address.*$//gim;
|
||
- $slurp_mod =~ s/\n\n/\n/gm;
|
||
- $slurp_mod =~ s/^\n+//gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS error message has a different case
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/no such file /No such file /gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS is putting comas instead of spaces in output
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/,/ /gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS Is sometimes adding extra leading spaces to output?
|
||
- if (!$answer_matched) {
|
||
- my $slurp_mod = $slurp_mod;
|
||
- $slurp_mod =~ s/^ +//gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS port not handling POSIX encoded child status
|
||
- # Translate error case it for now.
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/0x1035a00a/1/gim;
|
||
- $answer_matched = 1 if $slurp_mod =~ /\Q$answer_mod\E/i;
|
||
-
|
||
- }
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/0x1035a012/2/gim;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # Tests are using a UNIX null command, temp hack
|
||
- # until this can be handled by the VMS port.
|
||
- # ticket # 41761
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/^.+DCL-W-NOCOMD.*$//gim;
|
||
- $slurp_mod =~ s/\n\n+/\n/gm;
|
||
- $slurp_mod =~ s/^\n+//gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
- # Tests are using exit 0;
|
||
- # this generates a warning that should stop the make, but does not
|
||
- if (!$answer_matched) {
|
||
- $slurp_mod =~ s/^.+NONAME-W-NOMSG.*$//gim;
|
||
- $slurp_mod =~ s/\n\n+/\n/gm;
|
||
- $slurp_mod =~ s/^\n+//gm;
|
||
- $answer_matched = ($slurp_mod eq $answer_mod);
|
||
- }
|
||
-
|
||
- # VMS is sometimes adding single quotes to output?
|
||
- if (!$answer_matched) {
|
||
- my $noq_slurp_mod = $slurp_mod;
|
||
- $noq_slurp_mod =~ s/\'//gm;
|
||
- $answer_matched = ($noq_slurp_mod eq $answer_mod);
|
||
-
|
||
- # And missing an extra space in output
|
||
- if (!$answer_matched) {
|
||
- $noq_answer_mod = $answer_mod;
|
||
- $noq_answer_mod =~ s/\h\h+/ /gm;
|
||
- $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
|
||
- }
|
||
-
|
||
- # VMS adding ; to end of some lines.
|
||
- if (!$answer_matched) {
|
||
- $noq_slurp_mod =~ s/;\n/\n/gm;
|
||
- $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
|
||
- }
|
||
-
|
||
- # VMS adding trailing space to end of some quoted lines.
|
||
- if (!$answer_matched) {
|
||
- $noq_slurp_mod =~ s/\h+\n/\n/gm;
|
||
- $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
|
||
- }
|
||
-
|
||
- # And VMS missing leading blank line
|
||
- if (!$answer_matched) {
|
||
- $noq_answer_mod =~ s/\A\n//g;
|
||
- $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
|
||
- }
|
||
-
|
||
- # Unix double quotes showing up as single quotes on VMS.
|
||
- if (!$answer_matched) {
|
||
- $noq_answer_mod =~ s/\"//g;
|
||
- $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- # If it still doesn't match, see if the answer might be a regex.
|
||
- if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
|
||
- $answer_matched = ($slurp =~ /$1/);
|
||
- if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
|
||
- $answer_matched = ($slurp_mod =~ /$1/);
|
||
- }
|
||
- }
|
||
- }
|
||
+ $matched = compare_answer($answer, &read_file_into_string ($logfile));
|
||
}
|
||
|
||
- if ($keep || ! $answer_matched) {
|
||
+ if ($keep || ! $matched) {
|
||
&create_file(&get_basefile, $answer);
|
||
&create_file(&get_runfile, $command_string);
|
||
}
|
||
|
||
- if ($answer_matched && $test_passed && !$extra) {
|
||
+ if ($matched && $test_passed && !$extra) {
|
||
print "ok\n" if $debug;
|
||
++$tests_passed;
|
||
return 1;
|
||
}
|
||
|
||
- if (! $answer_matched) {
|
||
+ if (! $matched) {
|
||
print "DIFFERENT OUTPUT\n" if $debug;
|
||
|
||
print "\nCreating Difference File ...\n" if $debug;
|
||
@@ -1001,10 +980,11 @@ sub compare_output
|
||
# Create the difference file
|
||
my $base = get_basefile();
|
||
if ($diff_name) {
|
||
- my $command = "$diff_name -c $base $logfile";
|
||
- &run_command_with_output(get_difffile(), $command);
|
||
+ &run_command_with_output(get_difffile(),
|
||
+ "$diff_name -c $base $logfile");
|
||
} else {
|
||
- create_file(get_difffile(), "Log file $logfile differs from base file $base\n");
|
||
+ create_file(get_difffile(),
|
||
+ "Log file $logfile differs from base file $base\n");
|
||
}
|
||
}
|
||
|
||
diff --git a/tests/thelp.pl b/tests/thelp.pl
|
||
index 993339cb..c243bcb8 100755
|
||
--- a/tests/thelp.pl
|
||
+++ b/tests/thelp.pl
|
||
@@ -16,6 +16,7 @@
|
||
# wait <word> : wait for a file named <word> to exist
|
||
# tmout <secs> : Change the timeout for waiting. Default is 4 seconds.
|
||
# sleep <secs> : Sleep for <secs> seconds then echo <secs>
|
||
+# term <pid> : send SIGTERM to PID <pid>
|
||
# fail <err> : echo <err> to stdout then exit with error code err
|
||
#
|
||
# If given -q only the "out" command generates output.
|
||
@@ -95,6 +96,12 @@ sub op {
|
||
return 1;
|
||
}
|
||
|
||
+ if ($op eq 'term') {
|
||
+ print "term $nm\n";
|
||
+ kill('TERM', $nm);
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
if ($op eq 'fail') {
|
||
print "fail $nm\n";
|
||
exit($nm);
|