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 U

⟦41c5588de⟧ TextFile

    Length: 106844 (0x1a15c)
    Types: TextFile
    Notes: Uncompressed file

Derivation

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

TextFile

This file contains differences between versions 3.55 and 3.56 of GNU Make.
Differences in files generated by etags, ctags, makeinfo, or TeX have been
omitted.  Send bug reports to bug-gnu-utils@prep.ai.mit.edu.

diff -rc2 make-3.55/CHANGES make-3.56/CHANGES
*** make-3.55/CHANGES	Sat Aug 26 13:18:28 1989
--- make-3.56/CHANGES	Sat Aug 26 13:59:42 1989
***************
*** 7,10 ****
--- 7,12 ----
  for the Texinfo manual, but it documents the basic functionality and the
  switches.  For full documentation, you should still read the Texinfo manual.
+ Thanks to Dennis Morse of Stanford University for contributing the initial
+ version of this.
  
  * Variables which are defined by default (e.g., `CC') will no longer be put
diff -rc2 make-3.55/ChangeLog make-3.56/ChangeLog
*** make-3.55/ChangeLog	Sat Aug 26 13:26:07 1989
--- make-3.56/ChangeLog	Fri Sep 22 16:18:39 1989
***************
*** 1,4 ****
--- 1,318 ----
+ Fri Sep 22 16:15:29 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.56.
+ 
+ Thu Sep 21 14:28:42 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* main.c (main): Don't re-exec if a makefile was successfully updated
+ 	but didn't change.
+ 
+ 	* main.c (main): Make an array of the mtimes of the makefiles before
+ 	updating them, and compare their file_mtimes against this later.
+ 
+ 	* main.c (main): If a makefile failed to be remade and no longer
+ 	exists, die.  If a makefile failed to be remade, but changed anyway,
+ 	re-exec.  If a makefile failed to be remade, but is unchanged, continue
+ 	on.
+ 
+ Wed Sep 20 18:02:07 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.55.6.
+ 
+ 	* implicit.c (pattern_search): Maintain an array CHECK_LASTSLASH of the
+ 	CHECK_LASTSLASH flag values used to match each member of TRYRULES.
+ 	When making FILE->stem, if CHECKED_LASTSLASH[FOUNDRULE], prepend the
+ 	part of FILENAME before LASTSLASH.
+ 
+ Tue Sep 19 17:44:08 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* dir.c (dir_file_exists_p): Check for FILENAME being nil before
+ 	checking for it being "".
+ 
+ 	* main.c (define_makeflags): Fixed test for whether a flag/flag_off
+ 	option was non-default.  Also changed to generate a string that Unix
+ 	Make will grok (except for FP/int values and new flags).
+ 
+ 	* job.c (child_execute_job): Don't use the shell's -c option.
+ 	Also fixed an off-by-one bug in the ARGV -> shell arg list copying.
+ 
+ Mon Sep 18 15:17:31 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.55.5.
+ 
+ 	* read.c (parse_file_seq): Check the beginning of the file name for a
+ 	`./', not the two chars after the end of the name (Q rather than P).
+ 
+ 	* job.c (child_execute_job): Include all of ARGV in the arg list for
+ 	the shell.
+ 
+ 	* main.c (define_makeflags): Don't include floating and positive_int
+ 	options in !PF.
+ 
+ 	* job.c (exec_command): Set the effective gid to the real gid before
+ 	execing.
+ 
+ 	* job.c (child_execute_job): Don't clobber the arg list when execing
+ 	the shell.
+ 
+ Sun Sep 17 15:27:19 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* load.c, remake.c: Include job.h.
+ 
+ 	* file.c: Include variables.h.
+ 
+ 	* job.c: Declare dup2.
+ 
+ 	* job.c: Declare {block,unblock}_remote_children.
+ 
+ 	* file.h: Declare f_mtime.
+ 
+ 	* job.c: Don't declare construct_command_argv, since job.h does.
+ 
+ 	* function.c: Include job.h.
+ 
+ 	* main.c (define_makeflags): Moved all the checking inside the switch.
+ 
+ 	* main.c: Include job.h.
+ 
+ 	* load.c [LDAV_BASED] (load_average): When we can't get the load
+ 	average, return zero instead of running off the end.
+ 
+ 	* load.c [LDAV_BASED] (load_average): Declare nlist.
+ 
+ 	* variable.h: Declare print_file_variables.
+ 
+ 	* job.c [!USG]: Don't declare sigsetmask.
+ 	[!USG]: Declare getdtablesize.
+ 	Don't declare load_average.  Do declare wait_to_start_job.
+ 	Declare vfork, gete[gu]id, execve.
+ 
+ 	* commands.c: Declare remote_kill, getpid.
+ 
+ 	* make.h: Declare kill, exit, sigblock, pipe, close, ctime, open,
+ 	lseek, read.
+ 
+ 	* make.h [not USG]: Declare sigsetmask.
+ 
+ 	* job.h: Declare wait_for_children and {block,unblock}_children.
+ 
+ 	* dir.c (dir_file_exists_p): If FILENAME is nil, read in the whole
+ 	directory.
+ 	(find_directory): When we want to read in the whole directory, call
+ 	dir_file_exists_p with nil instead of "".
+ 
+ 	* file.h (struct file), job.h (struct child),
+ 	  variable.h (struct variable): Use bitfields for flags.
+ 	* make.h (ENUM_BITFIELD): If GCC or #ifdef ENUM_BITFIELDS, define as
+ 	:BITS, else empty.
+ 	* compatMakefile (defines): Document ENUM_BITFIELDS.
+ 
+ Sat Sep 16 12:38:58 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.55.4 (alpha).
+ 
+ 	* GNUmakefile (dist): Depend on default and doc.
+ 
+ 	* load.c [LDAV_BASED]: Include <nlist.h> rather than <a.out.h>; #ifdef
+ 	NLIST_NAME_UNION, use n_un.n_name instead of n_name.
+ 	* compatMakefile (LOAD_AVG): Document NLIST_NAME_UNION.
+ 
+ 	* job.c [USG-ish]: Don't redefine WIF{SIGNALED,EXITED} if they're
+ 	already defined.
+ 
+ Fri Sep 15 13:59:42 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* glob.c, dir.c [USGr3 or DIRENT]: If neither d_ino, nor d_fileno is
+ 	defined, define d_ino as d_fileno.
+ 
+ Thu Sep 14 18:29:38 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* job.c: Don't declare exec_command static.
+ 
+ 	* make.texinfo (Name Index): Changed title to include directives.
+ 
+ 	* Version 3.55.3 (alpha).
+ 
+ 	* make.texinfo (Running: Options): Document -e.
+ 
+ 	* variable.c (define_variable_in_set): Under -e, if ORIGIN, or an
+ 	existing variable's origin, is `o_env', make it `o_env_override'.
+ 
+ 	* main.c (main): Always give imported environment variables origin
+ 	`o_env'.
+ 
+ 	* load.c: Use the symbol KERNEL_FILE_NAME instead of KERNEL_FILE.
+ 	* compatMakefile: Changed the comment for `LOAD_AVG' accordinly.
+ 
+ Thu Sep  7 16:46:26 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* Version 3.55.2 (alpha).
+ 
+ 	* compatMakefile (defines): Document NO_FLOAT.
+ 
+ 	* variable.c (print_variable_set), rule.c (print_rule_data_base),
+ 	file.c (print_file_data_base): If NO_FLOAT is defined, don't use
+ 	floating-point for printing statistics.
+ 
+ 	* make.h (HASH): New macro to add the hashing value of one char to a
+ 	variable.c.
+ 	* file.c (lookup_file, enter_file, rename_file): Use it.
+ 	* dir.c (find_directory, dir_file_exists_p, file_impossible_p): Ditto.
+ 	* variable.c (define_variable_in_set, lookup_variable): Same here.
+ 
+ 	* variable.c, file.c, dir.c: Don't define *_BUCKETS if they are already
+ 	defined.
+ 
+ 	* compatMakefile (defines): Added comment about defining NO_ARCHIVES.
+ 	(ARCHIVES, ARCHIVES_SRC): New variables for {ar,arscan}.[oc].
+ 	(objs, srcs): Use $(ARCHIVES) and $(ARCHIVES_SRC).
+ 
+ 	* commands.c (set_file_variables), dir.c (file_exists_p),
+ 	remake.c (touch_file, name_mtime), implicit.c (try_implicit_rule,
+ 	pattern_search), make.h: If NO_ARCHIVES is #defined, don't do any
+ 	archive stuff.
+ 
+ 	* commands.c (set_file_variables): Don't kill the last char of
+ 	directory names in $([@*<%?^]D).
+ 
+ Wed Sep  6 15:23:11 1989  Roland McGrath  (mcgrath at paris.Berkeley.EDU)
+ 
+ 	* default.c (default_terminal_rules {%:: %,v}, {%:: RCS/%,v}): Don't
+ 	run co if the target exists.
+ 
+ 	* glob.c (glob_match): [!xyz], rather than [^xyz], means none of [xyz].
+ 
+ 	* glob.c: Misc minor cosmetic changes.
+ 
+ Tue Sep  5 14:49:56 1989  Roland McGrath  (mcgrath at saffron.Berkeley.EDU)
+ 
+ 	* load.c [LDAV_BASED] (load_average): Check for == -1, rather than < 0
+ 	to seek if lseek fails.  On some systems, `avenrun' is at an offset >
+ 	(2**31)-1, and lseek succeeds, returning a negative value.
+ 
+ Mon Sep  4 11:07:58 1989  Roland McGrath  (mcgrath at saffron.Berkeley.EDU)
+ 
+ 	* rule.c (new_pattern_rule): Return `int' instead of `void': nonzero if
+ 	the passed rule was used, zero if not.
+ 	(install_pattern_rule): Pay attention to the return from
+ 	new_pattern_rule, and don't set the rule's `terminal' flag or give it
+ 	commands unless it's used.
+ 	(create_pattern_rule): Same idea.
+ 
+ 	* dir.c (find_directory): Removed unused variable.
+ 
+ 	* commands.c (execute_file_commands): Removed unused variable.
+ 
+ 	* read.c (record_files): Don't use NAME after freeing it.
+ 
+ Sat Sep  2 00:33:19 1989  Roland McGrath  (mcgrath at saffron.Berkeley.EDU)
+ 
+ 	* Version 3.55.1 (alpha).
+ 
+ 	* function.c (string_glob): Don't add spaces after file names that
+ 	aren't added.  (Also means don't add spaces without checking the size
+ 	of the buffer.)
+ 
+ 	* remake.c (update_goal_chain): Don't remove makefiles with cmds and no
+ 	deps from the chain.
+ 	* main.c (main): Do it here, before calling update_goal_chain.
+ 
+ 	* remake.c (notice_finished_file): Don't return a value.
+ 	(update_file_1, remake_file): Don't expect one.
+ 	* commands.c (execute_file_commands): Same.
+ 	* make.h: Declare notice_finished_file void rather than int.
+ 
+ 	* commands.c (execute_file_commands): Don't return a value.
+ 	* remake.c (remake_file): Don't expect one.
+ 	* commands.h: Declare execute_file_commands void rather than int.
+ 
+ 	* remake.c (update_goal_chain): When updating fails, change STATUS even
+ 	if MAKEFILES is set.  Also stop remaking when updating fails if not
+ 	under -k and MAKEFILES is not set.
+ 
+ 	* remake.c: Declare remake_file as void instead of int.
+ 	(remake_file): Don't return a value.
+ 	(update_file_1): Don't expect one.
+ 
+ 	* remake.c (notice_finished_file): Don't set FILE's modtime to now if
+ 	it is a non-target with no commands.
+ 
+ Fri Sep  1 00:04:39 1989  Roland McGrath  (mcgrath at saffron.Berkeley.EDU)
+ 
+ 	* read.c (read_all_makefiles): After freeing each element on MAKEFILES,
+ 	replace it with the name stored in read_makefiles by read_makefile.
+ 
+ 	* remake.c (update_file_1): Don't decide not to remake if FILE has no
+ 	cmds and no deps actually changed if FILE doesn't have any deps.
+ 
+ 	* file.c (remove_intermediate): Remove precious files that also have
+ 	the `dontcare' flag set.
+ 
+ 	* remake.c (update_file_1): Don't always remake if FILE has cmds but no
+ 	deps; only if FILE is double-colon.  (I don't know why this should be
+ 	done for double-colon targets, but that's what Unix make does.)
+ 
+ 	* load.c [LDAV_BASED] (load_average): Write error messages if the
+ 	various system calls fail.  Keep track of if we've failed before.
+ 	The first time we fail, write a message saying -l won't be enforced.
+ 	The first time we succeed after having failed, write a message saying
+ 	-l will be enforced again.
+ 
+ 	* remake.c [USG]: Don't #include <sys/file.h>
+ 
+ 	* load.c [generic Unix LDAV_BASED]: #include <fcntl.h> #ifdef USG,
+ 	else <sys/file.h> instead.
+ 
+ 	* job.c [USG && !USGr3 && !HAVE_DUP2]: Remove redundant
+ 	#include <errno.h> and declaration of `errno'.
+ 	[...] (dup2): Fixed so it won't always lose.
+ 
+ 	* default.c (default_suffix_rules: .texinfo.dvi): Copy, rather than
+ 	move, the aux and index files, so the TeX run can use them.
+ 
+ 	* compatMakefile: Remove redundant comment.
+ 
+ 	* load.c [generic Unix LDAV_BASED]: Include <a.out.h> instead of
+ 	<nlist.h>, since the `struct nlist' declaration in <nlist.h> varies
+ 	more than the one in <a.out.h>.
+ 	(load_average): Use the `n_un.n_name' field of the `struct nlist',
+ 	since the <a.out.h> declaration uses the union.
+ 
+ 	* file.c (remove_intermediates): Don't print any messages for files
+ 	whose `dontcare' flag is set.
+ 
+ 	* main.c (main): For the temporary files made for stdin makefiles, set
+ 	the `intermediate' and `dontcare' flags.
+ 
+ 	* main.c (main): Use exec_command when re-execing.
+ 
+ 	* job.c (exec_command): Made global.
+ 	* job.h: Declare it.
+ 
+ 	* make.h: Declare environ.
+ 	* make.c: Don't.
+ 
+ 	* function.c (expand_function: `shell'): Use child_execute_job.
+ 
+ 	* job.h: Declare construct_command_argv and child_execute_job.
+ 
+ 	* job.c (child_execute_job): New function to perform everything done in
+ 	the child side of a fork (for a job or `shell' function).
+ 	(start_job): Call it.
+ 
+ Thu Aug 31 18:42:51 1989  Roland McGrath  (mcgrath at saffron.Berkeley.EDU)
+ 
+ 	* function.c (expand_function: `shell'): Remove a trailing newline
+ 	instead of turning it into a space.
+ 
+ 	* main.c (main): Do init_siglist #ifdef HAVE_SIGLIST.
+ 
+ 	* job.c [WTERMSIG || (USG && !HAVE_SYS_WAIT)]: Test each W* macro
+ 	separately and define all those that aren't defined.
+ 
  Sat Aug 26 15:13:21 1989  Roland McGrath  (roland at hobbes.ai.mit.edu)
  
+ 	* ar.c (ar_name): Return zero for `(foo)'.
+ 
  	* Version 3.55.
  
***************
*** 2289,2293 ****
  
  	* commands.c (wait_for_children): New function to block waiting for
! 	children, insuring th▶aa◀
  	(execute_file_commands, kill_children): Use wait_for_children.
  
--- 2603,2607 ----
  
  	* commands.c (wait_for_children): New function to block waiting for
! 	children, insuring that child_handler is not called recursively.
  	(execute_file_commands, kill_children): Use wait_for_children.
  
diff -rc2 make-3.55/Makefile make-3.56/Makefile
*** make-3.55/Makefile	Sat Aug 26 13:19:43 1989
--- make-3.56/Makefile	Fri Sep 22 16:28:36 1989
***************
*** 23,45 ****
  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.
  defines =
  
! # Define UMAX here to use Encore's inq_stats call.
! # If the load average is in a symbol in /dev/kmem, define KERNEL_FILE if not
! # "/vmunix", LDAV_SYMBOL if not "_avenrun", LDAV_TYPE if not `long int',
! # and LDAV_CVT to convert the LDAV_TYPE value from LDAV_SYMBOL (in `load')
! # to a double if this is not "(double) load".  If the `n_name' member of a
! # If no load average determination can be done, define NO_LDAV.
! # `struct nlist' is an array that must be copied into, define NLIST_NAME_ARRAY.
! # Otherwise, define NO_LDAV.
  LOAD_AVG =
  
  # If your system needs extra libraries loaded in, define them here.
  # System V probably need -lPW for alloca.
--- 23,51 ----
  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
! # symbol in /dev/kmem, define KERNEL_FILE_NAME if not "/vmunix", LDAV_SYMBOL if
! # not "_avenrun", LDAV_TYPE if not `long int', and LDAV_CVT to convert the
! # LDAV_TYPE value from LDAV_SYMBOL (in `load') to a double if this is not
! # "(double) load".  If a `struct nlist' (as defined in <nlist.h>) has a `n_un'
! # union, rather than a simple `n_name' member, define NLIST_NAME_UNION.  If the
! # `n_name' member of a `struct nlist' is an array that must be copied into,
! # define NLIST_NAME_ARRAY.  Otherwise, define NO_LDAV.
  LOAD_AVG =
  
+ # If you don't want archive support, comment these out.
+ ARCHIVES = arscan.o ar.o
+ ARCHIVES_SRC = arscan.c ar.c
+ 
  # If your system needs extra libraries loaded in, define them here.
  # System V probably need -lPW for alloca.
***************
*** 65,74 ****
  manext = 1
  
! objs = arscan.o glob.o ar.o commands.o job.o dir.o file.o load.o misc.o \
!        main.o read.o remake.o remote.o rule.o implicit.o default.o variable.o \
!        expand.o function.o vpath.o version.o $(ALLOCA) $(extras)
! srcs = arscan.c glob.c ar.c commands.c job.c dir.c file.c load.c misc.c \
!        main.c read.c remake.c remote.c rule.c implicit.c default.c variable.c \
!        expand.c function.c vpath.c version.c $(ALLOCASRC) \
         commands.h dep.h file.h job.h make.h rule.h variable.h
  
--- 71,80 ----
  manext = 1
  
! objs = glob.o commands.o job.o dir.o file.o load.o misc.o main.o read.o \
!        remake.o remote.o rule.o implicit.o default.o variable.o expand.o \
!        function.o vpath.o version.o $(ARCHIVES) $(ALLOCA) $(extras)
! srcs = glob.c commands.c job.c dir.c file.c load.c misc.c main.c read.c \
!        remake.c remote.c rule.c implicit.c default.c variable.c expand.c \
!        function.c vpath.c version.c $(ALLOCASRC) $(ARCHIVES_SRC) \
         commands.h dep.h file.h job.h make.h rule.h variable.h
  
***************
*** 129,144 ****
  	-rm -f make.?? make.??s make.log make.toc make.*aux
  # Automatically generated dependencies.
- arscan.o : arscan.c 
  glob.o : glob.c 
- ar.o : ar.c make.h file.h 
  commands.o : commands.c make.h dep.h commands.h file.h variable.h job.h 
  job.o : job.c make.h commands.h job.h file.h variable.h 
  dir.o : dir.c make.h 
! file.o : file.c make.h commands.h dep.h file.h 
! load.o : load.c make.h commands.h 
  misc.o : misc.c make.h dep.h 
! main.o : main.c make.h commands.h dep.h file.h variable.h 
  read.o : read.c make.h commands.h dep.h file.h variable.h 
! remake.o : remake.c make.h commands.h dep.h file.h 
  remote.o : remote.c remote-stub.c make.h commands.h 
  rule.o : rule.c make.h commands.h dep.h file.h variable.h rule.h 
--- 135,148 ----
  	-rm -f make.?? make.??s make.log make.toc make.*aux
  # Automatically generated dependencies.
  glob.o : glob.c 
  commands.o : commands.c make.h dep.h commands.h file.h variable.h job.h 
  job.o : job.c make.h commands.h job.h file.h variable.h 
  dir.o : dir.c make.h 
! file.o : file.c make.h commands.h dep.h file.h variable.h 
! load.o : load.c make.h commands.h job.h 
  misc.o : misc.c make.h dep.h 
! main.o : main.c make.h commands.h dep.h file.h variable.h job.h 
  read.o : read.c make.h commands.h dep.h file.h variable.h 
! remake.o : remake.c make.h commands.h job.h dep.h file.h 
  remote.o : remote.c remote-stub.c make.h commands.h 
  rule.o : rule.c make.h commands.h dep.h file.h variable.h rule.h 
***************
*** 147,151 ****
  variable.o : variable.c make.h commands.h variable.h dep.h file.h 
  expand.o : expand.c make.h commands.h file.h variable.h 
! function.o : function.c make.h variable.h dep.h commands.h 
  vpath.o : vpath.c make.h file.h variable.h 
  version.o : version.c 
--- 151,157 ----
  variable.o : variable.c make.h commands.h variable.h dep.h file.h 
  expand.o : expand.c make.h commands.h file.h variable.h 
! function.o : function.c make.h variable.h dep.h commands.h job.h 
  vpath.o : vpath.c make.h file.h variable.h 
  version.o : version.c 
+ arscan.o : arscan.c 
+ ar.o : ar.c make.h file.h 
diff -rc2 make-3.55/README make-3.56/README
*** make-3.55/README	Sun Aug 13 00:34:42 1989
--- make-3.56/README	Fri Sep 22 16:34:55 1989
***************
*** 1,3 ****
! This directory contains the 3.54.8 test release of GNU Make.
  All bugs reported for previous test releases have been fixed.
  Some bugs probably remain.
--- 1,3 ----
! 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.
diff -rc2 make-3.55/ar.c make-3.56/ar.c
*** make-3.55/ar.c	Sun Mar 19 20:37:55 1989
--- make-3.56/ar.c	Thu Sep  7 17:23:51 1989
***************
*** 20,24 ****
  
  
! /* Defined in arscan.c  */
  extern long int ar_scan ();
  extern int ar_member_touch ();
--- 20,24 ----
  
  
! /* Defined in arscan.c.  */
  extern long int ar_scan ();
  extern int ar_member_touch ();
***************
*** 36,40 ****
    char *p = index (name, '('), *end = name + strlen (name) - 1;
    
!   if (p == 0 || *end != ')')
      return 0;
  
--- 36,40 ----
    char *p = index (name, '('), *end = name + strlen (name) - 1;
    
!   if (p == 0 || p == name || *end != ')')
      return 0;
  
diff -rc2 make-3.55/commands.c make-3.56/commands.c
*** make-3.55/commands.c	Fri Aug 18 18:41:03 1989
--- make-3.56/commands.c	Sun Sep 17 16:36:04 1989
***************
*** 27,30 ****
--- 27,34 ----
  #define	sigmask(sig)	(1 << ((sig) - 1))
  #endif
+ 
+ extern int remote_kill ();
+ 
+ extern int getpid ();
  \f


  /* Chop CMDS->commands up into lines in CMDS->command_lines.
***************
*** 113,116 ****
--- 117,121 ----
    (void) define_variable_for_file (name, len, value, o_automatic, 0, file)
  
+ #ifndef	NO_ARCHIVES
    /* If the target is an archive member `lib(member)',
       then $@ is `lib' and $% is `member'.  */
***************
*** 128,131 ****
--- 133,137 ----
        percent = "";
      }
+ #endif
  
    DEFINE_VARIABLE ("@", 1, at);
***************
*** 135,139 ****
  #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.  */
--- 141,145 ----
  #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.  */
***************
*** 288,296 ****
  
  /* Execute the commands to remake FILE.  If they are currently executing,
!    return success (0).  If they have already finished executing, return
!    their status.  Otherwise, fork off a child process to run the first
!    command line in the sequence and return success.  */
  
! int
  execute_file_commands (file)
       struct file *file;
--- 294,301 ----
  
  /* Execute the commands to remake FILE.  If they are currently executing,
!    return or have already finished executing, just return.  Otherwise,
!    fork off a child process to run the first command line in the sequence.  */
  
! void
  execute_file_commands (file)
       struct file *file;
***************
*** 298,302 ****
    register char *p;
    register struct commands *cmds = file->cmds;
-   register char *line;
    struct child *c;
    int status;
--- 303,306 ----
***************
*** 310,316 ****
      case cs_deps_running:
      case cs_running:
-       return 0;
      case cs_finished:
!       return file->update_status;
      case cs_invalid:
      default:
--- 314,319 ----
      case cs_deps_running:
      case cs_running:
      case cs_finished:
!       return;
      case cs_invalid:
      default:
***************
*** 329,333 ****
        file->command_state = cs_finished;
        file->update_status = 0;
!       return 0;
      }
  
--- 332,336 ----
        file->command_state = cs_finished;
        file->update_status = 0;
!       return;
      }
  
***************
*** 375,382 ****
  
        file->update_status = (just_print_flag || touch_flag) ? 0 : 1;
-       return notice_finished_file (file);
      }
