Checkpoint changes. Bug fixes, mostly.
authorPaul Smith <psmith@gnu.org>
Sat, 3 Oct 1998 05:39:55 +0000 (05:39 +0000)
committerPaul Smith <psmith@gnu.org>
Sat, 3 Oct 1998 05:39:55 +0000 (05:39 +0000)
38 files changed:
ChangeLog
GNUmakefile
acconfig.h
acinclude.m4
amiga.c
ar.c
arscan.c
commands.c
commands.h
config.ami.template
config.h-vms.template
config.h.W32.template
configure.in
default.c
dep.h
expand.c
file.c
filedef.h
function.c
getloadavg.c
glob/ChangeLog
implicit.c
job.c
job.h
main.c
make.h
make.texinfo
misc.c
read.c
remake.c
remote-cstms.c
rule.c
rule.h
variable.c
variable.h
vpath.c
w32/subproc/NMakefile
w32/subproc/sub_proc.c

index c3ffc61..bf59080 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,225 @@
+1998-09-21  Paul D. Smith  <psmith@gnu.org>
+
+       * job.c (construct_command_argv_internal): Only add COMMAND.COM
+       "@echo off" line for non-UNIXy shells.
+
+1998-09-09  Paul D. Smith  <psmith@gnu.org>
+
+       * w32/subproc/sub_proc.c: Add in missing HAVE_MKS_SHELL tests.
+
+1998-09-04  Paul D. Smith  <psmith@gnu.org>
+
+       * read.c (read_makefile): If we hit the "missing separator" error,
+       check for the common case of 8 spaces instead of a TAB and give an
+       extra comment to help people out.
+
+1998-08-29  Paul Eggert  <eggert@twinsun.com>
+
+       * configure.in (AC_STRUCT_ST_MTIM_NSEC):
+       Renamed from AC_STRUCT_ST_MTIM.
+
+       * acinclude.m4 (AC_STRUCT_ST_MTIM_NSEC):  Likewise.
+       Port to UnixWare 2.1.2 and pedantic Solaris 2.6.
+
+       * acconfig.h (ST_MTIM_NSEC):
+       Renamed from HAVE_ST_MTIM, with a new meaning.
+
+       * filedef.h (FILE_TIMESTAMP_FROM_S_AND_NS):
+       Use new ST_MTIM_NSEC macro.
+
+1998-08-26  Paul D. Smith  <psmith@gnu.org>
+
+       * remake.c (check_dep): For any intermediate file, not just
+       secondary ones, try implicit and default rules if no explicit
+       rules are given.  I'm not sure why this was restricted to
+       secondary rules in the first place.
+
+1998-08-24  Paul D. Smith  <psmith@gnu.org>
+
+       * make.texinfo (Special Targets): Update documentation for
+       .INTERMEDIATE: if used with no dependencies, then it does nothing;
+       old docs said it marked all targets as intermediate, which it
+       didn't... and which would be silly :).
+
+       * implicit.c (pattern_search): If we find a dependency in our
+       internal tables, make sure it's not marked intermediate before
+       accepting it as a found_file[].
+
+1998-08-20  Paul D. Smith  <psmith@gnu.org>
+
+       * ar.c (ar_glob): Use existing alpha_compare() with qsort.
+       (ar_glob_alphacompare): Remove it.
+
+       Modify Paul Eggert's patch so we don't abandon older systems:
+
+       * configure.in: Warn the user if neither waitpid() nor wait3() is
+       available.
+
+       * job.c (WAIT_NOHANG): Don't syntax error on ancient hosts.
+       (child_handler, dead_children): Define these if WAIT_NOHANG is not
+       available.
+       (reap_children): Only track the dead_children count if no
+       WAIT_NOHANG.  Otherwise, it's a boolean.
+
+       * main.c (main): Add back signal handler if no WAIT_NOHANG is
+       available; only use default signal handler if it is.
+
+1998-08-20  Paul Eggert  <eggert@twinsun.com>
+
+       Install a more robust signal handling mechanism for systems which
+       support it.
+
+       * job.c (WAIT_NOHANG): Define to a syntax error if our host
+       is truly ancient; this should never happen.
+       (child_handler, dead_children): Remove.
+       (reap_children): Don't try to keep separate track of how many
+       dead children we have, as this is too bug-prone.
+       Just ask the OS instead.
+       (vmsHandleChildTerm): Fix typo in error message; don't mention
+       child_handler.
+
+       * main.c (main): Make sure we're not ignoring SIGCHLD/SIGCLD;
+       do this early, before we could possibly create a subprocess.
+       Just use the default behavior; don't have our own handler.
+
+1998-08-18  Eli Zaretskii  <eliz@is.elta.co.il>
+
+       * read.c (read_makefile) [__MSDOS__, WINDOWS32]: Add code to
+       recognize library archive members when dealing with drive spec
+       mess.  Discovery and initial fix by George Racz <gracz@mincom.com>.
+
+1998-08-18  Paul D. Smith  <psmith@gnu.org>
+
+       * configure.in: Check for stdlib.h explicitly (some hosts have it
+       but don't have STDC_HEADERS).
+       * make.h: Use HAVE_STDLIB_H.  Clean up some #defines.
+       * config.ami: Re-compute based on new config.h.in contents.
+       * config.h-vms: Ditto.
+       * config.h.W32: Ditto.
+       * configh.dos: Ditto.
+
+1998-08-17  Paul D. Smith  <psmith@gnu.org>
+
+       * make.texinfo: Added copyright year to the printed copy.  Removed
+       the price from the manual.  Change the top-level reference to
+       running make to be "Invoking make" instead of "make Invocation",
+       to comply with GNU doc standards.
+
+       * make.h (__format__, __printf__): Added support for these in
+       __attribute__ macro.
+       (message, error, fatal): Use ... prototype form under __STDC__.
+       Add __format__ attributes for printf-style functions.
+
+       * configure.in (AC_FUNC_VPRINTF): Check for vprintf()/_doprnt().
+
+       * misc.c(message, error, fatal): Add preprocessor stuff to enable
+       creation of variable-argument functions with appropriate
+       prototypes, that works with ANSI, pre-ANSI, varargs.h, stdarg.h,
+       v*printf(), _doprnt(), or none of the above.  Culled from GNU
+       fileutils and slightly modified.
+       (makefile_error, makefile_error): Removed (merged into error() and
+       fatal(), respectively).
+       * amiga.c: Use them.
+       * ar.c: Use them.
+       * arscan.c: Use them.
+       * commands.c: Use them.
+       * expand.c: Use them.
+       * file.c: Use them.
+       * function.c: Use them.
+       * job.c: Use them.
+       * main.c: Use them.
+       * misc.c: Use them.
+       * read.c: Use them.
+       * remake.c: Use them.
+       * remote-cstms.c: Use them.
+       * rule.c: Use them.
+       * variable.c: Use them.
+
+       * make.h (struct floc): New structure to store file location
+       information.
+       * commands.h (struct commands): Use it.
+       * variable.c (try_variable_definition): Use it.
+       * commands.c: Use it.
+       * default.c: Use it.
+       * file.c: Use it.
+       * function.c: Use it.
+       * misc.c: Use it.
+       * read.c: Use it.
+       * rule.c: Use it.
+
+1998-08-16  Paul Eggert  <eggert@twinsun.com>
+
+       * filedef.h (FILE_TIMESTAMP_PRINT_LEN_BOUND): Add 10, for nanoseconds.
+
+1998-08-16  Paul Eggert  <eggert@twinsun.com>
+
+       * filedef.h (FLOOR_LOG2_SECONDS_PER_YEAR): New macro.
+       (FILE_TIMESTAMP_PRINT_LEN_BOUND): Tighten bound, and try to
+       make it easier to understand.
+
+1998-08-14  Paul D. Smith  <psmith@gnu.org>
+
+       * read.c (read_makefile): We've already unquoted any colon chars
+       by the time we're done reading the targets, so arrange for
+       parse_file_seq() on the target list to not do so again.
+
+1998-08-05  Paul D. Smith  <psmith@gnu.org>
+
+       * configure.in: Added glob/configure.in data.  We'll have the glob
+       code include the regular make config.h, rather than creating its
+       own.
+
+       * getloadavg.c (main): Change return type to int.
+
+1998-08-01  Paul Eggert  <eggert@twinsun.com>
+
+       * job.c (reap_children): Ignore unknown children.
+
+1998-07-31  Paul D. Smith  <psmith@gnu.org>
+
+       * make.h, filedef.h, dep.h, rule.h, commands.h, remake.c:
+       Add prototypes for functions.  Some prototypes needed to be moved
+       in order to get #include order reasonable.
+
+1998-07-30  Paul D. Smith  <psmith@gnu.org>
+
+       * make.h: Added MIN/MAX.
+       * filedef.h: Use them; remove FILE_TIMESTAMP_MIN.
+
+1998-07-30  Paul Eggert  <eggert@twinsun.com>
+
+        Add support for sub-second timestamp resolution on hosts that
+        support it (just Solaris 2.6, so far).
+
+       * acconfig.h (HAVE_ST_MTIM, uintmax_t): New undefs.
+       * acinclude.m4 (jm_AC_HEADER_INTTYPES_H, AC_STRUCT_ST_MTIM,
+        jm_AC_TYPE_UINTMAX_T): New defuns.
+       * commands.c (delete_target): Convert file timestamp to
+        seconds before comparing to archive timestamp.  Extract mod
+        time from struct stat using FILE_TIMESTAMP_STAT_MODTIME.
+       * configure.in (C_STRUCT_ST_MTIM, jm_AC_TYPE_UINTMAX_T): Add.
+        (AC_CHECK_LIB, AC_CHECK_FUNCS): Add clock_gettime.
+       * file.c (snap_deps): Use FILE_TIMESTAMP, not time_t.
+        (file_timestamp_now, file_timestamp_sprintf): New functions.
+        (print_file): Print file timestamps as FILE_TIMESTAMP, not
+        time_t.
+       * filedef.h: Include <inttypes.h> if available and if HAVE_ST_MTIM.
+        (FILE_TIMESTAMP, FILE_TIMESTAMP_STAT_MODTIME, FILE_TIMESTAMP_MIN,
+        FILE_TIMESTAMPS_PER_S, FILE_TIMESTAMP_FROM_S_AND_NS,
+        FILE_TIMESTAMP_DIV, FILE_TIMESTAMP_MOD, FILE_TIMESTAMP_S,
+        FILE_TIMESTAMP_NS, FILE_TIMESTAMP_PRINT_LEN_BOUND): New macros.
+        (file_timestamp_now, file_timestamp_sprintf): New decls.
+        (struct file.last_mtime, f_mtime, file_mtime_1, NEW_MTIME):
+        time_t -> FILE_TIMESTAMP.
+       * implicit.c (pattern_search): Likewise.
+       * vpath.c (vpath_search, selective_vpath_search): Likewise.
+       * main.c (main): Likewise.
+       * remake.c (check_dep, name_mtime, library_search, f_mtime): Likewise.
+        (f_mtime): Use file_timestamp_now instead of `time'.
+        Print file timestamp with file_timestamp_sprintf.
+       * vpath.c (selective_vpath_search): Extract file time stamp from
+        struct stat with FILE_TIMESTAMP_STAT_MODTIME.
+
 1998-07-28  Paul D. Smith  <psmith@gnu.org>
 
        * Version 3.77 released.
 
 1998-06-19  Eli Zaretskii  <eliz@is.elta.co.il>
 
-        * job.c (start_job_command): Reset execute_by_shell after an empty
+       * job.c (start_job_command): Reset execute_by_shell after an empty
         command was skipped.
 
 1998-06-09  Paul D. Smith  <psmith@gnu.org>
@@ -503,7 +725,7 @@ Thu Aug 28 17:04:47 1997  Paul D. Smith  <psmith@baynetworks.com>
 
 Wed Aug 27 17:09:32 1997  Paul D. Smith  <psmith@baynetworks.com>
 
-        * Version 3.75.92
+       * Version 3.75.92
 
 Tue Aug 26 11:59:15 1997  Paul D. Smith  <psmith@baynetworks.com>
 
@@ -538,16 +760,16 @@ Fri Aug 22 1997  Eli Zaretskii  <eliz@is.elta.co.il>
 
 Sat Aug 16 00:56:15 1997  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
-        * vmsify.c (vmsify, case 11): After translating `..' elements, set
+       * vmsify.c (vmsify, case 11): After translating `..' elements, set
         nstate to N_OPEN if there are still more elements to process.
         (vmsify, case 2): After translating `foo/bar' up to the slash,
         set nstate to N_OPEN, not N_DOT.
 
 Fri Aug  8 15:18:09 1997  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
-        * dir.c (vmsstat_dir): Leave name unmodified on exit.
-        * make.h (PATH_SEPARATOR_CHAR): Set to comma for VMS.
-        * vpath.c: Fix comments to refer to path separator, not colon.
+       * dir.c (vmsstat_dir): Leave name unmodified on exit.
+       * make.h (PATH_SEPARATOR_CHAR): Set to comma for VMS.
+       * vpath.c: Fix comments to refer to path separator, not colon.
         (selective_vpath_search): Avoid Unixy slash handling for VMS.
 
 Thu Aug  7 22:24:03 1997  John W. Eaton  <jwe@bevo.che.wisc.edu>
index 15067c6..97b2e1d 100644 (file)
@@ -7,13 +7,18 @@
 
 NORECURSE = true
 
+ACLOCALARGS =
+
+CFLAGS = -g -O -Wall -D__USE_FIXED_PROTOTYPES__
+export CFLAGS
+
 # If the user asked for a specific target, invoke the Makefile instead.
 #
 .DEFAULT:
        @[ -f Makefile.in -a -f configure -a -f aclocal.m4 -a -f config.h.in ] \
          || $(MAKE) __cfg NORECURSE=
        @[ -f Makefile ] \
-         || ./configure
+         || CFLAGS='-g -O -Wall -D__USE_FIXED_PROTOTYPES__' ./configure
        $(MAKE) -f Makefile $@
 
 .PHONY: __cfg __cfg_basic
@@ -23,21 +28,20 @@ NORECURSE = true
 ACCONFIG = acconfig.h
 
 __cfg: __cfg_basic config.h.in TAGS
-       cd glob && $(MAKE) -f ../GNUmakefile __cfg_basic ACCONFIG=
 ifdef NORECURSE
-       @echo ""; echo "Now you should run one of:"; echo ""; \
-         echo "  make all"; \
+       @echo ""; echo "Now you should run:"; echo ""; \
+         echo "  make all"; echo ""; \
+         echo "then, optionally, one of:"; echo ""; \
          echo "  make dist"; \
          echo "  make distdir"; \
-         echo "  make distcheck"; echo ""; \
-         echo "Or similar to proceed.";\
+         echo "  make distcheck"; \
          echo ""
 endif
 
 __cfg_basic: aclocal.m4 stamp-h.in configure Makefile.in
 
 aclocal.m4: configure.in $(wildcard acinclude.m4)
-       aclocal
+       aclocal $(ACLOCALARGS)
 
 config.h.in: stamp-h.in
 stamp-h.in: configure.in aclocal.m4 $(ACCONFIG)
@@ -45,7 +49,7 @@ stamp-h.in: configure.in aclocal.m4 $(ACCONFIG)
        echo timestamp > $@
 
 configure: configure.in aclocal.m4
-       autoconf
+       autoconf $(ACARGS)
 
 Makefile.in: configure.in config.h.in Makefile.am aclocal.m4
        automake --add-missing
index d20cae1..d575b92 100644 (file)
 /* Define this if the SCCS `get' command understands the `-G<file>' option.  */
 #undef SCCS_GET_MINUS_G
 
+/* Define to be the nanoseconds member of struct stat's st_mtim,
+   if it exists.  */
+#undef ST_MTIM_NSEC
+
 /* Define this if the C library defines the variable `sys_siglist'.  */
 #undef HAVE_SYS_SIGLIST
 
@@ -18,3 +22,7 @@
 
 /* Define this if you have the `union wait' type in <sys/wait.h>.  */
 #undef HAVE_UNION_WAIT
+
+/* Define to `unsigned long' or `unsigned long long'
+   if <inttypes.h> doesn't define.  */
+#undef uintmax_t
index 343c333..ff51c4c 100644 (file)
@@ -86,7 +86,7 @@ changequote([,])dnl
 
 dnl ---------------------------------------------------------------------------
 dnl Got this from the GNU fileutils 3.16r distribution
-dnl by Paul Eggert <egger@twinsun.com>
+dnl by Paul Eggert <eggert@twinsun.com>
 dnl ---------------------------------------------------------------------------
 
 dnl The problem is that the default compilation flags in Solaris 2.6 won't
@@ -129,3 +129,82 @@ AC_DEFUN(AC_LFS,
       done ;;
   esac
 ])
+
+
+dnl ---------------------------------------------------------------------------
+dnl From Paul Eggert <eggert@twinsun.com>
+
+dnl Define HAVE_INTTYPES_H if <inttypes.h> exists,
+dnl doesn't clash with <sys/types.h>, and declares uintmax_t.
+
+AC_DEFUN(jm_AC_HEADER_INTTYPES_H,
+[
+  if test x = y; then
+    dnl This code is deliberately never run via ./configure.
+    dnl FIXME: this is a gross hack to make autoheader put an entry
+    dnl for `HAVE_INTTYPES_H' in config.h.in.
+    AC_CHECK_FUNCS(INTTYPES_H)
+  fi
+  AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h,
+  [AC_TRY_COMPILE(
+    [#include <sys/types.h>
+#include <inttypes.h>],
+    [uintmax_t i = (uintmax_t) -1;],
+    jm_ac_cv_header_inttypes_h=yes,
+    jm_ac_cv_header_inttypes_h=no)])
+  if test $jm_ac_cv_header_inttypes_h = yes; then
+    ac_kludge=HAVE_INTTYPES_H
+    AC_DEFINE_UNQUOTED($ac_kludge)
+  fi
+])
+
+
+dnl ---------------------------------------------------------------------------
+dnl From Paul Eggert <eggert@twinsun.com>
+
+AC_DEFUN(AC_STRUCT_ST_MTIM_NSEC,
+ [AC_CACHE_CHECK([for nanoseconds member of struct stat.st_mtim],
+   ac_cv_struct_st_mtim_nsec,
+   [ac_save_CPPFLAGS="$CPPFLAGS"
+    ac_cv_struct_st_mtim_nsec=no
+    # tv_nsec -- the usual case
+    # _tv_nsec -- Solaris 2.6, if
+    #  (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1
+    #   && !defined __EXTENSIONS__)
+    # st__tim.tv_nsec -- UnixWare 2.1.2
+    for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do
+      CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val"
+      AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/stat.h>], [struct stat s; s.st_mtim.ST_MTIM_NSEC;],
+        [ac_cv_struct_st_mtim_nsec=$ac_val; break])
+    done
+    CPPFLAGS="$ac_save_CPPFLAGS"])
+
+  if test $ac_cv_struct_st_mtim_nsec != no; then
+    AC_DEFINE_UNQUOTED(ST_MTIM_NSEC, $ac_cv_struct_st_mtim_nsec)
+  fi
+ ]
+)
+
+dnl ---------------------------------------------------------------------------
+dnl From Paul Eggert <eggert@twinsun.com>
+
+dnl Define uintmax_t to `unsigned long' or `unsigned long long'
+dnl if <inttypes.h> does not exist.
+
+AC_DEFUN(jm_AC_TYPE_UINTMAX_T,
+[
+  AC_REQUIRE([jm_AC_HEADER_INTTYPES_H])
+  if test $jm_ac_cv_header_inttypes_h = no; then
+    AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long,
+    [AC_TRY_COMPILE([],
+      [unsigned long long i = (unsigned long long) -1;],
+      ac_cv_type_unsigned_long_long=yes,
+      ac_cv_type_unsigned_long_long=no)])
+    if test $ac_cv_type_unsigned_long_long = yes; then
+      AC_DEFINE(uintmax_t, unsigned long long)
+    else
+      AC_DEFINE(uintmax_t, unsigned long)
+    fi
+  fi
+])
diff --git a/amiga.c b/amiga.c
index a163781..d0e4ff5 100644 (file)
--- a/amiga.c
+++ b/amiga.c
@@ -45,7 +45,7 @@ char ** argv;
     buffer = AllocMem (len, MEMF_ANY);
 
     if (!buffer)
-      fatal ("MyExecute: Cannot allocate space for calling a command");
+      fatal (NILF, "MyExecute: Cannot allocate space for calling a command");
 
     ptr = buffer;
 
diff --git a/ar.c b/ar.c
index 7167dc3..04d7411 100644 (file)
--- a/ar.c
+++ b/ar.c
@@ -46,7 +46,7 @@ ar_name (name)
     return 0;
 
   if (p[1] == '(' && end[-1] == ')')
-    fatal ("attempt to use unsupported feature: `%s'", name);
+    fatal (NILF, "attempt to use unsupported feature: `%s'", name);
 
   return 1;
 }
@@ -137,7 +137,7 @@ int
 ar_touch (name)
      char *name;
 {
-  error ("touch archive member is not available on VMS");
+  error (NILF, "touch archive member is not available on VMS");
   return -1;
 }
 #else
@@ -169,22 +169,24 @@ ar_touch (name)
   switch (ar_member_touch (arname, memname))
     {
     case -1:
-      error ("touch: Archive `%s' does not exist", arname);
+      error (NILF, "touch: Archive `%s' does not exist", arname);
       break;
     case -2:
-      error ("touch: `%s' is not a valid archive", arname);
+      error (NILF, "touch: `%s' is not a valid archive", arname);
       break;
     case -3:
       perror_with_name ("touch: ", arname);
       break;
     case 1:
-      error ("touch: Member `%s' does not exist in `%s'", memname, arname);
+      error (NILF,
+             "touch: Member `%s' does not exist in `%s'", memname, arname);
       break;
     case 0:
       val = 0;
       break;
     default:
-      error ("touch: Bad return code from ar_member_touch on `%s'", name);
+      error (NILF,
+             "touch: Bad return code from ar_member_touch on `%s'", name);
     }
 
   if (!arname_used)
@@ -233,15 +235,6 @@ ar_glob_match (desc, mem, truncated,
   return 0L;
 }
 
-/* Alphabetic sorting function for `qsort'.  */
-
-static int
-ar_glob_alphacompare (a, b)
-     char **a, **b;
-{
-  return strcmp (*a, *b);
-}
-
 /* Return nonzero if PATTERN contains any metacharacters.
    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
 static int
@@ -316,7 +309,7 @@ ar_glob (arname, member_pattern, size)
     names[i++] = n->name;
 
   /* Sort them alphabetically.  */
-  qsort ((char *) names, i, sizeof (*names), ar_glob_alphacompare);
+  qsort ((char *) names, i, sizeof (*names), alpha_compare);
 
   /* Put them back into the chain in the sorted order.  */
   i = 0;
