]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Various enhancements
authorPaul Smith <psmith@gnu.org>
Sun, 16 May 2004 19:16:52 +0000 (19:16 +0000)
committerPaul Smith <psmith@gnu.org>
Sun, 16 May 2004 19:16:52 +0000 (19:16 +0000)
  - OS/2 Patches
  - OpenVMS updates
  - Sanitize the handling of -include/sinclude with and without -k
  - Fix the setting of $< for order-only rules.

30 files changed:
ChangeLog
Makefile.am
commands.c
configure.in
default.c
dep.h
doc/make.texi
file.c
getloadavg.c
job.c
main.c
make.h
makefile.vms
read.c
readme.vms
remake.c
tests/run_make_tests.pl
tests/scripts/features/echoing
tests/scripts/features/errors
tests/scripts/features/include
tests/scripts/features/order_only
tests/scripts/functions/wildcard
tests/scripts/options/dash-C
tests/scripts/options/dash-k
tests/scripts/targets/FORCE
tests/scripts/targets/PHONY
tests/scripts/targets/SILENT
tests/scripts/targets/clean
tests/scripts/variables/special
tests/test_driver.pl

index 30f13b9ce12a3bc425e4201fd33fc7fed9de1fbf..759c4e423b87c2c8e9a995a185a685e32c0af3f9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2004-05-16  Paul D. Smith  <psmith@gnu.org>
+
+       * remake.c (update_goal_chain): Change the argument specifying
+       whether we're rebuilding makefiles to be a global variable,
+       REBUILDING_MAKEFILES.
+       (complain): Extract the code that complains about no rules to make
+       a target into a separate function.
+       (update_file_1): If we tried to rebuild a file during the makefile
+       rebuild phase and it was dontcare, then no message was printed.
+       If we then try to build the same file during the normal build,
+       print a message this time.
+       (remake_file): Don't complain about un-remake-able files when
+       we're rebuilding makefiles.
+
+2004-05-11  Paul D. Smith  <psmith@gnu.org>
+
+       * job.c (construct_command_argv_internal): OS/2 patches from
+       Andreas Buening <andreas.buening@nexgo.de>.
+
+2004-05-10  Paul D. Smith  <psmith@gnu.org>
+
+       * remake.c (update_file): Don't walk the double-colon chain unless
+       this is a double-colon rule.  Fix suggested by Boris Kolpackov
+       <boris@kolpackov.net>.
+
+       * makefile.vms (CFLAGS): Remove glob/globfree (see readme.vms docs)
+       * readme.vms: New section describing OpenVMS support and issues.
+       * default.c (default_variables): Add support for IA64.
+       * job.c (tryToSetupYAst) [VMS]: On VMS running make in batch mode
+       without some privilege aborts make with the error
+       %SYSTEM-F-NOPRIV. It happens when setting up a handler for
+       pressing Ctrl+Y and the input device is no terminal. The change
+       catches this error and just continues.
+
+       Patches by Hartmut Becker <Hartmut.Becker@hp.com>
+
+2004-04-25  Paul D. Smith  <psmith@gnu.org>
+
+       * commands.c (set_file_variables): Set $< properly in the face of
+       order-only prerequisites.
+       Patch from Boris Kolpackov <boris@kolpackov.net>
+
+2004-04-21  Bob Byrnes  <byrnes@curl.com>
+
+       * main.c (main): Notice failures to remake makefiles.
+
+2004-03-28  Paul D. Smith  <psmith@gnu.org>
+
+       Patches for Acorn RISC OS by Peter Naulls <peter@chocky.org>
+
+       * job.c: No default shell for RISC OS.
+       (load_too_high): Hard-code the return to 1.
+       (construct_command_argv_internal): No sh_chars or sh_cmds.
+       * getloadavg.c: Don't set LOAD_AVE_TYPE on RISC OS.
+
 2004-03-20  Paul D. Smith  <psmith@gnu.org>
 
        * variable.c (do_variable_definition): Don't append from the
index 77ebdf6524b722ee6c2aba4ea842b4b98c3df359..96fb188fd587b1874f0dac46e4664fcadeb1bf72 100644 (file)
@@ -114,11 +114,11 @@ check-local: check-regression check-loadavg
 
 .PHONY: check-loadavg check-regression
 
-check-loadavg: loadavg
+check-loadavg: loadavg$(EXEEXT)
        @echo The system uptime program believes the load average to be:
        -uptime
        @echo The GNU load average checking code thinks:
-       -./loadavg
+       -./loadavg$(EXEEXT)
 
 # The loadavg function is invoked during "make check" to test getloadavg.
 noinst_PROGRAMS = loadavg
index a1766b46add43e0b5608968c7d092511d5919112..b202f6cded9ad610962efae1e0503ba988dc9340 100644 (file)
@@ -41,6 +41,7 @@ extern int getpid ();
 static void
 set_file_variables (struct file *file)
 {
+  struct dep *d;
   char *at, *percent, *star, *less;
 
 #ifndef        NO_ARCHIVES
@@ -105,8 +106,14 @@ set_file_variables (struct file *file)
     }
   star = file->stem;
 
