update, bug fix, ANSI C, lint from Christos Zoulas
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Tue, 25 May 1993 05:46:05 +0000 (21:46 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Tue, 25 May 1993 05:46:05 +0000 (21:46 -0800)
see SCCS/README.christos for details

SCCS-vsn: usr.bin/make/arch.c 5.8
SCCS-vsn: usr.bin/make/bit.h 5.4
SCCS-vsn: usr.bin/make/buf.c 5.6
SCCS-vsn: usr.bin/make/buf.h 5.5
SCCS-vsn: usr.bin/make/compat.c 5.10
SCCS-vsn: usr.bin/make/cond.c 5.7
SCCS-vsn: usr.bin/make/config.h 5.10
SCCS-vsn: usr.bin/make/dir.c 5.8
SCCS-vsn: usr.bin/make/hash.c 5.6
SCCS-vsn: usr.bin/make/hash.h 5.5
SCCS-vsn: usr.bin/make/job.c 5.18
SCCS-vsn: usr.bin/make/job.h 5.4
SCCS-vsn: usr.bin/make/list.h 5.4
SCCS-vsn: usr.bin/make/lst.h 5.4
SCCS-vsn: usr.bin/make/main.c 5.30
SCCS-vsn: usr.bin/make/make.1 5.8
SCCS-vsn: usr.bin/make/make.c 5.4
SCCS-vsn: usr.bin/make/make.h 5.14
SCCS-vsn: usr.bin/make/nonints.h 5.7
SCCS-vsn: usr.bin/make/parse.c 5.19
SCCS-vsn: usr.bin/make/sprite.h 5.5
SCCS-vsn: usr.bin/make/str.c 5.9
SCCS-vsn: usr.bin/make/suff.c 5.7
SCCS-vsn: usr.bin/make/targ.c 5.10
SCCS-vsn: usr.bin/make/var.c 5.9

25 files changed:
usr/src/usr.bin/make/arch.c
usr/src/usr.bin/make/bit.h
usr/src/usr.bin/make/buf.c
usr/src/usr.bin/make/buf.h
usr/src/usr.bin/make/compat.c
usr/src/usr.bin/make/cond.c
usr/src/usr.bin/make/config.h
usr/src/usr.bin/make/dir.c
usr/src/usr.bin/make/hash.c
usr/src/usr.bin/make/hash.h
usr/src/usr.bin/make/job.c
usr/src/usr.bin/make/job.h
usr/src/usr.bin/make/list.h
usr/src/usr.bin/make/lst.h
usr/src/usr.bin/make/main.c
usr/src/usr.bin/make/make.1
usr/src/usr.bin/make/make.c
usr/src/usr.bin/make/make.h
usr/src/usr.bin/make/nonints.h
usr/src/usr.bin/make/parse.c
usr/src/usr.bin/make/sprite.h
usr/src/usr.bin/make/str.c
usr/src/usr.bin/make/suff.c
usr/src/usr.bin/make/targ.c
usr/src/usr.bin/make/var.c

index 9ee3750..0fc5d1d 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)arch.c     5.7 (Berkeley) %G%";
+static char sccsid[] = "@(#)arch.c     5.8 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -65,10 +65,12 @@ static char sccsid[] = "@(#)arch.c  5.7 (Berkeley) %G%";
 #include    <sys/time.h>
 #include    <ctype.h>
 #include    <ar.h>
 #include    <sys/time.h>
 #include    <ctype.h>
 #include    <ar.h>
-#include <ranlib.h>
+#include    <ranlib.h>
 #include    <stdio.h>
 #include    "make.h"
 #include    "hash.h"
 #include    <stdio.h>
 #include    "make.h"
 #include    "hash.h"
+#include    "dir.h"
+#include    "config.h"
 
 static Lst       archives;   /* Lst of archives we've already examined */
 
 
 static Lst       archives;   /* Lst of archives we've already examined */
 
@@ -78,7 +80,9 @@ typedef struct Arch {
                               * by <name, struct ar_hdr *> key/value pairs */
 } Arch;
 
                               * by <name, struct ar_hdr *> key/value pairs */
 } Arch;
 
-static FILE *ArchFindMember();
+static int ArchFindArchive __P((Arch *, char *));
+static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));
+static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));
 
 /*-
  *-----------------------------------------------------------------------
 
 /*-
  *-----------------------------------------------------------------------
@@ -107,7 +111,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
     GNode          *gn;            /* New node */
     char           *libName;       /* Library-part of specification */
     char           *memName;       /* Member-part of specification */
     GNode          *gn;            /* New node */
     char           *libName;       /* Library-part of specification */
     char           *memName;       /* Member-part of specification */
-    char           nameBuf[BSIZE]; /* temporary place for node name */
+    char           nameBuf[MAKE_BSIZE]; /* temporary place for node name */
     char           saveChar;       /* Ending delimiter of member-name */
     Boolean        subLibName;     /* TRUE if libName should have/had
                                     * variable substitution performed on it */
     char           saveChar;       /* Ending delimiter of member-name */
     Boolean        subLibName;     /* TRUE if libName should have/had
                                     * variable substitution performed on it */
@@ -142,11 +146,11 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
 
     *cp++ = '\0';
     if (subLibName) {
 
     *cp++ = '\0';
     if (subLibName) {
-       libName = Var_Subst(libName, ctxt, TRUE);
+       libName = Var_Subst(NULL, libName, ctxt, TRUE);
     }
     
 
     }
     
 