! 
!   if (job_slots == 1)
      {
        /* Since there is only one job slot, make things run linearly.
--- 378,383 ----
  
        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.
***************
*** 385,393 ****
  	wait_for_children (1, 0);
  
-       /* Return the status of the child.  */
-       return notice_finished_file (file);
      }
! 
!   return 0;
  }
  \f


--- 386,391 ----
  	wait_for_children (1, 0);
  
      }
!   notice_finished_file (file);
  }
  \f


diff -rc2 make-3.55/commands.h make-3.56/commands.h
*** make-3.55/commands.h	Sat Jul 29 18:03:04 1989
--- make-3.56/commands.h	Sat Sep  2 00:53:48 1989
***************
*** 30,34 ****
  
  
! extern int execute_file_commands ();
  extern void print_commands ();
  extern void delete_child_targets ();
--- 30,34 ----
  
  
! extern void execute_file_commands ();
  extern void print_commands ();
  extern void delete_child_targets ();
diff -rc2 make-3.55/default.c make-3.56/default.c
*** make-3.55/default.c	Wed Jun 28 14:54:47 1989
--- make-3.56/default.c	Wed Sep  6 16:09:31 1989
***************
*** 49,59 ****
  static struct pspec default_terminal_rules[] =
    {
!     /* RCS  */
      "%", "%,v",
!     "$(CO) $(COFLAGS) $< $@",
      "%", "RCS/%,v",
!     "$(CO) $(COFLAGS) $< $@",
  
!     /* SCCS  */
      "%", "s.%",
      "$(GET) $(GFLAGS) $<",
--- 49,59 ----
  static struct pspec default_terminal_rules[] =
    {
!     /* RCS.  */
      "%", "%,v",
!     "test -f $@ || $(CO) $(COFLAGS) $< $@",
      "%", "RCS/%,v",
!     "test -f $@ || $(CO) $(COFLAGS) $< $@",
  
!     /* SCCS.  */
      "%", "s.%",
      "$(GET) $(GFLAGS) $<",
***************
*** 148,155 ****
  
      ".texinfo.dvi",
!     "$(TEXINDEX) $(wildcard $(foreach _s_,cp fn ky pg tp vr,\
! $*.$(_s_)))\n\
!      -$(foreach _f_,$(wildcard $(foreach _s_,aux cp fn ky pg tp vr,\
! $*.$(_s_))),mv $(_f_) $(_f_)O;)\n\
       -$(TEX) $< \n\
       $(foreach _f_,$(wildcard $(foreach _s_,aux cp fn ky pg tp vr,\
--- 148,154 ----
  
      ".texinfo.dvi",
!     "$(TEXINDEX) $(wildcard $(foreach _s_,cp fn ky pg tp vr,$*.$(_s_)))\n\
!      -$(foreach _f_,$(wildcard $(foreach _s_,aux cp fn ky pg tp vr,$*.$(_s_)))\
! ,cp $(_f_) $(_f_)O;)\n\
       -$(TEX) $< \n\
       $(foreach _f_,$(wildcard $(foreach _s_,aux cp fn ky pg tp vr,\
diff -rc2 make-3.55/dir.c make-3.56/dir.c
*** make-3.55/dir.c	Mon Jul 10 15:03:25 1989
--- make-3.56/dir.c	Tue Sep 19 23:27:41 1989
***************
*** 1,3 ****
! /* Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  This file is part of GNU Make.
  
--- 1,4 ----
! /* Directory hashing for GNU Make.
! Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  This file is part of GNU Make.
  
***************
*** 19,26 ****
--- 20,33 ----
  
  #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)
+ 
  #else	/* Not USGr3 and not DIRENT.  */
+ 
  #define D_NAMLEN(d) ((d)->d_namlen)
  #	ifdef	USG
***************
*** 29,32 ****
--- 36,40 ----
  #include <sys/dir.h>
  #	endif	/* USG.  */
+ 
  #endif	/* USGr3 or DIRENT.  */
  
***************
*** 42,46 ****
--- 50,56 ----
    };
  
+ #ifndef	DIRECTORY_BUCKETS
  #define DIRECTORY_BUCKETS 23
+ #endif
  
  static struct directory *directories[DIRECTORY_BUCKETS];
***************
*** 63,67 ****
--- 73,79 ----
    };
  