index 13ae45b..1fc0a16 100644 (file)
--- a/arscan.c
+++ b/arscan.c
@@ -69,7 +69,7 @@ VMS_get_member_info (module, rfa)
                           &bufdesc.dsc$w_length, 0);
   if (! status)
     {
-      error ("lbr$set_module failed to extract module info, status = %d",
+      error (NILF, "lbr$set_module failed to extract module info, status = %d",
             status);
 
       lbr$close (&VMS_lib_idx);
@@ -151,7 +151,7 @@ ar_scan (archive, function, arg)
 
   if (! status)
     {
-      error ("lbr$ini_control failed with status = %d",status);
+      error (NILF, "lbr$ini_control failed with status = %d",status);
       return -2;
     }
 
@@ -162,7 +162,7 @@ ar_scan (archive, function, arg)
 
   if (! status)
     {
-      error ("unable to open library `%s' to lookup member `%s'",
+      error (NILF, "unable to open library `%s' to lookup member `%s'",
             archive, (char *)arg);
       return -1;
     }
index 5646b18..166b96d 100644 (file)
@@ -473,13 +473,13 @@ delete_target (file, on_behalf_of)
 #ifndef NO_ARCHIVES
   if (ar_name (file->name))
     {
-      if (ar_member_date (file->name) != file->last_mtime)
+      if (ar_member_date (file->name) != FILE_TIMESTAMP_S (file->last_mtime))
        {
          if (on_behalf_of)
-           error ("*** [%s] Archive member `%s' may be bogus; not deleted",
+           error (NILF, "*** [%s] Archive member `%s' may be bogus; not deleted",
                   on_behalf_of, file->name);
          else
-           error ("*** Archive member `%s' may be bogus; not deleted",
+           error (NILF, "*** Archive member `%s' may be bogus; not deleted",
                   file->name);
        }
       return;
@@ -488,12 +488,12 @@ delete_target (file, on_behalf_of)
 
   if (stat (file->name, &st) == 0
       && S_ISREG (st.st_mode)
-      && (time_t) st.st_mtime != file->last_mtime)
+      && FILE_TIMESTAMP_STAT_MODTIME (st) != file->last_mtime)
     {
       if (on_behalf_of)
-       error ("*** [%s] Deleting file `%s'", on_behalf_of, file->name);
+       error (NILF, "*** [%s] Deleting file `%s'", on_behalf_of, file->name);
       else
-       error ("*** Deleting file `%s'", file->name);
+       error (NILF, "*** Deleting file `%s'", file->name);
       if (unlink (file->name) < 0
          && errno != ENOENT)   /* It disappeared; so what.  */
        perror_with_name ("unlink: ", file->name);
@@ -533,10 +533,11 @@ print_commands (cmds)
 
   fputs ("#  commands to execute", stdout);
 
-  if (cmds->filename == 0)
+  if (cmds->fileinfo.filenm == 0)
     puts (" (built-in):");
   else
-    printf (" (from `%s', line %u):\n", cmds->filename, cmds->lineno);
+    printf (" (from `%s', line %lu):\n",
+            cmds->fileinfo.filenm, cmds->fileinfo.lineno);
 
   s = cmds->commands;
   while (*s != '\0')
index c55fa67..9547fc3 100644 (file)
@@ -21,8 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 struct commands
   {
-    char *filename;            /* File that contains commands.  */
-    unsigned int lineno;       /* Line number in file.  */
+    struct floc fileinfo;      /* Where commands were defined.  */
     char *commands;            /* Commands text.  */
     unsigned int ncommand_lines;/* Number of command lines.  */
     char **command_lines;      /* Commands chopped up into lines.  */
index b7103ed..523876e 100644 (file)
    System headers sometimes define this.
    We just want to avoid a redefinition error message. */
 #ifndef _ALL_SOURCE
-#undef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
 #endif
 
 /* Define if using alloca.c.  */
 #define C_ALLOCA
 
+/* Define if the closedir function returns void instead of int.  */
+/* #undef CLOSEDIR_VOID */
+
 /* Define to empty if the keyword does not work.  */
-#undef const
+/* #undef const */
 
 /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
    This function is required for alloca.c support on those systems.  */
-#undef CRAY_STACKSEG_END
+/* #undef CRAY_STACKSEG_END */
 
 /* Define for DGUX with <sys/dg_sys_info.h>.  */
-#undef DGUX
+/* #undef DGUX */
 
 /* Define if the `getloadavg' function needs to be run setuid or setgid.  */
-#undef GETLOADAVG_PRIVILEGED
+/* #undef GETLOADAVG_PRIVILEGED */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #define gid_t int
 
 /* Define if you have alloca, as a function or macro.  */
-#undef HAVE_ALLOCA
+/* #undef HAVE_ALLOCA */
 
 /* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
-#undef HAVE_ALLOCA_H
-
-/* Define if you have the memmove function.  */
-#define HAVE_MEMMOVE 1
+/* #undef HAVE_ALLOCA_H */
 
 /* Define if you don't have vprintf but do have _doprnt.  */
-#undef HAVE_DOPRNT
+/* #undef HAVE_DOPRNT */
+
+/* Define if your system has a working fnmatch function.  */
+/* #undef HAVE_FNMATCH */
 
 /* Define if your system has its own `getloadavg' function.  */
-#undef HAVE_GETLOADAVG
+/* #undef HAVE_GETLOADAVG */
 
 /* Define if you have the getmntent function.  */
-#undef HAVE_GETMNTENT
+/* #undef HAVE_GETMNTENT */
 
 /* Define if the `long double' type works.  */
-#undef HAVE_LONG_DOUBLE
+/* #undef HAVE_LONG_DOUBLE */
 
 /* Define if you support file names longer than 14 characters. */
-#define HAVE_LONG_FILE_NAMES
+#define HAVE_LONG_FILE_NAMES 1
 
 /* Define if you have a working `mmap' system call.  */
-#undef HAVE_MMAP
+/* #undef HAVE_MMAP */
 
 /* Define if system calls automatically restart after interruption
    by a signal.  */
-#undef HAVE_RESTARTABLE_SYSCALLS
+/* #undef HAVE_RESTARTABLE_SYSCALLS */
 
 /* Define if your struct stat has st_blksize.  */
-#undef HAVE_ST_BLKSIZE
+/* #undef HAVE_ST_BLKSIZE */
 
 /* Define if your struct stat has st_blocks.  */
-#undef HAVE_ST_BLOCKS
+/* #undef HAVE_ST_BLOCKS */
 
 /* Define if you have the strcoll function and it is properly defined. */
-#define HAVE_STRCOLL
+#define HAVE_STRCOLL 1
 
 /* Define if your struct stat has st_rdev.  */
-#define HAVE_ST_RDEV
+#define HAVE_ST_RDEV 1
 
 /* Define if you have the strftime function.  */
-#define HAVE_STRFTIME
+#define HAVE_STRFTIME 1
 
 /* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
+/* #undef HAVE_SYS_WAIT_H */
 
 /* Define if your struct tm has tm_zone.  */
-#undef HAVE_TM_ZONE
+/* #undef HAVE_TM_ZONE */
 
 /* Define if you don't have tm_zone but do have the external array
    tzname.  */
-#define HAVE_TZNAME
-/* #define tzname __tzname */
+#define HAVE_TZNAME 1
 
 /* Define if you have <unistd.h>.  */
-#define HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
 
 /* Define if utime(file, NULL) sets file's timestamp to the present.  */
-#undef HAVE_UTIME_NULL
+/* #undef HAVE_UTIME_NULL */
 
 /* Define if you have <vfork.h>.  */
-#undef HAVE_VFORK_H
+/* #undef HAVE_VFORK_H */
 
 /* Define if you have the vprintf function.  */
-#define HAVE_VPRINTF
+#define HAVE_VPRINTF 1
 
 /* Define if you have the wait3 system call.  */
-#undef HAVE_WAIT3
+/* #undef HAVE_WAIT3 */
 
 /* Define if on MINIX. */
-#undef _MINIX
+/* #undef _MINIX */
 
 /* Define if your struct nlist has an n_un member.  */
-#undef NLIST_NAME_UNION
+/* #undef NLIST_NAME_UNION */
 
 /* Define if you have <nlist.h>.  */
-#undef NLIST_STRUCT
+/* #undef NLIST_STRUCT */
 
 /* Define if your C compiler doesn't accept -c and -o together.  */
-#undef NO_MINUS_C_MINUS_O
+/* #undef NO_MINUS_C_MINUS_O */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #define pid_t int
 
 /* Define if the system does not provide POSIX.1 features except
    with this defined.  */
-#undef _POSIX_1_SOURCE
+/* #undef _POSIX_1_SOURCE */
 
 /* Define if you need to in order for stat and other things to work.  */
-#undef _POSIX_SOURCE
+/* #undef _POSIX_SOURCE */
 
 /* Define as the return type of signal handlers (int or void).  */
 #define RETSIGTYPE void
 /* Define if the setvbuf function takes the buffering type as its second
    argument and the buffer pointer as the third, as on System V
    before release 3.  */
-#undef SETVBUF_REVERSED
+/* #undef SETVBUF_REVERSED */
 
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be
 #define STACK_DIRECTION -1
 
 /* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
-#undef STAT_MACROS_BROKEN
+/* #undef STAT_MACROS_BROKEN */
 
 /* Define if you have the ANSI C header files. */
 #define STDC_HEADERS
 
 /* Define on System V Release 4.  */
-#undef SVR4
+/* #undef SVR4 */
 
 /* Define if `sys_siglist' is declared by <signal.h>.  */
-#undef SYS_SIGLIST_DECLARED
+/* #undef SYS_SIGLIST_DECLARED */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #define uid_t int
 
 /* Define for Encore UMAX.  */
-#undef UMAX
+/* #undef UMAX */
 
 /* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
    instead of <sys/cpustats.h>.  */
-#undef UMAX4_3
+/* #undef UMAX4_3 */
 
 /* Define vfork as fork if vfork does not work.  */
-#undef vfork
+/* #undef vfork */
 
 /* Name of this package (needed by automake) */
 #define PACKAGE "%PACKAGE%"
 #define SCCS_GET "get"
 
 /* Define this if the SCCS `get' command understands the `-G<file>' option.  */
-#undef SCCS_GET_MINUS_G
+/* #undef SCCS_GET_MINUS_G */
 
 /* Define this if the C library defines the variable `sys_siglist'.  */
-#undef HAVE_SYS_SIGLIST
+/* #undef HAVE_SYS_SIGLIST */
 
 /* Define this if the C library defines the variable `_sys_siglist'.  */
-#undef HAVE__SYS_SIGLIST
+/* #undef HAVE__SYS_SIGLIST */
 
 /* Define this if you have the `union wait' type in <sys/wait.h>.  */
-#undef HAVE_UNION_WAIT
-
-/* Define this if the POSIX.1 call `sysconf (_SC_OPEN_MAX)' works properly.  */
-#undef HAVE_SYSCONF_OPEN_MAX
+/* #undef HAVE_UNION_WAIT */
 
 /* Define if you have the dup2 function.  */
-#undef HAVE_DUP2
+/* #undef HAVE_DUP2 */
 
 /* Define if you have the getcwd function.  */
-#define HAVE_GETCWD
-
-/* Define if you have the getdtablesize function.  */
-#undef HAVE_GETDTABLESIZE
+#define HAVE_GETCWD 1
 
 /* Define if you have the getgroups function.  */
-#undef HAVE_GETGROUPS
+/* #undef HAVE_GETGROUPS */
+
+/* Define if you have the gethostbyname function.  */
+/* #undef HAVE_GETHOSTBYNAME */
+
+/* Define if you have the gethostname function.  */
+/* #undef HAVE_GETHOSTNAME */
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
 
 /* Define if you have the mktemp function.  */
-#define HAVE_MKTEMP
+#define HAVE_MKTEMP 1
 
 /* Define if you have the psignal function.  */
-#undef HAVE_PSIGNAL
+/* #undef HAVE_PSIGNAL */
+
+/* Define if you have the pstat_getdynamic function.  */
+/* #undef HAVE_PSTAT_GETDYNAMIC */
 
 /* Define if you have the setegid function.  */
-#undef HAVE_SETEGID
+/* #undef HAVE_SETEGID */
 
 /* Define if you have the seteuid function.  */
-#undef HAVE_SETEUID
+/* #undef HAVE_SETEUID */
 
 /* Define if you have the setlinebuf function. */
-#undef HAVE_SETLINEBUF
+/* #undef HAVE_SETLINEBUF */
 
 /* Define if you have the setregid function.  */
-#undef HAVE_SETREGID
+/* #undef HAVE_SETREGID */
 
 /* Define if you have the setreuid function.  */
-#undef HAVE_SETREUID
+/* #undef HAVE_SETREUID */
 
 /* Define if you have the sigsetmask function. */
-#undef HAVE_SIGSETMASK
+/* #undef HAVE_SIGSETMASK */
+
+/* Define if you have the socket function.  */
+/* #undef HAVE_SOCKET */
+
+/* Define if you have the strcasecmp function.  */
+/* #undef HAVE_STRCASECMP */
 
 /* Define if you have the strerror function.  */
-#define HAVE_STRERROR
+#define HAVE_STRERROR 1
 
 /* Define if you have the strsignal function.  */
-#undef HAVE_STRSIGNAL
+/* #undef HAVE_STRSIGNAL */
 
 /* Define if you have the wait3 function.  */
-#undef HAVE_WAIT3
+/* #undef HAVE_WAIT3 */
 
 /* Define if you have the waitpid function.  */
-#undef HAVE_WAITPID
+/* #undef HAVE_WAITPID */
 
 /* Define if you have the <dirent.h> header file.  */
-#define HAVE_DIRENT_H
+#define HAVE_DIRENT_H 1
 
 /* Define if you have the <fcntl.h> header file.  */
-#define HAVE_FCNTL_H
+#define HAVE_FCNTL_H 1
 
 /* Define if you have the <limits.h> header file.  */
-#define HAVE_LIMITS_H
+#define HAVE_LIMITS_H 1
 
 /* Define if you have the <mach/mach.h> header file.  */
-#undef HAVE_MACH_MACH_H
+/* #undef HAVE_MACH_MACH_H */
 
 /* Define if you have the <memory.h> header file.  */
-#undef HAVE_MEMORY_H
+/* #undef HAVE_MEMORY_H */
 
 /* Define if you have the <ndir.h> header file.  */
-#undef HAVE_NDIR_H
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <stdlib.h> header file.  */
+/* #undef HAVE_STDLIB_H */
 
 /* Define if you have the <string.h> header file.  */
-#define HAVE_STRING_H
+#define HAVE_STRING_H 1
 
 /* Define if you have the <sys/dir.h> header file.  */
-#define HAVE_SYS_DIR_H
+#define HAVE_SYS_DIR_H 1
 
 /* Define if you have the <sys/ndir.h> header file.  */
-#undef HAVE_SYS_NDIR_H
+/* #undef HAVE_SYS_NDIR_H */
 
 /* Define if you have the <sys/param.h> header file.  */
-#undef HAVE_SYS_PARAM_H
+/* #undef HAVE_SYS_PARAM_H */
 
 /* Define if you have the <sys/timeb.h> header file.  */
-#undef HAVE_SYS_TIMEB_H
+/* #undef HAVE_SYS_TIMEB_H */
 
 /* Define if you have the <sys/wait.h> header file.  */
-#undef HAVE_SYS_WAIT_H
+/* #undef HAVE_SYS_WAIT_H */
 
 /* Define if you have the <unistd.h> header file.  */
-#define HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
 
 /* Define if you have the dgc library (-ldgc).  */
-#undef HAVE_LIBDGC
+/* #undef HAVE_LIBDGC */
+
+/* Define if you have the kstat library (-lkstat).  */
+/* #undef HAVE_LIBKSTAT */
 
 /* Define if you have the sun library (-lsun).  */
-#undef HAVE_LIBSUN
+/* #undef HAVE_LIBSUN */
 
 /* Define for Case Insensitve behavior */
 #define HAVE_CASE_INSENSITIVE_FS
index a41ae06..e44af44 100644 (file)
@@ -12,6 +12,9 @@
 /* Define if using alloca.c.  */
 /* #undef C_ALLOCA */
 
+/* Define if the closedir function returns void instead of int.  */
+/* #undef CLOSEDIR_VOID */
+
 /* Define to empty if the keyword does not work.  */
 /* #undef const */
 
@@ -23,7 +26,7 @@
 /* #undef DGUX */
 
 /* Define if the `getloadavg' function needs to be run setuid or setgid.  */
-/* #undef GETLOADAVG_PRIVILEGED */
+/* #undef GETLOADAVG_PRIVILEGED */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 /* #undef gid_t */
 #define HAVE_ALLOCA 1
 
 /* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
-/* #undef HAVE_ALLOCA_H 1 */
-
-/* Define if you have the memmove function.  */
-#define HAVE_MEMMOVE 1
+/* #undef HAVE_ALLOCA_H */
 
 /* Define if you don't have vprintf but do have _doprnt.  */
 /* #undef HAVE_DOPRNT */
 
+/* Define if your system has a working fnmatch function.  */
+/* #undef HAVE_FNMATCH */
+
 /* Define if your system has its own `getloadavg' function.  */
 /* #undef HAVE_GETLOADAVG */
 
 /* #undef HAVE_ST_BLOCKS */
 
 /* Define if you have the strcoll function and it is properly defined.  */
-/* #undef HAVE_STRCOLL */
+/* #undef HAVE_STRCOLL */
 
 /* Define if your struct stat has st_rdev.  */
-/* #undef HAVE_ST_RDEV  */
+/* #undef HAVE_ST_RDEV */
 
 /* Define if you have the strftime function.  */
 /* #undef HAVE_STRFTIME */
 
 /* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
-/* #undef HAVE_SYS_WAIT_H */
+/* #undef HAVE_SYS_WAIT_H */
 
 /* Define if your struct tm has tm_zone.  */
 /* #undef HAVE_TM_ZONE */
 /* #undef HAVE_UTIME_NULL */
 
 /* Define if you have <vfork.h>.  */
-/* #undef HAVE_VFORK_H */
+/* #undef HAVE_VFORK_H */
 
 /* Define if you have the vprintf function.  */
 #define HAVE_VPRINTF 1
 
 /* Define if you have the wait3 system call.  */
-/* #undef HAVE_WAIT3 */
+/* #undef HAVE_WAIT3 */
 
 /* Define if on MINIX.  */
 /* #undef _MINIX */
 /* #undef NLIST_NAME_UNION */
 
 /* Define if you have <nlist.h>.  */
-/* #undef NLIST_STRUCT */
+/* #undef NLIST_STRUCT */
 
 /* Define if your C compiler doesn't accept -c and -o together.  */
 /* #undef NO_MINUS_C_MINUS_O */
 /* Define if the setvbuf function takes the buffering type as its second
    argument and the buffer pointer as the third, as on System V
    before release 3.  */
-/* #undef SETVBUF_REVERSED */
+/* #undef SETVBUF_REVERSED */
 
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be
    instead of <sys/cpustats.h>.  */
 /* #undef UMAX4_3 */
 
+/* Define vfork as fork if vfork does not work.  */
+/* #undef vfork */
+
 /* Name of this package (needed by automake) */
 #define PACKAGE "%PACKAGE%"
 
 /* Version of this package (needed by automake) */
 #define VERSION "%VERSION%"
 
-/* Define vfork as fork if vfork does not work.  */
-/* #undef vfork */
-
 /* Define to the name of the SCCS `get' command.  */
-/* #undef SCCS_GET "/usr/sccs/get" */
+/* #undef SCCS_GET */
 
 /* Define this if the SCCS `get' command understands the `-G<file>' option.  */
-/* #undef SCCS_GET_MINUS_G */
+/* #undef SCCS_GET_MINUS_G */
 
 /* Define this if the C library defines the variable `sys_siglist'.  */
-/* #undefine HAVE_SYS_SIGLIST */
+/* #undefine HAVE_SYS_SIGLIST */
 
 /* Define this if the C library defines the variable `_sys_siglist'.  */
 /* #undef HAVE__SYS_SIGLIST */
 /* Define this if you have the `union wait' type in <sys/wait.h>.  */
 /* #undef HAVE_UNION_WAIT */
 
-/* Define this if the POSIX.1 call `sysconf (_SC_OPEN_MAX)' works properly.  */
-/* #undef HAVE_SYSCONF_OPEN_MAX */
-
 /* Define if you have the dup2 function.  */
 #define HAVE_DUP2 1
 
 /* Define if you have the getcwd function.  */
 #define HAVE_GETCWD 1
 
-/* Define if you have the getdtablesize function.  */
-/* #undef HAVE_GETDTABLESIZE 1 */
-
 /* Define if you have the getgroups function.  */
-/* #undef HAVE_GETGROUPS 1 */
+/* #undef HAVE_GETGROUPS */
+
+/* Define if you have the gethostbyname function.  */
+/* #undef HAVE_GETHOSTBYNAME */
+
+/* Define if you have the gethostname function.  */
+/* #undef HAVE_GETHOSTNAME */
+
+/* Define if you have the getloadavg function.  */
+/* #undef HAVE_GETLOADAVG */
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
 
 /* Define if you have the mktemp function.  */
 #define HAVE_MKTEMP 1
 
 /* Define if you have the psignal function.  */
-/* #undef HAVE_PSIGNAL 1 */
+/* #undef HAVE_PSIGNAL */
+
+/* Define if you have the pstat_getdynamic function.  */
+/* #undef HAVE_PSTAT_GETDYNAMIC */
 
 /* Define if you have the setegid function.  */
-/* #undef HAVE_SETEGID */
+/* #undef HAVE_SETEGID */
 
 /* Define if you have the seteuid function.  */
-/* #undef HAVE_SETEUID */
+/* #undef HAVE_SETEUID */
 
 /* Define if you have the setlinebuf function.  */
-/* #undef HAVE_SETLINEBUF */
+/* #undef HAVE_SETLINEBUF */
 
 /* Define if you have the setregid function.  */
-/* #undefine HAVE_SETREGID */
+/* #undefine HAVE_SETREGID */
 
 /* Define if you have the setreuid function.  */
-/* #define HAVE_SETREUID */
+/* #define HAVE_SETREUID */
 
 /* Define if you have the sigsetmask function.  */
 #define HAVE_SIGSETMASK 1
 
+/* Define if you have the socket function.  */
+/* #undef HAVE_SOCKET */
+
+/* Define if you have the strcasecmp function.  */
+/* #undef HAVE_STRCASECMP */
+
 /* Define if you have the strerror function.  */
 #define HAVE_STRERROR 1
 
 /* #undef HAVE_STRSIGNAL */
 
 /* Define if you have the wait3 function.  */
-/* #define HAVE_WAIT3 1 */
+/* #undef HAVE_WAIT3 */
 
 /* Define if you have the waitpid function.  */
-/* #undef HAVE_WAITPID */
+/* #undef HAVE_WAITPID */
 
 /* Define if you have the <dirent.h> header file.  */
-/* #unddef HAVE_DIRENT_H 1 */
+/* #undef HAVE_DIRENT_H */
 
 /* Define if you have the <fcntl.h> header file.  */
 #ifdef __DECC
 /* #undef HAVE_MACH_MACH_H */
 
 /* Define if you have the <memory.h> header file.  */
-/* #undef HAVE_MEMORY_H */
+/* #undef HAVE_MEMORY_H */
 
 /* Define if you have the <ndir.h> header file.  */
 /* #undef HAVE_NDIR_H */
 
+/* Define if you have the <stdlib.h> header file.  */
+#define HAVE_STDLIB_H 1
+
 /* Define if you have the <string.h> header file.  */
 #define HAVE_STRING_H 1
 
-/* Define if you have the <pwd.h> header file.  */
-/* #undef HAVE_PWD_H */
-
 /* Define if you have the <sys/dir.h> header file.  */
 /* #undef HAVE_SYS_DIR_H */
 
 /* #undef HAVE_SYS_NDIR_H */
 
 /* Define if you have the <sys/param.h> header file.  */
-/* #undef HAVE_SYS_PARAM_H */
+/* #undef HAVE_SYS_PARAM_H */
 
 /* Define if you have the <sys/timeb.h> header file.  */
 #define HAVE_SYS_TIMEB_H 1
 
 /* Define if you have the <sys/wait.h> header file.  */
-/* #undef HAVE_SYS_WAIT_H 1 */
+/* #undef HAVE_SYS_WAIT_H */
+
+/* Define if you have the <unistd.h> header file.  */
+/* #undef HAVE_UNISTD_H */
 
 /* Define if you have the dgc library (-ldgc).  */
 /* #undef HAVE_LIBDGC */
 
+/* Define if you have the kstat library (-lkstat).  */
+/* #undef HAVE_LIBKSTAT */
+
 /* Define if you have the sun library (-lsun).  */
 /* #undef HAVE_LIBSUN */
 
 /* VMS specific */
 
 #define HAVE_VMSDIR_H 1
-#define HAVE_STDLIB_H 1
 #define INCLUDEDIR "sys$sysroot:[syslib]"
 #define LIBDIR "sys$sysroot:[syslib]"
 
index aa5a027..79bb6cd 100644 (file)
@@ -4,24 +4,27 @@
    System headers sometimes define this.
    We just want to avoid a redefinition error message.  */
 #ifndef _ALL_SOURCE
-#undef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
 #endif
 
 /* Define if using alloca.c.  */
-#undef C_ALLOCA
+/* #undef C_ALLOCA */
+
+/* Define if the closedir function returns void instead of int.  */
+/* #undef CLOSEDIR_VOID */
 
 /* Define to empty if the keyword does not work.  */
-#undef const
+/* #undef const */
 
 /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
    This function is required for alloca.c support on those systems.  */
-#undef CRAY_STACKSEG_END
+/* #undef CRAY_STACKSEG_END */
 
 /* Define for DGUX with <sys/dg_sys_info.h>.  */
-#undef DGUX
+/* #undef DGUX */
 
 /* Define if the `getloadavg' function needs to be run setuid or setgid.  */
-#undef GETLOADAVG_PRIVILEGED
+/* #undef GETLOADAVG_PRIVILEGED */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef gid_t
 #define HAVE_ALLOCA 1
 
 /* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
-#undef HAVE_ALLOCA_H
-
-/* Define if you have the memmove function.  */
-#undef HAVE_MEMMOVE
-#define HAVE_MEMMOVE 1
+/* #undef HAVE_ALLOCA_H */
 
 /* Define if you don't have vprintf but do have _doprnt.  */
-#undef HAVE_DOPRNT
+/* #undef HAVE_DOPRNT */
+
+/* Define if your system has a working fnmatch function.  */
+/* #undef HAVE_FNMATCH */
 
 /* Define if your system has its own `getloadavg' function.  */
-#undef HAVE_GETLOADAVG
+/* #undef HAVE_GETLOADAVG */
 
 /* Define if you have the getmntent function.  */
-#undef HAVE_GETMNTENT
+/* #undef HAVE_GETMNTENT */
 
 /* Define if the `long double' type works.  */
-#undef HAVE_LONG_DOUBLE
+/* #undef HAVE_LONG_DOUBLE */
 
 /* Define if you support file names longer than 14 characters.  */
 #undef HAVE_LONG_FILE_NAMES
 #define HAVE_LONG_FILE_NAMES 1
 
 /* Define if you have a working `mmap' system call.  */
-#undef HAVE_MMAP
+/* #undef HAVE_MMAP */
 
 /* Define if system calls automatically restart after interruption
    by a signal.  */
-#undef HAVE_RESTARTABLE_SYSCALLS
+/* #undef HAVE_RESTARTABLE_SYSCALLS */
 
 /* Define if your struct stat has st_blksize.  */
-#undef HAVE_ST_BLKSIZE
+/* #undef HAVE_ST_BLKSIZE */
 
 /* Define if your struct stat has st_blocks.  */
-#undef HAVE_ST_BLOCKS
+/* #undef HAVE_ST_BLOCKS */
 
 /* Define if you have the strcoll function and it is properly defined.  */
 #undef HAVE_STRCOLL
 #define HAVE_STRFTIME 1
 
 /* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
-#undef HAVE_SYS_WAIT_H
+/* #undef HAVE_SYS_WAIT_H */
 
 /* Define if your struct tm has tm_zone.  */
-#undef HAVE_TM_ZONE
+/* #undef HAVE_TM_ZONE */
 
 /* Define if you don't have tm_zone but do have the external array
    tzname.  */
 #define HAVE_TZNAME 1
 
 /* Define if you have <unistd.h>.  */
-#undef HAVE_UNISTD_H
+/* #undef HAVE_UNISTD_H */
 
 /* Define if utime(file, NULL) sets file's timestamp to the present.  */
 #undef HAVE_UTIME_NULL
 #define HAVE_UTIME_NULL 1
 
 /* Define if you have <vfork.h>.  */
-#undef HAVE_VFORK_H
+/* #undef HAVE_VFORK_H */
 
 /* Define if you have the vprintf function.  */
 #undef HAVE_VPRINTF
 #define HAVE_VPRINTF 1
 
 /* Define if you have the wait3 system call.  */
-#undef HAVE_WAIT3
+/* #undef HAVE_WAIT3 */
 
 /* Define if on MINIX.  */
-#undef _MINIX
+/* #undef _MINIX */
 
 /* Define if your struct nlist has an n_un member.  */
-#undef NLIST_NAME_UNION
+/* #undef NLIST_NAME_UNION */
 
 /* Define if you have <nlist.h>.  */
-#undef NLIST_STRUCT
+/* #undef NLIST_STRUCT */
 
 /* Define if your C compiler doesn't accept -c and -o together.  */
-#undef NO_MINUS_C_MINUS_O
+/* #undef NO_MINUS_C_MINUS_O */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef pid_t
 
 /* Define if the system does not provide POSIX.1 features except
    with this defined.  */
-#undef _POSIX_1_SOURCE
+/* #undef _POSIX_1_SOURCE */
 
 /* Define if you need to in order for stat and other things to work.  */
 #undef _POSIX_SOURCE
 /* Define if the setvbuf function takes the buffering type as its second
    argument and the buffer pointer as the third, as on System V
    before release 3.  */
-#undef SETVBUF_REVERSED
+/* #undef SETVBUF_REVERSED */
 
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be
        STACK_DIRECTION < 0 => grows toward lower addresses
        STACK_DIRECTION = 0 => direction of growth unknown
  */
-#undef STACK_DIRECTION
+/* #undef STACK_DIRECTION */
 
 /* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
-#undef STAT_MACROS_BROKEN
+/* #undef STAT_MACROS_BROKEN */
 
 /* Define if you have the ANSI C header files.  */
 #undef STDC_HEADERS
 #define STDC_HEADERS 1
 
 /* Define on System V Release 4.  */
-#undef SVR4
+/* #undef SVR4 */
 
 /* Define if `sys_siglist' is declared by <signal.h>.  */
-#undef SYS_SIGLIST_DECLARED
+/* #undef SYS_SIGLIST_DECLARED */
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef uid_t
 #define uid_t int
 
 /* Define for Encore UMAX.  */
-#undef UMAX
+/* #undef UMAX */
 
 /* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
    instead of <sys/cpustats.h>.  */
-#undef UMAX4_3
+/* #undef UMAX4_3 */
 
 /* Define vfork as fork if vfork does not work.  */
-#undef vfork
+/* #undef vfork */
 
 /* Name of this package (needed by automake) */
 #define PACKAGE "%PACKAGE%"
 #define SCCS_GET "echo no sccs get"
 
 /* Define this if the SCCS `get' command understands the `-G<file>' option.  */
-#undef SCCS_GET_MINUS_G
+/* #undef SCCS_GET_MINUS_G */
 
 /* Define this if the C library defines the variable `sys_siglist'.  */
-#undef HAVE_SYS_SIGLIST
+/* #undef HAVE_SYS_SIGLIST */
 
 /* Define this if the C library defines the variable `_sys_siglist'.  */
-#undef HAVE__SYS_SIGLIST
+/* #undef HAVE__SYS_SIGLIST */
 
 /* Define this if you have the `union wait' type in <sys/wait.h>.  */
-#undef HAVE_UNION_WAIT
+/* #undef HAVE_UNION_WAIT */
 
 /* Define if you have the dup2 function.  */
 #undef HAVE_DUP2
 #define HAVE_GETCWD 1
 
 /* Define if you have the getgroups function.  */
-#undef HAVE_GETGROUPS
+/* #undef HAVE_GETGROUPS */
+
+/* Define if you have the gethostbyname function.  */
+/* #undef HAVE_GETHOSTBYNAME */
+
+/* Define if you have the gethostname function.  */
+/* #undef HAVE_GETHOSTNAME */
+
+/* Define if you have the getloadavg function.  */
+/* #undef HAVE_GETLOADAVG */
+
+/* Define if you have the memmove function.  */
+#undef HAVE_MEMMOVE
+#define HAVE_MEMMOVE 1
 
 /* Define if you have the mktemp function.  */
 #undef HAVE_MKTEMP
 #define HAVE_MKTEMP 1
 
 /* Define if you have the psignal function.  */
-#undef HAVE_PSIGNAL
+/* #undef HAVE_PSIGNAL */
+
+/* Define if you have the pstat_getdynamic function.  */
+/* #undef HAVE_PSTAT_GETDYNAMIC */
 
 /* Define if you have the setegid function.  */
-#undef HAVE_SETEGID
+/* #undef HAVE_SETEGID */
 
 /* Define if you have the seteuid function.  */
-#undef HAVE_SETEUID
+/* #undef HAVE_SETEUID */
 
 /* Define if you have the setlinebuf function.  */
-#undef HAVE_SETLINEBUF
+/* #undef HAVE_SETLINEBUF */
 
 /* Define if you have the setregid function.  */
-#undef HAVE_SETREGID
+/* #undef HAVE_SETREGID */
 
 /* Define if you have the setreuid function.  */
-#undef HAVE_SETREUID
+/* #undef HAVE_SETREUID */
 
 /* Define if you have the sigsetmask function.  */
-#undef HAVE_SIGSETMASK
+/* #undef HAVE_SIGSETMASK */
+
+/* Define if you have the socket function.  */
+/* #undef HAVE_SOCKET */
+
+/* Define if you have the strcasecmp function.  */
+/* #undef HAVE_STRCASECMP */
 
 /* Define if you have the strerror function.  */
 #undef HAVE_STRERROR
 #define HAVE_STRERROR 1
 
 /* Define if you have the strsignal function.  */
-#undef HAVE_STRSIGNAL
+/* #undef HAVE_STRSIGNAL */
 
 /* Define if you have the wait3 function.  */
-#undef HAVE_WAIT3
+/* #undef HAVE_WAIT3 */
 
 /* Define if you have the waitpid function.  */
-#undef HAVE_WAITPID
+/* #undef HAVE_WAITPID */
 
 /* Define if you have the <dirent.h> header file.  */
 #undef HAVE_DIRENT_H
 #define HAVE_LIMITS_H 1
 
 /* Define if you have the <mach/mach.h> header file.  */
-#undef HAVE_MACH_MACH_H
+/* #undef HAVE_MACH_MACH_H */
 
 /* Define if you have the <memory.h> header file.  */
 #undef HAVE_MEMORY_H
 #define HAVE_MEMORY_H 1
 
 /* Define if you have the <ndir.h> header file.  */
-#undef HAVE_NDIR_H
+/* #undef HAVE_NDIR_H */
 
 /* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 #define HAVE_STRING_H 1
 
 /* Define if you have the <sys/dir.h> header file.  */
-#undef HAVE_SYS_DIR_H
+/* #undef HAVE_SYS_DIR_H */
 
 /* Define if you have the <sys/ndir.h> header file.  */
-#undef HAVE_SYS_NDIR_H
+/* #undef HAVE_SYS_NDIR_H */
 
 /* Define if you have the <sys/param.h> header file.  */
-#undef HAVE_SYS_PARAM_H
+/* #undef HAVE_SYS_PARAM_H */
 
 /* Define if you have the <sys/timeb.h> header file.  */
 #undef HAVE_SYS_TIMEB_H
 #define HAVE_SYS_TIMEB_H 1
 
 /* Define if you have the <sys/wait.h> header file.  */
-#undef HAVE_SYS_WAIT_H
+/* #undef HAVE_SYS_WAIT_H */
 
 /* Define if you have the <unistd.h> header file.  */
-#undef HAVE_UNISTD_H
+/* #undef HAVE_UNISTD_H */
 
 /* Define if you have the dgc library (-ldgc).  */
-#undef HAVE_LIBDGC
+/* #undef HAVE_LIBDGC */
+
+/* Define if you have the kstat library (-lkstat).  */
+/* #undef HAVE_LIBKSTAT */
 
 /* Define if you have the sun library (-lsun).  */
-#undef HAVE_LIBSUN
+/* #undef HAVE_LIBSUN */
 
 /*
  * Refer to README.W32 for info on the following settings
index 8fb99f7..ebc9cdf 100644 (file)
@@ -3,9 +3,8 @@ AC_REVISION([$Id$])
 AC_PREREQ(2.12)dnl             dnl Minimum Autoconf version required.
 AC_INIT(vpath.c)dnl            dnl A distinctive file to look for in srcdir.
 
-AM_INIT_AUTOMAKE(make, 3.77)
+AM_INIT_AUTOMAKE(make, 3.77.90)
 AM_CONFIG_HEADER(config.h)
-AC_CONFIG_SUBDIRS(glob)
 
 AM_CONDITIONAL(MAINT_MAKEFILE, test -r $srcdir/maintMakefile)
 
@@ -14,6 +13,8 @@ dnl Regular configure stuff
 AC_PROG_MAKE_SET
 AC_PROG_CC
 AC_PROG_INSTALL
+AC_CHECK_PROG(AR, ar, ar, ar)
+AC_PROG_RANLIB
 AC_PROG_CPP                    dnl Later checks need this.
 dnl AC_ARG_PROGRAM -- implied by AM_INIT_AUTOMAKE; gives errors if run twice.
 AC_AIX
@@ -30,12 +31,15 @@ AC_HEADER_DIRENT
 AC_TYPE_UID_T                  dnl Also does gid_t.
 AC_TYPE_PID_T
 AC_TYPE_SIGNAL
-AC_CHECK_HEADERS(unistd.h limits.h sys/param.h fcntl.h string.h memory.h \
-                sys/timeb.h)
+AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/param.h fcntl.h string.h \
+                memory.h sys/timeb.h)
 AC_PROG_CC_C_O
 AC_C_CONST                     dnl getopt needs this.
 AC_HEADER_STAT
 
+AC_STRUCT_ST_MTIM_NSEC
+jm_AC_TYPE_UINTMAX_T
+
 AC_SUBST(LIBOBJS)
 
 AC_DEFUN(AC_CHECK_SYMBOL, [dnl
@@ -51,19 +55,25 @@ changequote([,])dnl
 fi
 AC_MSG_RESULT($ac_cv_check_symbol_$1)])dnl
 
+# clock_gettime is in -lposix4 in Solaris 2.6.
+AC_CHECK_LIB(posix4, clock_gettime)
+
 AC_CHECK_FUNCS(memmove psignal mktemp pstat_getdynamic \
-              dup2 getcwd sigsetmask getgroups setlinebuf \
+              clock_gettime dup2 getcwd sigsetmask getgroups setlinebuf \
               seteuid setegid setreuid setregid strerror strsignal)
 AC_CHECK_SYMBOL(sys_siglist)
 AC_FUNC_ALLOCA
 AC_FUNC_VFORK
+AC_FUNC_VPRINTF
+AC_FUNC_STRCOLL
+AC_FUNC_CLOSEDIR_VOID
 AC_FUNC_SETVBUF_REVERSED
 AC_FUNC_GETLOADAVG
 AC_CHECK_LIB(kstat, kstat_open)
-AC_FUNC_STRCOLL
 
 # Check out the wait reality.
-AC_CHECK_HEADERS(sys/wait.h) AC_CHECK_FUNCS(waitpid wait3)
+AC_CHECK_HEADERS(sys/wait.h)
+AC_CHECK_FUNCS(waitpid wait3)
 AC_MSG_CHECKING(for union wait)
 AC_CACHE_VAL(make_cv_union_wait, [dnl
 AC_TRY_LINK([#include <sys/types.h>
@@ -137,7 +147,7 @@ if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 &&
 fi
 rm -f s.conftest conftoast
 
-AC_OUTPUT(Makefile build.sh)
+AC_OUTPUT(Makefile glob/Makefile build.sh)
 
 case "$make_badcust" in
   yes) echo
@@ -159,6 +169,15 @@ case "$with_customs" in
      fi ;;
 esac
 
+case "$ac_cv_func_waitpid/$ac_cv_func_wait3" in
+  no/no) echo
+         echo "WARNING: Your system has neither waitpid() nor wait3()."
+         echo "         Without one of these, signal handling is unreliable."
+         echo "         You should be aware that run GNU make with -j could"
+         echo "         result in erratic behavior."
+         echo ;;
+esac
+
 dnl Local Variables:
 dnl comment-start: "dnl "
 dnl comment-end: ""
index 653bc81..06f56fa 100644 (file)
--- a/default.c
+++ b/default.c
@@ -468,7 +468,7 @@ install_default_suffix_rules ()
       if (f->cmds == 0)
        {
          f->cmds = (struct commands *) xmalloc (sizeof (struct commands));
-         f->cmds->filename = 0;
+         f->cmds->fileinfo.filenm = 0;
          f->cmds->commands = s[1];
          f->cmds->command_lines = 0;
        }
diff --git a/dep.h b/dep.h
index fa3e073..2f9561c 100644 (file)
--- a/dep.h
+++ b/dep.h
@@ -16,6 +16,16 @@ You should have received a copy of the GNU General Public License
 along with GNU Make; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+/* Flag bits for the second argument to `read_makefile'.
+   These flags are saved in the `changed' field of each
+   `struct dep' in the chain returned by `read_all_makefiles'.  */
+
+#define RM_NO_DEFAULT_GOAL     (1 << 0) /* Do not set default goal.  */
+#define RM_INCLUDED            (1 << 1) /* Search makefile search path.  */
+#define RM_DONTCARE            (1 << 2) /* No error if it doesn't exist.  */
+#define RM_NO_TILDE            (1 << 3) /* Don't expand ~ in file name.  */
+#define RM_NOFLAG              0
+
 /* Structure representing one dependency of a file.
    Each struct file's `deps' points to a chain of these,
    chained through the `next'.
@@ -59,13 +69,7 @@ extern struct nameseq *ar_glob PARAMS ((char *arname, char *member_pattern, unsi
 extern char *dep_name ();
 #endif
 
+extern struct dep *copy_dep_chain PARAMS ((struct dep *d));
 extern struct dep *read_all_makefiles PARAMS ((char **makefiles));
-
-/* Flag bits for the second argument to `read_makefile'.
-   These flags are saved in the `changed' field of each
-   `struct dep' in the chain returned by `read_all_makefiles'.  */
-#define RM_NO_DEFAULT_GOAL     (1 << 0) /* Do not set default goal.  */
-#define RM_INCLUDED            (1 << 1) /* Search makefile search path.  */
-#define RM_DONTCARE            (1 << 2) /* No error if it doesn't exist.  */
-#define RM_NO_TILDE            (1 << 3) /* Don't expand ~ in file name.  */
-#define RM_NOFLAG              0
+extern int update_goal_chain PARAMS ((struct dep *goals, int makefiles));
+extern void uniquize_deps PARAMS ((struct dep *));
index 3f4bcfc..31c4024 100644 (file)
--- a/expand.c
+++ b/expand.c
@@ -95,17 +95,9 @@ recursively_expand (v)
   char *value;
 
   if (v->expanding)
-    {
-      /* Expanding V causes infinite recursion.  Lose.  */
-      if (reading_filename == 0)
-       fatal ("Recursive variable `%s' references itself (eventually)",
-              v->name);
-      else
-       makefile_fatal
-         (reading_filename, *reading_lineno_ptr,
-          "Recursive variable `%s' references itself (eventually)",
-          v->name);
-    }
+    /* Expanding V causes infinite recursion.  Lose.  */
+    fatal (reading_file,
+           "Recursive variable `%s' references itself (eventually)", v->name);
 
   v->expanding = 1;
   value = allocated_variable_expand (v->value);
@@ -125,14 +117,8 @@ warn_undefined (name, length)
      unsigned int length;
 {
   if (warn_undefined_variables_flag)
-    {
-      static const char warnmsg[] = "warning: undefined variable `%.*s'";
-      if (reading_filename != 0)
-       makefile_error (reading_filename, *reading_lineno_ptr,
-                       warnmsg, length, name);
-      else
-       error (warnmsg, length, name);
-    }
+    error (reading_file,
+           "warning: undefined variable `%.*s'", (int)length, name);
 }
 
 /* Expand a simple reference to variable NAME, which is LENGTH chars long.  */
@@ -243,14 +229,8 @@ variable_expand_string (line, string, length)
 
            end = index (beg, closeparen);
            if (end == 0)
-             {
-               /* Unterminated variable reference.  */
-               if (reading_filename != 0)
-                 makefile_fatal (reading_filename, *reading_lineno_ptr,
-                                 "unterminated variable reference");
-               else
-                 fatal ("unterminated variable reference");
-             }
+              /* Unterminated variable reference.  */
+              fatal (reading_file, "unterminated variable reference");
            p1 = lindex (beg, end, '$');
            if (p1 != 0)
              {
@@ -460,8 +440,7 @@ variable_expand_for_file (line, file)
 
   save = current_variable_set_list;
   current_variable_set_list = file->variables;
-  reading_filename = file->cmds->filename;
-  reading_lineno_ptr = &file->cmds->lineno;
+  reading_file = &file->cmds->fileinfo;
   fnext = file->variables->next;
   /* See if there's a pattern-specific variable struct for this target.  */
   if (!file->pat_searched)
@@ -476,8 +455,7 @@ variable_expand_for_file (line, file)
     }
   result = variable_expand (line);
   current_variable_set_list = save;
-  reading_filename = 0;
-  reading_lineno_ptr = 0;
+  reading_file = 0;
   file->variables->next = fnext;
 
   return result;
diff --git a/file.c b/file.c
index a60e70f..22e9584 100644 (file)
--- a/file.c
+++ b/file.c
@@ -16,13 +16,14 @@ You should have received a copy of the GNU General Public License
 along with GNU Make; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#include <assert.h>
+
 #include "make.h"
 #include "dep.h"
 #include "filedef.h"
 #include "job.h"
 #include "commands.h"
 #include "variable.h"
-#include <assert.h>
 
 
 /* Hash table of files the makefile knows how to make.  */
@@ -294,22 +295,22 @@ file_hash_enter (file, name, oldhash, oldname)
              /* We have two sets of commands.  We will go with the
                 one given in the rule explicitly mentioning this name,
                 but give a message to let the user know what's going on.  */
-             if (oldfile->cmds->filename != 0)
-               makefile_error (file->cmds->filename, file->cmds->lineno,
-                               "Commands were specified for \
-file `%s' at %s:%u,",
-                               oldname, oldfile->cmds->filename,
-                               oldfile->cmds->lineno);
+             if (oldfile->cmds->fileinfo.filenm != 0)
+                error (&file->cmds->fileinfo,
+                                "Commands were specified for \
+file `%s' at %s:%lu,",
+                                oldname, oldfile->cmds->fileinfo.filenm,
+                                oldfile->cmds->fileinfo.lineno);
              else
-               makefile_error (file->cmds->filename, file->cmds->lineno,
+               error (&file->cmds->fileinfo,
                                "Commands for file `%s' were found by \
 implicit rule search,",
                                oldname);
-             makefile_error (file->cmds->filename, file->cmds->lineno,
+             error (&file->cmds->fileinfo,
                              "but `%s' is now considered the same file \
 as `%s'.",
                              oldname, name);
-             makefile_error (file->cmds->filename, file->cmds->lineno,
+             error (&file->cmds->fileinfo,
                              "Commands for `%s' will be ignored \
 in favor of those for `%s'.",
                              name, oldname);
@@ -331,12 +332,12 @@ in favor of those for `%s'.",
       merge_variable_set_lists (&oldfile->variables, file->variables);
 
       if (oldfile->double_colon && file->is_target && !file->double_colon)
-       fatal ("can't rename single-colon `%s' to double-colon `%s'",
+       fatal (NILF, "can't rename single-colon `%s' to double-colon `%s'",
               oldname, name);
       if (!oldfile->double_colon  && file->double_colon)
        {
          if (oldfile->is_target)
-           fatal ("can't rename double-colon `%s' to single-colon `%s'",
+           fatal (NILF, "can't rename double-colon `%s' to single-colon `%s'",
                   oldname, name);
          else
            oldfile->double_colon = file->double_colon;
@@ -401,7 +402,7 @@ remove_intermediates (sig)
          if (!f->dontcare)
            {
              if (sig)
-               error ("*** Deleting intermediate file `%s'", f->name);
+               error (NILF, "*** Deleting intermediate file `%s'", f->name);
              else if (!silent_flag)
                {
                  if (! doneany)
@@ -465,7 +466,7 @@ snap_deps ()
        {
          /* Mark this file as phony and nonexistent.  */
          f2->phony = 1;
-         f2->last_mtime = (time_t) -1;
+         f2->last_mtime = (FILE_TIMESTAMP) -1;
        }
 
   for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev)
@@ -549,6 +550,51 @@ set_command_state (file, state)
     d->file->command_state = state;
 }
 \f
+/* Get and print file timestamps.  */
+
+FILE_TIMESTAMP
+file_timestamp_now ()
+{
+#if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
+  struct timespec timespec;
+  if (clock_gettime (CLOCK_REALTIME, &timespec) == 0)
+    return FILE_TIMESTAMP_FROM_S_AND_NS (timespec.tv_sec, timespec.tv_nsec);
+#endif
+  return FILE_TIMESTAMP_FROM_S_AND_NS (time ((time_t *) 0), 0);
+}
+
+void
+file_timestamp_sprintf (p, ts)
+     char *p;
+     FILE_TIMESTAMP ts;
+{
+  time_t t = FILE_TIMESTAMP_S (ts);
+  struct tm *tm = localtime (&t);
+
+  if (tm)
+    sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
+            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+            tm->tm_hour, tm->tm_min, tm->tm_sec);
+  else if (t < 0)
+    sprintf (p, "%ld", (long) t);
+  else
+    sprintf (p, "%lu", (unsigned long) t);
+  p += strlen (p);
+
+  /* Append nanoseconds as a fraction, but remove trailing zeros.
+     We don't know the actual timestamp resolution, since clock_getres
+     applies only to local times, whereas this timestamp might come
+     from a remote filesystem.  So removing trailing zeros is the
+     best guess that we can do.  */
+  sprintf (p, ".%09ld", (long) FILE_TIMESTAMP_NS (ts));
+  p += strlen (p) - 1;
+  while (*p == '0')
+    p--;
+  p += *p != '.';
+
+  *p = '\0';
+}
+\f
 /* Print the data base of files.  */
 
 static void
@@ -587,13 +633,16 @@ print_file (f)
        printf (" %s", dep_name (d));
       putchar ('\n');
     }
-  if (f->last_mtime == (time_t) 0)
+  if (f->last_mtime == 0)
     puts ("#  Modification time never checked.");
-  else if (f->last_mtime == (time_t) -1)
+  else if (f->last_mtime == (FILE_TIMESTAMP) -1)
     puts ("#  File does not exist.");
   else
-    printf ("#  Last modified %.24s (%ld)\n",
-           ctime (&f->last_mtime), (long int) f->last_mtime);
+    {
+      char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
+      file_timestamp_sprintf (buf, f->last_mtime);
+      printf ("#  Last modified %s\n", buf);
+    }
   printf ("#  File has%s been updated.\n",
          f->updated ? "" : " not");
   switch (f->command_state)
index a5de0a1..6ee5214 100644 (file)
--- a/filedef.h
+++ b/filedef.h
@@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License
 along with GNU Make; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+
 /* Structure that represents the info on one file
    that the makefile says how to make.
    All of these are chained together through `next'.  */
@@ -32,7 +33,7 @@ struct file
     char *stem;                        /* Implicit stem, if an implicit
                                   rule has been used */
     struct dep *also_make;     /* Targets that are made by making this.  */
-    time_t last_mtime;         /* File's modtime, if already known.  */
+    FILE_TIMESTAMP last_mtime; /* File's modtime, if already known.  */
     struct file *prev;         /* Previous entry for same file name;
                                   used when there are multiple double-colon
                                   entries for the same file.  */
@@ -96,11 +97,62 @@ extern unsigned int num_intermediates;
 extern struct file *default_goal_file, *suffix_file, *default_file;
 
 
-extern struct file *lookup_file (), *enter_file ();
-extern void remove_intermediates (), snap_deps ();
-extern void rename_file (), rehash_file (), file_hash_enter ();
-extern void set_command_state ();
-
+extern struct file *lookup_file PARAMS ((char *name));
+extern struct file *enter_file PARAMS ((char *name));
+extern void remove_intermediates PARAMS ((int sig));
+extern void snap_deps PARAMS ((void));
+extern void rename_file PARAMS ((struct file *file, char *name));
+extern void rehash_file PARAMS ((struct file *file, char *name));
+extern void file_hash_enter PARAMS ((struct file *file, char *name,
+                                     unsigned int oldhash, char *oldname));
+extern void set_command_state PARAMS ((struct file *file, int state));
+extern void notice_finished_file PARAMS ((struct file *file));
+
+
+#if ST_MTIM_NSEC
+# define FILE_TIMESTAMP_STAT_MODTIME(st) \
+    FILE_TIMESTAMP_FROM_S_AND_NS ((st).st_mtim.tv_sec, \
+                                  (st).st_mtim.ST_MTIM_NSEC)
+# define FILE_TIMESTAMPS_PER_S \
+    MIN ((FILE_TIMESTAMP) 1000000000, \
+         (INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) \
+         / INTEGER_TYPE_MAXIMUM (time_t)))
+#else
+# define FILE_TIMESTAMP_STAT_MODTIME(st) ((st).st_mtime)
+# define FILE_TIMESTAMPS_PER_S 1
+#endif
+
+#define FILE_TIMESTAMP_FROM_S_AND_NS(s, ns) \
+    ((s) * FILE_TIMESTAMPS_PER_S \
+     + (ns) * FILE_TIMESTAMPS_PER_S / 1000000000)
+#define FILE_TIMESTAMP_DIV(a, b) ((a)/(b) - ((a)%(b) < 0))
+#define FILE_TIMESTAMP_MOD(a, b) ((a)%(b) + ((a)%(b) < 0) * (b))
+#define FILE_TIMESTAMP_S(ts) FILE_TIMESTAMP_DIV ((ts), FILE_TIMESTAMPS_PER_S)
+#define FILE_TIMESTAMP_NS(ts) \
+    (((FILE_TIMESTAMP_MOD ((ts), FILE_TIMESTAMPS_PER_S) * 1000000000) \
+       + (FILE_TIMESTAMPS_PER_S - 1)) \
+      / FILE_TIMESTAMPS_PER_S)
+
+/* Upper bound on length of string "YYYY-MM-DD HH:MM:SS.NNNNNNNNN"
+   representing a file timestamp.  The upper bound is not necessarily 19,
+   since the year might be less than -999 or greater than 9999.
+
+   Subtract one for the sign bit if in case file timestamps can be negative;
+   subtract FLOOR_LOG2_SECONDS_PER_YEAR to yield an upper bound on how many
+   file timestamp bits might affect the year;
+   302 / 1000 is log10 (2) rounded up;
+   add one for integer division truncation;
+   add one more for a minus sign if file timestamps can be negative;
+   add 4 to allow for any 4-digit epoch year (e.g. 1970);
+   add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN".  */
+#define FLOOR_LOG2_SECONDS_PER_YEAR 24
+#define FILE_TIMESTAMP_PRINT_LEN_BOUND \
+  (((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \
+    * 302 / 1000) \
+   + 1 + 1 + 4 + 25)
+
+extern FILE_TIMESTAMP file_timestamp_now PARAMS ((void));
+extern void file_timestamp_sprintf PARAMS ((char *p, FILE_TIMESTAMP ts));
 
 /* Return the mtime of file F (a struct file *), caching it.
    The value is -1 if the file does not exist.  */
@@ -110,9 +162,9 @@ extern void set_command_state ();
    we don't find it.
    The value is -1 if the file does not exist.  */
 #define file_mtime_no_search(f) file_mtime_1 ((f), 0)
-extern time_t f_mtime ();
+extern FILE_TIMESTAMP f_mtime PARAMS ((struct file *file, int search));
 #define file_mtime_1(f, v) \
-  ((f)->last_mtime != (time_t) 0 ? (f)->last_mtime : f_mtime ((f), v))
+  ((f)->last_mtime ? (f)->last_mtime : f_mtime ((f), v))
 
 /* Modtime value to use for `infinitely new'.  We used to get the current time
    from the system and use that whenever we wanted `new'.  But that causes
@@ -121,12 +173,13 @@ extern time_t f_mtime ();
    targets, which need to be considered newer than anything that depends on
    them, even if said dependents' modtimes are in the future.
 
-   If time_t is unsigned, its maximum value is the same as "(time_t) -1",
-   so use one less than that, because -1 is used for non-existing files.  */
+   If FILE_TIMESTAMP is unsigned, its maximum value is the same as
+   ((FILE_TIMESTAMP) -1), so use one less than that, because -1 is
+   used for non-existing files.  */
 #define NEW_MTIME \
-     (INTEGER_TYPE_SIGNED (time_t) \
-      ? INTEGER_TYPE_MAXIMUM (time_t) \
-      : (INTEGER_TYPE_MAXIMUM (time_t) - 1))
+     (INTEGER_TYPE_SIGNED (FILE_TIMESTAMP) \
+      ? INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) \
+      : (INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) - 1))
 
 #define check_renamed(file) \
   while ((file)->renamed != 0) (file) = (file)->renamed /* No ; here.  */
index 198ab44..13196eb 100644 (file)
@@ -319,12 +319,8 @@ int shell_function_pid = 0, shell_function_completed;
 
 /* Note this absorbs a semicolon and is safe to use in conditionals.  */
 #define BADARGS(func)  do {                                                   \
-  if (reading_filename != 0)                                                  \
-    makefile_fatal (reading_filename, *reading_lineno_ptr,                    \
-                   "insufficient arguments to function `%s'",                \
-                   func);                                                    \
-  else                                                                        \
-    fatal ("insufficient arguments to function `%s'", func); } while (0)
+    fatal (reading_file, "insufficient arguments to function `%s'", func);    \
+  } while (0)
 
 static char *
 expand_function (o, function, text, end)
@@ -395,11 +391,11 @@ expand_function (o, function, text, end)
 #endif  /* Not Amiga.  */
 
        /* For error messages.  */
-       if (reading_filename != 0)
+       if (reading_file != 0)
          {
-           error_prefix = (char *) alloca (strlen (reading_filename) + 100);
+           error_prefix = (char *) alloca (strlen(reading_file->filenm)+100);
            sprintf (error_prefix,
-                    "%s:%u: ", reading_filename, *reading_lineno_ptr);
+                    "%s:%lu: ", reading_file->filenm, reading_file->lineno);
          }
        else
          error_prefix = "";
@@ -417,7 +413,7 @@ expand_function (o, function, text, end)
                            0,
                            TRUE,
                            DUPLICATE_SAME_ACCESS) == FALSE) {
-         fatal("create_child_process: DuplicateHandle(In) failed (e=%d)\n",
+         fatal (NILF, "create_child_process: DuplicateHandle(In) failed (e=%d)\n",
                GetLastError());
        }
        if (DuplicateHandle(GetCurrentProcess(),
@@ -427,17 +423,17 @@ expand_function (o, function, text, end)
                            0,
                            TRUE,
                            DUPLICATE_SAME_ACCESS) == FALSE) {
-         fatal("create_child_process: DuplicateHandle(Err) failed (e=%d)\n",
+         fatal (NILF, "create_child_process: DuplicateHandle(Err) failed (e=%d)\n",
                GetLastError());
        }
 
        if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
-         fatal("CreatePipe() failed (e=%d)\n", GetLastError());
+         fatal (NILF, "CreatePipe() failed (e=%d)\n", GetLastError());
 
        hProcess = process_init_fd(hIn, hChildOutWr, hErr);
 
        if (!hProcess)
-         fatal("expand_function: process_init_fd() failed\n");
+         fatal (NILF, "expand_function: process_init_fd() failed\n");
        else
          process_register(hProcess);
 
@@ -447,7 +443,7 @@ expand_function (o, function, text, end)
        if (!process_begin(hProcess, argv, envp, argv[0], NULL))
                pid = (int) hProcess;
        else
-               fatal("expand_function: unable to launch process (e=%d)\n",
+               fatal (NILF, "expand_function: unable to launch process (e=%d)\n",
                      process_last_err(hProcess));
 
        /* set up to read data from child */
@@ -1178,24 +1174,13 @@ expand_function (o, function, text, end)
       /* Check the first argument.  */
       for (p2 = text; *p2 != '\0'; ++p2)
        if (*p2 < '0' || *p2 > '9')
-         {
-           if (reading_filename != 0)
-             makefile_fatal (reading_filename, *reading_lineno_ptr,
-                             "non-numeric first argument to `word' function");
-           else
-             fatal ("non-numeric first argument to `word' function");
-         }
+          fatal (reading_file,
+                 "non-numeric first argument to `word' function");
 
       i = (unsigned int) atoi (text);
       if (i == 0)
-       {
-         if (reading_filename != 0)
-           makefile_fatal (reading_filename, *reading_lineno_ptr,
-                           "the `word' function takes a one-origin \
-index argument");
-         else
-           fatal ("the `word' function takes a one-origin index argument");
-       }
+        fatal (reading_file,
+               "the `word' function takes a one-origin index argument");
 
       p2 = p3;
       while ((p = find_next_token (&p2, &len)) != 0)
@@ -1245,13 +1230,8 @@ index argument");
       /* Check the first argument.  */
       for (p2 = text; *p2 != '\0'; ++p2)
        if (*p2 < '0' || *p2 > '9')
-         {
-           if (reading_filename != 0)
-             makefile_fatal (reading_filename, *reading_lineno_ptr,
-                             "non-numeric first argument to `wordlist' function");
-           else
-             fatal ("non-numeric first argument to `wordlist' function");
-         }
+          fatal (reading_file,
+                 "non-numeric first argument to `wordlist' function");
       i = (unsigned int)atoi(text);
       free (text);
 
@@ -1274,13 +1254,8 @@ index argument");
 
       for (p2 = text; *p2 != '\0'; ++p2)
        if (*p2 < '0' || *p2 > '9')
-         {
-           if (reading_filename != 0)
-             makefile_fatal (reading_filename, *reading_lineno_ptr,
-                             "non-numeric second argument to `wordlist' function");
-           else
-             fatal ("non-numeric second argument to `wordlist' function");
-         }
+          fatal (reading_file,
+                 "non-numeric second argument to `wordlist' function");
       j = (unsigned int)atoi(text);
       free (text);
 
@@ -1545,15 +1520,9 @@ handle_function (op, stringp)
        }
 
       if (count >= 0)
-       {
-         static const char errmsg[]
-           = "unterminated call to function `%s': missing `%c'";
-         if (reading_filename == 0)
-           fatal (errmsg, function_table[code].name, closeparen);
-         else
-           makefile_fatal (reading_filename, *reading_lineno_ptr, errmsg,
-                           function_table[code].name, closeparen);
-       }
+        fatal (reading_file,
+               "unterminated call to function `%s': missing `%c'",
+               function_table[code].name, closeparen);
 
       /* We found the end; expand the function call.  */
 
index 7c1cc80..36245ef 100644 (file)
@@ -1038,7 +1038,7 @@ getloadavg (loadavg, nelem)
 #endif /* ! HAVE_GETLOADAVG */
 \f
 #ifdef TEST
-void
+int
 main (argc, argv)
      int argc;
      char **argv;
index e3854a5..b7e85ad 100644 (file)
@@ -1,3 +1,8 @@
+1998-08-05  Paul D. Smith  <psmith@gnu.org>
+
+       * configure.in: Remove; configuration for glob is handled by the
+       make configure.in.
+
 1998-07-29  Paul D. Smith  <psmith@gnu.org>
 
        * glob.c, fnmatch.c: New versions from the GLIBC folks (Ulrich
index a999a0f..4be5cf5 100644 (file)
@@ -148,7 +148,7 @@ pattern_search (file, archive, depth, recursions)
      that is not just `%'.  */
   int specific_rule_matched = 0;
 
-  register unsigned int i;
+  register unsigned int i = 0;  /* uninit checks OK */
   register struct rule *rule;
   register struct dep *dep;
 
@@ -342,6 +342,8 @@ pattern_search (file, archive, depth, recursions)
          deps_found = 0;
          for (dep = rule->deps; dep != 0; dep = dep->next)
            {
+              struct file *fp;
+
              /* If the dependency name has a %, substitute the stem.  */
              p = index (dep_name (dep), '%');
              if (p != 0)
@@ -390,9 +392,12 @@ pattern_search (file, archive, depth, recursions)
                 dependency file we are actually looking for is in a different
                 directory (the one gotten by prepending FILENAME's directory),
                 so it might actually exist.  */
+              /* If we find a file but the intermediate flag is set, then it
+                 was put here by a .INTERMEDIATE: rule so ignore it.  */
 
              if ((!dep->changed || check_lastslash)
-                 && (lookup_file (p) != 0 || file_exists_p (p)))
+                 && (((fp = lookup_file (p)) != 0 && !fp->intermediate)
+                      || file_exists_p (p)))
                {
                  found_files[deps_found++] = savestring (p, strlen (p));
                  continue;
@@ -400,7 +405,7 @@ pattern_search (file, archive, depth, recursions)
              /* This code, given FILENAME = "lib/foo.o", dependency name
                 "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c".  */
              vp = p;
-             if (vpath_search (&vp, (time_t *) 0))
+             if (vpath_search (&vp, (FILE_TIMESTAMP *) 0))
                {
                  DEBUGP2 ("Found dependency `%s' as VPATH `%s'\n", p, vp);
                  strcpy(vp, p);
diff --git a/job.c b/job.c
index 91bc30b..fcdd2f1 100644 (file)
--- a/job.c
+++ b/job.c
@@ -29,25 +29,25 @@ char *default_shell = "sh.exe";
 int no_default_sh_exe = 1;
 int batch_mode_shell = 1;
 #else  /* WINDOWS32 */
-#ifdef _AMIGA
+# ifdef _AMIGA
 char default_shell[] = "";
 extern int MyExecute (char **);
-#else /* _AMIGA */
-#ifdef __MSDOS__
+# else /* _AMIGA */
+#  ifdef __MSDOS__
 /* The default shell is a pointer so we can change it if Makefile
    says so.  It is without an explicit path so we get a chance
    to search the $PATH for it (since MSDOS doesn't have standard
    directories we could trust).  */
 char *default_shell = "command.com";
-#else  /* __MSDOS__ */
+#  else  /* __MSDOS__ */
 char default_shell[] = "/bin/sh";
-#endif /* __MSDOS__ */
+#  endif /* __MSDOS__ */
 int batch_mode_shell = 0;
-#endif /* _AMIGA */
+# endif /* _AMIGA */
 #endif /* WINDOWS32 */
 
 #ifdef __MSDOS__
-#include <process.h>
+# include <process.h>
 static int execute_by_shell;
 static int dos_pid = 123;
 int dos_status;
@@ -55,7 +55,7 @@ int dos_command_running;
 #endif /* __MSDOS__ */
 
 #ifdef _AMIGA
-#include <proto/dos.h>
+# include <proto/dos.h>
 static int amiga_pid = 123;
 static int amiga_status;
 static char amiga_bname[32];
@@ -63,101 +63,101 @@ static int amiga_batch_file;
 #endif /* Amiga.  */
 
 #ifdef VMS
-#include <time.h>
-#include <processes.h>
-#include <starlet.h>
-#include <lib$routines.h>
+# include <time.h>
+# include <processes.h>
+# include <starlet.h>
+# include <lib$routines.h>
 #endif
 
 #ifdef WINDOWS32
-#include <windows.h>
-#include <io.h>
-#include <process.h>
-#include "sub_proc.h"
-#include "w32err.h"
-#include "pathstuff.h"
+# include <windows.h>
+# include <io.h>
+# include <process.h>
+# include "sub_proc.h"
+# include "w32err.h"
+# include "pathstuff.h"
 #endif /* WINDOWS32 */
 
 #ifdef HAVE_FCNTL_H
-#include <fcntl.h>
+# include <fcntl.h>
 #else
-#include <sys/file.h>
+# include <sys/file.h>
 #endif
 
 #if defined (HAVE_SYS_WAIT_H) || defined (HAVE_UNION_WAIT)
-#include <sys/wait.h>
+# include <sys/wait.h>
 #endif
 
-#ifdef HAVE_WAITPID
-#define        WAIT_NOHANG(status)     waitpid (-1, (status), WNOHANG)
+#ifdef HAVE_WAITPID
+# define WAIT_NOHANG(status)   waitpid (-1, (status), WNOHANG)
 #else  /* Don't have waitpid.  */
-#ifdef HAVE_WAIT3
-#ifndef        wait3
+# ifdef HAVE_WAIT3
+#  ifndef wait3
 extern int wait3 ();
-#endif
-#define        WAIT_NOHANG(status)     wait3 ((status), WNOHANG, (struct rusage *) 0)
-#endif /* Have wait3.  */
-#endif /* Have waitpid.  */
+#  endif
+#  define WAIT_NOHANG(status)  wait3 ((status), WNOHANG, (struct rusage *) 0)
+# endif /* Have wait3.  */
+#endif /* Have waitpid.  */
 
-#if    !defined (wait) && !defined (POSIX)
+#if !defined (wait) && !defined (POSIX)
 extern int wait ();
 #endif
 
 #ifndef        HAVE_UNION_WAIT
 
-#define        WAIT_T int
-
-#ifndef        WTERMSIG
-#define WTERMSIG(x) ((x) & 0x7f)
-#endif
-#ifndef        WCOREDUMP
-#define WCOREDUMP(x) ((x) & 0x80)
-#endif
-#ifndef        WEXITSTATUS
-#define WEXITSTATUS(x) (((x) >> 8) & 0xff)
-#endif
-#ifndef        WIFSIGNALED
-#define WIFSIGNALED(x) (WTERMSIG (x) != 0)
-#endif
-#ifndef        WIFEXITED
-#define WIFEXITED(x) (WTERMSIG (x) == 0)
-#endif
+# define WAIT_T int
+
+# ifndef WTERMSIG
+#  define WTERMSIG(x) ((x) & 0x7f)
+# endif
+# ifndef WCOREDUMP
+#  define WCOREDUMP(x) ((x) & 0x80)
+# endif
+# ifndef WEXITSTATUS
+#  define WEXITSTATUS(x) (((x) >> 8) & 0xff)
+# endif
+# ifndef WIFSIGNALED
+#  define WIFSIGNALED(x) (WTERMSIG (x) != 0)
+# endif
+# ifndef WIFEXITED
+#  define WIFEXITED(x) (WTERMSIG (x) == 0)
+# endif
 
 #else  /* Have `union wait'.  */
 
-#define WAIT_T union wait
-#ifndef        WTERMSIG
-#define WTERMSIG(x)    ((x).w_termsig)
-#endif
-#ifndef        WCOREDUMP
-#define WCOREDUMP(x)   ((x).w_coredump)
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(x) ((x).w_retcode)
-#endif
-#ifndef        WIFSIGNALED
-#define        WIFSIGNALED(x)  (WTERMSIG(x) != 0)
-#endif
-#ifndef        WIFEXITED
-#define        WIFEXITED(x)    (WTERMSIG(x) == 0)
-#endif
+# define WAIT_T union wait
+# ifndef WTERMSIG
+#  define WTERMSIG(x) ((x).w_termsig)
+# endif
+# ifndef WCOREDUMP
+#  define WCOREDUMP(x) ((x).w_coredump)
+# endif
+# ifndef WEXITSTATUS
+#  define WEXITSTATUS(x) ((x).w_retcode)
+# endif
+# ifndef WIFSIGNALED
+#  define WIFSIGNALED(x) (WTERMSIG(x) != 0)
+# endif
+# ifndef WIFEXITED
+#  define WIFEXITED(x) (WTERMSIG(x) == 0)
+# endif
 
 #endif /* Don't have `union wait'.  */
 
 #ifdef VMS
-static int vms_jobsefnmask=0;
+static int vms_jobsefnmask = 0;
 #endif /* !VMS */
 
 #ifndef        HAVE_UNISTD_H
 extern int dup2 ();
 extern int execve ();
 extern void _exit ();
-#ifndef VMS
+# ifndef VMS
 extern int geteuid ();
 extern int getegid ();
 extern int setgid ();
 extern int getgid ();
-#endif
+# endif
 #endif
 
 extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file));
@@ -169,7 +169,6 @@ extern int start_remote_job_p PARAMS ((int));
 extern int remote_status PARAMS ((int *exit_code_ptr, int *signal_ptr,
                int *coredump_ptr, int block));
 
-RETSIGTYPE child_handler PARAMS ((int));
 static void free_child PARAMS ((struct child *));
 static void start_job_command PARAMS ((struct child *child));
 static int load_too_high PARAMS ((void));
@@ -224,21 +223,19 @@ child_error (target_name, exit_code, exit_sig, coredump, ignored)
 
 #ifdef VMS
   if (!(exit_code & 1))
-      error("*** [%s] Error 0x%x%s", target_name, exit_code, ((ignored)? " (ignored)" : ""));
+      error (NILF, "*** [%s] Error 0x%x%s", target_name, exit_code, ((ignored)? " (ignored)" : ""));
 #else
   if (exit_sig == 0)
-    error (ignored ? "[%s] Error %d (ignored)" :
+    error (NILF, ignored ? "[%s] Error %d (ignored)" :
           "*** [%s] Error %d",
           target_name, exit_code);
   else
-    error ("*** [%s] %s%s",
+    error (NILF, "*** [%s] %s%s",
           target_name, strsignal (exit_sig),
           coredump ? " (core dumped)" : "");
 #endif /* VMS */
 }
 \f
-static unsigned int dead_children = 0;
-
 #ifdef VMS
 /* Wait for nchildren children to terminate */
 static void
@@ -259,6 +256,13 @@ vmsWaitForChildren(int *status)
 #endif
 
 
+/* If we can't use waitpid() or wait3(), then we use a signal handler
+   to track the number of SIGCHLD's we got.  This is less robust.  */
+
+#ifndef WAIT_NOHANG
+
+static unsigned int dead_children = 0;
+
 /* Notice that a child died.
    reap_children should be called when convenient.  */
 RETSIGTYPE
@@ -271,6 +275,8 @@ child_handler (sig)
     printf ("Got a SIGCHLD; %d unreaped children.\n", dead_children);
 }
 
+#endif /* WAIT_NOHANG */
+
 extern int shell_function_pid, shell_function_completed;
 
 /* Reap dead children, storing the returned status and the new command
@@ -284,9 +290,12 @@ reap_children (block, err)
      int block, err;
 {
   WAIT_T status;
+#ifdef WAIT_NOHANG
+  int dead_children = 1;  /* Initially, assume we have some.  */
+#endif
 
   while ((children != 0 || shell_function_pid != 0) &&
-        (block || dead_children > 0))
+        (block || dead_children))
     {
       int remote = 0;
       register int pid;
@@ -295,13 +304,14 @@ reap_children (block, err)
       int child_failed;
       int any_remote, any_local;
 
-      if (err && dead_children == 0)
+      if (err && block)
        {
          /* We might block for a while, so let the user know why.  */
          fflush (stdout);
-         error ("*** Waiting for unfinished jobs....");
+         error (NILF, "*** Waiting for unfinished jobs....");
        }
 
+#ifndef WAIT_NOHANG
       /* We have one less dead child to reap.
         The test and decrement are not atomic; if it is compiled into:
                register = dead_children - 1;
@@ -316,6 +326,7 @@ reap_children (block, err)
 
       if (dead_children > 0)
        --dead_children;
+#endif
 
       any_remote = 0;
       any_local = shell_function_pid != 0;
@@ -338,8 +349,12 @@ reap_children (block, err)
       else
        pid = 0;
 
-      if (pid < 0)
+      if (pid > 0)
+       /* We got a remote child.  */
+       remote = 1;
+      else if (pid < 0)
        {
+          /* A remote status command failed miserably.  Punt.  */
        remote_status_lose:
 #ifdef EINTR
          if (errno == EINTR)
@@ -347,11 +362,11 @@ reap_children (block, err)
 #endif
          pfatal_with_name ("remote_status");
        }
-      else if (pid == 0)
+      else
        {
-#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
          /* No remote children.  Check for local children.  */
 
+#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
          if (any_local)
            {
 #ifdef VMS
@@ -371,15 +386,26 @@ reap_children (block, err)
 
          if (pid < 0)
            {
+              /* The wait*() failed miserably.  Punt.  */
 #ifdef EINTR
              if (errno == EINTR)
                continue;
 #endif
              pfatal_with_name ("wait");
            }
-         else if (pid == 0)
+         else if (pid > 0)
+           {
+             /* We got one; chop the status word up.  */
+             exit_code = WEXITSTATUS (status);
+             exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
+             coredump = WCOREDUMP (status);
+           }
+         else
            {
-             /* No local children.  */
+             /* No local children are dead.  */
+#ifdef WAIT_NOHANG
+              dead_children = 0;
+#endif
              if (block && any_remote)
                {
                  /* Now try a blocking wait for a remote child.  */
@@ -396,14 +422,7 @@ reap_children (block, err)
              else
                break;
            }
-         else
-           {
-             /* Chop the status word up.  */
-             exit_code = WEXITSTATUS (status);
-             exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
-             coredump = WCOREDUMP (status);
-           }
-#else  /* __MSDOS__, Amiga, WINDOWS32.  */
+#endif /* !__MSDOS__, !Amiga, !WINDOWS32.  */
 #ifdef __MSDOS__
          /* Life is very different on MSDOS.  */
          pid = dos_pid - 1;
@@ -423,39 +442,35 @@ reap_children (block, err)
          coredump = 0;
 #endif /* _AMIGA */
 #ifdef WINDOWS32
-      {
-        HANDLE hPID;
-        int err;
+          {
+            HANDLE hPID;
+            int err;
 
-        /* wait for anything to finish */
-        if (hPID = process_wait_for_any()) {
+            /* wait for anything to finish */
+            if (hPID = process_wait_for_any()) {
 
-          /* was an error found on this process? */
-          err = process_last_err(hPID);
+              /* was an error found on this process? */
+              err = process_last_err(hPID);
 
-          /* get exit data */
-          exit_code = process_exit_code(hPID);
+              /* get exit data */
+              exit_code = process_exit_code(hPID);
 
-          if (err)
-            fprintf(stderr, "make (e=%d): %s",
-              exit_code, map_windows32_error_to_string(exit_code));
+              if (err)
+                fprintf(stderr, "make (e=%d): %s",
+                  exit_code, map_windows32_error_to_string(exit_code));
 
-          /* signal */
-          exit_sig = process_signal(hPID);
+              /* signal */
+              exit_sig = process_signal(hPID);
 
-          /* cleanup process */
-          process_cleanup(hPID);
+              /* cleanup process */
+              process_cleanup(hPID);
 
-          coredump = 0;
-        }
-        pid = (int) hPID;
-      }
+              coredump = 0;
+            }
+            pid = (int) hPID;
+          }
 #endif /* WINDOWS32 */
-#endif /* Not __MSDOS__ */
        }
-      else
-       /* We got a remote child.  */
-       remote = 1;
 
       /* Check if this is the child of the `shell' function.  */
       if (!remote && pid == shell_function_pid)
@@ -478,14 +493,9 @@ reap_children (block, err)
 
       if (c == 0)
        {
-         /* An unknown child died.  */
-         char buf[100];
-         sprintf (buf, "Unknown%s job %d", remote ? " remote" : "", pid);
-         if (child_failed)
-           child_error (buf, exit_code, exit_sig, coredump,
-                        ignore_errors_flag);
-         else
-           error ("%s finished.", buf);
+         /* An unknown child died.
+             Ignore it; it was inherited from our invoker.  */
+          continue;
        }
       else
        {
@@ -495,17 +505,17 @@ reap_children (block, err)
                    (unsigned long int) c,
                    (long) c->pid, c->remote ? " (remote)" : "");
 
-      if (c->sh_batch_file) {
-         if (debug_flag)
-           printf("Cleaning up temporary batch file %s\n", c->sh_batch_file);
+          if (c->sh_batch_file) {
+            if (debug_flag)
+              printf("Cleaning up temp batch file %s\n", c->sh_batch_file);
 
-         /* just try and remove, don't care if this fails */
-         remove(c->sh_batch_file);
+            /* just try and remove, don't care if this fails */
+            remove(c->sh_batch_file);
 
-         /* all done with memory */
-         free(c->sh_batch_file);
-         c->sh_batch_file = NULL;
-      }
+            /* all done with memory */
+            free(c->sh_batch_file);
+            c->sh_batch_file = NULL;
+          }
 
          /* If this child had the good stdin, say it is now free.  */
          if (c->good_stdin)
@@ -661,12 +671,12 @@ extern sigset_t fatal_signal_set;
 void
 block_sigs ()
 {
-#ifdef  POSIX
+#ifdef POSIX
   (void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0);
 #else
-#ifdef HAVE_SIGSETMASK
+# ifdef HAVE_SIGSETMASK
   (void) sigblock (fatal_signal_mask);
-#endif
+# endif
 #endif
 }
 
@@ -1098,9 +1108,9 @@ start_waiting_job (c)
     case cs_running:
       c->next = children;
       if (debug_flag)
-       printf ("Putting child 0x%08lx PID %05d%s on the chain.\n",
+       printf ("Putting child 0x%08lx PID %ld%s on the chain.\n",
                (unsigned long int) c,
-               c->pid, c->remote ? " (remote)" : "");
+               (long) c->pid, c->remote ? " (remote)" : "");
       children = c;
       /* One more job slot is in use.  */
       ++job_slots_used;
@@ -1322,7 +1332,7 @@ load_too_high ()
        {
          if (errno == 0)
            /* An errno value of zero means getloadavg is just unsupported.  */
-           error ("cannot enforce load limits on this operating system");
+           error (NILF, "cannot enforce load limits on this operating system");
          else
            perror_with_name ("cannot enforce load limit: ", "getloadavg");
        }
@@ -1427,8 +1437,7 @@ int vmsHandleChildTerm(struct child *child)
            break;
 
          default:
-           error ("internal error: `%s' command_state \
-%d in child_handler", c->file->name);
+           error (NILF, "internal error: `%s' command_state", c->file->name);
            abort ();
            break;
          }
@@ -1682,7 +1691,7 @@ exec_command (argv, envp)
   switch (errno)
     {
     case ENOENT:
-      error ("%s: Command not found", argv[0]);
+      error (NILF, "%s: Command not found", argv[0]);
       break;
     case ENOEXEC:
       {
@@ -1711,7 +1720,7 @@ exec_command (argv, envp)
 
        execvp (shell, new_argv);
        if (errno == ENOENT)
-         error ("%s: Shell program not found", shell);
+         error (NILF, "%s: Shell program not found", shell);
        else
          perror_with_name ("execvp: ", shell);
        break;
@@ -2205,8 +2214,8 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
 
            p = next_token (p);
            --p;
-        if (unixy_shell && !batch_mode_shell)
-          *ap++ = '\\';
+            if (unixy_shell && !batch_mode_shell)
+              *ap++ = '\\';
            *ap++ = ' ';
            continue;
          }
@@ -2234,11 +2243,9 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
     *ap = '\0';
 
 #ifdef WINDOWS32
-    /*
-        * Some shells do not work well when invoked as 'sh -c  xxx' to run
-        * a command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems).
-        * In these cases, run commands via a script file.
-     */
+    /* Some shells do not work well when invoked as 'sh -c xxx' to run a
+       command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems).  In these
+       cases, run commands via a script file.  */
     if ((no_default_sh_exe || batch_mode_shell) && batch_filename_ptr) {
       FILE* batch = NULL;
       int id = GetCurrentProcessId();
@@ -2269,7 +2276,8 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
 
       /* create batch file to execute command */
       batch = fopen (*batch_filename_ptr, "w");
-      fputs ("@echo off\n", batch);
+      if (!unixy_shell)
+        fputs ("@echo off\n", batch);
       fputs (command_ptr, batch);
       fputc ('\n', batch);
       fclose (batch);
@@ -2305,7 +2313,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
       }
 #else
     else
-      fatal("%s (line %d) Invalid shell context (!unixy && !batch_mode_shell)\n",
+      fatal (NILF, "%s (line %d) Bad shell context (!unixy && !batch_mode_shell)\n",
             __FILE__, __LINE__);
 #endif
   }
diff --git a/job.h b/job.h
index eaac492..d60247a 100644 (file)
--- a/job.h
+++ b/job.h
@@ -44,7 +44,7 @@ struct child
 
     unsigned int good_stdin:1; /* Nonzero if this child has a good stdin.  */
     unsigned int deleted:1;    /* Nonzero if targets have been deleted.  */
-       char* sh_batch_file; /* used to execute shell commands via scripts */
+    char *sh_batch_file;        /* Script file for shell commands */
   };
 
 extern struct child *children;
diff --git a/main.c b/main.c
index dcffa37..efad30d 100644 (file)
--- a/main.c
+++ b/main.c
@@ -22,6 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "variable.h"
 #include "job.h"
 #include "commands.h"
+#include "rule.h"
 #include "getopt.h"
 #include <assert.h>
 #ifdef _AMIGA
@@ -41,7 +42,6 @@ extern void init_dir PARAMS ((void));
 extern void remote_setup PARAMS ((void));
 extern void remote_cleanup PARAMS ((void));
 extern RETSIGTYPE fatal_error_signal PARAMS ((int sig));
-extern RETSIGTYPE child_handler PARAMS ((int sig));
 
 extern void print_variable_data_base PARAMS ((void));
 extern void print_dir_data_base PARAMS ((void));
@@ -49,18 +49,22 @@ extern void print_rule_data_base PARAMS ((void));
 extern void print_file_data_base PARAMS ((void));
 extern void print_vpath_data_base PARAMS ((void));
 
+#if defined HAVE_WAITPID || defined HAVE_WAIT3
+# define HAVE_WAIT_NOHANG
+#endif
+
 #ifndef        HAVE_UNISTD_H
 extern int chdir ();
 #endif
 #ifndef        STDC_HEADERS
 #ifndef        sun                     /* Sun has an incorrect decl in a header.  */
-extern void exit ();
+extern void exit PARAMS ((int)) __attribute__ ((noreturn));
 #endif
 extern double atof ();
 #endif
 extern char *mktemp ();
 
-static void print_data_base PARAMS((void));
+static void print_data_base PARAMS ((void));
 static void print_version PARAMS ((void));
 static void decode_switches PARAMS ((int argc, char **argv, int env));
 static void decode_env_switches PARAMS ((char *envar, unsigned int len));
@@ -413,7 +417,7 @@ enter_command_line_file (name)
      char *name;
 {
   if (name[0] == '\0')
-    fatal ("empty string invalid as file name");
+    fatal (NILF, "empty string invalid as file name");
 
   if (name[0] == '~')
     {
@@ -664,8 +668,7 @@ int main (int argc, char ** argv)
 #endif
 
   default_goal_file = 0;
-  reading_filename = 0;
-  reading_lineno_ptr = 0;
+  reading_file = 0;
 
 #if defined (__MSDOS__) && !defined (_POSIX_SOURCE)
   /* Request the most powerful version of `system', to
@@ -722,6 +725,20 @@ int main (int argc, char ** argv)
 
 #undef FATAL_SIG
 
+  /* Do not ignore the child-death signal.  This must be done before
+     any children could possibly be created; otherwise, the wait
+     functions won't work on systems with the SVR4 ECHILD brain
+     damage, if our invoker is ignoring this signal.  */
+
+#ifdef HAVE_WAIT_NOHANG
+# if defined SIGCHLD
+  (void) signal (SIGCHLD, SIG_DFL);
+# endif
+# if defined SIGCLD && SIGCLD != SIGCHLD
+  (void) signal (SIGCLD, SIG_DFL);
+# endif
+#endif
+
   /* Make sure stdout is line-buffered.  */
 
 #ifdef HAVE_SETLINEBUF
@@ -782,7 +799,7 @@ int main (int argc, char ** argv)
 #ifdef HAVE_GETCWD
       perror_with_name ("getcwd: ", "");
 #else
-      error ("getwd: %s", current_directory);
+      error (NILF, "getwd: %s", current_directory);
 #endif
       current_directory[0] = '\0';
       directory_before_chdir = 0;
@@ -1051,7 +1068,7 @@ int main (int argc, char ** argv)
 #ifdef HAVE_GETCWD
          perror_with_name ("getcwd: ", "");
 #else
-         error ("getwd: %s", current_directory);
+         error (NILF, "getwd: %s", current_directory);
 #endif
          starting_directory = 0;
        }
@@ -1089,7 +1106,7 @@ int main (int argc, char ** argv)
 #endif
 
             if (stdin_nm)
-              fatal("Makefile from standard input specified twice.");
+              fatal (NILF, "Makefile from standard input specified twice.");
 
            outfile = fopen (name, "w");
            if (outfile == 0)
@@ -1126,14 +1143,20 @@ int main (int argc, char ** argv)
          }
     }
 
-  /* Set up to handle children dying.  This must be done before
-     reading in the makefiles so that `shell' function calls will work.  */
-
-#ifdef SIGCHLD
-  (void) signal (SIGCHLD, child_handler);
-#endif
-#ifdef SIGCLD
-  (void) signal (SIGCLD, child_handler);
+#ifndef HAVE_WAIT_NOHANG
+  {
+    extern RETSIGTYPE child_handler PARAMS ((int sig));
+
+    /* Set up to handle children dying.  This must be done before
+       reading in the makefiles so that `shell' function calls will work.
+       Note we only do this if we have to.   */
+# if defined SIGCHLD
+    (void) signal (SIGCHLD, child_handler);
+# endif
+# if defined SIGCLD && SIGCLD != SIGCHLD
+    (void) signal (SIGCLD, child_handler);
+# endif
+  }
 #endif
 
   /* Let the user send us SIGUSR1 to toggle the -d flag during the run.  */
@@ -1178,8 +1201,8 @@ int main (int argc, char ** argv)
     no_default_sh_exe = !find_and_set_default_shell(NULL);
 
   if (no_default_sh_exe && job_slots != 1) {
-    error("Do not specify -j or --jobs if sh.exe is not available.");
-    error("Resetting make for single job mode.");
+    error (NILF, "Do not specify -j or --jobs if sh.exe is not available.");
+    error (NILF, "Resetting make for single job mode.");
     job_slots = 1;
   }
 #endif /* WINDOWS32 */
@@ -1251,7 +1274,7 @@ int main (int argc, char ** argv)
     for (p = old_files->list; *p != 0; ++p)
       {
        f = enter_command_line_file (*p);
-       f->last_mtime = (time_t) 1;
+       f->last_mtime = (FILE_TIMESTAMP) 1;
        f->updated = 1;
        f->update_status = 0;
        f->command_state = cs_finished;
@@ -1273,7 +1296,7 @@ int main (int argc, char ** argv)
     {
       /* Update any makefiles if necessary.  */
 
-      time_t *makefile_mtimes = 0;
+      FILE_TIMESTAMP *makefile_mtimes = 0;
       unsigned int mm_idx = 0;
       char **nargv = argv;
       int nargc = argc;
@@ -1323,11 +1346,12 @@ int main (int argc, char ** argv)
            if (f == NULL || !f->double_colon)
              {
                if (makefile_mtimes == 0)
-                 makefile_mtimes = (time_t *) xmalloc (sizeof (time_t));
+                 makefile_mtimes = (FILE_TIMESTAMP *)
+                   xmalloc (sizeof (FILE_TIMESTAMP));
                else
-                 makefile_mtimes = (time_t *)
+                 makefile_mtimes = (FILE_TIMESTAMP *)
                    xrealloc ((char *) makefile_mtimes,
-                             (mm_idx + 1) * sizeof (time_t));
+                             (mm_idx + 1) * sizeof (FILE_TIMESTAMP));
                makefile_mtimes[mm_idx++] = file_mtime_no_search (d->file);
                last = d;
                d = d->next;
@@ -1373,13 +1397,13 @@ int main (int argc, char ** argv)
                     }
                   else if (! (d->changed & RM_DONTCARE))
                     {
-                      time_t mtime;
+                      FILE_TIMESTAMP mtime;
                       /* The update failed and this makefile was not
                          from the MAKEFILES variable, so we care.  */
-                      error ("Failed to remake makefile `%s'.",
+                      error (NILF, "Failed to remake makefile `%s'.",
                              d->file->name);
                       mtime = file_mtime_no_search (d->file);
-                      any_remade |= (mtime != (time_t) -1
+                      any_remade |= (mtime != (FILE_TIMESTAMP) -1
                                      && mtime != makefile_mtimes[i]);
                     }
                 }
@@ -1391,12 +1415,12 @@ int main (int argc, char ** argv)
                     if (d->changed & RM_INCLUDED)
                       /* An included makefile.  We don't need
                          to die, but we do want to complain.  */
-                      error ("Included makefile `%s' was not found.",
+                      error (NILF, "Included makefile `%s' was not found.",
                              dep_name (d));
                     else
                       {
                         /* A normal makefile.  We must die later.  */
-                        error ("Makefile `%s' was not found", dep_name (d));
+                        error (NILF, "Makefile `%s' was not found", dep_name (d));
                         any_failed = 1;
                       }
                   }
@@ -1461,7 +1485,7 @@ int main (int argc, char ** argv)
              else
                bad = 1;
              if (bad)
-               fatal ("Couldn't change back to original directory.");
+               fatal (NILF, "Couldn't change back to original directory.");
            }
 
 #ifndef _AMIGA
@@ -1570,14 +1594,14 @@ int main (int argc, char ** argv)
     else
       {
        if (read_makefiles == 0)
-         fatal ("No targets specified and no makefile found");
+         fatal (NILF, "No targets specified and no makefile found");
        else
-         fatal ("No targets");
+         fatal (NILF, "No targets");
       }
 
     /* If we detected some clock skew, generate one last warning */
     if (clock_skew_detected)
-      error("*** Warning:  Clock skew detected.  Your build may be incomplete.");
+      error (NILF, "*** Warning:  Clock skew detected.  Your build may be incomplete.");
 
     /* Exit.  */
     die (status);
@@ -1661,7 +1685,7 @@ handle_non_switch_argument (arg, env)
   if (arg[0] == '-' && arg[1] == '\0')
     /* Ignore plain `-' for compatibility.  */
     return;
-  v = try_variable_definition ((char *) 0, 0, arg, o_command);
+  v = try_variable_definition (0, arg, o_command);
   if (v != 0)
     {
       /* It is indeed a variable definition.  Record a pointer to
@@ -1825,7 +1849,7 @@ decode_switches (argc, argv, env)
                      if (i < 1)
                        {
                          if (doit)
-                           error ("the `-%c' option requires a \
+                           error (NILF, "the `-%c' option requires a \
 positive integral argument",
                                   cs->c);
                          bad = 1;
diff --git a/make.h b/make.h
index 58a0ff2..9f5af96 100644 (file)
--- a/make.h
+++ b/make.h
@@ -25,27 +25,27 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
    (which it would do because make.h was found in $srcdir).  */
 #include <config.h>
-#undef HAVE_CONFIG_H
-#define HAVE_CONFIG_H
+#undef  HAVE_CONFIG_H
+#define HAVE_CONFIG_H 1
 
 
 /* Use prototypes if available.  */
 #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
-#undef  PARAMS
-#define PARAMS(protos)  protos
+# undef  PARAMS
+# define PARAMS(protos)  protos
 #else /* Not C++ or ANSI C.  */
-#undef  PARAMS
-#define PARAMS(protos)  ()
+# undef  PARAMS
+# define PARAMS(protos)  ()
 #endif /* C++ or ANSI C.  */
 
 
-#ifdef CRAY
+#ifdef  CRAY
 /* This must happen before #include <signal.h> so
    that the declaration therein is changed.  */
-#define        signal  bsdsignal
+# define signal bsdsignal
 #endif
 
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <signal.h>
@@ -55,35 +55,35 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* SCO 3.2 "devsys 4.2" has a prototype for `ftime' in <time.h> that bombs
    unless <sys/timeb.h> has been included first.  Does every system have a
    <sys/timeb.h>?  If any does not, configure should check for it.  */
-#include <sys/timeb.h>
+# include <sys/timeb.h>
 #endif
 #include <time.h>
 #include <errno.h>
 
-#ifndef        errno
+#ifndef errno
 extern int errno;
 #endif
 
-#ifndef        isblank
-#define        isblank(c)      ((c) == ' ' || (c) == '\t')
+#ifndef isblank
+# define isblank(c)     ((c) == ' ' || (c) == '\t')
 #endif
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#ifdef  HAVE_UNISTD_H
+# include <unistd.h>
 /* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get
    POSIX.1 behavior with `cc -YPOSIX', which predefines POSIX itself!  */
-#if defined (_POSIX_VERSION) && !defined (ultrix) && !defined (VMS)
-#define        POSIX
-#endif
+# if defined (_POSIX_VERSION) && !defined (ultrix) && !defined (VMS)
+#  define POSIX 1
+# endif
 #endif
 
 /* Some systems define _POSIX_VERSION but are not really POSIX.1.  */
 #if (defined (butterfly) || defined (__arm) || (defined (__mips) && defined (_SYSTYPE_SVR3)) || (defined (sequent) && defined (i386)))
-#undef POSIX
+# undef POSIX
 #endif
 
 #if !defined (POSIX) && defined (_AIX) && defined (_POSIX_SOURCE)
-#define POSIX
+# define POSIX 1
 #endif
 
 #if defined (HAVE_SYS_SIGLIST) && !defined (SYS_SIGLIST_DECLARED)
@@ -91,54 +91,54 @@ extern char *sys_siglist[];
 #endif
 
 #if !defined (HAVE_SYS_SIGLIST) || !defined (HAVE_STRSIGNAL)
-#include "signame.h"
+# include "signame.h"
 #endif
 
 /* Some systems do not define NSIG in <signal.h>.  */
-#ifndef        NSIG
-#ifdef _NSIG
-#define        NSIG    _NSIG
-#else
-#define        NSIG    32
-#endif
+#ifndef NSIG
+# ifdef _NSIG
+#  define NSIG  _NSIG
+# else
+#  define NSIG  32
+# endif
 #endif
 
-#ifndef        RETSIGTYPE
-#define        RETSIGTYPE      void
+#ifndef RETSIGTYPE
+# define RETSIGTYPE     void
 #endif
 
-#ifndef        sigmask
-#define        sigmask(sig)    (1 << ((sig) - 1))
+#ifndef sigmask
+# define sigmask(sig)   (1 << ((sig) - 1))
 #endif
 
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
+#ifdef  HAVE_LIMITS_H
+# include <limits.h>
 #endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
+#ifdef  HAVE_SYS_PARAM_H
+# include <sys/param.h>
 #endif
 
-#ifndef        PATH_MAX
-#ifndef        POSIX
-#define        PATH_MAX        MAXPATHLEN
-#endif /* Not POSIX.  */
-#endif /* No PATH_MAX.  */
+#ifndef PATH_MAX
+# ifndef POSIX
+#  define PATH_MAX      MAXPATHLEN
+# endif
+#endif
 #ifndef MAXPATHLEN
-#define MAXPATHLEN 1024
-#endif /* No MAXPATHLEN.  */
+# define MAXPATHLEN 1024
+#endif
 
-#ifdef PATH_MAX
-#define        GET_PATH_MAX    PATH_MAX
-#define        PATH_VAR(var)   char var[PATH_MAX]
+#ifdef  PATH_MAX
+# define GET_PATH_MAX   PATH_MAX
+# define PATH_VAR(var)  char var[PATH_MAX]
 #else
-#define        NEED_GET_PATH_MAX
+# define NEED_GET_PATH_MAX 1
+# define GET_PATH_MAX   (get_path_max ())
+# define PATH_VAR(var)  char *var = (char *) alloca (GET_PATH_MAX)
 extern unsigned int get_path_max PARAMS ((void));
-#define        GET_PATH_MAX    (get_path_max ())
-#define        PATH_VAR(var)   char *var = (char *) alloca (GET_PATH_MAX)
 #endif
 
 #ifndef CHAR_BIT
-#define CHAR_BIT 8
+# define CHAR_BIT 8
 #endif
 
 /* Nonzero if the integer type T is signed.  */
@@ -150,171 +150,189 @@ extern unsigned int get_path_max PARAMS ((void));
   (! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))
 #define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t))
 
-#ifdef STAT_MACROS_BROKEN
-#ifdef S_ISREG
-#undef S_ISREG
-#endif
-#ifdef S_ISDIR
-#undef S_ISDIR
-#endif
-#endif /* STAT_MACROS_BROKEN.  */
+#ifdef STAT_MACROS_BROKEN
+# ifdef S_ISREG
+#  undef S_ISREG
+# endif
+# ifdef S_ISDIR
+#  undef S_ISDIR
+# endif
+#endif  /* STAT_MACROS_BROKEN.  */
 
-#ifndef        S_ISREG
-#define        S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
+#ifndef S_ISREG
+# define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
 #endif
-#ifndef        S_ISDIR
-#define        S_ISDIR(mode)   (((mode) & S_IFMT) == S_IFDIR)
+#ifndef S_ISDIR
+# define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
 #endif
 
 #ifdef VMS
-#include <stdio.h>
-#include <types.h>
-#include <unixlib.h>
-#include <unixio.h>
-#include <errno.h>
-#include <perror.h>
+# include <stdio.h>
+# include <types.h>
+# include <unixlib.h>
+# include <unixio.h>
+# include <errno.h>
+# include <perror.h>
 #endif
 
-#if    (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) || defined(VMS))
-#include <stdlib.h>
-#include <string.h>
-#define        ANSI_STRING
-#else  /* No standard headers.  */
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#define        ANSI_STRING
-#else
-#include <strings.h>
-#endif
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
+#  define __attribute__(x)
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+   are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __format__ format
+#  define __printf__ printf
+# endif
 #endif
 
+#if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)
+# include <stdlib.h>
+# include <string.h>
+# define ANSI_STRING 1
+#else   /* No standard headers.  */
+# ifdef HAVE_STRING_H
+#  include <string.h>
+#  define ANSI_STRING 1
+# else
+#  include <strings.h>
+# endif
+# ifdef HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# else
 extern char *malloc PARAMS ((int));
 extern char *realloc PARAMS ((char *, int));
 extern void free PARAMS ((char *));
 
-extern void abort PARAMS ((void));
-extern void exit PARAMS ((int));
+extern void abort PARAMS ((void)) __attribute__ ((noreturn));
+extern void exit PARAMS ((int)) __attribute__ ((noreturn));
+# endif /* HAVE_STDLIB_H.  */
 
-#endif /* Standard headers.  */
+#endif /* Standard headers.  */
 
-#ifdef ANSI_STRING
-
-#ifndef        index
-#define        index(s, c)     strchr((s), (c))
-#endif
-#ifndef        rindex
-#define        rindex(s, c)    strrchr((s), (c))
+#if ST_MTIM_NSEC
+# if HAVE_INTTYPES_H
+#  include <inttypes.h>
+# endif
+# define FILE_TIMESTAMP uintmax_t
+#else
+# define FILE_TIMESTAMP time_t
 #endif
 
-#ifndef        bcmp
-#define bcmp(s1, s2, n)        memcmp ((s1), (s2), (n))
-#endif
-#ifndef        bzero
-#define bzero(s, n)    memset ((s), 0, (n))
-#endif
-#if defined(HAVE_MEMMOVE) && !defined(bcopy)
-#define bcopy(s, d, n) memmove ((d), (s), (n))
-#endif
+#ifdef  ANSI_STRING
 
-#else  /* Not ANSI_STRING.  */
+# ifndef index
+#  define index(s, c)       strchr((s), (c))
+# endif
+# ifndef rindex
+#  define rindex(s, c)      strrchr((s), (c))
+# endif
 
-#ifndef        bcmp
-extern int bcmp ();
-#endif
-#ifndef        bzero
-extern void bzero ();
-#endif
-#ifndef        bcopy
-extern void bcopy ();
+# ifndef bcmp
+#  define bcmp(s1, s2, n)   memcmp ((s1), (s2), (n))
+# endif
+# ifndef bzero
+#  define bzero(s, n)       memset ((s), 0, (n))
+# endif
+# if defined(HAVE_MEMMOVE) && !defined(bcopy)
+#  define bcopy(s, d, n)    memmove ((d), (s), (n))
+# endif
+
+#else   /* Not ANSI_STRING.  */
+
+# ifndef bcmp
+extern int bcmp PARAMS ((const char *, const char *, int));
+# endif
+# ifndef bzero
+extern void bzero PARAMS ((char *, int));
 #endif
+# ifndef bcopy
+extern void bcopy PARAMS ((const char *b1, char *b2, int));
+# endif
 
-#endif /* ANSI_STRING.  */
-#undef ANSI_STRING
+#endif  /* ANSI_STRING.  */
+#undef  ANSI_STRING
 
 /* SCO Xenix has a buggy macro definition in <string.h>.  */
-#undef strerror
+#undef  strerror
 
 #if !defined(ANSI_STRING) && !defined(__DECC)
 extern char *strerror PARAMS ((int errnum));
 #endif
 
-#ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
-#  define __attribute__(x)
-# endif
-#endif
-
-#ifdef __GNUC__
-#undef alloca
-#define        alloca(n)       __builtin_alloca (n)
-#else  /* Not GCC.  */
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#else  /* Not HAVE_ALLOCA_H.  */
-#ifndef        _AIX
+#ifdef __GNUC__
+# undef alloca
+# define alloca(n)      __builtin_alloca (n)
+#else   /* Not GCC.  */
+# ifdef HAVE_ALLOCA_H
+#  include <alloca.h>
+# else /* Not HAVE_ALLOCA_H.  */
+#  ifndef _AIX
 extern char *alloca ();
-#endif /* Not AIX.  */
-#endif /* HAVE_ALLOCA_H.  */
-#endif /* GCC.  */
-
-#ifndef        iAPX286
-#define streq(a, b) \
-  ((a) == (b) || \
-   (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
-#ifdef HAVE_CASE_INSENSITIVE_FS
-#define strieq(a, b) \
-  ((a) == (b) || \
-   (tolower(*(a)) == tolower(*(b)) && (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1))))
-#else
-#define strieq(a, b) \
-  ((a) == (b) || \
-   (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
-#endif
+#  endif /* Not AIX.  */
+# endif /* HAVE_ALLOCA_H.  */
+#endif /* GCC.  */
+
+#ifndef iAPX286
+# define streq(a, b) \
+   ((a) == (b) || \
+    (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
+# ifdef HAVE_CASE_INSENSITIVE_FS
+#  define strieq(a, b) \
+    ((a) == (b) || \
+     (tolower(*(a)) == tolower(*(b)) && (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1))))
+# else
+#  define strieq(a, b) \
+    ((a) == (b) || \
+     (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
+# endif
 #else
 /* Buggy compiler can't handle this.  */
-#define streq(a, b) (strcmp ((a), (b)) == 0)
-#define strieq(a, b) (strcmp ((a), (b)) == 0)
+# define streq(a, b) (strcmp ((a), (b)) == 0)
+# define strieq(a, b) (strcmp ((a), (b)) == 0)
 #endif
 
 /* Add to VAR the hashing value of C, one character in a name.  */
-#define        HASH(var, c) \
+#define HASH(var, c) \
   ((var += (c)), (var = ((var) << 7) + ((var) >> 20)))
 #ifdef HAVE_CASE_INSENSITIVE_FS /* Fold filenames */
-#define HASHI(var, c) \
-  ((var += tolower((c))), (var = ((var) << 7) + ((var) >> 20)))
+# define HASHI(var, c) \
+   ((var += tolower((c))), (var = ((var) << 7) + ((var) >> 20)))
 #else
-#define HASHI(var, c) HASH(var,c)
+# define HASHI(var, c) HASH(var,c)
 #endif
 
 #if defined(__GNUC__) || defined(ENUM_BITFIELDS)
-#define        ENUM_BITFIELD(bits)     :bits
+# define ENUM_BITFIELD(bits)    :bits
 #else
-#define        ENUM_BITFIELD(bits)
+# define ENUM_BITFIELD(bits)
 #endif
 
 #if defined(__MSDOS__) || defined(WINDOWS32)
-#define PATH_SEPARATOR_CHAR ';'
-#else
-#if defined(VMS)
-#define PATH_SEPARATOR_CHAR ','
+# define PATH_SEPARATOR_CHAR ';'
 #else
-#define PATH_SEPARATOR_CHAR ':'
-#endif
+# if defined(VMS)
+#  define PATH_SEPARATOR_CHAR ','
+# else
+#  define PATH_SEPARATOR_CHAR ':'
+# endif
 #endif
 
 #ifdef WINDOWS32
-#include <fcntl.h>
-#include <malloc.h>
-#define pipe(p) _pipe(p, 512, O_BINARY)
-#define kill(pid,sig) w32_kill(pid,sig)
+# include <fcntl.h>
+# include <malloc.h>
+# define pipe(p) _pipe(p, 512, O_BINARY)
+# define kill(pid,sig) w32_kill(pid,sig)
 
 extern void sync_Path_environment(void);
 extern int kill(int pid, int sig);
 extern int safe_stat(char *file, struct stat *sb);
-extern char *end_of_token_w32();
+extern char *end_of_token_w32(char *s, char stopchar);
 extern int find_and_set_default_shell(char *token);
 
 /* indicates whether or not we have Bourne shell */
@@ -323,72 +341,81 @@ extern int no_default_sh_exe;
 /* is default_shell unixy? */
 extern int unixy_shell;
 #endif  /* WINDOWS32 */
+
+struct floc
+  {
+    char *filenm;
+    unsigned long lineno;
+  };
+#define NILF ((struct floc *)0)
+
 \f
-extern void die () __attribute__ ((noreturn));
+/* Fancy processing for variadic functions in both ANSI and pre-ANSI
+   compilers.  */
+#if defined __STDC__ && __STDC__
+extern void message (int prefix, const char *fmt, ...)
+                     __attribute__ ((__format__ (__printf__, 2, 3)));
+extern void error (const struct floc *flocp, const char *fmt, ...)
+                   __attribute__ ((__format__ (__printf__, 2, 3)));
+extern void fatal (const struct floc *flocp, const char *fmt, ...)
+                   __attribute__ ((noreturn, __format__ (__printf__, 2, 3)));
+#else
 extern void message ();
-extern void fatal () __attribute__ ((noreturn));
 extern void error ();
-extern void log_working_directory ();
-extern void makefile_error ();
-extern void makefile_fatal () __attribute__ ((noreturn));
-extern void pfatal_with_name () __attribute__ ((noreturn));
-extern void perror_with_name ();
-extern char *savestring ();
-extern char *concat ();
-extern char *xmalloc ();
-extern char *xrealloc ();
-extern char *find_next_token ();
-extern char *next_token ();
-extern char *end_of_token ();
-extern void collapse_continuations ();
-extern void remove_comments ();
-extern char *sindex ();
-extern char *lindex ();
-extern int alpha_compare ();
-extern void print_spaces ();
-extern struct dep *copy_dep_chain ();
-extern char *find_char_unquote ();
-extern char *find_percent ();
-
-#ifndef        NO_ARCHIVES
-extern int ar_name ();
-extern void ar_parse_name ();
-extern int ar_touch ();
-extern time_t ar_member_date ();
-#endif
-
-extern void dir_load ();
-extern int dir_file_exists_p ();
-extern int file_exists_p ();
-extern int file_impossible_p ();
-extern void file_impossible ();
-extern char *dir_name ();
-
-extern void define_default_variables ();
-extern void set_default_suffixes ();
-extern void install_default_suffix_rules ();
-extern void install_default_implicit_rules ();
-extern void count_implicit_rule_limits ();
-extern void convert_to_pattern ();
-extern void create_pattern_rule ();
-
-extern void build_vpath_lists ();
-extern void construct_vpath_list ();
-extern int vpath_search ();
-extern int gpath_search ();
-
-extern void construct_include_path ();
-extern void uniquize_deps ();
-
-extern int update_goal_chain ();
-extern void notice_finished_file ();
-
-extern void user_access ();
-extern void make_access ();
-extern void child_access ();
-
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
+extern void fatal ();
+#endif
+
+extern void die PARAMS ((int)) __attribute__ ((noreturn));
+extern void log_working_directory PARAMS ((int));
+extern void pfatal_with_name PARAMS ((char *)) __attribute__ ((noreturn));
+extern void perror_with_name PARAMS ((char *, char *));
+extern char *savestring PARAMS ((char *, unsigned int));
+extern char *concat PARAMS ((char *, char *, char *));
+extern char *xmalloc PARAMS ((unsigned int));
+extern char *xrealloc PARAMS ((char *, unsigned int));
+extern char *find_next_token PARAMS ((char **, unsigned int *));
+extern char *next_token PARAMS ((char *));
+extern char *end_of_token PARAMS ((char *));
+extern void collapse_continuations PARAMS ((char *));
+extern void remove_comments PARAMS((char *));
+extern char *sindex PARAMS ((char *, unsigned int, char *, unsigned int));
+extern char *lindex PARAMS ((char *, char *, int));
+extern int alpha_compare PARAMS ((const void *, const void *));
+extern void print_spaces PARAMS ((unsigned int));
+extern char *find_char_unquote PARAMS ((char *, char *, int));
+extern char *find_percent PARAMS ((char *));
+
+#ifndef NO_ARCHIVES
+extern int ar_name PARAMS ((char *));
+extern void ar_parse_name PARAMS ((char *, char **, char **));
+extern int ar_touch PARAMS ((char *));
+extern time_t ar_member_date PARAMS ((char *));
+#endif
+
+extern int dir_file_exists_p PARAMS ((char *, char *));
+extern int file_exists_p PARAMS ((char *));
+extern int file_impossible_p PARAMS ((char *));
+extern void file_impossible PARAMS ((char *));
+extern char *dir_name PARAMS ((char *));
+
+extern void define_default_variables PARAMS ((void));
+extern void set_default_suffixes PARAMS ((void));
+extern void install_default_suffix_rules PARAMS ((void));
+extern void install_default_implicit_rules PARAMS ((void));
+
+extern void build_vpath_lists PARAMS ((void));
+extern void construct_vpath_list PARAMS ((char *pattern, char *dirpath));
+extern int vpath_search PARAMS ((char **file, FILE_TIMESTAMP *mtime_ptr));
+extern int gpath_search PARAMS ((char *file, int len));
+
+extern void construct_include_path PARAMS ((char **arg_dirs));
+
+extern void user_access PARAMS ((void));
+extern void make_access PARAMS ((void));
+extern void child_access PARAMS ((void));
+
+#ifdef  HAVE_VFORK_H
+# include <vfork.h>
 #endif
 
 /* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
@@ -397,26 +424,25 @@ extern void child_access ();
 #if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION) && !defined(WINDOWS32)
 
 extern long int atol ();
-#ifndef VMS
+# ifndef VMS
 extern long int lseek ();
-#endif
+# endif
 
-#endif /* Not GNU C library or POSIX.  */
+#endif  /* Not GNU C library or POSIX.  */
 
-#ifdef HAVE_GETCWD
+#ifdef  HAVE_GETCWD
 extern char *getcwd ();
-#ifdef VMS
+# ifdef VMS
 extern char *getwd PARAMS ((char *));
-#endif
+# endif
 #else
 extern char *getwd ();
-#define        getcwd(buf, len)        getwd (buf)
+# define getcwd(buf, len)       getwd (buf)
 #endif
 
-extern char **environ;
+extern const struct floc *reading_file;
 
-extern char *reading_filename;
-extern unsigned int *reading_lineno_ptr;
+extern char **environ;
 
 extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
 extern int debug_flag, print_data_base_flag, question_flag, touch_flag;
@@ -445,9 +471,16 @@ extern unsigned int commands_started;
 extern int handling_fatal_signal;
 
 
+#ifndef MIN
+#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
+#endif
+#ifndef MAX
+#define MAX(_a,_b) ((_a)>(_b)?(_a):(_b))
+#endif
+
 #define DEBUGPR(msg) \
   do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \
-                      fflush (stdout); } while (0)
+                       fflush (stdout); } while (0)
 
 #ifdef VMS
 # ifndef EXIT_FAILURE
@@ -470,4 +503,3 @@ extern int handling_fatal_signal;
 #  define EXIT_TROUBLE 1
 # endif
 #endif
-
index 05d0746..e7b3bbf 100644 (file)
@@ -68,17 +68,17 @@ by the Free Software Foundation.
 @titlepage
 @title GNU Make
 @subtitle A Program for Directing Recompilation
-@subtitle GNU @code{make} Version @value{VERSION}.
+@subtitle GNU @code{make} Version @value{VERSION}
 @subtitle @value{UPDATE-MONTH}
 @author Richard M. Stallman and Roland McGrath
 @page
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97 Free Software Foundation, Inc.
+Copyright @copyright{} 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98
+Free Software Foundation, Inc.
 @sp 2
 Published by the Free Software Foundation @*
 59 Temple Place -- Suite 330, @*
 Boston, MA 02111-1307 USA @*
-Printed copies are available for $20 each. @*
 ISBN @value{ISBN} @*
 
 Permission is granted to make and distribute verbatim copies of
@@ -124,7 +124,7 @@ This manual describes @code{make} and contains the following chapters:@refill
 * Conditionals::                Use or ignore parts of the makefile based
                                  on the values of variables.
 * Functions::                   Many powerful ways to manipulate text.
-* make Invocation: Running.     How to invoke @code{make} on the command line.
+* Invoking make: Running.       How to invoke @code{make} on the command line.
 * Implicit Rules::              Use implicit rules to treat many files alike,
                                  based on their file names.
 * Archives::                    How @code{make} can update library archives.
@@ -2241,8 +2241,7 @@ match that file's name.
 
 The targets which @code{.INTERMEDIATE} depends on are treated as
 intermediate files.  @xref{Chained Rules, ,Chains of Implicit Rules}.
-@code{.INTERMEDIATE} with no dependencies marks all file targets
-mentioned in the makefile as intermediate.
+@code{.INTERMEDIATE} with no dependencies has no effect.
 
 @findex .SECONDARY
 @item .SECONDARY
diff --git a/misc.c b/misc.c
index 1411e54..0612862 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -20,17 +20,52 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "dep.h"
 
 
+/* Variadic functions.  We go through contortions to allow proper function
+   prototypes for both ANSI and pre-ANSI C compilers, and also for those
+   which support stdarg.h vs. varargs.h, and finally those which have
+   vfprintf(), etc. and those who have _doprnt... or nothing.
+
+   This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and
+   VA_END macros used here since we have multiple print functions.  */
+
+#if HAVE_VPRINTF || HAVE_DOPRNT
+# define HAVE_STDVARARGS 1
+# if __STDC__
+#  include <stdarg.h>
+#  define VA_START(args, lastarg) va_start(args, lastarg)
+# else
+#  include <varargs.h>
+#  define VA_START(args, lastarg) va_start(args)
+# endif
+# if HAVE_VPRINTF
+#  define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
+# else
+#  define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
+# endif
+# define VA_END(args) va_end(args)
+#else
+/* # undef HAVE_STDVARARGS */
+# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+# define VA_START(args, lastarg)
+# define VA_END(args)
+#endif
+
+
 /* Compare strings *S1 and *S2.
    Return negative if the first is less, positive if it is greater,
    zero if they are equal.  */
 
 int
-alpha_compare (s1, s2)
-     char **s1, **s2;
+alpha_compare (v1, v2)
+     const void *v1, *v2;
 {
-  if (**s1 != **s2)
-    return **s1 - **s2;
-  return strcmp (*s1, *s2);
+  const char *s1 = *((char **)v1);
+  const char *s2 = *((char **)v2);
+
+  if (*s1 != *s2)
+    return *s1 - *s2;
+  return strcmp (s1, s2);
 }
 \f
 /* Discard each backslash-newline combination from LINE.
@@ -173,13 +208,22 @@ concat (s1, s2, s3)
 /* Print a message on stdout.  */
 
 void
-message (prefix, s1, s2, s3, s4, s5, s6)
+#if __STDC__ && HAVE_STDVARARGS
+message (int prefix, const char *fmt, ...)
+#else
+message (prefix, fmt, va_alist)
      int prefix;
-     char *s1, *s2, *s3, *s4, *s5, *s6;
+     const char *fmt;
+     va_dcl
+#endif
 {
+#if HAVE_STDVARARGS
+  va_list args;
+#endif
+
   log_working_directory (1);
 
-  if (s1 != 0)
+  if (fmt != 0)
     {
       if (prefix)
        {
@@ -188,78 +232,77 @@ message (prefix, s1, s2, s3, s4, s5, s6)
          else
            printf ("%s[%u]: ", program, makelevel);
        }
-      printf (s1, s2, s3, s4, s5, s6);
+      VA_START (args, fmt);
+      VA_PRINTF (stdout, fmt, args);
+      VA_END (args);
       putchar ('\n');
     }
 
   fflush (stdout);
 }
 
-/* Print an error message and exit.  */
+/* Print an error message.  */
 
-/* VARARGS1 */
 void
-fatal (s1, s2, s3, s4, s5, s6)
-     char *s1, *s2, *s3, *s4, *s5, *s6;
+#if __STDC__ && HAVE_STDVARARGS
+error (const struct floc *flocp, const char *fmt, ...)
+#else
+error (flocp, fmt, va_alist)
+     const struct floc *flocp;
+     const char *fmt;
+     va_dcl
+#endif
 {
-  log_working_directory (1);
-
-  if (makelevel == 0)
-    fprintf (stderr, "%s: *** ", program);
-  else
-    fprintf (stderr, "%s[%u]: *** ", program, makelevel);
-  fprintf (stderr, s1, s2, s3, s4, s5, s6);
-  fputs (".  Stop.\n", stderr);
-
-  die (2);
-}
-
-/* Print error message.  `s1' is printf control string, `s2' is arg for it. */
-
-/* VARARGS1 */
+#if HAVE_STDVARARGS
+  va_list args;
+#endif
 
-void
-error (s1, s2, s3, s4, s5, s6)
-     char *s1, *s2, *s3, *s4, *s5, *s6;
-{
   log_working_directory (1);
 
-  if (makelevel == 0)
+  if (flocp && flocp->filenm)
+    fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
+  else if (makelevel == 0)
     fprintf (stderr, "%s: ", program);
   else
     fprintf (stderr, "%s[%u]: ", program, makelevel);
-  fprintf (stderr, s1, s2, s3, s4, s5, s6);
-  putc ('\n', stderr);
-  fflush (stderr);
-}
 
-void
-makefile_error (file, lineno, s1, s2, s3, s4, s5, s6)
-     char *file;
-     unsigned int lineno;
-     char *s1, *s2, *s3, *s4, *s5, *s6;
-{
-  log_working_directory (1);
+  VA_START(args, fmt);
+  VA_PRINTF (stderr, fmt, args);
+  VA_END (args);
 
-  fprintf (stderr, "%s:%u: ", file, lineno);
-  fprintf (stderr, s1, s2, s3, s4, s5, s6);
   putc ('\n', stderr);
   fflush (stderr);
 }
 
+/* Print an error message and exit.  */
+
 void
-makefile_fatal (file, lineno, s1, s2, s3, s4, s5, s6)
-     char *file;
-     unsigned int lineno;
-     char *s1, *s2, *s3, *s4, *s5, *s6;
+#if __STDC__ && HAVE_STDVARARGS
+fatal (const struct floc *flocp, const char *fmt, ...)
+#else
+fatal (flocp, fmt, va_alist)
+     const struct floc *flocp;
+     const char *fmt;
+     va_dcl
+#endif
 {
-  if (!file)
-    fatal(s1, s2, s3, s4, s5, s6);
+#if HAVE_STDVARARGS
+  va_list args;
+#endif
 
   log_working_directory (1);
 
-  fprintf (stderr, "%s:%u: *** ", file, lineno);
-  fprintf (stderr, s1, s2, s3, s4, s5, s6);
+  if (flocp && flocp->filenm)
+    fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
+  else if (makelevel == 0)
+    fprintf (stderr, "%s: *** ", program);
+  else
+    fprintf (stderr, "%s[%u]: *** ", program, makelevel);
+
+  VA_START(args, fmt);
+  VA_PRINTF (stderr, fmt, args);
+  VA_END (args);
+
   fputs (".  Stop.\n", stderr);
 
   die (2);
@@ -293,7 +336,7 @@ void
 perror_with_name (str, name)
      char *str, *name;
 {
-  error ("%s%s: %s", str, name, strerror (errno));
+  error (NILF, "%s%s: %s", str, name, strerror (errno));
 }
 
 /* Print an error message from errno and exit.  */
@@ -302,7 +345,7 @@ void
 pfatal_with_name (name)
      char *name;
 {
-  fatal ("%s: %s", name, strerror (errno));
+  fatal (NILF, "%s: %s", name, strerror (errno));
 
   /* NOTREACHED */
 }
@@ -318,7 +361,7 @@ xmalloc (size)
 {
   char *result = (char *) malloc (size);
   if (result == 0)
-    fatal ("virtual memory exhausted");
+    fatal (NILF, "virtual memory exhausted");
   return result;
 }
 
@@ -330,7 +373,7 @@ xrealloc (ptr, size)
 {
   char *result = (char *) realloc (ptr, size);
   if (result == 0)
-    fatal ("virtual memory exhausted");
+    fatal (NILF, "virtual memory exhausted");
   return result;
 }
 
diff --git a/read.c b/read.c
index 0207516..a677399 100644 (file)
--- a/read.c
+++ b/read.c
@@ -119,26 +119,27 @@ static unsigned int max_incl_len;
 /* The filename and pointer to line number of the
    makefile currently being read in.  */
 
-char *reading_filename;
-unsigned int *reading_lineno_ptr;
+const struct floc *reading_file;
 
 /* The chain of makefiles read by read_makefile.  */
 
 static struct dep *read_makefiles = 0;
 
 static int read_makefile PARAMS ((char *filename, int flags));
-static unsigned int readline PARAMS ((struct linebuffer *linebuffer, FILE *stream,
-                       char *filename, unsigned int lineno));
-static unsigned int do_define PARAMS ((char *name, unsigned int namelen, enum variable_origin origin,
-                       unsigned int lineno, FILE *infile, char *filename));
-static int conditional_line PARAMS ((char *line, char *filename, unsigned int lineno));
+static unsigned long readline PARAMS ((struct linebuffer *linebuffer,
+                                       FILE *stream, const struct floc *flocp));
+static void do_define PARAMS ((char *name, unsigned int namelen,
+                               enum variable_origin origin, FILE *infile,
+                               struct floc *flocp));
+static int conditional_line PARAMS ((char *line, const struct floc *flocp));
 static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent,
                        struct dep *deps, unsigned int cmds_started, char *commands,
-                       unsigned int commands_idx, int two_colon, char *filename,
-                       unsigned int lineno, int set_default));
+                       unsigned int commands_idx, int two_colon,
+                       const struct floc *flocp, int set_default));
 static void record_target_var PARAMS ((struct nameseq *filenames, char *defn,
-                        int two_colon, enum variable_origin origin,
-                        char *filename, unsigned int lineno));
+                                       int two_colon,
+                                       enum variable_origin origin,
+                                       const struct floc *flocp));
 static enum make_word_type get_next_mword PARAMS ((char *buffer, char *delim,
                         char **startp, unsigned int *length));
 \f
@@ -290,11 +291,11 @@ read_makefile (filename, flags)
   int len, reading_target;
   int ignoring = 0, in_ignored_define = 0;
   int no_targets = 0;          /* Set when reading a rule without targets.  */
+  struct floc fileinfo;
   char *passed_filename = filename;
 
   struct nameseq *filenames = 0;
   struct dep *deps;
-  unsigned int lineno = 1;
   unsigned int nlines = 0;
   int two_colon = 0;
   char *pattern = 0, *pattern_percent;
@@ -310,19 +311,22 @@ read_makefile (filename, flags)
       if (filenames != 0)                                                    \
        record_files (filenames, pattern, pattern_percent, deps,              \
                      cmds_started, commands, commands_idx,                   \
-                     two_colon, filename, lineno,                            \
+                     two_colon, &fileinfo,                                   \
                      !(flags & RM_NO_DEFAULT_GOAL));                         \
       filenames = 0;                                                         \
       commands_idx = 0;                                                              \
       if (pattern) { free(pattern); pattern = 0; }                            \
     } while (0)
 
+  fileinfo.filenm = filename;
+  fileinfo.lineno = 1;
+
   pattern_percent = 0;
-  cmds_started = lineno;
+  cmds_started = fileinfo.lineno;
 
   if (debug_flag)
     {
-      printf ("Reading makefile `%s'", filename);
+      printf ("Reading makefile `%s'", fileinfo.filenm);
       if (flags & RM_NO_DEFAULT_GOAL)
        printf (" (no default goal)");
       if (flags & RM_INCLUDED)
@@ -398,8 +402,7 @@ read_makefile (filename, flags)
       return 0;
     }
 
-  reading_filename = filename;
-  reading_lineno_ptr = &lineno;
+  reading_file = &fileinfo;
 
   /* Loop over lines in the file.
      The strategy is to accumulate target names in FILENAMES, dependencies
@@ -410,8 +413,8 @@ read_makefile (filename, flags)
 
   while (!feof (infile))
     {
-      lineno += nlines;
-      nlines = readline (&lb, infile, filename, lineno);
+      fileinfo.lineno += nlines;
+      nlines = readline (&lb, infile, &fileinfo);
 
       /* Check for a shell command line first.
         If it is not one, we can stop treating tab specially.  */
@@ -437,7 +440,7 @@ read_makefile (filename, flags)
              /* Append this command line to the line being accumulated.  */
              p = lb.buffer;
              if (commands_idx == 0)
-               cmds_started = lineno;
+               cmds_started = fileinfo.lineno;
              len = strlen (p);
              if (len + 1 + commands_idx > commands_len)
                {
@@ -506,12 +509,11 @@ read_makefile (filename, flags)
              || word1eq ("ifeq", 4) || word1eq ("ifneq", 5)
              || word1eq ("else", 4) || word1eq ("endif", 5)))
        {
-         int i = conditional_line (p, filename, lineno);
+         int i = conditional_line (p, &fileinfo);
          if (i >= 0)
            ignoring = i;
          else
-           makefile_fatal (filename, lineno,
-                           "invalid syntax in conditional");
+           fatal (&fileinfo, "invalid syntax in conditional");
          continue;
        }
 
@@ -520,7 +522,7 @@ read_makefile (filename, flags)
          if (in_ignored_define)
            in_ignored_define = 0;
          else
-           makefile_fatal (filename, lineno, "extraneous `endef'");
+           fatal (&fileinfo, "extraneous `endef'");
          continue;
        }
 
@@ -538,8 +540,7 @@ read_makefile (filename, flags)
              p = index (p2, '\0');
              while (isblank (p[-1]))
                --p;
-             lineno = do_define (p2, p - p2, o_file,
-                                 lineno, infile, filename);
+             do_define (p2, p - p2, o_file, infile, &fileinfo);
            }
          continue;
        }
