DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦b8a279d91⟧ TextFile

    Length: 65556 (0x10014)
    Types: TextFile
    Names: »make-3.56-3.57.diff«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦this⟧ »./make-3.56-3.57.diff« 

TextFile

diff -rc make-3.56/CHANGES make-3.57/CHANGES
*** make-3.56/CHANGES	Sat Aug 26 13:59:42 1989
--- make-3.57/CHANGES	Thu Sep 28 17:32:18 1989
***************
*** 1,6 ****
--- 1,11 ----
  User-visible changes in GNU Make, excluding bug fixes, since version 3.05:
  ==========================================================================
  \f


+ Version 3.57
+ 
+ * Dependencies of the form `-lLIB' are searched for as /usr/local/lib/libLIB.a
+   as well as libLIB.a in /usr/lib, /lib, the current directory, and VPATH.
+ \f


  Version 3.55
  
  * There is now a Unix man page for GNU Make.  It is certainly not a replacement
diff -rc make-3.56/ChangeLog make-3.57/ChangeLog
*** make-3.56/ChangeLog	Fri Sep 22 16:18:39 1989
--- make-3.57/ChangeLog	Fri Nov  3 19:31:28 1989
***************
*** 1,3 ****
--- 1,221 ----
+ Fri Nov  3 15:53:03 1989  Roland McGrath  (mcgrath at tully.Berkeley.EDU)
+ 
+ 	* Version 3.57.
+ 
+ 	* variable.c (try_variable_definition): Don't calculate useless value.
+ 
+ 	* main.c (define_makeflags): Fixed -j propagation.
+ 
+ 	* commands.c (execute_file_commands): Removed unused variable.
+ 
+ Sun Oct 29 11:11:15 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* commands.c (execute_file_commands): If the commands are empty, call
+ 	notice_finished_file before returning.
+ 
+ Sat Oct 28 23:06:32 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* remake.c (update_file_1): Don't always update a target that has no
+ 	deps.  Only do this for double-colon targets.
+ 
+ Wed Oct 25 16:36:16 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* main.c (main) [hpux]: hpux == HPUX.
+ 	* compatMakefile (defines): Document that HPUX should be defined.
+ 
+ Tue Oct 24 19:19:48 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.8.
+ 
+ 	* job.c (exec_command): Fixed what mode bits are checked.
+ 
+ 	* remake.c (update_file_1): "No cmds and no deps actually changed"
+ 	loses if ! FILE->is_target.
+ 
+ 	* make.texinfo (Variables: Setting): Don't say that spaces after a
+ 	variable definition are ignored (since they aren't).
+ 
+ Mon Oct 23 14:34:23 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.7.
+ 
+ 	* remake.c (update_file_1): If, after being updated, any dependency
+ 	does not exist, remake the target.
+ 
+ 	* remake.c (update_file_1): Always update if FILE has commands but no
+ 	deps.
+ 
+ 	* commands.c (execute_file_commands): If we return early because there
+ 	are no commands, set FILE->updated.
+ 
+ Thu Oct 19 18:47:37 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* arscan.c (ar_scan) [M_XENIX]: Don't run atoi or atol on the
+ 	`struct ar_hdr' members that are int or long int on Xenix.
+ 
+ Sat Oct 14 10:43:03 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* ar.c (ar_member_date_1): Use ar_name_equal.
+ 
+ 	* arscan.c (ar_scan): Cosmetic clean ups.
+ 	(ar_name_equal): New function to compare names, handling truncated
+ 	member names and special `.o' truncation.
+ 	(ar_member_pos): Use ar_name_equal.
+ 
+ 	* Version 3.56.6.
+ 
+ 	* file.h (struct file): Made `update_status' a `short int', and moved
+ 	it before `command_state' so the bitfields can be packed better.
+ 
+ 	* remake.c (notice_finished_file): Don't increment files_remade.
+ 	* job.c (new_job): Do.
+ 
+ 	* job.c (start_job): Don't return a value.  Always set
+ 	CHILD->file->command_state to either cs_running or cs_finished.
+ 	(new_job, child_handler): Don't expect start_job to return a value.
+ 	Instead, look at the file's command_state.
+ 
+ 	* commands.c (chop_commands): Merged into job.c (new_job).
+ 
+ 	* commands.h: Don't declare chop_commands.
+ 
+ 	* job.h: Don't declare start_job.  Do declare new_job.
+ 
+ 	* commands.c (execute_file_commands): Call new_job.
+ 
+ 	* job.c (free_child): New function to free a `struct child'.
+ 	(child_handler, new_job): Call it.
+ 
+ 	* job.c (start_job): Made static.
+ 	(new_job): New function to create a `struct child' and call start_job.
+ 
+ 	* commands.c (execute_file_commands): Don't set FILE->update_status if
+ 	start_job fails.
+ 
+ 	* remake.c (files_remade): Made global.
+ 
+ 	* function.c (expand_function): Don't use `reading_filename' and
+ 	`reading_lineno_ptr' if they're nil.
+ 
+ Fri Oct 13 18:16:00 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* read.c (find_semicolon): New function to look for an unquoted ; not
+ 	preceded by an unquoted # in a string.
+ 	(read_makefile): Call it before expanding the line.  If it finds a ;,
+ 	cut the line short there before expanding it.  If not, call it again
+ 	after expanding.
+ 
+ 	* commands.c (execute_file_commands): Don't check FILE->command_state.
+ 	We won't get called unless it's cs_not_started.
+ 
+ 	* read.c (read_makefile): Call collapse_line on the variable-expanded
+ 	rule line after checking for ; and #.
+ 
+ 	* job.c (start_job): When there are no more commands, always return 0.
+ 	* commands.c (execute_file_commands): Don't put the new child in the
+ 	`children' chain unless FILE->command_state is cs_running.
+ 
+ 	* read.c (read_makefile): Rewrote ;-handling to only do it once (why
+ 	did I do it twice??) and to check for a # before the ;.
+ 
+ 	* job.c (start_job): Set CHILD->file->update_status to 0 when we run
+ 	out of commands.  Set it to 1 before returning failure.
+ 	(child_handler): Don't set C->file->update_status to 0 when start_job
+ 	returns success and commands are not running.
+ 
+ 	* read.c (read_makefile): If there is a # before the ; for commands,
+ 	forget the ; and commands.
+ 
+ Thu Oct 12 15:48:16 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* job.c (child_execute_job): Pass -c to the shell.
+ 
+ Wed Oct 11 18:41:10 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.5.
+ 
+ 	* main.c (define_makeflags): Cleaned up to keep better track of dashes
+ 	written, etc.
+ 
+ 	* function.c (expand_function: `shell'): When converting newlines to
+ 	spaces in output, search with `index' calls rather than a simple loop.
+ 
+ 	* main.c (main): Make sure stdout is line-buffered.
+ 
+ 	* main.c (decode_switches): Always check for missing switch arg.
+ 
+ Mon Oct  9 17:17:23 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.4.
+ 
+ Sat Oct  7 00:32:25 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* commands.c (set_file_variables): #ifdef NO_ARCHIVES, still set $@ and
+ 	$%.
+ 
+ 	* commands.c (set_file_variables): Include a trailing slash in the
+ 	directory variables (@D, etc.).
+ 
+ 	* job.c (child_handler): Call notice_finished_file after changing a
+ 	child's state to `cs_finished'.
+ 
+ 	* remake.c (update_file_1): Don't call notice_finished_file if
+ 	FILE->command_state == cs_finished.
+ 
+ Wed Oct  4 16:09:33 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.3.
+ 
+ Tue Oct  3 21:09:51 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* read.c (read_all_makefiles): When setting elements of MAKEFILES from
+ 	the contents of read_makefiles, make sure we're using the right
+ 	element.
+ 
+ 	* dir.c, glob.c [USGr3 || DIRENT]: Don't define d_ino as d_fileno.
+ 
+ 	* Version 3.56.2.
+ 
+ 	* remake.c (update_file_1): Return zero after calling remake_file if
+ 	FILE->command_state != cs_finished.  Test update_status thoroughly.
+ 
+ 	* commands.c (execute_file_commands): Don't call notice_finished_file.
+ 
+ 	* remake.c (remake_file): Return immediately after calling
+ 	execute_file_commands.
+ 
+ Sat Sep 30 14:57:05 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.1 (alpha).
+ 
+ 	* file.h (struct file): Made `update_status' not be a bitfield, since
+ 	some broken compilers don't handle it right.
+ 
+ 	* function.c (expand_function: `join'): Don't clobber the pointers and
+ 	then try to free them.
+ 
+ 	* job.c (exec_command): Fixed & vs = precedence problem.
+ 
+ Thu Sep 28 17:29:56 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* remake.c (update_file_1): Fixed typo in debugging output.
+ 
+ 	* remake.c (library_file_mtime): Search for /usr/local/lib/libLIB.a
+ 	after /usr/lib/libLIB.a.
+ 
+ Tue Sep 26 16:07:58 1989  Roland McGrath  (mcgrath at helen.Berkeley.EDU)
+ 
+ 	* read.c (conditional_line): For `ifeq (a, b)', swallow space after the
+ 	comma.
+ 
+ Sun Sep 24 13:25:32 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* function.c (patsubst_function): If BY_WORD and the match is not a
+ 	full word, update the text pointer correctly.
+ 
+ 	* function.c (expand_function: `word'): Don't lose track of the second
+ 	arg's expansion and free something else instead.
+ 
  Fri Sep 22 16:15:29 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
  
  	* Version 3.56.
diff -rc make-3.56/Makefile make-3.57/Makefile
*** make-3.56/Makefile	Fri Sep 22 16:28:36 1989
--- make-3.57/Makefile	Fri Nov  3 19:32:53 1989
***************
*** 23,36 ****
  LDFLAGS = -g
  
  # Define nothing for BSD, USG for System V, and USGr3 (as well as USG) for
! # SVR3.  If you have a USG hybrid with <sys/wait.h> and wait3, define
! # HAVE_SYS_WAIT.  If you are USG but have sys_siglist, define HAVE_SIGLIST.  If
! # you are USG, and not USGr3, but have dup2, define HAVE_DUP2.  If your `cc'
! # command doesn't grok -o options with -c (true for many 4.2 BSD derivatives),
! # define NO_MINUS_C_MINUS_O.  If you don't want archive support, define
! # NO_ARCHIVES.  If you want to avoid use of floating-point numbers, define
! # NO_FLOAT.  If your compiler can handle `enum' bitfields (and it's not GCC),
! # define ENUM_BITFIELDS.
  defines =
  
  # Define UMAX here to use Encore's inq_stats call.  If the load average is in a
--- 23,37 ----
  LDFLAGS = -g
  
  # Define nothing for BSD, USG for System V, and USGr3 (as well as USG) for
! # SVR3, HPUX for HP-UX (as well as USG or USGr3 as appropriate).  If you have a
! # USG hybrid with <sys/wait.h> and wait3, define HAVE_SYS_WAIT.  If you are USG
! # but have sys_siglist, define HAVE_SIGLIST.  If you are USG, and not USGr3,
! # but have dup2, define HAVE_DUP2.  If your `cc' command doesn't grok -o
! # options with -c (true for many 4.2 BSD derivatives), define
! # NO_MINUS_C_MINUS_O.  If you don't want archive support, define NO_ARCHIVES.
! # If you want to avoid use of floating-point numbers, define NO_FLOAT.  If your
! # compiler can handle `enum' bitfields (and it's not GCC), define
! # ENUM_BITFIELDS.
  defines =
  
  # Define UMAX here to use Encore's inq_stats call.  If the load average is in a
diff -rc make-3.56/README make-3.57/README
*** make-3.56/README	Fri Sep 22 16:34:55 1989
--- make-3.57/README	Fri Nov  3 19:32:29 1989
***************
*** 1,4 ****
! This directory contains the 3.56 test release of GNU Make.
  All bugs reported for previous test releases have been fixed.
  Some bugs probably remain.
  
--- 1,4 ----
! This directory contains the 3.57 test release of GNU Make.
  All bugs reported for previous test releases have been fixed.
  Some bugs probably remain.
  
diff -rc make-3.56/ar.c make-3.57/ar.c
*** make-3.56/ar.c	Thu Sep  7 17:23:51 1989
--- make-3.57/ar.c	Sat Oct 14 15:18:37 1989
***************
*** 91,97 ****
       int uid, gid, mode;
       char *mem;
  {
!   return streq (name, mem) ? date : 0;
  }
  \f


  /* Set the archive-member NAME's modtime to now.  */
--- 91,97 ----
       int uid, gid, mode;
       char *mem;
  {
!   return ar_name_equal (name, mem) ? date : 0;
  }
  \f


  /* Set the archive-member NAME's modtime to now.  */
diff -rc make-3.56/arscan.c make-3.57/arscan.c
*** make-3.56/arscan.c	Mon Jun 19 14:37:37 1989
--- make-3.57/arscan.c	Thu Oct 19 22:46:34 1989
***************
*** 83,91 ****
  {
    register int desc = open (archive, O_RDONLY, 0);
    if (desc < 0)
!     {
!       return -1;
!     }
  #ifdef SARMAG
    {
      char buf[SARMAG];
--- 83,89 ----
  {
    register int desc = open (archive, O_RDONLY, 0);
    if (desc < 0)
!     return -1;
  #ifdef SARMAG
    {
      char buf[SARMAG];
***************
*** 92,98 ****
      register int nread = read (desc, buf, SARMAG);
      if (nread != SARMAG || bcmp (buf, ARMAG, SARMAG))
        {
! 	close (desc);
  	return -2;
        }
    }
--- 90,96 ----
      register int nread = read (desc, buf, SARMAG);
      if (nread != SARMAG || bcmp (buf, ARMAG, SARMAG))
        {
! 	(void) close (desc);
  	return -2;
        }
    }
***************
*** 106,112 ****
      register int nread = read(desc, &buf, sizeof (buf));
      if (nread != sizeof (buf) || buf != ARMAG)
        {
! 	close (desc);
  	return -2;
        }
    }
--- 104,110 ----
      register int nread = read(desc, &buf, sizeof (buf));
      if (nread != sizeof (buf) || buf != ARMAG)
        {
! 	(void) close (desc);
  	return -2;
        }
    }
***************
*** 128,134 ****
        {
  	register int nread;
  	struct ar_hdr member_header;
! 	char name [1 + sizeof member_header.ar_name];
  	long int eltsize;
  	int eltmode;
  	long int fnval;
--- 126,132 ----
        {
  	register int nread;
  	struct ar_hdr member_header;
! 	char name[sizeof member_header.ar_name + 1];
  	long int eltsize;
  	int eltmode;
  	long int fnval;
***************
*** 135,147 ****
  
  	if (lseek (desc, member_offset, 0) < 0)
  	  {
! 	    close (desc);
  	    return -2;
  	  }
  
  	nread = read (desc, (char *) &member_header, sizeof (struct ar_hdr));
  	if (nread == 0)
! 	  /* No data left means end of file; that is ok */
  	  break;
  
  	if (nread != sizeof (member_header)
--- 133,145 ----
  
  	if (lseek (desc, member_offset, 0) < 0)
  	  {
! 	    (void) close (desc);
  	    return -2;
  	  }
  
  	nread = read (desc, (char *) &member_header, sizeof (struct ar_hdr));
  	if (nread == 0)
! 	  /* No data left means end of file; that is OK.  */
  	  break;
  
  	if (nread != sizeof (member_header)
***************
*** 150,158 ****
  #endif
  	    )
  	  {
! 	    close (desc);
  	    return -2;
  	  }
  	bcopy (member_header.ar_name, name, sizeof member_header.ar_name);
  	{
  	  register char *p = name + sizeof member_header.ar_name;
--- 148,157 ----
  #endif
  	    )
  	  {
! 	    (void) close (desc);
  	    return -2;
  	  }
+ 
  	bcopy (member_header.ar_name, name, sizeof member_header.ar_name);
  	{
  	  register char *p = name + sizeof member_header.ar_name;
***************
*** 176,189 ****
  	fnval =
  	  (*function) (desc, name, member_offset,
  		       member_offset + sizeof (member_header), eltsize,
  		       atol (member_header.ar_date),
  		       atoi (member_header.ar_uid),
  		       atoi (member_header.ar_gid),
  		       eltmode, arg);
  
  	if (fnval)
  	  {
! 	    close (desc);
  	    return fnval;
  	  }
  
--- 175,194 ----
  	fnval =
  	  (*function) (desc, name, member_offset,
  		       member_offset + sizeof (member_header), eltsize,
+ #ifndef	M_XENIX
  		       atol (member_header.ar_date),
  		       atoi (member_header.ar_uid),
  		       atoi (member_header.ar_gid),
+ #else	/* Xenix.  */
+ 		       member_header.ar_date,
+ 		       member_header.ar_uid,
+ 		       member_header.ar_gid,
+ #endif	/* Not Xenix.  */
  		       eltmode, arg);
  
  	if (fnval)
  	  {
! 	    (void) close (desc);
  	    return fnval;
  	  }
  
***************
*** 196,201 ****
--- 201,234 ----
    return 0;
  }
  \f


+ /* Return nonzero iff NAME matches MEM.  If NAME is longer than
+    sizeof (struct ar_hdr.ar_name), MEM may be the truncated version.  */
+ 
+ int
+ ar_name_equal (name, mem)
+      char *name, *mem;
+ {
+   if (!strncmp (name, mem, 13))
+     {
+       unsigned int namelen, memlen;
+ 
+       namelen = strlen (name);
+       if (namelen <= 13)
+ 	return 1;
+ 
+       memlen = strlen (mem);
+       if (memlen <= 13)
+ 	return 1;
+ 
+       if (name[namelen - 2] == '.' && name[namelen - 1] == 'o'
+ 	  && memlen == 15 && mem[13] == '.' && mem[14] == 'o')
+ 	return 1;
+       return !strncmp (mem + 13, name + 13,
+ 		       (namelen > memlen ? namelen : memlen) - 13);
+     }
+   return 0;
+ }
+ \f


  /* ARGSUSED */
  static long int
  ar_member_pos (desc, name, hdrpos, datapos, size, date, uid, gid, mode, mem)
***************
*** 205,211 ****
       int uid, gid, mode;
       char *mem;
  {
!   if (strcmp (name, mem))
      return 0;
    return hdrpos;
  }
--- 238,244 ----
       int uid, gid, mode;
       char *mem;
  {
!   if (!ar_name_equal (name, mem))
      return 0;
    return hdrpos;
  }
diff -rc make-3.56/commands.c make-3.57/commands.c
*** make-3.56/commands.c	Sun Sep 17 16:36:04 1989
--- make-3.57/commands.c	Fri Nov  3 16:34:18 1989
***************
*** 31,109 ****
  
  extern int getpid ();
  \f


- /* Chop CMDS->commands up into lines in CMDS->command_lines.
-    Also set the corresponding CMDS->lines_recurse elements,
-    and the CMDS->any_recurse flag.  */
- void
- chop_commands (cmds)
-      register struct commands *cmds;
- {
-   register char *p;
-   unsigned int nlines, idx;
-   char **lines;
- 
-   nlines = 5;
-   lines = (char **) xmalloc (5 * sizeof (char *));
-   idx = 0;
-   p = cmds->commands;
-   while (*p != '\0')
-     {
-       char *end = p;
-     find_end:;
-       end = index (end, '\n');
-       if (end == 0)
- 	end = p + strlen (p);
-       else if (end > p && end[-1] == '\\')
- 	{
- 	  int backslash = 1;
- 	  register char *b;
- 	  for (b = end - 2; b >= p && *b == '\\'; --b)
- 	    backslash = !backslash;
- 	  if (backslash)
- 	    {
- 	      ++end;
- 	      goto find_end;
- 	    }
- 	}
- 
-       if (idx == nlines - 1)
- 	{
- 	  nlines += 2;
- 	  lines = (char **) xrealloc ((char *) lines,
- 				      nlines * sizeof (char *));
- 	}
-       lines[idx++] = savestring (p, end - p);
-       p = end;
-       if (*p != '\0')
- 	++p;
-     }
-   lines[idx++] = 0;
- 
-   if (idx != nlines)
-     {
-       nlines = idx;
-       lines = (char **) xrealloc ((char *) lines,
- 				  nlines * sizeof (char *));
-     }
- 
-   cmds->command_lines = lines;
- 
-   cmds->any_recurse = 0;
-   --nlines;
-   cmds->lines_recurse = (char *) xmalloc (nlines);
-   for (idx = 0; idx < nlines; ++idx)
-     {
-       unsigned int len;
-       int recursive;
-       p = lines[idx];
-       len = strlen (p);
-       recursive = (sindex (p, len, "$(MAKE)", 7) != 0
- 		   || sindex (p, len, "${MAKE}", 7) != 0);
-       cmds->lines_recurse[idx] = recursive;
-       cmds->any_recurse |= recursive;
-     }
- }
- \f


  /* Set FILE's automatic variables up.  */
  
  static void
--- 31,36 ----
***************
*** 128,138 ****
        percent = savestring (p, strlen (p) - 1);
      }
    else
      {
        at = savestring (file->name, strlen (file->name));
        percent = "";
      }
- #endif
  
    DEFINE_VARIABLE ("@", 1, at);
    DEFINE_VARIABLE ("%", 1, percent);
--- 55,65 ----
        percent = savestring (p, strlen (p) - 1);
      }
    else
+ #endif	/* NO_ARCHIVES.  */
      {
        at = savestring (file->name, strlen (file->name));
        percent = "";
      }
  
    DEFINE_VARIABLE ("@", 1, at);
    DEFINE_VARIABLE ("%", 1, percent);
***************
*** 140,146 ****
  #define	LASTSLASH(s)	rindex ((s), '/')
  #define	FILEONLY(s)	(p != 0 ? p + 1 : (s))
  #define	DIRONLY(s)	(p == 0 ? "./" : p == (s) ? "/" \
! 			 : savestring ((s), p - (s)))
  
    /* $* is the stem from an implicit or static pattern rule.  */
    if (file->stem == 0)
--- 67,73 ----
  #define	LASTSLASH(s)	rindex ((s), '/')
  #define	FILEONLY(s)	(p != 0 ? p + 1 : (s))
  #define	DIRONLY(s)	(p == 0 ? "./" : p == (s) ? "/" \
! 			 : savestring ((s), (p - (s)) + 1))
  
    /* $* is the stem from an implicit or static pattern rule.  */
    if (file->stem == 0)