+ #ifndef	DIRFILE_BUCKETS
  #define DIRFILE_BUCKETS 1007
+ #endif
  \f


  /* Find the directory named NAME and return its `struct directory'.  */
***************
*** 76,83 ****
  
    for (p = name; *p != '\0'; ++p)
!     {
!       hash += *p;
!       hash = (hash << 7) + (hash >> 20);
!     }
    hash %= DIRECTORY_BUCKETS;
  
--- 88,92 ----
  
    for (p = name; *p != '\0'; ++p)
!     HASH (hash, *p);
    hash %= DIRECTORY_BUCKETS;
  
***************
*** 90,94 ****
        /* The directory was not found.  Create a new entry
  	 for it and start its directory stream reading.  */
-       struct stat st;
        dir = (struct directory *) xmalloc (sizeof (struct directory));
        dir->next = directories[hash];
--- 99,102 ----
***************
*** 111,117 ****
  	  ++open_directories;
  	  if (open_directories == MAX_OPEN_DIRECTORIES)
! 	    /* This will force it to read the entire directory and then close
! 	       it because no directory can contain a file named "".  */
! 	    (void) dir_file_exists_p (dir->name, "");
  	}
      }
--- 119,124 ----
  	  ++open_directories;
  	  if (open_directories == MAX_OPEN_DIRECTORIES)
! 	    /* Read the entire directory and then close it.  */
! 	    (void) dir_file_exists_p (dir->name, (char *) 0);
  	}
      }
***************
*** 141,162 ****
      return 0;
  
-   if (*filename == '\0')
-     /* Checking if the directory exists.  */
-     return 1;
- 
    hash = 0;
!   for (p = filename; *p != '\0'; ++p)
      {
!       hash += *p;
!       hash = (hash <<  7) + (hash >> 20);
!     }
!   hash %= DIRFILE_BUCKETS;
  
!   /* Search the list of hashed files.  */
  
!   for (df = dir->files[hash]; df != 0; df = df->next)
!     if (streq (df->name, filename))
!       return !df->impossible;
  
    /* The file was not found in the hashed list.
       Try to read the directory further.  */
--- 148,169 ----
      return 0;
  
    hash = 0;
!   if (filename != 0)
      {
!       if (*filename == '\0')
! 	/* Checking if the directory exists.  */
! 	return 1;
  
!       for (p = filename; *p != '\0'; ++p)
! 	HASH (hash, *p);
!       hash %= DIRFILE_BUCKETS;
  
!       /* Search the list of hashed files.  */
  
+       for (df = dir->files[hash]; df != 0; df = df->next)
+ 	if (streq (df->name, filename))
+ 	  return !df->impossible;
+     }
+ 
    /* The file was not found in the hashed list.
       Try to read the directory further.  */
***************
*** 172,179 ****
        register unsigned int i;
        for (i = 0; i < D_NAMLEN(d); ++i)
! 	{
! 	  newhash += d->d_name[i];
! 	  newhash = (newhash << 7) + (newhash >> 20);
! 	}
        newhash %= DIRFILE_BUCKETS;
        df = (struct dirfile *) xmalloc (sizeof (struct dirfile));
--- 179,183 ----
        register unsigned int i;
        for (i = 0; i < D_NAMLEN(d); ++i)
! 	HASH (newhash, d->d_name[i]);
        newhash %= DIRFILE_BUCKETS;
        df = (struct dirfile *) xmalloc (sizeof (struct dirfile));
***************
*** 184,188 ****
  
        /* Check if the name matches the one we're searching for.  */
!       if (newhash == hash && streq (d->d_name, filename))
  	return 1;
      }
--- 188,193 ----
  
        /* Check if the name matches the one we're searching for.  */
!       if (filename != 0
! 	  && newhash == hash && streq (d->d_name, filename))
  	return 1;
      }
***************
*** 209,214 ****
--- 214,221 ----
    char *dirname;
  
+ #ifndef	NO_ARCHIVES
    if (ar_name (name))
      return ar_member_date (name) != (time_t) -1;
+ #endif
  
    dirend = rindex (name, '/');
***************
*** 248,257 ****
      }
  
!   hash = 0;
!   while (*p != '\0')
!     {
!       hash += *p++;
!       hash = (hash << 7) + (hash >> 20);
!     }
    hash %= DIRFILE_BUCKETS;
  
--- 255,260 ----
      }
  
!   for (hash = 0; *p != '\0'; ++p)
!     HASH (hash, *p);
    hash %= DIRFILE_BUCKETS;
  
***************
*** 301,310 ****
      return 0;
  
!   hash = 0;
!   while (*p != '\0')
!     {
!       hash += *p++;
!       hash = (hash << 7) + (hash >> 20);
!     }
    hash %= DIRFILE_BUCKETS;
  
--- 304,309 ----
      return 0;
  
!   for (hash = 0; *p != '\0'; ++p)
!     HASH (hash, *p);
    hash %= DIRFILE_BUCKETS;
  
diff -rc2 make-3.55/file.c make-3.56/file.c
*** make-3.55/file.c	Sun Jun 11 22:36:56 1989
--- make-3.56/file.c	Mon Sep 18 17:16:20 1989
***************
*** 20,23 ****
--- 20,24 ----
  #include "dep.h"
  #include "file.h"
+ #include "variable.h"
  #include <errno.h>
  
***************
*** 28,32 ****
--- 29,35 ----
  /* Hash table of files the makefile knows how to make.  */
  
+ #ifndef	FILE_BUCKETS
  #define FILE_BUCKETS	1007
+ #endif
  static struct file *files[FILE_BUCKETS];
  
***************
*** 57,64 ****
    hashval = 0;
    for (n = name; *n != '\0'; ++n)
!     {
!       hashval += *n;
!       hashval = (hashval << 7) + (hashval >> 20);
!     }
    hashval %= FILE_BUCKETS;
  
--- 60,64 ----
    hashval = 0;
    for (n = name; *n != '\0'; ++n)
!     HASH (hashval, *n);
    hashval %= FILE_BUCKETS;
  
***************
*** 80,90 ****
      abort ();
  
-   n = name;
    hashval = 0;
    for (n = name; *n != '\0'; ++n)
!     {
!       hashval += *n;
!       hashval = (hashval << 7) + (hashval >> 20);
!     }
    hashval %= FILE_BUCKETS;
  
--- 80,86 ----
      abort ();
  
    hashval = 0;
    for (n = name; *n != '\0'; ++n)
!     HASH (hashval, *n);
    hashval %= FILE_BUCKETS;
  
***************
*** 135,142 ****
    hashval = 0;
    for (n = file->name; *n != '\0'; ++n)
!     {
!       hashval += *n;
!       hashval = (hashval << 7) + (hashval >> 20);
!     }
    hashval %= FILE_BUCKETS;
  
--- 131,135 ----
    hashval = 0;
    for (n = file->name; *n != '\0'; ++n)
!     HASH (hashval, *n);
    hashval %= FILE_BUCKETS;
  
***************
*** 159,166 ****
    hashval = 0;
    for (n = name; *n != '\0'; ++n)
!     {
!       hashval += *n;
!       hashval = (hashval << 7) + (hashval >> 20);
!     }
    hashval %= FILE_BUCKETS;
  
--- 152,156 ----
    hashval = 0;
    for (n = name; *n != '\0'; ++n)
!     HASH (hashval, *n);
    hashval %= FILE_BUCKETS;
  
***************
*** 218,222 ****
    for (i = 0; i < FILE_BUCKETS; ++i)
      for (f = files[i]; f != 0; f = f->next)
!       if (f->intermediate && !f->precious)
  	{
  	  int status;
--- 208,212 ----
    for (i = 0; i < FILE_BUCKETS; ++i)
      for (f = files[i]; f != 0; f = f->next)
!       if (f->intermediate && (f->dontcare || !f->precious))
  	{
  	  int status;
***************
*** 229,248 ****
  		continue;
  	    }
! 	  if (sig)
! 	    error ("*** Deleting file `%s'", f->name);
! 	  else if (!silent_flag && !just_print_flag)
  	    {
! 	      if (!doneany)
  		{
! 		  fputs ("rm ", stdout);
! 		  doneany = 1;
  		}
! 	      putchar (' ');
! 	      fputs (f->name, stdout);
! 	      fflush (stdout);
  	    }
- 
- 	  if (status < 0)
- 	    perror_with_name ("unlink: ", f->name);
  	}
  
--- 219,240 ----
  		continue;
  	    }
! 	  if (!f->dontcare)
  	    {
! 	      if (sig)
! 		error ("*** Deleting file `%s'", f->name);
! 	      else if (!silent_flag && !just_print_flag)
  		{
! 		  if (!doneany)
! 		    {
! 		      fputs ("rm ", stdout);
! 		      doneany = 1;
! 		    }
! 		  putchar (' ');
! 		  fputs (f->name, stdout);
! 		  fflush (stdout);
  		}
! 	      if (status < 0)
! 		perror_with_name ("unlink: ", f->name);
  	    }
  	}
  
***************
*** 358,362 ****
  		printf ("#  Last modified %.24s (%ld)\n",
  			ctime (&f->last_mtime), (long int) f->last_mtime);
! 	      printf ("#  File has%s been updated.\n", f->updated ? "" : " not");
  	      switch (f->command_state)
  		{
--- 350,355 ----
  		printf ("#  Last modified %.24s (%ld)\n",
  			ctime (&f->last_mtime), (long int) f->last_mtime);
! 	      printf ("#  File has%s been updated.\n",
! 		      f->updated ? "" : " not");
  	      switch (f->command_state)
  		{
***************
*** 411,416 ****
--- 404,411 ----
      {
        printf ("\n# %u files in %u hash buckets.\n", nfiles, FILE_BUCKETS);
+ #ifndef	NO_FLOAT
        printf ("# average %.1f files per bucket, max %u files in one bucket.\n",
  	      ((double) nfiles) * 100.0 / (double) FILE_BUCKETS, per_bucket);
+ #endif
      }
  }
diff -rc2 make-3.55/file.h make-3.56/file.h
*** make-3.55/file.h	Sat Jun 10 00:37:52 1989
--- make-3.56/file.h	Sun Sep 17 16:35:52 1989
***************
*** 30,35 ****
      char **also_make;		/* Targets that are also made by this file's
  				   commands, an implicit rule was used.  */
-     int update_status;		/* Status of the last attempt to update,
- 				   or -1 if none has been made.  */
      time_t last_mtime;		/* File's modtime, if already known.  */
      struct file *prev;		/* Previous entry for same file name;
--- 30,33 ----
***************
*** 37,40 ****
--- 35,45 ----
  				   entries for the same file.  */
  
+     /* List of variable sets used for this file.  */
+     struct variable_set_list *variables;
+ 
+     /* Immediate dependent that caused this target to be remade,
+        or nil if there isn't one.  */
+     struct file *parent;
+ 
      enum			/* State of the commands.  */
        {		/* Note: It is important that cs_not_started be zero.  */
***************
*** 44,68 ****
  	cs_finished,		/* Commands finished.  */
  	cs_invalid,
!       } command_state;
  
!     /* List of variable sets used for this file.  */
!     struct variable_set_list *variables;
! 
!     /* Immediate dependent that caused this target to be remade,
!        or nil if there isn't one.  */
!     struct file *parent;
! 
!     char double_colon;		/* Nonzero for double-colon entry */
!     char precious;		/* Non-0 means don't delete file on quit */
!     char tried_implicit;	/* Nonzero if have searched for implicit rule
! 				   for making this file; don't search again */
!     char updating;		/* Nonzero while updating deps of this file */
!     char updated;		/* Nonzero if this file has been remade.  */
!     char is_target;		/* Nonzero if file is described as target.  */
!     char cmd_target;		/* Nonzero if file was given on cmd line.  */
!     char phony;			/* Nonzero if this is a phony file
  				   ie, a dependent of .PHONY.  */
!     char intermediate;		/* Nonzero if this is an intermediate file.  */
!     char dontcare;		/* Nonzero if no complaint is to be made if
  				   this target cannot be remade.  */
    };
--- 49,69 ----
  	cs_finished,		/* Commands finished.  */
  	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
! 				     for implicit rule for making
! 				     this file; don't search again.  */
!     unsigned int updating:1;	/* Nonzero while updating deps of this file */
!     unsigned int updated:1;	/* Nonzero if this file has been remade.  */
!     unsigned int is_target:1;	/* Nonzero if file is described as target.  */
!     unsigned int cmd_target:1;	/* Nonzero if file was given on cmd line.  */
!     unsigned int phony:1;	/* Nonzero if this is a phony file
  				   ie, a dependent of .PHONY.  */
!     unsigned int intermediate:1;/* Nonzero if this is an intermediate file.  */
!     unsigned int dontcare:1;	/* Nonzero if no complaint is to be made if
  				   this target cannot be remade.  */
    };
***************
*** 80,83 ****
--- 81,85 ----
  
  
+ extern time_t f_mtime ();
  #define file_mtime(f) \
    ((f)->last_mtime != (time_t) 0 ? (f)->last_mtime : f_mtime (f))
diff -rc2 make-3.55/function.c make-3.56/function.c
*** make-3.55/function.c	Mon Aug 14 21:03:50 1989
--- make-3.56/function.c	Sun Sep 17 16:35:59 1989
***************
*** 21,24 ****
--- 21,25 ----
  #include "dep.h"
  #include "commands.h"
+ #include "job.h"
  #include <errno.h>
  
***************
*** 352,377 ****
  	  perror_with_name (buf, "fork");
  	else if (pid == 0)