-  /* $< is the first dependency.  */
-  less = file->deps != 0 ? dep_name (file->deps) : "";
+  /* $< is the first not order-only dependency.  */
+  less = "";
+  for (d = file->deps; d != 0; d = d->next)
+    if (!d->ignore_mtime)
+      {
+        less = dep_name (d);
+        break;
+      }
 
   if (file->cmds == default_file->cmds)
     /* This file got its commands from .DEFAULT.
@@ -134,7 +141,6 @@ set_file_variables (struct file *file)
     char *caret_value;
     char *qp;
     char *bp;
-    struct dep *d;
     unsigned int len;
 
     /* Compute first the value for $+, which is supposed to contain
index b28c3fb02cc5b15b19e60e1b632327fddbab5d1d..15c2b88a431fecb70f90d816431cbec9d8117f3f 100644 (file)
@@ -259,7 +259,8 @@ if test "$make_cv_sa_restart" != no; then
      [Define if <signal.h> defines the SA_RESTART constant.])
 fi
 
-# enable make_cv_sa_restart for OS/2
+# enable make_cv_sa_restart for OS/2 so that the jobserver will be enabled,
+# but do it after HAVE_SA_RESTART has been defined.
 case "$host_os" in
   os2*) make_cv_sa_restart=yes ;;
 esac
index b07f1527bd212f82ea58f7eaa943538886b4229c..58855c680b0c4cd69ddb92c621397ce1303e0e90 100644 (file)
--- a/default.c
+++ b/default.c
@@ -308,7 +308,11 @@ static char *default_variables[] =
 #ifdef VMS
 #ifdef __ALPHA
     "ARCH", "ALPHA",
-#else
+#endif
+#ifdef __ia64
+    "ARCH", "IA64",
+#endif
+#ifdef __VAX
     "ARCH", "VAX",
 #endif
     "AR", "library/obj",
diff --git a/dep.h b/dep.h
index 7f4380b71a1938339dea8add520222d1cccf496e..4c9a1523bcfaff11f25a51109644d0384aa36f0b 100644 (file)
--- a/dep.h
+++ b/dep.h
@@ -74,5 +74,5 @@ extern char *dep_name ();
 extern struct dep *copy_dep_chain PARAMS ((struct dep *d));
 extern struct dep *read_all_makefiles PARAMS ((char **makefiles));
 extern int eval_buffer PARAMS ((char *buffer));
-extern int update_goal_chain PARAMS ((struct dep *goals, int makefiles));
+extern int update_goal_chain PARAMS ((struct dep *goals));
 extern void uniquize_deps PARAMS ((struct dep *));
index 72701345fcc25e30bc4ca36f02492f2a907b058f..e694068366c76b9df1e60a4cc58232cd41cc5ac7 100644 (file)
@@ -9,11 +9,11 @@
 
 @set RCSID $Id$
 @set EDITION 0.61
-@set VERSION 3.81
-@set UPDATED 02 May 2003
-@set UPDATE-MONTH May 2003
-@comment The ISBN number might need to change on next publication.
-@set ISBN 1-882114-81-7 @c From Brian Youmans <3diff@gnu.org>, 25 Apr 2000
+@set VERSION 3.80
+@set UPDATED 23 Feb 2003
+@set UPDATE-MONTH Feb 2003
+@c ISBN provided by Lisa M. Opus Goldstein <opus@gnu.org>, 5 May 2004
+@set ISBN 1-882114-83-5
 
 @c finalout
 
@@ -6637,7 +6637,8 @@ files := $(shell echo *.c)
 @noindent
 sets @code{files} to the expansion of @samp{*.c}.  Unless @code{make} is
 using a very strange shell, this has the same result as
-@w{@samp{$(wildcard *.c)}}.@refill
+@w{@samp{$(wildcard *.c)}} (as long as at least one @samp{.c} file
+exists).@refill
 
 @node Make Control Functions,  , Shell Function, Functions
 @section Functions That Control Make
@@ -7519,8 +7520,8 @@ retained for compatibility.
 * Implicit Variables::          How to change what predefined rules do.
 * Chained Rules::               How to use a chain of implicit rules.
 * Pattern Rules::               How to define new implicit rules.
-* Last Resort::                 How to defining commands for rules
-                                  which cannot find any.
+* Last Resort::                 How to define commands for rules which
+                                cannot find any.
 * Suffix Rules::                The old-fashioned style of implicit rule.
 * Implicit Rule Search::        The precise algorithm for applying
                                   implicit rules.
@@ -9445,6 +9446,7 @@ Various new built-in implicit rules.
 @item
 The built-in variable @samp{MAKE_VERSION} gives the version number of
 @code{make}.
+@vindex MAKE_VERSION
 @end itemize
 
 @node Missing, Makefile Conventions, Features, Top
@@ -10220,9 +10222,11 @@ AUX =   README COPYING ChangeLog Makefile.in  \
         level-0 level-1 backup-specs testpad.c
 @end group
 
+.PHONY: all
 all:    tar rmt tar.info
 
 @group
+.PHONY: tar
 tar:    $(OBJS)
         $(CC) $(LDFLAGS) -o $@@ $(OBJS) $(LIBS)
 @end group
@@ -10238,6 +10242,7 @@ tar.info: tar.texinfo
 @end group
 
 @group
+.PHONY: install
 install: all
         $(INSTALL) tar $(bindir)/$(binprefix)tar
         -test ! -f rmt || $(INSTALL) rmt /etc/rmt
@@ -10266,21 +10271,25 @@ TAGS:   $(SRCS)
 @end group
 
 @group
+.PHONY: clean
 clean:
         rm -f *.o tar rmt testpad testpad.h core
 @end group
 
 @group
+.PHONY: distclean
 distclean: clean
         rm -f TAGS Makefile config.status
 @end group
 
 @group
+.PHONY: realclean
 realclean: distclean
         rm -f tar.info*
 @end group
 
 @group
+.PHONY: shar
 shar: $(SRCS) $(AUX)
         shar $(SRCS) $(AUX) | compress \
           > tar-`sed -e '/version_string/!d' \
@@ -10290,6 +10299,7 @@ shar: $(SRCS) $(AUX)
 @end group
 
 @group
+.PHONY: dist
 dist: $(SRCS) $(AUX)
         echo tar-`sed \
              -e '/version_string/!d' \
diff --git a/file.c b/file.c
index 0d577d159e6f93ab80f37d9fa39b14542f9e1756..8f895037dc9c660a3cfbb40532585068cc572aaf 100644 (file)
--- a/file.c
+++ b/file.c
@@ -342,6 +342,10 @@ remove_intermediates (int sig)
     if (! HASH_VACANT (*file_slot))
       {
        register struct file *f = *file_slot;
+        /* Is this file eligible for automatic deletion?
+           Yes, IFF: it's marked intermediate, it's not secondary, it wasn't
+           given on the command-line, and it's either a -include makefile or
+           it's not precious.  */
        if (f->intermediate && (f->dontcare || !f->precious)
            && !f->secondary && !f->cmd_target)
          {
@@ -679,7 +683,7 @@ print_file (const void *item)
   if (f->cmd_target)
     puts (_("#  Command-line target."));
   if (f->dontcare)
-    puts (_("#  A default or MAKEFILES makefile."));
+    puts (_("#  A default, MAKEFILES, or -include/sinclude makefile."));
   puts (f->tried_implicit
         ? _("#  Implicit rule search has been done.")
         : _("#  Implicit rule search has not been done."));
index c4d97460d71a99bafaacc197259ea97746b23f65..16deff5cc2bd38b010744343b50a257e86077e83 100644 (file)
@@ -355,7 +355,7 @@ extern int errno;
 
 /* LOAD_AVE_TYPE should only get defined if we're going to use the
    nlist method.  */
-# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL))
+# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) && !defined(__riscos__)
 #  define LOAD_AVE_TYPE double
 # endif
 
diff --git a/job.c b/job.c
index 01539950b26d67783e13446f41ca2b9333a15456..13431d356c851a96539eac573b42db904efbfe23 100644 (file)
--- a/job.c
+++ b/job.c
@@ -63,6 +63,11 @@ int batch_mode_shell = 0;
 char default_shell[] = "";
 int batch_mode_shell = 0;
 
+#elif defined (__riscos__)
+
+char default_shell[] = "";
+int batch_mode_shell = 0;
+
 #else
 
 char default_shell[] = "/bin/sh";
@@ -1725,7 +1730,7 @@ job_next_command (struct child *child)
 static int
 load_too_high (void)
 {
-#if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA)
+#if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA) || defined(__riscos__)
   return 1;
 #else
   static double last_sec;
@@ -1953,7 +1958,9 @@ static void tryToSetupYAst(void) {
        }
        status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
                astHandler,0,0,0,0,0);
-       if (status==SS$_ILLIOFUNC) {
+       if (status==SS$_NORMAL)
+               status= iosb.status;
+        if (status==SS$_ILLIOFUNC || status==SS$_NOPRIV) {
                sys$dassgn(chan);
 #ifdef CTRLY_ENABLED_ANYWAY
                fprintf (stderr,
@@ -1962,9 +1969,8 @@ static void tryToSetupYAst(void) {
                return;
 #endif
        }
-       if (status==SS$_NORMAL)
-               status= iosb.status;
-       if (!(status&SS$_NORMAL)) {
+       else if (!(status&SS$_NORMAL)) {
+               sys$dassgn(chan);
                lib$signal(status);
                return;
        }
@@ -2773,6 +2779,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
                  0 };
   char*  sh_chars;
   char** sh_cmds;
+#elif defined(__riscos__)
+  static char sh_chars[] = "";
+  static char *sh_cmds[] = { 0 };
 #else  /* must be UNIX-ish */
   static char sh_chars[] = "#;\"*?[]&|<>(){}$`^~!";
   static char *sh_cmds[] = { ".", ":", "break", "case", "cd", "continue",
@@ -3295,7 +3304,22 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
            We use line here instead of new_line because we run the shell
            manually.  */
         size_t line_len = strlen (line);
+        char *p = new_line;
+        char *q = new_line;
         memcpy (new_line, line, line_len + 1);
+        /* replace all backslash-newline combination and also following tabs */
+        while (*q != '\0')
+          {
+            if (q[0] == '\\' && q[1] == '\n')
+              {
+                q += 2; /* remove '\\' and '\n' */
+                if (q[0] == '\t')
+                  q++; /* remove 1st tab in the next line */
+              }
+            else
+              *p++ = *q++;
+          }
+        *p = '\0';
 
 # ifndef NO_CMD_DEFAULT
         if (strnicmp (new_line, "echo", 4) == 0
@@ -3338,7 +3362,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
           new_argv[1] = new_argv[0] + sh_len + 1;
           memcpy (new_argv[1], "/c", 3);
           new_argv[2] = new_argv[1] + 3;
-          memcpy (new_argv[2], new_line, line_len);
+          memcpy (new_argv[2], new_line, line_len + 1);
           new_argv[3] = NULL;
         }
       }
diff --git a/main.c b/main.c
index d17e576de83a39fa260e81786a0e0f70db9227bf..13c341568de7a07ad3074aec448d884c6ba9a99f 100644 (file)
--- a/main.c
+++ b/main.c
@@ -259,6 +259,11 @@ int warn_undefined_variables_flag;
    they appear out of date or not.  */
 
 int always_make_flag = 0;
+
+/* If nonzero, we're in the "try to rebuild makefiles" phase.  */
+
+int rebuilding_makefiles = 0;
+
 \f
 /* The usage output.  We write it this way to make life easier for the
    translators, especially those trying to translate to right-to-left
@@ -839,6 +844,7 @@ main (int argc, char **argv, char **envp)
   static char *stdin_nm = 0;
   struct file *f;
   int i;
+  int makefile_status = MAKE_SUCCESS;
   char **p;
   struct dep *read_makefiles;
   PATH_VAR (current_directory);
@@ -1666,6 +1672,7 @@ main (int argc, char **argv, char **envp)
       char **nargv = argv;
       int nargc = argc;
       int orig_db_level = db_level;
+      int status;
 
       if (! ISDB (DB_MAKEFILES))
         db_level = DB_NONE;
@@ -1726,7 +1733,11 @@ main (int argc, char **argv, char **envp)
       /* Set up `MAKEFLAGS' specially while remaking makefiles.  */
       define_makeflags (1, 1);
 
-      switch (update_goal_chain (read_makefiles, 1))
+      rebuilding_makefiles = 1;
+      status = update_goal_chain (read_makefiles);
+      rebuilding_makefiles = 0;
+
+      switch (status)
        {
        case 1:
           /* The only way this can happen is if the user specified -q and asked
@@ -1775,6 +1786,7 @@ main (int argc, char **argv, char **envp)
                         mtime = file_mtime_no_search (d->file);
                         any_remade |= (mtime != NONEXISTENT_MTIME
                                        && mtime != makefile_mtimes[i]);
+                        makefile_status = MAKE_FAILURE;
                       }
                   }
                 else
@@ -1985,13 +1997,13 @@ main (int argc, char **argv, char **envp)
 
     DB (DB_BASIC, (_("Updating goal targets....\n")));
 
-    switch (update_goal_chain (goals, 0))
+    switch (update_goal_chain (goals))
     {
       case -1:
         /* Nothing happened.  */
       case 0:
         /* Updated successfully.  */
-        status = MAKE_SUCCESS;
+        status = makefile_status;
         break;
       case 1:
         /* We are under -q and would run some commands.  */
diff --git a/make.h b/make.h
index ea8f07c9e7d5b77552c49d343d5ccdcb3b7b08af..ce88d5c4afd1b3e2ef131e7e99b7f73ce3d31c88 100644 (file)
--- a/make.h
+++ b/make.h
@@ -496,7 +496,7 @@ extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
 extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
 extern int print_version_flag, print_directory_flag;
 extern int warn_undefined_variables_flag, posix_pedantic, not_parallel;
-extern int clock_skew_detected;
+extern int clock_skew_detected, rebuilding_makefiles;
 
 /* can we run commands via 'sh -c xxx' or must we use batch files? */
 extern int batch_mode_shell;
index 3ada8314d58649079c7d0027bed8430306c1265d..6ed86c103ffab1976de9b675c25e72ef2ddc8859 100644 (file)
@@ -5,6 +5,7 @@
 #  Klaus Kämpf (kkaempf@rmi.de)
 # Modified for version 3.78.1 by Hartmut.Becker@compaq.com.
 # Modified for version 3.80 by zinser@decus.de
+# Modified for version 3.81 by Hartmut Becker
 #
 # GNU Make is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -31,7 +32,7 @@ CP = copy
 #
 
 ifeq ($(CC),cc)
-CFLAGS = $(defines) /include=([],[.glob])/prefix=all/standard=relaxed
+CFLAGS = $(defines) /include=([],[.glob])/prefix=(all,except=(glob,globfree))/standard=relaxed
 else
 CFLAGS = $(defines) /include=([],[.glob])
 endif
@@ -111,7 +112,6 @@ make.exe: $(objs)
 clean:
        $$ purge [...]
        -$(RM) make.exe;,*.obj;
-       -$(RM) *.opt;
        -$(RM) [.glob]*.obj;
 
 # Automatically generated dependencies.
diff --git a/read.c b/read.c
index 1da2eacdf5abfcfc2d537e89b4066dbc60ebae4d..e2ad630cdd93a063ff6adfa8dd63b3e7ba218671 100644 (file)
--- a/read.c
+++ b/read.c
@@ -367,16 +367,14 @@ eval_makefile (char *filename, int flags)
   deps->name = 0;
   deps->file = lookup_file (filename);
   if (deps->file == 0)
-    {
-      deps->file = enter_file (xstrdup (filename));
-      if (flags & RM_DONTCARE)
-       deps->file->dontcare = 1;
-    }
+    deps->file = enter_file (xstrdup (filename));
   if (filename != ebuf.floc.filenm)
     free (filename);
   filename = deps->file->name;
   deps->changed = flags;
   deps->ignore_mtime = 0;
+  if (flags & RM_DONTCARE)
+    deps->file->dontcare = 1;
 
   /* If the makefile can't be found at all, give up entirely.  */
 
index d4a9667c4fc332e62e8c88bc2f1a2c10680f1b8b..6e1436f1a2ec38f0c11ae27a2fa13d2c3353a5e1 100644 (file)
@@ -1,3 +1,54 @@
+This is the VMS version of GNU Make, updated by Hartmut Becker
+
+Changes are based on GNU make 3.80. Latest changes are for OpenVMS/I64
+and new VMS CRTLs.
+
+This version was tested on OpenVMS/I64 V8.2 (field test) with hp C
+X7.1-024 OpenVMS/Alpha V7.3-2 with Compaq C V6.5-001 and OpenVMS/VAX 7.1
+with Compaq C V6.2-003 There are still some warning and informational
+message issued by the compilers.
+
+Build instructions
+Make a 1st version
+       $ @makefile.com
+       $ rena make.exe 1st-make.exe
+Use the 1st version to generate a 2nd version
+       $ mc sys$disk:[]1st-make clean
+       $ mc sys$disk:[]1st-make
+Verify your 2nd version
+       $ rena make.exe 2nd-make.exe
+       $ mc sys$disk:[]2nd-make clean
+       $ mc sys$disk:[]2nd-make
+
+Changes:
+
+. In default.c define variable ARCH as IA64 for VMS on Itanium systems.
+
+. In makefile.vms avoid name collision for glob and globfree.
+
+In newer version of the VMS CRTL there are glob and globfree implemented.
+Compiling and linking may result in
+
+  %ILINK-W-MULDEFLNKG, symbol DECC$GLOBFREE has subsequent linkage definition
+       in module DECC$SHR file SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
+  %ILINK-W-MULDEF, symbol DECC$GLOBFREE multiply defined
+       in module DECC$SHR file SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
+
+linker messages (and similar for DECC$GLOB). The messages just say, that
+globfree is a known CRTL whose name was mapped by the compiler to
+DECC$GLOBFREE.  This is done in glob.c as well, so this name is defined
+twice. One possible solution is to use the VMS versions of glob and
+globfree. However, then the build environment needs to figure out if
+there is a new CRTL supporting these or not. This adds complexity. Even
+more, these functions return VMS file specifications, which is not
+expected by the other make sources. There is a switch at run time (a VMS
+logical DECC$GLOB_UNIX_STYLE), which can be set to get Unix style
+names. This may conflict with other software. The recommended solution
+for this is to set this switch just prior to calling main: in an
+initialization routine. This adds more complexity and more VMS specific
+code. It is easier to tell the compiler NOT to map the routine names
+with a simple change in makefile.vms.
+\f
 This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
 
 It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
index 619aec0e7d3a59fc74a3523224a425d1f765f359..b0c76dc0fdd06a29c86049a65701c1c6c72a7de1 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -73,19 +73,20 @@ static int library_search PARAMS ((char **lib, FILE_TIMESTAMP *mtime_ptr));
 \f
 /* Remake all the goals in the `struct dep' chain GOALS.  Return -1 if nothing
    was done, 0 if all goals were updated successfully, or 1 if a goal failed.
-   If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should
-   be disabled for them unless they were also command-line targets, and we
-   should only make one goal at a time and return as soon as one goal whose
-   `changed' member is nonzero is successfully made.  */
+
+   If rebuilding_makefiles is nonzero, these goals are makefiles, so -t, -q,
+   and -n should be disabled for them unless they were also command-line
+   targets, and we should only make one goal at a time and return as soon as
+   one goal whose `changed' member is nonzero is successfully made.  */
 
 int
-update_goal_chain (struct dep *goals, int makefiles)
+update_goal_chain (struct dep *goals)
 {
   int t = touch_flag, q = question_flag, n = just_print_flag;
   unsigned int j = job_slots;
   int status = -1;
 
-#define        MTIME(file) (makefiles ? file_mtime_no_search (file) \
+#define        MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
                     : file_mtime (file))
 
   /* Duplicate the chain so we can remove things from it.  */
@@ -135,7 +136,7 @@ update_goal_chain (struct dep *goals, int makefiles)
              unsigned int ocommands_started;
              int x;
              check_renamed (file);
-             if (makefiles)
+             if (rebuilding_makefiles)
                {
                  if (file->cmd_target)
                    {
@@ -152,7 +153,7 @@ update_goal_chain (struct dep *goals, int makefiles)
                 actually run.  */
              ocommands_started = commands_started;
 
-             x = update_file (file, makefiles ? 1 : 0);
+             x = update_file (file, rebuilding_makefiles ? 1 : 0);
              check_renamed (file);
 
              /* Set the goal's `changed' flag if any commands were started
@@ -176,7 +177,7 @@ update_goal_chain (struct dep *goals, int makefiles)
                          matter how much more we run, since we already know
                          the answer to return.  */
                       stop = (!keep_going_flag && !question_flag
-                              && !makefiles);
+                              && !rebuilding_makefiles);
                     }
                   else
                     {
@@ -192,10 +193,10 @@ update_goal_chain (struct dep *goals, int makefiles)
                              as a command-line target), don't change STATUS.
                              If STATUS is changed, we will get re-exec'd, and
                              enter an infinite loop.  */
-                          if (!makefiles
+                          if (!rebuilding_makefiles
                               || (!just_print_flag && !question_flag))
                             status = 0;
-                          if (makefiles && file->dontcare)
+                          if (rebuilding_makefiles && file->dontcare)
                             /* This is a default makefile; stop remaking.  */
                             stop = 1;
                         }
@@ -218,7 +219,7 @@ update_goal_chain (struct dep *goals, int makefiles)
              /* If we have found nothing whatever to do for the goal,
                 print a message saying nothing needs doing.  */
 
-             if (!makefiles
+             if (!rebuilding_makefiles
                  /* If the update_status is zero, we updated successfully
                     or not at all.  G->changed will have been set above if
                     any commands were actually started for this goal.  */
@@ -257,7 +258,7 @@ update_goal_chain (struct dep *goals, int makefiles)
         considered = !considered;
     }
 
-  if (makefiles)
+  if (rebuilding_makefiles)
     {
       touch_flag = t;
       question_flag = q;
@@ -321,19 +322,44 @@ update_file (struct file *file, unsigned int depth)
 
   /* Process the remaining rules in the double colon chain so they're marked
      considered.  Start their prerequisites, too.  */
-  for (; f != 0 ; f = f->prev)
-    {
-      struct dep *d;
+  if (file->double_colon)
+    for (; f != 0 ; f = f->prev)
+      {
+        struct dep *d;
 
-      f->considered = considered;
+        f->considered = considered;
 
-      for (d = f->deps; d != 0; d = d->next)
-        status |= update_file (d->file, depth + 1);
-    }
+        for (d = f->deps; d != 0; d = d->next)
+          status |= update_file (d->file, depth + 1);
+      }
 
   return status;
 }
 \f
+/* Show a message stating the target failed to build.  */
+
+static void
+complain (const struct file *file)
+{
+  const char *msg_noparent
+    = _("%sNo rule to make target `%s'%s");
+  const char *msg_parent
+    = _("%sNo rule to make target `%s', needed by `%s'%s");
+
+  if (!keep_going_flag)
+    {
+      if (file->parent == 0)
+        fatal (NILF, msg_noparent, "", file->name, "");
+
+      fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
+    }
+
+  if (file->parent == 0)
+    error (NILF, msg_noparent, "*** ", file->name, ".");
+  else
+    error (NILF, msg_parent, "*** ", file->name, file->parent->name, ".");
+}
+
 /* Consider a single `struct file' and update it as appropriate.  */
 
 static int
@@ -353,6 +379,17 @@ update_file_1 (struct file *file, unsigned int depth)
        {
          DBF (DB_VERBOSE,
                _("Recently tried and failed to update file `%s'.\n"));
+
+          /* If the file we tried to make is marked dontcare then no message
+             was printed about it when it failed during the makefile rebuild.
+             If we're trying to build it again in the normal rebuild, print a
+             message now.  */
+          if (file->dontcare && !rebuilding_makefiles)
+            {
+              file->dontcare = 0;
+              complain (file);
+            }
+
          return file->update_status;
        }
 
@@ -1008,28 +1045,9 @@ remake_file (struct file *file)
        file->update_status = 0;
       else
         {
-          const char *msg_noparent
-            = _("%sNo rule to make target `%s'%s");
-          const char *msg_parent
-            = _("%sNo rule to make target `%s', needed by `%s'%s");
-
           /* This is a dependency file we cannot remake.  Fail.  */
-          if (!keep_going_flag && !file->dontcare)
-            {
-              if (file->parent == 0)
-                fatal (NILF, msg_noparent, "", file->name, "");
-
-              fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
-            }
-
-          if (!file->dontcare)
-            {
-              if (file->parent == 0)
-                error (NILF, msg_noparent, "*** ", file->name, ".");
-              else
-                error (NILF, msg_parent, "*** ",
-                       file->name, file->parent->name, ".");
-            }
+          if (!rebuilding_makefiles || !file->dontcare)
+            complain (file);
           file->update_status = 2;
         }
     }
index 4389d4349f26fe182eecc65abb7501c62712eedc..8452c6b56e9534f3be7acc8b042c6867c67e1f5b 100755 (executable)
@@ -48,66 +48,100 @@ sub valid_option
    return 0;
 }
 
-sub run_make_with_options
+
+# This is an "all-in-one" function.  Arguments are as follows:
+#
+#  [0] (string):  The makefile to be tested.
+#  [1] (string):  Arguments to pass to make.
+#  [2] (string):  Answer we should get back.
+#  [3] (integer): Exit code we expect.  A missing code means 0 (success)
+
+sub run_make_test
 {
-   local ($filename,$options,$logname,$expected_code) = @_;
-   local($code);
-   local($command) = $make_path;
+  local ($makestring, $options, $answer, $err_code) = @_;
 
-   $expected_code = 0 unless defined($expected_code);
+  if (! defined($makefile)) {
+    $makefile = &get_tmpfile();
+  }
 
-   if ($filename)
-   {
-      $command .= " -f $filename";
-   }
+  # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
+  # make in both $makestring and $answer.
 
-   if ($options)
-   {
-      $command .= " $options";
-   }
+  $makestring =~ s/#MAKEFILE#/$makefile/g;
+  $makestring =~ s/#MAKE#/$make_name/g;
 
-   if ($valgrind) {
-     print VALGRIND "\n\nExecuting: $command\n";
-   }
+  $answer =~ s/#MAKEFILE#/$makefile/g;
+  $answer =~ s/#MAKE#/$make_name/g;
 
-   $code = &run_command_with_output($logname,$command);
+  open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
+  print MAKEFILE $makestring, "\n";
+  close(MAKEFILE) || die "Failed to write $makefile: $!\n";
 
-   # Check to see if we have Purify errors.  If so, keep the logfile.
-   # For this to work you need to build with the Purify flag -exit-status=yes
+  &run_make_with_options($makefile, $options, &get_logfile(0), $err_code);
+  &compare_output($answer, &get_logfile(1));
 
-   if ($pure_log && -f $pure_log) {
-     if ($code & 0x7000) {
-       $code &= ~0x7000;
+  $makefile = undef;
+}
 
-       # If we have a purify log, save it
-       $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
-       print("Renaming purify log file to $tn\n") if $debug;
-       rename($pure_log, "$tn")
-        || die "Can't rename $log to $tn: $!\n";
-       ++$purify_errors;
-     }
-     else {
-       unlink($pure_log);
-     }
-   }
+# The old-fashioned way...
+sub run_make_with_options {
+  local ($filename,$options,$logname,$expected_code) = @_;
+  local($code);
+  local($command) = $make_path;
 
-   if ($code != $expected_code)
-   {
-      print "Error running $make_path ($code): $command\n";
-      $test_passed = 0;
-      # If it's a SIGINT, stop here
-      if ($code & 127) {
-        print STDERR "\nCaught signal ".($code & 127)."!\n";
-        exit($code);
-      }
-      return 0;
-   }
+  $expected_code = 0 unless defined($expected_code);
 
-   if ($profile & $vos)
-   {
-      system "add_profile $make_path";
-   }
-1;
+  # Reset to reflect this one test.
+  $test_passed = 1;
+
+  if ($filename) {
+    $command .= " -f $filename";
+  }
+
+  if ($options) {
+    $command .= " $options";
+  }
+
+  if ($valgrind) {
+    print VALGRIND "\n\nExecuting: $command\n";
+  }
+
+  $code = &run_command_with_output($logname,$command);
+
+  # Check to see if we have Purify errors.  If so, keep the logfile.
+  # For this to work you need to build with the Purify flag -exit-status=yes
+
+  if ($pure_log && -f $pure_log) {
+    if ($code & 0x7000) {
+      $code &= ~0x7000;
+
+      # If we have a purify log, save it
+      $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
+      print("Renaming purify log file to $tn\n") if $debug;
+      rename($pure_log, "$tn")
+        || die "Can't rename $log to $tn: $!\n";
+      ++$purify_errors;
+    } else {
+      unlink($pure_log);
+    }
+  }
+
+  if ($code != $expected_code) {
+    print "Error running $make_path (expected $expected_code; got $code): $command\n";
+    $test_passed = 0;
+    # If it's a SIGINT, stop here
+    if ($code & 127) {
+      print STDERR "\nCaught signal ".($code & 127)."!\n";
+      exit($code);
+    }
+    return 0;
+  }
+
+  if ($profile & $vos) {
+    system "add_profile $make_path";
+  }
+
+  1;
 }
 
 sub print_usage
index ed1e862264475ad6920c5617bcee01343894891b..2e366cdf4441eea8a6cf24d6568b467d2ab82be6 100644 (file)
@@ -54,13 +54,10 @@ $answer = "echo This makefile did not clean the dir... good\n"
 # -------
 
 &run_make_with_options($makefile,"clean",&get_logfile,0);
-$answer = "";
-&compare_output($answer,&get_logfile(1));
-
-if (-f $example)
-{
-   $test_passed = 0;
+if (-f $example) {
+  $test_passed = 0;
 }
+&compare_output('',&get_logfile(1));
 
 # TEST #3
 # -------
index a39064f649932dc639e3a68393abd4719025147f..253f50f0b122f34eb3754022815f99280069d0b9 100644 (file)
@@ -52,6 +52,13 @@ $answer = "$delete_command cleanit\n"
 
 &run_make_with_options($makefile,"",&get_logfile);
 
+# If make acted as planned, it should ignore the error from the first
+# command in the target and execute the second which deletes the file "foo"
+# This file, therefore, should not exist if the test PASSES.
+if (-f "foo") {
+  $test_passed = 0;
+}
+
 # The output for this on VOS is too hard to replicate, so we only check it
 # on unix.
 if (!$vos)
@@ -59,14 +66,6 @@ if (!$vos)
    &compare_output($answer,&get_logfile(1));
 }
 
-# If make acted as planned, it should ignore the error from the first
-# command in the target and execute the second which deletes the file "foo"
-# This file, therefore, should not exist if the test PASSES.
-if (-f "foo")
-{
-   $test_passed = 0;
-}
-
 
 &touch("foo");
 
@@ -80,14 +79,12 @@ $answer = "$delete_command cleanit\n"
 
 &run_make_with_options($makefile,"clean2 -i",&get_logfile);
 
-if (!$vos)
-{
-   &compare_output($answer,&get_logfile(1));
+if (-f "foo") {
+  $test_passed = 0;
 }
 
-if (-f "foo")
-{
-   $test_passed = 0;
+if (!$vos) {
+   &compare_output($answer,&get_logfile(1));
 }
 
 1;
index 60f4482db4ed8fa8bc7a28f06e9ec35c92f52700..5f20ad87a738d25d4a6a80b6d4d0ea5def9f9fef 100644 (file)
@@ -2,7 +2,8 @@
 
 $description = "Test various forms of the GNU make `include' command.";
 
-$details = "Test include, -include, sinclude and various regressions involving them.
+$details = "\
+Test include, -include, sinclude and various regressions involving them.
 Test extra whitespace at the end of the include, multiple -includes and
 sincludes (should not give an error) and make sure that errors are reported
 for targets that were also -included.";
@@ -46,16 +47,36 @@ $answer = "There should be no errors for this makefile.\n";
 $answer = "This is another included makefile\n";
 &compare_output($answer, &get_logfile(1));
 
+$makefile = undef;
+
 # Try to build the "error" target; this will fail since we don't know
 # how to create makeit.mk, but we should also get a message (even though
 # the -include suppressed it during the makefile read phase, we should
 # see one during the makefile run phase).
 
-# The fix to this caused more problems than the error, so I removed it.
-# pds -- 22 Jan 2000
+run_make_test
+  ('
+-include foo.mk
+error: foo.mk ; @echo $@
+',
+   '',
+   "#MAKE#: *** No rule to make target `foo.mk', needed by `error'.  Stop.\n",
+   512
+  );
+
+# Make sure that target-specific variables don't impact things.  This could
+# happen because a file record is created when a target-specific variable is
+# set.
+
+run_make_test
+  ('
+bar.mk: foo := baz
+-include bar.mk
+hello: ; @echo hello
+',
+   '',
+   "hello\n"
+  );
 
-#&run_make_with_options($makefile, "error", &get_logfile, 512);
-#$answer = "$make_name: *** No rule to make target `makeit.mk', needed by `error'.\n";
-#&compare_output($answer, &get_logfile(1));
 
 1;
index ac0d53899a6f0fef8de5f493d2dd82925ea41e84..82a7253572fb4562d95f2c70d6569d64ee767c32 100644 (file)
@@ -144,4 +144,15 @@ $answer = "touch baz\n";
 
 unlink(qw(foo.w foo.x baz));
 
+# TEST #9 -- make sure that $< is set correctly in the face of order-only
+# prerequisites in pattern rules.
+
+run_make_test('
+%r: | baz ; @echo $< $^ $|
+bar: foo
+foo:;@:
+baz:;@:
+', '', "foo foo baz\n");
+
+
 1;
index 0f79acc4e579b08eb2a26bf7eacae5f4a5e1874c..5e5a5ff660d5e73ddd04ac942a5a124044fd492e 100644 (file)
@@ -85,13 +85,12 @@ else
 
 &run_make_with_options($makefile,"clean",&get_logfile);
 
-&compare_output($answer,&get_logfile(1));
-
-if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for"))
-{
+if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) {
    $test_passed = 0;
 }
 
+&compare_output($answer,&get_logfile(1));
+
 
 1;
 
index 3f2b3a13bfc793fcfba47c252359055063f9fe16..f31238f18675e159fb60e2d29240a5087873c470 100644 (file)
@@ -33,6 +33,10 @@ chdir $workdir;
 $wpath = &get_this_pwd;
 chdir $pwd;
 
+if (-f $example) {
+  $test_passed = 0;
+}
+
 # Create the answer to what should be produced by this Makefile
 $answer = "$make_name: Entering directory `$wpath'\n"
         . "$delete_command EXAMPLE_FILE\n"
@@ -40,9 +44,4 @@ $answer = "$make_name: Entering directory `$wpath'\n"
 
 &compare_output($answer,&get_logfile(1));
 
-if (-f $example)
-{
-   $test_passed = 0;
-}
-
 1;
index fe5689e34ecafdd8eadb463ae740222c0d9153ef..d87a7861aecf32bf423f9a5368d0773fb28da2c9 100644 (file)
@@ -97,4 +97,18 @@ $make_name: Target `all' not remade because of errors.\n";
 
 &compare_output($answer, &get_logfile(1));
 
+# TEST -- make sure we keep the error code if we can't create an included
+# makefile.
+
+run_make_test('all: ; @echo hi
+include ifile
+ifile: no-such-file; @false
+',
+              '-k',
+              "#MAKEFILE#:2: ifile: No such file or directory
+#MAKE#: *** No rule to make target `no-such-file', needed by `ifile'.
+#MAKE#: Failed to remake makefile `ifile'.
+hi\n",
+              512);
+
 1;
index 90ee48d66e2f0faec2637a0e0641f35f58015093..befb326d3d01bdd79da46b9ec1d9d9d5aa0f1637 100644 (file)
@@ -1,4 +1,4 @@
-$description = "The following tests rules without Commands or Dependencies."; 
+$description = "The following tests rules without Commands or Dependencies.";
 
 $details = "If the rule ...\n";
 
@@ -17,7 +17,7 @@ open(MAKEFILE,"> $makefile");
 
 print MAKEFILE ".IGNORE :\n";
 print MAKEFILE "clean: FORCE\n";
-print MAKEFILE "\t$delete_command clean\n"; 
+print MAKEFILE "\t$delete_command clean\n";
 print MAKEFILE "FORCE:\n";
 
 # END of Contents of MAKEFILE
@@ -26,20 +26,15 @@ close(MAKEFILE);
 
 
 # Create a file named "clean".  This is the same name as the target clean
-# and tricks the target into thinking that it is up to date.  (Unless you 
+# and tricks the target into thinking that it is up to date.  (Unless you
 # use the .PHONY target.
 &touch("clean");
 
 $answer = "$delete_command clean\n";
 &run_make_with_options($makefile,"clean",&get_logfile);
 
-&compare_output($answer,&get_logfile(1)); 
+&compare_output($answer,&get_logfile(1));
 
-if (-f $example)
-{
-   $test_passed = 0;
-}
 1;
 
 
index 14d5ae1cf0984c136848c9e26991864d22e068ab..dd46b3fe441db5ae1f69ffdf53e3a1d9acc23d1c 100644 (file)
@@ -27,7 +27,7 @@ print MAKEFILE ".PHONY : clean \n";
 print MAKEFILE "all: \n";
 print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n";
 print MAKEFILE "clean: \n";
-print MAKEFILE "\t$delete_command $example clean\n"; 
+print MAKEFILE "\t$delete_command $example clean\n";
 
 # END of Contents of MAKEFILE
 
@@ -36,20 +36,19 @@ close(MAKEFILE);
 &touch($example);
 
 # Create a file named "clean".  This is the same name as the target clean
-# and tricks the target into thinking that it is up to date.  (Unless you 
+# and tricks the target into thinking that it is up to date.  (Unless you
 # use the .PHONY target.
 &touch("clean");
 
 $answer = "$delete_command $example clean\n";
 &run_make_with_options($makefile,"clean",&get_logfile);
 
-&compare_output($answer,&get_logfile(1)); 
-
-if (-f $example)
-{
-   $test_passed = 0;
+if (-f $example) {
+  $test_passed = 0;
 }
+
+&compare_output($answer,&get_logfile(1));
+
 1;
 
 
index 375cad4913b9c1a75618e319eedcbc7581cc95b4..5f9a1dbb2d0474a19974b4fdfb90f78c9eff5516 100644 (file)
@@ -22,7 +22,7 @@ open(MAKEFILE,"> $makefile");
 
 print MAKEFILE ".SILENT : clean\n";
 print MAKEFILE "clean: \n";
-print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; 
+print MAKEFILE "\t$delete_command EXAMPLE_FILE\n";
 
 # END of Contents of MAKEFILE
 
@@ -32,13 +32,11 @@ close(MAKEFILE);
 
 $answer = "";
 &run_make_with_options($makefile,"clean",&get_logfile,0);
-
-&compare_output($answer,&get_logfile(1)); 
-if (-f $example)
-{
-   $test_passed = 0;
+if (-f $example) {
+  $test_passed = 0;
 }
+&compare_output($answer,&get_logfile(1));
+
 1;
 
 
index 69f4fd1b709c458d548f108caa0d5efab3c8da9c..b32c976702ba902f7bd1223a5af418bfa782ba94 100644 (file)
@@ -33,11 +33,10 @@ $answer = "This makefile did not clean the dir... good\n";
 
 $answer = "$delete_command $example\n";
 &run_make_with_options($makefile,"clean",&get_logfile,0);
-
-&compare_output($answer,&get_logfile(1)) || &error ("abort");
 if (-f $example) {
-   $test_passed = 0;
+  $test_passed = 0;
 }
+&compare_output($answer,&get_logfile(1)) || &error ("abort");
 
 1;
 
index 58c86552e45c2d83bb7dd51c2bc6aeb0f81999f3..77b355c96d30954e529cb4d3f38f986ac2a4ee8b 100644 (file)
@@ -4,12 +4,7 @@ $description = "Test special GNU make variables.";
 
 $details = "";
 
-$makefile2 = &get_tmpfile;
-
-
-open(MAKEFILE, "> $makefile");
-
-print MAKEFILE <<'EOF';
+&run_make_test('
 
 X1 := $(sort $(filter FOO BAR,$(.VARIABLES)))
 
@@ -23,21 +18,12 @@ all:
        @echo X1 = $(X1)
        @echo X2 = $(X2)
        @echo LAST = $(sort $(filter FOO BAR,$(.VARIABLES)))
-
-EOF
-
-close(MAKEFILE);
-
-# TEST #1
-# -------
-
-&run_make_with_options($makefile, "", &get_logfile);
-$answer = "X1 =\nX2 = FOO\nLAST = BAR FOO\n";
-&compare_output($answer, &get_logfile(1));
-
+',
+               '', "X1 =\nX2 = FOO\nLAST = BAR FOO\n");
 
 
 
+# $makefile2 = &get_tmpfile;
 # open(MAKEFILE, "> $makefile2");
 
 # print MAKEFILE <<'EOF';
index 0ddb8842c57ad9a1181b1e17a7057c4902438a8c..0bca669b81893ec7d7d2bbbe5ddd2afe5f7d80b5 100644 (file)
@@ -28,6 +28,10 @@ $tests_run = 0;
 # The number of tests in this category that have passed
 $tests_passed = 0;
 
+
+# Yeesh.  This whole test environment is such a hack!
+$test_passed = 1;
+
 sub toplevel
 {
   # Get a clean environment
@@ -376,7 +380,7 @@ sub run_each_test
   foreach $testname (sort @TESTS)
   {
     ++$categories_run;
-    $passed = 1;       # reset by test on failure
+    $suite_passed = 1;       # reset by test on failure
     $num_of_logfiles = 0;
     $num_of_tmpfiles = 0;
     $description = "";
@@ -423,7 +427,7 @@ sub run_each_test
     # How did it go?
     if (!defined($code))
     {
-      $passed = 0;
+      $suite_passed = 0;
       if (length ($@))
       {
         warn "\n*** Test died ($testname): $@\n";
@@ -434,14 +438,14 @@ sub run_each_test
       }
     }
     elsif ($code == -1) {
-      $passed = 0;
+      $suite_passed = 0;
     }
     elsif ($code != 1 && $code != -1) {
-      $passed = 0;
+      $suite_passed = 0;
       warn "\n*** Test returned $code\n";
     }
 
-    if ($passed) {
+    if ($suite_passed) {
       ++$categories_passed;
       $status = "ok     ($tests_passed passed)";
       for ($i = $num_of_tmpfiles; $i; $i--)
@@ -608,10 +612,7 @@ sub compare_output
   local($answer,$logfile) = @_;
   local($slurp);
 
-  if ($debug)
-  {
-    print "Comparing Output ........ ";
-  }
+  print "Comparing Output ........ " if $debug;
 
   $slurp = &read_file_into_string ($logfile);
 
@@ -622,34 +623,28 @@ sub compare_output
 
   ++$tests_run;
 
-  if ($slurp eq $answer)
+  if ($slurp eq $answer && $test_passed)
   {
-    if ($debug)
-    {
-      print "ok\n";
-    }
+    print "ok\n" if $debug;
     ++$tests_passed;
     return 1;
   }
-  else
-  {
-    if ($debug)
-    {
-      print "DIFFERENT OUTPUT\n";
-    }
-    $passed = 0;
+
+  if ($slurp ne $answer) {
+    print "DIFFERENT OUTPUT\n" if $debug;
+
     &create_file (&get_basefile, $answer);
 
-    if ($debug)
-    {
-      print "\nCreating Difference File ...\n";
-    }
+    print "\nCreating Difference File ...\n" if $debug;
+
     # Create the difference file
     local($command) = "diff -c " . &get_basefile . " " . $logfile;
     &run_command_with_output(&get_difffile,$command);
 
-    return 0;
   }
+
+  $suite_passed = 0;
+  return 0;
 }
 
 sub read_file_into_string