***************
*** 301,326 ****
       struct file *file;
  {
    register char *p;
-   register struct commands *cmds = file->cmds;
    struct child *c;
    int status;
  
-   /* Check if the commands are currently running or have already been run.  */
- 
-   switch (file->command_state)
-     {
-     case cs_not_started:
-       break;
-     case cs_deps_running:
-     case cs_running:
-     case cs_finished:
-       return;
-     case cs_invalid:
-     default:
-       abort ();
-       break;
-     }
- 
    /* Don't go through all the preparations if
       the commands are nothing but whitespace.  */
  
--- 228,236 ----
***************
*** 331,336 ****
--- 241,247 ----
      {
        file->command_state = cs_finished;
        file->update_status = 0;
+       notice_finished_file (file);
        return;
      }
  
***************
*** 340,392 ****
  
    set_file_variables (file);
  
!   /* Chop the commands up into lines.  */
!   if (cmds->command_lines == 0)
!     chop_commands (cmds);
! 
!   if (job_slots > 0)
!     /* Wait for a job slot to be freed up.  */
!     while (job_slots_used == job_slots)
!       wait_for_children (1, 0);
! 
!   /* Start the command sequence, record it in a new
!      `struct child', and add that to the chain.  */
! 
!   block_children ();
! 
!   c = (struct child *) xmalloc (sizeof (struct child));
!   c->file = file;
!   c->command_line = 0;
!   c->command_ptr = c->commands = 0;
!   c->environment = 0;
!   status = start_job (c);
! 
!   if (!status)
!     {
!       c->next = children;
!       children = c;
!       /* One more job slot is in use.  */
!       ++job_slots_used;
!     }
! 
!   unblock_children ();
! 
!   if (status)
!     {
!       free (c->commands);
!       free ((char *) c);
! 
!       file->update_status = (just_print_flag || touch_flag) ? 0 : 1;
!     }
!   else if (job_slots == 1)
!     {
!       /* Since there is only one job slot, make things run linearly.
! 	 Wait for the child to finish, setting the state to `cs_finished'.  */
!       while (file->command_state != cs_finished)
! 	wait_for_children (1, 0);
! 
!     }
!   notice_finished_file (file);
  }
  \f


  #define	PROPAGATED_SIGNAL_MASK \