! 	  {
! 	    /* We are the child.  Run the command.  */
! 	    extern char **construct_command_argv ();
! 	    char **argv;
! 
! 	    /* Make the write side of the pipe be stdout.  */
! 	    if (dup2 (pipedes[1], 1) < 0)
! 	      {
! 		perror_with_name (buf, "dup2");
! 		_exit (127);
! 	      }
! 
! 	    /* Close both sides of the pipe.  */
! 	    (void) close (pipedes[0]);
! 	    (void) close (pipedes[1]);
! 
! 	    /* Make the argument list and exec the command.  */
! 	    argv = construct_command_argv (text, (struct file *) 0);
! 	    (void) execvp (argv[0], argv);
! 	    perror_with_name (buf, "execvp");
! 	    _exit (127);
! 	  }
  	else
  	  {
--- 353,359 ----
  	  perror_with_name (buf, "fork");
  	else if (pid == 0)
! 	  child_execute_job (0, pipedes[1], (struct file *) 0,
! 			     construct_command_argv (text, (struct file *) 0),
! 			     environ);
  	else
  	  {
***************
*** 438,441 ****
--- 420,425 ----
  		   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')
***************
*** 1158,1166 ****
  	  bcopy (name, &result[idx], len);
  	  idx += len;
  	}
  
        free (name);
- 
-       result[idx++] = ' ';
      }
  
--- 1142,1149 ----
  	  bcopy (name, &result[idx], len);
  	  idx += len;
+ 	  result[idx++] = ' ';
  	}
  
        free (name);
      }
  
diff -rc2 make-3.55/glob.c make-3.56/glob.c
*** make-3.55/glob.c	Mon Jul 10 15:03:30 1989
--- make-3.56/glob.c	Fri Sep 15 14:04:41 1989
***************
*** 17,22 ****
  \f


  /* To whomever it may concern: I have never seen the code which most
!  Unix programs use to perform this function.  I wrote this from scratch
!  based on specifications for the pattern matching.  */
  
  #include <sys/types.h>
--- 17,22 ----
  \f


  /* To whomever it may concern: I have never seen the code which most
!    Unix programs use to perform this function.  I wrote this from scratch
!    based on specifications for the pattern matching.  --RMS.  */
  
  #include <sys/types.h>
***************
*** 23,30 ****
--- 23,36 ----
  
  #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)
+ 
  #else	/* Not USGr3 and not DIRENT.  */
+ 
  #define D_NAMLEN(d) ((d)->d_namlen)
  #	ifdef	USG
***************
*** 33,36 ****
--- 39,43 ----
  #include <sys/dir.h>
  #	endif	/* USG.  */
+ 
  #endif	/* USGr3 or DIRENT.  */
  
***************
*** 64,68 ****
  #endif
  
! /* Zero if * matches .*.  */
  int noglob_dot_filenames = 1;
  
--- 71,76 ----
  #endif
  
! /* Global variable which controls whether or not * matches .*.
!    Non-zero means don't match .*.  */
  int noglob_dot_filenames = 1;
  
***************
*** 78,100 ****
    register char c;
  
!   while ((c = *p++))
!     {
!       switch (c)
! 	{
! 	case '?':
! 	case '[':
! 	case '*':
! 	  return 1;
  
! 	case '\\':
! 	  if (*p++ == 0) return 0;
! 	default:
! 	  ;
! 	}
!     }
  
    return 0;
  }
- 
  \f


  /* Match the pattern PATTERN against the string TEXT;
--- 86,104 ----
    register char c;
  
!   while ((c = *p++) != '\0')
!     switch (c)
!       {
!       case '?':
!       case '[':
!       case '*':
! 	return 1;
  
!       case '\\':
! 	if (*p++ == '\0')
! 	  return 0;
!       }
  
    return 0;
  }
  \f


  /* Match the pattern PATTERN against the string TEXT;
***************
*** 105,109 ****
     In the pattern string, `*' matches any sequence of characters,
     `?' matches any character, [SET] matches any character in the specified set,
!    [^SET] matches any character not in the specified set.
  
     A set is composed of characters or ranges; a range looks like
--- 109,113 ----
     In the pattern string, `*' matches any sequence of characters,
     `?' matches any character, [SET] matches any character in the specified set,
!    [!SET] matches any character not in the specified set.
  
     A set is composed of characters or ranges; a range looks like
***************
*** 112,116 ****
     Any other character in the pattern must be matched exactly.
  
!    To suppress the special syntactic significance of any of `[]*?^-\',
     and match the character exactly, precede it with a `\'.
  
--- 116,120 ----
     Any other character in the pattern must be matched exactly.
  
!    To suppress the special syntactic significance of any of `[]*?!-\',
     and match the character exactly, precede it with a `\'.
  
***************
*** 126,201 ****
    register char c;
  
!   while ((c = *p++))
!     {
!       switch (c)
! 	{
! 	case '?':
! 	  if (*t == 0 || (dot_special && t == text && *t == '.')) return 0;
! 	  else ++t;
! 	  break;
  
! 	case '\\':
! 	  if (*p++ != *t++) return 0;
! 	  break;
  
! 	case '*':
! 	  if (dot_special && t == text && *t == '.')
! 	    return 0;
! 	  return glob_match_after_star (p, t);
  
! 	case '[':
! 	  {
! 	    register char c1 = *t++;
! 	    register int invert = (*p == '^');
  
! 	    if (invert) p++;
  
! 	    c = *p++;
! 	    while (1)
! 	      {
! 		register char cstart = c, cend = c;
  
! 		if (c == '\\')
! 		  {
! 		    cstart = *p++; cend = cstart;
! 		  }
  
! 		if (!c) return (0);
  
! 		c = *p++;
! 
! 		if (c == '-')
! 		  {
  		    cend = *p++;
! 		    if (cend == '\\')
! 		      cend = *p++;
! 		    if (!cend) return (0);
! 		    c = *p++;
! 		  }
! 		if (c1 >= cstart && c1 <= cend) goto match;
! 		if (c == ']')
! 		  break;
! 	      }
! 	    if (!invert) return 0;
! 	    break;
  
! 	  match:
! 	    /* Skip the rest of the [...] construct that already matched.  */
! 	    while (c != ']')
! 	      { 
! 	        if (!c || !(c = *p++)) return (0);
! 		if (c == '\\') p++;
! 	      }
! 	    if (invert) return 0;
! 	    break;
! 	  }
! 
! 	default:
! 	  if (c != *t++) return 0;
  	}
-     }
  
!   if (*t) return 0;
!   return 1;
  }
  \f


--- 130,218 ----
    register char c;
  
!   while ((c = *p++) != '\0')
!     switch (c)
!       {
!       case '?':
! 	if (*t == '\0' || (dot_special && t == text && *t == '.'))
! 	  return 0;
! 	else
! 	  ++t;
! 	break;
  
!       case '\\':
! 	if (*p++ != *t++)
! 	  return 0;
! 	break;
  
!       case '*':
! 	if (dot_special && t == text && *t == '.')
! 	  return 0;
! 	return glob_match_after_star (p, t);
  
!       case '[':
! 	{
! 	  register char c1 = *t++;
! 	  int invert;
  
! 	  invert = *p == '!';
! 	  if (invert)
! 	    p++;
  
! 	  c = *p++;
! 	  while (1)
! 	    {
! 	      register char cstart = c, cend = c;
  
! 	      if (c == '\\')
! 		{
! 		  cstart = *p++;
! 		  cend = cstart;
! 		}
  
! 	      if (c == '\0')
! 		return 0;
  
! 	      c = *p++;
! 	      if (c == '-')
! 		{
! 		  cend = *p++;
! 		  if (cend == '\\')
  		    cend = *p++;
! 		  if (cend == '\0')
! 		    return 0;
! 		  c = *p++;
! 		}
! 	      if (c1 >= cstart && c1 <= cend)
! 		goto match;
! 	      if (c == ']')
! 		break;
! 	    }
! 	  if (!invert)
! 	    return 0;
! 	  break;
  
! 	match:
! 	  /* Skip the rest of the [...] construct that already matched.  */
! 	  while (c != ']')
! 	    { 
! 	      if (c == '\0')
! 		return 0;
! 	      c = *p++;
! 	      if (c == '\0')
! 		return 0;
! 	      else if (c == '\\')
! 		++p;
! 	    }
! 	  if (invert)
! 	    return 0;
! 	  break;
  	}
  
!       default:
! 	if (c != *t++)
! 	  return 0;
!       }
! 
!   return *t == '\0';
  }
  \f


***************
*** 210,230 ****
  
    while ((c = *p++) == '?' || c == '*')
!     {
!       if (c == '?' && *t++ == 0)
! 	return 0;
!     }
  
!   if (c == 0)
      return 1;
  
!   if (c == '\\') c1 = *p;
!   else c1 = c;
  
!   for (;;)
      {
!       if ((c == '[' || *t == c1) 
!           && glob_match (p - 1, t, 0))
  	return 1;
!       if (*t++ == 0) return 0;
      }
  }
--- 227,247 ----
  
    while ((c = *p++) == '?' || c == '*')
!     if (c == '?' && *t++ == '\0')
!       return 0;
  
!   if (c == '\0')
      return 1;
  
!   if (c == '\\')
!     c1 = *p;
!   else
!     c1 = c;
  
!   while (1)
      {
!       if ((c == '[' || *t == c1) && glob_match (p - 1, t, 0))
  	return 1;
!       if (*t++ == '\0')
! 	return 0;
      }
  }
***************
*** 262,271 ****
    register struct globval *nextlink;
    register char *nextname;
!   int count;
    int lose;
    register char **name_vector;
!   register int i;
  
!   if (!(d = opendir (dir)))
      return (char **) -1;
  
--- 279,289 ----
    register struct globval *nextlink;
    register char *nextname;
!   unsigned int count;
    int lose;
    register char **name_vector;
!   register unsigned int i;
  
!   d = opendir (dir);
!   if (d == NULL)
      return (char **) -1;
  
***************
*** 278,287 ****
       on the stack and store the name in it.
       Chain those structs together; lastlink is the front of the chain.  */
-   /* Loop reading blocks */
    while (1)
      {
        dp = readdir (d);
!       if (!dp) break;
!       if (dp->d_ino && glob_match (pat, dp->d_name, noglob_dot_filenames))
  	{
  	  nextlink = (struct globval *) alloca (sizeof (struct globval));
--- 296,306 ----
       on the stack and store the name in it.
       Chain those structs together; lastlink is the front of the chain.  */
    while (1)
      {
        dp = readdir (d);
!       if (dp == NULL)
! 	break;
!       if (dp->d_ino != 0
! 	  && glob_match (pat, dp->d_name, noglob_dot_filenames))
  	{
  	  nextlink = (struct globval *) alloca (sizeof (struct globval));
***************
*** 288,292 ****
  	  nextlink->next = lastlink;
  	  nextname = (char *) malloc (D_NAMLEN(dp) + 1);
! 	  if (!nextname)
  	    {
  	      lose = 1;
--- 307,311 ----
  	  nextlink->next = lastlink;
  	  nextname = (char *) malloc (D_NAMLEN(dp) + 1);
! 	  if (nextname == NULL)
  	    {
  	      lose = 1;
***************
*** 296,310 ****
  	  nextlink->name = nextname;
  	  bcopy (dp->d_name, nextname, D_NAMLEN(dp) + 1);
! 	  count++;
  	}
      }
!   closedir (d);
  
!   name_vector = (char **) malloc ((count + 1) * sizeof (char *));
  
    /* Have we run out of memory?  */
!   if (!name_vector || lose)
      {
!       /* Here free the strings we have got */
        while (lastlink)
  	{
--- 315,333 ----
  	  nextlink->name = nextname;
  	  bcopy (dp->d_name, nextname, D_NAMLEN(dp) + 1);
! 	  ++count;
  	}
      }
!   (void) closedir (d);
  
!   if (!lose)
!     {
!       name_vector = (char **) malloc ((count + 1) * sizeof (char *));
!       lose |= name_vector == NULL;
!     }
  
    /* Have we run out of memory?  */
!   if (lose)
      {
!       /* Here free the strings we have got.  */
        while (lastlink)
  	{
***************
*** 312,320 ****
  	  lastlink = lastlink->next;
  	}
!       return 0;
      }
  
!   /* Copy the name pointers from the linked list into the vector */
!   for (i = 0; i < count; i++)
      {
        name_vector[i] = lastlink->name;
--- 335,343 ----
  	  lastlink = lastlink->next;
  	}
!       return NULL;
      }
  
!   /* Copy the name pointers from the linked list into the vector.  */
!   for (i = 0; i < count; ++i)
      {
        name_vector[i] = lastlink->name;
***************
*** 322,331 ****
      }
  
!   name_vector[count] = 0;
    return name_vector;
  }
  \f


! /* Return a new array which is the concatenation of each string in
!    ARRAY to DIR. */
  
  static char **
--- 345,354 ----
      }
  
!   name_vector[count] = NULL;
    return name_vector;
  }
  \f


! /* Return a new array which is the concatenation
!    of each string in ARRAY to DIR. */
  
  static char **
***************
*** 333,363 ****
       char *dir, **array;
  {
!   register int i, l;
!   int add_slash = 0;
    char **result;
  
    l = strlen (dir);
!   if (!l) return (array);
  
!   if (dir[l - 1] != '/') add_slash++;
  
!   for (i = 0; array[i]; i++);
  
!   result = (char **)malloc ((1 + i) * sizeof (char *));
!   if (!result) return (result);
  
!   for (i = 0; array[i]; i++) {
!     result[i] = (char *)malloc (1 + l + add_slash + strlen (array[i]));
!     if (!result[i]) return (char **)NULL;
!     strcpy (result[i], dir);
!     if (add_slash) strcat (result[i], "/");
!     strcat (result[i], array[i]);
!   }
!   result[i] = (char *)NULL;
  
!   /* Free the input array. */
!   for (i = 0; array[i]; i++) free (array[i]);
!   free (array);
!   return (result);
  }
  \f


--- 356,393 ----
       char *dir, **array;
  {
!   register unsigned int i, l;
!   int add_slash;
    char **result;
  
    l = strlen (dir);
!   if (l == 0)
!     return array;
  
!   add_slash = dir[l - 1] != '/';
  
!   i = 0;
!   while (array[i] != NULL)
!     ++i;
  
!   result = (char **) malloc ((i + 1) * sizeof (char *));
!   if (result == NULL)
!     return NULL;
  
!   for (i = 0; array[i] != NULL; i++)
!     {
!       result[i] = (char *) malloc (l + (add_slash ? 1 : 0)
! 				   + strlen (array[i]) + 1);
!       if (result[i] == NULL)
! 	return NULL;
!       sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
!     }
!   result[i] = NULL;
  
!   /* Free the input array.  */
!   for (i = 0; array[i] != NULL; i++)
!     free (array[i]);
!   free ((char *) array);
! 
!   return result;
  }
  \f