@@ -548,7 +549,7 @@ read_makefile (filename, flags)
         {
          p2 = next_token (p + 8);
          if (p2 == 0)
-           makefile_error (filename, lineno, "empty `override' directive");
+           error (&fileinfo, "empty `override' directive");
          if (!strncmp (p2, "define", 6) && (isblank (p2[6]) || p2[6] == '\0'))
            {
              if (ignoring)
@@ -563,14 +564,12 @@ read_makefile (filename, flags)
                  p = index (p2, '\0');
                  while (isblank (p[-1]))
                    --p;
-                 lineno = do_define (p2, p - p2, o_override,
-                                     lineno, infile, filename);
+                 do_define (p2, p - p2, o_override, infile, &fileinfo);
                }
            }
          else if (!ignoring
-                  && !try_variable_definition (filename, lineno,
-                                               p2, o_override))
-           makefile_error (filename, lineno, "empty `override' directive");
+                  && !try_variable_definition (&fileinfo, p2, o_override))
+           error (&fileinfo, "empty `override' directive");
 
          continue;
        }
@@ -587,7 +586,7 @@ read_makefile (filename, flags)
          p2 = next_token (p + 6);
          if (*p2 == '\0')
            export_all_variables = 1;
-         v = try_variable_definition (filename, lineno, p2, o_file);
+         v = try_variable_definition (&fileinfo, p2, o_file);
          if (v != 0)
            v->export = v_export;
          else