--- 251,258 ----
  
    set_file_variables (file);
  
!   /* Start the commands running.  */
!   new_job (file);
  }
  \f


  #define	PROPAGATED_SIGNAL_MASK \
diff -rc make-3.56/commands.h make-3.57/commands.h
*** make-3.56/commands.h	Sat Sep  2 00:53:48 1989
--- make-3.57/commands.h	Sat Oct 14 12:15:19 1989
***************
*** 32,36 ****
  extern void execute_file_commands ();
  extern void print_commands ();
  extern void delete_child_targets ();
- 
- extern void chop_commands ();
--- 32,34 ----
diff -rc make-3.56/dir.c make-3.57/dir.c
*** make-3.56/dir.c	Tue Sep 19 23:27:41 1989
--- make-3.57/dir.c	Tue Oct  3 22:12:47 1989
***************
*** 21,29 ****
  #if	defined(USGr3) || defined(DIRENT)
  
  #include <dirent.h>
- #	if	!defined(d_ino) && !defined(d_fileno)
- #define	d_ino	d_fileno
- #	endif
  #define direct dirent
  #define	D_NAMLEN(d) strlen((d)->d_name)
  
--- 21,26 ----
diff -rc make-3.56/file.h make-3.57/file.h
*** make-3.56/file.h	Sun Sep 17 16:35:52 1989
--- make-3.57/file.h	Sat Oct 14 12:21:12 1989
***************
*** 41,46 ****
--- 41,49 ----
         or nil if there isn't one.  */
      struct file *parent;
  
+     short int update_status;	/* Status of the last attempt to update,
+ 				   or -1 if none has been made.  */
+ 
      enum			/* State of the commands.  */
        {		/* Note: It is important that cs_not_started be zero.  */
  	cs_not_started,		/* Not yet started.  */
***************
*** 50,57 ****
  	cs_invalid,
        } command_state ENUM_BITFIELD (2);
  
-     int update_status:2;	/* Status of the last attempt to update,
- 				   or -1 if none has been made.  */
      unsigned int double_colon:1;/* Nonzero for double-colon entry */
      unsigned int precious:1;	/* Non-0 means don't delete file on quit */
      unsigned int tried_implicit:1;/* Nonzero if have searched
--- 53,58 ----
diff -rc make-3.56/function.c make-3.57/function.c
*** make-3.56/function.c	Sun Sep 17 16:35:59 1989
--- make-3.57/function.c	Sat Oct 14 10:44:41 1989
***************
*** 54,60 ****
        return o;
      }
  
!   while (p = sindex (t, 0, subst, slen))
      {
        /* Output everything before this occurence of the string to replace.  */
        if (p > t)
--- 54,60 ----
        return o;
      }
  