***************
*** 366,374 ****
     If no pathnames match, then the array is empty (first element is null).
     If there isn't enough memory, then return NULL.
!    If a file system error occurs, return -1; `errno' has the error code.
  
-    Wildcards at the beginning of PAT, or following a slash,
-    do not match an initial period.  */
- 
  char **
  glob_filename (pathname)
--- 396,401 ----
     If no pathnames match, then the array is empty (first element is null).
     If there isn't enough memory, then return NULL.
!    If a file system error occurs, return -1; `errno' has the error code.  */
  
  char **
  glob_filename (pathname)
***************
*** 389,393 ****
    /* Find the filename.  */
    filename = rindex (pathname, '/');
!   if (filename == 0)
      {
        filename = pathname;
--- 416,420 ----
    /* Find the filename.  */
    filename = rindex (pathname, '/');
!   if (filename == NULL)
      {
        filename = pathname;
***************
*** 439,444 ****
  	    {
  	      char **array = glob_dir_to_array (directories[i], temp_results);
  
! 	      register unsigned int l = 0;
  	      while (array[l] != NULL)
  		++l;
--- 466,472 ----
  	    {
  	      char **array = glob_dir_to_array (directories[i], temp_results);
+ 	      register unsigned int l;
  
! 	      l = 0;
  	      while (array[l] != NULL)
  		++l;
***************
*** 452,455 ****
--- 480,484 ----
  		result[result_size++ - 1] = array[l];
  	      result[result_size - 1] = NULL;
+ 	      /* Note that the elements of ARRAY are not freed.  */
  	      free ((char *) array);
  	    }
***************
*** 490,494 ****
      }
  
!   memory_error:;
    if (result != NULL)
      {
--- 519,523 ----
      }
  
!  memory_error:;
    if (result != NULL)
      {
***************
*** 500,505 ****
    return NULL;
  }
- 
- 
  \f


  #ifdef TEST
--- 529,532 ----
***************
*** 509,528 ****
       char **argv;
  {
!   char **value;
!   int i, index = 1;
  
!   while (index < argc) {
!     value = glob_filename (argv[index]);
!     if ((int) value == 0)
!       printf ("Memory exhausted.\n");
!     else if ((int) value == -1)
!       perror (argv[index]);
!     else
!       for (i = 0; value[i]; i++)
! 	printf ("%s\n", value[i]);
!     index++;
!   }
    return 0;
  }
! 
! #endif /* TEST */
--- 536,555 ----
       char **argv;
  {
!   unsigned int i;
  
!   for (i = 1; i < argc; ++i)
!     {
!       char **value = glob_filename (argv[i]);
!       if (value == NULL)
! 	puts ("Out of memory.")
!       else if ((int) value == -1)
! 	perror (argv[i]);
!       else
! 	for (i = 0; value[i] != NULL; i++)
! 	  puts (value[i]);
!     }
! 
!   exit (0);
    return 0;
  }
! #endif	/* TEST.  */
diff -rc2 make-3.55/implicit.c make-3.56/implicit.c
*** make-3.55/implicit.c	Sat Aug 19 08:21:57 1989
--- make-3.56/implicit.c	Wed Sep 20 18:06:03 1989
***************
*** 39,42 ****
--- 39,43 ----
    DEBUGPR ("Looking for an implicit rule for `%s'.\n");
  
+ #ifndef	NO_ARCHIVES
    /* If this is an archive member reference, use just the
       archive member name to search for implicit rules.  */
***************
*** 48,51 ****
--- 49,53 ----
  	return 1;
      }
+ #endif
  
    return pattern_search (file, (char *) 0, depth, 0);
***************
*** 120,123 ****
--- 122,130 ----
      = (unsigned int *) alloca (num_pattern_rules * sizeof (unsigned int));
  
+   /* Each element is nonzero if LASTSLASH was used in
+      matching the corresponding element of TRYRULES.  */
+   char *checked_lastslash
+     = (char *) alloca (num_pattern_rules * sizeof (char));
+ 
    /* The index in TRYRULES of the rule we found.  */
    unsigned int foundrule;
***************
*** 136,142 ****
--- 143,151 ----
    char *p;
  
+ #ifndef	NO_ARCHIVES
    if (ar_name (filename))
      lastslash = 0;
    else
+ #endif
      {
        /* Set LASTSLASH to point at the last slash in FILENAME
***************
*** 181,184 ****
--- 190,197 ----
  	    continue;
  
+ 	  if (rule->lens[i] > namelen)
+ 	    /* It can't possibly match.  */
+ 	    continue;
+ 
  	  /* From the lengths of the filename and the pattern parts,
  	     find the stem: the part of the filename that matches the %.  */
***************
*** 194,205 ****
  	      /* In that case, don't include the
  		 directory prefix in STEM here.  */
! 	      stem += lastslash - filename + 1;
! 	      stemlen -= (lastslash - filename) + 1;
  	    }
  
- 	  /* Check that filename is long enough to match the whole pattern.  */
- 	  if (stemlen <= 0)
- 	    continue;
- 
  	  /* Check that the rule pattern matches the text before the stem.  */
  	  if (check_lastslash)
--- 207,217 ----
  	      /* In that case, don't include the
  		 directory prefix in STEM here.  */
! 	      unsigned int difference = lastslash - filename + 1;
! 	      if (difference > stemlen)
! 		continue;
! 	      stemlen -= difference;
! 	      stem += difference;
  	    }
  
  	  /* Check that the rule pattern matches the text before the stem.  */
  	  if (check_lastslash)
***************
*** 245,248 ****
--- 257,261 ----
        tryrules[nrules] = rule;
        matches[nrules] = i;
+       checked_lastslash[nrules] = check_lastslash;
        ++nrules;
      }
***************
*** 294,299 ****
  	    + (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1;
  	  stemlen = namelen - rule->lens[matches[i]] + 1;
! 	  check_lastslash = lastslash != 0
! 	                    && index (rule->targets[matches[i]], '/') == 0;
  	  if (check_lastslash)
  	    {
--- 307,312 ----
  	    + (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1;
  	  stemlen = namelen - rule->lens[matches[i]] + 1;
! 	  check_lastslash = (lastslash != 0
! 			     && index (rule->targets[matches[i]], '/') == 0);
  	  if (check_lastslash)
  	    {
***************
*** 522,527 ****
  	}
      }
  
-   file->stem = stem[stemlen] == '\0' ? stem : savestring (stem, stemlen);
    file->cmds = rule->cmds;
  
--- 535,550 ----
  	}
      }
+  
+   if (!checked_lastslash[foundrule])
+     file->stem = stem[stemlen] == '\0' ? stem : savestring (stem, stemlen);
+   else
+     {
+       file->stem = (char *) xmalloc (((lastslash + 1) - filename)
+ 				     + stemlen + 1);
+       bcopy (filename, file->stem, (lastslash + 1) - filename);
+       bcopy (stem, file->stem + ((lastslash + 1) - filename), stemlen);
+       file->stem[((lastslash + 1) - filename) + stemlen] = '\0';
+     }
  
    file->cmds = rule->cmds;
  
diff -rc2 make-3.55/job.c make-3.56/job.c
*** make-3.55/job.c	Mon Aug 14 21:52:30 1989
--- make-3.56/job.c	Thu Sep 21 15:49:50 1989
***************
*** 26,37 ****
  extern int errno;
  
! extern char **construct_command_argv ();
! 
! #ifdef	USG
  #define	vfork	fork
  #define	VFORK_NAME	"fork"
! #else	/* Not USG.  */
  #define	VFORK_NAME	"vfork"
! #endif	/* USG.  */
  
  #if	defined(HAVE_SYS_WAIT) || !defined(USG)
--- 26,36 ----
  extern int errno;
  
! #if	defined(USG) && !defined(HAVE_VFORK)
  #define	vfork	fork
  #define	VFORK_NAME	"fork"
! #else	/* Have vfork or not USG.  */
  #define	VFORK_NAME	"vfork"
! #endif	/* USG and don't have vfork.  */
! extern int vfork ();
  
  #if	defined(HAVE_SYS_WAIT) || !defined(USG)
***************
*** 43,60 ****
  #endif
  
! #ifdef	WTERMSIG
  #define	WAIT_T int
- #else
  
! #if	defined(USG) && !defined(HAVE_SYS_WAIT)
! 
! #define WAIT_T int
  #define WTERMSIG(x) ((x) & 0x7f)
  #define WCOREDUMP(x) ((x) & 0x80)
  #define WEXITSTATUS(x) (((x) >> 8) & 0xff)
  #define WIFSIGNALED(x) (WTERMSIG (x) != 0)
  #define WIFEXITED(x) (WTERMSIG (x) == 0)
  
! #else	/* Have <sys/wait.h> or not USG.  */
  
  #define WAIT_T union wait
--- 42,65 ----
  #endif
  
! #if	defined(WTERMSIG) || (defined(USG) && !defined(HAVE_SYS_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
  
! #else	/* WTERMSIG not defined and have <sys/wait.h> or not USG.  */
  
  #define WAIT_T union wait
***************
*** 66,85 ****
  #endif
  
! #endif	/* USG and don't have <sys/wait.h>.  */
  
- #endif	/* WTERMSIG.  */
  
! 
! extern int fork (), wait (), kill (), getpid ();
  extern void _exit ();
  
! #ifndef	USG
! #ifndef sigmask
  #define sigmask(sig) (1 << ((sig) - 1))
  #endif
- extern int sigsetmask ();
- #endif
  
! #ifdef USG
  #include <sys/param.h>
  #define getdtablesize() NOFILE
--- 71,89 ----
  #endif
  
! #endif	/* WTERMSIG defined or USG and don't have <sys/wait.h>.  */
  
  
! extern int dup2 ();
! extern int fork (), wait (), execve ();
  extern void _exit ();
+ extern int geteuid (), getegid ();
  
! #if	!defined(USG) && !defined(sigmask)
  #define sigmask(sig) (1 << ((sig) - 1))
  #endif
  
! #ifndef USG
! extern int getdtablesize ();
! #else
  #include <sys/param.h>
  #define getdtablesize() NOFILE
***************
*** 86,91 ****
  #endif
  
! extern void block_remote_children (), unblock_remote_children ();
! extern double load_average ();
  extern int start_remote_job_p ();
  extern int start_remote_job (), remote_status ();
--- 90,94 ----
  #endif
  
! extern void wait_to_start_job ();
  extern int start_remote_job_p ();
  extern int start_remote_job (), remote_status ();
***************
*** 138,141 ****
--- 141,146 ----
  }
  \f


+ extern void block_remote_children (), unblock_remote_children ();
+ 
  /* Block the child termination signal.  */
  
***************
*** 380,385 ****
  }
  \f


- static void exec_command ();
- 
  /* Start a job to run the commands specified in CHILD.
     CHILD is updated to reflect the commands and ID of the child process.  */
--- 385,388 ----
***************
*** 564,605 ****
        child->pid = vfork ();
        if (child->pid == 0)