@@ -653,7 +652,7 @@ read_makefile (filename, flags)
          p = allocated_variable_expand (next_token (p + (noerror ? 8 : 7)));
          if (*p == '\0')
            {
-             makefile_error (filename, lineno,
+             error (&fileinfo,
                              "no file name for `%sinclude'",
                              noerror ? "-" : "");
              continue;
@@ -688,7 +687,7 @@ read_makefile (filename, flags)
              if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
                                          | (noerror ? RM_DONTCARE : 0)))
                  && ! noerror)
-               makefile_error (filename, lineno,
+               error (&fileinfo,
                                "%s: %s", name, strerror (errno));
               free(name);
            }
@@ -701,11 +700,10 @@ read_makefile (filename, flags)
 
          /* Restore state.  */
          conditionals = save;
-         reading_filename = filename;
-         reading_lineno_ptr = &lineno;
+         reading_file = &fileinfo;
        }
 #undef word1eq
-      else if (try_variable_definition (filename, lineno, p, o_file))
+      else if (try_variable_definition (&fileinfo, p, o_file))
        /* This line has been dealt with.  */
        ;
       else if (lb.buffer[0] == '\t')
@@ -720,7 +718,7 @@ read_makefile (filename, flags)
             because there was no preceding target, and the line
             might have been usable as a variable definition.
             But now it is definitely lossage.  */