!   while ((p = sindex (t, 0, subst, slen)) != 0)
      {
        /* Output everything before this occurence of the string to replace.  */
        if (p > t)
***************
*** 62,81 ****
  
        /* If we're substituting only by fully matched words,
  	 check if this is one.  */
!       if (by_word && (p > t && p[-1] != ' ' && p[-1] != '\t'))
! 	{
! 	  /* Struck out.  Output the rest of the string that is
! 	     no longer to be replaced.  */
! 	  o = variable_buffer_output (o, subst, slen);
! 	  continue;
! 	}
! 
!       /* Advance T past the string to be replaced.  */
!       t = p + slen;
! 
!       /* If we're substituting only at the end of whitespace-delimited
! 	 words, check if we're at the end of one.  */
!       if ((by_word || suffix_only) && (*t != '\0' && *t != ' ' && *t != '\t'))
  	/* Struck out.  Output the rest of the string that is
  	   no longer to be replaced.  */
  	o = variable_buffer_output (o, subst, slen);
--- 62,70 ----
  
        /* If we're substituting only by fully matched words,
  	 check if this is one.  */
!       if (by_word
! 	  && ((p > t && p[-1] != ' ' && p[-1] != '\t')
! 	      || (p[slen] != '\0' && p[slen] != ' ' && p[slen] != '\t')))
  	/* Struck out.  Output the rest of the string that is
  	   no longer to be replaced.  */
  	o = variable_buffer_output (o, subst, slen);
***************
*** 82,87 ****
--- 71,79 ----
        else if (rlen > 0)
  	/* Output the replacement string.  */
  	o = variable_buffer_output (o, replace, rlen);
+ 
+       /* Advance T past the string to be replaced.  */
+       t = p + slen;
      }
  
    /* Output everything left on the end.  */
***************
*** 338,344 ****
  	text = expand_argument (text, end);
  
  	/* For error messages.  */
! 	sprintf (buf, "%s:%u: ", reading_filename, *reading_lineno_ptr);
  
  	if (pipe (pipedes) < 0)
  	  {
--- 330,339 ----
  	text = expand_argument (text, end);
  
  	/* For error messages.  */
! 	if (reading_filename != 0)
! 	  sprintf (buf, "%s:%u: ", reading_filename, *reading_lineno_ptr);
! 	else
! 	  buf[0] = '\0';
  
  	if (pipe (pipedes) < 0)
  	  {
***************
*** 419,429 ****
  		/* The child finished normally.  Replace all
  		   newlines in its output with spaces, and put
  		   that in the variable output buffer.  */
! 		if (buffer[i - 1] == '\n')
! 		  --i;
! 		for (p = buffer; p < buffer + i; ++p)
! 		  if (*p == '\n')
! 		    *p = ' ';
  		o = variable_buffer_output (o, buffer, i);
  	      }
  
--- 414,423 ----
  		/* The child finished normally.  Replace all
  		   newlines in its output with spaces, and put
  		   that in the variable output buffer.  */
! 		if (i > 0 && buffer[i - 1] == '\n')
! 		  buffer[--i] = '\0';
! 		for (p = buffer; (p = index (buffer, '\n')) != 0; buffer = ++p)
! 		  *p = ' ';
  		o = variable_buffer_output (o, buffer, i);
  	      }
  
***************
*** 737,750 ****
  	   If the two arguments have a different number of words,
  	   the excess words are just output separated by blanks.  */
  	register char *tp, *pp;
! 	unsigned int tlen, plen;
  	do
  	  {
! 	    tp = find_next_token (&text, &tlen);
  	    if (tp != 0)
  	      o = variable_buffer_output (o, tp, tlen);
  	    
! 	    pp = find_next_token (&p, &plen);
  	    if (pp != 0)
  	      o = variable_buffer_output (o, pp, plen);
  	    
--- 731,747 ----
  	   If the two arguments have a different number of words,
  	   the excess words are just output separated by blanks.  */
  	register char *tp, *pp;
! 	p2 = text;
! 	p3 = p;
  	do
  	  {
! 	    unsigned int tlen, plen;
! 
! 	    tp = find_next_token (&p2, &tlen);
  	    if (tp != 0)
  	      o = variable_buffer_output (o, tp, tlen);
  	    
! 	    pp = find_next_token (&p3, &plen);
  	    if (pp != 0)
  	      o = variable_buffer_output (o, pp, plen);
  	    
***************
*** 860,879 ****
  	BADARGS ("word");
        text = expand_argument (text, p);
  
!       p = expand_argument (p + 1, end);
  
        /* Check the first argument.  */
        for (p2 = text; *p2 != '\0'; ++p2)
  	if (*p2 < '0' || *p2 > '9')
! 	  fatal ("%s:%u: non-numeric first argument to `word' function",
! 		 reading_filename, *reading_lineno_ptr);
  
        i = (unsigned int) atoi (text);
        if (i == 0)
! 	fatal ("%s:%u: the `word' function takes a one-origin index argument",
! 	       reading_filename, *reading_lineno_ptr);
!       
!       p2 = p;
        while ((p = find_next_token (&p2, &len)) != 0)
  	if (--i == 0)
  	  break;
--- 857,887 ----
  	BADARGS ("word");
        text = expand_argument (text, p);
  
!       p3 = expand_argument (p + 1, end);
  
        /* Check the first argument.  */
        for (p2 = text; *p2 != '\0'; ++p2)
  	if (*p2 < '0' || *p2 > '9')
! 	  {
! 	    if (reading_filename != 0)
! 	      fatal ("%s:%u: non-numeric first argument to `word' function",
! 		     reading_filename, *reading_lineno_ptr);
! 	    else
! 	      fatal ("non-numeric first argument to `word' function");
! 	  }
  
        i = (unsigned int) atoi (text);
        if (i == 0)
! 	{
! 	  if (reading_filename != 0)
! 	    fatal ("%s:%u: the `word' function takes a one-origin \
! index argument",
! 		   reading_filename, *reading_lineno_ptr);
! 	  else
! 	    fatal ("the `word' function takes a one-origin index argument");
! 	}
! 
!       p2 = p3;
        while ((p = find_next_token (&p2, &len)) != 0)
  	if (--i == 0)
  	  break;
***************
*** 881,887 ****
  	o = variable_buffer_output (o, p, len);
  
        free (text);
!       free (p);
        break;
  
      case function_words:
--- 889,895 ----
  	o = variable_buffer_output (o, p, len);
  
        free (text);
!       free (p3);
        break;
  
      case function_words:
diff -rc make-3.56/glob.c make-3.57/glob.c
*** make-3.56/glob.c	Fri Sep 15 14:04:41 1989
--- make-3.57/glob.c	Tue Oct  3 22:12:49 1989
***************
*** 24,32 ****
  #if	defined(USGr3) || defined(DIRENT)
  
  #include <dirent.h>
- #	if	!defined(d_ino) && !defined(d_fileno)
- #define	d_ino	d_fileno
- #	endif
  #define direct dirent
  #define	D_NAMLEN(d) strlen((d)->d_name)
  
--- 24,29 ----
***************
*** 550,555 ****
      }
  
    exit (0);
-   return 0;
  }
  #endif	/* TEST.  */
--- 547,551 ----
diff -rc make-3.56/job.c make-3.57/job.c
*** make-3.56/job.c	Thu Sep 21 15:49:50 1989
--- make-3.57/job.c	Tue Oct 24 19:38:09 1989
***************
*** 102,107 ****
--- 102,108 ----
  #endif	/* USG and not HAVE_SIGLIST.  */
  
  int child_handler ();
+ static void free_child (), start_job ();
  \f


  /* Chain of all children.  */
  
***************
*** 303,334 ****
  		}
  
  	      /* If there are more commands to run, try to start them.  */
! 	      if (start_job (c))
  		{
! 		  /* We failed to start the commands.  */
! 		  c->file->update_status
! 		    = (just_print_flag || touch_flag) ? 0 : 1;
! 		  delete_child_targets (c);
! 		}
! 	      else
! 		if (c->file->command_state == cs_running)
  		  /* Successfully started.  Loop to reap more children.  */
  		  continue;
! 		else
! 		  /* There were no more commands.  */
! 		  c->file->update_status = 0;
  	    }
  
  	  /* Set the state flag to say the commands have finished.  */
  	  c->file->command_state = cs_finished;
! 	    
  	  /* Remove the child from the chain and free it.  */
  	  if (lastc == 0)
  	    children = c->next;
  	  else
  	    lastc->next = c->next;
! 	  free (c->commands);
! 	  free ((char *) c);
  
  	  /* There is now another slot open.  */
  	  --job_slots_used;
--- 304,342 ----
  		}
  
  	      /* If there are more commands to run, try to start them.  */
! 	      start_job (c);
! 	      switch (c->file->command_state)
  		{
! 		case cs_running:
  		  /* Successfully started.  Loop to reap more children.  */
  		  continue;
! 
! 		case cs_finished:
! 		  if (c->file->update_status != 0)
! 		    {
! 		      /* We failed to start the commands.  */
! 		      delete_child_targets (c);
! 		    }
! 		  break;
! 
! 		default:
! 		  error ("internal error: `%s' command_state \
! %d in child_handler", c->file->name);
! 		  abort ();
! 		  break;
! 		}
  	    }
  
  	  /* Set the state flag to say the commands have finished.  */
  	  c->file->command_state = cs_finished;
! 	  notice_finished_file (c->file);
! 
  	  /* Remove the child from the chain and free it.  */
  	  if (lastc == 0)
  	    children = c->next;
  	  else
  	    lastc->next = c->next;
! 	  free_child (c);
  
  	  /* There is now another slot open.  */
  	  --job_slots_used;
***************
*** 384,393 ****
    unblock_children ();
  }
  \f


  /* Start a job to run the commands specified in CHILD.
     CHILD is updated to reflect the commands and ID of the child process.  */
  
! int
  start_job (child)
       register struct child *child;
  {
--- 392,412 ----
    unblock_children ();
  }
  \f


+ /* Free the storage allocated for CHILD.  */
+ 
+ static void
+ free_child (child)
+      register struct child *child;
+ {
+   if (child->commands != 0)
+     free (child->commands);
+   free ((char *) child);
+ }
+ \f


  /* Start a job to run the commands specified in CHILD.
     CHILD is updated to reflect the commands and ID of the child process.  */
  