! 	{
! 	  /* We are the child side.  */
! 	  extern char **environ;
! 	  char *path;
! 
! 	  if (!child->good_stdin)
! 	    /* We get the `bad' standard input.  */
! 	    (void) dup2 (bad_stdin, 0);
! 
! 	  /* Free up file descriptors.  */
! 	  {
! 	    register int d;
! 	    int max = getdtablesize ();
! 	    for (d = 3; d < max; ++d)
! 	      (void) close (d);
! 	  }
! 
! 	  /* Don't block children for our child.  */
! 	  unblock_children ();
! 
! 	  path = allocated_variable_expand_for_file ("$(PATH)", child->file);
! 
! 	  /* Run the command.  */
! 	  exec_command (argv, child->environment, path);
! 
! 	  /* If exec_command returned, then we should use the shell.  */
! 	  {
! 	    argv = (char **) alloca (4 * sizeof (char *));
! 	    argv[0] = variable_expand_for_file ("$(SHELL)", child->file);
! 	    argv[1] = "-c";
! 	    argv[2] = p;
! 	    argv[3] = 0;
! 	    exec_command (argv, child->environment, path);
! 
! 	    /* If that returned, die.  */
! 	    _exit (127);
! 	  }
! 	}
        else if (child->pid < 0)
  	{
--- 567,573 ----
        child->pid = vfork ();
        if (child->pid == 0)
! 	/* We are the child side.  */
! 	child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
! 			   child->file, argv, child->environment);
        else if (child->pid < 0)
  	{
***************
*** 616,620 ****
--- 584,642 ----
    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;
+    FILE, if not nil, is used as the variable-set to expand `PATH' and `SHELL';
+    ENVP is the environment of the new program.  This function won't return.  */
  
+ void
+ child_execute_job (stdin_fd, stdout_fd, file, argv, envp)
+      int stdin_fd, stdout_fd;
+      struct file *file;
+      char **argv, **envp;
+ {
+   char *path;
+ 
+   if (stdin_fd != 0)
+     (void) dup2 (stdin_fd, 0);
+   if (stdout_fd != 1)
+     (void) dup2 (stdout_fd, 1);
+ 
+   /* Free up file descriptors.  */
+   {
+     register int d;
+     int max = getdtablesize ();
+     for (d = 3; d < max; ++d)
+       (void) close (d);
+   }
+ 
+   /* Don't block children for our child.  */
+   unblock_children ();
+ 
+   path = allocated_variable_expand_for_file ("$(PATH)", file);
+ 
+   /* Run the command.  */
+   exec_command (argv, envp, path);
+ 
+   /* If exec_command returned, then we should use the shell.  */
+   {
+     int argc;
+     char **shell_argv;
+ 
+     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.  */
+     _exit (127);
+   }
+ }
+ 
  /* Replace the current process with one running the command
     in ARGV, with environment ENVP.  The program named in ARGV[0]
***************
*** 621,625 ****
     is searched for in PATH.  This function does not return.  */
  
! static void
  exec_command (argv, envp, path)
       char **argv, **envp;
--- 643,647 ----
     is searched for in PATH.  This function does not return.  */
  
! void
  exec_command (argv, envp, path)
       char **argv, **envp;
***************
*** 696,699 ****
--- 718,725 ----
  
   run:;
+   /* Make might be installed set-gid kmem so that the load average
+      code works, so we want to make sure we use the real gid.  */
+   (void) setgid (getgid ());
+ 
    execve (program, argv, envp);
  
***************
*** 717,720 ****
--- 743,747 ----
  construct_command_argv (line, file)
       char *line;
+      struct file *file;
  {
    static char sh_chars[] = "#;\"*?[]&|<>(){}=$`";
***************
*** 989,996 ****
  
  #if	defined(USG) && !defined(USGr3) && !defined(HAVE_DUP2)
- 
- #include <errno.h>
- extern int errno;
- 
  int
  dup2 (old, new)
--- 1016,1019 ----
***************
*** 1001,1005 ****
    (void) close (new);
    fd = dup (old);
!   if (fd != old)
      {
        (void) close (fd);
--- 1024,1028 ----
    (void) close (new);
    fd = dup (old);
!   if (fd != new)
      {
        (void) close (fd);
diff -rc2 make-3.55/job.h make-3.56/job.h
*** make-3.55/job.h	Sun Jun 11 20:34:33 1989
--- make-3.56/job.h	Sun Sep 17 16:36:00 1989
***************
*** 5,11 ****
      struct child *next;		/* Link in the chain.  */
  
-     int pid;			/* Child process's ID number.  */
-     char remote;		/* Nonzero if executing remotely.  */
- 
      struct file *file;		/* File being remade.  */
  
--- 5,8 ----
***************
*** 12,22 ****
      char **environment;		/* Environment for commands.  */
  
-     unsigned int command_line;	/* Index into file->cmds->command_lines.  */
      char *commands;		/* Commands being executed.  */
      char *command_ptr;		/* Pointer into above.  */
!     char noerror;	       	/* Nonzero if commands contained a `-'.  */
  
!     char good_stdin;		/* Nonzero if this child has a good stdin.  */
!     char deleted;		/* Nonzero if targets have been deleted.  */
    };
  
--- 9,23 ----
      char **environment;		/* Environment for commands.  */
  
      char *commands;		/* Commands being executed.  */
      char *command_ptr;		/* Pointer into above.  */
!     unsigned int command_line;	/* Index into file->cmds->command_lines.  */
  
!     int pid;			/* Child process's ID number.  */
!     unsigned int remote:1;	/* Nonzero if executing remotely.  */
! 
!     unsigned int noerror:1;	/* Nonzero if commands contained a `-'.  */
! 
!     unsigned int good_stdin:1;	/* Nonzero if this child has a good stdin.  */
!     unsigned int deleted:1;	/* Nonzero if targets have been deleted.  */
    };
  
***************
*** 24,27 ****
--- 25,34 ----
  
  extern int start_job ();
+ extern void wait_for_children ();
+ extern void block_children (), unblock_children ();
+ 
+ extern char **construct_command_argv ();
+ extern void child_execute_job ();
+ extern void exec_command ();
  
  extern unsigned int job_slots_used;
diff -rc2 make-3.55/load.c make-3.56/load.c
*** make-3.55/load.c	Fri Jul 14 11:21:55 1989
--- make-3.56/load.c	Sun Sep 17 16:42:33 1989
***************
*** 18,21 ****
--- 18,22 ----
  #include "make.h"
  #include "commands.h"
+ #include "job.h"
  
  #ifdef UMAX
***************
*** 115,120 ****
  #define LDAV_BASED
  
! #ifndef	KERNEL_FILE
! #define KERNEL_FILE "/vmunix"
  #endif
  #ifndef	LDAV_SYMBOL
--- 116,121 ----
  #define LDAV_BASED
  
! #ifndef	KERNEL_FILE_NAME
! #define KERNEL_FILE_NAME "/vmunix"
  #endif
  #ifndef	LDAV_SYMBOL
***************
*** 129,133 ****
--- 130,144 ----
  
  #include <nlist.h>
+ #ifdef	NLIST_NAME_UNION
+ #define	nl_name	n_un.n_name
+ #else
+ #define	nl_name	n_name
+ #endif
+ 
+ #ifdef	USG
  #include <fcntl.h>
+ #else
+ #include <sys/file.h>
+ #endif
  
  /* Return the current load average as a double.  */
***************
*** 136,140 ****
--- 147,153 ----
  load_average ()
  {
+   extern int nlist ();
    LDAV_TYPE load;
+   static int complained = 0;
    static int kmem = -1;
    static unsigned long int offset = 0;
***************
*** 144,148 ****
        kmem = open ("/dev/kmem", O_RDONLY);
        if (kmem < 0)
! 	return 0.0;
      }
  
--- 157,165 ----
        kmem = open ("/dev/kmem", O_RDONLY);
        if (kmem < 0)
! 	{
! 	  if (!complained)
! 	    perror_with_name ("open: ", "/dev/kmem");
! 	  goto lose;
! 	}
      }
  
***************
*** 152,173 ****
  
  #ifdef	NLIST_NAME_ARRAY
!       strcpy (nl[0].n_name, LDAV_SYMBOL);
!       strcpy (nl[1].n_name, "");
  #else	/* Not NLIST_NAME_ARRAY.  */
!       nl[0].n_name = LDAV_SYMBOL;
!       nl[1].n_name = 0;
  #endif	/* NLIST_NAME_ARRAY.  */
  
!       if (nlist (KERNEL_FILE, nl) < 0 || nl[0].n_type == 0)
! 	return 0.0;
        offset = nl[0].n_value;
      }
  
!   if (lseek (kmem, offset, 0) < 0L)
!     return 0.0;
    if (read (kmem, &load, sizeof load) < 0)
!     return 0.0;
  
    return LDAV_CVT;
  }
  
--- 169,215 ----
  
  #ifdef	NLIST_NAME_ARRAY
!       strcpy (nl[0].nl_name, LDAV_SYMBOL);
!       strcpy (nl[1].nl_name, "");
  #else	/* Not NLIST_NAME_ARRAY.  */
!       nl[0].nl_name = LDAV_SYMBOL;
!       nl[1].nl_name = 0;
  #endif	/* NLIST_NAME_ARRAY.  */
  
!       if (nlist (KERNEL_FILE_NAME, nl) < 0 || nl[0].n_type == 0)
! 	{
! 	  if (!complained)
! 	    perror_with_name ("nlist: ", KERNEL_FILE_NAME);
! 	  goto lose;
! 	}
        offset = nl[0].n_value;
      }
  
!   if (lseek (kmem, offset, 0) == -1L)
!     {
!       if (!complained)
! 	perror_with_name ("lseek: ", "/dev/kmem");
!       goto lose;
!     }
    if (read (kmem, &load, sizeof load) < 0)
!     {
!       if (!complained)
! 	perror_with_name ("read: ", "/dev/kmem");
!       goto lose;
!     }
  
+   if (complained)
+     {
+       error ("Load average limits will be enforced again.");
+       complained = 0;
+     }
    return LDAV_CVT;
+ 
+  lose:;
+   if (!complained)
+     {
+       error ("Load average limits will not be enforced.");
+       complained = 1;
+     }
+   return 0.0;
  }
  
diff -rc2 make-3.55/main.c make-3.56/main.c
*** make-3.55/main.c	Fri Aug 11 02:13:55 1989
--- make-3.56/main.c	Thu Sep 21 16:15:58 1989
***************
*** 21,24 ****
--- 21,25 ----
  #include "file.h"
  #include "variable.h"
+ #include "job.h"
  #include <ctype.h>
  #include <time.h>
***************
*** 262,267 ****
  struct file *default_file;
  \f


- extern char **environ;
- 
  int
  main (argc, argv, envp)
--- 263,266 ----
***************
*** 270,274 ****
       char **envp;
  {
! #ifdef	USG
    extern void init_siglist ();
  #endif
--- 269,273 ----
       char **envp;
  {
! #if	defined(USG) && !defined(HAVE_SIGLIST)
    extern void init_siglist ();
  #endif
***************
*** 290,294 ****
    reading_lineno_ptr = 0;
    
! #ifdef	USG
    init_siglist ();
  #endif
--- 289,293 ----
    reading_lineno_ptr = 0;
    
! #if	defined(USG) && !defined(HAVE_SIGLIST)
    init_siglist ();
  #endif
***************
*** 365,370 ****
        while (*ep++ != '=')
  	;
!       (void) define_variable (envp[i], ep - envp[i] - 1, ep,
! 			      env_overrides ? o_env_override : o_env, 1);
      }
  
--- 364,368 ----
        while (*ep++ != '=')
  	;
!       (void) define_variable (envp[i], ep - envp[i] - 1, ep, o_env, 1);
      }
  
***************
*** 536,539 ****
--- 534,541 ----
  	    f->updated = 1;
  	    f->update_status = 0;
+ 	    /* Let it be removed when we're done.  */
+ 	    f->intermediate = 1;
+ 	    /* But don't mention it.  */
+ 	    f->dontcare = 1;
  	  }
      }
***************
*** 627,633 ****
--- 629,685 ----
        /* Update any makefiles if necessary.  */
  
+       time_t *makefile_mtimes = 0;
+       unsigned int mm_idx = 0;
+ 
        if (debug_flag)
  	puts ("Updating makefiles....");
  
+       /* Remove any makefiles we don't want to try to update.
+ 	 Also record the current modtimes so we can compare them later.  */
+       {
+ 	register struct dep *d, *last;
+ 	last = 0;
+ 	d = read_makefiles;
+ 	while (d != 0)
+ 	  {
+ 	    register struct file *f = d->file;
+ 	    if (f->is_target && f->deps == 0)
+ 	      {
+ 		/* This makefile is a target, but has no dependencies.
+ 		   So, it will always be remade.  This might well cause
+ 		   an infinite loop, so don't try to remake it.
+ 		   (This will only happen if your makefiles are written
+ 		   exceptionally stupidly; but if you work for Athena,
+ 		   that is how you write makefiles.)  */
+ 
+ 		if (debug_flag)
+ 		  printf ("Makefile `%s' might loop; not remaking it.",
+ 			  f->name);
+ 
+ 		if (last == 0)
+ 		  read_makefiles = d->next;
+ 		else
+ 		  last->next = d->next;
+ 
+ 		/* Free the storage.  */
+ 		free ((char *) d);
+ 
+ 		d = last == 0 ? 0 : last->next;
+ 	      }
+ 	    else
+ 	      {
+ 		if (makefile_mtimes == 0)
+ 		  makefile_mtimes = (time_t *) xmalloc (sizeof (time_t));
+ 		else
+ 		  makefile_mtimes = (time_t *)
+ 		    xrealloc ((char *) makefile_mtimes,
+ 			      (mm_idx + 1) * sizeof (time_t));
+ 		makefile_mtimes[mm_idx++] = file_mtime (d->file);
+ 		last = d;
+ 		d = d->next;
+ 	      }
+ 	  }
+       }	
+ 
        switch (update_goal_chain (read_makefiles, 1))
  	{
***************
*** 641,693 ****
  	case 1:
  	  /* Failed to update.  Figure out if we care.  */
! 	  status = 0;
! 	  while (read_makefiles != 0)
! 	    {
! 	      struct dep *d = read_makefiles;
! 	      read_makefiles = d->next;
! 	      if (d->file->updated)
! 		{
! 		  /* This makefile was updated.  */
! 		  if (d->file->update_status != 0 && d->changed != 1)
! 		    /* The update failed and this makefile was not
! 		       from the MAKEFILES variable, so we care.  */
! 		    {
! 		      error ("Failed to remake makefile `%s'.", dep_name (d));
! 		      /* If this was not an included makefile,
! 			 set STATUS to tell us to die later.  */
! 		      if (d->changed == 0)
! 			status = 1;
! 		    }
! 		}
! 	      else
! 		/* This makefile was not found at all.  */
! 		switch (d->changed)
  		  {
! 		  case 0:
! 		    /* A normal makefile.  We must die later.  */
! 		    error ("Makefile `%s' was not found", dep_name (d));
! 		    status = 1;
! 		    break;
! 		  case 1:
! 		    /* A makefile from the MAKEFILES variable.
! 		       We don't care.  */
! 		    break;
! 		  case 2:
! 		    /* An included makefile.  */
! 		    error ("Included makefile `%s' was not found.",
! 			   dep_name (d));
! 		    break;
  		  }
! 	      
! 	      free ((char *) d);
! 	    }
! 	  
! 	  if (status)
! 	    /* A makefile we care about couldn't be found or remade.  */
! 	    die (1);
! 	  
! 	  break;
! 	  
  	case 0:
  	  /* Updated successfully.  Re-exec ourselves.  */
  	  if (print_directory_flag)
--- 693,763 ----
  	case 1:
  	  /* Failed to update.  Figure out if we care.  */
! 	  {
! 	    /* Nonzero if any makefile was successfully remade.  */
! 	    int any_remade = 0;
! 	    /* Nonzero if any makefile we care about failed
! 	       in updating or could not be found at all.  */
! 	    int any_failed = 0;
! 	    register unsigned int i;
! 
! 	    for (i = 0; read_makefiles != 0; ++i)
! 	      {
! 		struct dep *d = read_makefiles;
! 		read_makefiles = d->next;
! 		if (d->file->updated)
  		  {
! 		    /* This makefile was updated.  */
! 		    if (d->file->update_status == 0)
! 		      {
! 			/* It was successfully updated.  */
! 			any_remade
! 			  |= file_mtime (d->file) != makefile_mtimes[i];
! 		      }
! 		    else if (d->changed != 1)
! 		      {
! 			time_t mtime;
! 			/* The update failed and this makefile was not
! 			   from the MAKEFILES variable, so we care.  */
! 			error ("Failed to remake makefile `%s'.",
! 			       d->file->name);
! 			mtime = file_mtime (d->file);
! 			any_remade |= (mtime != (time_t) -1
! 				       && mtime != makefile_mtimes[i]);
! 		      }
  		  }
! 		else
! 		  /* This makefile was not found at all.  */
! 		  switch (d->changed)
! 		    {
! 		    case 0:
! 		      /* A normal makefile.  We must die later.  */
! 		      error ("Makefile `%s' was not found", dep_name (d));
! 		      any_failed = 1;
! 		      break;
! 		    case 1:
! 		      /* A makefile from the MAKEFILES variable.
! 			 We don't care.  */
! 		      break;
! 		    case 2:
! 		      /* An included makefile.  We don't need
! 			 to die, but we do want to complain.  */
! 		      error ("Included makefile `%s' was not found.",
! 			     dep_name (d));
! 		      break;
! 		    }
! 
! 		free ((char *) d);
! 	      }
! 
! 	    if (any_remade)
! 	      goto re_exec;
! 	    else if (any_failed)
! 	      die (1);
! 	    else
! 	      break;
! 	  }
! 
  	case 0:
+ 	re_exec:;
  	  /* Updated successfully.  Re-exec ourselves.  */
  	  if (print_directory_flag)
***************
*** 736,741 ****
  		break;
  	      }