-    while (1) {
+    for (;;) {
        /*
         * First skip to the start of the member's name, mark that
         * place and skip to the end of it (either white-space or
        /*
         * First skip to the start of the member's name, mark that
         * place and skip to the end of it (either white-space or
@@ -221,7 +225,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
            char    *sacrifice;
            char    *oldMemName = memName;
            
            char    *sacrifice;
            char    *oldMemName = memName;
            
-           memName = Var_Subst(memName, ctxt, TRUE);
+           memName = Var_Subst(NULL, memName, ctxt, TRUE);
 
            /*
             * Now form an archive spec and recurse to deal with nested
 
            /*
             * Now form an archive spec and recurse to deal with nested
@@ -232,7 +236,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
 
            sprintf(buf, "%s(%s)", libName, memName);
 
 
            sprintf(buf, "%s(%s)", libName, memName);
 
-           if (index(memName, '$') && strcmp(memName, oldMemName) == 0) {
+           if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) {
                /*
                 * Must contain dynamic sources, so we can't deal with it now.
                 * Just create an ARCHV node for the thing and let
                /*
                 * Must contain dynamic sources, so we can't deal with it now.
                 * Just create an ARCHV node for the thing and let
@@ -401,7 +405,7 @@ ArchStatMember (archive, member, hash)
      * to point 'member' to the final component, if there is one, to make
      * the comparisons easier...
      */
      * to point 'member' to the final component, if there is one, to make
      * the comparisons easier...
      */
-    cp = rindex (member, '/');
+    cp = strrchr (member, '/');
     if (cp != (char *) NULL) {
        member = cp + 1;
     }
     if (cp != (char *) NULL) {
        member = cp + 1;
     }
@@ -490,7 +494,7 @@ ArchStatMember (archive, member, hash)
            he = Hash_CreateEntry (&ar->members, strdup (memName),
                                   (Boolean *)NULL);
            Hash_SetValue (he, (ClientData)emalloc (sizeof (struct ar_hdr)));
            he = Hash_CreateEntry (&ar->members, strdup (memName),
                                   (Boolean *)NULL);
            Hash_SetValue (he, (ClientData)emalloc (sizeof (struct ar_hdr)));
-           bcopy ((Address)&arh, (Address)Hash_GetValue (he)
+           memcpy ((Address)Hash_GetValue (he), (Address)&arh
                sizeof (struct ar_hdr));
        }
        /*
                sizeof (struct ar_hdr));
        }
        /*
@@ -573,7 +577,7 @@ ArchFindMember (archive, member, arhPtr, mode)
      * to point 'member' to the final component, if there is one, to make
      * the comparisons easier...
      */
      * to point 'member' to the final component, if there is one, to make
      * the comparisons easier...
      */
-    cp = rindex (member, '/');
+    cp = strrchr (member, '/');
     if (cp != (char *) NULL) {
        member = cp + 1;
     }
     if (cp != (char *) NULL) {
        member = cp + 1;
     }
@@ -774,8 +778,8 @@ Arch_MemMTime (gn)
             * child. We keep searching its parents in case some other
             * parent requires this child to exist...
             */
             * child. We keep searching its parents in case some other
             * parent requires this child to exist...
             */
-           nameStart = index (pgn->name, '(') + 1;
-           nameEnd = index (nameStart, ')');
+           nameStart = strchr (pgn->name, '(') + 1;
+           nameEnd = strchr (nameStart, ')');
 
            if (pgn->make &&
                strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) {
 
            if (pgn->make &&
                strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) {
index b9d2475..d44d559 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)bit.h       5.3 (Berkeley) %G%
+ *     @(#)bit.h       5.4 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -71,4 +71,4 @@ extern Boolean          Bit_Union();
 extern Boolean           Bit_AnySet();
 extern int       *Bit_Expand();
         
 extern Boolean           Bit_AnySet();
 extern int       *Bit_Expand();
         
-#endif _BIT
+#endif /* _BIT */
index 6278fad..4a48a80 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)buf.c      5.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)buf.c      5.6 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -20,6 +20,7 @@ static char sccsid[] = "@(#)buf.c     5.5 (Berkeley) %G%";
  */
 
 #include    "sprite.h"
  */
 
 #include    "sprite.h"
+#include    "make.h"
 #include    "buf.h"
 
 #ifndef max
 #include    "buf.h"
 
 #ifndef max
@@ -65,7 +66,7 @@ static char sccsid[] = "@(#)buf.c     5.5 (Berkeley) %G%";
 void
 Buf_OvAddByte (bp, byte)
     register Buffer bp;
 void
 Buf_OvAddByte (bp, byte)
     register Buffer bp;
-    Byte    byte;
+    int    byte;
 {
 
     bp->left = 0;
 {
 
     bp->left = 0;
@@ -102,7 +103,7 @@ Buf_AddBytes (bp, numBytes, bytesPtr)
 
     BufExpand (bp, numBytes);
 
 
     BufExpand (bp, numBytes);
 
-    bcopy (bytesPtr, bp->inPtr, numBytes);
+    memcpy (bp->inPtr, bytesPtr, numBytes);
     bp->inPtr += numBytes;
     bp->left -= numBytes;
 
     bp->inPtr += numBytes;
     bp->left -= numBytes;
 
@@ -128,7 +129,7 @@ Buf_AddBytes (bp, numBytes, bytesPtr)
 void
 Buf_UngetByte (bp, byte)
     register Buffer bp;
 void
 Buf_UngetByte (bp, byte)
     register Buffer bp;
-    Byte    byte;
+    int    byte;
 {
 
     if (bp->outPtr != bp->buffer) {
 {
 
     if (bp->outPtr != bp->buffer) {
@@ -150,8 +151,7 @@ Buf_UngetByte (bp, byte)
        Byte      *newBuf;
 
        newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
        Byte      *newBuf;
 
        newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
-       bcopy ((char *)bp->outPtr,
-                       (char *)(newBuf+BUF_UNGET_INC), numBytes+1);
+       memcpy ((char *)(newBuf+BUF_UNGET_INC), (char *)bp->outPtr, numBytes+1);
        bp->outPtr = newBuf + BUF_UNGET_INC;
        bp->inPtr = bp->outPtr + numBytes;
        free ((char *)bp->buffer);
        bp->outPtr = newBuf + BUF_UNGET_INC;
        bp->inPtr = bp->outPtr + numBytes;
        free ((char *)bp->buffer);
@@ -185,7 +185,7 @@ Buf_UngetBytes (bp, numBytes, bytesPtr)
 
     if (bp->outPtr - bp->buffer >= numBytes) {
        bp->outPtr -= numBytes;
 
     if (bp->outPtr - bp->buffer >= numBytes) {
        bp->outPtr -= numBytes;
-       bcopy (bytesPtr, bp->outPtr, numBytes);
+       memcpy (bp->outPtr, bytesPtr, numBytes);
     } else if (bp->outPtr == bp->inPtr) {
        Buf_AddBytes (bp, numBytes, bytesPtr);
     } else {
     } else if (bp->outPtr == bp->inPtr) {
        Buf_AddBytes (bp, numBytes, bytesPtr);
     } else {
@@ -194,7 +194,7 @@ Buf_UngetBytes (bp, numBytes, bytesPtr)
        int       newBytes = max(numBytes,BUF_UNGET_INC);
 
        newBuf = (Byte *)emalloc (bp->size + newBytes);
        int       newBytes = max(numBytes,BUF_UNGET_INC);
 
        newBuf = (Byte *)emalloc (bp->size + newBytes);
-       bcopy((char *)bp->outPtr, (char *)(newBuf+newBytes), curNumBytes+1);
+       memcpy((char *)(newBuf+newBytes), (char *)bp->outPtr, curNumBytes+1);
        bp->outPtr = newBuf + newBytes;
        bp->inPtr = bp->outPtr + curNumBytes;
        free ((char *)bp->buffer);
        bp->outPtr = newBuf + newBytes;
        bp->inPtr = bp->outPtr + curNumBytes;
        free ((char *)bp->buffer);
@@ -202,7 +202,7 @@ Buf_UngetBytes (bp, numBytes, bytesPtr)
        bp->size += newBytes;
        bp->left = bp->size - (bp->inPtr - bp->buffer);
        bp->outPtr -= numBytes;
        bp->size += newBytes;
        bp->left = bp->size - (bp->inPtr - bp->buffer);
        bp->outPtr -= numBytes;
-       bcopy ((char *)bytesPtr, (char *)bp->outPtr, numBytes);
+       memcpy ((char *)bp->outPtr, (char *)bytesPtr, numBytes);
     }
 }
 \f
     }
 }
 \f
@@ -264,7 +264,7 @@ Buf_GetBytes (bp, numBytes, bytesPtr)
     if (bp->inPtr - bp->outPtr < numBytes) {
        numBytes = bp->inPtr - bp->outPtr;
     }
     if (bp->inPtr - bp->outPtr < numBytes) {
        numBytes = bp->inPtr - bp->outPtr;
     }
-    bcopy (bp->outPtr, bytesPtr, numBytes);
+    memcpy (bytesPtr, bp->outPtr, numBytes);
     bp->outPtr += numBytes;
 
     if (bp->outPtr == bp->inPtr) {
     bp->outPtr += numBytes;
 
     if (bp->outPtr == bp->inPtr) {
index 14e5bba..363293e 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)buf.h       5.4 (Berkeley) %G%
+ *     @(#)buf.h       5.5 (Berkeley) %G%
  */
 
 /*-
  */
 
 /*-
@@ -32,24 +32,23 @@ typedef struct Buffer {
     Byte    *outPtr;   /* Place to read from */
 } *Buffer;
 
     Byte    *outPtr;   /* Place to read from */
 } *Buffer;
 
-Buffer           Buf_Init();       /* Initialize a buffer */
-void             Buf_Destroy();    /* Destroy a buffer */
-void             Buf_AddBytes();   /* Add a range of bytes to a buffer */
-int              Buf_GetByte();    /* Get a byte from a buffer */
-int              Buf_GetBytes();   /* Get multiple bytes */
-void             Buf_UngetByte();  /* Push a byte back into the buffer */
-void             Buf_UngetBytes(); /* Push many bytes back into the buf */
-Byte             *Buf_GetAll();    /* Get them all */
-void             Buf_Discard();    /* Throw away some of the bytes */
-int              Buf_Size();       /* See how many are there */
-
 /* Buf_AddByte adds a single byte to a buffer. */
 #define        Buf_AddByte(bp, byte) \
 /* Buf_AddByte adds a single byte to a buffer. */
 #define        Buf_AddByte(bp, byte) \
-       (--(bp)->left <= 0 ? Buf_OvAddByte(bp, byte) : \
-               (void)(*(bp)->inPtr++ = (byte), *(bp)->inPtr = 0))
-
-void   Buf_OvAddByte();                /* adds a byte when buffer overflows */
+       (void) (--(bp)->left <= 0 ? Buf_OvAddByte(bp, byte), 1 : \
+               (*(bp)->inPtr++ = (byte), *(bp)->inPtr = 0), 1)
 
 #define BUF_ERROR 256
 
 
 #define BUF_ERROR 256
 
-#endif _BUF_H
+void    Buf_AddBytes __P((Buffer, int, Byte *));
+void    Buf_Destroy __P((Buffer, Boolean));
+void    Buf_Discard __P((Buffer, int));
+Byte   *Buf_GetAll __P((Buffer, int *));
+int     Buf_GetByte __P((Buffer));
+int     Buf_GetBytes __P((Buffer, int, Byte *));
+Buffer  Buf_Init __P((int));
+void    Buf_OvAddByte __P((Buffer, int));
+int     Buf_Size __P((Buffer));
+void    Buf_UngetByte __P((Buffer, int));
+void    Buf_UngetBytes __P((Buffer, int, Byte *));
+
+#endif /* _BUF_H */
index e6326f1..a5c3d17 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)compat.c   5.9 (Berkeley) %G%";
+static char sccsid[] = "@(#)compat.c   5.10 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -29,12 +29,14 @@ static char sccsid[] = "@(#)compat.c        5.9 (Berkeley) %G%";
 
 #include    <stdio.h>
 #include    <sys/types.h>
 
 #include    <stdio.h>
 #include    <sys/types.h>
-#include    <sys/stat.h>
+#include    <sys/signal.h>
 #include    <sys/wait.h>
 #include    <sys/errno.h>
 #include    <sys/wait.h>
 #include    <sys/errno.h>
-#include    <signal.h>
 #include    <ctype.h>
 #include    "make.h"
 #include    <ctype.h>
 #include    "make.h"
+#include    "hash.h"
+#include    "dir.h"
+#include    "job.h"
 extern int errno;
 
 /*
 extern int errno;
 
 /*
@@ -48,7 +50,9 @@ static char       meta[256];
 
 static GNode       *curTarg = NILGNODE;
 static GNode       *ENDNode;
 
 static GNode       *curTarg = NILGNODE;
 static GNode       *ENDNode;
-static int         CompatRunCommand();
+static void CompatInterrupt __P((int));
+static int CompatRunCommand __P((char *, GNode *));
+static int CompatMake __P((GNode *, GNode *));
 
 /*-
  *-----------------------------------------------------------------------
 
 /*-
  *-----------------------------------------------------------------------
@@ -70,13 +74,11 @@ CompatInterrupt (signo)
     int            signo;
 {
     GNode   *gn;
     int            signo;
 {
     GNode   *gn;
-    struct stat sb;
     
     if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
        char      *file = Var_Value (TARGET, curTarg);
 
     
     if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
        char      *file = Var_Value (TARGET, curTarg);
 
-       if (!stat(file, &sb) && S_ISREG(sb.st_mode) &&
-           unlink (file) == SUCCESS) {
+       if (unlink (file) == SUCCESS) {
            printf ("*** %s removed\n", file);
        }
 
            printf ("*** %s removed\n", file);
        }
 
@@ -119,7 +121,6 @@ CompatRunCommand (cmd, gn)
     union wait           reason;       /* Reason for child's death */
     int                  status;       /* Description of child's death */
     int                  cpid;         /* Child actually found */
     union wait           reason;       /* Reason for child's death */
     int                  status;       /* Description of child's death */
     int                  cpid;         /* Child actually found */
-    int                  numWritten;   /* Number of bytes written for error message */
     ReturnStatus  stat;                /* Status of fork */
     LstNode      cmdNode;      /* Node where current command is located */
     char         **av;         /* Argument vector for thing to exec */
     ReturnStatus  stat;                /* Status of fork */
     LstNode      cmdNode;      /* Node where current command is located */
     char         **av;         /* Argument vector for thing to exec */
@@ -132,7 +133,7 @@ CompatRunCommand (cmd, gn)
     errCheck = !(gn->type & OP_IGNORE);
 
     cmdNode = Lst_Member (gn->commands, (ClientData)cmd);
     errCheck = !(gn->type & OP_IGNORE);
 
     cmdNode = Lst_Member (gn->commands, (ClientData)cmd);
-    cmdStart = Var_Subst (cmd, gn, FALSE);
+    cmdStart = Var_Subst (NULL, cmd, gn, FALSE);
 
     /*
      * brk_string will return an argv with a NULL in av[1], thus causing
 
     /*
      * brk_string will return an argv with a NULL in av[1], thus causing
@@ -171,7 +172,7 @@ CompatRunCommand (cmd, gn)
      * characters, there's no need to execute a shell to execute the
      * command.
      */
      * characters, there's no need to execute a shell to execute the
      * command.
      */
-    for (cp = cmd; !meta[*cp]; cp++) {
+    for (cp = cmd; !meta[(unsigned char)*cp]; cp++) {
        continue;
     }
 
        continue;
     }
 
@@ -229,8 +230,8 @@ CompatRunCommand (cmd, gn)
     if (cpid == 0) {
        if (local) {
            execvp(av[0], av);
     if (cpid == 0) {
        if (local) {
            execvp(av[0], av);
-           numWritten = write (2, av[0], strlen (av[0]));
-           numWritten = write (2, ": not found\n", sizeof(": not found"));
+           (void) write (2, av[0], strlen (av[0]));
+           (void) write (2, ": not found\n", sizeof(": not found"));
        } else {
            (void)execv(av[0], av);
        }
        } else {
            (void)execv(av[0], av);
        }
@@ -460,6 +461,8 @@ CompatMake (gn, pgn)
            if (noExecute || Dir_MTime(gn) == 0) {
                gn->mtime = now;
            }
            if (noExecute || Dir_MTime(gn) == 0) {
                gn->mtime = now;
            }
+           if (gn->cmtime > gn->mtime)
+               gn->mtime = gn->cmtime;
            if (DEBUG(MAKE)) {
                printf("update time: %s\n", Targ_FmtTime(gn->mtime));
            }
            if (DEBUG(MAKE)) {
                printf("update time: %s\n", Targ_FmtTime(gn->mtime));
            }
@@ -501,6 +504,8 @@ CompatMake (gn, pgn)
                    Make_TimeStamp(pgn, gn);
                }
                break;
                    Make_TimeStamp(pgn, gn);
                }
                break;
+           default:
+               break;
        }
     }
 
        }
     }
 
@@ -525,7 +530,7 @@ Compat_Run(targs)
     Lst                  targs;    /* List of target nodes to re-create */
 {
     char         *cp;      /* Pointer to string of shell meta-characters */
     Lst                  targs;    /* List of target nodes to re-create */
 {
     char         *cp;      /* Pointer to string of shell meta-characters */
-    GNode        *gn;      /* Current root target */
+    GNode        *gn = NULL;/* Current root target */
     int                  errors;   /* Number of targets not remade due to errors */
 
     if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
     int                  errors;   /* Number of targets not remade due to errors */
 
     if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
@@ -542,7 +547,7 @@ Compat_Run(targs)
     }
 
     for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
     }
 
     for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
-       meta[*cp] = 1;
+       meta[(unsigned char) *cp] = 1;
     }
     /*
      * The null character serves as a sentinel in the string.
     }
     /*
      * The null character serves as a sentinel in the string.
index cd9e1ad..81b6330 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cond.c     5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)cond.c     5.7 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -23,9 +23,12 @@ static char sccsid[] = "@(#)cond.c   5.6 (Berkeley) %G%";
  *
  */
 
  *
  */
 
-#include    "make.h"
-#include    <buf.h>
 #include    <ctype.h>
 #include    <ctype.h>
+#include    <math.h>
+#include    "make.h"
+#include    "hash.h"
+#include    "dir.h"
+#include    "buf.h"
 
 /*
  * The parsing of conditional expressions is based on this grammar:
 
 /*
  * The parsing of conditional expressions is based on this grammar:
@@ -65,8 +68,17 @@ typedef enum {
  * Structures to handle elegantly the different forms of #if's. The
  * last two fields are stored in condInvert and condDefProc, respectively.
  */
  * Structures to handle elegantly the different forms of #if's. The
  * last two fields are stored in condInvert and condDefProc, respectively.
  */
-static Boolean   CondDoDefined(),
-                 CondDoMake();
+static int CondGetArg __P((char **, char **, char *, Boolean));
+static Boolean CondDoDefined __P((int, char *));
+static int CondStrMatch __P((char *, char *));
+static Boolean CondDoMake __P((int, char *));
+static Boolean CondDoExists __P((int, char *));
+static Boolean CondDoTarget __P((int, char *));
+static Boolean CondCvtArg __P((char *, double *));
+static Token CondToken __P((Boolean));
+static Token CondT __P((Boolean));
+static Token CondF __P((Boolean));
+static Token CondE __P((Boolean));
 
 static struct If {
     char       *form;        /* Form of if */
 
 static struct If {
     char       *form;        /* Form of if */
@@ -74,12 +86,12 @@ static struct If {
     Boolean    doNot;        /* TRUE if default function should be negated */
     Boolean    (*defProc)(); /* Default function to apply */
 } ifs[] = {
     Boolean    doNot;        /* TRUE if default function should be negated */
     Boolean    (*defProc)(); /* Default function to apply */
 } ifs[] = {
-    "ifdef",     5,      FALSE,  CondDoDefined,
-    "ifndef",    6,      TRUE,   CondDoDefined,
-    "ifmake",    6,      FALSE,  CondDoMake,
-    "ifnmake",   7,      TRUE,   CondDoMake,
-    "if",        2,      FALSE,  CondDoDefined,
-    (char *)0,   0,      FALSE,  (Boolean (*)())0,
+    { "ifdef",   5,      FALSE,  CondDoDefined },
+    { "ifndef",          6,      TRUE,   CondDoDefined },
+    { "ifmake",          6,      FALSE,  CondDoMake },
+    { "ifnmake",  7,     TRUE,   CondDoMake },
+    { "if",      2,      FALSE,  CondDoDefined },
+    { (char *)0,  0,     FALSE,  (Boolean (*)())0 }
 };
 
 static Boolean   condInvert;           /* Invert the default function */
 };
 
 static Boolean   condInvert;           /* Invert the default function */
@@ -96,8 +108,6 @@ static int     skipIfLevel=0;        /* Depth of skipped conditionals */
 static Boolean   skipLine = FALSE;     /* Whether the parse module is skipping
                                         * lines */
 
 static Boolean   skipLine = FALSE;     /* Whether the parse module is skipping
                                         * lines */
 
-static Token     CondT(), CondF(), CondE();
-
 /*-
  *-----------------------------------------------------------------------
  * CondPushBack --
 /*-
  *-----------------------------------------------------------------------
  * CondPushBack --
@@ -175,7 +185,7 @@ CondGetArg (linePtr, argPtr, func, parens)
      */
     buf = Buf_Init(16);
     
      */
     buf = Buf_Init(16);
     
-    while ((index(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) {
+    while ((strchr(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) {
        if (*cp == '$') {
            /*
             * Parse the variable spec and install it as part of the argument
        if (*cp == '$') {
            /*
             * Parse the variable spec and install it as part of the argument
@@ -378,60 +388,45 @@ CondDoTarget (argLen, arg)
  *-----------------------------------------------------------------------
  * CondCvtArg --
  *     Convert the given number into a double. If the number begins
  *-----------------------------------------------------------------------
  * CondCvtArg --
  *     Convert the given number into a double. If the number begins
- *     with 0x, or just x, it is interpreted as a hexadecimal integer
+ *     with 0x, it is interpreted as a hexadecimal integer
  *     and converted to a double from there. All other strings just have
  *     and converted to a double from there. All other strings just have
- *     atof called on them.
+ *     strtod called on them.
  *
  * Results:
  *
  * Results:
- *     The double value of string.
+ *     Sets 'value' to double value of string.
+ *     Returns true if the string was a valid number, false o.w.
  *
  * Side Effects:
  *
  * Side Effects:
+ *     Can change 'value' even if string is not a valid number.
  *     
  *
  *-----------------------------------------------------------------------
  */
  *     
  *
  *-----------------------------------------------------------------------
  */
-static double
-CondCvtArg(str)
+static Boolean
+CondCvtArg(str, value)
     register char      *str;
     register char      *str;
+    double             *value;
 {
 {
-    int                        sign = 1;
-    double             atof();
-    
-    if (*str == '-') {
-       sign = -1;
-       str++;
-    } else if (*str == '+') {
-       str++;
-    }
-    if (((*str == '0') && (str[1] == 'x')) ||
-       (*str == 'x'))
-    {
-       register int i;
-       
-       str += (*str == 'x') ? 1 : 2;
+    if ((*str == '0') && (str[1] == 'x')) {
+       register long i;
 
 
-       i = 0;
-
-       while (isxdigit(*str)) {
-           i *= 16;
-           if (*str <= '9') {
-               i += *str - '0';
-           } else if (*str <= 'F') {
-               i += *str - 'A' + 10;
-           } else {
-               i += *str - 'a' + 10;
-           }
-           str++;
-       }
-       if (sign < 0) {
-           return((double)(-i));
-       } else {
-           return((double)i);
+       for (str += 2, i = 0; *str; str++) {
+           int x;
+           if (isdigit((unsigned char) *str))
+               x  = *str - '0';
+           else if (isxdigit((unsigned char) *str))
+               x = 10 + *str - isupper((unsigned char) *str) ? 'A' : 'a';
+           else
+               return FALSE;
+           i = (i << 4) + x;
        }
        }
-    } else if (sign < 0) {
-       return(- atof(str));
-    } else {
-       return(atof(str));
+       *value = (double) i;
+       return TRUE;
+    }
+    else {
+       char *eptr;
+       *value = strtod(str, &eptr);
+       return *eptr == '\0';
     }
 }
 \f
     }
 }
 \f
@@ -511,12 +506,34 @@ CondToken(doEval)
                }
                condExpr += varSpecLen;
 
                }
                condExpr += varSpecLen;
 
+               if (!isspace(*condExpr) && strchr("!=><", *condExpr) == NULL) {
+                   Buffer buf;
+                   char *cp;
+
+                   buf = Buf_Init(0);
+
+                   for (cp = lhs; *cp; cp++)
+                       Buf_AddByte(buf, (Byte)*cp);
+
+                   if (doFree)
+                       free(lhs);
+
+                   for (;*condExpr && !isspace(*condExpr); condExpr++)
+                       Buf_AddByte(buf, (Byte)*condExpr);
+
+                   Buf_AddByte(buf, (Byte)'\0');
+                   lhs = (char *)Buf_GetAll(buf, &varSpecLen);
+                   Buf_Destroy(buf, FALSE);
+
+                   doFree = TRUE;
+               }
+
                /*
                 * Skip whitespace to get to the operator
                 */
                /*
                 * Skip whitespace to get to the operator
                 */
-               while (isspace(*condExpr)) {
+               while (isspace(*condExpr))
                    condExpr++;
                    condExpr++;
-               }
+
                /*
                 * Make sure the operator is a valid one. If it isn't a
                 * known relational operator, pretend we got a
                /*
                 * Make sure the operator is a valid one. If it isn't a
                 * known relational operator, pretend we got a
@@ -559,6 +576,7 @@ do_compare:
                    char    *cp, *cp2;
                    Buffer  buf;
 
                    char    *cp, *cp2;
                    Buffer  buf;
 
+do_string_compare:
                    if (((*op != '!') && (*op != '=')) || (op[1] != '=')) {
                        Parse_Error(PARSE_WARNING,
                "String comparison operator should be either == or !=");
                    if (((*op != '!') && (*op != '=')) || (op[1] != '=')) {
                        Parse_Error(PARSE_WARNING,
                "String comparison operator should be either == or !=");
@@ -567,7 +585,8 @@ do_compare:
 
                    buf = Buf_Init(0);
                    
 
                    buf = Buf_Init(0);
                    
-                   for (cp = rhs+1; (*cp != '"') && (*cp != '\0'); cp++) {
+                   for (cp = &rhs[*rhs == '"' ? 1 : 0]; 
+                        (*cp != '"') && (*cp != '\0'); cp++) {
                        if ((*cp == '\\') && (cp[1] != '\0')) {
                            /*
                             * Backslash escapes things -- skip over next
                        if ((*cp == '\\') && (cp[1] != '\0')) {
                            /*
                             * Backslash escapes things -- skip over next
@@ -624,7 +643,8 @@ do_compare:
                    double      left, right;
                    char        *string;
 
                    double      left, right;
                    char        *string;
 
-                   left = CondCvtArg(lhs);
+                   if (!CondCvtArg(lhs, &left))
+                       goto do_string_compare;
                    if (*rhs == '$') {
                        int     len;
                        Boolean freeIt;
                    if (*rhs == '$') {
                        int     len;
                        Boolean freeIt;
@@ -633,16 +653,19 @@ do_compare:
                        if (string == var_Error) {
                            right = 0.0;
                        } else {
                        if (string == var_Error) {
                            right = 0.0;
                        } else {
-                           right = CondCvtArg(string);
-                           if (freeIt) {
-                               free(string);
+                           if (!CondCvtArg(string, &right)) {
+                               if (freeIt)
+                                   free(string);
+                               goto do_string_compare;
                            }
                            }
-                           if (rhs == condExpr) {
+                           if (freeIt)
+                               free(string);
+                           if (rhs == condExpr)
                                condExpr += len;
                                condExpr += len;
-                           }
                        }
                    } else {
                        }
                    } else {
-                       right = CondCvtArg(rhs);
+                       if (!CondCvtArg(rhs, &right))
+                           goto do_string_compare;
                        if (rhs == condExpr) {
                            /*
                             * Skip over the right-hand side
                        if (rhs == condExpr) {
                            /*
                             * Skip over the right-hand side
@@ -691,9 +714,8 @@ do_compare:
                    }
                }
 error:
                    }
                }
 error:
-               if (doFree) {
+               if (doFree)
                    free(lhs);
                    free(lhs);
-               }
                break;
            }
            default: {
                break;
            }
            default: {
@@ -764,7 +786,14 @@ error:
                        if (val == var_Error) {
                            t = Err;
                        } else {
                        if (val == var_Error) {
                            t = Err;
                        } else {
-                           t = (*val == '\0') ? True : False;
+                           /* 
+                            * A variable is empty when it just contains 
+                            * spaces... 4/15/92, christos
+                            */
+                           char *p;
+                           for (p = val; *p && isspace(*p); p++)
+                               continue;
+                           t = (*p == '\0') ? True : False;
                        }
                        if (doFree) {
                            free(val);
                        }
                        if (doFree) {
                            free(val);
@@ -993,12 +1022,13 @@ CondE(doEval)
  *
  *-----------------------------------------------------------------------
  */
  *
  *-----------------------------------------------------------------------
  */
+int
 Cond_Eval (line)
     char           *line;    /* Line to parse */
 {
     struct If      *ifp;
     Boolean        isElse;
 Cond_Eval (line)
     char           *line;    /* Line to parse */
 {
     struct If      *ifp;
     Boolean        isElse;
-    Boolean        value;
+    Boolean        value = FALSE;
     int                    level;      /* Level at which to report errors. */
 
     level = PARSE_FATAL;
     int                    level;      /* Level at which to report errors. */
 
     level = PARSE_FATAL;
@@ -1128,6 +1158,8 @@ Cond_Eval (line)
                Parse_Error (level, "Malformed conditional (%s)",
                             line);
                return (COND_INVALID);
                Parse_Error (level, "Malformed conditional (%s)",
                             line);
                return (COND_INVALID);
+           default:
+               break;
        }
     }
     if (!isElse) {
        }
     }
     if (!isElse) {
index 9bc0fe6..4ada928 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)config.h    5.9 (Berkeley) %G%
+ *     @(#)config.h    5.10 (Berkeley) %G%
  */
 
 #define        DEFSHELL        1                       /* Bourne shell */
  */
 
 #define        DEFSHELL        1                       /* Bourne shell */
@@ -59,4 +59,8 @@
  */
 #define        LIBSUFF ".a"
 #define        RECHECK
  */
 #define        LIBSUFF ".a"
 #define        RECHECK
+
+#ifndef RANLIBMAG
+#define RANLIBMAG "__.SYMDEF"
+#endif
 /*#define POSIX*/
 /*#define POSIX*/
index 0858fe9..f328049 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)dir.c      5.7 (Berkeley) %G%";
+static char sccsid[] = "@(#)dir.c      5.8 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -61,6 +61,7 @@ static char sccsid[] = "@(#)dir.c     5.7 (Berkeley) %G%";
 #include <sys/stat.h>
 #include "make.h"
 #include "hash.h"
 #include <sys/stat.h>
 #include "make.h"
 #include "hash.h"
+#include "dir.h"
 
 /*
  *     A search path consists of a Lst of Path structures. A Path structure
 
 /*
  *     A search path consists of a Lst of Path structures. A Path structure
@@ -145,14 +146,6 @@ static int    hits,              /* Found in directory cache */
              nearmisses,     /* Found under search path */
              bigmisses;      /* Sought by itself */
 
              nearmisses,     /* Found under search path */
              bigmisses;      /* Sought by itself */
 
-typedef struct Path {
-    char         *name;                /* Name of directory */
-    int                  refCount;     /* Number of paths with this directory */
-    int                  hits;         /* the number of times a file in this
-                                * directory has been found */
-    Hash_Table    files;       /* Hash table of files in directory */
-} Path;
-
 static Path              *dot;     /* contents of current directory */
 static Hash_Table mtimes;   /* Results of doing a last-resort stat in
                             * Dir_FindFile -- if we have to go to the
 static Path              *dot;     /* contents of current directory */
 static Hash_Table mtimes;   /* Results of doing a last-resort stat in
                             * Dir_FindFile -- if we have to go to the
@@ -165,6 +158,13 @@ static Hash_Table mtimes;   /* Results of doing a last-resort stat in
                             * should be ok, but... */
 
 
                             * should be ok, but... */
 
 
+static int DirFindName __P((Path *, char *));
+static int DirMatchFiles __P((char *, Path *, Lst));
+static void DirExpandCurly __P((char *, char *, Lst, Lst));
+static void DirExpandInt __P((char *, Lst, Lst));
+static int DirPrintWord __P((char *));
+static int DirPrintDir __P((Path *));
+
 /*-
  *-----------------------------------------------------------------------
  * Dir_Init --
 /*-
  *-----------------------------------------------------------------------
  * Dir_Init --
@@ -258,7 +258,7 @@ Dir_HasWildcards (name)
  *     Given a pattern and a Path structure, see if any files
  *     match the pattern and add their names to the 'expansions' list if
  *     any do. This is incomplete -- it doesn't take care of patterns like
  *     Given a pattern and a Path structure, see if any files
  *     match the pattern and add their names to the 'expansions' list if
  *     any do. This is incomplete -- it doesn't take care of patterns like
- *     src/*src/*.c properly (just *.c on any of the directories), but it
+ *     src / *src / *.c properly (just *.c on any of the directories), but it
  *     will do for now.
  *
  * Results:
  *     will do for now.
  *
  * Results:
@@ -277,7 +277,6 @@ DirMatchFiles (pattern, p, expansions)
 {
     Hash_Search          search;       /* Index into the directory's table */  
     Hash_Entry   *entry;       /* Current entry in the table */
 {
     Hash_Search          search;       /* Index into the directory's table */  
     Hash_Entry   *entry;       /* Current entry in the table */
-    char         *f;           /* Current entry in the directory */
     Boolean      isDot;        /* TRUE if the directory being searched is . */
     
     isDot = (*p->name == '.' && p->name[1] == '\0');
     Boolean      isDot;        /* TRUE if the directory being searched is . */
     
     isDot = (*p->name == '.' && p->name[1] == '\0');
@@ -500,11 +499,11 @@ Dir_Expand (word, path, expansions)
        printf("expanding \"%s\"...", word);
     }
     
        printf("expanding \"%s\"...", word);
     }
     
-    cp = index(word, '{');
+    cp = strchr(word, '{');
     if (cp) {
        DirExpandCurly(word, cp, path, expansions);
     } else {
     if (cp) {
        DirExpandCurly(word, cp, path, expansions);
     } else {
-       cp = index(word, '/');
+       cp = strchr(word, '/');
        if (cp) {
            /*
             * The thing has a directory component -- find the first wildcard
        if (cp) {
            /*
             * The thing has a directory component -- find the first wildcard
@@ -582,7 +581,7 @@ Dir_Expand (word, path, expansions)
     }
     if (DEBUG(DIR)) {
        Lst_ForEach(expansions, DirPrintWord, NULL);
     }
     if (DEBUG(DIR)) {
        Lst_ForEach(expansions, DirPrintWord, NULL);
-       putchar('\n');
+       fputc('\n', stdout);
     }
 }
 
     }
 }
 
@@ -623,7 +622,7 @@ Dir_FindFile (name, path)
      * Find the final component of the name and note whether it has a
      * slash in it (the name, I mean)
      */
      * Find the final component of the name and note whether it has a
      * slash in it (the name, I mean)
      */
-    cp = rindex (name, '/');
+    cp = strrchr (name, '/');
     if (cp) {
        hasSlash = TRUE;
        cp += 1;
     if (cp) {
        hasSlash = TRUE;
        cp += 1;
@@ -784,7 +783,7 @@ Dir_FindFile (name, path)
                 * again in such a manner, we will find it without having to do
                 * numerous numbers of access calls. Hurrah!
                 */
                 * again in such a manner, we will find it without having to do
                 * numerous numbers of access calls. Hurrah!
                 */
-               cp = rindex (file, '/');
+               cp = strrchr (file, '/');
                *cp = '\0';
                Dir_AddDir (path, file);
                *cp = '/';
                *cp = '\0';
                Dir_AddDir (path, file);
                *cp = '/';
@@ -797,7 +796,7 @@ Dir_FindFile (name, path)
                    printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                            file);
                }
                    printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                            file);
                }
-               entry = Hash_CreateEntry(&mtimes, (ClientData)file,
+               entry = Hash_CreateEntry(&mtimes, (char *) file,
                                         (Boolean *)NULL);
                Hash_SetValue(entry, stb.st_mtime);
                nearmisses += 1;
                                         (Boolean *)NULL);
                Hash_SetValue(entry, stb.st_mtime);
                nearmisses += 1;
@@ -933,7 +932,7 @@ Dir_MTime (gn)
         */
        if (DEBUG(DIR)) {
            printf("Using cached time %s for %s\n",
         */
        if (DEBUG(DIR)) {
            printf("Using cached time %s for %s\n",
-                   Targ_FmtTime(Hash_GetValue(entry)), fullName);
+                   Targ_FmtTime((time_t) Hash_GetValue(entry)), fullName);
        }
        stb.st_mtime = (time_t)Hash_GetValue(entry);
        Hash_DeleteEntry(&mtimes, entry);
        }
        stb.st_mtime = (time_t)Hash_GetValue(entry);
        Hash_DeleteEntry(&mtimes, entry);
@@ -977,8 +976,6 @@ Dir_AddDir (path, name)
     register Path *p;        /* pointer to new Path structure */
     DIR          *d;         /* for reading directory */
     register struct direct *dp; /* entry in directory */
     register Path *p;        /* pointer to new Path structure */
     DIR          *d;         /* for reading directory */
     register struct direct *dp; /* entry in directory */
-    Hash_Entry   *he;
-    char         *fName;
     
     ln = Lst_Find (openDirectories, (ClientData)name, DirFindName);
     if (ln != NILLNODE) {
     
     ln = Lst_Find (openDirectories, (ClientData)name, DirFindName);
     if (ln != NILLNODE) {
@@ -1112,9 +1109,6 @@ void
 Dir_Destroy (p)
     Path         *p;       /* The directory descriptor to nuke */
 {
 Dir_Destroy (p)
     Path         *p;       /* The directory descriptor to nuke */
 {
-    Hash_Search          thing1;
-    Hash_Entry   *thing2;
-    
     p->refCount -= 1;
 
     if (p->refCount == 0) {
     p->refCount -= 1;
 
     if (p->refCount == 0) {
@@ -1187,6 +1181,7 @@ Dir_Concat(path1, path2)
 }
 
 /********** DEBUG INFO **********/
 }
 
 /********** DEBUG INFO **********/
+void
 Dir_PrintDirectories()
 {
     LstNode    ln;
 Dir_PrintDirectories()
 {
     LstNode    ln;
@@ -1209,6 +1204,7 @@ Dir_PrintDirectories()
 
 static int DirPrintDir (p) Path *p; { printf ("%s ", p->name); return (0); }
 
 
 static int DirPrintDir (p) Path *p; { printf ("%s ", p->name); return (0); }
 
+void
 Dir_PrintPath (path)
     Lst        path;
 {
 Dir_PrintPath (path)
     Lst        path;
 {
index 0dca32b..293f820 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)hash.c     5.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)hash.c     5.6 (Berkeley) %G%";
 #endif /* not lint */
 
 /* hash.c --
 #endif /* not lint */
 
 /* hash.c --
@@ -21,8 +21,8 @@ static char sccsid[] = "@(#)hash.c    5.5 (Berkeley) %G%";
  *     table.  Hash tables grow automatically as the amount of
  *     information increases.
  */
  *     table.  Hash tables grow automatically as the amount of
  *     information increases.
  */
-
 #include "sprite.h"
 #include "sprite.h"
+#include "make.h"
 #include "hash.h"
 
 /*
 #include "hash.h"
 
 /*
@@ -30,7 +30,7 @@ static char sccsid[] = "@(#)hash.c    5.5 (Berkeley) %G%";
  * defined:
  */
 
  * defined:
  */
 
-static void            RebuildTable();
+static void RebuildTable __P((Hash_Table *));
 
 /* 
  * The following defines the ratio of # entries to # buckets
 
 /* 
  * The following defines the ratio of # entries to # buckets
@@ -74,7 +74,7 @@ Hash_InitTable(t, numBuckets)
                i = 16;
        else {
                for (i = 2; i < numBuckets; i <<= 1)
                i = 16;
        else {
                for (i = 2; i < numBuckets; i <<= 1)
-                        /* void */ ;
+                        continue;
        }
        t->numEntries = 0;
        t->size = i;
        }
        t->numEntries = 0;
        t->size = i;
@@ -106,7 +106,7 @@ void
 Hash_DeleteTable(t)
        Hash_Table *t;
 {
 Hash_DeleteTable(t)
        Hash_Table *t;
 {
-       register struct Hash_Entry **hp, *h, *nexth;
+       register struct Hash_Entry **hp, *h, *nexth = NULL;
        register int i;
 
        for (hp = t->bucketPtr, i = t->size; --i >= 0;) {
        register int i;
 
        for (hp = t->bucketPtr, i = t->size; --i >= 0;) {
@@ -367,7 +367,7 @@ static void
 RebuildTable(t)
        register Hash_Table *t;
 {
 RebuildTable(t)
        register Hash_Table *t;
 {
-       register Hash_Entry *e, *next, **hp, **xp;
+       register Hash_Entry *e, *next = NULL, **hp, **xp;
        register int i, mask;
         register Hash_Entry **oldhp;
        int oldsize;
        register int i, mask;
         register Hash_Entry **oldhp;
        int oldsize;
index 7156981..855ff7c 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)hash.h      5.4 (Berkeley) %G%
+ *     @(#)hash.h      5.5 (Berkeley) %G%
  */
 
 /* hash.h --
  */
 
 /* hash.h --
@@ -79,20 +79,12 @@ typedef struct Hash_Search {
 
 #define        Hash_Size(n)    (((n) + sizeof (int) - 1) / sizeof (int))
 
 
 #define        Hash_Size(n)    (((n) + sizeof (int) - 1) / sizeof (int))
 
-/*
- * The following procedure declarations and macros
- * are the only things that should be needed outside
- * the implementation code.
- */
+Hash_Entry     *Hash_CreateEntry __P((Hash_Table *, char *, Boolean *));
+void            Hash_DeleteEntry __P((Hash_Table *, Hash_Entry *));
+void            Hash_DeleteTable __P((Hash_Table *));
+Hash_Entry     *Hash_EnumFirst __P((Hash_Table *, Hash_Search *));
+Hash_Entry     *Hash_EnumNext __P((Hash_Search *));
+Hash_Entry     *Hash_FindEntry __P((Hash_Table *, char *));
+void            Hash_InitTable __P((Hash_Table *, int));
 
 
-extern Hash_Entry *    Hash_CreateEntry();
-extern void            Hash_DeleteTable();
-extern void            Hash_DeleteEntry();
-extern void            Hash_DeleteTable();
-extern Hash_Entry *    Hash_EnumFirst();
-extern Hash_Entry *    Hash_EnumNext();
-extern Hash_Entry *    Hash_FindEntry();
-extern void            Hash_InitTable();
-extern void            Hash_PrintStats();
-
-#endif _HASH
+#endif /* _HASH */
index 72867cb..d8b56a6 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)job.c      5.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)job.c      5.18 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -70,16 +70,20 @@ static char sccsid[] = "@(#)job.c   5.17 (Berkeley) %G%";
  *     Job_Wait                Wait for all currently-running jobs to finish.
  */
 
  *     Job_Wait                Wait for all currently-running jobs to finish.
  */
 
-#include "make.h"
+#include <sys/types.h>
+#include <sys/signal.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/wait.h>
-#include <signal.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
+#include <signal.h>
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
 #include "job.h"
 #include "pathnames.h"
 
 #include "job.h"
 #include "pathnames.h"
 
@@ -88,8 +92,8 @@ extern int  errno;
 /*
  * error handling variables 
  */
 /*
  * error handling variables 
  */
-int            errors = 0;         /* number of errors reported */
-int            aborting = 0;       /* why is the make aborting? */
+static int             errors = 0;         /* number of errors reported */
+static int     aborting = 0;       /* why is the make aborting? */
 #define ABORT_ERROR    1           /* Because of an error */
 #define ABORT_INTERRUPT        2           /* Because it was interrupted */
 #define ABORT_WAIT     3           /* Waiting for jobs to finish */
 #define ABORT_ERROR    1           /* Because of an error */
 #define ABORT_INTERRUPT        2           /* Because it was interrupted */
 #define ABORT_WAIT     3           /* Waiting for jobs to finish */
@@ -159,22 +163,22 @@ static Shell    shells[] = {
     (char *)0, (char *)0,
 }
 };
     (char *)0, (char *)0,
 }
 };
-Shell          *commandShell = &shells[DEFSHELL]; /* this is the shell to
+static Shell   *commandShell = &shells[DEFSHELL];/* this is the shell to
                                                   * which we pass all
                                                   * commands in the Makefile.
                                                   * It is set by the
                                                   * Job_ParseShell function */
                                                   * which we pass all
                                                   * commands in the Makefile.
                                                   * It is set by the
                                                   * Job_ParseShell function */
-char           *shellPath = (char *) NULL,       /* full pathname of
+static char    *shellPath = (char *) NULL,       /* full pathname of
                                                   * executable image */
                        *shellName;                       /* last component of shell */
 
 
 static int     maxJobs;        /* The most children we can run at once */
 static int     maxLocal;       /* The most local ones we can have */
                                                   * executable image */
                        *shellName;                       /* last component of shell */
 
 
 static int     maxJobs;        /* The most children we can run at once */
 static int     maxLocal;       /* The most local ones we can have */
-int            nJobs;          /* The number of children currently running */
-int            nLocal;         /* The number of local children */
-Lst            jobs;           /* The structures that describe them */
-Boolean                jobFull;        /* Flag to tell when the job table is full. It
+static int             nJobs;          /* The number of children currently running */
+static int     nLocal;         /* The number of local children */
+static Lst             jobs;           /* The structures that describe them */
+static Boolean jobFull;        /* Flag to tell when the job table is full. It
                                 * is set TRUE when (1) the total number of
                                 * running jobs equals the maximum allowed or
                                 * (2) a job can only be run locally, but
                                 * is set TRUE when (1) the total number of
                                 * running jobs equals the maximum allowed or
                                 * (2) a job can only be run locally, but
@@ -184,9 +188,9 @@ static fd_set       outputs;        /* Set of descriptors of pipes connected to
                                 * the output channels of children */
 #endif
 
                                 * the output channels of children */
 #endif
 
-GNode          *lastNode;      /* The node for which output was most recently
+static GNode           *lastNode;      /* The node for which output was most recently
                                 * produced. */
                                 * produced. */
-char           *targFmt;       /* Format string to use to head output from a
+static char            *targFmt;       /* Format string to use to head output from a
                                 * job when it's not the most-recent job heard
                                 * from */
 #define TARG_FMT  "--- %s ---\n" /* Default format */
                                 * job when it's not the most-recent job heard
                                 * from */
 #define TARG_FMT  "--- %s ---\n" /* Default format */
@@ -197,20 +201,34 @@ char              *targFmt;       /* Format string to use to head output from a
  * been migrated home, the job is placed on the stoppedJobs queue to be run
  * when the next job finishes. 
  */
  * been migrated home, the job is placed on the stoppedJobs queue to be run
  * when the next job finishes. 
  */
-Lst        stoppedJobs;        /* Lst of Job structures describing
+static Lst    stoppedJobs;     /* Lst of Job structures describing
                                 * jobs that were stopped due to concurrency
                                 * limits or migration home */
 
 
                                 * jobs that were stopped due to concurrency
                                 * limits or migration home */
 
 
+#if defined(USE_PGRP) && defined(SYSV)
+#define KILL(pid,sig)  killpg (-(pid),(sig))
+#else
 # if defined(USE_PGRP)
 # if defined(USE_PGRP)
-#define KILL(pid,sig)  killpg((pid),(sig))
+#define KILL(pid,sig)  killpg ((pid),(sig))
 # else
 # else
-#define KILL(pid,sig)  kill((pid),(sig))
+#define KILL(pid,sig)  kill ((pid),(sig))
 # endif
 # endif
+#endif
 
 
-static void JobRestart();
-static int  JobStart();
-static void JobInterrupt();
+static int JobCondPassSig __P((Job *, int));
+static void JobPassSig __P((int));
+static int JobCmpPid __P((Job *, int));
+static int JobPrintCommand __P((char *, Job *));
+static int JobSaveCommand __P((char *, GNode *));
+static void JobFinish __P((Job *, union wait));
+static void JobExec __P((Job *, char **));
+static void JobMakeArgv __P((Job *, char **));
+static void JobRestart __P((Job *));
+static int JobStart __P((GNode *, int, Job *));
+static void JobDoOutput __P((Job *, Boolean));
+static Shell *JobMatchShell __P((char *));
+static void JobInterrupt __P((int));
 
 /*-
  *-----------------------------------------------------------------------
 
 /*-
  *-----------------------------------------------------------------------
@@ -284,7 +302,7 @@ JobPassSig(signo)
      * Leave gracefully if SIGQUIT, rather than core dumping.
      */
     if (signo == SIGQUIT) {
      * Leave gracefully if SIGQUIT, rather than core dumping.
      */
     if (signo == SIGQUIT) {
-       Finish();
+       Finish(0);
     }
     
     /*
     }
     
     /*
@@ -376,6 +394,7 @@ JobPrintCommand (cmd, job)
     noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
 
     if (strcmp (cmd, "...") == 0) {
     noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
 
     if (strcmp (cmd, "...") == 0) {
+       job->node->type |= OP_SAVE_CMDS; 
        if ((job->flags & JOB_IGNDOTS) == 0) {
            job->tailCmds = Lst_Succ (Lst_Member (job->node->commands,
                                                  (ClientData)cmd));
        if ((job->flags & JOB_IGNDOTS) == 0) {
            job->tailCmds = Lst_Succ (Lst_Member (job->node->commands,
                                                  (ClientData)cmd));
@@ -393,7 +412,7 @@ JobPrintCommand (cmd, job)
      * the variables in the command.
      */
     cmdNode = Lst_Member (job->node->commands, (ClientData)cmd);
      * the variables in the command.
      */
     cmdNode = Lst_Member (job->node->commands, (ClientData)cmd);
-    cmdStart = cmd = Var_Subst (cmd, job->node, FALSE);
+    cmdStart = cmd = Var_Subst (NULL, cmd, job->node, FALSE);
     Lst_Replace (cmdNode, (ClientData)cmdStart);
 
     cmdTemplate = "%s\n";
     Lst_Replace (cmdNode, (ClientData)cmdStart);
 
     cmdTemplate = "%s\n";
@@ -510,7 +529,7 @@ JobSaveCommand (cmd, gn)
     char    *cmd;
     GNode   *gn;
 {
     char    *cmd;
     GNode   *gn;
 {
-    cmd = Var_Subst (cmd, gn, FALSE);
+    cmd = Var_Subst (NULL, cmd, gn, FALSE);
     (void)Lst_AtEnd (postCommands->commands, (ClientData)cmd);
     return (0);
 }
     (void)Lst_AtEnd (postCommands->commands, (ClientData)cmd);
     return (0);
 }
@@ -539,7 +558,7 @@ JobSaveCommand (cmd, gn)
  *-----------------------------------------------------------------------
  */
 /*ARGSUSED*/
  *-----------------------------------------------------------------------
  */
 /*ARGSUSED*/
-void
+static void
 JobFinish (job, status)
     Job           *job;                  /* job to finish */
     union wait   status;         /* sub-why job went away */
 JobFinish (job, status)
     Job           *job;                  /* job to finish */
     union wait   status;         /* sub-why job went away */
@@ -790,7 +809,6 @@ Job_Touch (gn, silent)
 {
     int                  streamID;     /* ID of stream opened to do the touch */
     struct timeval times[2];   /* Times for utimes() call */
 {
     int                  streamID;     /* ID of stream opened to do the touch */
     struct timeval times[2];   /* Times for utimes() call */
-    struct stat attr;        /* Attributes of the file */
 
     if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
        /*
 
     if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
        /*
@@ -856,7 +874,8 @@ Boolean
 Job_CheckCommands (gn, abortProc)
     GNode          *gn;                    /* The target whose commands need
                                     * verifying */
 Job_CheckCommands (gn, abortProc)
     GNode          *gn;                    /* The target whose commands need
                                     * verifying */
-    void         (*abortProc)();   /* Function to abort with message */
+    void         (*abortProc) __P((const char *, ...));   
+                       /* Function to abort with message */
 {
     if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
        (gn->type & OP_LIB) == 0) {
 {
     if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
        (gn->type & OP_LIB) == 0) {
@@ -1046,7 +1065,7 @@ JobExec(job, argv)
        }
 
        if (job->flags & JOB_REMOTE) {
        }
 
        if (job->flags & JOB_REMOTE) {
-           job->rmtID = (char *)0;
+           job->rmtID = 0;
        } else {
            nLocal += 1;
            /*
        } else {
            nLocal += 1;
            /*
@@ -1059,7 +1078,9 @@ JobExec(job, argv)
        }
     }
 
        }
     }
 
+#ifdef RMT_NO_EXEC
 jobExecFinish:    
 jobExecFinish:    
+#endif
     /*
      * Now the job is actually running, add it to the table.
      */
     /*
      * Now the job is actually running, add it to the table.
      */
@@ -1317,7 +1338,6 @@ JobStart (gn, flags, previous)
 {
     register Job  *job;       /* new job descriptor */
     char         *argv[4];   /* Argument vector to shell */
 {
     register Job  *job;       /* new job descriptor */
     char         *argv[4];   /* Argument vector to shell */
-    char          args[5];    /* arguments to shell */
     static int    jobno = 0;  /* job number of catching output in a file */
     Boolean      cmdsOK;     /* true if the nodes commands were all right */
     Boolean      local;      /* Set true if the job was run locally */
     static int    jobno = 0;  /* job number of catching output in a file */
     Boolean      cmdsOK;     /* true if the nodes commands were all right */
     Boolean      local;      /* Set true if the job was run locally */
@@ -1391,7 +1411,7 @@ JobStart (gn, flags, previous)
         * used to be backwards; replace when start doing multiple commands
         * per shell.
         */
         * used to be backwards; replace when start doing multiple commands
         * per shell.
         */
-       if (1) {
+       if (compatMake) {
            /*
             * Be compatible: If this is the first time for this node,
             * verify its commands are ok and open the commands list for
            /*
             * Be compatible: If this is the first time for this node,
             * verify its commands are ok and open the commands list for
@@ -1621,7 +1641,7 @@ JobStart (gn, flags, previous)
  *     curPos may be shifted as may the contents of outBuf.
  *-----------------------------------------------------------------------
  */
  *     curPos may be shifted as may the contents of outBuf.
  *-----------------------------------------------------------------------
  */
-void
+static void
 JobDoOutput (job, finish)
     register Job   *job;         /* the job whose output needs printing */
     Boolean       finish;        /* TRUE if this is the last time we'll be
 JobDoOutput (job, finish)
     register Job   *job;         /* the job whose output needs printing */
     Boolean       finish;        /* TRUE if this is the last time we'll be
@@ -1633,7 +1653,6 @@ JobDoOutput (job, finish)
     register int  max;           /* limit for i (end of current data) */
     int                  nRead;          /* (Temporary) number of bytes read */
 
     register int  max;           /* limit for i (end of current data) */
     int                  nRead;          /* (Temporary) number of bytes read */
 
-    char          c;             /* character after noPrint string */
     FILE         *oFILE;         /* Stream pointer to shell's output file */
     char          inLine[132];
 
     FILE         *oFILE;         /* Stream pointer to shell's output file */
     char          inLine[132];
 
@@ -1767,9 +1786,8 @@ end_loop:
                fflush (stdout);
            }
            if (i < max - 1) {
                fflush (stdout);
            }
            if (i < max - 1) {
-               bcopy (&job->outBuf[i + 1], /* shift the remaining */
-                      job->outBuf,        /* characters down */
-                      max - (i + 1));
+               /* shift the remaining characters down */
+               memcpy ( job->outBuf, &job->outBuf[i + 1], max - (i + 1));
                job->curPos = max - (i + 1);
                
            } else {
                job->curPos = max - (i + 1);
                
            } else {
@@ -1955,7 +1973,9 @@ Job_CatchOutput ()
     fd_set               readfds;
     register LstNode     ln;
     register Job         *job;
     fd_set               readfds;
     register LstNode     ln;
     register Job         *job;
+#ifdef RMT_WILL_WATCH
     int                          pnJobs;       /* Previous nJobs */
     int                          pnJobs;       /* Previous nJobs */
+#endif
 
     fflush(stdout);
 #ifdef RMT_WILL_WATCH
 
     fflush(stdout);
 #ifdef RMT_WILL_WATCH
@@ -1986,7 +2006,7 @@ Job_CatchOutput ()
        timeout.tv_sec = SEL_SEC;
        timeout.tv_usec = SEL_USEC;
 
        timeout.tv_sec = SEL_SEC;
        timeout.tv_usec = SEL_USEC;
 
-       if ((nfds = select (FD_SETSIZE, &readfds, (int *) 0, (int *) 0, &timeout)) < 0)
+       if ((nfds = select (FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0)
        {
            return;
        } else {
        {
            return;
        } else {
@@ -2304,7 +2324,7 @@ Job_ParseShell (line)
     }
     words = brk_string (line, &wordCount);
 
     }
     words = brk_string (line, &wordCount);
 
-    bzero ((Address)&newShell, sizeof(newShell));
+    memset ((Address)&newShell, 0, sizeof(newShell));
     
     /*
      * Parse the specification by keyword
     
     /*
      * Parse the specification by keyword
@@ -2368,7 +2388,7 @@ Job_ParseShell (line)
         * path the user gave for the shell.
         */
        shellPath = path;
         * path the user gave for the shell.
         */
        shellPath = path;
-       path = rindex (path, '/');
+       path = strrchr (path, '/');
        if (path == (char *)NULL) {
            path = shellPath;
        } else {
        if (path == (char *)NULL) {
            path = shellPath;
        } else {
@@ -2429,8 +2449,7 @@ JobInterrupt (runINTERRUPT)
     LstNode      ln;           /* element in job table */
     Job           *job;                /* job descriptor in that element */
     GNode         *interrupt;  /* the node describing the .INTERRUPT target */
     LstNode      ln;           /* element in job table */
     Job           *job;                /* job descriptor in that element */
     GNode         *interrupt;  /* the node describing the .INTERRUPT target */
-    struct stat sb;
-
+    
     aborting = ABORT_INTERRUPT;
 
     (void)Lst_Open (jobs);
     aborting = ABORT_INTERRUPT;
 
     (void)Lst_Open (jobs);
@@ -2441,8 +2460,7 @@ JobInterrupt (runINTERRUPT)
            char        *file = (job->node->path == (char *)NULL ?
                                 job->node->name :
                                 job->node->path);
            char        *file = (job->node->path == (char *)NULL ?
                                 job->node->name :
                                 job->node->path);
-           if (!stat(file, &sb) && S_ISREG(sb.st_mode) &&
-               unlink(file) == 0) {
+           if (unlink (file) == 0) {
                Error ("*** %s removed", file);
            }
        }
                Error ("*** %s removed", file);
            }
        }
@@ -2605,8 +2623,7 @@ Job_AbortAll ()
     /*
      * Catch as many children as want to report in at first, then give up
      */
     /*
      * Catch as many children as want to report in at first, then give up
      */
-    while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0) {
-       ;
-    }
+    while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0)
+       continue;
     (void) unlink (tfile);
 }
     (void) unlink (tfile);
 }
index 14d2f82..cc9bbf8 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)job.h       5.3 (Berkeley) %G%
+ *     @(#)job.h       5.4 (Berkeley) %G%
  */
 
 /*-
  */
 
 /*-
@@ -71,7 +71,7 @@ typedef struct Job {
                             * saved when the job has been run */
     FILE       *cmdFILE;   /* When creating the shell script, this is
                             * where the commands go */
                             * saved when the job has been run */
     FILE       *cmdFILE;   /* When creating the shell script, this is
                             * where the commands go */
-    char       *rmtID;     /* ID returned from Rmt module */
+    int        rmtID;     /* ID returned from Rmt module */
     short              flags;      /* Flags to control treatment of job */
 #define        JOB_IGNERR      0x001   /* Ignore non-zero exits */
 #define        JOB_SILENT      0x002   /* no output */
     short              flags;      /* Flags to control treatment of job */
 #define        JOB_IGNERR      0x001   /* Ignore non-zero exits */
 #define        JOB_SILENT      0x002   /* no output */
@@ -189,18 +189,19 @@ extern Lst        stoppedJobs;    /* List of jobs that are stopped or didn't
                                 * quite get started */
 extern Boolean jobFull;        /* Non-zero if no more jobs should/will start*/
 
                                 * quite get started */
 extern Boolean jobFull;        /* Non-zero if no more jobs should/will start*/
 
-/*
- * These functions should be used only by an intelligent Rmt module, hence
- * their names do *not* include an underscore as they are not fully exported,
- * if you see what I mean.
- */
-extern void    JobDoOutput(/* job, final? */); /* Funnel output from
-                                                * job->outPipe to the screen,
-                                                * filtering out echo-off
-                                                * strings etc. */
-extern void    JobFinish(/* job, status */);   /* Finish out a job. If
-                                                * status indicates job has
-                                                * just stopped, not finished,
-                                                * the descriptor is placed on
-                                                * the stoppedJobs list. */
+void           JobFlagForMigration __P((int));
+void           Job_AbortAll __P((void));
+void           Job_CatchChildren __P((Boolean));
+void           Job_CatchOutput __P((void));
+Boolean                Job_CheckCommands __P((GNode *,
+                   void (*abortProc )(const char *, ...)));
+Boolean                Job_Empty __P((void));
+int            Job_End __P((void));
+Boolean                Job_Full __P((void));
+void           Job_Init __P((int, int));
+void           Job_Make __P((GNode *));
+ReturnStatus   Job_ParseShell __P((char *));
+void           Job_Touch __P((GNode *, Boolean));
+void           Job_Wait __P((void));
+
 #endif /* _JOB_H_ */
 #endif /* _JOB_H_ */
index 2ad60d9..9c7358e 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)list.h      5.3 (Berkeley) %G%
+ *     @(#)list.h      5.4 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -269,4 +269,4 @@ void        List_Move();    /* move an element elsewhere in a list */
 
 #define LIST_ATREAR(headerPtr) (((List_Links *) headerPtr)->prevPtr)
 
 
 #define LIST_ATREAR(headerPtr) (((List_Links *) headerPtr)->prevPtr)
 
-#endif _LIST
+#endif /* _LIST */
index df9a584..3a8cac2 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)lst.h       5.3 (Berkeley) %G%
+ *     @(#)lst.h       5.4 (Berkeley) %G%
  */
 
 /*-
  */
 
 /*-
@@ -20,6 +20,9 @@
 #define _LST_H_
 
 #include       <sprite.h>
 #define _LST_H_
 
 #include       <sprite.h>
+#if __STDC__
+#include       <stdlib.h>
+#endif
 
 /*
  * basic typedef. This is what the Lst_ functions handle
 
 /*
  * basic typedef. This is what the Lst_ functions handle
index a19cf5c..b544c27 100644 (file)
@@ -17,7 +17,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.29 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     5.30 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -47,14 +47,24 @@ static char sccsid[] = "@(#)main.c  5.29 (Berkeley) %G%";
  *                             exiting.
  */
 
  *                             exiting.
  */
 
+#include <sys/types.h>
+#include <sys/time.h>
 #include <sys/param.h>
 #include <sys/param.h>
+#include <sys/resource.h>
 #include <sys/signal.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/signal.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
 #include <varargs.h>
 #include <varargs.h>
+#endif
 #include "make.h"
 #include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
 #include "pathnames.h"
 
 #ifndef        DEFMAXLOCAL
 #include "pathnames.h"
 
 #ifndef        DEFMAXLOCAL
@@ -72,6 +82,7 @@ static Boolean                noBuiltins;     /* -r flag */
 static Lst             makefiles;      /* ordered list of makefiles to read */
 int                    maxJobs;        /* -J argument */
 static int             maxLocal;       /* -L argument */
 static Lst             makefiles;      /* ordered list of makefiles to read */
 int                    maxJobs;        /* -J argument */
 static int             maxLocal;       /* -L argument */
+Boolean                        compatMake;     /* -B argument */
 Boolean                        debug;          /* -d flag */
 Boolean                        noExecute;      /* -n flag */
 Boolean                        keepgoing;      /* -k flag */
 Boolean                        debug;          /* -d flag */
 Boolean                        noExecute;      /* -n flag */
 Boolean                        keepgoing;      /* -k flag */
@@ -85,6 +96,7 @@ Boolean                       checkEnvFirst;  /* -e flag */
 static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
 
 static Boolean         ReadMakefile();
 static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
 
 static Boolean         ReadMakefile();
+static void            usage();
 
 static char *curdir;                   /* if chdir'd for an architecture */
 
 
 static char *curdir;                   /* if chdir'd for an architecture */
 
@@ -109,11 +121,15 @@ MainParseArgs(argc, argv)
 {
        extern int optind;
        extern char *optarg;
 {
        extern int optind;
        extern char *optarg;
-       register char *cp;
-       int c;
+       char c;
 
        optind = 1;     /* since we're called more than once */
 
        optind = 1;     /* since we're called more than once */
-rearg: while((c = getopt(argc, argv, "D:I:d:ef:ij:knqrst")) != EOF) {
+#ifdef notyet
+# define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
+#else
+# define OPTFLAGS "D:I:d:ef:ij:knqrst"
+#endif
+rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                switch(c) {
                case 'D':
                        Var_Set(optarg, "1", VAR_GLOBAL);
                switch(c) {
                case 'D':
                        Var_Set(optarg, "1", VAR_GLOBAL);
@@ -125,7 +141,10 @@ rearg:     while((c = getopt(argc, argv, "D:I:d:ef:ij:knqrst")) != EOF) {
                        Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                        break;
                        Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                        break;
-#ifdef notdef
+#ifdef notyet
+               case 'B':
+                       compatMake = TRUE;
+                       break;
                case 'L':
                        maxLocal = atoi(optarg);
                        Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
                case 'L':
                        maxLocal = atoi(optarg);
                        Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
@@ -157,6 +176,9 @@ rearg:      while((c = getopt(argc, argv, "D:I:d:ef:ij:knqrst")) != EOF) {
                                case 'd':
                                        debug |= DEBUG_DIR;
                                        break;
                                case 'd':
                                        debug |= DEBUG_DIR;
                                        break;
+                               case 'f':
+                                       debug |= DEBUG_FOR;
+                                       break;
                                case 'g':
                                        if (modules[1] == '1') {
                                                debug |= DEBUG_GRAPH1;
                                case 'g':
                                        if (modules[1] == '1') {
                                                debug |= DEBUG_GRAPH1;
@@ -250,7 +272,7 @@ rearg:      while((c = getopt(argc, argv, "D:I:d:ef:ij:knqrst")) != EOF) {
                if (Parse_IsVar(*argv))
                        Parse_DoVar(*argv, VAR_CMD);
                else {
                if (Parse_IsVar(*argv))
                        Parse_DoVar(*argv, VAR_CMD);
                else {
-                       if (!*argv[0] || *argv[0] == '-' && !(*argv)[1])
+                       if (!**argv)
                                Punt("illegal (null) argument.");
                        if (**argv == '-') {
                                optind = 0;
                                Punt("illegal (null) argument.");
                        if (**argv == '-') {
                                optind = 0;
@@ -284,7 +306,8 @@ Main_ParseArgLine(line)
 
        if (line == NULL)
                return;
 
        if (line == NULL)
                return;
-       for (; *line == ' '; ++line);
+       for (; *line == ' '; ++line)
+               continue;
        if (!*line)
                return;
 
        if (!*line)
                return;
 
@@ -309,14 +332,37 @@ Main_ParseArgLine(line)
  * Side Effects:
  *     The program exits when done. Targets are created. etc. etc. etc.
  */
  * Side Effects:
  *     The program exits when done. Targets are created. etc. etc. etc.
  */
+int
 main(argc, argv)
        int argc;
        char **argv;
 {
        Lst targs;      /* target nodes to create -- passed to Make_Init */
 main(argc, argv)
        int argc;
        char **argv;
 {
        Lst targs;      /* target nodes to create -- passed to Make_Init */
-       Boolean outOfDate;      /* FALSE if all targets up to date */
-       struct stat sb;
-       char *p, *path, *getenv();
+       Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
+       struct stat sb, sa;
+       char *p, *path, *pwd, *getenv();
+
+       /*
+        * Find where we are and take care of PWD for the automounter...
+        */
+       curdir = emalloc((u_int)MAXPATHLEN + 1);
+       if (!getwd(curdir)) {
+               (void)fprintf(stderr, "make: %s.\n", curdir);
+               exit(2);
+       }
+
+       if (stat(curdir, &sa) == -1) {
+           (void)fprintf(stderr, "make: %s: %s.\n",
+                         curdir, strerror(errno));
+           exit(2);
+       }
+
+       if ((pwd = getenv("PWD")) != NULL) {
+           if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
+               sa.st_dev == sb.st_dev) 
+               (void) strcpy(curdir, pwd);
+       }
+
 
        /*
         * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
 
        /*
         * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
@@ -327,23 +373,24 @@ main(argc, argv)
         */
        if (!(path = getenv("MAKEOBJDIR")))
                path = _PATH_OBJDIR;
         */
        if (!(path = getenv("MAKEOBJDIR")))
                path = _PATH_OBJDIR;
-       if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode) &&
-           lstat(path, &sb) == 0) {
-               if (S_ISDIR(sb.st_mode))
-                       curdir = "..";
-               else {
-                       curdir = emalloc((u_int)MAXPATHLEN + 1);
-                       if (!getwd(curdir)) {
-                               (void)fprintf(stderr, "make: %s.\n", curdir);
-                               exit(2);
-                       }
-               }
+       
+       if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+
                if (chdir(path)) {
                        (void)fprintf(stderr, "make: %s: %s.\n",
                            path, strerror(errno));
                        exit(2);
                }
                if (chdir(path)) {
                        (void)fprintf(stderr, "make: %s: %s.\n",
                            path, strerror(errno));
                        exit(2);
                }
+               if (path[0] != '/') {
+                       char cwd[MAXPATHLEN];
+                       (void) sprintf(cwd, "%s/%s", curdir, path);
+                       setenv("PWD", cwd, 1);
+               }
+               else
+                       setenv("PWD", path, 1);
        }
        }
+       else 
+               setenv("PWD", curdir, 1);
 
        create = Lst_Init(FALSE);
        makefiles = Lst_Init(FALSE);
 
        create = Lst_Init(FALSE);
        makefiles = Lst_Init(FALSE);
@@ -361,7 +408,13 @@ main(argc, argv)
 
        maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
        maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
 
        maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
        maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
+#ifdef notyet
+       compatMake = FALSE;             /* No compat mode */
+#else
+       compatMake = TRUE;              /* No compat mode */
+#endif
     
     
+
        /*
         * Initialize the parsing, directory and variable modules to prepare
         * for the reading of inclusion paths and variable settings on the
        /*
         * Initialize the parsing, directory and variable modules to prepare
         * for the reading of inclusion paths and variable settings on the
@@ -373,12 +426,11 @@ main(argc, argv)
                                 * directories */
        Var_Init();             /* As well as the lists of variables for
                                 * parsing arguments */
                                 * directories */
        Var_Init();             /* As well as the lists of variables for
                                 * parsing arguments */
-
        if (curdir) {
                Dir_AddDir(dirSearchPath, curdir);
                Var_Set(".CURDIR", curdir, VAR_GLOBAL);
        if (curdir) {
                Dir_AddDir(dirSearchPath, curdir);
                Var_Set(".CURDIR", curdir, VAR_GLOBAL);
-       } else
-               Var_Set(".CURDIR", ".", VAR_GLOBAL);
+       }
+       Var_Set(".OBJDIR", path, VAR_GLOBAL);
 
        /*
         * Initialize various variables.
 
        /*
         * Initialize various variables.
@@ -454,7 +506,7 @@ main(argc, argv)
        Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
 
        /* Install all the flags into the MAKE envariable. */
        Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
 
        /* Install all the flags into the MAKE envariable. */
-       if ((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) && *p)
+       if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
 #ifdef POSIX
                setenv("MAKEFLAGS", p, 1);
 #else
 #ifdef POSIX
                setenv("MAKEFLAGS", p, 1);
 #else
@@ -476,11 +528,12 @@ main(argc, argv)
                 */
                static char VPATH[] = "${VPATH}";
 
                 */
                static char VPATH[] = "${VPATH}";
 
-               vpath = Var_Subst(VPATH, VAR_CMD, FALSE);
+               vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
                path = vpath;
                do {
                        /* skip to end of directory */
                path = vpath;
                do {
                        /* skip to end of directory */
-                       for (cp = path; *cp != ':' && *cp != '\0'; cp++);
+                       for (cp = path; *cp != ':' && *cp != '\0'; cp++)
+                               continue;
                        /* Save terminator character so know when to stop */
                        savec = *cp;
                        *cp = '\0';
                        /* Save terminator character so know when to stop */
                        savec = *cp;
                        *cp = '\0';
@@ -516,7 +569,7 @@ main(argc, argv)
  * this was original amMake -- want to allow parallelism, so put this
  * back in, eventually.
  */
  * this was original amMake -- want to allow parallelism, so put this
  * back in, eventually.
  */
-       if (0) {
+       if (!compatMake) {
                /*
                 * Initialize job module before traversing the graph, now that
                 * any .BEGIN and .END targets have been read.  This is done
                /*
                 * Initialize job module before traversing the graph, now that
                 * any .BEGIN and .END targets have been read.  This is done
@@ -544,9 +597,9 @@ main(argc, argv)
                Targ_PrintGraph(2);
 
        if (queryFlag && outOfDate)
                Targ_PrintGraph(2);
 
        if (queryFlag && outOfDate)
-               exit(1);
+               return(1);
        else
        else
-               exit(0);
+               return(0);
 }
 
 /*-
 }
 
 /*-
@@ -571,12 +624,12 @@ ReadMakefile(fname)
                Parse_File("(stdin)", stdin);
                Var_Set("MAKEFILE", "", VAR_GLOBAL);
        } else {
                Parse_File("(stdin)", stdin);
                Var_Set("MAKEFILE", "", VAR_GLOBAL);
        } else {
-               if (stream = fopen(fname, "r"))
+               if ((stream = fopen(fname, "r")) != NULL)
                        goto found;
                /* if we've chdir'd, rebuild the path name */
                if (curdir && *fname != '/') {
                        (void)sprintf(path, "%s/%s", curdir, fname);
                        goto found;
                /* if we've chdir'd, rebuild the path name */
                if (curdir && *fname != '/') {
                        (void)sprintf(path, "%s/%s", curdir, fname);
-                       if (stream = fopen(path, "r")) {
+                       if ((stream = fopen(path, "r")) != NULL) {
                                fname = path;
                                goto found;
                        }
                                fname = path;
                                goto found;
                        }
@@ -612,14 +665,20 @@ found:            Var_Set("MAKEFILE", fname, VAR_GLOBAL);
  */
 /* VARARGS */
 void
  */
 /* VARARGS */
 void
-Error(va_alist)
+#if __STDC__
+Error(const char *fmt, ...)
+#else
+Error(fmt, va_alist)
+       char *fmt;
        va_dcl
        va_dcl
+#endif
 {
        va_list ap;
 {
        va_list ap;
-       char *fmt;
-
+#if __STDC__
+       va_start(ap, fmt);
+#else
        va_start(ap);
        va_start(ap);
-       fmt = va_arg(ap, char *);
+#endif
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
@@ -639,17 +698,23 @@ Error(va_alist)
  */
 /* VARARGS */
 void
  */
 /* VARARGS */
 void
-Fatal(va_alist)
+#if __STDC__
+Fatal(const char *fmt, ...)
+#else
+Fatal(fmt, va_alist)
+       char *fmt;
        va_dcl
        va_dcl
+#endif
 {
        va_list ap;
 {
        va_list ap;
-       char *fmt;
-
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
        if (jobsRunning)
                Job_Wait();
 
        if (jobsRunning)
                Job_Wait();
 
-       va_start(ap);
-       fmt = va_arg(ap, char *);
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
@@ -673,15 +738,21 @@ Fatal(va_alist)
  */
 /* VARARGS */
 void
  */
 /* VARARGS */
 void
-Punt(va_alist)
+#if __STDC__
+Punt(const char *fmt, ...)
+#else
+Punt(fmt, va_alist)
+       char *fmt;
        va_dcl
        va_dcl
+#endif
 {
        va_list ap;
 {
        va_list ap;
-       char *fmt;
-
-       (void)fprintf(stderr, "make: ");
+#if __STDC__
+       va_start(ap, fmt);
+#else
        va_start(ap);
        va_start(ap);
-       fmt = va_arg(ap, char *);
+#endif
+       (void)fprintf(stderr, "make: ");
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
@@ -736,7 +807,7 @@ char *
 emalloc(len)
        u_int len;
 {
 emalloc(len)
        u_int len;
 {
-       char *p, *malloc();
+       char *p;
 
        if (!(p = malloc(len)))
                enomem();
 
        if (!(p = malloc(len)))
                enomem();
@@ -747,6 +818,7 @@ emalloc(len)
  * enomem --
  *     die when out of memory.
  */
  * enomem --
  *     die when out of memory.
  */
+void
 enomem()
 {
        (void)fprintf(stderr, "make: %s.\n", strerror(errno));
 enomem()
 {
        (void)fprintf(stderr, "make: %s.\n", strerror(errno));
@@ -757,6 +829,7 @@ enomem()
  * usage --
  *     exit with usage message
  */
  * usage --
  *     exit with usage message
  */
+static void
 usage()
 {
        (void)fprintf(stderr,
 usage()
 {
        (void)fprintf(stderr,
index 3d3aacb..d2f4872 100644 (file)
@@ -3,7 +3,7 @@
 .\"
 .\" %sccs.include.redist.roff%
 .\"
 .\"
 .\" %sccs.include.redist.roff%
 .\"
-.\"    @(#)make.1      5.7 (Berkeley) %G%
+.\"    @(#)make.1      5.8 (Berkeley) %G%
 .\"
 .Dd 
 .Dt MAKE 1
 .\"
 .Dd 
 .Dt MAKE 1
@@ -136,9 +136,9 @@ to
 .Ar value .
 .El
 .Pp
 .Ar value .
 .El
 .Pp
-There are six different types of lines in a makefile: file dependency
+There are seven different types of lines in a makefile: file dependency
 specifications, shell commands, variable assignments, include statements,
 specifications, shell commands, variable assignments, include statements,
-conditional directives, and comments.
+conditional directives, for loops, and comments.
 .Pp
 In general, lines may be continued from one line to the next by ending
 them with a backslash
 .Pp
 In general, lines may be continued from one line to the next by ending
 them with a backslash
@@ -462,9 +462,9 @@ It must be the last modifier specified.
 is anchored at the end of each word, so only suffixes or entire
 words may be replaced.
 .El
 is anchored at the end of each word, so only suffixes or entire
 words may be replaced.
 .El
-.Sh INCLUDE STATEMENTS AND CONDITIONALS
-Makefile inclusion and conditional structures reminiscent of the C
-programming language are provided in
+.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
+Makefile inclusion, conditional structures and for loops  reminiscent 
+of the C programming language are provided in
 .Nm make .
 All such structures are identified by a line beginning with a single
 dot
 .Nm make .
 All such structures are identified by a line beginning with a single
 dot
@@ -625,20 +625,18 @@ has been defined.
 .El
 .Pp
 .Ar Expression
 .El
 .Pp
 .Ar Expression
-may also be an arithmetic or string comparison, with the left-hand side
-being a variable expansion.
-The standard C relational operators are all supported, and the usual
-number/base conversion is performed.
-Note, octal numbers are not supported.
-If the righthand value of a
+may also be an arithmetic or string comparison.  Variable expansion is
+performed on both sides of the comparison, after which the integral
+values are compared.  A value is interpreted as hexadecimal if it is
+preceded by 0x, otherwise it is decimal; octal numbers are not supported.
+The standard C relational operators are all supported.  If after
+variable expansion, either the left or right hand side of a
 .Ql Ic ==
 or
 .Ql Ic "!="
 .Ql Ic ==
 or
 .Ql Ic "!="
-operator begins with a
-quotation mark
-.Pq Ql \*q
-a string comparison is done between the expanded
-variable and the text between the quotation marks.
+operator is not an integral value, then
+string comparison is performed between the expanded
+variables.
 If no relational operator is given, it is assumed that the expanded
 variable is being compared against 0.
 .Pp
 If no relational operator is given, it is assumed that the expanded
 variable is being compared against 0.
 .Pp
@@ -667,6 +665,31 @@ In both cases this continues until a
 or
 .Ql Ic .endif
 is found.
 or
 .Ql Ic .endif
 is found.
+.Pp 
+For loops are typically used to apply a set of rules to a list of files.
+The syntax of a for loop is:
+.Bl -tag -width Ds
+.It Xo
+.Ic \&.for
+.Ar variable 
+.Ic in 
+.Ar expression
+.Xc
+.It Xo
+<make-rules>
+.Xc
+.It Xo
+.Ic \&.endfor
+.Xc
+.El
+After the for
+.Ic expression 
+is evaluated, it is split into words. The 
+iteration
+.Ic variable
+is successively set to each word, and substituted in the 
+.Ic make-rules 
+inside the body of the for loop.
 .Sh COMMENTS
 Comments begin with a hash
 .Pq Ql \&#
 .Sh COMMENTS
 Comments begin with a hash
 .Pq Ql \&#
index eccf3bd..0cd370f 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)make.c     5.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)make.c     5.4 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -47,6 +47,9 @@ static char sccsid[] = "@(#)make.c    5.3 (Berkeley) %G%";
  */
 
 #include    "make.h"
  */
 
 #include    "make.h"
+#include    "hash.h"
+#include    "dir.h"
+#include    "job.h"
 
 static Lst             toBeMade;       /* The current fringe of the graph. These
                                 * are nodes which await examination by
 
 static Lst             toBeMade;       /* The current fringe of the graph. These
                                 * are nodes which await examination by
@@ -57,6 +60,10 @@ static int   numNodes;       /* Number of nodes to be processed. If this
                                 * is non-zero when Job_Empty() returns
                                 * TRUE, there's a cycle in the graph */
 
                                 * is non-zero when Job_Empty() returns
                                 * TRUE, there's a cycle in the graph */
 
+static int MakeAddChild __P((GNode *, Lst));
+static int MakeAddAllSrc __P((GNode *, GNode *));
+static Boolean MakeStartJobs __P((void));
+static int MakePrintStatus __P((GNode *, Boolean));
 /*-
  *-----------------------------------------------------------------------
  * Make_TimeStamp --
 /*-
  *-----------------------------------------------------------------------
  * Make_TimeStamp --
@@ -399,7 +406,12 @@ Make_Update (cgn)
         * little, so this stuff is commented out unless you're sure it's ok.
         * -- ardeb 1/12/88
         */
         * little, so this stuff is commented out unless you're sure it's ok.
         * -- ardeb 1/12/88
         */
-       if (noExecute || Dir_MTime(cgn) == 0) {
+       /*
+        * Christos, 4/9/92: If we are  saving commands pretend that
+        * the target is made now. Otherwise archives with ... rules
+        * don't work!
+        */
+       if (noExecute || (cgn->type & OP_SAVE_CMDS) || Dir_MTime(cgn) == 0) {
            cgn->mtime = now;
        }
        if (DEBUG(MAKE)) {
            cgn->mtime = now;
        }
        if (DEBUG(MAKE)) {
index f879c4a..e5792ca 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)make.h      5.13 (Berkeley) %G%
+ *     @(#)make.h      5.14 (Berkeley) %G%
  */
 
 /*-
  */
 
 /*-
 #define _MAKE_H_
 
 #include <sys/types.h>
 #define _MAKE_H_
 
 #include <sys/types.h>
+#include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #include <string.h>
 #include <ctype.h>
+#include <sys/cdefs.h>
+#if __STDC__
+#include <stdlib.h>
+#include <unistd.h>
+#endif
 #include "sprite.h"
 #include "lst.h"
 #include "config.h"
 #include "sprite.h"
 #include "lst.h"
 #include "config.h"
+#include "buf.h"
 
 /*-
  * The structure for an individual graph node. Each node has several
 
 /*-
  * The structure for an individual graph node. Each node has several
@@ -188,7 +195,7 @@ typedef struct GNode {
  * case, it ought to be a power of two simply because most storage allocation
  * schemes allocate in powers of two. 
  */
  * case, it ought to be a power of two simply because most storage allocation
  * schemes allocate in powers of two. 
  */
-#define BSIZE          256     /* starting size for expandable buffers */
+#define MAKE_BSIZE             256     /* starting size for expandable buffers */
 
 /*
  * These constants are all used by the Str_Concat function to decide how the
 
 /*
  * These constants are all used by the Str_Concat function to decide how the
@@ -245,6 +252,7 @@ extern Lst          create;         /* The list of target names specified on the
 extern Lst             dirSearchPath;  /* The list of directories to search when
                                 * looking for targets */
 
 extern Lst             dirSearchPath;  /* The list of directories to search when
                                 * looking for targets */
 
+extern Boolean compatMake;     /* True if we are make compatible */
 extern Boolean ignoreErrors;   /* True if should ignore all errors */
 extern Boolean  beSilent;      /* True if should print no commands */
 extern Boolean  noExecute;     /* True if should execute nothing */
 extern Boolean ignoreErrors;   /* True if should ignore all errors */
 extern Boolean  beSilent;      /* True if should print no commands */
 extern Boolean  noExecute;     /* True if should execute nothing */
@@ -296,6 +304,7 @@ extern int debug;
 #define        DEBUG_SUFF      0x0080
 #define        DEBUG_TARG      0x0100
 #define        DEBUG_VAR       0x0200
 #define        DEBUG_SUFF      0x0080
 #define        DEBUG_TARG      0x0100
 #define        DEBUG_VAR       0x0200
+#define DEBUG_FOR      0x0400
 
 #ifdef __STDC__
 #define CONCAT(a,b)    a##b
 
 #ifdef __STDC__
 #define CONCAT(a,b)    a##b
@@ -312,4 +321,11 @@ extern int debug;
  */
 #include "nonints.h"
 
  */
 #include "nonints.h"
 
-#endif _MAKE_H_
+void   Make_DoAllVar __P((GNode *));
+int    Make_HandleUse __P((GNode *, GNode *));
+Boolean        Make_OODate __P((GNode *));
+Boolean        Make_Run __P((Lst));
+int    Make_TimeStamp __P((GNode *, GNode *));
+void   Make_Update __P((GNode *));
+
+#endif /* _MAKE_H_ */
index 6fcc888..c5cfaf1 100644 (file)
@@ -9,94 +9,95 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nonints.h   5.6 (Berkeley) %G%
+ *     @(#)nonints.h   5.7 (Berkeley) %G%
  */
 
 char **brk_string(), *emalloc(), *str_concat();
 
  */
 
 char **brk_string(), *emalloc(), *str_concat();
 
-ReturnStatus   Arch_ParseArchive ();
-void   Arch_Touch ();
-void   Arch_TouchLib ();
-int    Arch_MTime ();
-int    Arch_MemMTime ();
-void   Arch_FindLib ();
-Boolean        Arch_LibOODate ();
-void   Arch_Init ();
-void   Compat_Run();
-void   Dir_Init ();
-Boolean        Dir_HasWildcards ();
-void   Dir_Expand ();
-char * Dir_FindFile ();
-int    Dir_MTime ();
-void   Dir_AddDir ();
-ClientData     Dir_CopyDir ();
-char * Dir_MakeFlags ();
-void   Dir_Destroy ();
-void   Dir_ClearPath ();
-void   Dir_Concat ();
-int    Make_TimeStamp ();
-Boolean        Make_OODate ();
-int    Make_HandleUse ();
-void   Make_Update ();
-void   Make_DoAllVar ();
-Boolean        Make_Run ();
-void   Job_Touch ();
-Boolean        Job_CheckCommands ();
-void   Job_CatchChildren ();
-void   Job_CatchOutput ();
-void   Job_Make ();
-void   Job_Init ();
-Boolean        Job_Full ();
-Boolean        Job_Empty ();
-ReturnStatus   Job_ParseShell ();
-int    Job_End ();
-void   Job_Wait();
-void   Job_AbortAll ();
-void   Main_ParseArgLine ();
-void   Error ();
-void   Fatal ();
-void   Punt ();
-void   DieHorribly ();
-void   Finish ();
-void   Parse_Error ();
-Boolean        Parse_IsVar ();
-void   Parse_DoVar ();
-void   Parse_AddIncludeDir ();
-void   Parse_File();
-Lst    Parse_MainName();
-void   Suff_ClearSuffixes ();
-Boolean        Suff_IsTransform ();
-GNode *        Suff_AddTransform ();
-void   Suff_AddSuffix ();
-int    Suff_EndTransform ();
-Lst    Suff_GetPath ();
-void   Suff_DoPaths();
-void   Suff_AddInclude ();
-void   Suff_AddLib ();
-void   Suff_FindDeps ();
-void   Suff_SetNull();
-void   Suff_Init ();
-void   Targ_Init ();
-GNode *        Targ_NewGN ();
-GNode *        Targ_FindNode ();
-Lst    Targ_FindList ();
-Boolean        Targ_Ignore ();
-Boolean        Targ_Silent ();
-Boolean        Targ_Precious ();
-void   Targ_SetMain ();
-int    Targ_PrintCmd ();
-char * Targ_FmtTime ();
-void   Targ_PrintType ();
-char * Str_Concat ();
-int    Str_Match();
-void   Var_Delete();
-void   Var_Set ();
-void   Var_Append ();
-Boolean        Var_Exists();
-char * Var_Value ();
-char * Var_Parse ();
-char * Var_Subst ();
-char * Var_GetTail();
-char * Var_GetHead();
-void   Var_Init ();
-char * Str_FindSubstring();
+char   *Dir_FindFile();
+char   *Dir_MakeFlags();
+char   *Str_Concat();
+char   *Str_FindSubstring();
+GNode  *Suff_AddTransform();
+GNode  *Targ_FindNode();
+char   *Targ_FmtTime();
+void    enomem __P((void));
+GNode  *Targ_NewGN();
+char   *Var_GetHead();
+char   *Var_GetTail();
+char   *Var_Parse();
+char   *Var_Subst();
+char   *Var_Value();
+void    Arch_FindLib();
+void    Arch_Init();
+Boolean         Arch_LibOODate();
+int     Arch_MTime();
+int     Arch_MemMTime();
+ReturnStatus    Arch_ParseArchive();
+void    Arch_Touch();
+void    Arch_TouchLib();
+void    Compat_Run();
+void    DieHorribly();
+void    Dir_AddDir();
+void    Dir_ClearPath();
+void    Dir_Concat();
+ClientData      Dir_CopyDir();
+void    Dir_Destroy();
+void    Dir_Expand();
+Boolean         Dir_HasWildcards();
+void    Dir_Init();
+int     Dir_MTime();
+void    Error __P((const char *, ...));
+void    Fatal __P((const char *, ...));
+void    Finish();
+void    Job_AbortAll();
+void    Job_CatchChildren();
+void    Job_CatchOutput();
+Boolean         Job_CheckCommands();
+Boolean         Job_Empty();
+int     Job_End();
+Boolean         Job_Full();
+void    Job_Init();
+void    Job_Make();
+ReturnStatus    Job_ParseShell();
+void    Job_Touch();
+void    Job_Wait();
+void    Main_ParseArgLine();
+void    Make_DoAllVar();
+int     Make_HandleUse();
+Boolean         Make_OODate();
+Boolean         Make_Run();
+int     Make_TimeStamp();
+void    Make_Update();
+void    Parse_AddIncludeDir();
+void    Parse_DoVar();
+void    Parse_Error __P((int, const char *, ...));
+void    Parse_File();
+Boolean         Parse_IsVar();
+Lst     Parse_MainName();
+void    Punt __P((const char *, ...));
+int     Str_Match();
+void    Suff_AddInclude();
+void    Suff_AddLib();
+void    Suff_AddSuffix();
+void    Suff_ClearSuffixes();
+void    Suff_DoPaths();
+int     Suff_EndTransform();
+void    Suff_FindDeps();
+Lst     Suff_GetPath();
+void    Suff_Init();
+Boolean         Suff_IsTransform();
+void    Suff_SetNull();
+Lst     Targ_FindList();
+Boolean         Targ_Ignore();
+void    Targ_Init();
+Boolean         Targ_Precious();
+int     Targ_PrintCmd();
+void    Targ_PrintType();
+void    Targ_SetMain();
+Boolean         Targ_Silent();
+void    Var_Append();
+void    Var_Delete();
+Boolean         Var_Exists();
+void    Var_Init();
+void    Var_Set();
index f478d13..4e1304c 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)parse.c    5.18 (Berkeley) %G%";
+static char sccsid[] = "@(#)parse.c    5.19 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -54,10 +54,19 @@ static char sccsid[] = "@(#)parse.c 5.18 (Berkeley) %G%";
  *     Parse_MainName              Returns a Lst of the main target to create.
  */
 
  *     Parse_MainName              Returns a Lst of the main target to create.
  */
 
+#if __STDC__
+#include <stdarg.h>
+#else
 #include <varargs.h>
 #include <varargs.h>
+#endif
 #include <stdio.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <errno.h>
+#include <sys/wait.h>
 #include "make.h"
 #include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
 #include "buf.h"
 #include "pathnames.h"
 
 #include "buf.h"
 #include "pathnames.h"
 
@@ -68,15 +77,19 @@ static char sccsid[] = "@(#)parse.c 5.18 (Berkeley) %G%";
  */
 #define        CONTINUE        1
 #define        DONE            0
  */
 #define        CONTINUE        1
 #define        DONE            0
-static int         ParseEOF();
-
 static Lst                 targets;    /* targets we're working on */
 static Boolean     inLine;     /* true if currently in a dependency
                                 * line or its commands */
 static Lst                 targets;    /* targets we're working on */
 static Boolean     inLine;     /* true if currently in a dependency
                                 * line or its commands */
+typedef struct {
+    char *str;
+    char *ptr;
+} PTR;
 
 static char                *fname;     /* name of current file (for errors) */
 static int          lineno;    /* line number in current file */
 
 static char                *fname;     /* name of current file (for errors) */
 static int          lineno;    /* line number in current file */
-static FILE        *curFILE;   /* current makefile */
+static FILE        *curFILE = NULL;    /* current makefile */
+
+static PTR         *curPTR = NULL;     /* current makefile */
 
 static int         fatals = 0;
 
 
 static int         fatals = 0;
 
@@ -89,8 +102,9 @@ static GNode     *mainNode;  /* The main target to create. This is the
 typedef struct IFile {
     char           *fname;         /* name of previous file */
     int             lineno;        /* saved line number */
 typedef struct IFile {
     char           *fname;         /* name of previous file */
     int             lineno;        /* saved line number */
-    FILE *       F;                /* the open stream */
-}                        IFile;
+    FILE *          F;             /* the open stream */
+    PTR *          p;              /* the char pointer */
+} IFile;
 
 static Lst      includes;      /* stack of IFiles generated by
                                 * #includes */
 
 static Lst      includes;      /* stack of IFiles generated by
                                 * #includes */
@@ -114,20 +128,21 @@ typedef enum {
     MFlags,        /* .MFLAGS or .MAKEFLAGS */
     Main,          /* .MAIN and we don't have anything user-specified to
                     * make */
     MFlags,        /* .MFLAGS or .MAKEFLAGS */
     Main,          /* .MAIN and we don't have anything user-specified to
                     * make */
+    NoExport,      /* .NOEXPORT */
     Not,           /* Not special */
     NotParallel,    /* .NOTPARALELL */
     Null,          /* .NULL */
     Order,         /* .ORDER */
     Not,           /* Not special */
     NotParallel,    /* .NOTPARALELL */
     Null,          /* .NULL */
     Order,         /* .ORDER */
-    Path,          /* .PATH */
+    ExPath,        /* .PATH */
     Precious,      /* .PRECIOUS */
     Precious,      /* .PRECIOUS */
-    Shell,         /* .SHELL */
+    ExShell,       /* .SHELL */
     Silent,        /* .SILENT */
     SingleShell,    /* .SINGLESHELL */
     Suffixes,      /* .SUFFIXES */
     Silent,        /* .SILENT */
     SingleShell,    /* .SINGLESHELL */
     Suffixes,      /* .SUFFIXES */
-    Attribute,     /* Generic attribute */
+    Attribute      /* Generic attribute */
 } ParseSpecial;
 
 } ParseSpecial;
 
-ParseSpecial specType;
+static ParseSpecial specType;
 
 /*
  * Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
 
 /*
  * Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
@@ -166,16 +181,36 @@ static struct {
 { ".NOTPARALLEL", NotParallel, 0 },
 { ".NULL",       Null,         0 },
 { ".ORDER",      Order,        0 },
 { ".NOTPARALLEL", NotParallel, 0 },
 { ".NULL",       Null,         0 },
 { ".ORDER",      Order,        0 },
-{ ".PATH",       Path,         0 },
+{ ".PATH",       ExPath,       0 },
 { ".PRECIOUS",   Precious,     OP_PRECIOUS },
 { ".RECURSIVE",          Attribute,    OP_MAKE },
 { ".PRECIOUS",   Precious,     OP_PRECIOUS },
 { ".RECURSIVE",          Attribute,    OP_MAKE },
-{ ".SHELL",      Shell,        0 },
+{ ".SHELL",      ExShell,      0 },
 { ".SILENT",     Silent,       OP_SILENT },
 { ".SINGLESHELL", SingleShell, 0 },
 { ".SUFFIXES",   Suffixes,     0 },
 { ".USE",        Attribute,    OP_USE },
 };
 
 { ".SILENT",     Silent,       OP_SILENT },
 { ".SINGLESHELL", SingleShell, 0 },
 { ".SUFFIXES",   Suffixes,     0 },
 { ".USE",        Attribute,    OP_USE },
 };
 
+static int ParseFindKeyword __P((char *));
+static int ParseLinkSrc __P((GNode *, GNode *));
+static int ParseDoOp __P((GNode *, int));
+static void ParseDoSrc __P((int, char *));
+static int ParseFindMain __P((GNode *));
+static int ParseAddDir __P((Lst, char *));
+static int ParseClearPath __P((Lst));
+static void ParseDoDependency __P((char *));
+static int ParseAddCmd __P((GNode *, char *));
+static int ParseReadc __P((void));
+static int ParseHasCommands __P((GNode *));
+static void ParseDoInclude __P((char *));
+#ifdef SYSVINCLUDE
+static void ParseTraditionalInclude __P((char *));
+#endif
+static int ParseEOF __P((int));
+static char *ParseReadLine __P((void));
+static char *ParseSkipLine __P((int));
+static void ParseFinishLine __P((void));
+
 /*-
  *----------------------------------------------------------------------
  * ParseFindKeyword --
 /*-
  *----------------------------------------------------------------------
  * ParseFindKeyword --
@@ -229,18 +264,24 @@ ParseFindKeyword (str)
  */
 /* VARARGS */
 void
  */
 /* VARARGS */
 void
-Parse_Error(type, va_alist)
-       int type;               /* Error type (PARSE_WARNING, PARSE_FATAL) */
+#if __STDC__
+Parse_Error(int type, const char *fmt, ...)
+#else
+Parse_Error(type, fmt, va_alist)
+       int type;
+       char *fmt;
        va_dcl
        va_dcl
+#endif
 {
        va_list ap;
 {
        va_list ap;
-       char *fmt;
-
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
        (void)fprintf(stderr, "\"%s\", line %d: ", fname, lineno);
        if (type == PARSE_WARNING)
                (void)fprintf(stderr, "warning: ");
        (void)fprintf(stderr, "\"%s\", line %d: ", fname, lineno);
        if (type == PARSE_WARNING)
                (void)fprintf(stderr, "warning: ");
-       va_start(ap);
-       fmt = va_arg(ap, char *);
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
@@ -648,7 +689,7 @@ ParseDoDependency (line)
             */
            int keywd = ParseFindKeyword(line);
            if (keywd != -1) {
             */
            int keywd = ParseFindKeyword(line);
            if (keywd != -1) {
-               if (specType == Path && parseKeywords[keywd].spec != Path) {
+               if (specType == ExPath && parseKeywords[keywd].spec != ExPath) {
                    Parse_Error(PARSE_FATAL, "Mismatched special targets");
                    return;
                }
                    Parse_Error(PARSE_FATAL, "Mismatched special targets");
                    return;
                }
@@ -684,7 +725,7 @@ ParseDoDependency (line)
                 *      .ORDER          Must set initial predecessor to NIL
                 */
                switch (specType) {
                 *      .ORDER          Must set initial predecessor to NIL
                 */
                switch (specType) {
-                   case Path:
+                   case ExPath:
                        if (paths == NULL) {
                            paths = Lst_Init(FALSE);
                        }
                        if (paths == NULL) {
                            paths = Lst_Init(FALSE);
                        }
@@ -716,11 +757,13 @@ ParseDoDependency (line)
                        break;
                    }
                    case SingleShell:
                        break;
                    }
                    case SingleShell:
-                       /* backwards = 1; */
+                       compatMake = 1;
                        break;
                    case Order:
                        predecessor = NILGNODE;
                        break;
                        break;
                    case Order:
                        predecessor = NILGNODE;
                        break;
+                   default:
+                       break;
                }
            } else if (strncmp (line, ".PATH", 5) == 0) {
                /*
                }
            } else if (strncmp (line, ".PATH", 5) == 0) {
                /*
@@ -730,7 +773,7 @@ ParseDoDependency (line)
                 */
                Lst     path;
                
                 */
                Lst     path;
                
-               specType = Path;
+               specType = ExPath;
                path = Suff_GetPath (&line[5]);
                if (path == NILLST) {
                    Parse_Error (PARSE_FATAL,
                path = Suff_GetPath (&line[5]);
                if (path == NILLST) {
                    Parse_Error (PARSE_FATAL,
@@ -782,7 +825,7 @@ ParseDoDependency (line)
                
                (void)Lst_AtEnd (targets, (ClientData)gn);
            }
                
                (void)Lst_AtEnd (targets, (ClientData)gn);
            }
-       } else if (specType == Path && *line != '.' && *line != '\0') {
+       } else if (specType == ExPath && *line != '.' && *line != '\0') {
            Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
        }
        
            Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
        }
        
@@ -791,7 +834,7 @@ ParseDoDependency (line)
         * If it is a special type and not .PATH, it's the only target we
         * allow on this line...
         */
         * If it is a special type and not .PATH, it's the only target we
         * allow on this line...
         */
-       if (specType != Not && specType != Path) {
+       if (specType != Not && specType != ExPath) {
            Boolean warn = FALSE;
            
            while ((*cp != '!') && (*cp != ':') && *cp) {
            Boolean warn = FALSE;
            
            while ((*cp != '!') && (*cp != ':') && *cp) {
@@ -890,9 +933,11 @@ ParseDoDependency (line)
            case Silent:
                beSilent = TRUE;
                break;
            case Silent:
                beSilent = TRUE;
                break;
-           case Path:
+           case ExPath:
                Lst_ForEach(paths, ParseClearPath, (ClientData)NULL);
                break;
                Lst_ForEach(paths, ParseClearPath, (ClientData)NULL);
                break;
+           default:
+               break;
        }
     } else if (specType == MFlags) {
        /*
        }
     } else if (specType == MFlags) {
        /*
@@ -902,7 +947,7 @@ ParseDoDependency (line)
         */
        Main_ParseArgLine (line);
        *line = '\0';
         */
        Main_ParseArgLine (line);
        *line = '\0';
-    } else if (specType == Shell) {
+    } else if (specType == ExShell) {
        if (Job_ParseShell (line) != SUCCESS) {
            Parse_Error (PARSE_FATAL, "improper shell specification");
            return;
        if (Job_ParseShell (line) != SUCCESS) {
            Parse_Error (PARSE_FATAL, "improper shell specification");
            return;
@@ -915,7 +960,7 @@ ParseDoDependency (line)
     /*
      * NOW GO FOR THE SOURCES 
      */
     /*
      * NOW GO FOR THE SOURCES 
      */
-    if ((specType == Suffixes) || (specType == Path) ||
+    if ((specType == Suffixes) || (specType == ExPath) ||
        (specType == Includes) || (specType == Libs) ||
        (specType == Null))
     {
        (specType == Includes) || (specType == Libs) ||
        (specType == Null))
     {
@@ -954,7 +999,7 @@ ParseDoDependency (line)
                case Suffixes:
                    Suff_AddSuffix (line);
                    break;
                case Suffixes:
                    Suff_AddSuffix (line);
                    break;
-               case Path:
+               case ExPath:
                    Lst_ForEach(paths, ParseAddDir, (ClientData)line);
                    break;
                case Includes:
                    Lst_ForEach(paths, ParseAddDir, (ClientData)line);
                    break;
                case Includes:
@@ -966,6 +1011,8 @@ ParseDoDependency (line)
                case Null:
                    Suff_SetNull (line);
                    break;
                case Null:
                    Suff_SetNull (line);
                    break;
+               default:
+                   break;
            }
            *cp = savec;
            if (savec != '\0') {
            }
            *cp = savec;
            if (savec != '\0') {
@@ -1229,13 +1276,12 @@ Parse_DoVar (line, ctxt)
        Boolean   oldOldVars = oldVars;
 
        oldVars = FALSE;
        Boolean   oldOldVars = oldVars;
 
        oldVars = FALSE;
-       cp = Var_Subst(cp, ctxt, FALSE);
+       cp = Var_Subst(NULL, cp, ctxt, FALSE);
        oldVars = oldOldVars;
 
        Var_Set(line, cp, ctxt);
        free(cp);
     } else if (type == VAR_SHELL) {
        oldVars = oldOldVars;
 
        Var_Set(line, cp, ctxt);
        free(cp);
     } else if (type == VAR_SHELL) {
-       char    result[BUFSIZ]; /* Result of command */
        char    *args[4];       /* Args for invoking the shell */
        int     fds[2];         /* Pipe streams */
        int     cpid;           /* Child PID */
        char    *args[4];       /* Args for invoking the shell */
        int     fds[2];         /* Pipe streams */
        int     cpid;           /* Child PID */
@@ -1243,18 +1289,19 @@ Parse_DoVar (line, ctxt)
        Boolean freeCmd;        /* TRUE if the command needs to be freed, i.e.
                                 * if any variable expansion was performed */
 
        Boolean freeCmd;        /* TRUE if the command needs to be freed, i.e.
                                 * if any variable expansion was performed */
 
+
        /*
         * Set up arguments for shell
         */
        args[0] = "sh";
        args[1] = "-c";
        /*
         * Set up arguments for shell
         */
        args[0] = "sh";
        args[1] = "-c";
-       if (index(cp, '$') != (char *)NULL) {
+       if (strchr(cp, '$') != (char *)NULL) {
            /*
             * There's a dollar sign in the command, so perform variable
             * expansion on the whole thing. The resulting string will need
             * freeing when we're done, so set freeCmd to TRUE.
             */
            /*
             * There's a dollar sign in the command, so perform variable
             * expansion on the whole thing. The resulting string will need
             * freeing when we're done, so set freeCmd to TRUE.
             */
-           args[2] = Var_Subst(cp, VAR_CMD, TRUE);
+           args[2] = Var_Subst(NULL, cp, VAR_CMD, TRUE);
            freeCmd = TRUE;
        } else {
            args[2] = cp;
            freeCmd = TRUE;
        } else {
            args[2] = cp;
@@ -1296,34 +1343,44 @@ Parse_DoVar (line, ctxt)
        } else {
            int status;
            int cc;
        } else {
            int status;
            int cc;
+           Buffer buf;
+           char *res;
 
            /*
             * No need for the writing half
             */
            close(fds[1]);
            
 
            /*
             * No need for the writing half
             */
            close(fds[1]);
            
+           buf = Buf_Init (MAKE_BSIZE);
+
+           do {
+               char   result[BUFSIZ];
+               cc = read(fds[0], result, sizeof(result));
+               if (cc > 0) 
+                   Buf_AddBytes(buf, cc, (unsigned char *) result);
+           }
+           while (cc > 0 || (cc == -1 && errno == EINTR));
+
            /*
            /*
-            * Wait for the process to exit.
-            *
-            * XXX: If the child writes more than a pipe's worth, we will
-            * deadlock.
+            * Close the input side of the pipe.
             */
             */
-           while(((pid = wait(&status)) != cpid) && (pid >= 0)) {
-               ;
-           }
+           close(fds[0]);
 
            /*
 
            /*
-            * Read all the characters the child wrote.
+            * Wait for the process to exit.
             */
             */
-           cc = read(fds[0], result, sizeof(result));
+           while(((pid = wait(&status)) != cpid) && (pid >= 0))
+               continue;
 
 
-           if (cc < 0) {
+           res = (char *)Buf_GetAll (buf, &cc);
+           Buf_Destroy (buf, FALSE);
+
+           if (cc == 0) {
                /*
                 * Couldn't read the child's output -- tell the user and
                 * set the variable to null
                 */
                Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
                /*
                 * Couldn't read the child's output -- tell the user and
                 * set the variable to null
                 */
                Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
-               cc = 0;
            }
 
            if (status) {
            }
 
            if (status) {
@@ -1333,12 +1390,13 @@ Parse_DoVar (line, ctxt)
                 */
                Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
            }
                 */
                Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
            }
+
            /*
             * Null-terminate the result, convert newlines to spaces and
             * install it in the variable.
             */
            /*
             * Null-terminate the result, convert newlines to spaces and
             * install it in the variable.
             */
-           result[cc] = '\0';
-           cp = &result[cc] - 1;
+           res[cc] = '\0';
+           cp = &res[cc] - 1;
 
            if (*cp == '\n') {
                /*
 
            if (*cp == '\n') {
                /*
@@ -1346,18 +1404,15 @@ Parse_DoVar (line, ctxt)
                 */
                *cp-- = '\0';
            }
                 */
                *cp-- = '\0';
            }
-           while (cp >= result) {
+           while (cp >= res) {
                if (*cp == '\n') {
                    *cp = ' ';
                }
                cp--;
            }
                if (*cp == '\n') {
                    *cp = ' ';
                }
                cp--;
            }
-           Var_Set(line, result, ctxt);
+           Var_Set(line, res, ctxt);
+           free(res);
 
 
-           /*
-            * Close the input side of the pipe.
-            */
-           close(fds[0]);
        }
        if (freeCmd) {
            free(args[2]);
        }
        if (freeCmd) {
            free(args[2]);
@@ -1380,7 +1435,7 @@ Parse_DoVar (line, ctxt)
  * Side Effects:
  *     A new element is added to the commands list of the node.
  */
  * Side Effects:
  *     A new element is added to the commands list of the node.
  */
-static
+static int
 ParseAddCmd(gn, cmd)
        GNode *gn;      /* the node to which the command is to be added */
        char *cmd;      /* the command to add */
 ParseAddCmd(gn, cmd)
        GNode *gn;      /* the node to which the command is to be added */
        char *cmd;      /* the command to add */
@@ -1462,7 +1517,6 @@ ParseDoInclude (file)
 {
     char          *fullname;   /* full pathname of file */
     IFile         *oldFile;    /* state associated with current file */
 {
     char          *fullname;   /* full pathname of file */
     IFile         *oldFile;    /* state associated with current file */
-    Lst           path;                /* the path to use to find the file */
     char          endc;                /* the character which ends the file spec */
     char          *cp;         /* current position in file spec */
     Boolean      isSystem;     /* TRUE if makefile is a system makefile */
     char          endc;                /* the character which ends the file spec */
     char          *cp;         /* current position in file spec */
     Boolean      isSystem;     /* TRUE if makefile is a system makefile */
@@ -1502,7 +1556,8 @@ ParseDoInclude (file)
 
     if (*cp != endc) {
        Parse_Error (PARSE_FATAL,
 
     if (*cp != endc) {
        Parse_Error (PARSE_FATAL,
-                    "Unclosed .include filename. '%c' expected", endc);
+                    "Unclosed %cinclude filename. '%c' expected",
+                    '.', endc);
        return;
     }
     *cp = '\0';
        return;
     }
     *cp = '\0';
@@ -1511,7 +1566,7 @@ ParseDoInclude (file)
      * Substitute for any variables in the file name before trying to
      * find the thing.
      */
      * Substitute for any variables in the file name before trying to
      * find the thing.
      */
-    file = Var_Subst (file, VAR_CMD, FALSE);
+    file = Var_Subst (NULL, file, VAR_CMD, FALSE);
 
     /*
      * Now we know the file's name and its search path, we attempt to
 
     /*
      * Now we know the file's name and its search path, we attempt to
@@ -1528,7 +1583,7 @@ ParseDoInclude (file)
         */
        char      *prefEnd;
 
         */
        char      *prefEnd;
 
-       prefEnd = rindex (fname, '/');
+       prefEnd = strrchr (fname, '/');
        if (prefEnd != (char *)NULL) {
            char        *newName;
            
        if (prefEnd != (char *)NULL) {
            char        *newName;
            
@@ -1585,6 +1640,7 @@ ParseDoInclude (file)
     oldFile->fname = fname;
 
     oldFile->F = curFILE;
     oldFile->fname = fname;
 
     oldFile->F = curFILE;
+    oldFile->p = curPTR;
     oldFile->lineno = lineno;
 
     (void) Lst_AtFront (includes, (ClientData)oldFile);
     oldFile->lineno = lineno;
 
     (void) Lst_AtFront (includes, (ClientData)oldFile);
@@ -1599,6 +1655,7 @@ ParseDoInclude (file)
     lineno = 0;
 
     curFILE = fopen (fullname, "r");
     lineno = 0;
 
     curFILE = fopen (fullname, "r");
+    curPTR = NULL;
     if (curFILE == (FILE * ) NULL) {
        Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);
        /*
     if (curFILE == (FILE * ) NULL) {
        Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);
        /*
@@ -1608,6 +1665,189 @@ ParseDoInclude (file)
     }
 }
 
     }
 }
 
+
+/*-
+ *---------------------------------------------------------------------
+ * Parse_FromString  --
+ *     Start Parsing from the given string
+ *     
+ * Results:
+ *     None
+ *
+ * Side Effects:
+ *     A structure is added to the includes Lst and readProc, lineno,
+ *     fname and curFILE are altered for the new file
+ *---------------------------------------------------------------------
+ */
+void
+Parse_FromString(str)
+    char *str;
+{
+    IFile         *oldFile;    /* state associated with this file */
+
+    if (DEBUG(FOR))
+       (void) fprintf(stderr, "%s\n----\n", str);
+
+    oldFile = (IFile *) emalloc (sizeof (IFile));
+    oldFile->lineno = lineno;
+    oldFile->fname = fname;
+    oldFile->F = curFILE;
+    oldFile->p = curPTR;
+    
+    (void) Lst_AtFront (includes, (ClientData)oldFile);
+
+    curFILE = NULL;
+    curPTR = (PTR *) emalloc (sizeof (PTR));
+    curPTR->str = curPTR->ptr = str;
+    lineno = 0;
+    fname = strdup(fname);
+}
+
+
+#ifdef SYSVINCLUDE
+/*-
+ *---------------------------------------------------------------------
+ * ParseTraditionalInclude  --
+ *     Push to another file.
+ *     
+ *     The input is the line minus the "include".  The file name is
+ *     the string following the "include".
+ *
+ * Results:
+ *     None
+ *
+ * Side Effects:
+ *     A structure is added to the includes Lst and readProc, lineno,
+ *     fname and curFILE are altered for the new file
+ *---------------------------------------------------------------------
+ */
+static void
+ParseTraditionalInclude (file)
+    char          *file;       /* file specification */
+{
+    char          *fullname;   /* full pathname of file */
+    IFile         *oldFile;    /* state associated with current file */
+    char          *cp;         /* current position in file spec */
+    char         *prefEnd;
+
+    /*
+     * Skip over whitespace
+     */
+    while ((*file == ' ') || (*file == '\t')) {
+       file++;
+    }
+
+    if (*file == '\0') {
+       Parse_Error (PARSE_FATAL,
+                    "Filename missing from \"include\"");
+       return;
+    }
+
+    /*
+     * Skip to end of line or next whitespace
+     */
+    for (cp = file; *cp && *cp != '\n' && *cp != '\t' && *cp != ' '; cp++) {
+       continue;
+    }
+
+    *cp = '\0';
+
+    /*
+     * Substitute for any variables in the file name before trying to
+     * find the thing.
+     */
+    file = Var_Subst (NULL, file, VAR_CMD, FALSE);
+
+    /*
+     * Now we know the file's name, we attempt to find the durn thing.
+     * A return of NULL indicates the file don't exist.
+     *
+     * Include files are first searched for relative to the including
+     * file's location. We don't want to cd there, of course, so we
+     * just tack on the old file's leading path components and call
+     * Dir_FindFile to see if we can locate the beast.
+     * XXX - this *does* search in the current directory, right?
+     */
+
+    prefEnd = strrchr (fname, '/');
+    if (prefEnd != (char *)NULL) {
+       char    *newName;
+           
+       *prefEnd = '\0';
+       newName = str_concat (fname, file, STR_ADDSLASH);
+       fullname = Dir_FindFile (newName, parseIncPath);
+       if (fullname == (char *)NULL) {
+           fullname = Dir_FindFile(newName, dirSearchPath);
+       }
+       free (newName);
+       *prefEnd = '/';
+    } else {
+       fullname = (char *)NULL;
+    }
+
+    if (fullname == (char *)NULL) {
+       /*
+        * System makefile or makefile wasn't found in same directory as
+        * included makefile. Search for it first on the -I search path,
+        * then on the .PATH search path, if not found in a -I directory.
+        * XXX: Suffix specific?
+        */
+       fullname = Dir_FindFile (file, parseIncPath);
+       if (fullname == (char *)NULL) {
+           fullname = Dir_FindFile(file, dirSearchPath);
+       }
+    }
+
+    if (fullname == (char *)NULL) {
+       /*
+        * Still haven't found the makefile. Look for it on the system
+        * path as a last resort.
+        */
+       fullname = Dir_FindFile(file, sysIncPath);
+    }
+
+    if (fullname == (char *) NULL) {
+       Parse_Error (PARSE_FATAL, "Could not find %s", file);
+       return;
+    }
+
+    /*
+     * Once we find the absolute path to the file, we get to save all the
+     * state from the current file before we can start reading this
+     * include file. The state is stored in an IFile structure which
+     * is placed on a list with other IFile structures. The list makes
+     * a very nice stack to track how we got here...
+     */
+    oldFile = (IFile *) emalloc (sizeof (IFile));
+    oldFile->fname = fname;
+
+    oldFile->F = curFILE;
+    oldFile->p = curPTR;
+    oldFile->lineno = lineno;
+
+    (void) Lst_AtFront (includes, (ClientData)oldFile);
+
+    /*
+     * Once the previous state has been saved, we can get down to reading
+     * the new file. We set up the name of the file to be the absolute
+     * name of the include file so error messages refer to the right
+     * place. Naturally enough, we start reading at line number 0.
+     */
+    fname = fullname;
+    lineno = 0;
+
+    curFILE = fopen (fullname, "r");
+    curPTR = NULL;
+    if (curFILE == (FILE * ) NULL) {
+       Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);
+       /*
+        * Pop to previous file
+        */
+       (void) ParseEOF(1);
+    }
+}
+#endif
+
 /*-
  *---------------------------------------------------------------------
  * ParseEOF  --
 /*-
  *---------------------------------------------------------------------
  * ParseEOF  --
@@ -1634,12 +1874,17 @@ ParseEOF (opened)
     }
 
     ifile = (IFile *) Lst_DeQueue (includes);
     }
 
     ifile = (IFile *) Lst_DeQueue (includes);
-    free (fname);
+    free ((Address) fname);
     fname = ifile->fname;
     lineno = ifile->lineno;
     fname = ifile->fname;
     lineno = ifile->lineno;
-    if (opened)
+    if (opened && curFILE)
        (void) fclose (curFILE);
        (void) fclose (curFILE);
+    if (curPTR) {
+       free((Address) curPTR->str);
+       free((Address) curPTR);
+    }
     curFILE = ifile->F;
     curFILE = ifile->F;
+    curPTR = ifile->p;
     free ((Address)ifile);
     return (CONTINUE);
 }
     free ((Address)ifile);
     return (CONTINUE);
 }
@@ -1647,24 +1892,83 @@ ParseEOF (opened)
 /*-
  *---------------------------------------------------------------------
  * ParseReadc  --
 /*-
  *---------------------------------------------------------------------
  * ParseReadc  --
- *     Read a character from the current file and update the line number
- *     counter as necessary
+ *     Read a character from the current file 
  *
  * Results:
  *     The character that was read
  *
  * Side Effects:
  *
  * Results:
  *     The character that was read
  *
  * Side Effects:
- *     The lineno counter is incremented if the character is a newline
  *---------------------------------------------------------------------
  */
  *---------------------------------------------------------------------
  */
-#ifdef notdef
-static int parseReadChar;
+static int
+ParseReadc()
+{
+    if (curFILE)
+       return fgetc(curFILE);
+         
+    if (curPTR && *curPTR->ptr)
+       return *curPTR->ptr++;
+    return EOF;
+}
 
 
-#define ParseReadc() (((parseReadChar = getc(curFILE)) == '\n') ? \
-                     (lineno++, '\n') : parseReadChar)
-#else
-#define ParseReadc() (getc(curFILE))
-#endif /* notdef */
+/* ParseSkipLine():
+ *     Grab the next line
+ */
+static char *
+ParseSkipLine(skip)
+    int skip;          /* Skip lines that don't start with . */
+{
+    char *line;
+    int c, lastc = '\0', lineLength;
+    Buffer buf;
+
+    c = ParseReadc();
+
+    if (skip) {
+       /*
+        * Skip lines until get to one that begins with a
+        * special char.
+        */
+       while ((c != '.') && (c != EOF)) {
+           while (((c != '\n') || (lastc == '\\')) && (c != EOF))
+           {
+               /*
+                * Advance to next unescaped newline
+                */
+               if ((lastc = c) == '\n') {
+                   lineno++;
+               }
+               c = ParseReadc();
+           }
+           lineno++;
+           
+           lastc = c;
+           c = ParseReadc ();
+       }
+    }
+    
+    if (c == EOF) {
+       Parse_Error (PARSE_FATAL, "Unclosed conditional/for loop");
+       return ((char *)NULL);
+    }
+    
+    /*
+     * Read the entire line into buf
+     */
+    buf = Buf_Init (MAKE_BSIZE);
+    if (c != '\n') {
+       do {
+           Buf_AddByte (buf, (Byte)c);
+           c = ParseReadc();
+       } while ((c != '\n') && (c != EOF));
+    }
+    lineno++;
+    
+    Buf_AddByte (buf, (Byte)'\0');
+    line = (char *)Buf_GetAll (buf, &lineLength);
+    Buf_Destroy (buf, FALSE);
+    return line;
+}
 
 
 /*-
 
 
 /*-
@@ -1709,20 +2013,14 @@ ParseReadLine ()
      * semi-colons as semi-colons (by leaving semiNL FALSE). This also
      * discards completely blank lines.
      */
      * semi-colons as semi-colons (by leaving semiNL FALSE). This also
      * discards completely blank lines.
      */
-    while(1) {
+    for (;;) {
        c = ParseReadc();
 
        c = ParseReadc();
 
-       if (c == '\t') {
+       if ((c == '\t') || (c == '.')) {
            ignComment = ignDepOp = TRUE;
            break;
            ignComment = ignDepOp = TRUE;
            break;
-       } else if (c == '.') {
-           ignComment = TRUE;
-           break;
        } else if (c == '\n') {
            lineno++;
        } else if (c == '\n') {
            lineno++;
-       } else if (c == '#') {
-               ungetc(c, curFILE); 
-               break;
        } else {
            /*
             * Anything else breaks out without doing anything
        } else {
            /*
             * Anything else breaks out without doing anything
@@ -1733,7 +2031,7 @@ ParseReadLine ()
        
     if (c != EOF) {
        lastc = c;
        
     if (c != EOF) {
        lastc = c;
-       buf = Buf_Init(BSIZE);
+       buf = Buf_Init(MAKE_BSIZE);
        
        while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) &&
               (c != EOF))
        
        while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) &&
               (c != EOF))
@@ -1763,7 +2061,9 @@ test_char:
                     */
                    goto test_char;
                }
                     */
                    goto test_char;
                }
+               /*NOTREACHED*/
                break;
                break;
+
            case ';':
                /*
                 * Semi-colon: Need to see if it should be interpreted as a
            case ';':
                /*
                 * Semi-colon: Need to see if it should be interpreted as a
@@ -1806,6 +2106,7 @@ test_char:
                break;
            case '#':
                if (!ignComment) {
                break;
            case '#':
                if (!ignComment) {
+                   if (compatMake || (lastc != '\\')) {
                        /*
                         * If the character is a hash mark and it isn't escaped
                         * (or we're being compatible), the thing is a comment.
                        /*
                         * If the character is a hash mark and it isn't escaped
                         * (or we're being compatible), the thing is a comment.
@@ -1815,6 +2116,14 @@ test_char:
                            c = ParseReadc();
                        } while ((c != '\n') && (c != EOF));
                        goto line_read;
                            c = ParseReadc();
                        } while ((c != '\n') && (c != EOF));
                        goto line_read;
+                   } else {
+                       /*
+                        * Don't add the backslash. Just let the # get copied
+                        * over.
+                        */
+                       lastc = c;
+                       continue;
+                   }
                }
                break;
            case ':':
                }
                break;
            case ':':
@@ -1853,62 +2162,47 @@ test_char:
             */
            switch (Cond_Eval (line)) {
            case COND_SKIP:
             */
            switch (Cond_Eval (line)) {
            case COND_SKIP:
+               /*
+                * Skip to next conditional that evaluates to COND_PARSE.
+                */
                do {
                do {
-                   /*
-                    * Skip to next conditional that evaluates to COND_PARSE.
-                    */
                    free (line);
                    free (line);
-                   c = ParseReadc();
-                   /*
-                    * Skip lines until get to one that begins with a
-                    * special char.
-                    */
-                   while ((c != '.') && (c != EOF)) {
-                       while (((c != '\n') || (lastc == '\\')) &&
-                              (c != EOF))
-                       {
-                           /*
-                            * Advance to next unescaped newline
-                            */
-                           if ((lastc = c) == '\n') {
-                               lineno++;
-                           }
-                           c = ParseReadc();
-                       }
-                       lineno++;
-                       
-                       lastc = c;
-                       c = ParseReadc ();
-                   }
-                   
-                   if (c == EOF) {
-                       Parse_Error (PARSE_FATAL, "Unclosed conditional");
-                       return ((char *)NULL);
-                   }
-                   
-                   /*
-                    * Read the entire line into buf
-                    */
-                   buf = Buf_Init (BSIZE);
-                   do {
-                       Buf_AddByte (buf, (Byte)c);
-                       c = ParseReadc();
-                   } while ((c != '\n') && (c != EOF));
-                   lineno++;
-                   
-                   Buf_AddByte (buf, (Byte)'\0');
-                   line = (char *)Buf_GetAll (buf, &lineLength);
-                   Buf_Destroy (buf, FALSE);
-               } while (Cond_Eval(line) != COND_PARSE);
+                   line = ParseSkipLine(1);
+               } while (line && Cond_Eval(line) != COND_PARSE);
+               if (line == NULL)
+                   break;
                /*FALLTHRU*/
            case COND_PARSE:
                /*FALLTHRU*/
            case COND_PARSE:
-               free (line);
+               free ((Address) line);
                line = ParseReadLine();
                break;
                line = ParseReadLine();
                break;
+           case COND_INVALID:
+               if (For_Eval(line)) {
+                   int ok;
+                   free(line);
+                   do {
+                       /*
+                        * Skip after the matching end
+                        */
+                       line = ParseSkipLine(0);
+                       if (line == NULL) {
+                           Parse_Error (PARSE_FATAL, 
+                                    "Unexpected end of file in for loop.\n");
+                           break;
+                       }
+                       ok = For_Eval(line);
+                       free(line);
+                   }
+                   while (ok);
+                   if (line != NULL)
+                       For_Run();
+                   line = ParseReadLine();
+               }
+               break;
            }
        }
            }
        }
-       
        return (line);
        return (line);
+
     } else {
        /*
         * Hit end-of-file, so return a NULL line to indicate this.
     } else {
        /*
         * Hit end-of-file, so return a NULL line to indicate this.
@@ -1973,7 +2267,7 @@ Parse_File(name, stream)
     fatals = 0;
 
     do {
     fatals = 0;
 
     do {
-       while (line = ParseReadLine ()) {
+       while ((line = ParseReadLine ()) != NULL) {
            if (*line == '.') {
                /*
                 * Lines that begin with the special character are either
            if (*line == '.') {
                /*
                 * Lines that begin with the special character are either
@@ -2035,6 +2329,15 @@ Parse_File(name, stream)
                                     cp);
                    }
                }
                                     cp);
                    }
                }
+#ifdef SYSVINCLUDE
+           } else if (strncmp (line, "include", 7) == 0 && 
+                      strchr(line, ':') == NULL) {
+               /*
+                * It's an S3/S5-style "include".
+                */
+               ParseTraditionalInclude (line + 7);
+               goto nextLine;
+#endif
            } else if (Parse_IsVar (line)) {
                ParseFinishLine();
                Parse_DoVar (line, VAR_GLOBAL);
            } else if (Parse_IsVar (line)) {
                ParseFinishLine();
                Parse_DoVar (line, VAR_GLOBAL);
@@ -2078,7 +2381,7 @@ Parse_File(name, stream)
 #endif
                    ParseFinishLine();
 
 #endif
                    ParseFinishLine();
 
-                   cp = Var_Subst (line, VAR_CMD, TRUE);
+                   cp = Var_Subst (NULL, line, VAR_CMD, TRUE);
                    free (line);
                    line = cp;
                    
                    free (line);
                    line = cp;
                    
@@ -2126,9 +2429,10 @@ Parse_File(name, stream)
  *     the parseIncPath list is initialized...
  *---------------------------------------------------------------------
  */
  *     the parseIncPath list is initialized...
  *---------------------------------------------------------------------
  */
+void
 Parse_Init ()
 {
 Parse_Init ()
 {
-       char *cp, *start;
+       char *cp = NULL, *start;
                                        /* avoid faults on read-only strings */
        static char syspath[] = _PATH_DEFSYSPATH;
     
                                        /* avoid faults on read-only strings */
        static char syspath[] = _PATH_DEFSYSPATH;
     
@@ -2142,9 +2446,8 @@ Parse_Init ()
      * as dir1:...:dirn) to the system include path.
      */
     for (start = syspath; *start != '\0'; start = cp) {
      * as dir1:...:dirn) to the system include path.
      */
     for (start = syspath; *start != '\0'; start = cp) {
-       for (cp = start; *cp != '\0' && *cp != ':'; cp++) {
-           ;
-       }
+       for (cp = start; *cp != '\0' && *cp != ':'; cp++) 
+           continue;
        if (*cp == '\0') {
            Dir_AddDir(sysIncPath, start);
        } else {
        if (*cp == '\0') {
            Dir_AddDir(sysIncPath, start);
        } else {
index 8aa83fa..531eb38 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sprite.h    5.4 (Berkeley) %G%
+ *     @(#)sprite.h    5.5 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -60,7 +60,7 @@ typedef int  ReturnStatus;
  * by user processes.
  */
 
  * by user processes.
  */
 
-#define NIL            (~0)
+#define NIL            0xFFFFFFFF
 #define USER_NIL       0
 #ifndef NULL
 #define NULL           0
 #define USER_NIL       0
 #ifndef NULL
 #define NULL           0
index 405a2e0..1fc4fa2 100644 (file)
@@ -11,8 +11,8 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char     sccsid[] = "@(#)str.c  5.8 (Berkeley) %G%";
-#endif                         /* not lint */
+static char     sccsid[] = "@(#)str.c  5.9 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "make.h"
 
 
 #include "make.h"
 
@@ -40,7 +40,7 @@ str_concat(s1, s2, flags)
        result = emalloc((u_int)(len1 + len2 + 2));
 
        /* copy first string into place */
        result = emalloc((u_int)(len1 + len2 + 2));
 
        /* copy first string into place */
-       bcopy(s1, result, len1);
+       memcpy(result, s1, len1);
 
        /* add separator character */
        if (flags & STR_ADDSPACE) {
 
        /* add separator character */
        if (flags & STR_ADDSPACE) {
@@ -52,7 +52,7 @@ str_concat(s1, s2, flags)
        }
 
        /* copy second string plus EOS into place */
        }
 
        /* copy second string plus EOS into place */
-       bcopy(s2, result + len1, len2 + 1);
+       memcpy(result + len1, s2, len2 + 1);
 
        /* free original strings */
        if (flags & STR_DOFREE) {
 
        /* free original strings */
        if (flags & STR_DOFREE) {
@@ -89,8 +89,9 @@ brk_string(str, store_argc)
                argv[0] = Var_Value(".MAKE", VAR_GLOBAL);
        }
 
                argv[0] = Var_Value(".MAKE", VAR_GLOBAL);
        }
 
-       /* skip leading space chars.
-       for (; *str == ' ' || *str == '\t'; ++str);
+       /* skip leading space chars. */
+       for (; *str == ' ' || *str == '\t'; ++str)
+               continue;
 
        /* allocate room for a copy of the string */
        if ((len = strlen(str) + 1) > curlen)
 
        /* allocate room for a copy of the string */
        if ((len = strlen(str) + 1) > curlen)
@@ -112,7 +113,7 @@ brk_string(str, store_argc)
                                else
                                        break;
                        else
                                else
                                        break;
                        else
-                               inquote = ch;
+                               inquote = (char) ch;
                        continue;
                case ' ':
                case '\t':
                        continue;
                case ' ':
                case '\t':
@@ -167,7 +168,7 @@ brk_string(str, store_argc)
                }
                if (!start)
                        start = t;
                }
                if (!start)
                        start = t;
-               *t++ = ch;
+               *t++ = (char) ch;
        }
 done:  argv[argc] = (char *)NULL;
        *store_argc = argc;
        }
 done:  argv[argc] = (char *)NULL;
        *store_argc = argc;
@@ -223,6 +224,7 @@ Str_FindSubstring(string, substring)
  * 
  * Side effects: None.
  */
  * 
  * Side effects: None.
  */
+int
 Str_Match(string, pattern)
        register char *string;          /* String */
        register char *pattern;         /* Pattern */
 Str_Match(string, pattern)
        register char *string;          /* String */
        register char *pattern;         /* Pattern */
index ade503c..221ef28 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)suff.c     5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)suff.c     5.7 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -65,6 +65,8 @@ static char sccsid[] = "@(#)suff.c    5.6 (Berkeley) %G%";
 
 #include         <stdio.h>
 #include         "make.h"
 
 #include         <stdio.h>
 #include         "make.h"
+#include         "hash.h"
+#include         "dir.h"
 #include         "bit.h"
 
 static Lst       sufflist;     /* Lst of suffixes */
 #include         "bit.h"
 
 static Lst       sufflist;     /* Lst of suffixes */
@@ -102,10 +104,43 @@ typedef struct _Src {
                                 * this thing too early or never nuke it) */
 } Src;
 
                                 * this thing too early or never nuke it) */
 } Src;
 
+/*
+ * A structure for passing more than one argument to the Lst-library-invoked
+ * function...
+ */
+typedef struct {
+    Lst            l;
+    Src            *s;
+} LstSrc;
+
 static Suff        *suffNull;  /* The NULL suffix for this run */
 static Suff        *emptySuff; /* The empty suffix required for POSIX
                                 * single-suffix transformation rules */
 
 static Suff        *suffNull;  /* The NULL suffix for this run */
 static Suff        *emptySuff; /* The empty suffix required for POSIX
                                 * single-suffix transformation rules */
 
+
+static char *SuffStrIsPrefix __P((char *, char *));
+static char *SuffSuffIsSuffix __P((Suff *, char *));
+static int SuffSuffIsSuffixP __P((Suff *, char *));
+static int SuffSuffHasNameP __P((Suff *, char *));
+static int SuffSuffIsPrefix __P((Suff *, char *));
+static int SuffGNHasNameP __P((GNode *, char *));
+static void SuffFree __P((Suff *));
+static void SuffInsert __P((Lst, Suff *));
+static Boolean SuffParseTransform __P((char *, Suff **, Suff **));
+static int SuffRebuildGraph __P((GNode *, Suff *));
+static int SuffAddSrc __P((Suff *, LstSrc *));
+static void SuffAddLevel __P((Lst, Src *));
+static void SuffFreeSrc __P((Src *));
+static Src *SuffFindThem __P((Lst));
+static Src *SuffFindCmds __P((Src *));
+static int SuffExpandChildren __P((GNode *, GNode *));
+static Boolean SuffApplyTransform __P((GNode *, GNode *, Suff *, Suff *));
+static void SuffFindArchiveDeps __P((GNode *));
+static void SuffFindNormalDeps __P((GNode *));
+static int SuffPrintName __P((Suff *));
+static int SuffPrintSuff __P((Suff *));
+static int SuffPrintTrans __P((GNode *));
+
        /*************** Lst Predicates ****************/
 /*-
  *-----------------------------------------------------------------------
        /*************** Lst Predicates ****************/
 /*-
  *-----------------------------------------------------------------------
@@ -179,6 +214,7 @@ SuffSuffIsSuffix (s, str)
  *
  *-----------------------------------------------------------------------
  */
  *
  *-----------------------------------------------------------------------
  */
+static int
 SuffSuffIsSuffixP(s, str)
     Suff       *s;
     char       *str;
 SuffSuffIsSuffixP(s, str)
     Suff       *s;
     char       *str;
@@ -293,7 +329,7 @@ SuffInsert (l, s)
     Suff          *s;          /* the suffix to insert */
 {
     LstNode      ln;           /* current element in l we're examining */
     Suff          *s;          /* the suffix to insert */
 {
     LstNode      ln;           /* current element in l we're examining */
-    Suff          *s2;         /* the suffix descriptor in this element */
+    Suff          *s2 = NULL;  /* the suffix descriptor in this element */
 
     if (Lst_Open (l) == FAILURE) {
        return;
 
     if (Lst_Open (l) == FAILURE) {
        return;
@@ -376,7 +412,7 @@ SuffParseTransform(str, srcPtr, targPtr)
     register char      *str2;      /* Extra pointer (maybe target suffix) */
     LstNode            singleLn;   /* element in suffix list of any suffix
                                     * that exactly matches str */
     register char      *str2;      /* Extra pointer (maybe target suffix) */
     LstNode            singleLn;   /* element in suffix list of any suffix
                                     * that exactly matches str */
-    Suff               *single;    /* Source of possible transformation to
+    Suff               *single = NULL;/* Source of possible transformation to
                                     * null suffix */
 
     srcLn = NILLNODE;
                                     * null suffix */
 
     srcLn = NILLNODE;
@@ -388,7 +424,7 @@ SuffParseTransform(str, srcPtr, targPtr)
      * we can find two that meet these criteria, we've successfully
      * parsed the string.
      */
      * we can find two that meet these criteria, we've successfully
      * parsed the string.
      */
-    while (1) {
+    for (;;) {
        if (srcLn == NILLNODE) {
            srcLn = Lst_Find(sufflist, (ClientData)str, SuffSuffIsPrefix);
        } else {
        if (srcLn == NILLNODE) {
            srcLn = Lst_Find(sufflist, (ClientData)str, SuffSuffIsPrefix);
        } else {
@@ -842,14 +878,6 @@ Suff_AddLib (sname)
 }
 
          /********** Implicit Source Search Functions *********/
 }
 
          /********** Implicit Source Search Functions *********/
-/*
- * A structure for passing more than one argument to the Lst-library-invoked
- * function...
- */
-typedef struct {
-    Lst            l;
-    Src            *s;
-} LstSrc;
 
 /*-
  *-----------------------------------------------------------------------
 
 /*-
  *-----------------------------------------------------------------------
@@ -1041,7 +1069,7 @@ SuffFindCmds (targ)
     while ((ln = Lst_Next (t->children)) != NILLNODE) {
        s = (GNode *)Lst_Datum (ln);
 
     while ((ln = Lst_Next (t->children)) != NILLNODE) {
        s = (GNode *)Lst_Datum (ln);
 
-       cp = rindex (s->name, '/');
+       cp = strrchr (s->name, '/');
        if (cp == (char *)NULL) {
            cp = s->name;
        } else {
        if (cp == (char *)NULL) {
            cp = s->name;
        } else {
@@ -1130,11 +1158,11 @@ SuffExpandChildren(cgn, pgn)
      * to later since the resulting words are tacked on to the end of
      * the children list.
      */
      * to later since the resulting words are tacked on to the end of
      * the children list.
      */
-    if (index(cgn->name, '$') != (char *)NULL) {
+    if (strchr(cgn->name, '$') != (char *)NULL) {
        if (DEBUG(SUFF)) {
            printf("Expanding \"%s\"...", cgn->name);
        }
        if (DEBUG(SUFF)) {
            printf("Expanding \"%s\"...", cgn->name);
        }
-       cp = Var_Subst(cgn->name, pgn, TRUE);
+       cp = Var_Subst(NULL, cgn->name, pgn, TRUE);
 
        if (cp != (char *)NULL) {
            Lst     members = Lst_Init(FALSE);
 
        if (cp != (char *)NULL) {
            Lst     members = Lst_Init(FALSE);
@@ -1159,9 +1187,8 @@ SuffExpandChildren(cgn, pgn)
                char        *start;
                char        *initcp = cp;   /* For freeing... */
 
                char        *start;
                char        *initcp = cp;   /* For freeing... */
 
-               for (start = cp; *start == ' ' || *start == '\t'; start++) {
-                   ;
-               }
+               for (start = cp; *start == ' ' || *start == '\t'; start++) 
+                   continue;
                for (cp = start; *cp != '\0'; cp++) {
                    if (*cp == ' ' || *cp == '\t') {
                        /*
                for (cp = start; *cp != '\0'; cp++) {
                    if (*cp == ' ' || *cp == '\t') {
                        /*
@@ -1468,7 +1495,6 @@ SuffFindArchiveDeps(gn)
     };
     char       *vals[sizeof(copy)/sizeof(copy[0])];
     int                i;          /* Index into copy and vals */
     };
     char       *vals[sizeof(copy)/sizeof(copy[0])];
     int                i;          /* Index into copy and vals */
-    char       *cp;        /* Suffix for member */
     Suff       *ms;        /* Suffix descriptor for member */
     char       *name;      /* Start of member's name */
     
     Suff       *ms;        /* Suffix descriptor for member */
     char       *name;      /* Start of member's name */
     
@@ -1476,8 +1502,8 @@ SuffFindArchiveDeps(gn)
      * The node is an archive(member) pair. so we must find a
      * suffix for both of them.
      */
      * The node is an archive(member) pair. so we must find a
      * suffix for both of them.
      */
-    eoarch = index (gn->name, '(');
-    eoname = index (eoarch, ')');
+    eoarch = strchr (gn->name, '(');
+    eoname = strchr (eoarch, ')');
 
     *eoname = '\0';      /* Nuke parentheses during suffix search */
     *eoarch = '\0';      /* So a suffix can be found */
 
     *eoname = '\0';      /* Nuke parentheses during suffix search */
     *eoarch = '\0';      /* So a suffix can be found */
@@ -1597,7 +1623,6 @@ SuffFindNormalDeps(gn)
 {
     char       *eoname;    /* End of name */
     char       *sopref;    /* Start of prefix */
 {
     char       *eoname;    /* End of name */
     char       *sopref;    /* Start of prefix */
-    Suff       *s;         /* Current suffix */
     LstNode    ln;         /* Next suffix node to check */
     Lst                srcs;       /* List of sources at which to look */
     Lst                targs;      /* List of targets to which things can be
     LstNode    ln;         /* Next suffix node to check */
     Lst                srcs;       /* List of sources at which to look */
     Lst                targs;      /* List of targets to which things can be
@@ -1663,7 +1688,7 @@ SuffFindNormalDeps(gn)
             */
            prefLen = (eoname - targ->suff->nameLen) - sopref;
            targ->pref = emalloc(prefLen + 1);
             */
            prefLen = (eoname - targ->suff->nameLen) - sopref;
            targ->pref = emalloc(prefLen + 1);
-           bcopy(sopref, targ->pref, prefLen);
+           memcpy(targ->pref, sopref, prefLen);
            targ->pref[prefLen] = '\0';
 
            /*
            targ->pref[prefLen] = '\0';
 
            /*
@@ -1723,9 +1748,8 @@ SuffFindNormalDeps(gn)
         * Work up the transformation path to find the suffix of the
         * target to which the transformation was made.
         */
         * Work up the transformation path to find the suffix of the
         * target to which the transformation was made.
         */
-       for (targ = bottom; targ->parent != NULL; targ = targ->parent) {
-           ;
-       }
+       for (targ = bottom; targ->parent != NULL; targ = targ->parent)
+           continue;
     }
 
     /*
     }
 
     /*
@@ -2092,19 +2116,19 @@ SuffPrintSuff (s)
                    printf ("LIBRARY");
                    break;
            }
                    printf ("LIBRARY");
                    break;
            }
-           putc(flags ? '|' : ')', stdout);
+           fputc(flags ? '|' : ')', stdout);
        }
     }
        }
     }
-    putc ('\n', stdout);
+    fputc ('\n', stdout);
     printf ("#\tTo: ");
     Lst_ForEach (s->parents, SuffPrintName, (ClientData)0);
     printf ("#\tTo: ");
     Lst_ForEach (s->parents, SuffPrintName, (ClientData)0);
-    putc ('\n', stdout);
+    fputc ('\n', stdout);
     printf ("#\tFrom: ");
     Lst_ForEach (s->children, SuffPrintName, (ClientData)0);
     printf ("#\tFrom: ");
     Lst_ForEach (s->children, SuffPrintName, (ClientData)0);
-    putc ('\n', stdout);
+    fputc ('\n', stdout);
     printf ("#\tSearch Path: ");
     Dir_PrintPath (s->searchPath);
     printf ("#\tSearch Path: ");
     Dir_PrintPath (s->searchPath);
-    putc ('\n', stdout);
+    fputc ('\n', stdout);
     return (0);
 }
 
     return (0);
 }
 
@@ -2116,12 +2140,13 @@ SuffPrintTrans (t)
 
     printf ("%-16s: ", t->name);
     Targ_PrintType (t->type);
 
     printf ("%-16s: ", t->name);
     Targ_PrintType (t->type);
-    putc ('\n', stdout);
+    fputc ('\n', stdout);
     Lst_ForEach (t->commands, Targ_PrintCmd, (ClientData)0);
     Lst_ForEach (t->commands, Targ_PrintCmd, (ClientData)0);
-    putc ('\n', stdout);
+    fputc ('\n', stdout);
     return(0);
 }
 
     return(0);
 }
 
+void
 Suff_PrintAll()
 {
     printf ("#*** Suffixes:\n");
 Suff_PrintAll()
 {
     printf ("#*** Suffixes:\n");
@@ -2130,4 +2155,3 @@ Suff_PrintAll()
     printf ("#*** Transformations:\n");
     Lst_ForEach (transforms, SuffPrintTrans, (ClientData)0);
 }
     printf ("#*** Transformations:\n");
     Lst_ForEach (transforms, SuffPrintTrans, (ClientData)0);
 }
-
index 76a34e5..962a593 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)targ.c     5.9 (Berkeley) %G%";
+static char sccsid[] = "@(#)targ.c     5.10 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -57,6 +57,7 @@ static char sccsid[] = "@(#)targ.c    5.9 (Berkeley) %G%";
 #include         <time.h>
 #include         "make.h"
 #include         "hash.h"
 #include         <time.h>
 #include         "make.h"
 #include         "hash.h"
+#include         "dir.h"
 
 static Lst        allTargets;  /* the list of all targets found so far */
 static Hash_Table targets;     /* a hash table of same */
 
 static Lst        allTargets;  /* the list of all targets found so far */
 static Hash_Table targets;     /* a hash table of same */
@@ -122,6 +123,7 @@ Targ_NewGN (name)
     gn->preds =        Lst_Init(FALSE);
     gn->context =      Lst_Init (FALSE);
     gn->commands =     Lst_Init (FALSE);
     gn->preds =        Lst_Init(FALSE);
     gn->context =      Lst_Init (FALSE);
     gn->commands =     Lst_Init (FALSE);
+    gn->suffix =       NULL;
 
     return (gn);
 }
 
     return (gn);
 }
@@ -315,6 +317,7 @@ Targ_SetMain (gn)
 }
 
 static int
 }
 
 static int
+/*ARGSUSED*/
 TargPrintName (gn, ppath)
     GNode          *gn;
     int                    ppath;
 TargPrintName (gn, ppath)
     GNode          *gn;
     int                    ppath;
@@ -329,7 +332,7 @@ TargPrintName (gn, ppath)
            printf ("(MAIN NAME)  ");
        }
     }
            printf ("(MAIN NAME)  ");
        }
     }
-#endif notdef
+#endif /* notdef */
     return (0);
 }
 
     return (0);
 }
 
@@ -469,13 +472,13 @@ TargPrintNode (gn, pass)
            if (!Lst_IsEmpty (gn->iParents)) {
                printf("# implicit parents: ");
                Lst_ForEach (gn->iParents, TargPrintName, (ClientData)0);
            if (!Lst_IsEmpty (gn->iParents)) {
                printf("# implicit parents: ");
                Lst_ForEach (gn->iParents, TargPrintName, (ClientData)0);
-               putc ('\n', stdout);
+               fputc ('\n', stdout);
            }
        }
        if (!Lst_IsEmpty (gn->parents)) {
            printf("# parents: ");
            Lst_ForEach (gn->parents, TargPrintName, (ClientData)0);
            }
        }
        if (!Lst_IsEmpty (gn->parents)) {
            printf("# parents: ");
            Lst_ForEach (gn->parents, TargPrintName, (ClientData)0);
-           putc ('\n', stdout);
+           fputc ('\n', stdout);
        }
        
        printf("%-16s", gn->name);
        }
        
        printf("%-16s", gn->name);
@@ -489,7 +492,7 @@ TargPrintNode (gn, pass)
        }
        Targ_PrintType (gn->type);
        Lst_ForEach (gn->children, TargPrintName, (ClientData)0);
        }
        Targ_PrintType (gn->type);
        Lst_ForEach (gn->children, TargPrintName, (ClientData)0);
-       putc ('\n', stdout);
+       fputc ('\n', stdout);
        Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0);
        printf("\n\n");
        if (gn->type & OP_DOUBLEDEP) {
        Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0);
        printf("\n\n");
        if (gn->type & OP_DOUBLEDEP) {
@@ -535,6 +538,7 @@ TargPrintOnlySrc(gn)
  *     lots o' output
  *-----------------------------------------------------------------------
  */
  *     lots o' output
  *-----------------------------------------------------------------------
  */
+void
 Targ_PrintGraph (pass)
     int            pass;       /* Which pass this is. 1 => no processing
                         * 2 => processing done */
 Targ_PrintGraph (pass)
     int            pass;       /* Which pass this is. 1 => no processing
                         * 2 => processing done */
index a3c3d64..7601d47 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)var.c      5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)var.c      5.9 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -35,7 +35,8 @@ static char sccsid[] = "@(#)var.c     5.8 (Berkeley) %G%";
  *     Var_Value           Return the value of a variable in a context or
  *                         NULL if the variable is undefined.
  *
  *     Var_Value           Return the value of a variable in a context or
  *                         NULL if the variable is undefined.
  *
- *     Var_Subst           Substitute for all variables in a string using
+ *     Var_Subst           Substitute named variable, or all variables if
+ *                         NULL in a string using
  *                         the given context as the top-most one. If the
  *                         third argument is non-zero, Parse_Error is
  *                         called if any variables are undefined.
  *                         the given context as the top-most one. If the
  *                         third argument is non-zero, Parse_Error is
  *                         called if any variables are undefined.
@@ -58,7 +59,6 @@ static char sccsid[] = "@(#)var.c     5.8 (Berkeley) %G%";
 #include    <ctype.h>
 #include    "make.h"
 #include    "buf.h"
 #include    <ctype.h>
 #include    "make.h"
 #include    "buf.h"
-extern char *getenv();
 
 /*
  * This is a harmless return value for Var_Parse that can be used by Var_Subst
 
 /*
  * This is a harmless return value for Var_Parse that can be used by Var_Subst
@@ -72,7 +72,7 @@ char  var_Error[] = "";
  * set false. Why not just use a constant? Well, gcc likes to condense
  * identical string instances...
  */
  * set false. Why not just use a constant? Well, gcc likes to condense
  * identical string instances...
  */
-char   varNoError[] = "";
+static char    varNoError[] = "";
 
 /*
  * Internally, variables are contained in four different contexts.
 
 /*
  * Internally, variables are contained in four different contexts.
@@ -110,6 +110,31 @@ typedef struct Var {
                                     * modified variables */
 }  Var;
 
                                     * modified variables */
 }  Var;
 
+typedef struct {
+    char         *lhs;     /* String to match */
+    int                  leftLen;  /* Length of string */
+    char         *rhs;     /* Replacement string (w/ &'s removed) */
+    int                  rightLen; /* Length of replacement */
+    int                  flags;
+#define VAR_SUB_GLOBAL 1   /* Apply substitution globally */
+#define VAR_MATCH_START        2   /* Match at start of word */
+#define VAR_MATCH_END  4   /* Match at end of word */
+#define VAR_NO_SUB     8   /* Substitution is non-global and already done */
+} VarPattern;
+
+static int VarCmp __P((Var *, char *));
+static Var *VarFind __P((char *, GNode *, int));
+static void VarAdd __P((char *, char *, GNode *));
+static Boolean VarHead __P((char *, Boolean, Buffer));
+static Boolean VarTail __P((char *, Boolean, Buffer));
+static Boolean VarSuffix __P((char *, Boolean, Buffer));
+static Boolean VarRoot __P((char *, Boolean, Buffer));
+static Boolean VarMatch __P((char *, Boolean, Buffer, char *));
+static Boolean VarNoMatch __P((char *, Boolean, Buffer, char *));
+static Boolean VarSubstitute __P((char *, Boolean, Buffer, VarPattern *));
+static char *VarModify __P((char *, Boolean (*modProc )(), ClientData));
+static int VarPrintVar __P((Var *));
+
 /*-
  *-----------------------------------------------------------------------
  * VarCmp  --
 /*-
  *-----------------------------------------------------------------------
  * VarCmp  --
@@ -263,7 +288,7 @@ VarFind (name, ctxt, flags)
  *     safely be freed.
  *-----------------------------------------------------------------------
  */
  *     safely be freed.
  *-----------------------------------------------------------------------
  */
-static
+static void
 VarAdd (name, val, ctxt)
     char           *name;      /* name of variable to add */
     char           *val;       /* value to set it to */
 VarAdd (name, val, ctxt)
     char           *name;      /* name of variable to add */
     char           *val;       /* value to set it to */
@@ -276,7 +301,7 @@ VarAdd (name, val, ctxt)
 
     v->name = strdup (name);
 
 
     v->name = strdup (name);
 
-    len = strlen(val);
+    len = val ? strlen(val) : 0;
     v->val = Buf_Init(len+1);
     Buf_AddBytes(v->val, len, (Byte *)val);
 
     v->val = Buf_Init(len+1);
     Buf_AddBytes(v->val, len, (Byte *)val);
 
@@ -406,7 +431,6 @@ Var_Append (name, val, ctxt)
     GNode          *ctxt;      /* Context in which this should occur */
 {
     register Var   *v;
     GNode          *ctxt;      /* Context in which this should occur */
 {
     register Var   *v;
-    register char  *cp;
 
     v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
 
 
     v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
 
@@ -516,7 +540,7 @@ VarHead (word, addSpace, buf)
 {
     register char *slash;
 
 {
     register char *slash;
 
-    slash = rindex (word, '/');
+    slash = strrchr (word, '/');
     if (slash != (char *)NULL) {
        if (addSpace) {
            Buf_AddByte (buf, (Byte)' ');
     if (slash != (char *)NULL) {
        if (addSpace) {
            Buf_AddByte (buf, (Byte)' ');
@@ -566,7 +590,7 @@ VarTail (word, addSpace, buf)
        Buf_AddByte (buf, (Byte)' ');
     }
 
        Buf_AddByte (buf, (Byte)' ');
     }
 
-    slash = rindex (word, '/');
+    slash = strrchr (word, '/');
     if (slash != (char *)NULL) {
        *slash++ = '\0';
        Buf_AddBytes (buf, strlen(slash), (Byte *)slash);
     if (slash != (char *)NULL) {
        *slash++ = '\0';
        Buf_AddBytes (buf, strlen(slash), (Byte *)slash);
@@ -600,7 +624,7 @@ VarSuffix (word, addSpace, buf)
 {
     register char *dot;
 
 {
     register char *dot;
 
-    dot = rindex (word, '.');
+    dot = strrchr (word, '.');
     if (dot != (char *)NULL) {
        if (addSpace) {
            Buf_AddByte (buf, (Byte)' ');
     if (dot != (char *)NULL) {
        if (addSpace) {
            Buf_AddByte (buf, (Byte)' ');
@@ -642,7 +666,7 @@ VarRoot (word, addSpace, buf)
        Buf_AddByte (buf, (Byte)' ');
     }
 
        Buf_AddByte (buf, (Byte)' ');
     }
 
-    dot = rindex (word, '.');
+    dot = strrchr (word, '.');
     if (dot != (char *)NULL) {
        *dot = '\0';
        Buf_AddBytes (buf, strlen (word), (Byte *)word);
     if (dot != (char *)NULL) {
        *dot = '\0';
        Buf_AddBytes (buf, strlen (word), (Byte *)word);
@@ -721,17 +745,6 @@ VarNoMatch (word, addSpace, buf, pattern)
     return(addSpace);
 }
 
     return(addSpace);
 }
 
-typedef struct {
-    char         *lhs;     /* String to match */
-    int                  leftLen;  /* Length of string */
-    char         *rhs;     /* Replacement string (w/ &'s removed) */
-    int                  rightLen; /* Length of replacement */
-    int                  flags;
-#define VAR_SUB_GLOBAL 1   /* Apply substitution globally */
-#define VAR_MATCH_START        2   /* Match at start of word */
-#define VAR_MATCH_END  4   /* Match at end of word */
-#define VAR_NO_SUB     8   /* Substitution is non-global and already done */
-} VarPattern;
 
 /*-
  *-----------------------------------------------------------------------
 
 /*-
  *-----------------------------------------------------------------------
@@ -940,16 +953,15 @@ VarModify (str, modProc, datum)
     cp = str;
     addSpace = FALSE;
     
     cp = str;
     addSpace = FALSE;
     
-    while (1) {
+    for (;;) {
        /*
         * Skip to next word and place cp at its end.
         */
        while (isspace (*str)) {
            str++;
        }
        /*
         * Skip to next word and place cp at its end.
         */
        while (isspace (*str)) {
            str++;
        }
-       for (cp = str; *cp != '\0' && !isspace (*cp); cp++) {
-           /* void */ ;
-       }
+       for (cp = str; *cp != '\0' && !isspace (*cp); cp++) 
+           continue;
        if (cp == str) {
            /*
             * If we didn't go anywhere, we must be done!
        if (cp == str) {
            /*
             * If we didn't go anywhere, we must be done!
@@ -1230,8 +1242,8 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
      * return.
      */
     str = (char *)Buf_GetAll(v->val, (int *)NULL);
      * return.
      */
     str = (char *)Buf_GetAll(v->val, (int *)NULL);
-    if (index (str, '$') != (char *)NULL) {
-       str = Var_Subst(str, ctxt, err);
+    if (strchr (str, '$') != (char *)NULL) {
+       str = Var_Subst(NULL, str, ctxt, err);
        *freePtr = TRUE;
     }
     
        *freePtr = TRUE;
     }
     
@@ -1325,8 +1337,6 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
                    VarPattern      pattern;
                    register char   delim;
                    Buffer          buf;        /* Buffer for patterns */
                    VarPattern      pattern;
                    register char   delim;
                    Buffer          buf;        /* Buffer for patterns */
-                   register char   *cp2;
-                   int             lefts;
 
                    pattern.flags = 0;
                    delim = tstr[1];
 
                    pattern.flags = 0;
                    delim = tstr[1];
@@ -1552,9 +1562,8 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
                         * Now we break this sucker into the lhs and
                         * rhs. We must null terminate them of course.
                         */
                         * Now we break this sucker into the lhs and
                         * rhs. We must null terminate them of course.
                         */
-                       for (cp = tstr; *cp != '='; cp++) {
-                           ;
-                       }
+                       for (cp = tstr; *cp != '='; cp++)
+                           continue;
                        pattern.lhs = tstr;
                        pattern.leftLen = cp - tstr;
                        *cp++ = '\0';
                        pattern.lhs = tstr;
                        pattern.leftLen = cp - tstr;
                        *cp++ = '\0';
@@ -1585,9 +1594,8 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
                        Error ("Unknown modifier '%c'\n", *tstr);
                        for (cp = tstr+1;
                             *cp != ':' && *cp != endc && *cp != '\0';
                        Error ("Unknown modifier '%c'\n", *tstr);
                        for (cp = tstr+1;
                             *cp != ':' && *cp != endc && *cp != '\0';
-                            cp++) {
-                                ;
-                       }
+                            cp++) 
+                                continue;
                        termc = *cp;
                        newStr = var_Error;
                    }
                        termc = *cp;
                        newStr = var_Error;
                    }
@@ -1672,8 +1680,9 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
  *-----------------------------------------------------------------------
  */
 char *
  *-----------------------------------------------------------------------
  */
 char *
-Var_Subst (str, ctxt, undefErr)
-    register char *str;                    /* the string in which to substitute */
+Var_Subst (var, str, ctxt, undefErr)
+    char         *var;             /* Named variable || NULL for all */
+    char         *str;             /* the string in which to substitute */
     GNode         *ctxt;           /* the context wherein to find variables */
     Boolean      undefErr;         /* TRUE if undefineds are an error */
 {
     GNode         *ctxt;           /* the context wherein to find variables */
     Boolean      undefErr;         /* TRUE if undefineds are an error */
 {
@@ -1685,11 +1694,11 @@ Var_Subst (str, ctxt, undefErr)
                                     * been reported to prevent a plethora
                                     * of messages when recursing */
 
                                     * been reported to prevent a plethora
                                     * of messages when recursing */
 
-    buf = Buf_Init (BSIZE);
+    buf = Buf_Init (MAKE_BSIZE);
     errorReported = FALSE;
 
     while (*str) {
     errorReported = FALSE;
 
     while (*str) {
-       if ((*str == '$') && (str[1] == '$')) {
+       if (var == NULL && (*str == '$') && (str[1] == '$')) {
            /*
             * A dollar sign may be escaped either with another dollar sign.
             * In such a case, we skip over the escape character and store the
            /*
             * A dollar sign may be escaped either with another dollar sign.
             * In such a case, we skip over the escape character and store the
@@ -1705,11 +1714,65 @@ Var_Subst (str, ctxt, undefErr)
             */
            char  *cp;
 
             */
            char  *cp;
 
-           for (cp = str++; *str != '$' && *str != '\0'; str++) {
-               ;
-           }
+           for (cp = str++; *str != '$' && *str != '\0'; str++)
+               continue;
            Buf_AddBytes(buf, str - cp, (Byte *)cp);
        } else {
            Buf_AddBytes(buf, str - cp, (Byte *)cp);
        } else {
+           if (var != NULL) {
+               int expand;
+               for (;;) {
+                   if (str[1] != '(' && str[1] != '{') {
+                       if (str[1] != *var) {
+                           Buf_AddBytes(buf, 2, (Byte *) str);
+                           str += 2;
+                           expand = FALSE;
+                       }
+                       else
+                           expand = TRUE;
+                       break;
+                   }
+                   else {
+                       char *p;
+
+                       /*
+                        * Scan up to the end of the variable name.
+                        */
+                       for (p = &str[2]; *p && 
+                            *p != ':' && *p != ')' && *p != '}'; p++)
+                           if (*p == '$') 
+                               break;
+                       /*
+                        * A variable inside the variable. We cannot expand
+                        * the external variable yet, so we try again with
+                        * the nested one
+                        */
+                       if (*p == '$') {
+                           Buf_AddBytes(buf, p - str, (Byte *) str);
+                           str = p;
+                           continue;
+                       }
+                               
+                       if (strncmp(var, str + 2, p - str - 2) != 0 || 
+                           var[p - str - 2] != '\0') {
+                           /*
+                            * Not the variable we want to expand, scan
+                            * until the next variable
+                            */
+                           for (;*p != '$' && *p != '\0'; p++) 
+                               continue;
+                           Buf_AddBytes(buf, p - str, (Byte *) str);
+                           str = p;
+                           expand = FALSE;
+                       }
+                       else
+                           expand = TRUE;
+                       break;
+                   }
+               }
+               if (!expand)
+                   continue;
+           }
+                       
            val = Var_Parse (str, ctxt, undefErr, &length, &doFree);
 
            /*
            val = Var_Parse (str, ctxt, undefErr, &length, &doFree);
 
            /*
@@ -1832,7 +1895,7 @@ Var_Init ()
 }
 
 /****************** PRINT DEBUGGING INFO *****************/
 }
 
 /****************** PRINT DEBUGGING INFO *****************/
-static
+static int
 VarPrintVar (v)
     Var            *v;
 {
 VarPrintVar (v)
     Var            *v;
 {
@@ -1846,6 +1909,7 @@ VarPrintVar (v)
  *     print all variables in a context
  *-----------------------------------------------------------------------
  */
  *     print all variables in a context
  *-----------------------------------------------------------------------
  */
+void
 Var_Dump (ctxt)
     GNode          *ctxt;
 {
 Var_Dump (ctxt)
     GNode          *ctxt;
 {