! static void
  start_job (child)
       register struct child *child;
  {
***************
*** 405,411 ****
  	/* There are no more lines to be expanded.  */
  	child->command_ptr = 0;
  	child->file->command_state = cs_finished;
! 	return (just_print_flag || touch_flag);
        }
      else
        {
--- 424,431 ----
  	/* There are no more lines to be expanded.  */
  	child->command_ptr = 0;
  	child->file->command_state = cs_finished;
! 	child->file->update_status = 0;
! 	return;
        }
      else
        {
***************
*** 475,481 ****
  
    /* If -q was given, just say that updating `failed'.  */
    if (question_flag && !recursive)
!     return 1;
  
    /* There may be some preceding whitespace left if there
       was nothing but a backslash on the first line.  */
--- 495,501 ----
  
    /* If -q was given, just say that updating `failed'.  */
    if (question_flag && !recursive)
!     goto error;
  
    /* There may be some preceding whitespace left if there
       was nothing but a backslash on the first line.  */
***************
*** 483,489 ****
  
    if (*p == '\0')
      /* There were no commands on this line.  Go to the next.  */
!     return start_job (child);
  
    /* Print out the command.  */
  
--- 503,512 ----
  
    if (*p == '\0')
      /* There were no commands on this line.  Go to the next.  */
!     {
!       start_job (child);
!       return;
!     }
  
    /* Print out the command.  */
  
***************
*** 493,499 ****
    /* If -n was given, recurse to get the next line in the sequence.  */
  
    if (just_print_flag && !recursive)
!     return start_job (child);
  
    /* Collapse backslash-newlines in this line.  */
  
--- 516,525 ----
    /* If -n was given, recurse to get the next line in the sequence.  */
  
    if (just_print_flag && !recursive)
!     {
!       start_job (child);
!       return;
!     }
  
    /* Collapse backslash-newlines in this line.  */
  
***************
*** 543,549 ****
        int is_remote, id, used_stdin;
        if (start_remote_job (argv, child->good_stdin ? 0 : bad_stdin,
  			    &is_remote, &id, &used_stdin))
! 	return 1;
        else
  	{
  	  if (child->good_stdin && !used_stdin)
--- 569,575 ----
        int is_remote, id, used_stdin;
        if (start_remote_job (argv, child->good_stdin ? 0 : bad_stdin,
  			    &is_remote, &id, &used_stdin))
! 	goto error;
        else
  	{
  	  if (child->good_stdin && !used_stdin)
***************
*** 573,588 ****
  	{
  	  /* Fork failed!  */
  	  perror_with_name (VFORK_NAME, "");
! 	  return 1;
  	}
      }
  
!   /* We are the parent side.  Set the state to say
!      the commands are running and return success.  */
  
    child->file->command_state = cs_running;
!   return 0;
  }
  \f


  /* Replace the current process with one executing the command in ARGV.
     STDIN_FD and STDOUT_FD are used as the process's stdin and stdout;
--- 599,749 ----
  	{
  	  /* Fork failed!  */
  	  perror_with_name (VFORK_NAME, "");
! 	  goto error;
  	}
      }
  
!   /* We are the parent side.  Set the state to
!      say the commands are running and return.  */
  
    child->file->command_state = cs_running;
!   return;
! 
!  error:;
!   child->file->update_status = 1;
!   child->file->command_state = cs_finished;
  }
+ 
+ 
+ /* Create a `struct child' for FILE and start its commands running.  */
+ 
+ void
+ new_job (file)
+      register struct file *file;
+ {
+   extern unsigned int files_remade;
+   register struct commands *cmds = file->cmds;
+   register struct child *c;
+ 
+   if (cmds->command_lines == 0)
+     {
+       /* Chop CMDS->commands up into lines in CMDS->command_lines.
+ 	 Also set the corresponding CMDS->lines_recurse elements,
+ 	 and the CMDS->any_recurse flag.  */
+       register char *p;
+       unsigned int nlines, idx;
+       char **lines;
+ 
+       nlines = 5;
+       lines = (char **) xmalloc (5 * sizeof (char *));
+       idx = 0;
+       p = cmds->commands;
+       while (*p != '\0')
+ 	{
+ 	  char *end = p;
+ 	find_end:;
+ 	  end = index (end, '\n');
+ 	  if (end == 0)
+ 	    end = p + strlen (p);
+ 	  else if (end > p && end[-1] == '\\')
+ 	    {
+ 	      int backslash = 1;
+ 	      register char *b;
+ 	      for (b = end - 2; b >= p && *b == '\\'; --b)
+ 		backslash = !backslash;
+ 	      if (backslash)
+ 		{
+ 		  ++end;
+ 		  goto find_end;
+ 		}
+ 	    }
+ 
+ 	  if (idx == nlines - 1)
+ 	    {
+ 	      nlines += 2;
+ 	      lines = (char **) xrealloc ((char *) lines,
+ 					  nlines * sizeof (char *));
+ 	    }
+ 	  lines[idx++] = savestring (p, end - p);
+ 	  p = end;
+ 	  if (*p != '\0')
+ 	    ++p;
+ 	}
+       lines[idx++] = 0;
+ 
+       if (idx != nlines)
+ 	{
+ 	  nlines = idx;
+ 	  lines = (char **) xrealloc ((char *) lines,
+ 				      nlines * sizeof (char *));
+ 	}
+ 
+       cmds->command_lines = lines;
+ 
+       cmds->any_recurse = 0;
+       --nlines;
+       cmds->lines_recurse = (char *) xmalloc (nlines);
+       for (idx = 0; idx < nlines; ++idx)
+ 	{
+ 	  unsigned int len;
+ 	  int recursive;
+ 	  p = lines[idx];
+ 	  len = strlen (p);
+ 	  recursive = (sindex (p, len, "$(MAKE)", 7) != 0
+ 		       || sindex (p, len, "${MAKE}", 7) != 0);
+ 	  cmds->lines_recurse[idx] = recursive;
+ 	  cmds->any_recurse |= recursive;
+ 	}
+     }
+ 
+   if (job_slots > 0)
+     /* Wait for a job slot to be freed up.  */
+     while (job_slots_used == job_slots)
+       wait_for_children (1, 0);
+ 
+   /* Start the command sequence, record it in a new
+      `struct child', and add that to the chain.  */
+ 
+   block_children ();
+ 
+   c = (struct child *) xmalloc (sizeof (struct child));
+   c->file = file;
+   c->command_line = 0;
+   c->command_ptr = c->commands = 0;
+   c->environment = 0;
+   start_job (c);
+   switch (file->command_state)
+     {
+     case cs_running:
+       c->next = children;
+       children = c;
+       /* One more job slot is in use.  */
+       ++job_slots_used;
+       break;
+ 
+     case cs_finished:
+       free_child (c);
+       break;
+ 
+     default:
+       error ("internal error: `%s' command_state == %d in new_job",
+ 	     file->name, (int) file->command_state);
+       abort ();
+       break;
+     }
+ 
+   unblock_children ();
+ 
+   ++files_remade;
+ 
+   if (job_slots == 1 && file->command_state == cs_running)
+     {
+       /* Since there is only one job slot, make things run linearly.
+ 	 Wait for the child to finish, setting the state to `cs_finished'.  */
+       while (file->command_state != cs_finished)
+ 	wait_for_children (1, 0);
+     }
+ }
  \f


  /* Replace the current process with one executing the command in ARGV.
     STDIN_FD and STDOUT_FD are used as the process's stdin and stdout;
***************
*** 626,636 ****
      argc = 0;
      while (argv[argc] != 0)
        ++argc;
!     shell_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *));
      shell_argv[0] = variable_expand_for_file ("$(SHELL)", file);
!     shell_argv[1 + argc] = 0;
!     while (argc-- > 0)
!       shell_argv[1 + argc] = argv[argc];
      exec_command (shell_argv, envp, path);
  
      /* If that returned, die.  */
--- 787,798 ----
      argc = 0;
      while (argv[argc] != 0)
        ++argc;
!     shell_argv = (char **) alloca ((2 + argc + 1) * sizeof (char *));
      shell_argv[0] = variable_expand_for_file ("$(SHELL)", file);
!     shell_argv[1] = "-c";
!     do
!       shell_argv[2 + argc] = argv[argc];
!     while (argc-- > 0);
      exec_command (shell_argv, envp, path);
  
      /* If that returned, die.  */
***************
*** 688,696 ****
  	      && (st.st_mode & S_IFMT) == S_IFREG)
  	    {
  	      if (st.st_uid == geteuid ())
! 		perm = st.st_mode & 07;
  	      else if (st.st_gid == getegid ())
! 		perm = (st.st_mode & 070) >> 3;
  	      else
  		{
  #ifndef	USG
--- 850,858 ----
  	      && (st.st_mode & S_IFMT) == S_IFREG)
  	    {
  	      if (st.st_uid == geteuid ())
! 		perm = (st.st_mode & 0100);
  	      else if (st.st_gid == getegid ())
! 		perm = (st.st_mode & 0010);
  	      else
  		{
  #ifndef	USG
***************
*** 699,711 ****
  		    if (groups[i] == st.st_gid)
  		      break;
  		  if (i < ngroups)
! 		    perm = (st.st_mode & 070) >> 3;
  		  else
  #endif	/* Not USG.  */
! 		    perm = (st.st_mode & 0700) >> 6;
  		}
  
! 	      if (perm & 1)
  		goto run;
  	    }
  
--- 861,873 ----
  		    if (groups[i] == st.st_gid)
  		      break;
  		  if (i < ngroups)
! 		    perm = (st.st_mode & 0010);
  		  else
  #endif	/* Not USG.  */
! 		    perm = (st.st_mode & 0001);
  		}
  