! 	  (void) execvp (argv[0], argv);
! 	  pfatal_with_name ("execvp");
  	  /* NOTREACHED */
  	}
--- 806,811 ----
  		break;
  	      }
! 	  exec_command (argv, environ, allocated_variable_expand ("$(PATH)"));
! 	  pfatal_with_name ("exec_command");
  	  /* NOTREACHED */
  	}
***************
*** 903,907 ****
  			  if (arg == argv[i])
  			    /* We moved to the next arg, so move back.  */
! 			    argv[--i];
  			}
  		      sw = "";
--- 973,977 ----
  			  if (arg == argv[i])
  			    /* We moved to the next arg, so move back.  */
! 			    --i;
  			}
  		      sw = "";
***************
*** 933,937 ****
  			  if (arg == argv[i])
  			    /* We moved to the next arg, so move back.  */
! 			    argv[--i];
  			}
  		      sw = "";
--- 1003,1007 ----
  			  if (arg == argv[i])
  			    /* We moved to the next arg, so move back.  */
! 			    --i;
  			}
  		      sw = "";
***************
*** 1035,1068 ****
    register struct command_switch *cs;
    char flags[200];
!   register unsigned int i = 0;
  
    for (cs = switches; cs->c != '\0'; ++cs)
      if (cs->toenv)
!       {
! 	if ((cs->type == flag && *(int *) cs->value_ptr)
! 	    || (cs->type == flag_off && !*(int *) cs->value_ptr))
! 	  {
! 	    flags[i++] = '-';
  	    flags[i++] = cs->c;
! 	    flags[i++] = ' ';
! 	  }
! 	else if (pf)
! 	  switch (cs->type)
  	    {
! 	    case positive_int:
! 	      if (*(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++] = '-';
! 		  flags[i++] = cs->c;
! 		  flags[i++] = ' ';
! 		}
  	      else if (cs->c == 'j')
  		{
! 		  strcpy (&flags[i], " -j1 ");
  		  i += 5;
  		}
--- 1105,1145 ----
    register struct command_switch *cs;
    char flags[200];
!   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;
  		}
***************
*** 1070,1104 ****
  		{
  		  char *p = &flags[i];
! 		  sprintf (p, " -%c%u ", cs->c,
  			   *(unsigned int *) cs->value_ptr);
  		  i += strlen (p);
  		}
! 	      break;
! 	    case floating:
! 	      if (*(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++] = '-';
! 		  flags[i++] = cs->c;
! 		  flags[i++] = ' ';
! 		}
  	      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
      flags[i - 1] = '\0';
  
    /* On Sun, the value of MFLAGS starts with a `-' but the
--- 1147,1184 ----
  		{
  		  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';
  
    /* On Sun, the value of MFLAGS starts with a `-' but the
diff -rc2 make-3.55/make.h make-3.56/make.h
*** make-3.55/make.h	Fri Jul 21 16:26:34 1989
--- make-3.56/make.h	Sun Sep 17 16:35:57 1989
***************
*** 67,71 ****
--- 67,80 ----
  #endif
  
+ /* Add to VAR the hashing value of C, one character in a name.  */
+ #define	HASH(var, c) \
+   ((var += (c)), (var = ((var) << 7) + ((var) >> 20)))
  
+ #if defined(__GNUC__) || defined(ENUM_BITFIELDS)
+ #define	ENUM_BITFIELD(bits)	:bits
+ #else
+ #define	ENUM_BITFIELD(bits)
+ #endif
+ 
  extern void die ();
  extern void fatal (), error ();
***************
*** 81,87 ****
--- 90,98 ----
  extern char *find_percent ();
  
+ #ifndef	NO_ARCHIVES
  extern int ar_name ();
  extern int ar_touch ();
  extern time_t ar_member_date ();
+ #endif
  
  extern void dir_load ();
***************
*** 100,104 ****
  
  extern int update_goal_chain ();
! extern int notice_finished_file ();
  
  
--- 111,115 ----
  
  extern int update_goal_chain ();
! extern void notice_finished_file ();
  
  
***************
*** 106,114 ****
  extern char **glob_filename ();
  
  extern void free ();
! extern void abort ();
! extern int unlink (), stat (), execvp ();
  extern void qsort ();
  extern int atoi ();
  
  #ifdef	USG
--- 117,133 ----
  extern char **glob_filename ();
  
+ #ifndef	USG
+ extern int sigsetmask ();
+ #endif
+ extern int kill (), sigblock ();
  extern void free ();
! extern void abort (), exit ();
! extern int unlink (), stat ();
  extern void qsort ();
  extern int atoi ();
+ extern int pipe (), close (), open (), lseek (), read ();
+ extern char *ctime ();
+ 
+ extern char **environ;
  
  #ifdef	USG
diff -rc2 make-3.55/make.texinfo make-3.56/make.texinfo
*** make-3.55/make.texinfo	Sat Aug 26 13:26:11 1989
--- make-3.56/make.texinfo	Sat Sep 16 16:14:34 1989
***************
*** 51,59 ****
  @center by Richard M. Stallman and Roland McGrath
  @sp 3
! @center Edition 0.23 Beta,
  @sp 1
! @center last updated 26 August 1989,
  @sp 1
! @center for @code{make}, Version 3.55 Beta.
  @page
  @vskip 0pt plus 1filll
--- 51,59 ----
  @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
***************
*** 61,67 ****
  @sp 2
  
! This is Edition 0.22 Beta of the @cite{GNU Make Manual}, @*
! last updated 26 August 1989, @*
! for @code{make} Version 3.55 Beta.
  
  @sp 2
--- 61,67 ----
  @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
***************
*** 90,94 ****
  @page
  
! @node     Top, Overview,  (dir),  (dir)
  @comment  node-name,  next,  previous,  up
  
--- 90,94 ----
  @page
  
! @node     Top, Overview, , (dir)
  @comment  node-name,  next,  previous,  up
  
***************
*** 130,135 ****
  
  
! @node Overview, Copying,  Top,  Top
! @comment  node-name,  next,  previous,  up
  @chapter Overview of @code{make}
  
--- 130,134 ----
  
  
! @node Overview, Copying, Top, Top
  @chapter Overview of @code{make}
  
***************
*** 795,799 ****
  @end itemize
  
! @node Makefile Names, MAKEFILES Variable, Makefile Contents, Makefiles
  @section What Name to Give Your Makefile
  @cindex makefile names
--- 794,798 ----
  @end itemize
  
! @node Makefile Names, Include, Makefile Contents, Makefiles
  @section What Name to Give Your Makefile
  @cindex makefile names
***************
*** 874,878 ****
  of the makefile containing the @code{include} continues.@refill
  
! @node MAKEFILES Variable, Remaking Makefiles, Makefile Names, Makefiles
  @section The Variable @code{MAKEFILES}
  
--- 873,877 ----
  of the makefile containing the @code{include} continues.@refill
  
! @node MAKEFILES Variable, Remaking Makefiles, Include, Makefiles
  @section The Variable @code{MAKEFILES}
  
***************
*** 966,970 ****
  specified by the existing contents of @file{mfile}.
  
! @node Overriding Makefiles,, Remaking Makefiles, Makefiles
  @section Overriding Part of One Makefile with Another Makefile
  
--- 965,969 ----
  specified by the existing contents of @file{mfile}.
  
! @node Overriding Makefiles,  , Remaking Makefiles, Makefiles
  @section Overriding Part of One Makefile with Another Makefile
  
***************
*** 1244,1248 ****
  @end iftex
  
! @node Wildcard Function,, Wildcard Pitfall, Wildcards
  @subsection The Function @code{wildcard}
  @findex wildcard
--- 1243,1247 ----
  @end iftex
  
! @node Wildcard Function,  , Wildcard Pitfall, Wildcards
  @subsection The Function @code{wildcard}
  @findex wildcard
***************
*** 1478,1482 ****
  names found by directory search with no extra effort.
  
! @node Libraries/Search,, Implicit/Search, Directory Search
  @subsection Directory Search for Link Libraries
  
--- 1477,1481 ----
  names found by directory search with no extra effort.
  
! @node Libraries/Search,  , Implicit/Search, Directory Search
  @subsection Directory Search for Link Libraries
  
***************
*** 1866,1870 ****
  from @file{foo.el}.@refill
  
! @node Static vs Implicit,, Static Usage, Static Pattern
  @subsection Static Pattern Rules versus Implicit Rules
  
--- 1865,1869 ----
  from @file{foo.el}.@refill
  
! @node Static vs Implicit,  , Static Usage, Static Pattern
  @subsection Static Pattern Rules versus Implicit Rules
  
***************
*** 1949,1953 ****
  @xref{Implicit}.
  
! @node Double-Colon,, Multiple Rules, Rules
  @section Double-Colon Rules
  @cindex double-colon rule
--- 1948,1952 ----
  @xref{Implicit}.
  
! @node Double-Colon,  , Multiple Rules, Rules
  @section Double-Colon Rules
  @cindex double-colon rule
***************
*** 2439,2443 ****
  probably annoying effects.@refill
  
! @node -w Option,, Options/Recursion, Recursion
  @subsection The @samp{-w} Option
  
--- 2438,2442 ----
  probably annoying effects.@refill
  
! @node -w Option,  , Options/Recursion, Recursion
  @subsection The @samp{-w} Option
  
***************
*** 2515,2519 ****
  commands based on the file names involved.  @xref{Implicit}.
  
! @node Empty Commands,, Sequences, Commands
  @section Defining Empty Commands
  @cindex empty commands
--- 2514,2518 ----
  commands based on the file names involved.  @xref{Implicit}.
  
! @node Empty Commands,  , Sequences, Commands
  @section Defining Empty Commands
  @cindex empty commands
***************
*** 2790,2794 ****
  sets @samp{bar} to @samp{a.c b.c c.c}.
  
! @node Computed Names,, Substitution Refs, Advanced
  @subsection Computed Variable Names
  @cindex nested variable reference
--- 2789,2793 ----
  sets @samp{bar} to @samp{a.c b.c c.c}.
  
! @node Computed Names,  , Substitution Refs, Advanced
  @subsection Computed Variable Names
  @cindex nested variable reference
***************
*** 3110,3114 ****
  @xref{Override Directive}.
  
! @node Environment,, Defining, Variables
  @section Variables from the Environment
  
--- 3109,3113 ----
  @xref{Override Directive}.
  
! @node Environment,  , Defining, Variables
  @section Variables from the Environment
  
***************
*** 3339,3343 ****
  not attempt to terminate the conditional inside the included file.
  
! @node Testing Flags,, Conditional Syntax, Conditionals
  @section Conditionals that Test Flags
  
--- 3338,3342 ----
  not attempt to terminate the conditional inside the included file.
  
! @node Testing Flags,  , Conditional Syntax, Conditionals
  @section Conditionals that Test Flags
  
***************
*** 3963,3967 ****
  @samp{environment} or @samp{environment override}.
  
! @node Shell Function,, Origin Function, Functions
  @section The @code{shell} Function
  @findex shell
--- 3962,3966 ----
  @samp{environment} or @samp{environment override}.
  
! @node Shell Function,  , Origin Function, Functions
  @section The @code{shell} Function
  @findex shell
***************
*** 4353,4357 ****
  @kbd{M-x compile} command passes the @samp{-k} flag by default.
  
! @node Options,, Testing, Running
  @section Summary of Options
  @cindex options
--- 4352,4356 ----
  @kbd{M-x compile} command passes the @samp{-k} flag by default.
  
! @node Options,  , Testing, Running
  @section Summary of Options
  @cindex options
***************
*** 4380,4383 ****
--- 4379,4386 ----
  @code{make} decides what to do.
  
+ @item -e
+ Make variables environment taken from the environment have precedence
+ over variables from makefiles.  @xref{Environment}.
+ 
  @item -f @var{file}
  Use file @var{file} as a makefile.  @xref{Makefiles}.
***************
*** 5411,5415 ****
  suffix listed as valid for use in suffix rules.  @xref{Suffix Rules}.
  
! @node Canceling Rules,, Match-Anything Rules, Pattern Rules
  @subsection Canceling Implicit Rules
  
--- 5414,5418 ----
  suffix listed as valid for use in suffix rules.  @xref{Suffix Rules}.
  
! @node Canceling Rules,  , Match-Anything Rules, Pattern Rules
  @subsection Canceling Implicit Rules
  
***************
*** 5562,5566 ****
  this variable.
  
! @node Search Algorithm,, Suffix Rules, Implicit
  @section Implicit Rule Search Algorithm
  
--- 5565,5569 ----
  this variable.
  
! @node Search Algorithm,  , Suffix Rules, Implicit
  @section Implicit Rule Search Algorithm
  
***************
*** 5708,5712 ****
  and there is an implicit rule to do it for you.
  
! @node Archive Update, Archive Symbols, Archive Members, Archives
  @section Implicit Rule for Archive Member Targets
  
--- 5711,5715 ----
  and there is an implicit rule to do it for you.
  
! @node Archive Update,  , Archive Members, Archives
  @section Implicit Rule for Archive Member Targets
  
***************
*** 5755,5759 ****
  @code{%D} and @code{%F} may be useful.
  
! @node Archive Symbols,, Archive Update, Archives
  @subsection Updating Archive Symbol Directories
  @cindex __.SYMDEF
--- 5758,5762 ----
  @code{%D} and @code{%F} may be useful.
  
! @node Archive Symbols, , Archive Update, Archives
  @subsection Updating Archive Symbol Directories
  @cindex __.SYMDEF
***************
*** 6037,6042 ****
  @printindex cp
  
! @node Name Index,, Concept Index, Top
! @unnumbered Index of Functions and Variables
  
  @printindex fn
--- 6040,6045 ----
  @printindex cp
  
! @node Name Index,  , Concept Index, Top
! @unnumbered Index of Functions, Variables, and Directives
  
  @printindex fn
diff -rc2 make-3.55/read.c make-3.56/read.c
*** make-3.55/read.c	Mon Aug 14 21:03:39 1989
--- make-3.56/read.c	Mon Sep 18 17:18:56 1989
***************
*** 128,132 ****
--- 128,134 ----
        {
  	read_makefile (*makefiles, 0);
+ 	/* Use the storage read_filename allocates.  */
  	free (*makefiles);
+ 	*makefiles = dep_name (read_makefiles);
  	++num_makefiles;
  	++makefiles;
***************
*** 1037,1041 ****
        if (f != 0 && name != f->name
  	  && !(f->name == name - 2 && name[0] == '.' && name[1] == '/'))
! 	free (name);
  
        /* See if this is first target seen whose name does
--- 1039,1046 ----
        if (f != 0 && name != f->name
  	  && !(f->name == name - 2 && name[0] == '.' && name[1] == '/'))
! 	{
! 	  free (name);
! 	  name = f->name;
! 	}
  
        /* See if this is first target seen whose name does
***************
*** 1176,1181 ****
  
        /* Remove leading `./' sequences.  */
!       while (p - q > 2 && p[0] == '.' && p[1] == '/')
! 	p += 2;
  
        /* Extract the filename just found, and skip it.  */
--- 1181,1186 ----
  
        /* Remove leading `./' sequences.  */
!       while (p - q > 2 && q[0] == '.' && q[1] == '/')
! 	q += 2;
  
        /* Extract the filename just found, and skip it.  */
diff -rc2 make-3.55/remake.c make-3.56/remake.c
*** make-3.55/remake.c	Tue Aug 22 02:21:12 1989
--- make-3.56/remake.c	Sun Sep 17 16:42:29 1989
***************
*** 18,27 ****
  #include "make.h"
  #include "commands.h"
  #include "dep.h"
  #include "file.h"
- #include <fcntl.h>
  
  #ifndef USG
  #include <sys/file.h>
  #endif
  
--- 18,29 ----
  #include "make.h"
  #include "commands.h"
+ #include "job.h"
  #include "dep.h"
  #include "file.h"
  
  #ifndef USG
  #include <sys/file.h>
+ #else
+ #include <fcntl.h>
  #endif
  
***************
*** 39,43 ****
  static unsigned int files_remade = 0;
  
! static int update_file (), update_file_1 (), check_dep (), remake_file ();
  static time_t name_mtime (), library_file_mtime ();
  extern time_t f_mtime ();
--- 41,46 ----
  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 ();
  extern time_t f_mtime ();
***************
*** 67,108 ****
      job_slots = 1;
  
-   if (makefiles)
-     {
-       register struct dep *g, *lastgoal;
-       lastgoal = 0;
-       g = goals;
-       while (g != 0)
- 	{
- 	  register struct file *f = g->file;
- 	  if (f->is_target && f->deps == 0)
- 	    {
- 	      /* This makefile is a target, but has no dependencies.
- 		 So, it will always be remade.  This might well cause
- 		 an infinite loop, so don't try to remake it.
- 		 (This will only happen if your makefiles are written
- 		 exceptionally stupidly; but if you work for Athena,
- 		 that is how you write makefiles.)  */
- 
- 	      if (debug_flag)
- 		printf ("Makefile `%s' might loop; not remaking it.", f->name);
- 
- 	      if (lastgoal == 0)
- 		goals = g->next;
- 	      else
- 		lastgoal->next = g->next;
- 
- 	      /* Free the storage.  */
- 	      free ((char *) g);
- 
- 	      g = lastgoal == 0 ? 0 : lastgoal->next;
- 	    }
- 	  else
- 	    {
- 	      lastgoal = g;
- 	      g = g->next;
- 	    }
- 	}
-     }	
- 
    /* Update all the goals until they are all finished.  */
  
--- 70,73 ----
***************
*** 142,148 ****
  	      if (status < 1)
  		{
! 		  if (g->file->update_status != 0 && !makefiles)
! 		    /* Updating failed on a regular target.  */
! 		    status = 1;
  		  else if (file_mtime (g->file) != mtime)
  		    {
--- 107,116 ----
  	      if (status < 1)
  		{
! 		  if (g->file->update_status != 0)
! 		    {
! 		      /* Updating failed.  */
! 		      status = 1;
! 		      stop = !keep_going_flag && !makefiles;
! 		    }
  		  else if (file_mtime (g->file) != mtime)
  		    {
***************
*** 181,187 ****
  	    }
  	}
- 
-       if ((status > 0 && !keep_going_flag) || (makefiles && status >= 0))
- 	break;
      }
  
--- 149,152 ----
***************
*** 278,283 ****
      case cs_finished:
        DEBUGPR ("Finished updating file `%s'.\n");
! 
!       return notice_finished_file (file);
      case cs_invalid:
      default:
--- 243,248 ----
      case cs_finished:
        DEBUGPR ("Finished updating file `%s'.\n");
!       notice_finished_file (file);
!       return file->update_status;
      case cs_invalid:
      default:
***************
*** 450,459 ****
    depth--;
  
!   if (file->deps == 0 && file->cmds != 0)
      {
        must_make = 1;
!       DEBUGPR ("Target `%s' has commands but no dependencies.\n");
      }
!   else if (!deps_changed && file->cmds == 0)
      {
        must_make = 0;
--- 415,424 ----
    depth--;
  
!   if (file->double_colon && file->deps == 0)
      {
        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;
***************
*** 473,477 ****
  
    /* Now, take appropriate actions to remake the file.  */
!   file->update_status = remake_file (file);
  
    if (file->update_status != 0)
--- 438,442 ----
  
    /* Now, take appropriate actions to remake the file.  */
!   remake_file (file);
  
    if (file->update_status != 0)
***************
*** 491,495 ****
     of all files listed in its `also_make' member.  */
  
! int
  notice_finished_file (file)
       register struct file *file;
--- 456,460 ----
     of all files listed in its `also_make' member.  */
  
! void
  notice_finished_file (file)
       register struct file *file;
***************
*** 499,503 ****
    if (!file->phony)
      {
!       if (just_print_flag || question_flag || file->cmds == 0)
  	{
  	  file->last_mtime = time ((time_t *) 0);
--- 464,469 ----
    if (!file->phony)
      {
!       if (just_print_flag || question_flag
! 	  || (file->is_target && file->cmds == 0))
  	{
  	  file->last_mtime = time ((time_t *) 0);
***************
*** 526,531 ****
  	}
      }
- 
-   return file->update_status;
  }
  \f


--- 492,495 ----
***************
*** 618,624 ****
--- 582,590 ----
      }
  
+ #ifndef	NO_ARCHIVES
    if (ar_name (file->name))
      return ar_touch (file->name);
    else
+ #endif
      {
        int fd = open (file->name, O_RDWR | O_CREAT, 0666);
***************
*** 660,664 ****
     Return the status from executing FILE's commands.  */
  
! static int
  remake_file (file)
       struct file *file;
--- 626,630 ----
     Return the status from executing FILE's commands.  */
  
! static void
  remake_file (file)
       struct file *file;
***************
*** 698,706 ****
  	}
        else
! 	return execute_file_commands (file);
      }
  
    file->command_state = cs_finished;
!   return notice_finished_file (file);
  }
  \f


--- 664,672 ----
  	}
        else
! 	execute_file_commands (file);
      }
  
    file->command_state = cs_finished;
!   notice_finished_file (file);
  }
  \f