-         makefile_fatal (filename, lineno,
+         fatal (&fileinfo,
                          "commands commence before first target");
        }
       else
@@ -739,6 +737,7 @@ read_makefile (filename, flags)
           enum variable_origin v_origin;
           char *cmdleft, *lb_next;
           unsigned int len, plen = 0;
+          char *colonp;
 
          /* Record the previous rule.  */
 
@@ -768,7 +767,7 @@ read_makefile (filename, flags)
             {
             case w_eol:
               if (cmdleft != 0)
-                makefile_fatal (filename, lineno,
+                fatal (&fileinfo,
                                 "missing rule before commands");
               else
                 /* This line contained a variable reference that
@@ -789,8 +788,6 @@ read_makefile (filename, flags)
           p2 = variable_expand_string(NULL, lb_next, len);
           while (1)
             {
-              char *colonp;
-
               lb_next += len;
               if (cmdleft == 0)
                 {
@@ -825,12 +822,12 @@ read_makefile (filename, flags)
               colonp = find_char_unquote(p2, ":", 0);
 #if defined(__MSDOS__) || defined(WINDOWS32)
              /* The drive spec brain-damage strikes again...  */
-             /* FIXME: is whitespace the only possible separator of words
-                in this context?  If not, the `isspace' test below will
-                need to be changed into a call to `index'.  */
+             /* Note that the only separators of targets in this context
+                are whitespace and a left paren.  If others are possible,
+                they should be added to the string in the call to index.  */
              while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
                     colonp > p2 && isalpha(colonp[-1]) &&
-                    (colonp == p2 + 1 || isspace(colonp[-2])))
+                    (colonp == p2 + 1 || index(" \t(", colonp[-2]) != 0))
                colonp = find_char_unquote(colonp + 1, ":", 0);
 #endif
               if (colonp != 0)
@@ -838,7 +835,11 @@ read_makefile (filename, flags)
 
               wtype = get_next_mword(lb_next, NULL, &lb_next, &len);
               if (wtype == w_eol)
-                makefile_fatal (filename, lineno, "missing separator");
+                /* There's no need to be ivory-tower about this: check for
+                   one of the most common bugs found in makefiles...  */
+                fatal (&fileinfo, "missing separator%s",
+                       strncmp(lb.buffer, "        ", 8) ? ""
+                       : " (did you mean TAB instead of 8 spaces?)");
 
               p2 += strlen(p2);
               *(p2++) = ' ';
@@ -850,10 +851,14 @@ read_makefile (filename, flags)
 
          p2 = next_token (variable_buffer);
 