! 	      if (perm != 0)
  		goto run;
  	    }
  
diff -rc make-3.56/job.h make-3.57/job.h
*** make-3.56/job.h	Sun Sep 17 16:36:00 1989
--- make-3.57/job.h	Sat Oct 14 12:15:23 1989
***************
*** 23,29 ****
  
  extern struct child *children;
  
! extern int start_job ();
  extern void wait_for_children ();
  extern void block_children (), unblock_children ();
  
--- 23,29 ----
  
  extern struct child *children;
  
! extern void new_job ();
  extern void wait_for_children ();
  extern void block_children (), unblock_children ();
  
diff -rc make-3.56/main.c make-3.57/main.c
*** make-3.56/main.c	Thu Sep 21 16:15:58 1989
--- make-3.57/main.c	Fri Nov  3 16:34:16 1989
***************
*** 331,336 ****
--- 331,348 ----
      (void) signal (SIGXFSZ, SIG_IGN);
  #endif
  
+   /* Make sure stdout is line-buffered.  */
+ 
+ #if	defined(USGr3) || defined(HPUX) || defined(hpux)
+   setvbuf (stdout, (char *) 0, _IOLBF, BUFSIZ);
+ #else	/* Not USGr3 and not HPUX.  */
+ #ifdef	USG
+   setvbuf (stdout, _IOLBF, (char *) 0, BUFSIZ);
+ #else	/* Not USG.  */
+   setlinebuf (stdout);
+ #endif	/* USG.  */
+ #endif	/* USGr3.  */
+ 
    /* Figure out where this program lives.  */
  
    if (argv[0] == 0)
***************
*** 909,923 ****
  		      break;
  		    case string:
  		      if (*sw == '\0')
- 			arg = argv[++i];
- 		      else
- 			arg = sw;
- 		      if (arg == 0)
  			{
! 			  error ("argument required for `-%c' option", cs->c);
! 			  bad = 1;
! 			  break;
  			}
  
  		      sl = *(struct stringlist **) cs->value_ptr;
  		      if (sl == 0)
--- 921,939 ----
  		      break;
  		    case string:
  		      if (*sw == '\0')
  			{
! 			  arg = argv[++i];
! 			  if (arg == 0)
! 			    {
! 			    missing_arg:;
! 			      error ("argument required for `-%c' option",
! 				     cs->c);
! 			      bad = 1;
! 			      break;
! 			    }
  			}
+ 		      else
+ 			arg = sw;
  
  		      sl = *(struct stringlist **) cs->value_ptr;
  		      if (sl == 0)
***************
*** 943,949 ****
  
  		    case positive_int:
  		      if (*sw == '\0')
! 			arg = argv[++i];
  		      else
  			arg = sw;
  		      if (arg != 0 && isdigit (*arg))
--- 959,969 ----
  
  		    case positive_int:
  		      if (*sw == '\0')
! 			{
! 			  arg = argv[++i];
! 			  if (arg == 0)
! 			    goto missing_arg;
! 			}
  		      else
  			arg = sw;
  		      if (arg != 0 && isdigit (*arg))
***************
*** 979,985 ****
  
  		    case floating:
  		      if (*sw == '\0')
! 			arg = argv[++i];
  		      else
  			arg = sw;
  		      if (arg != 0 && (*arg == '.' || isdigit (*arg)))
--- 999,1009 ----
  
  		    case floating:
  		      if (*sw == '\0')
! 			{
! 			  arg = argv[++i];
! 			  if (arg == 0)
! 			    goto missing_arg;
! 			}
  		      else
  			arg = sw;
  		      if (arg != 0 && (*arg == '.' || isdigit (*arg)))
***************
*** 1107,1182 ****
    register unsigned int i;
  
    i = 0;
-   flags[i++] = '-';
- 
    for (cs = switches; cs->c != '\0'; ++cs)
      if (cs->toenv)
!       switch (cs->type)
! 	{
! 	default:
! 	  abort ();
  
! 	case ignore:
! 	  break;
  
! 	case flag:
! 	case flag_off:
! 	  if ((cs->default_value != 0
! 	       && *(int *) cs->value_ptr != *(int *) cs->default_value)
! 	      || !*(int *) cs->value_ptr == (cs->type == flag_off))
! 	    flags[i++] = cs->c;
! 	  break;
  
! 	case positive_int:
! 	  if (pf)
! 	    {
! 	      if ((cs->default_value != 0
! 		   && (*(unsigned int *) cs->value_ptr
! 		       == *(unsigned int *) cs->default_value)))
! 		break;
! 	      else if (cs->noarg_value != 0
! 		       && (*(unsigned int *) cs->value_ptr ==
! 			   *(unsigned int *) cs->noarg_value))
! 		flags[i++] = cs->c;
! 	      else if (cs->c == 'j')
! 		{
! 		  strcpy (&flags[i], "j1 ");
! 		  i += 5;
! 		}
! 	      else
! 		{
! 		  char *p = &flags[i];
! 		  sprintf (p, "%c%u ", cs->c,
! 			   *(unsigned int *) cs->value_ptr);
! 		  i += strlen (p);
! 		}
! 	    }
! 	  break;
  
! 	case floating:
! 	  if (pf)
! 	    {
! 	      if (cs->default_value != 0
! 		  && (*(double *) cs->value_ptr
! 		      == *(double *) cs->default_value))
! 		break;
! 	      else if (cs->noarg_value != 0
! 		       && (*(double *) cs->value_ptr
! 			   == *(double *) cs->noarg_value))
! 		flags[i++] = cs->c;
! 	      else
! 		{
! 		  char *p = &flags[i];
! 		  sprintf (p, "%c%f ", cs->c, *(double *) cs->value_ptr);
! 		  i += strlen (p);
! 		}
! 	    }
! 	  break;
! 	}
  
    if (i == 0)
      flags[0] = flags[1] = '\0';
!   else if (flags[i - 1] == ' ')
      flags[i - 1] = '\0';
    else
      flags[i] = '\0';
--- 1131,1206 ----
    register unsigned int i;
  
    i = 0;
    for (cs = switches; cs->c != '\0'; ++cs)
      if (cs->toenv)
!       {
! 	if (i == 0 || flags[i - 1] == ' ')
! 	  flags[i++] = '-';
! 	switch (cs->type)
! 	  {
! 	  default:
! 	    abort ();
  
! 	  case ignore:
! 	    break;
  
! 	  case flag:
! 	  case flag_off:
! 	    if ((cs->default_value != 0
! 		 && *(int *) cs->value_ptr != *(int *) cs->default_value)
! 		|| !*(int *) cs->value_ptr == (cs->type == flag_off))
! 	      flags[i++] = cs->c;
! 	    break;
  
! 	  case positive_int:
! 	    if (pf)
! 	      {
! 		if ((cs->default_value != 0
! 		     && (*(unsigned int *) cs->value_ptr
! 			 == *(unsigned int *) cs->default_value)))
! 		  break;
! 		else if (cs->noarg_value != 0
! 			 && (*(unsigned int *) cs->value_ptr ==
! 			     *(unsigned int *) cs->noarg_value))
! 		  flags[i++] = cs->c;
! 		else
! 		  {
! 		    unsigned int value;
! 		    if (cs->c == 'j')
! 		      value = 1;
! 		    else
! 		      value = *(unsigned int *) cs->value_ptr;
! 		    sprintf (&flags[i], "%c%u ", cs->c, value);
! 		    i += strlen (&flags[i]);
! 		  }
! 	      }
! 	    break;
  
! 	  case floating:
! 	    if (pf)
! 	      {
! 		if (cs->default_value != 0
! 		    && (*(double *) cs->value_ptr
! 			== *(double *) cs->default_value))
! 		  break;
! 		else if (cs->noarg_value != 0
! 			 && (*(double *) cs->value_ptr
! 			     == *(double *) cs->noarg_value))
! 		  flags[i++] = cs->c;
! 		else
! 		  {
! 		    sprintf (&flags[i], "%c%f ",
! 			     cs->c, *(double *) cs->value_ptr);
! 		    i += strlen (&flags[i]);
! 		  }
! 	      }
! 	    break;
! 	  }
!       }
  
    if (i == 0)
      flags[0] = flags[1] = '\0';
!   else if (flags[i - 1] == ' ' || flags[i - 1] == '-')
      flags[i - 1] = '\0';
    else
      flags[i] = '\0';
diff -rc make-3.56/make.texinfo make-3.57/make.texinfo
*** make-3.56/make.texinfo	Sat Sep 16 16:14:34 1989
--- make-3.57/make.texinfo	Tue Oct 24 19:24:42 1989
***************
*** 50,68 ****
  @sp 2
  @center by Richard M. Stallman and Roland McGrath
  @sp 3
! @center Edition 0.24 Beta,
  @sp 1
! @center last updated 14 September 1989,
  @sp 1
! @center for @code{make}, Version 3.56 Beta.
  @page
  @vskip 0pt plus 1filll
  Copyright @copyright{} 1988, 1989 Free Software Foundation, Inc.
  @sp 2
  
! This is Edition 0.24 Beta of the @cite{GNU Make Manual}, @*
! last updated 14 September 1989, @*
! for @code{make} Version 3.56 Beta.
  
  @sp 2
  Published by the Free Software Foundation @*