***************
*** 757,762 ****
--- 723,730 ----
    struct stat st;
  
+ #ifndef	NO_ARCHIVES
    if (ar_name (name))
      return ar_member_date (name);
+ #endif
  
    if (stat (name, &st) < 0)
diff -rc2 make-3.55/rule.c make-3.56/rule.c
*** make-3.55/rule.c	Mon Aug 14 21:10:20 1989
--- make-3.56/rule.c	Sun Sep 17 16:36:06 1989
***************
*** 24,28 ****
  #include "rule.h"
  
! static void new_pattern_rule (), freerule ();
  \f


  /* Chain of all pattern rules.  */
--- 24,29 ----
  #include "rule.h"
  
! static void freerule ();
! static int new_pattern_rule ();
  \f


  /* Chain of all pattern rules.  */
***************
*** 220,226 ****
     if OVERRIDE is nonzero, otherwise this new one is thrown out.
     When an old rule is replaced, the new one is put at the end of the
!    list.  */
  
! static void
  new_pattern_rule (rule, override)
       register struct rule *rule;
--- 221,227 ----
     if OVERRIDE is nonzero, otherwise this new one is thrown out.
     When an old rule is replaced, the new one is put at the end of the
!    list.  Return nonzero if RULE is used; zero if not.  */
  
! static int
  new_pattern_rule (rule, override)
       register struct rule *rule;
***************
*** 268,272 ****
  		  /* The old rule stays intact.  Destroy the new one.  */
  		  freerule (rule, (struct rule *) 0);
! 		  return;
  		}
  	  }
--- 269,273 ----
  		  /* The old rule stays intact.  Destroy the new one.  */
  		  freerule (rule, (struct rule *) 0);
! 		  return 0;
  		}
  	  }
***************
*** 283,286 ****
--- 284,289 ----
        last_pattern_rule = rule;
      }
+ 
+   return 1;
  }
  
***************
*** 324,338 ****
                                                         sizeof (struct dep)),
  				       sizeof (struct dep));
-   r->cmds = (struct commands *) xmalloc (sizeof (struct commands));
-   r->cmds->filename = 0;
-   r->cmds->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));
-   r->cmds->command_lines = 0;
  
!   new_pattern_rule (r, 0);
! 
!   r->terminal = terminal;
  }
  
--- 327,342 ----
                                                         sizeof (struct dep)),
  				       sizeof (struct dep));
  
!   if (new_pattern_rule (r, 0))
!     {
!       r->terminal = terminal;
!       r->cmds = (struct commands *) xmalloc (sizeof (struct commands));
!       r->cmds->filename = 0;
!       r->cmds->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));
!       r->cmds->command_lines = 0;
!     }
  }
  
***************
*** 438,444 ****
      }
  
!   new_pattern_rule (r, override);
! 
!   r->terminal = terminal;
  }
  \f


--- 442,447 ----
      }
  
!   if (new_pattern_rule (r, override))
!     r->terminal = terminal;
  }
  \f


***************
*** 493,500 ****
    else
      {
!       printf ("\n# %u implicit rules, %u (%.1f%%) terminal.\n",
! 	      rules, terminal, (double) terminal / (double) rules * 100.0);
!       printf ("# %u (%.1f%%) reference nonexistent subdirectories.\n",
! 	      subdir, (double) subdir / (double) rules * 100.0);
      }
  }
--- 496,510 ----
    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
!       puts (" reference nonexistent subdirectories.");
      }
  }
diff -rc2 make-3.55/variable.c make-3.56/variable.c
*** make-3.55/variable.c	Thu Aug 24 12:08:15 1989
--- make-3.56/variable.c	Thu Sep 14 18:39:10 1989
***************
*** 33,39 ****
--- 33,45 ----
  /* Hash table of all global variable definitions.  */
  
+ #ifndef	VARIABLE_BUCKETS
  #define VARIABLE_BUCKETS		523
+ #endif
+ #ifndef	PERFILE_VARIABLE_BUCKETS
  #define	PERFILE_VARIABLE_BUCKETS	23
+ #endif
+ #ifndef	SMALL_SCOPE_VARIABLE_BUCKETS
  #define	SMALL_SCOPE_VARIABLE_BUCKETS	13
+ #endif
  static struct variable *variable_table[VARIABLE_BUCKETS];
  static struct variable_set global_variable_set
***************
*** 71,82 ****
  {
    register unsigned int i;
!   register unsigned int hashval = 0;
    register struct variable *v;
  
    for (i = 0; i < length; ++i)
!     {
!       hashval += name[i];
!       hashval = (hashval << 7) + (hashval >> 20);
!     }
    hashval %= set->buckets;
  
--- 77,86 ----
  {
    register unsigned int i;
!   register unsigned int hashval;
    register struct variable *v;
  
+   hashval = 0;
    for (i = 0; i < length; ++i)
!     HASH (hashval, name[i]);
    hashval %= set->buckets;
  
***************
*** 87,92 ****
--- 91,101 ----
        break;
  
+   if (env_overrides && origin == o_env)
+     origin = o_env_override;
+ 
    if (v != 0)
      {
+       if (env_overrides && v->origin == o_env)
+ 	v->origin = o_env_override;
        /* A variable of this name is already defined.
  	 If the old definition is from a stronger source
***************
*** 159,166 ****
  
    for (i = 0; i < length; ++i)
!     {
!       rawhash += name[i];
!       rawhash = (rawhash << 7) + (rawhash >> 20);
!     }
  
    for (setlist = current_variable_set_list;
--- 168,172 ----
  
    for (i = 0; i < length; ++i)
!     HASH (rawhash, name[i]);
  
    for (setlist = current_variable_set_list;
***************
*** 592,595 ****
--- 598,602 ----
        printf ("# %u variables in %u hash buckets.\n",
  	      nvariables, set->buckets);
+ #ifndef	NO_FLOAT
        printf ("# average of %.1f variables per bucket, \
  max %u in one bucket.\n",
***************
*** 596,599 ****
--- 603,607 ----
  	      ((double) nvariables) * 100.0 / (double) set->buckets,
  	      per_bucket);
+ #endif
      }
  }
diff -rc2 make-3.55/variable.h make-3.56/variable.h
*** make-3.55/variable.h	Sun Jun 11 12:19:06 1989
--- make-3.56/variable.h	Sun Sep 17 16:36:14 1989
***************
*** 39,45 ****
      char *name;			/* Variable name.  */
      char *value;		/* Variable value.  */
!     enum variable_origin origin;/* Variable origin.  */
!     char recursive;		/* Gets recursively re-evaluated.  */
!     char expanding;		/* Is currently expanding.  */
    };
  
--- 39,46 ----
      char *name;			/* Variable name.  */
      char *value;		/* Variable value.  */
!     enum variable_origin
!       origin ENUM_BITFIELD (3);	/* Variable origin.  */
!     unsigned int recursive:1;	/* Gets recursively re-evaluated.  */
!     unsigned int expanding:1;	/* Is currently expanding.  */
    };
  
***************
*** 79,82 ****
--- 80,84 ----
  extern void define_automatic_variables ();
  extern void initialize_file_variables ();
+ extern void print_file_variables ();
  
  extern int try_variable_definition ();
diff -rc2 make-3.55/version.c make-3.56/version.c
*** make-3.55/version.c	Sat Aug 26 13:18:23 1989
--- make-3.56/version.c	Fri Sep 22 16:18:41 1989
***************
*** 1,3 ****
! char *version_string = "3.55";
  \f


  /*
--- 1,3 ----
! char *version_string = "3.56";
  \f


  /*