-         filenames = multi_glob (parse_file_seq (&p2, ':',
+          /* Make the colon the end-of-string so we know where to stop
+             looking for targets.  */
+          *colonp = '\0';
+         filenames = multi_glob (parse_file_seq (&p2, '\0',
                                                  sizeof (struct nameseq),
                                                  1),
                                  sizeof (struct nameseq));
+          *colonp = ':';
 
           if (!filenames)
             {
@@ -896,8 +901,7 @@ read_makefile (filename, flags)
 
           if (wtype == w_varassign || v_origin == o_override)
             {
-              record_target_var(filenames, p, two_colon, v_origin,
-                                filename, lineno);
+              record_target_var(filenames, p, two_colon, v_origin, &fileinfo);
               filenames = 0;
               continue;
             }
@@ -959,7 +963,8 @@ read_makefile (filename, flags)
             check_again = 0;
             /* For MSDOS and WINDOWS32, skip a "C:\..." or a "C:/..." */
             if (p != 0 && (p[1] == '\\' || p[1] == '/') &&
-               isalpha(p[-1]) && (p == p2 + 1 || index(" \t:", p[-2]) != 0)) {
+               isalpha(p[-1]) &&
+               (p == p2 + 1 || index(" \t:(", p[-2]) != 0)) {
               p = index(p + 1, ':');
               check_again = 1;
             }
@@ -971,13 +976,13 @@ read_makefile (filename, flags)
              target = parse_file_seq (&p2, ':', sizeof (struct nameseq), 1);
              ++p2;
              if (target == 0)
-               makefile_fatal (filename, lineno, "missing target pattern");
+               fatal (&fileinfo, "missing target pattern");
              else if (target->next != 0)
-               makefile_fatal (filename, lineno, "multiple target patterns");
+               fatal (&fileinfo, "multiple target patterns");
              pattern = target->name;
              pattern_percent = find_percent (pattern);
              if (pattern_percent == 0)
-               makefile_fatal (filename, lineno,
+               fatal (&fileinfo,
                                "target pattern contains no `%%'");
               free((char *)target);
            }
@@ -995,7 +1000,7 @@ read_makefile (filename, flags)
              /* Semicolon means rest of line is a command.  */
              unsigned int len = strlen (cmdleft);
 
-             cmds_started = lineno;
+             cmds_started = fileinfo.lineno;
 
              /* Add this command line to the buffer.  */
              if (len + 2 > commands_len)
@@ -1019,7 +1024,7 @@ read_makefile (filename, flags)
     }
 
   if (conditionals->if_cmds)
-    makefile_fatal (filename, lineno, "missing `endif'");
+    fatal (&fileinfo, "missing `endif'");
 
   /* At eof, record the last rule.  */
   record_waiting_files ();
@@ -1028,8 +1033,7 @@ read_makefile (filename, flags)
   free ((char *) commands);
   fclose (infile);
 
-  reading_filename = 0;
-  reading_lineno_ptr = 0;
+  reading_file = 0;
 
   return 1;
 }
@@ -1040,14 +1044,13 @@ read_makefile (filename, flags)
    LINENO, INFILE and FILENAME refer to the makefile being read.
    The value returned is LINENO, updated for lines read here.  */
 
-static unsigned int
-do_define (name, namelen, origin, lineno, infile, filename)
+static void
+do_define (name, namelen, origin, infile, flocp)
      char *name;
      unsigned int namelen;
      enum variable_origin origin;
-     unsigned int lineno;
      FILE *infile;
-     char *filename;
+     struct floc *flocp;
 {
   struct linebuffer lb;
   unsigned int nlines = 0;
@@ -1067,8 +1070,8 @@ do_define (name, namelen, origin, lineno, infile, filename)
     {
       unsigned int len;
 
-      lineno += nlines;
-      nlines = readline (&lb, infile, filename, lineno);
+      flocp->lineno += nlines;
+      nlines = readline (&lb, infile, flocp);
 
       collapse_continuations (lb.buffer);
 
@@ -1080,8 +1083,7 @@ do_define (name, namelen, origin, lineno, infile, filename)
          p += 5;
          remove_comments (p);
          if (*next_token (p) != '\0')
-           makefile_error (filename, lineno,
-                           "Extraneous text after `endef' directive");
+           error (flocp, "Extraneous text after `endef' directive");
          /* Define the variable.  */
          if (idx == 0)
            definition[0] = '\0';
@@ -1090,7 +1092,7 @@ do_define (name, namelen, origin, lineno, infile, filename)
          (void) define_variable (var, strlen (var), definition, origin, 1);
          free (definition);
          freebuffer (&lb);
-         return (lineno + nlines);
+         return;
        }
       else
        {
@@ -1110,10 +1112,10 @@ do_define (name, namelen, origin, lineno, infile, filename)
     }
 
   /* No `endef'!!  */
-  makefile_fatal (filename, lineno, "missing `endef', unterminated `define'");
+  fatal (flocp, "missing `endef', unterminated `define'");
 
   /* NOTREACHED */
-  return 0;
+  return;
 }
 \f
 /* Interpret conditional commands "ifdef", "ifndef", "ifeq",
@@ -1128,10 +1130,9 @@ do_define (name, namelen, origin, lineno, infile, filename)
    1 if following text should be ignored.  */
 
 static int
-conditional_line (line, filename, lineno)
+conditional_line (line, flocp)
      char *line;
-     char *filename;
-     unsigned int lineno;
+     const struct floc *flocp;
 {
   int notdef;
   char *cmdname;
@@ -1165,17 +1166,16 @@ conditional_line (line, filename, lineno)
   if (*cmdname == 'e')
     {
       if (*line != '\0')
-       makefile_error (filename, lineno,
-                       "Extraneous text after `%s' directive",
-                       cmdname);
+       error (flocp,
+                        "Extraneous text after `%s' directive", cmdname);
       /* "Else" or "endif".  */
       if (conditionals->if_cmds == 0)
-       makefile_fatal (filename, lineno, "extraneous `%s'", cmdname);
+       fatal (flocp, "extraneous `%s'", cmdname);
       /* NOTDEF indicates an `endif' command.  */
       if (notdef)
        --conditionals->if_cmds;
       else if (conditionals->seen_else[conditionals->if_cmds - 1])
-       makefile_fatal (filename, lineno, "only one `else' per conditional");
+       fatal (flocp, "only one `else' per conditional");
       else
        {
          /* Toggle the state of ignorance.  */
@@ -1321,9 +1321,8 @@ conditional_line (line, filename, lineno)
       *line = '\0';
       line = next_token (++line);
       if (*line != '\0')
-       makefile_error (filename, lineno,
-                       "Extraneous text after `%s' directive",
-                       cmdname);
+       error (flocp,
+                        "Extraneous text after `%s' directive", cmdname);
 
       s2 = variable_expand (s2);
       conditionals->ignoring[conditionals->if_cmds - 1]
@@ -1384,13 +1383,12 @@ uniquize_deps (chain)
    variable value list.  */
 
 static void
-record_target_var (filenames, defn, two_colon, origin, filename, lineno)
+record_target_var (filenames, defn, two_colon, origin, flocp)
      struct nameseq *filenames;
      char *defn;
      int two_colon;
      enum variable_origin origin;
-     char *filename;
-     unsigned int lineno;
+     const struct floc *flocp;
 {
   struct nameseq *nextf;
   struct variable_set_list *global;
@@ -1433,10 +1431,9 @@ record_target_var (filenames, defn, two_colon, origin, filename, lineno)
 
       /* Make the new variable context current and define the variable.  */
       current_variable_set_list = vlist;
-      v = try_variable_definition(filename, lineno, defn, origin);
+      v = try_variable_definition(flocp, defn, origin);
       if (!v)
-        makefile_error(filename, lineno,
-                       "Malformed per-target variable definition");
+        error (flocp, "Malformed per-target variable definition");
       v->per_target = 1;
 
       /* If it's not an override, check to see if there was a command-line
@@ -1474,7 +1471,7 @@ record_target_var (filenames, defn, two_colon, origin, filename, lineno)
 
 static void
 record_files (filenames, pattern, pattern_percent, deps, cmds_started,
-             commands, commands_idx, two_colon, filename, lineno, set_default)
+             commands, commands_idx, two_colon, flocp, set_default)
      struct nameseq *filenames;
      char *pattern, *pattern_percent;
      struct dep *deps;
@@ -1482,8 +1479,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
      char *commands;
      unsigned int commands_idx;
      int two_colon;
-     char *filename;
-     unsigned int lineno;
+     const struct floc *flocp;
      int set_default;
 {
   struct nameseq *nextf;
@@ -1495,8 +1491,8 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
   if (commands_idx > 0)
     {
       cmds = (struct commands *) xmalloc (sizeof (struct commands));
-      cmds->filename = filename;
-      cmds->lineno = cmds_started;
+      cmds->fileinfo.filenm = flocp->filenm;
+      cmds->fileinfo.lineno = cmds_started;
       cmds->commands = savestring (commands, commands_idx);
       cmds->command_lines = 0;
     }
@@ -1519,11 +1515,10 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
       implicit |= implicit_percent != 0;
 
       if (implicit && pattern != 0)
-       makefile_fatal (filename, lineno,
-                       "mixed implicit and static pattern rules");
+       fatal (flocp, "mixed implicit and static pattern rules");
 
       if (implicit && implicit_percent == 0)
-       makefile_fatal (filename, lineno, "mixed implicit and normal rules");
+       fatal (flocp, "mixed implicit and normal rules");
 
       if (implicit)
        {
@@ -1562,7 +1557,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
        if (!pattern_matches (pattern, pattern_percent, name))
          {
            /* Give a warning if the rule is meaningless.  */
-           makefile_error (filename, lineno,
+           error (flocp,
                            "target `%s' doesn't match the target pattern",
                            name);
            this = 0;
@@ -1594,15 +1589,15 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
          f = enter_file (name);
 
          if (f->double_colon)
-           makefile_fatal (filename, lineno,
+           fatal (flocp,
                            "target file `%s' has both : and :: entries",
                            f->name);
 
          /* If CMDS == F->CMDS, this target was listed in this rule
             more than once.  Just give a warning since this is harmless.  */
          if (cmds != 0 && cmds == f->cmds)
-           makefile_error
-             (filename, lineno,
+           error
+             (flocp,
               "target `%s' given more than once in the same rule.",
               f->name);
 
@@ -1611,10 +1606,10 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
             whose commands were preinitialized.  */
          else if (cmds != 0 && f->cmds != 0 && f->is_target)
            {
-             makefile_error (cmds->filename, cmds->lineno,
+             error (&cmds->fileinfo,
                              "warning: overriding commands for target `%s'",
                              f->name);
-             makefile_error (f->cmds->filename, f->cmds->lineno,
+             error (&f->cmds->fileinfo,
                              "warning: ignoring old commands for target `%s'",
                              f->name);
            }
@@ -1696,7 +1691,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
          /* Check for both : and :: rules.  Check is_target so
             we don't lose on default suffix rules or makefiles.  */
          if (f != 0 && f->is_target && !f->double_colon)
-           makefile_fatal (filename, lineno,
+           fatal (flocp,
                            "target file `%s' has both : and :: entries",
                            f->name);
          f = enter_file (name);
@@ -2089,12 +2084,11 @@ parse_file_seq (stringp, stopchar, size, strip)
    Return the number of actual lines read (> 1 if hacked continuation lines).
  */
 
-static unsigned int
-readline (linebuffer, stream, filename, lineno)
+static unsigned long
+readline (linebuffer, stream, flocp)
      struct linebuffer *linebuffer;
      FILE *stream;
-     char *filename;
-     unsigned int lineno;
+     const struct floc *flocp;
 {
   char *buffer = linebuffer->buffer;
   register char *p = linebuffer->buffer;
@@ -2116,8 +2110,7 @@ readline (linebuffer, stream, filename, lineno)
             lossage strikes again!  (xmkmf puts NULs in its makefiles.)
             There is nothing really to be done; we synthesize a newline so
             the following line doesn't appear to be part of this line.  */
-         makefile_error (filename, lineno,
-                         "warning: NUL character seen; rest of line ignored");
+         error (flocp, "warning: NUL character seen; rest of line ignored");
          p[0] = '\n';
          len = 1;
        }
@@ -2177,7 +2170,7 @@ readline (linebuffer, stream, filename, lineno)
     }
 
   if (ferror (stream))
-    pfatal_with_name (filename);
+    pfatal_with_name (flocp->filenm);
 
   return nlines;
 }
@@ -2296,8 +2289,12 @@ get_next_mword (buffer, delim, startp, length)
 
         case ':':
 #if defined(__MSDOS__) || defined(WINDOWS32)
-         /* A word CAN include a colon in its drive spec.  */
-         if (!(p - beg == 2 && (*p == '/' || *p == '\\') && isalpha (*beg)))
+         /* A word CAN include a colon in its drive spec.  The drive
+            spec is allowed either at the beginning of a word, or as part
+            of the archive member name, like in "libfoo.a(d:/foo/bar.o)".  */
+         if (!(p - beg >= 2 &&
+               (*p == '/' || *p == '\\') && isalpha (p[-2]) &&
+               (p - beg == 2 || p[-3] == '(')))
 #endif
          goto done_word;
 
@@ -2657,7 +2654,7 @@ multi_glob (chain, size)
          }
 
        case GLOB_NOSPACE:
-         fatal ("virtual memory exhausted");
+         fatal (NILF, "virtual memory exhausted");
          break;
 
        default:
index 9c459a4..d312321 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -48,13 +48,11 @@ unsigned int commands_started = 0;
 
 static int update_file PARAMS ((struct file *file, unsigned int depth));
 static int update_file_1 PARAMS ((struct file *file, unsigned int depth));
-static int check_dep PARAMS ((struct file *file, unsigned int depth, time_t this_mtime, int *must_make_ptr));
+static int check_dep PARAMS ((struct file *file, unsigned int depth, FILE_TIMESTAMP this_mtime, int *must_make_ptr));
 static int touch_file PARAMS ((struct file *file));
 static void remake_file PARAMS ((struct file *file));
-static time_t name_mtime PARAMS ((char *name));
-static int library_search PARAMS ((char **lib, time_t *mtime_ptr));
-
-extern time_t f_mtime PARAMS ((struct file *file, int search));
+static FILE_TIMESTAMP name_mtime PARAMS ((char *name));
+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
@@ -128,7 +126,7 @@ update_goal_chain (goals, makefiles)
            {
              unsigned int ocommands_started;
              int x;
-             time_t mtime = MTIME (file);
+             FILE_TIMESTAMP mtime = MTIME (file);
              check_renamed (file);
              if (makefiles)
                {
@@ -268,9 +266,9 @@ no_rule_error(file)
       if (!file->dontcare)
         {
           if (file->parent == 0)
-            error (msg_noparent, "*** ", file->name, ".");
+            error (NILF, msg_noparent, "*** ", file->name, ".");
           else
-            error (msg_parent, "*** ",
+            error (NILF, msg_parent, "*** ",
                    file->name, file->parent->name, ".");
           file->shownerror = 1;
         }
@@ -279,9 +277,9 @@ no_rule_error(file)
   else
     {
       if (file->parent == 0)
-        fatal (msg_noparent, "", file->name, "");
+        fatal (NILF, msg_noparent, "", file->name, "");
       else
-        fatal (msg_parent, "", file->name, file->parent->name, "");
+        fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
     }
 }
 \f
@@ -341,7 +339,7 @@ update_file_1 (file, depth)
      struct file *file;
      unsigned int depth;
 {
-  register time_t this_mtime;
+  register FILE_TIMESTAMP this_mtime;
   int noexist, must_make, deps_changed;
   int dep_status = 0;
   register struct dep *d, *lastd;
@@ -396,7 +394,7 @@ update_file_1 (file, depth)
 
   this_mtime = file_mtime (file);
   check_renamed (file);
-  noexist = this_mtime == (time_t) -1;
+  noexist = this_mtime == (FILE_TIMESTAMP) -1;
   if (noexist)
     DEBUGPR ("File `%s' does not exist.\n");
 
@@ -427,7 +425,7 @@ update_file_1 (file, depth)
   d = file->deps;
   while (d != 0)
     {
-      time_t mtime;
+      FILE_TIMESTAMP mtime;
 
       check_renamed (d->file);
 
@@ -436,7 +434,7 @@ update_file_1 (file, depth)
 
       if (d->file->updating)
        {
-         error ("Circular %s <- %s dependency dropped.",
+         error (NILF, "Circular %s <- %s dependency dropped.",
                 file->name, d->file->name);
          /* We cannot free D here because our the caller will still have
             a reference to it when we were called recursively via
@@ -484,7 +482,7 @@ update_file_1 (file, depth)
       for (d = file->deps; d != 0; d = d->next)
        if (d->file->intermediate)
          {
-           time_t mtime = file_mtime (d->file);
+           FILE_TIMESTAMP mtime = file_mtime (d->file);
            check_renamed (d->file);
            d->file->parent = file;
            dep_status |= update_file (d->file, depth);
@@ -537,7 +535,7 @@ update_file_1 (file, depth)
 
       if (depth == 0 && keep_going_flag
          && !just_print_flag && !question_flag)
-       error ("Target `%s' not remade because of errors.", file->name);
+       error (NILF, "Target `%s' not remade because of errors.", file->name);
 
       return dep_status;
     }
@@ -559,13 +557,13 @@ update_file_1 (file, depth)
   deps_changed = 0;
   for (d = file->deps; d != 0; d = d->next)
     {
-      time_t d_mtime = file_mtime (d->file);
+      FILE_TIMESTAMP d_mtime = file_mtime (d->file);
       check_renamed (d->file);
 
 #if 1  /* %%% In version 4, remove this code completely to
           implement not remaking deps if their deps are newer
           than their parents.  */
-      if (d_mtime == (time_t) -1 && !d->file->intermediate)
+      if (d_mtime == (FILE_TIMESTAMP) -1 && !d->file->intermediate)
        /* We must remake if this dep does not
           exist and is not intermediate.  */
        must_make = 1;
@@ -581,7 +579,7 @@ update_file_1 (file, depth)
       if (debug_flag && !noexist)
        {
          print_spaces (depth);
-         if (d_mtime == (time_t) -1)
+         if (d_mtime == (FILE_TIMESTAMP) -1)
            printf ("Dependency `%s' does not exist.\n", dep_name (d));
          else
            printf ("Dependency `%s' is %s than dependent `%s'.\n",
@@ -771,7 +769,7 @@ static int
 check_dep (file, depth, this_mtime, must_make_ptr)
      struct file *file;
      unsigned int depth;
-     time_t this_mtime;
+     FILE_TIMESTAMP this_mtime;
      int *must_make_ptr;
 {
   register struct dep *d;
@@ -784,21 +782,20 @@ check_dep (file, depth, this_mtime, must_make_ptr)
     /* If this is a non-intermediate file, update it and record
        whether it is newer than THIS_MTIME.  */
     {
-      time_t mtime;
+      FILE_TIMESTAMP mtime;
       dep_status = update_file (file, depth);
       check_renamed (file);
       mtime = file_mtime (file);
       check_renamed (file);
-      if (mtime == (time_t) -1 || mtime > this_mtime)
+      if (mtime == (FILE_TIMESTAMP) -1 || mtime > this_mtime)
        *must_make_ptr = 1;
     }
   else
     {
       /* FILE is an intermediate file.  */
-      time_t mtime;
+      FILE_TIMESTAMP mtime;
 
-      if (!file->phony && file->cmds == 0 && !file->tried_implicit
-         && file->secondary)
+      if (!file->phony && file->cmds == 0 && !file->tried_implicit)
        {
          if (try_implicit_rule (file, depth))
            DEBUGPR ("Found an implicit rule for `%s'.\n");
@@ -806,7 +803,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
            DEBUGPR ("No implicit rule found for `%s'.\n");
          file->tried_implicit = 1;
        }
-      if (file->cmds == 0 && !file->is_target && file->secondary
+      if (file->cmds == 0 && !file->is_target
          && default_file != 0 && default_file->cmds != 0)
        {
          DEBUGPR ("Using default commands for `%s'.\n");
@@ -818,7 +815,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
       check_renamed (file);
       mtime = file_mtime (file);
       check_renamed (file);
-      if (mtime != (time_t) -1 && mtime > this_mtime)
+      if (mtime != (FILE_TIMESTAMP) -1 && mtime > this_mtime)
        *must_make_ptr = 1;
          /* Otherwise, update all non-intermediate files we depend on,
             if necessary, and see whether any of them is more
@@ -833,7 +830,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
            {
              if (d->file->updating)
                {
-                 error ("Circular %s <- %s dependency dropped.",
+                 error (NILF, "Circular %s <- %s dependency dropped.",
                         file->name, d->file->name);
                  if (lastd == 0)
                    {
@@ -858,7 +855,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
 
              if (d->file->command_state == cs_running
                  || d->file->command_state == cs_deps_running)
-               /* Record that some of FILE's dependencies are still being made.
+               /* Record that some of FILE's deps are still being made.
                   This tells the upper levels to wait on processing it until
                   the commands are finished.  */
                set_command_state (file, cs_deps_running);
@@ -978,12 +975,12 @@ remake_file (file)
    the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into
    FILE.  */
 
-time_t
+FILE_TIMESTAMP
 f_mtime (file, search)
      register struct file *file;
      int search;
 {
-  time_t mtime;
+  FILE_TIMESTAMP mtime;
 
   /* File's mtime is not known; must get it from the system.  */
 
@@ -1049,9 +1046,9 @@ f_mtime (file, search)
        free (arname);
       free (memname);
 
-      if (mtime == (time_t) -1)
+      if (mtime == (FILE_TIMESTAMP) -1)
        /* The archive doesn't exist, so it's members don't exist either.  */
-       return (time_t) -1;
+       return (FILE_TIMESTAMP) -1;
 
       mtime = ar_member_date (file->hname);
     }
@@ -1060,7 +1057,7 @@ f_mtime (file, search)
     {
       mtime = name_mtime (file->name);
 
-      if (mtime == (time_t) -1 && search && !file->ignore_vpath)
+      if (mtime == (FILE_TIMESTAMP) -1 && search && !file->ignore_vpath)
        {
          /* If name_mtime failed, search VPATH.  */
          char *name = file->name;
@@ -1098,16 +1095,15 @@ f_mtime (file, search)
 
        We only need to do this once, for now. */
 
-    static time_t now = 0;
+    static FILE_TIMESTAMP now = 0;
     if (!clock_skew_detected
-        && mtime != (time_t)-1 && mtime > now
+        && mtime != (FILE_TIMESTAMP)-1 && mtime > now
         && !file->updated)
       {
        /* This file's time appears to be in the future.
           Update our concept of the present, and compare again.  */
 
-       extern time_t time ();
-       time (&now);
+       now = file_timestamp_now ();
 
 #ifdef WINDOWS32
        /*
@@ -1126,8 +1122,13 @@ f_mtime (file, search)
 #endif
 #endif
           {
-            error("*** Warning: File `%s' has modification time in the future (%ld > %ld)",
-                  file->name, mtime, now);
+           char mtimebuf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
+           char nowbuf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
+
+           file_timestamp_sprintf (mtimebuf, mtime);
+           file_timestamp_sprintf (nowbuf, now);
+            error (NILF, "*** Warning: File `%s' has modification time in the future (%s > %s)",
+                   file->name, mtimebuf, nowbuf);
             clock_skew_detected = 1;
           }
       }
@@ -1148,16 +1149,16 @@ f_mtime (file, search)
 
 /* Return the mtime of the file or archive-member reference NAME.  */
 
-static time_t
+static FILE_TIMESTAMP
 name_mtime (name)
      register char *name;
 {
   struct stat st;
 
   if (stat (name, &st) < 0)
-    return (time_t) -1;
+    return (FILE_TIMESTAMP) -1;
 
-  return (time_t) st.st_mtime;
+  return FILE_TIMESTAMP_STAT_MODTIME (st);
 }
 
 
@@ -1168,7 +1169,7 @@ name_mtime (name)
 static int
 library_search (lib, mtime_ptr)
      char **lib;
-     time_t *mtime_ptr;
+     FILE_TIMESTAMP *mtime_ptr;
 {
   static char *dirs[] =
     {
@@ -1188,7 +1189,7 @@ library_search (lib, mtime_ptr)
     };
 
   char *libname = &(*lib)[2];  /* Name without the `-l'.  */
-  time_t mtime;
+  FILE_TIMESTAMP mtime;
 
   /* Buffer to construct possible names in.  */
   char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
@@ -1202,7 +1203,7 @@ library_search (lib, mtime_ptr)
   sprintf (buf, "%s.lib", libname);
 #endif
   mtime = name_mtime (buf);
-  if (mtime != (time_t) -1)
+  if (mtime != (FILE_TIMESTAMP) -1)
     {
       *lib = buf;
       if (mtime_ptr != 0)
@@ -1235,7 +1236,7 @@ library_search (lib, mtime_ptr)
          buf = (char *) xrealloc (djdir_len + 1);
        sprintf (buf, "%s/lib/lib%s.a", djdir->value, libname);
        mtime = name_mtime (buf);
-       if (mtime != (time_t) -1)
+       if (mtime != (FILE_TIMESTAMP) -1)
          {
            *lib = buf;
            if (mtime_ptr != 0)
@@ -1254,7 +1255,7 @@ library_search (lib, mtime_ptr)
       sprintf (buf, "%s/%s.lib", *dp, libname);
 #endif
       mtime = name_mtime (buf);
-      if (mtime != (time_t) -1)
+      if (mtime != (FILE_TIMESTAMP) -1)
        {
          *lib = buf;
          if (mtime_ptr != 0)
index e1d63a3..cf91816 100644 (file)
@@ -157,7 +157,7 @@ start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
   retsock = Rpc_UdpCreate (True, 0);
   if (retsock < 0)
     {
-      error ("exporting: Couldn't create return socket.");
+      error (NILF, "exporting: Couldn't create return socket.");
       return 1;
     }
 
@@ -202,7 +202,7 @@ start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
     {
       (void) close (retsock);
       (void) close (sock);
-      error ("exporting to %s: %s",
+      error (NILF, "exporting to %s: %s",
              host ? host->h_name : inet_ntoa (permit.addr),
              Rpc_ErrorMessage (status));
       return 1;
@@ -211,14 +211,14 @@ start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
     {
       (void) close (retsock);
       (void) close (sock);
-      error ("exporting to %s: %s",
+      error (NILF, "exporting to %s: %s",
              host ? host->h_name : inet_ntoa (permit.addr),
              msg);
       return 1;
     }
   else
     {
-      error ("*** exported to %s (id %u)",
+      error (NILF, "*** exported to %s (id %u)",
              host ? host->h_name : inet_ntoa (permit.addr),
              permit.id);
     }
diff --git a/rule.c b/rule.c
index 6933631..eb4602f 100644 (file)
--- a/rule.c
+++ b/rule.c
@@ -416,8 +416,8 @@ install_pattern_rule (p, terminal)
     {
       r->terminal = terminal;
       r->cmds = (struct commands *) xmalloc (sizeof (struct commands));
-      r->cmds->filename = 0;
-      r->cmds->lineno = 0;
+      r->cmds->fileinfo.filenm = 0;
+      r->cmds->fileinfo.lineno = 0;
       /* These will all be string literals, but we malloc space for them
         anyway because somebody might want to free them later.  */
       r->cmds->commands = savestring (p->commands, strlen (p->commands));
@@ -664,7 +664,7 @@ print_rule_data_base ()
     }
 
   if (num_pattern_rules != rules)
-    fatal ("BUG: num_pattern_rules wrong!  %u != %u",
+    fatal (NILF, "BUG: num_pattern_rules wrong!  %u != %u",
           num_pattern_rules, rules);
 
   puts ("\n# Pattern-specific variable values");
diff --git a/rule.h b/rule.h
index 4effeb0..f57c7e0 100644 (file)
--- a/rule.h
+++ b/rule.h
@@ -62,3 +62,10 @@ extern void install_pattern_rule PARAMS ((struct pspec *p, int terminal));
 extern int new_pattern_rule PARAMS ((struct rule *rule, int override));
 extern struct pattern_var *create_pattern_var PARAMS ((char *target, char *suffix));
 extern struct pattern_var *lookup_pattern_var PARAMS ((char *target));
+extern void count_implicit_rule_limits PARAMS ((void));
+extern void convert_to_pattern PARAMS ((void));
+extern void create_pattern_rule PARAMS ((char **targets,
+                                         char **target_percents, int terminal,
+                                         struct dep *deps,
+                                         struct commands *commands,
+                                         int override));
index 3155a92..85987db 100644 (file)
@@ -676,9 +676,8 @@ target_environment (file)
    returned.  */
 
 struct variable *
-try_variable_definition (filename, lineno, line, origin)
-     char *filename;
-     unsigned int lineno;
+try_variable_definition (flocp, line, origin)
+     const struct floc *flocp;
      char *line;
      enum variable_origin origin;
 {
@@ -766,7 +765,7 @@ try_variable_definition (filename, lineno, line, origin)
   expanded_name = allocated_variable_expand (name);
 
   if (expanded_name[0] == '\0')
-    makefile_fatal (filename, lineno, "empty variable name");
+    fatal (flocp, "empty variable name");
 
   /* Calculate the variable's new value in VALUE.  */
 
index 4289c14..b1d0daf 100644 (file)
@@ -102,7 +102,7 @@ extern void initialize_file_variables PARAMS ((struct file *file));
 extern void print_file_variables PARAMS ((struct file *file));
 extern void print_variable_set PARAMS ((struct variable_set *set, char *prefix));
 extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1));
-extern struct variable *try_variable_definition PARAMS ((char *filename, unsigned int lineno, char *line, enum variable_origin origin));
+extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin));
 
 extern struct variable *lookup_variable PARAMS ((char *name, unsigned int length));
 extern struct variable *define_variable PARAMS ((char *name, unsigned int length, char *value,
diff --git a/vpath.c b/vpath.c
index ab88ac3..d332031 100644 (file)
--- a/vpath.c
+++ b/vpath.c
@@ -48,7 +48,7 @@ static struct vpath *general_vpath;
 
 static struct vpath *gpaths;
 \f
-static int selective_vpath_search PARAMS ((struct vpath *path, char **file, time_t *mtime_ptr));
+static int selective_vpath_search PARAMS ((struct vpath *path, char **file, FILE_TIMESTAMP *mtime_ptr));
 
 /* Reverse the chain of selective VPATH lists so they
    will be searched in the order given in the makefiles
@@ -338,7 +338,7 @@ gpath_search (file, len)
 int
 vpath_search (file, mtime_ptr)
      char **file;
-     time_t *mtime_ptr;
+     FILE_TIMESTAMP *mtime_ptr;
 {
   register struct vpath *v;
 
@@ -376,7 +376,7 @@ static int
 selective_vpath_search (path, file, mtime_ptr)
      struct vpath *path;
      char **file;
-     time_t *mtime_ptr;
+     FILE_TIMESTAMP *mtime_ptr;
 {
   int not_target;
   char *name, *n;
@@ -524,7 +524,9 @@ selective_vpath_search (path, file, mtime_ptr)
                /* Store the modtime into *MTIME_PTR for the caller.
                   If we have had no need to stat the file here,
                   we record a zero modtime to indicate this.  */
-               *mtime_ptr = exists_in_cache ? st.st_mtime : (time_t) 0;
+               *mtime_ptr = (exists_in_cache
+                             ? FILE_TIMESTAMP_STAT_MODTIME (st)
+                             : (FILE_TIMESTAMP) 0);
 
              free (name);
              return 1;
index f187827..66afe65 100644 (file)
@@ -1,60 +1,60 @@
-# NOTE: If you have no `make' program at all to process this makefile, run\r
-# `build.bat' instead.\r
-#\r
-# Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc\r
-# This file is part of GNU Make.\r
-#\r
-# GNU Make is free software; you can redistribute it and/or modify\r
-# it under the terms of the GNU General Public License as published by\r
-# the Free Software Foundation; either version 2, or (at your option)\r
-# any later version.\r
-#\r
-# GNU Make is distributed in the hope that it will be useful,\r
-# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-# GNU General Public License for more details.\r
-#\r
-# You should have received a copy of the GNU General Public License\r
-# along with GNU Make; see the file COPYING.  If not, write to\r
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\r
-\r
-#\r
-#       NMakefile for GNU Make (subproc library)\r
-#\r
-LIB = lib\r
-CC = cl\r
-\r
-OUTDIR=.\r
-MAKEFILE=NMakefile\r
-\r
-CFLAGS_any = /nologo /MT /W3 /GX /Z7 /YX /D WIN32 /D WINDOWS32 /D _WINDOWS  -I. -I../include -I../..\r
-CFLAGS_debug = $(CFLAGS_any) /Od /D _DEBUG /FR.\WinDebug\ /Fp.\WinDebug\subproc.pch /Fo.\WinDebug/\r
-CFLAGS_release = $(CFLAGS_any) /O2 /FR.\WinRel\ /Fp.\WinRel\subproc.pch /Fo.\WinRel/\r
-\r
-all: Release Debug\r
-\r
-Release: \r
-       $(MAKE) /f $(MAKEFILE) OUTDIR=WinRel CFLAGS="$(CFLAGS_release)" WinRel/subproc.lib\r
-Debug: \r
-       $(MAKE) /f $(MAKEFILE) OUTDIR=WinDebug CFLAGS="$(CFLAGS_debug)" WinDebug/subproc.lib\r
-\r
-clean:\r
-       rmdir /s /q WinRel WinDebug\r
-       erase *.pdb\r
-\r
-$(OUTDIR):\r
-       if not exist .\$@\nul mkdir .\$@\r
-\r
-OBJS = $(OUTDIR)/misc.obj $(OUTDIR)/w32err.obj $(OUTDIR)/sub_proc.obj\r
-\r
-$(OUTDIR)/subproc.lib: $(OUTDIR) $(OBJS)\r
-       $(LIB) -out:$@ @<<\r
-               $(OBJS)\r
-<<\r
-\r
-.c{$(OUTDIR)}.obj:\r
-       $(CC) $(CFLAGS) /c $<\r
-       \r
-$(OUTDIR)/misc.obj: misc.c proc.h\r
-$(OUTDIR)/sub_proc.obj: sub_proc.c  ../include/sub_proc.h ../include/w32err.h proc.h\r
-$(OUTDIR)/w32err.obj: w32err.c ../include/w32err.h\r
+# NOTE: If you have no `make' program at all to process this makefile, run
+# `build.bat' instead.
+#
+# Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc
+# This file is part of GNU Make.
+#
+# 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
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Make is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#
+#       NMakefile for GNU Make (subproc library)
+#
+LIB = lib
+CC = cl
+
+OUTDIR=.
+MAKEFILE=NMakefile
+
+CFLAGS_any = /nologo /MT /W3 /GX /Z7 /YX /D WIN32 /D WINDOWS32 /D _WINDOWS  -I. -I../include -I../../
+CFLAGS_debug = $(CFLAGS_any) /Od /D _DEBUG /FR.\WinDebug\ /Fp.\WinDebug\subproc.pch /Fo.\WinDebug/
+CFLAGS_release = $(CFLAGS_any) /O2 /FR.\WinRel\ /Fp.\WinRel\subproc.pch /Fo.\WinRel/
+
+all: Release Debug
+
+Release:
+       $(MAKE) /f $(MAKEFILE) OUTDIR=WinRel CFLAGS="$(CFLAGS_release)" WinRel/subproc.lib
+Debug:
+       $(MAKE) /f $(MAKEFILE) OUTDIR=WinDebug CFLAGS="$(CFLAGS_debug)" WinDebug/subproc.lib
+
+clean:
+       rmdir /s /q WinRel WinDebug
+       erase *.pdb
+
+$(OUTDIR):
+       if not exist .\$@\nul mkdir .\$@
+
+OBJS = $(OUTDIR)/misc.obj $(OUTDIR)/w32err.obj $(OUTDIR)/sub_proc.obj
+
+$(OUTDIR)/subproc.lib: $(OUTDIR) $(OBJS)
+       $(LIB) -out:$@ @<<
+               $(OBJS)
+<<
+
+.c{$(OUTDIR)}.obj:
+       $(CC) $(CFLAGS) /c $<
+
+$(OUTDIR)/misc.obj: misc.c proc.h
+$(OUTDIR)/sub_proc.obj: sub_proc.c  ../include/sub_proc.h ../include/w32err.h proc.h
+$(OUTDIR)/w32err.obj: w32err.c ../include/w32err.h
index 281c81c..300bb7b 100644 (file)
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <process.h>  /* for msvc _beginthreadex, _endthreadex */\r
-#include <windows.h>\r
-\r
-#include "sub_proc.h"\r
-#include "proc.h"\r
-#include "w32err.h"\r
-#include "config.h"\r
-\r
-static char *make_command_line( char *shell_name, char *exec_path, char **argv);\r
-\r
-typedef struct sub_process_t {\r
-       int sv_stdin[2];\r
-       int sv_stdout[2];\r
-       int sv_stderr[2];\r
-       int using_pipes;\r
-       char *inp;\r
-       DWORD incnt;\r
-       char * volatile outp;\r
-       volatile DWORD outcnt;\r
-       char * volatile errp;\r
-       volatile DWORD errcnt;\r
-       int pid;\r
-       int exit_code;\r
-       int signal;\r
-       long last_err;\r
-       long lerrno;\r
-} sub_process;\r
-\r
-/* keep track of children so we can implement a waitpid-like routine */\r
-static sub_process *proc_array[256];\r
-static int proc_index = 0;\r
-static int fake_exits_pending = 0;\r
-\r
-/*\r
- * When a process has been waited for, adjust the wait state\r
- * array so that we don't wait for it again\r
- */\r
-static void\r
-process_adjust_wait_state(sub_process* pproc)\r
-{\r
-       int i;\r
-\r
-       if (!proc_index)\r
-               return;\r
-\r
-       for (i = 0; i < proc_index; i++)\r
-               if (proc_array[i]->pid == pproc->pid)\r
-                       break;\r
-\r
-       if (i < proc_index) {\r
-               proc_index--;\r
-               if (i != proc_index)\r
-                       memmove(&proc_array[i], &proc_array[i+1], \r
-                               (proc_index-i) * sizeof(sub_process*));\r
-               proc_array[proc_index] = NULL;\r
-       }\r
-}\r
-\r
-/*\r
- * Waits for any of the registered child processes to finish.\r
- */\r
-static sub_process *\r
-process_wait_for_any_private(void)\r
-{\r
-       HANDLE handles[256];\r
-       DWORD retval, which;\r
-       int i;\r
-\r
-       if (!proc_index)\r
-               return NULL;\r
-\r
-       /* build array of handles to wait for */\r
-       for (i = 0; i < proc_index; i++) {\r
-               handles[i] = (HANDLE) proc_array[i]->pid;\r
-\r
-               if (fake_exits_pending && proc_array[i]->exit_code)\r
-                       break;\r
-       }\r
-\r
-       /* wait for someone to exit */\r
-       if (!fake_exits_pending) {\r
-               retval = WaitForMultipleObjects(proc_index, handles, FALSE, INFINITE);\r
-               which = retval - WAIT_OBJECT_0;\r
-       } else {\r
-               fake_exits_pending--;\r
-               retval = !WAIT_FAILED;\r
-               which = i;\r
-       }\r
-\r
-       /* return pointer to process */\r
-       if (retval != WAIT_FAILED) {\r
-               sub_process* pproc = proc_array[which]; \r
-               process_adjust_wait_state(pproc);\r
-               return pproc;\r
-       } else\r
-               return NULL;\r
-}\r
-\r
-/*\r
- * Terminate a process.\r
- */\r
-BOOL\r
-process_kill(HANDLE proc, int signal)\r
-{\r
-       sub_process* pproc = (sub_process*) proc;\r
-       pproc->signal = signal;\r
-       return (TerminateProcess((HANDLE) pproc->pid, signal));\r
-}\r
-\r
-/*\r
- * Use this function to register processes you wish to wait for by\r
- * calling process_file_io(NULL) or process_wait_any(). This must be done \r
- * because it is possible for callers of this library to reuse the same \r
- * handle for multiple processes launches :-(\r
- */\r
-void\r
-process_register(HANDLE proc)\r
-{\r
-       proc_array[proc_index++] = (sub_process *) proc;\r
-}\r
-\r
-/*\r
- * Public function which works kind of like waitpid(). Wait for any\r
- * of the children to die and return results. To call this function,\r
- * you must do 1 of things:\r
- *\r
- *     x = process_easy(...);\r
- *     \r
- * or\r
- *\r
- *     x = process_init_fd();\r
- *     process_register(x);\r
- *\r
- * or\r
- *\r
- *     x = process_init();\r
- *     process_register(x);\r
- *\r
- * You must NOT then call process_pipe_io() because this function is\r
- * not capable of handling automatic notification of any child\r
- * death.\r
- */\r
-\r
-HANDLE\r
-process_wait_for_any(void)\r
-{\r
-       sub_process* pproc = process_wait_for_any_private(); \r
-\r
-       if (!pproc)\r
-               return NULL;\r
-       else {\r
-               /* \r
-                * Ouch! can't tell caller if this fails directly. Caller \r
-                * will have to use process_last_err() \r
-                 */\r
-               (void) process_file_io(pproc);\r
-               return ((HANDLE) pproc);\r
-       }\r
-}\r
-\r
-long\r
-process_errno(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->lerrno);\r
-}\r
-\r
-long\r
-process_signal(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->signal);\r
-}\r
-\r
-       long\r
-process_last_err(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->last_err);\r
-}\r
-\r
-       long\r
-process_exit_code(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->exit_code);\r
-}\r
-\r
-       char *\r
-process_outbuf(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->outp);\r
-}\r
-\r
-       char *\r
-process_errbuf(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->errp);\r
-}\r
-\r
-       int\r
-process_outcnt(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->outcnt);\r
-}\r
-\r
-       int\r
-process_errcnt(HANDLE proc)\r
-{\r
-       return (((sub_process *)proc)->errcnt);\r
-}\r
-\r
-       void\r
-process_pipes(HANDLE proc, int pipes[3])\r
-{\r
-       pipes[0] = ((sub_process *)proc)->sv_stdin[0];\r
-       pipes[1] = ((sub_process *)proc)->sv_stdout[0];\r
-       pipes[2] = ((sub_process *)proc)->sv_stderr[0];\r
-       return;\r
-}\r
-\r
-\r
-       HANDLE\r
-process_init()\r
-{\r
-       sub_process *pproc;\r
-       /*\r
-        * open file descriptors for attaching stdin/stdout/sterr\r
-        */\r
-       HANDLE stdin_pipes[2];\r
-       HANDLE stdout_pipes[2];\r
-       HANDLE stderr_pipes[2];\r
-       SECURITY_ATTRIBUTES inherit;\r
-       BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];\r
-\r
-       pproc = malloc(sizeof(*pproc));\r
-       memset(pproc, 0, sizeof(*pproc));\r
-\r
-       /* We can't use NULL for lpSecurityDescriptor because that\r
-          uses the default security descriptor of the calling process.\r
-          Instead we use a security descriptor with no DACL.  This\r
-          allows nonrestricted access to the associated objects. */\r
-       \r
-       if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),\r
-                                         SECURITY_DESCRIPTOR_REVISION)) {\r
-               pproc->last_err = GetLastError();\r
-               pproc->lerrno = E_SCALL;\r
-               return((HANDLE)pproc);\r
-       }\r
-\r
-       inherit.nLength = sizeof(inherit);\r
-       inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);\r
-       inherit.bInheritHandle = TRUE;\r
-\r
-       // By convention, parent gets pipe[0], and child gets pipe[1]\r
-       // This means the READ side of stdin pipe goes into pipe[1]\r
-       // and the WRITE side of the stdout and stderr pipes go into pipe[1]\r
-       if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||\r
-       CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||\r
-       CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {\r
-\r
-               pproc->last_err = GetLastError();\r
-               pproc->lerrno = E_SCALL;\r
-               return((HANDLE)pproc);\r
-       }\r
-\r
-       //\r
-       // Mark the parent sides of the pipes as non-inheritable\r
-       //\r
-       if (SetHandleInformation(stdin_pipes[0], \r
-                               HANDLE_FLAG_INHERIT, 0) == FALSE ||\r
-               SetHandleInformation(stdout_pipes[0], \r
-                               HANDLE_FLAG_INHERIT, 0) == FALSE ||\r
-               SetHandleInformation(stderr_pipes[0], \r
-                               HANDLE_FLAG_INHERIT, 0) == FALSE) {\r
-\r
-               pproc->last_err = GetLastError();\r
-               pproc->lerrno = E_SCALL;\r
-               return((HANDLE)pproc);\r
-       }\r
-       pproc->sv_stdin[0]  = (int) stdin_pipes[0];\r
-       pproc->sv_stdin[1]  = (int) stdin_pipes[1];\r
-       pproc->sv_stdout[0] = (int) stdout_pipes[0];\r
-       pproc->sv_stdout[1] = (int) stdout_pipes[1];\r
-       pproc->sv_stderr[0] = (int) stderr_pipes[0];\r
-       pproc->sv_stderr[1] = (int) stderr_pipes[1];\r
-\r
-       pproc->using_pipes = 1;\r
-\r
-       pproc->lerrno = 0;\r
-\r
-       return((HANDLE)pproc);\r
-}\r
-\r
-\r
-       HANDLE\r
-process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)\r
-{\r
-       sub_process *pproc;\r
-\r
-       pproc = malloc(sizeof(*pproc));\r
-       memset(pproc, 0, sizeof(*pproc));\r
-\r
-       /*\r
-        * Just pass the provided file handles to the 'child side' of the\r
-        * pipe, bypassing pipes altogether.\r
-        */\r
-       pproc->sv_stdin[1]  = (int) stdinh;\r
-       pproc->sv_stdout[1] = (int) stdouth;\r
-       pproc->sv_stderr[1] = (int) stderrh;\r
-\r
-       pproc->last_err = pproc->lerrno = 0;\r
-\r
-       return((HANDLE)pproc);\r
-}\r
-\r
-\r
-static HANDLE\r
-find_file(char *exec_path, LPOFSTRUCT file_info)\r
-{\r
-       HANDLE exec_handle;\r
-       char *fname;\r
-       char *ext;\r
-\r
-       fname = malloc(strlen(exec_path) + 5);\r
-       strcpy(fname, exec_path);\r
-       ext = fname + strlen(fname);\r
-\r
-       strcpy(ext, ".exe");\r
-       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,\r
-                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {\r
-               free(fname);\r
-               return(exec_handle);\r
-       }\r
-\r
-       strcpy(ext, ".cmd");\r
-       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,\r
-                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {\r
-               free(fname);\r
-               return(exec_handle);\r
-       }\r
-\r
-       strcpy(ext, ".bat");\r
-       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,\r
-                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {\r
-               free(fname);\r
-               return(exec_handle);\r
-       }\r
-\r
-       /* should .com come before this case? */\r
-       if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info,\r
-                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {\r
-               free(fname);\r
-               return(exec_handle);\r
-       }\r
-\r
-       strcpy(ext, ".com");\r
-       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,\r
-                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {\r
-               free(fname);\r
-               return(exec_handle);\r
-       }\r
-\r
-       free(fname);\r
-       return(exec_handle);\r
-}\r
-\r
-\r
-/*\r
- * Description:   Create the child process to be helped\r
- *\r
- * Returns: \r
- *\r
- * Notes/Dependencies:  \r
- */\r
-long\r
-process_begin(\r
-       HANDLE proc,\r
-       char **argv,\r
-       char **envp,\r
-       char *exec_path,\r
-       char *as_user)\r
-{\r
-       sub_process *pproc = (sub_process *)proc;\r
-       char *shell_name = 0;\r
-       int file_not_found=0;\r
-       HANDLE exec_handle;\r
-       char buf[256];\r
-       DWORD bytes_returned;\r
-       DWORD flags;\r
-       char *command_line;\r
-       STARTUPINFO startInfo;\r
-       PROCESS_INFORMATION procInfo;\r
-       char *envblk=NULL;\r
-       OFSTRUCT file_info;\r
-\r
-\r
-       /*\r
-        *  Shell script detection...  if the exec_path starts with #! then\r
-        *  we want to exec shell-script-name exec-path, not just exec-path\r
-        *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not\r
-        *  hard-code the path to the shell or perl or whatever:  Instead, we\r
-        *  assume it's in the path somewhere (generally, the NT tools\r
-        *  bin directory)\r
-        *  We use OpenFile here because it is capable of searching the Path.\r
-        */\r
-\r
-       exec_handle = find_file(exec_path, &file_info);\r
-\r
-       /*\r
-        * If we couldn't open the file, just assume that Windows32 will be able\r
-        * to find and execute it.\r
-        */\r
-       if (exec_handle == (HANDLE)HFILE_ERROR) {\r
-               file_not_found++;\r
-       }\r
-       else {\r
-               /* Attempt to read the first line of the file */\r
-               if (ReadFile( exec_handle, \r
-                               buf, sizeof(buf) - 1, /* leave room for trailing NULL */\r
-                               &bytes_returned, 0) == FALSE || bytes_returned < 2) {\r
-       \r
-                       pproc->last_err = GetLastError();\r
-                       pproc->lerrno = E_IO;\r
-                       CloseHandle(exec_handle);\r
-                       return(-1);\r
-               }\r
-               if (buf[0] == '#' && buf[1] == '!') {\r
-                       /*\r
-                        *  This is a shell script...  Change the command line from\r
-                        *      exec_path args to shell_name exec_path args\r
-                        */\r
-                       char *p;\r
-       \r
-                       /*  Make sure buf is NULL terminated */\r
-                       buf[bytes_returned] = 0;\r
-                       /*\r
-                        * Depending on the file system type, etc. the first line\r
-                        * of the shell script may end with newline or newline-carriage-return\r
-                        * Whatever it ends with, cut it off.\r
-                        */\r
-                       p= strchr(buf, '\n');\r
-                       if (p)\r
-                               *p = 0;\r
-                       p = strchr(buf, '\r');\r
-                       if (p)\r
-                               *p = 0;\r
-               \r
-                       /*\r
-                        *  Find base name of shell\r
-                        */\r
-                       shell_name = strrchr( buf, '/');\r
-                       if (shell_name) {\r
-                               shell_name++;\r
-                       } else {\r
-                               shell_name = &buf[2];/* skipping "#!" */\r
-                       }\r
-\r
-               } \r
-               CloseHandle(exec_handle);\r
-       }\r
-\r
-       flags = 0;\r
-\r
-       if (file_not_found)\r
-               command_line = make_command_line( shell_name, exec_path, argv);\r
-       else\r
-               command_line = make_command_line( shell_name, file_info.szPathName,\r
-                                argv);\r
-\r
-       if ( command_line == NULL ) {\r
-               pproc->last_err = 0;\r
-               pproc->lerrno = E_NO_MEM;\r
-               return(-1);\r
-       }\r
-\r
-       if (envp) {\r
-               if (arr2envblk(envp, &envblk) ==FALSE) {\r
-                       pproc->last_err = 0;\r
-                       pproc->lerrno = E_NO_MEM;\r
-                       free( command_line );\r
-                       return(-1);\r
-               }\r
-       }\r
-\r
-       if ((shell_name) || (file_not_found)) {\r
-               exec_path = 0;  /* Search for the program in %Path% */\r
-       } else {\r
-               exec_path = file_info.szPathName;\r
-       }\r
-\r
-       /*\r
-        *  Set up inherited stdin, stdout, stderr for child\r
-        */\r
-       GetStartupInfo(&startInfo);\r
-       startInfo.dwFlags = STARTF_USESTDHANDLES;\r
-       startInfo.lpReserved = 0;\r
-       startInfo.cbReserved2 = 0;\r
-       startInfo.lpReserved2 = 0;\r
-       startInfo.lpTitle = shell_name ? shell_name : exec_path;\r
-       startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];\r
-       startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];\r
-       startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];\r
-\r
-       if (as_user) {\r
-               if (envblk) free(envblk);\r
-               return -1;\r
-       } else {\r
-               if (CreateProcess(\r
-                       exec_path,\r
-                       command_line,\r
-                       NULL,\r
-                       0, /* default security attributes for thread */\r
-                       TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */\r
-                       flags, \r
-                       envblk,\r
-                       0, /* default starting directory */\r
-                       &startInfo,\r
-                       &procInfo) == FALSE) {\r
-               \r
-                       pproc->last_err = GetLastError();\r
-                       pproc->lerrno = E_FORK;\r
-                       fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line);\r
-                       if (envblk) free(envblk);\r
-                       free( command_line );\r
-                       return(-1);\r
-               }\r
-       }\r
-       \r
-       pproc->pid = (int)procInfo.hProcess;\r
-       /* Close the thread handle -- we'll just watch the process */\r
-       CloseHandle(procInfo.hThread);\r
-       \r
-       /* Close the halves of the pipes we don't need */\r
-       if (pproc->sv_stdin) {\r
-               CloseHandle((HANDLE)pproc->sv_stdin[1]);\r
-               (HANDLE)pproc->sv_stdin[1] = 0;\r
-       }\r
-       if (pproc->sv_stdout) {\r
-               CloseHandle((HANDLE)pproc->sv_stdout[1]);\r
-               (HANDLE)pproc->sv_stdout[1] = 0;\r
-       }\r
-       if (pproc->sv_stderr) {\r
-               CloseHandle((HANDLE)pproc->sv_stderr[1]);\r
-               (HANDLE)pproc->sv_stderr[1] = 0;\r
-       }\r
-\r
-       free( command_line );\r
-       if (envblk) free(envblk);\r
-       pproc->lerrno=0;\r
-       return 0;\r
-}\r
-\r
-\r
-\r
-static DWORD \r
-proc_stdin_thread(sub_process *pproc)\r
-{\r
-       DWORD in_done;\r
-       for (;;) {\r
-               if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,\r
-                                        &in_done, NULL) == FALSE)\r
-                       _endthreadex(0);\r
-               // This if should never be true for anonymous pipes, but gives\r
-               // us a chance to change I/O mechanisms later\r
-               if (in_done < pproc->incnt) {\r
-                       pproc->incnt -= in_done;\r
-                       pproc->inp += in_done;\r
-               } else {\r
-                       _endthreadex(0);\r
-               }\r
-       }\r
-       return 0; // for compiler warnings only.. not reached\r
-}\r
-\r
-static DWORD\r
-proc_stdout_thread(sub_process *pproc)\r
-{\r
-       DWORD bufsize = 1024;\r
-       char c;\r
-       DWORD nread;\r
-       pproc->outp = malloc(bufsize);\r
-       if (pproc->outp == NULL)\r
-               _endthreadex(0);\r
-       pproc->outcnt = 0;\r
-\r
-       for (;;) {\r
-               if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL) \r
-                                       == FALSE) {\r
-/*                     map_windows32_error_to_string(GetLastError());*/\r
-                       _endthreadex(0);\r
-               }\r
-               if (nread == 0)\r
-                       _endthreadex(0);\r
-               if (pproc->outcnt + nread > bufsize) {\r
-                       bufsize += nread + 512; \r
-                       pproc->outp = realloc(pproc->outp, bufsize);\r
-                       if (pproc->outp == NULL) {\r
-                               pproc->outcnt = 0;\r
-                               _endthreadex(0);\r
-                       }\r
-               }\r
-               pproc->outp[pproc->outcnt++] = c;\r
-       }\r
-       return 0;\r
-}\r
-\r
-static DWORD\r
-proc_stderr_thread(sub_process *pproc)\r
-{\r
-       DWORD bufsize = 1024;\r
-       char c;\r
-       DWORD nread;\r
-       pproc->errp = malloc(bufsize);\r
-       if (pproc->errp == NULL)\r
-               _endthreadex(0);\r
-       pproc->errcnt = 0;\r
-\r
-       for (;;) {\r
-               if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {\r
-                       map_windows32_error_to_string(GetLastError());\r
-                       _endthreadex(0);\r
-               }\r
-               if (nread == 0)\r
-                       _endthreadex(0);\r
-               if (pproc->errcnt + nread > bufsize) {\r
-                       bufsize += nread + 512; \r
-                       pproc->errp = realloc(pproc->errp, bufsize);\r
-                       if (pproc->errp == NULL) {\r
-                               pproc->errcnt = 0;\r
-                               _endthreadex(0);\r
-                       }\r
-               }\r
-               pproc->errp[pproc->errcnt++] = c;\r
-       }\r
-       return 0;\r
-}\r
-\r
-\r
-/*\r
- * Purpose: collects output from child process and returns results\r
- *\r
- * Description:\r
- *\r
- * Returns: \r
- *\r
- * Notes/Dependencies:\r
- */\r
-       long\r
-process_pipe_io(\r
-       HANDLE proc,\r
-       char *stdin_data, \r
-       int stdin_data_len)\r
-{\r
-       sub_process *pproc = (sub_process *)proc;\r
-       bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;\r
-       HANDLE childhand = (HANDLE) pproc->pid;\r
-       HANDLE tStdin, tStdout, tStderr;\r
-       DWORD dwStdin, dwStdout, dwStderr;\r
-       HANDLE wait_list[4];\r
-       DWORD wait_count;\r
-       DWORD wait_return;\r
-       HANDLE ready_hand;\r
-       bool_t child_dead = FALSE;\r
-\r
-\r
-       /*\r
-        *  Create stdin thread, if needed\r
-        */\r
-    pproc->inp = stdin_data;\r
-    pproc->incnt = stdin_data_len;\r
-       if (!pproc->inp) {\r
-               stdin_eof = TRUE;\r
-               CloseHandle((HANDLE)pproc->sv_stdin[0]);\r
-               (HANDLE)pproc->sv_stdin[0] = 0;\r
-       } else {\r
-               tStdin = (HANDLE) _beginthreadex( 0, 1024,\r
-                       (unsigned (__stdcall *) (void *))proc_stdin_thread, pproc, 0,\r
-                       (unsigned int *) &dwStdin);\r
-               if (tStdin == 0) {\r
-                       pproc->last_err = GetLastError();\r
-                       pproc->lerrno = E_SCALL;\r
-                       goto done;\r
-               }\r
-       }\r
-       \r
-       /*\r
-        *   Assume child will produce stdout and stderr\r
-        */ \r
-       tStdout = (HANDLE) _beginthreadex( 0, 1024,\r
-               (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,\r
-               (unsigned int *) &dwStdout);\r
-       tStderr = (HANDLE) _beginthreadex( 0, 1024,\r
-               (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,\r
-               (unsigned int *) &dwStderr);\r
-       \r
-       if (tStdout == 0 || tStderr == 0) {\r
-       \r
-               pproc->last_err = GetLastError();\r
-               pproc->lerrno = E_SCALL;\r
-               goto done;\r
-       }\r
-\r
-\r
-       /*\r
-        *  Wait for all I/O to finish and for the child process to exit\r
-        */\r
-\r
-       while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {\r
-               wait_count = 0;\r
-               if (!stdin_eof) {\r
-                       wait_list[wait_count++] = tStdin;\r
-               }\r
-               if (!stdout_eof) {\r
-                       wait_list[wait_count++] = tStdout;\r
-               }\r
-               if (!stderr_eof) {\r
-                       wait_list[wait_count++] = tStderr;\r
-               }\r
-               if (!child_dead) {\r
-                       wait_list[wait_count++] = childhand;\r
-               }\r
-               \r
-               wait_return = WaitForMultipleObjects(wait_count, wait_list,\r
-                        FALSE, /* don't wait for all: one ready will do */\r
-                        child_dead? 1000 :INFINITE); /* after the child dies, subthreads have\r
-                               one second to collect all remaining output */\r
-               \r
-               if (wait_return == WAIT_FAILED) {\r
-/*                     map_windows32_error_to_string(GetLastError());*/\r
-                       pproc->last_err = GetLastError();\r
-                       pproc->lerrno = E_SCALL;\r
-                       goto done;\r
-               }\r
-\r
-               ready_hand = wait_list[wait_return - WAIT_OBJECT_0];\r
-               \r
-               if (ready_hand == tStdin) {\r
-                       CloseHandle((HANDLE)pproc->sv_stdin[0]);\r
-                       (HANDLE)pproc->sv_stdin[0] = 0;\r
-                       CloseHandle(tStdin);\r
-                       tStdin = 0;\r
-                       stdin_eof = TRUE;\r
-               \r
-               } else if (ready_hand == tStdout) {\r
-               \r
-                       CloseHandle((HANDLE)pproc->sv_stdout[0]);\r
-                       (HANDLE)pproc->sv_stdout[0] = 0;\r
-                       CloseHandle(tStdout);\r
-                       tStdout = 0;\r
-                       stdout_eof = TRUE;\r
-               \r
-               } else if (ready_hand == tStderr) {\r
-                       \r
-                       CloseHandle((HANDLE)pproc->sv_stderr[0]);\r
-                       (HANDLE)pproc->sv_stderr[0] = 0;\r
-                       CloseHandle(tStderr);\r
-                       tStderr = 0;\r
-                       stderr_eof = TRUE;\r
-               \r
-               } else if (ready_hand == childhand) {\r
-                       \r
-                       if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) {\r
-                               pproc->last_err = GetLastError();\r
-                               pproc->lerrno = E_SCALL;\r
-                               goto done;\r
-                       }\r
-                       child_dead = TRUE;\r
-       \r
-               } else {\r
-               \r
-                       /* ?? Got back a handle we didn't query ?? */\r
-                       pproc->last_err = 0;\r
-                       pproc->lerrno = E_FAIL;\r
-                       goto done;\r
-               }\r
-       }\r
\r
- done:\r
-       if (tStdin != 0)\r
-               CloseHandle(tStdin);\r
-       if (tStdout != 0)\r
-               CloseHandle(tStdout);\r
-       if (tStderr != 0)\r
-               CloseHandle(tStderr);\r
-\r
-       if (pproc->lerrno)\r
-               return(-1);\r
-       else\r
-               return(0);\r
-\r
-}\r
-\r
-/*\r
- * Purpose: collects output from child process and returns results\r
- *\r
- * Description:\r
- *\r
- * Returns: \r
- *\r
- * Notes/Dependencies:\r
- */\r
-       long\r
-process_file_io(\r
-       HANDLE proc)\r
-{\r
-       sub_process *pproc;\r
-       HANDLE childhand;\r
-       DWORD wait_return;\r
-\r
-       if (proc == NULL)\r
-               pproc = process_wait_for_any_private();\r
-       else\r
-               pproc = (sub_process *)proc;\r
-\r
-       /* some sort of internal error */\r
-       if (!pproc)\r
-               return -1;\r
-\r
-       childhand = (HANDLE) pproc->pid;\r
-\r
-       /*\r
-        * This function is poorly named, and could also be used just to wait\r
-        * for child death if you're doing your own pipe I/O.  If that is \r
-        * the case, close the pipe handles here.\r
-        */\r
-       if (pproc->sv_stdin[0]) {\r
-               CloseHandle((HANDLE)pproc->sv_stdin[0]);\r
-               pproc->sv_stdin[0] = 0;\r
-       }\r
-       if (pproc->sv_stdout[0]) {\r
-               CloseHandle((HANDLE)pproc->sv_stdout[0]);\r
-               pproc->sv_stdout[0] = 0;\r
-       }\r
-       if (pproc->sv_stderr[0]) {\r
-               CloseHandle((HANDLE)pproc->sv_stderr[0]);\r
-               pproc->sv_stderr[0] = 0;\r
-       }\r
-\r
-       /*\r
-        *  Wait for the child process to exit\r
-        */\r
-\r
-       wait_return = WaitForSingleObject(childhand, INFINITE);\r
-               \r
-       if (wait_return != WAIT_OBJECT_0) {\r
-/*             map_windows32_error_to_string(GetLastError());*/\r
-               pproc->last_err = GetLastError();\r
-               pproc->lerrno = E_SCALL;\r
-               goto done2;\r
-       }\r
-\r
-       if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) {\r
-               pproc->last_err = GetLastError();\r
-               pproc->lerrno = E_SCALL;\r
-       }\r
-       \r
-done2:\r
-       if (pproc->lerrno)\r
-               return(-1);\r
-       else\r
-               return(0);\r
-\r
-}\r
-\r
-/*\r
- * Description:  Clean up any leftover handles, etc.  It is up to the\r
- * caller to manage and free the input, ouput, and stderr buffers.\r
- */\r
-       void\r
-process_cleanup(\r
-       HANDLE proc)\r
-{\r
-       sub_process *pproc = (sub_process *)proc;\r
-       int i;\r
-\r
-       if (pproc->using_pipes) {\r
-               for (i= 0; i <= 1; i++) {\r
-                       if ((HANDLE)pproc->sv_stdin[i])\r
-                               CloseHandle((HANDLE)pproc->sv_stdin[i]);\r
-                       if ((HANDLE)pproc->sv_stdout[i])\r
-                               CloseHandle((HANDLE)pproc->sv_stdout[i]);\r
-                       if ((HANDLE)pproc->sv_stderr[i])\r
-                               CloseHandle((HANDLE)pproc->sv_stderr[i]);\r
-               }\r
-       }\r
-       if ((HANDLE)pproc->pid)\r
-               CloseHandle((HANDLE)pproc->pid);\r
-       \r
-       free(pproc);\r
-}\r
-\r
-\r
-/*\r
- * Description: \r
- *      Create a command line buffer to pass to CreateProcess\r
- *\r
- * Returns:  the buffer or NULL for failure\r
- *     Shell case:  sh_name a:/full/path/to/script argv[1] argv[2] ...\r
- *  Otherwise:   argv[0] argv[1] argv[2] ...\r
- *\r
- * Notes/Dependencies: \r
- *   CreateProcess does not take an argv, so this command creates a\r
- *   command line for the executable.  \r
- */\r
-\r
-static char *\r
-make_command_line( char *shell_name, char *full_exec_path, char **argv)\r
-{\r
-       int             argc = 0;\r
-       char**          argvi;\r
-       int*            enclose_in_quotes = NULL;\r
-       int*            enclose_in_quotes_i;\r
-       unsigned int    bytes_required = 0;\r
-       char*           command_line;\r
-       char*           command_line_i;\r
-\r
-       if (shell_name && full_exec_path) {\r
-               bytes_required\r
-                 = strlen(shell_name) + 1 + strlen(full_exec_path);\r
-               /*\r
-                * Skip argv[0] if any, when shell_name is given.\r
-                */\r
-               if (*argv) argv++;\r
-               /*\r
-                * Add one for the intervening space.\r
-                */\r
-               if (*argv) bytes_required++;\r
-       }\r
-\r
-       argvi = argv;\r
-       while (*(argvi++)) argc++;\r
-\r
-       if (argc) {\r
-               enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));\r
-\r
-               if (!enclose_in_quotes) {\r
-                       return NULL;\r
-               }\r
-       }\r
-\r
-       /* We have to make one pass through each argv[i] to see if we need\r
-        * to enclose it in ", so we might as well figure out how much\r
-        * memory we'll need on the same pass.\r
-        */\r
-\r
-       argvi = argv;\r
-       enclose_in_quotes_i = enclose_in_quotes;\r
-       while(*argvi) {\r
-               char* p = *argvi;\r
-               unsigned int backslash_count = 0;\r
-\r
-               /*\r
-                * We have to enclose empty arguments in ".\r
-                */\r
-               if (!(*p)) *enclose_in_quotes_i = 1;\r
-\r
-               while(*p) {\r
-                       switch (*p) {\r
-                       case '\"':\r
-                               /*\r
-                                * We have to insert a backslash for each "\r
-                                * and each \ that precedes the ".\r
-                                */\r
-                               bytes_required += (backslash_count + 1);\r
-                               backslash_count = 0;\r
-                               break;\r
-\r
-                       case '\\':\r
-                               backslash_count++;\r
-                               break;\r
-       /*\r
-        * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress\r
-        * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so\r
-        * that argv in always equals argv out. This was removed.  Say you have\r
-        * such a program named glob.exe.  You enter\r
-        * glob '*'\r
-        * at the sh command prompt.  Obviously the intent is to make glob do the\r
-        * wildcarding instead of sh.  If we set *enclose_in_quotes_i for '*' or '?',\r
-        * then the command line that glob would see would be\r
-        * glob "*"\r
-        * and the _setargv in SETARGV.OBJ would _not_ expand the *.\r
-        */\r
-                       case ' ':\r
-                       case '\t':\r
-                               *enclose_in_quotes_i = 1;\r
-                               /* fall through */\r
-\r
-                       default:\r
-                               backslash_count = 0;\r
-                               break;\r
-                       }\r
-                       \r
-                       /*\r
-                        * Add one for each character in argv[i].\r
-                        */\r
-                       bytes_required++;\r
-\r
-                       p++;\r
-               }\r
-\r
-               if (*enclose_in_quotes_i) {\r
-                       /*\r
-                        * Add one for each enclosing ",\r
-                        * and one for each \ that precedes the\r
-                        * closing ".\r
-                        */\r
-                       bytes_required += (backslash_count + 2);\r
-               }\r
-               \r
-               /*\r
-                * Add one for the intervening space.\r
-                */\r
-               if (*(++argvi)) bytes_required++;\r
-               enclose_in_quotes_i++;\r
-       }\r
-\r
-       /*\r
-        * Add one for the terminating NULL.\r
-        */\r
-       bytes_required++;\r
-\r
-       command_line = (char*) malloc(bytes_required);\r
-\r
-       if (!command_line) {\r
-               if (enclose_in_quotes) free(enclose_in_quotes);\r
-               return NULL;\r
-       }\r
-\r
-       command_line_i = command_line;\r
-\r
-       if (shell_name && full_exec_path) {\r
-               while(*shell_name) {\r
-                       *(command_line_i++) = *(shell_name++);\r
-               }\r
-\r
-               *(command_line_i++) = ' ';\r
-\r
-               while(*full_exec_path) {\r
-                       *(command_line_i++) = *(full_exec_path++);\r
-               }\r
-\r
-               if (*argv) {\r
-                       *(command_line_i++) = ' ';\r
-               }\r
-       }\r
-\r
-       argvi = argv;\r
-       enclose_in_quotes_i = enclose_in_quotes;\r
-\r
-       while(*argvi) {\r
-               char* p = *argvi;\r
-               unsigned int backslash_count = 0;\r
-\r
-               if (*enclose_in_quotes_i) {\r
-                       *(command_line_i++) = '\"';\r
-               }\r
-\r
-               while(*p) {\r
-                       if (*p == '\"') {\r
-                               /*\r
-                                * We have to insert a backslash for the "\r
-                                * and each \ that precedes the ".\r
-                                */\r
-                               backslash_count++;\r
-\r
-                               while(backslash_count) {\r
-                                       *(command_line_i++) = '\\';\r
-                                       backslash_count--;\r
-                               };\r
-\r
-                       } else if (*p == '\\') {\r
-                               backslash_count++;\r
-                       } else {\r
-                               backslash_count = 0;\r
-                       }\r
-\r
-                       /*\r
-                        * Copy the character.\r
-                        */\r
-                       *(command_line_i++) = *(p++);\r
-               }\r
-\r
-               if (*enclose_in_quotes_i) {\r
-                       /*\r
-                        * Add one \ for each \ that precedes the\r
-                        * closing ".\r
-                        */\r
-                       while(backslash_count--) {\r
-                               *(command_line_i++) = '\\';\r
-                       };\r
-                               \r
-                       *(command_line_i++) = '\"';\r
-               }\r
-               \r
-               /*\r
-                * Append an intervening space.\r
-                */\r
-               if (*(++argvi)) {\r
-                       *(command_line_i++) = ' ';\r
-               }\r
-               \r
-               enclose_in_quotes_i++;\r
-       }\r
-\r
-       /*\r
-        * Append the terminating NULL.\r
-        */\r
-       *command_line_i = '\0';\r
-\r
-       if (enclose_in_quotes) free(enclose_in_quotes);\r
-       return command_line;\r
-}\r
-\r
-/*\r
- * Description: Given an argv and optional envp, launch the process\r
- *              using the default stdin, stdout, and stderr handles.\r
- *              Also, register process so that process_wait_for_any_private()\r
- *             can be used via process_file_io(NULL) or \r
- *             process_wait_for_any().\r
- *\r
- * Returns: \r
- *\r
- * Notes/Dependencies:  \r
- */\r
-HANDLE\r
-process_easy(\r
-       char **argv,\r
-       char **envp)\r
-{\r
-  HANDLE hIn;\r
-  HANDLE hOut;\r
-  HANDLE hErr;\r
-  HANDLE hProcess;\r
-\r
-  if (DuplicateHandle(GetCurrentProcess(),\r
-                      GetStdHandle(STD_INPUT_HANDLE),\r
-                      GetCurrentProcess(),\r
-                      &hIn,\r
-                      0,\r
-                      TRUE,\r
-                      DUPLICATE_SAME_ACCESS) == FALSE) {\r
-    fprintf(stderr,\r
-            "process_easy: DuplicateHandle(In) failed (e=%d)\n",\r
-            GetLastError());\r
-    return INVALID_HANDLE_VALUE;\r
-  }\r
-  if (DuplicateHandle(GetCurrentProcess(),\r
-                      GetStdHandle(STD_OUTPUT_HANDLE),\r
-                      GetCurrentProcess(),\r
-                      &hOut,\r
-                      0,\r
-                      TRUE,\r
-                      DUPLICATE_SAME_ACCESS) == FALSE) {\r
-    fprintf(stderr,\r
-           "process_easy: DuplicateHandle(Out) failed (e=%d)\n",\r
-           GetLastError());\r
-    return INVALID_HANDLE_VALUE;\r
-  }\r
-  if (DuplicateHandle(GetCurrentProcess(),\r
-                      GetStdHandle(STD_ERROR_HANDLE),\r
-                      GetCurrentProcess(),\r
-                      &hErr,\r
-                      0,\r
-                      TRUE,\r
-                      DUPLICATE_SAME_ACCESS) == FALSE) {\r
-    fprintf(stderr,\r
-            "process_easy: DuplicateHandle(Err) failed (e=%d)\n",\r
-            GetLastError());\r
-    return INVALID_HANDLE_VALUE;\r
-  }\r
-\r
-  hProcess = process_init_fd(hIn, hOut, hErr);\r
-\r
-  if (process_begin(hProcess, argv, envp, argv[0], NULL)) {\r
-    fake_exits_pending++;\r
-    ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);\r
-\r
-    /* close up unused handles */\r
-    CloseHandle(hIn);\r
-    CloseHandle(hOut);\r
-    CloseHandle(hErr);\r
-  }\r
-\r
-  process_register(hProcess);\r
-\r
-  return hProcess;\r
-}\r
+#include <stdlib.h>
+#include <stdio.h>
+#include <process.h>  /* for msvc _beginthreadex, _endthreadex */
+#include <windows.h>
+
+#include "sub_proc.h"
+#include "proc.h"
+#include "w32err.h"
+#include "config.h"
+
+static char *make_command_line( char *shell_name, char *exec_path, char **argv);
+
+typedef struct sub_process_t {
+       int sv_stdin[2];
+       int sv_stdout[2];
+       int sv_stderr[2];
+       int using_pipes;
+       char *inp;
+       DWORD incnt;
+       char * volatile outp;
+       volatile DWORD outcnt;
+       char * volatile errp;
+       volatile DWORD errcnt;
+       int pid;
+       int exit_code;
+       int signal;
+       long last_err;
+       long lerrno;
+} sub_process;
+
+/* keep track of children so we can implement a waitpid-like routine */
+static sub_process *proc_array[256];
+static int proc_index = 0;
+static int fake_exits_pending = 0;
+
+/*
+ * When a process has been waited for, adjust the wait state
+ * array so that we don't wait for it again
+ */
+static void
+process_adjust_wait_state(sub_process* pproc)
+{
+       int i;
+
+       if (!proc_index)
+               return;
+
+       for (i = 0; i < proc_index; i++)
+               if (proc_array[i]->pid == pproc->pid)
+                       break;
+
+       if (i < proc_index) {
+               proc_index--;
+               if (i != proc_index)
+                       memmove(&proc_array[i], &proc_array[i+1],
+                               (proc_index-i) * sizeof(sub_process*));
+               proc_array[proc_index] = NULL;
+       }
+}
+
+/*
+ * Waits for any of the registered child processes to finish.
+ */
+static sub_process *
+process_wait_for_any_private(void)
+{
+       HANDLE handles[256];
+       DWORD retval, which;
+       int i;
+
+       if (!proc_index)
+               return NULL;
+
+       /* build array of handles to wait for */
+       for (i = 0; i < proc_index; i++) {
+               handles[i] = (HANDLE) proc_array[i]->pid;
+
+               if (fake_exits_pending && proc_array[i]->exit_code)
+                       break;
+       }
+
+       /* wait for someone to exit */
+       if (!fake_exits_pending) {
+               retval = WaitForMultipleObjects(proc_index, handles, FALSE, INFINITE);
+               which = retval - WAIT_OBJECT_0;
+       } else {
+               fake_exits_pending--;
+               retval = !WAIT_FAILED;
+               which = i;
+       }
+
+       /* return pointer to process */
+       if (retval != WAIT_FAILED) {
+               sub_process* pproc = proc_array[which];
+               process_adjust_wait_state(pproc);
+               return pproc;
+       } else
+               return NULL;
+}
+
+/*
+ * Terminate a process.
+ */
+BOOL
+process_kill(HANDLE proc, int signal)
+{
+       sub_process* pproc = (sub_process*) proc;
+       pproc->signal = signal;
+       return (TerminateProcess((HANDLE) pproc->pid, signal));
+}
+
+/*
+ * Use this function to register processes you wish to wait for by
+ * calling process_file_io(NULL) or process_wait_any(). This must be done
+ * because it is possible for callers of this library to reuse the same
+ * handle for multiple processes launches :-(
+ */
+void
+process_register(HANDLE proc)
+{
+       proc_array[proc_index++] = (sub_process *) proc;
+}
+
+/*
+ * Public function which works kind of like waitpid(). Wait for any
+ * of the children to die and return results. To call this function,
+ * you must do 1 of things:
+ *
+ *     x = process_easy(...);
+ *
+ * or
+ *
+ *     x = process_init_fd();
+ *     process_register(x);
+ *
+ * or
+ *
+ *     x = process_init();
+ *     process_register(x);
+ *
+ * You must NOT then call process_pipe_io() because this function is
+ * not capable of handling automatic notification of any child
+ * death.
+ */
+
+HANDLE
+process_wait_for_any(void)
+{
+       sub_process* pproc = process_wait_for_any_private();
+
+       if (!pproc)
+               return NULL;
+       else {
+               /*
+                * Ouch! can't tell caller if this fails directly. Caller
+                * will have to use process_last_err()
+                 */
+               (void) process_file_io(pproc);
+               return ((HANDLE) pproc);
+       }
+}
+
+long
+process_errno(HANDLE proc)
+{
+       return (((sub_process *)proc)->lerrno);
+}
+
+long
+process_signal(HANDLE proc)
+{
+       return (((sub_process *)proc)->signal);
+}
+
+       long
+process_last_err(HANDLE proc)
+{
+       return (((sub_process *)proc)->last_err);
+}
+
+       long
+process_exit_code(HANDLE proc)
+{
+       return (((sub_process *)proc)->exit_code);
+}
+
+       char *
+process_outbuf(HANDLE proc)
+{
+       return (((sub_process *)proc)->outp);
+}
+
+       char *
+process_errbuf(HANDLE proc)
+{
+       return (((sub_process *)proc)->errp);
+}
+
+       int
+process_outcnt(HANDLE proc)
+{
+       return (((sub_process *)proc)->outcnt);
+}
+
+       int
+process_errcnt(HANDLE proc)
+{
+       return (((sub_process *)proc)->errcnt);
+}
+
+       void
+process_pipes(HANDLE proc, int pipes[3])
+{
+       pipes[0] = ((sub_process *)proc)->sv_stdin[0];
+       pipes[1] = ((sub_process *)proc)->sv_stdout[0];
+       pipes[2] = ((sub_process *)proc)->sv_stderr[0];
+       return;
+}
+
+
+       HANDLE
+process_init()
+{
+       sub_process *pproc;
+       /*
+        * open file descriptors for attaching stdin/stdout/sterr
+        */
+       HANDLE stdin_pipes[2];
+       HANDLE stdout_pipes[2];
+       HANDLE stderr_pipes[2];
+       SECURITY_ATTRIBUTES inherit;
+       BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
+
+       pproc = malloc(sizeof(*pproc));
+       memset(pproc, 0, sizeof(*pproc));
+
+       /* We can't use NULL for lpSecurityDescriptor because that
+          uses the default security descriptor of the calling process.
+          Instead we use a security descriptor with no DACL.  This
+          allows nonrestricted access to the associated objects. */
+
+       if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
+                                         SECURITY_DESCRIPTOR_REVISION)) {
+               pproc->last_err = GetLastError();
+               pproc->lerrno = E_SCALL;
+               return((HANDLE)pproc);
+       }
+
+       inherit.nLength = sizeof(inherit);
+       inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
+       inherit.bInheritHandle = TRUE;
+
+       // By convention, parent gets pipe[0], and child gets pipe[1]
+       // This means the READ side of stdin pipe goes into pipe[1]
+       // and the WRITE side of the stdout and stderr pipes go into pipe[1]
+       if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
+       CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
+       CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {
+
+               pproc->last_err = GetLastError();
+               pproc->lerrno = E_SCALL;
+               return((HANDLE)pproc);
+       }
+
+       //
+       // Mark the parent sides of the pipes as non-inheritable
+       //
+       if (SetHandleInformation(stdin_pipes[0],
+                               HANDLE_FLAG_INHERIT, 0) == FALSE ||
+               SetHandleInformation(stdout_pipes[0],
+                               HANDLE_FLAG_INHERIT, 0) == FALSE ||
+               SetHandleInformation(stderr_pipes[0],
+                               HANDLE_FLAG_INHERIT, 0) == FALSE) {
+
+               pproc->last_err = GetLastError();
+               pproc->lerrno = E_SCALL;
+               return((HANDLE)pproc);
+       }
+       pproc->sv_stdin[0]  = (int) stdin_pipes[0];
+       pproc->sv_stdin[1]  = (int) stdin_pipes[1];
+       pproc->sv_stdout[0] = (int) stdout_pipes[0];
+       pproc->sv_stdout[1] = (int) stdout_pipes[1];
+       pproc->sv_stderr[0] = (int) stderr_pipes[0];
+       pproc->sv_stderr[1] = (int) stderr_pipes[1];
+
+       pproc->using_pipes = 1;
+
+       pproc->lerrno = 0;
+
+       return((HANDLE)pproc);
+}
+
+
+       HANDLE
+process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
+{
+       sub_process *pproc;
+
+       pproc = malloc(sizeof(*pproc));
+       memset(pproc, 0, sizeof(*pproc));
+
+       /*
+        * Just pass the provided file handles to the 'child side' of the
+        * pipe, bypassing pipes altogether.
+        */
+       pproc->sv_stdin[1]  = (int) stdinh;
+       pproc->sv_stdout[1] = (int) stdouth;
+       pproc->sv_stderr[1] = (int) stderrh;
+
+       pproc->last_err = pproc->lerrno = 0;
+
+       return((HANDLE)pproc);
+}
+
+
+static HANDLE
+find_file(char *exec_path, LPOFSTRUCT file_info)
+{
+       HANDLE exec_handle;
+       char *fname;
+       char *ext;
+
+       fname = malloc(strlen(exec_path) + 5);
+       strcpy(fname, exec_path);
+       ext = fname + strlen(fname);
+
+       strcpy(ext, ".exe");
+       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
+                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
+               free(fname);
+               return(exec_handle);
+       }
+
+       strcpy(ext, ".cmd");
+       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
+                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
+               free(fname);
+               return(exec_handle);
+       }
+
+       strcpy(ext, ".bat");
+       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
+                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
+               free(fname);
+               return(exec_handle);
+       }
+
+       /* should .com come before this case? */
+       if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info,
+                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
+               free(fname);
+               return(exec_handle);
+       }
+
+       strcpy(ext, ".com");
+       if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
+                       OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
+               free(fname);
+               return(exec_handle);
+       }
+
+       free(fname);
+       return(exec_handle);
+}
+
+
+/*
+ * Description:   Create the child process to be helped
+ *
+ * Returns:
+ *
+ * Notes/Dependencies:
+ */
+long
+process_begin(
+       HANDLE proc,
+       char **argv,
+       char **envp,
+       char *exec_path,
+       char *as_user)
+{
+       sub_process *pproc = (sub_process *)proc;
+       char *shell_name = 0;
+       int file_not_found=0;
+       HANDLE exec_handle;
+       char buf[256];
+       DWORD bytes_returned;
+       DWORD flags;
+       char *command_line;
+       STARTUPINFO startInfo;
+       PROCESS_INFORMATION procInfo;
+       char *envblk=NULL;
+       OFSTRUCT file_info;
+
+
+       /*
+        *  Shell script detection...  if the exec_path starts with #! then
+        *  we want to exec shell-script-name exec-path, not just exec-path
+        *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
+        *  hard-code the path to the shell or perl or whatever:  Instead, we
+        *  assume it's in the path somewhere (generally, the NT tools
+        *  bin directory)
+        *  We use OpenFile here because it is capable of searching the Path.
+        */
+
+       exec_handle = find_file(exec_path, &file_info);
+
+       /*
+        * If we couldn't open the file, just assume that Windows32 will be able
+        * to find and execute it.
+        */
+       if (exec_handle == (HANDLE)HFILE_ERROR) {
+               file_not_found++;
+       }
+       else {
+               /* Attempt to read the first line of the file */
+               if (ReadFile( exec_handle,
+                               buf, sizeof(buf) - 1, /* leave room for trailing NULL */
+                               &bytes_returned, 0) == FALSE || bytes_returned < 2) {
+
+                       pproc->last_err = GetLastError();
+                       pproc->lerrno = E_IO;
+                       CloseHandle(exec_handle);
+                       return(-1);
+               }
+               if (buf[0] == '#' && buf[1] == '!') {
+                       /*
+                        *  This is a shell script...  Change the command line from
+                        *      exec_path args to shell_name exec_path args
+                        */
+                       char *p;
+
+                       /*  Make sure buf is NULL terminated */
+                       buf[bytes_returned] = 0;
+                       /*
+                        * Depending on the file system type, etc. the first line
+                        * of the shell script may end with newline or newline-carriage-return
+                        * Whatever it ends with, cut it off.
+                        */
+                       p= strchr(buf, '\n');
+                       if (p)
+                               *p = 0;
+                       p = strchr(buf, '\r');
+                       if (p)
+                               *p = 0;
+
+                       /*
+                        *  Find base name of shell
+                        */
+                       shell_name = strrchr( buf, '/');
+                       if (shell_name) {
+                               shell_name++;
+                       } else {
+                               shell_name = &buf[2];/* skipping "#!" */
+                       }
+
+               }
+               CloseHandle(exec_handle);
+       }
+
+       flags = 0;
+
+       if (file_not_found)
+               command_line = make_command_line( shell_name, exec_path, argv);
+       else
+               command_line = make_command_line( shell_name, file_info.szPathName,
+                                argv);
+
+       if ( command_line == NULL ) {
+               pproc->last_err = 0;
+               pproc->lerrno = E_NO_MEM;
+               return(-1);
+       }
+
+       if (envp) {
+               if (arr2envblk(envp, &envblk) ==FALSE) {
+                       pproc->last_err = 0;
+                       pproc->lerrno = E_NO_MEM;
+                       free( command_line );
+                       return(-1);
+               }
+       }
+
+       if ((shell_name) || (file_not_found)) {
+               exec_path = 0;  /* Search for the program in %Path% */
+       } else {
+               exec_path = file_info.szPathName;
+       }
+
+       /*
+        *  Set up inherited stdin, stdout, stderr for child
+        */
+       GetStartupInfo(&startInfo);
+       startInfo.dwFlags = STARTF_USESTDHANDLES;
+       startInfo.lpReserved = 0;
+       startInfo.cbReserved2 = 0;
+       startInfo.lpReserved2 = 0;
+       startInfo.lpTitle = shell_name ? shell_name : exec_path;
+       startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
+       startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
+       startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];
+
+       if (as_user) {
+               if (envblk) free(envblk);
+               return -1;
+       } else {
+               if (CreateProcess(
+                       exec_path,
+                       command_line,
+                       NULL,
+                       0, /* default security attributes for thread */
+                       TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
+                       flags,
+                       envblk,
+                       0, /* default starting directory */
+                       &startInfo,
+                       &procInfo) == FALSE) {
+
+                       pproc->last_err = GetLastError();
+                       pproc->lerrno = E_FORK;
+                       fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line);
+                       if (envblk) free(envblk);
+                       free( command_line );
+                       return(-1);
+               }
+       }
+
+       pproc->pid = (int)procInfo.hProcess;
+       /* Close the thread handle -- we'll just watch the process */
+       CloseHandle(procInfo.hThread);
+
+       /* Close the halves of the pipes we don't need */
+       if (pproc->sv_stdin) {
+               CloseHandle((HANDLE)pproc->sv_stdin[1]);
+               (HANDLE)pproc->sv_stdin[1] = 0;
+       }
+       if (pproc->sv_stdout) {
+               CloseHandle((HANDLE)pproc->sv_stdout[1]);
+               (HANDLE)pproc->sv_stdout[1] = 0;
+       }
+       if (pproc->sv_stderr) {
+               CloseHandle((HANDLE)pproc->sv_stderr[1]);
+               (HANDLE)pproc->sv_stderr[1] = 0;
+       }
+
+       free( command_line );
+       if (envblk) free(envblk);
+       pproc->lerrno=0;
+       return 0;
+}
+
+
+
+static DWORD
+proc_stdin_thread(sub_process *pproc)
+{
+       DWORD in_done;
+       for (;;) {
+               if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
+                                        &in_done, NULL) == FALSE)
+                       _endthreadex(0);
+               // This if should never be true for anonymous pipes, but gives
+               // us a chance to change I/O mechanisms later
+               if (in_done < pproc->incnt) {
+                       pproc->incnt -= in_done;
+                       pproc->inp += in_done;
+               } else {
+                       _endthreadex(0);
+               }
+       }
+       return 0; // for compiler warnings only.. not reached
+}
+
+static DWORD
+proc_stdout_thread(sub_process *pproc)
+{
+       DWORD bufsize = 1024;
+       char c;
+       DWORD nread;
+       pproc->outp = malloc(bufsize);
+       if (pproc->outp == NULL)
+               _endthreadex(0);
+       pproc->outcnt = 0;
+
+       for (;;) {
+               if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
+                                       == FALSE) {
+/*                     map_windows32_error_to_string(GetLastError());*/
+                       _endthreadex(0);
+               }
+               if (nread == 0)
+                       _endthreadex(0);
+               if (pproc->outcnt + nread > bufsize) {
+                       bufsize += nread + 512;
+                       pproc->outp = realloc(pproc->outp, bufsize);
+                       if (pproc->outp == NULL) {
+                               pproc->outcnt = 0;
+                               _endthreadex(0);
+                       }
+               }
+               pproc->outp[pproc->outcnt++] = c;
+       }
+       return 0;
+}
+
+static DWORD
+proc_stderr_thread(sub_process *pproc)
+{
+       DWORD bufsize = 1024;
+       char c;
+       DWORD nread;
+       pproc->errp = malloc(bufsize);
+       if (pproc->errp == NULL)
+               _endthreadex(0);
+       pproc->errcnt = 0;
+
+       for (;;) {
+               if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
+                       map_windows32_error_to_string(GetLastError());
+                       _endthreadex(0);
+               }
+               if (nread == 0)
+                       _endthreadex(0);
+               if (pproc->errcnt + nread > bufsize) {
+                       bufsize += nread + 512;
+                       pproc->errp = realloc(pproc->errp, bufsize);
+                       if (pproc->errp == NULL) {
+                               pproc->errcnt = 0;
+                               _endthreadex(0);
+                       }
+               }
+               pproc->errp[pproc->errcnt++] = c;
+       }
+       return 0;
+}
+
+
+/*
+ * Purpose: collects output from child process and returns results
+ *
+ * Description:
+ *
+ * Returns:
+ *
+ * Notes/Dependencies:
+ */
+       long
+process_pipe_io(
+       HANDLE proc,
+       char *stdin_data,
+       int stdin_data_len)
+{
+       sub_process *pproc = (sub_process *)proc;
+       bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
+       HANDLE childhand = (HANDLE) pproc->pid;
+       HANDLE tStdin, tStdout, tStderr;
+       DWORD dwStdin, dwStdout, dwStderr;
+       HANDLE wait_list[4];
+       DWORD wait_count;
+       DWORD wait_return;
+       HANDLE ready_hand;
+       bool_t child_dead = FALSE;
+
+
+       /*
+        *  Create stdin thread, if needed
+        */
+    pproc->inp = stdin_data;
+    pproc->incnt = stdin_data_len;
+       if (!pproc->inp) {
+               stdin_eof = TRUE;
+               CloseHandle((HANDLE)pproc->sv_stdin[0]);
+               (HANDLE)pproc->sv_stdin[0] = 0;
+       } else {
+               tStdin = (HANDLE) _beginthreadex( 0, 1024,
+                       (unsigned (__stdcall *) (void *))proc_stdin_thread, pproc, 0,
+                       (unsigned int *) &dwStdin);
+               if (tStdin == 0) {
+                       pproc->last_err = GetLastError();
+                       pproc->lerrno = E_SCALL;
+                       goto done;
+               }
+       }
+
+       /*
+        *   Assume child will produce stdout and stderr
+        */
+       tStdout = (HANDLE) _beginthreadex( 0, 1024,
+               (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
+               (unsigned int *) &dwStdout);
+       tStderr = (HANDLE) _beginthreadex( 0, 1024,
+               (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
+               (unsigned int *) &dwStderr);
+
+       if (tStdout == 0 || tStderr == 0) {
+
+               pproc->last_err = GetLastError();
+               pproc->lerrno = E_SCALL;
+               goto done;
+       }
+
+
+       /*
+        *  Wait for all I/O to finish and for the child process to exit
+        */
+
+       while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
+               wait_count = 0;
+               if (!stdin_eof) {
+                       wait_list[wait_count++] = tStdin;
+               }
+               if (!stdout_eof) {
+                       wait_list[wait_count++] = tStdout;
+               }
+               if (!stderr_eof) {
+                       wait_list[wait_count++] = tStderr;
+               }
+               if (!child_dead) {
+                       wait_list[wait_count++] = childhand;
+               }
+
+               wait_return = WaitForMultipleObjects(wait_count, wait_list,
+                        FALSE, /* don't wait for all: one ready will do */
+                        child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
+                               one second to collect all remaining output */
+
+               if (wait_return == WAIT_FAILED) {
+/*                     map_windows32_error_to_string(GetLastError());*/
+                       pproc->last_err = GetLastError();
+                       pproc->lerrno = E_SCALL;
+                       goto done;
+               }
+
+               ready_hand = wait_list[wait_return - WAIT_OBJECT_0];
+
+               if (ready_hand == tStdin) {
+                       CloseHandle((HANDLE)pproc->sv_stdin[0]);
+                       (HANDLE)pproc->sv_stdin[0] = 0;
+                       CloseHandle(tStdin);
+                       tStdin = 0;
+                       stdin_eof = TRUE;
+
+               } else if (ready_hand == tStdout) {
+
+                       CloseHandle((HANDLE)pproc->sv_stdout[0]);
+                       (HANDLE)pproc->sv_stdout[0] = 0;
+                       CloseHandle(tStdout);
+                       tStdout = 0;
+                       stdout_eof = TRUE;
+
+               } else if (ready_hand == tStderr) {
+
+                       CloseHandle((HANDLE)pproc->sv_stderr[0]);
+                       (HANDLE)pproc->sv_stderr[0] = 0;
+                       CloseHandle(tStderr);
+                       tStderr = 0;
+                       stderr_eof = TRUE;
+
+               } else if (ready_hand == childhand) {
+
+                       if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) {
+                               pproc->last_err = GetLastError();
+                               pproc->lerrno = E_SCALL;
+                               goto done;
+                       }
+                       child_dead = TRUE;
+
+               } else {
+
+                       /* ?? Got back a handle we didn't query ?? */
+                       pproc->last_err = 0;
+                       pproc->lerrno = E_FAIL;
+                       goto done;
+               }
+       }
+
+ done:
+       if (tStdin != 0)
+               CloseHandle(tStdin);
+       if (tStdout != 0)
+               CloseHandle(tStdout);
+       if (tStderr != 0)
+               CloseHandle(tStderr);
+
+       if (pproc->lerrno)
+               return(-1);
+       else
+               return(0);
+
+}
+
+/*
+ * Purpose: collects output from child process and returns results
+ *
+ * Description:
+ *
+ * Returns:
+ *
+ * Notes/Dependencies:
+ */
+       long
+process_file_io(
+       HANDLE proc)
+{
+       sub_process *pproc;
+       HANDLE childhand;
+       DWORD wait_return;
+
+       if (proc == NULL)
+               pproc = process_wait_for_any_private();
+       else
+               pproc = (sub_process *)proc;
+
+       /* some sort of internal error */
+       if (!pproc)
+               return -1;
+
+       childhand = (HANDLE) pproc->pid;
+
+       /*
+        * This function is poorly named, and could also be used just to wait
+        * for child death if you're doing your own pipe I/O.  If that is
+        * the case, close the pipe handles here.
+        */
+       if (pproc->sv_stdin[0]) {
+               CloseHandle((HANDLE)pproc->sv_stdin[0]);
+               pproc->sv_stdin[0] = 0;
+       }
+       if (pproc->sv_stdout[0]) {
+               CloseHandle((HANDLE)pproc->sv_stdout[0]);
+               pproc->sv_stdout[0] = 0;
+       }
+       if (pproc->sv_stderr[0]) {
+               CloseHandle((HANDLE)pproc->sv_stderr[0]);
+               pproc->sv_stderr[0] = 0;
+       }
+
+       /*
+        *  Wait for the child process to exit
+        */
+
+       wait_return = WaitForSingleObject(childhand, INFINITE);
+
+       if (wait_return != WAIT_OBJECT_0) {
+/*             map_windows32_error_to_string(GetLastError());*/
+               pproc->last_err = GetLastError();
+               pproc->lerrno = E_SCALL;
+               goto done2;
+       }
+
+       if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) {
+               pproc->last_err = GetLastError();
+               pproc->lerrno = E_SCALL;
+       }
+
+done2:
+       if (pproc->lerrno)
+               return(-1);
+       else
+               return(0);
+
+}
+
+/*
+ * Description:  Clean up any leftover handles, etc.  It is up to the
+ * caller to manage and free the input, ouput, and stderr buffers.
+ */
+       void
+process_cleanup(
+       HANDLE proc)
+{
+       sub_process *pproc = (sub_process *)proc;
+       int i;
+
+       if (pproc->using_pipes) {
+               for (i= 0; i <= 1; i++) {
+                       if ((HANDLE)pproc->sv_stdin[i])
+                               CloseHandle((HANDLE)pproc->sv_stdin[i]);
+                       if ((HANDLE)pproc->sv_stdout[i])
+                               CloseHandle((HANDLE)pproc->sv_stdout[i]);
+                       if ((HANDLE)pproc->sv_stderr[i])
+                               CloseHandle((HANDLE)pproc->sv_stderr[i]);
+               }
+       }
+       if ((HANDLE)pproc->pid)
+               CloseHandle((HANDLE)pproc->pid);
+
+       free(pproc);
+}
+
+
+/*
+ * Description:
+ *      Create a command line buffer to pass to CreateProcess
+ *
+ * Returns:  the buffer or NULL for failure
+ *     Shell case:  sh_name a:/full/path/to/script argv[1] argv[2] ...
+ *  Otherwise:   argv[0] argv[1] argv[2] ...
+ *
+ * Notes/Dependencies:
+ *   CreateProcess does not take an argv, so this command creates a
+ *   command line for the executable.
+ */
+
+static char *
+make_command_line( char *shell_name, char *full_exec_path, char **argv)
+{
+       int             argc = 0;
+       char**          argvi;
+       int*            enclose_in_quotes = NULL;
+       int*            enclose_in_quotes_i;
+       unsigned int    bytes_required = 0;
+       char*           command_line;
+       char*           command_line_i;
+
+       if (shell_name && full_exec_path) {
+               bytes_required
+                 = strlen(shell_name) + 1 + strlen(full_exec_path);
+               /*
+                * Skip argv[0] if any, when shell_name is given.
+                */
+               if (*argv) argv++;
+               /*
+                * Add one for the intervening space.
+                */
+               if (*argv) bytes_required++;
+       }
+
+       argvi = argv;
+       while (*(argvi++)) argc++;
+
+       if (argc) {
+               enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));
+
+               if (!enclose_in_quotes) {
+                       return NULL;
+               }
+       }
+
+       /* We have to make one pass through each argv[i] to see if we need
+        * to enclose it in ", so we might as well figure out how much
+        * memory we'll need on the same pass.
+        */
+
+       argvi = argv;
+       enclose_in_quotes_i = enclose_in_quotes;
+       while(*argvi) {
+               char* p = *argvi;
+               unsigned int backslash_count = 0;
+
+               /*
+                * We have to enclose empty arguments in ".
+                */
+               if (!(*p)) *enclose_in_quotes_i = 1;
+
+               while(*p) {
+                       switch (*p) {
+                       case '\"':
+                               /*
+                                * We have to insert a backslash for each "
+                                * and each \ that precedes the ".
+                                */
+                               bytes_required += (backslash_count + 1);
+                               backslash_count = 0;
+                               break;
+
+#ifndef HAVE_MKS_SHELL
+                       case '\\':
+                               backslash_count++;
+                               break;
+#endif
+       /*
+        * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
+        * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
+        * that argv in always equals argv out. This was removed.  Say you have
+        * such a program named glob.exe.  You enter
+        * glob '*'
+        * at the sh command prompt.  Obviously the intent is to make glob do the
+        * wildcarding instead of sh.  If we set *enclose_in_quotes_i for '*' or '?',
+        * then the command line that glob would see would be
+        * glob "*"
+        * and the _setargv in SETARGV.OBJ would _not_ expand the *.
+        */
+                       case ' ':
+                       case '\t':
+                               *enclose_in_quotes_i = 1;
+                               /* fall through */
+
+                       default:
+                               backslash_count = 0;
+                               break;
+                       }
+
+                       /*
+                        * Add one for each character in argv[i].
+                        */
+                       bytes_required++;
+
+                       p++;
+               }
+
+               if (*enclose_in_quotes_i) {
+                       /*
+                        * Add one for each enclosing ",
+                        * and one for each \ that precedes the
+                        * closing ".
+                        */
+                       bytes_required += (backslash_count + 2);
+               }
+
+               /*
+                * Add one for the intervening space.
+                */
+               if (*(++argvi)) bytes_required++;
+               enclose_in_quotes_i++;
+       }
+
+       /*
+        * Add one for the terminating NULL.
+        */
+       bytes_required++;
+
+       command_line = (char*) malloc(bytes_required);
+
+       if (!command_line) {
+               if (enclose_in_quotes) free(enclose_in_quotes);
+               return NULL;
+       }
+
+       command_line_i = command_line;
+
+       if (shell_name && full_exec_path) {
+               while(*shell_name) {
+                       *(command_line_i++) = *(shell_name++);
+               }
+
+               *(command_line_i++) = ' ';
+
+               while(*full_exec_path) {
+                       *(command_line_i++) = *(full_exec_path++);
+               }
+
+               if (*argv) {
+                       *(command_line_i++) = ' ';
+               }
+       }
+
+       argvi = argv;
+       enclose_in_quotes_i = enclose_in_quotes;
+
+       while(*argvi) {
+               char* p = *argvi;
+               unsigned int backslash_count = 0;
+
+               if (*enclose_in_quotes_i) {
+                       *(command_line_i++) = '\"';
+               }
+
+               while(*p) {
+                       if (*p == '\"') {
+                               /*
+                                * We have to insert a backslash for the "
+                                * and each \ that precedes the ".
+                                */
+                               backslash_count++;
+
+                               while(backslash_count) {
+                                       *(command_line_i++) = '\\';
+                                       backslash_count--;
+                               };
+#ifndef HAVE_MKS_SHELL
+                       } else if (*p == '\\') {
+                               backslash_count++;
+                       } else {
+                               backslash_count = 0;
+#endif
+                       }
+
+                       /*
+                        * Copy the character.
+                        */
+                       *(command_line_i++) = *(p++);
+               }
+
+               if (*enclose_in_quotes_i) {
+#ifndef HAVE_MKS_SHELL
+                       /*
+                        * Add one \ for each \ that precedes the
+                        * closing ".
+                        */
+                       while(backslash_count--) {
+                               *(command_line_i++) = '\\';
+                       };
+#endif
+                       *(command_line_i++) = '\"';
+               }
+
+               /*
+                * Append an intervening space.
+                */
+               if (*(++argvi)) {
+                       *(command_line_i++) = ' ';
+               }
+
+               enclose_in_quotes_i++;
+       }
+
+       /*
+        * Append the terminating NULL.
+        */
+       *command_line_i = '\0';
+
+       if (enclose_in_quotes) free(enclose_in_quotes);
+       return command_line;
+}
+
+/*
+ * Description: Given an argv and optional envp, launch the process
+ *              using the default stdin, stdout, and stderr handles.
+ *              Also, register process so that process_wait_for_any_private()
+ *             can be used via process_file_io(NULL) or
+ *             process_wait_for_any().
+ *
+ * Returns:
+ *
+ * Notes/Dependencies:
+ */
+HANDLE
+process_easy(
+       char **argv,
+       char **envp)
+{
+  HANDLE hIn;
+  HANDLE hOut;
+  HANDLE hErr;
+  HANDLE hProcess;
+
+  if (DuplicateHandle(GetCurrentProcess(),
+                      GetStdHandle(STD_INPUT_HANDLE),
+                      GetCurrentProcess(),
+                      &hIn,
+                      0,
+                      TRUE,
+                      DUPLICATE_SAME_ACCESS) == FALSE) {
+    fprintf(stderr,
+            "process_easy: DuplicateHandle(In) failed (e=%d)\n",
+            GetLastError());
+    return INVALID_HANDLE_VALUE;
+  }
+  if (DuplicateHandle(GetCurrentProcess(),
+                      GetStdHandle(STD_OUTPUT_HANDLE),
+                      GetCurrentProcess(),
+                      &hOut,
+                      0,
+                      TRUE,
+                      DUPLICATE_SAME_ACCESS) == FALSE) {
+    fprintf(stderr,
+           "process_easy: DuplicateHandle(Out) failed (e=%d)\n",
+           GetLastError());
+    return INVALID_HANDLE_VALUE;
+  }
+  if (DuplicateHandle(GetCurrentProcess(),
+                      GetStdHandle(STD_ERROR_HANDLE),
+                      GetCurrentProcess(),
+                      &hErr,
+                      0,
+                      TRUE,
+                      DUPLICATE_SAME_ACCESS) == FALSE) {
+    fprintf(stderr,
+            "process_easy: DuplicateHandle(Err) failed (e=%d)\n",
+            GetLastError());
+    return INVALID_HANDLE_VALUE;
+  }
+
+  hProcess = process_init_fd(hIn, hOut, hErr);
+
+  if (process_begin(hProcess, argv, envp, argv[0], NULL)) {
+    fake_exits_pending++;
+    ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);
+
+    /* close up unused handles */
+    CloseHandle(hIn);
+    CloseHandle(hOut);
+    CloseHandle(hErr);
+  }
+
+  process_register(hProcess);
+
+  return hProcess;
+}