--- 50,68 ----
  @sp 2
  @center by Richard M. Stallman and Roland McGrath
  @sp 3
! @center Edition 0.25 Beta,
  @sp 1
! @center last updated 24 October 1989,
  @sp 1
! @center for @code{make}, Version 3.57 Beta.
  @page
  @vskip 0pt plus 1filll
  Copyright @copyright{} 1988, 1989 Free Software Foundation, Inc.
  @sp 2
  
! This is Edition 0.25 Beta of the @cite{GNU Make Manual}, @*
! last updated 24 October 1989, @*
! for @code{make} Version 3.57 Beta.
  
  @sp 2
  Published by the Free Software Foundation @*
***************
*** 2982,2990 ****
  @end example
  
  @noindent
! defines a variable named @code{objects}.  Spaces around the variable name
! are ignored, and so are spaces after the @samp{=} or at the end of the
! line.
  
  Variables defined with @samp{=} are @dfn{recursively expanded} variables.
  Variables defined with @samp{:=} are @dfn{simply expanded} variables; these
--- 2982,2989 ----
  @end example
  
  @noindent
! defines a variable named @code{objects}.  Whitespace around the variable
! name and after the @samp{=} is ignored.
  
  Variables defined with @samp{=} are @dfn{recursively expanded} variables.
  Variables defined with @samp{:=} are @dfn{simply expanded} variables; these
diff -rc make-3.56/read.c make-3.57/read.c
*** make-3.56/read.c	Mon Sep 18 17:18:56 1989
--- make-3.57/read.c	Fri Oct 13 20:44:27 1989
***************
*** 29,34 ****
--- 29,35 ----
  static unsigned int readline (), do_define ();
  static int conditional_line ();
  static void record_files ();
+ static char *find_semicolon ();
  
  
  /* A `struct linebuffer' is a structure which holds a line of text.
***************
*** 126,135 ****
    if (makefiles != 0)
      while (*makefiles != 0)
        {
  	read_makefile (*makefiles, 0);
  	/* Use the storage read_filename allocates.  */
  	free (*makefiles);
! 	*makefiles = dep_name (read_makefiles);
  	++num_makefiles;
  	++makefiles;
        }
--- 127,145 ----
    if (makefiles != 0)
      while (*makefiles != 0)
        {
+ 	struct dep *tail = read_makefiles;
+ 	register struct dep *d;
+ 
  	read_makefile (*makefiles, 0);
+ 
+ 	/* Find the right element of read_makefiles.  */
+ 	d = read_makefiles;
+ 	while (d->next != tail)
+ 	  d = d->next;
+ 
  	/* Use the storage read_filename allocates.  */
  	free (*makefiles);
! 	*makefiles = dep_name (d);
  	++num_makefiles;
  	++makefiles;
        }
***************
*** 204,210 ****
    unsigned int lineno = 1;
    unsigned int nlines = 0;
    int two_colon;
-   char *cmdleft;
    char *pattern = 0, *pattern_percent;
  
  #define record_waiting_files()						      \
--- 214,219 ----
***************
*** 435,469 ****
  	continue;
        else
  	{
! 	  /* This line describes some target files.
! 	     Record the previous rule.  */
  
  	  record_waiting_files ();
  
  	  /* Expand variable and function references before doing anything
  	     else so that special characters can be inside variables.  */
! 	  p = variable_expand (collapsed);
  
! 	  /* Does this line contain a semicolon (that isn't quoted with \)?
! 	     If so, find the first such.  */
! 	  cmdleft = index (p, ';');
! 	  while (cmdleft != 0 && cmdleft[-1] == '\\')
! 	    {
! 	      register char *q = &cmdleft[-1];
! 	      register int backslash = 0;
! 	      while (*q-- == '\\')
! 		backslash = !backslash;
! 	      if (backslash)
! 		cmdleft = index (cmdleft + 1, ';');
! 	      else
! 		break;
! 	    }
  	  if (cmdleft != 0)
! 	    {
! 	      commands_started = lineno;
! 	      *cmdleft = '\0';
! 	    }
  
  	  p2 = next_token (p);
  	  if (*p2 == '\0')
  	    /* This line contained a variable reference that
--- 444,478 ----
  	continue;
        else
  	{
! 	  /* This line describes some target files.  */
  
+ 	  char *cmdleft;
+ 
+ 	  /* Record the previous rule.  */
+ 
  	  record_waiting_files ();
  
+ 	  /* Look for a semicolon in the unexpanded line.  */
+ 	  cmdleft = find_semicolon (lb.buffer);
+ 	  if (cmdleft != 0)
+ 	    /* Found one.  Cut the line short there before expanding it.  */
+ 	    *cmdleft = '\0';
+ 
  	  /* Expand variable and function references before doing anything
  	     else so that special characters can be inside variables.  */
! 	  p = variable_expand (lb.buffer);
  
! 	  if (cmdleft == 0)
! 	    /* Look for a semicolon in the expanded line.  */
! 	    cmdleft = find_semicolon (p);
! 
  	  if (cmdleft != 0)
! 	    /* Cut the line short at the semicolon.  */
! 	    *cmdleft = '\0';
  
+ 	  /* Remove comments from the line.  */
+ 	  collapse_line (p);
+ 
  	  p2 = next_token (p);
  	  if (*p2 == '\0')
  	    /* This line contained a variable reference that
***************
*** 479,485 ****
  	    fatal ("%s:%u: missing separator", filename, lineno);
  	  /* Is this a one-colon or two-colon entry?  */
  	  two_colon = *p2 == ':';
! 	  if (two_colon) p2++;
  
  	  /* Is this a static pattern rule: `target: %targ: %dep; ...'?  */
  	  p = index (p2, ':');
--- 488,495 ----
  	    fatal ("%s:%u: missing separator", filename, lineno);
  	  /* Is this a one-colon or two-colon entry?  */
  	  two_colon = *p2 == ':';
! 	  if (two_colon)
! 	    p2++;
  
  	  /* Is this a static pattern rule: `target: %targ: %dep; ...'?  */
  	  p = index (p2, ':');
***************
*** 518,541 ****
  			sizeof (struct dep));
  
  	  commands_idx = 0;
- 
- 	  cmdleft = index (lb.buffer, ';');
- 	  while (cmdleft != 0 && cmdleft[-1] == '\\')
- 	    {
- 	      register char *q = &cmdleft[-1];
- 	      register int backslash = 0;
- 	      while (*q-- == '\\')
- 		backslash = !backslash;
- 	      if (backslash)
- 		cmdleft = index (cmdleft + 1, ';');
- 	      else
- 		break;
- 	    }
  	  if (cmdleft != 0)
  	    {
  	      /* Semicolon means rest of line is a command */
  	      unsigned int len = strlen (cmdleft + 1);
  
  	      /* Add this command line to the buffer.  */
  	      if (len + 2 > commands_len)
  		{
--- 528,540 ----
  			sizeof (struct dep));
  
  	  commands_idx = 0;
  	  if (cmdleft != 0)
  	    {
  	      /* Semicolon means rest of line is a command */
  	      unsigned int len = strlen (cmdleft + 1);
  
+ 	      commands_started = lineno;
+ 
  	      /* Add this command line to the buffer.  */
  	      if (len + 2 > commands_len)
  		{
***************
*** 771,790 ****
        termin = termin == ',' ? ')' : *line;
        if (termin != ')' && termin != '"' && termin != '\'')
  	return -1;
-       s2 = line;
  
        /* Find the end of the second string.  */
        if (termin == ')')
  	{
  	  register int count = 0;
! 	  for (; *line != '\0'; ++line)
! 	    if (*line == '(')
! 	      ++count;
! 	    else if (*line == ')')
! 	      if (count <= 0)
! 		break;
! 	      else
! 		--count;
  	}
        else
  	{
--- 770,791 ----
        termin = termin == ',' ? ')' : *line;
        if (termin != ')' && termin != '"' && termin != '\'')
  	return -1;
  
        /* Find the end of the second string.  */
        if (termin == ')')
  	{
  	  register int count = 0;
! 	  s2 = next_token (line);
! 	  for (line = s2; *line != '\0'; ++line)
! 	    {
! 	      if (*line == '(')
! 		++count;
! 	      else if (*line == ')')
! 		if (count <= 0)
! 		  break;
! 		else
! 		  --count;
! 	    }
  	}
        else
  	{
***************
*** 1088,1093 ****
--- 1089,1135 ----
        create_pattern_rule (targets, target_percents, two_colon, deps, cmds, 1);
        free ((char *) target_percents);
      }
+ }
+ \f


+ /* Search STRING for an unquoted ; that is not after an unquoted #.  */
+ 
+ static char *
+ find_semicolon (string)
+      char *string;
+ {
+   char *found, *p;
+ 
+   found = index (string, ';');
+   while (found != 0 && found[-1] == '\\')
+     {
+       register char *q = &found[-1];
+       register int backslash = 0;
+       while (*q-- == '\\')
+ 	backslash = !backslash;
+       if (backslash)
+ 	found = index (found + 1, ';');
+       else
+ 	break;
+     }
+   if (found == 0)
+     return 0;
+ 
+   /* Look for a comment character (#) before the ; we found.  */
+   p = lindex (string, found, '#');
+   while (p != 0 && p[-1] == '\\')
+     {
+       register char *q = &p[-1];
+       register int backslash = 0;
+       while (*q-- == '\\')
+ 	backslash = !backslash;
+       if (backslash)
+ 	p = lindex (p + 1, found, '#');
+       else
+ 	break;
+     }
+   if (p == 0)
+     return found;
+   return 0;
  }
  \f


  /* Search PATTERN for an unquoted %.  Backslashes quote % and backslash.
diff -rc make-3.56/remake.c make-3.57/remake.c
*** make-3.56/remake.c	Sun Sep 17 16:42:29 1989
--- make-3.57/remake.c	Sat Oct 28 23:07:17 1989
***************
*** 35,45 ****
  extern time_t ar_member_date ();
  
  
! /* Incremented when we find a file needs to be remade, even if it
!    has no commands or if we are not really executing commands.  */
  
- static unsigned int files_remade = 0;
- 
  static int update_file (), update_file_1 (), check_dep ();
  static void remake_file ();
  static time_t name_mtime (), library_file_mtime ();
--- 35,43 ----
  extern time_t ar_member_date ();
  
  
! /* Incremented when a file has been remade.  */
! unsigned int files_remade = 0;
  
  static int update_file (), update_file_1 (), check_dep ();
  static void remake_file ();
  static time_t name_mtime (), library_file_mtime ();
***************
*** 242,248 ****
        return 0;
      case cs_finished:
        DEBUGPR ("Finished updating file `%s'.\n");
-       notice_finished_file (file);
        return file->update_status;
      case cs_invalid:
      default:
--- 240,245 ----
***************
*** 273,279 ****
    if (!file->phony && file->cmds == 0 && !file->tried_implicit)
      {
        if (try_implicit_rule (file, depth))
! 	DEBUGPR ("Found implicit an rule for `%s'.\n");
        else
  	{
  	  DEBUGPR ("No implicit rule found for `%s'.\n");
--- 270,276 ----
    if (!file->phony && file->cmds == 0 && !file->tried_implicit)
      {
        if (try_implicit_rule (file, depth))
! 	DEBUGPR ("Found an implicit rule for `%s'.\n");
        else
  	{
  	  DEBUGPR ("No implicit rule found for `%s'.\n");
***************
*** 394,412 ****
    deps_changed = 0;
    for (d = file->deps; d != 0; d = d->next)
      {
        /* Set DEPS_CHANGED if this dep actually changed.  */
        deps_changed |= d->changed;
  
        /* Set D->changed if either this dep actually changed,
  	 or its dependent, FILE, is older or does not exist.  */
!       d->changed |= noexist || file_mtime (d->file) > this_mtime;
  
        if (debug_flag && !noexist)
  	{
  	  print_spaces (depth);
! 	  printf ("Dependency `%s' is %s than dependent `%s'.\n",
! 		  dep_name (d), d->changed ? "newer" : "older",
! 		  file->name);
  	  fflush (stdout);
  	}
      }
--- 391,417 ----
    deps_changed = 0;
    for (d = file->deps; d != 0; d = d->next)
      {
+       time_t d_mtime = file_mtime (d->file);
+ 
+       if (d_mtime == (time_t) -1)
+ 	/* We must remake if this dep does not exist.  */
+ 	must_make = 1;
+ 
        /* Set DEPS_CHANGED if this dep actually changed.  */
        deps_changed |= d->changed;
  
        /* Set D->changed if either this dep actually changed,
  	 or its dependent, FILE, is older or does not exist.  */
!       d->changed |= noexist || d_mtime > this_mtime;
  
        if (debug_flag && !noexist)
  	{
  	  print_spaces (depth);
! 	  if (d_mtime == (time_t) -1)
! 	    printf ("Dependency `%s' does not exist.\n", dep_name (d));
! 	  else
! 	    printf ("Dependency `%s' is %s than dependent `%s'.\n",
! 		    dep_name (d), d->changed ? "newer" : "older", file->name);
  	  fflush (stdout);
  	}
      }
***************
*** 419,425 ****
        must_make = 1;
        DEBUGPR ("Target `%s' is double-colon and has no dependencies.\n");
      }
!   else if (file->deps != 0 && !deps_changed && file->cmds == 0)
      {
        must_make = 0;
        DEBUGPR ("No commands for `%s' and no dependencies actually changed.\n");
--- 424,430 ----
        must_make = 1;
        DEBUGPR ("Target `%s' is double-colon and has no dependencies.\n");
      }
!   else if (file->is_target && !deps_changed && file->cmds == 0)
      {
        must_make = 0;
        DEBUGPR ("No commands for `%s' and no dependencies actually changed.\n");
***************
*** 439,454 ****
    /* Now, take appropriate actions to remake the file.  */
    remake_file (file);
  
!   if (file->update_status != 0)
      {
!       DEBUGPR ("Failed to remake target file `%s'.\n");
!       file->updated = 1;
      }
!   else if (file->command_state == cs_finished)
      {
        DEBUGPR ("Successfully remade target file `%s'.\n");
      }
  
    return file->update_status;
  }
  \f


--- 444,473 ----
    /* Now, take appropriate actions to remake the file.  */
    remake_file (file);
  
!   if (file->command_state != cs_finished)
      {
!       DEBUGPR ("Commands of `%s' are being run.\n");
!       return 0;
      }
! 
!   switch (file->update_status)
      {
+     case 1:
+       DEBUGPR ("Failed to remake target file `%s'.\n");
+       break;
+     case 0:
        DEBUGPR ("Successfully remade target file `%s'.\n");
+       break;
+     case -1:
+       error ("internal error: `%s' update_status is -1 at cs_finished!",
+ 	     file->name);
+       abort ();
+     default:
+       error ("internal error: `%s' update_status invalid!", file->name);
+       abort ();
      }
  
+   file->updated = 1;
    return file->update_status;
  }
  \f


***************
*** 465,480 ****
      {
        if (just_print_flag || question_flag
  	  || (file->is_target && file->cmds == 0))
! 	{
! 	  file->last_mtime = time ((time_t *) 0);
! 	  ++files_remade;
! 	}
        else
! 	{
! 	  file->last_mtime = 0;
! 	  if (file->update_status != -1)
! 	    ++files_remade;
! 	}
      }
  
    if (file->also_make != 0)
--- 484,492 ----
      {
        if (just_print_flag || question_flag
  	  || (file->is_target && file->cmds == 0))
! 	file->last_mtime = time ((time_t *) 0);
        else
! 	file->last_mtime = 0;
      }
  
    if (file->also_make != 0)
***************
*** 654,660 ****
      }
    else
      {
!       if (touch_flag && !file->cmds->any_recurse)
  	{
  	  if (file->phony)
  	    file->update_status = 0;
--- 666,672 ----
      }
    else
      {
!       if (touch_flag && file->cmds != 0 && !file->cmds->any_recurse)
  	{
  	  if (file->phony)
  	    file->update_status = 0;
***************
*** 663,669 ****
  	    file->update_status = touch_file (file);
  	}
        else
! 	execute_file_commands (file);
      }
  
    file->command_state = cs_finished;
--- 675,684 ----
  	    file->update_status = touch_file (file);
  	}
        else
! 	{
! 	  execute_file_commands (file);
! 	  return;
! 	}
      }
  
    file->command_state = cs_finished;
***************
*** 748,753 ****
--- 763,774 ----
    mtime = name_mtime (name);
    if (mtime == (time_t) -1)
      mtime = name_mtime (name + 4);
+   if (mtime == (time_t) -1)
+     {
+       char *local = concat ("/usr/local/lib/lib", lib,  ".a");
+       mtime = name_mtime (local);
+       free (local);
+     }
    if (mtime == (time_t) -1)
      mtime = name_mtime (name + 9);
    if (mtime == (time_t) -1)
diff -rc make-3.56/rule.c make-3.57/rule.c
*** make-3.56/rule.c	Sun Sep 17 16:36:06 1989
--- make-3.57/rule.c	Thu Sep 28 17:55:32 1989
***************
*** 495,507 ****
      puts ("\n# No implicit rules.");
    else
      {
!       printf ("\n# %u implicit rules, %u ", rules, terminal);
  #ifndef	NO_FLOAT
        printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
  #endif
!       puts ("terminal.");
  
!       printf ("# %u ", subdir);
  #ifndef	NO_FLOAT
        printf (" (%.1f%%)", (double) subdir / (double) rules * 100.0);
  #endif
--- 495,507 ----
      puts ("\n# No implicit rules.");
    else
      {
!       printf ("\n# %u implicit rules, %u", rules, terminal);
  #ifndef	NO_FLOAT
        printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
  #endif
!       puts (" terminal.");
  
!       printf ("# %u", subdir);
  #ifndef	NO_FLOAT
        printf (" (%.1f%%)", (double) subdir / (double) rules * 100.0);
  #endif
diff -rc make-3.56/variable.c make-3.57/variable.c
*** make-3.56/variable.c	Thu Sep 14 18:39:10 1989
--- make-3.57/variable.c	Fri Nov  3 16:34:14 1989
***************
*** 472,478 ****
        else if (c == ':')
  	if (*p == '=')
  	  {
! 	    c = *p++;
  	    recursive = 0;
  	    break;
  	  }
--- 472,478 ----
        else if (c == ':')
  	if (*p == '=')
  	  {
! 	    ++p;
  	    recursive = 0;
  	    break;
  	  }
diff -rc make-3.56/version.c make-3.57/version.c
*** make-3.56/version.c	Fri Sep 22 16:18:41 1989
--- make-3.57/version.c	Fri Nov  3 19:31:30 1989
***************
*** 1,4 ****
! char *version_string = "3.56";
  \f


  /*
    Local variables:
--- 1,4 ----
! char *version_string = "3.57";
  \f


  /*
    Local variables: