BSD 4_4_Lite1 release
[unix-history] / usr / src / usr.bin / make / main.c
index 602fcfc..7b3f5a5 100644 (file)
@@ -1,33 +1,49 @@
 /*
 /*
- * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
- * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1988, 1989, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  * Copyright (c) 1989 by Berkeley Softworks
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Adam de Boor.
  *
  * Copyright (c) 1989 by Berkeley Softworks
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Adam de Boor.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     8.3 (Berkeley) 3/19/94";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -36,132 +52,82 @@ static char sccsid[] = "@(#)main.c 5.6 (Berkeley) %G%";
  *     reside here.
  *
  * Utility functions defined in this file:
  *     reside here.
  *
  * Utility functions defined in this file:
- *     Main_ParseArgLine       Takes a line of arguments, breaks them and
- *                             treats them as if they were given when first
- *                             invoked. Used by the parse module to implement
- *                             the .MFLAGS target.
+ *     Main_ParseArgLine       Takes a line of arguments, breaks them and
+ *                             treats them as if they were given when first
+ *                             invoked. Used by the parse module to implement
+ *                             the .MFLAGS target.
  *
  *
- *     Error                   Print a tagged error message. The global
- *                             MAKE variable must have been defined. This
- *                             takes a format string and two optional
- *                             arguments for it.
+ *     Error                   Print a tagged error message. The global
+ *                             MAKE variable must have been defined. This
+ *                             takes a format string and two optional
+ *                             arguments for it.
  *
  *
- *     Fatal                   Print an error message and exit. Also takes
- *                             a format string and two arguments.
+ *     Fatal                   Print an error message and exit. Also takes
+ *                             a format string and two arguments.
  *
  *
- *     Punt                    Aborts all jobs and exits with a message. Also
- *                             takes a format string and two arguments.
+ *     Punt                    Aborts all jobs and exits with a message. Also
+ *                             takes a format string and two arguments.
  *
  *
- *     Finish                  Finish things up by printing the number of
- *                             errors which occured, as passed to it, and
- *                             exiting.
+ *     Finish                  Finish things up by printing the number of
+ *                             errors which occured, as passed to it, and
+ *                             exiting.
  */
 
  */
 
-#include    <sys/types.h>
-#include    <sys/signal.h>
-#include    <sys/stat.h>
-#include    <sys/errno.h>
-#include    <fcntl.h>
-#include    <ctype.h>
-#include    <stdio.h>
-#include    "make.h"
-
-extern int errno;
-
-
-#ifndef DEFMAXLOCAL
-#define DEFMAXLOCAL DEFMAXJOBS
-#endif  DEFMAXLOCAL
-
-#define MAKEFLAGS      ".MAKEFLAGS"
-
-static char            *progName;      /* Our invocation name */
-Lst                    create;         /* Targets to be made */
-time_t                 now;            /* Time at start of make */
-GNode                  *DEFAULT;       /* .DEFAULT node */
-Boolean                        allPrecious;    /* .PRECIOUS given on line by itself */
-
-static int              printGraph;    /* -p flag */
-static Boolean          noBuiltins;    /* -r flag */
-static Lst             makefiles;      /* List of makefiles to read (in
-                                        * order) */
-int                    maxJobs;        /* -J argument */
-static int             maxLocal;       /* -L argument */
-Boolean                        debug;          /* -d flag */
-Boolean                        amMake;         /* -M flag */
-Boolean                        noWarnings;     /* -W flag */
-Boolean                        noExecute;      /* -n flag */
-Boolean                        keepgoing;      /* -k flag */
-Boolean                        queryFlag;      /* -q flag */
-Boolean                        touchFlag;      /* -t flag */
-Boolean                        usePipes;       /* !-P flag */
-Boolean                        backwards;      /* -B flag */
-Boolean                        ignoreErrors;   /* -i flag */
-Boolean                        beSilent;       /* -s flag */
-Boolean                        sysVmake;       /* -v flag */
-Boolean                        oldVars;        /* -V flag */
-Boolean                        checkEnvFirst;  /* -e flag */
-static Boolean         XFlag=FALSE;    /* -X flag given */
-static Boolean         xFlag=FALSE;    /* -x flag given */
-Boolean                        noExport;       /* Set TRUE if shouldn't export */
-static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
-
-static Boolean         ReadMakefile();
-
-/*
- * Initial value for optind when parsing args. Different getopts start it
- * differently...
- */
-static int     initOptInd;
-
-#ifdef CAN_EXPORT
-#define OPTSTR "BCD:I:J:L:MPSVWXd:ef:iknp:qrstvxh"
+#include <sys/types.h>
+#include <sys/time.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>
+#if __STDC__
+#include <stdarg.h>
 #else
 #else
-#define OPTSTR "BCD:I:J:L:MPSVWd:ef:iknp:qrstvh"
+#include <varargs.h>
 #endif
 #endif
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
+#include "pathnames.h"
+
+#ifndef        DEFMAXLOCAL
+#define        DEFMAXLOCAL DEFMAXJOBS
+#endif DEFMAXLOCAL
+
+#define        MAKEFLAGS       ".MAKEFLAGS"
+
+Lst                    create;         /* Targets to be made */
+time_t                 now;            /* Time at start of make */
+GNode                  *DEFAULT;       /* .DEFAULT node */
+Boolean                        allPrecious;    /* .PRECIOUS given on line by itself */
+
+static Boolean         noBuiltins;     /* -r flag */
+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                        queryFlag;      /* -q flag */
+Boolean                        touchFlag;      /* -t flag */
+Boolean                        usePipes;       /* !-P flag */
+Boolean                        ignoreErrors;   /* -i flag */
+Boolean                        beSilent;       /* -s flag */
+Boolean                        oldVars;        /* variable substitution style */
+Boolean                        checkEnvFirst;  /* -e flag */
+static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
 
 
-static char        *help[] = {
-"-B            Be as backwards-compatible with make as possible without\n\
-               being make.",
-"-C            Cancel any current indications of compatibility.",
-"-D<var>       Define the variable <var> with value 1.",
-"-I<dir>       Specify another directory in which to search for included\n\
-               makefiles.",
-"-J<num>       Specify maximum overall concurrency.",
-"-L<num>       Specify maximum local concurrency.",
-"-M            Be Make as closely as possible.",
-"-P            Don't use pipes to catch the output of jobs, use files.",
-"-S            Turn off the -k flag (see below).",
-#ifndef POSIX
-"-V            Use old-style variable substitution.",
-#endif
-"-W            Don't print warning messages.",
-#ifdef CAN_EXPORT
-"-X            Turn off exporting of commands.",
-#endif
-"-d<flags>     Turn on debugging output.",
-"-e            Give environment variables precedence over those in the\n\
-               makefile(s).",
-"-f<file>      Specify a(nother) makefile to read",
-"-i            Ignore errors from executed commands.",
-"-k            On error, continue working on targets that do not depend on\n\
-               the one for which an error was detected.",
-"-n            Don't execute commands, just print them.",
-"-p<num>       Tell when to print the input graph: 1 (before processing),\n\
-               2 (after processing), or 3 (both).",
-"-q            See if anything needs to be done. Exits 1 if so.",
-"-r            Do not read the system makefile for pre-defined rules.",
-"-s            Don't print commands as they are executed.",
-"-t            Update targets by \"touching\" them (see touch(1)).",
-"-v            Be compatible with System V make. Implies -B, -V.",
-#ifdef CAN_EXPORT
-"-x            Allow exportation of commands.",
-#endif
-};
+static Boolean         ReadMakefile();
+static void            usage();
 
 
+static char *curdir;                   /* startup directory */
+static char *objdir;                   /* where we chdir'ed to */
 
 /*-
 
 /*-
- *----------------------------------------------------------------------
  * MainParseArgs --
  *     Parse a given argument vector. Called from main() and from
  *     Main_ParseArgLine() when the .MAKEFLAGS target is used.
  * MainParseArgs --
  *     Parse a given argument vector. Called from main() and from
  *     Main_ParseArgLine() when the .MAKEFLAGS target is used.
@@ -174,207 +140,179 @@ static char         *help[] = {
  * Side Effects:
  *     Various global and local flags will be set depending on the flags
  *     given
  * Side Effects:
  *     Various global and local flags will be set depending on the flags
  *     given
- *----------------------------------------------------------------------
  */
 static void
  */
 static void
-MainParseArgs (argc, argv)
-    int                  argc;       /* Number of arguments in argv */
-    char         **argv;     /* The arguments themselves */
+MainParseArgs(argc, argv)
+       int argc;
+       char **argv;
 {
 {
-    register int  i;
-    register char *cp;
-    extern int optind;
-    extern char        *optarg;
-    char       c;
-
-    optind = initOptInd;
-
-    while((c = getopt(argc, argv, OPTSTR)) != -1) {
-       switch(c) {
-           case 'B':
-               backwards = oldVars = TRUE;
-               Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
-               break;
-           case 'C':
-               oldVars = backwards = sysVmake = amMake = FALSE;
-               Var_Append(MAKEFLAGS, "-C", VAR_GLOBAL);
-               break;
-           case 'D':
-               Var_Set(optarg, "1", VAR_GLOBAL);
-               Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
-               Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
-               break;
-           case 'I':
-               Parse_AddIncludeDir(optarg);
-               Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
-               Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
-               break;
-           case 'J':
-               maxJobs = atoi(optarg);
-               Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
-               Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
-               break;
-           case 'L':
-               maxLocal = atoi(optarg);
-               Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
-               Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
-               break;
-           case 'M':
-               amMake = TRUE;
-               Var_Append(MAKEFLAGS, "-M", VAR_GLOBAL);
-               break;
-           case 'P':
-               usePipes = FALSE;
-               Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
-               break;
-           case 'S':
-               keepgoing = FALSE;
-               Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
-               break;
-           case 'V':
-               oldVars = TRUE;
-               Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
-               break;
-           case 'W':
-               noWarnings = TRUE;
-               Var_Append(MAKEFLAGS, "-W", VAR_GLOBAL);
-               break;
-           case 'X':
-               XFlag = TRUE;
-               Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
-               break;
-           case 'd':
-           {
-               char    *modules = optarg;
-
-               while (*modules) {
-                   switch (*modules) {
-                       case 's':
-                           debug |= DEBUG_SUFF;
-                           break;
-                       case 'm':
-                           debug |= DEBUG_MAKE;
-                           break;
-                       case 'j':
-                           debug |= DEBUG_JOB;
-                           break;
-                       case 't':
-                           debug |= DEBUG_TARG;
-                           break;
-                       case 'd':
-                           debug |= DEBUG_DIR;
-                           break;
-                       case 'v':
-                           debug |= DEBUG_VAR;
-                           break;
-                       case 'c':
-                           debug |= DEBUG_COND;
-                           break;
-                       case 'p':
-                           debug |= DEBUG_PARSE;
-                           break;
-                       case 'r':
-                           debug |= DEBUG_RMT;
-                           break;
-                       case 'a':
-                           debug |= DEBUG_ARCH;
-                           break;
-                       case '*':
-                           debug = ~0;
-                           break;
-                   }
-                   modules++;
+       extern int optind;
+       extern char *optarg;
+       char c;
+
+       optind = 1;     /* since we're called more than once */
+#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);
+                       Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
+                       Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+                       break;
+               case 'I':
+                       Parse_AddIncludeDir(optarg);
+                       Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
+                       Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+                       break;
+#ifdef notyet
+               case 'B':
+                       compatMake = TRUE;
+                       break;
+               case 'L':
+                       maxLocal = atoi(optarg);
+                       Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
+                       Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+                       break;
+               case 'P':
+                       usePipes = FALSE;
+                       Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
+                       break;
+               case 'S':
+                       keepgoing = FALSE;
+                       Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
+                       break;
+#endif
+               case 'd': {
+                       char *modules = optarg;
+
+                       for (; *modules; ++modules)
+                               switch (*modules) {
+                               case 'A':
+                                       debug = ~0;
+                                       break;
+                               case 'a':
+                                       debug |= DEBUG_ARCH;
+                                       break;
+                               case 'c':
+                                       debug |= DEBUG_COND;
+                                       break;
+                               case 'd':
+                                       debug |= DEBUG_DIR;
+                                       break;
+                               case 'f':
+                                       debug |= DEBUG_FOR;
+                                       break;
+                               case 'g':
+                                       if (modules[1] == '1') {
+                                               debug |= DEBUG_GRAPH1;
+                                               ++modules;
+                                       }
+                                       else if (modules[1] == '2') {
+                                               debug |= DEBUG_GRAPH2;
+                                               ++modules;
+                                       }
+                                       break;
+                               case 'j':
+                                       debug |= DEBUG_JOB;
+                                       break;
+                               case 'm':
+                                       debug |= DEBUG_MAKE;
+                                       break;
+                               case 's':
+                                       debug |= DEBUG_SUFF;
+                                       break;
+                               case 't':
+                                       debug |= DEBUG_TARG;
+                                       break;
+                               case 'v':
+                                       debug |= DEBUG_VAR;
+                                       break;
+                               default:
+                                       (void)fprintf(stderr,
+                               "make: illegal argument to d option -- %c\n",
+                                           *modules);
+                                       usage();
+                               }
+                       Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
+                       Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+                       break;
                }
                }
-               Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
-               Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
-               break;
-           }
-           case 'e':
-               checkEnvFirst = TRUE;
-               Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
-               break;
-           case 'f':
-               (void)Lst_AtEnd(makefiles, (ClientData)optarg);
-               break;
-           case 'i':
-               ignoreErrors = TRUE;
-               Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
-               break;
-           case 'k':
-               keepgoing = TRUE;
-               Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
-               break;
-           case 'n':
-               noExecute = TRUE;
-               Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
-               break;
-           case 'p':
-               printGraph = atoi(optarg);
-               break;
-           case 'q':
-               queryFlag = TRUE;
-               Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); /* Kind of
-                                                         * nonsensical, wot?
-                                                         */
-               break;
-           case 'r':
-               noBuiltins = TRUE;
-               Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
-               break;
-           case 's':
-               beSilent = TRUE;
-               Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
-               break;
-           case 't':
-               touchFlag = TRUE;
-               Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
-               break;
-           case 'v':
-               sysVmake = oldVars = backwards = TRUE;
-               Var_Append(MAKEFLAGS, "-v", VAR_GLOBAL);
-               break;
-           case 'h':
-           case '?':
-           {
-               int     i;
-
-               for (i = 0; i < sizeof(help)/sizeof(help[0]); i++) {
-                   printf("%s\n", help[i]);
+               case 'e':
+                       checkEnvFirst = TRUE;
+                       Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
+                       break;
+               case 'f':
+                       (void)Lst_AtEnd(makefiles, (ClientData)optarg);
+                       break;
+               case 'i':
+                       ignoreErrors = TRUE;
+                       Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
+                       break;
+               case 'j':
+                       maxJobs = atoi(optarg);
+                       Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
+                       Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+                       break;
+               case 'k':
+                       keepgoing = TRUE;
+                       Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
+                       break;
+               case 'n':
+                       noExecute = TRUE;
+                       Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
+                       break;
+               case 'q':
+                       queryFlag = TRUE;
+                       /* Kind of nonsensical, wot? */
+                       Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
+                       break;
+               case 'r':
+                       noBuiltins = TRUE;
+                       Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
+                       break;
+               case 's':
+                       beSilent = TRUE;
+                       Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
+                       break;
+               case 't':
+                       touchFlag = TRUE;
+                       Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
+                       break;
+               default:
+               case '?':
+                       usage();
                }
                }
-               exit(c == '?' ? -1 : 0);
-           }
        }
        }
-    }
-
-    /*
-     * Take care of encompassing compatibility levels...
-     */
-    if (amMake) {
-       backwards = TRUE;
-    }
-    if (backwards) {
+
        oldVars = TRUE;
        oldVars = TRUE;
-    }
-
-    /*
-     * See if the rest of the arguments are variable assignments and perform
-     * them if so. Else take them to be targets and stuff them on the end
-     * of the "create" list.
-     */
-    for (i = optind; i < argc; i++) {
-       if (Parse_IsVar (argv[i])) {
-           Parse_DoVar(argv[i], VAR_CMD);
-       } else {
-           if (argv[i][0] == 0) {
-               Punt("Bogus argument in MainParseArgs");
-           }
-           (void)Lst_AtEnd (create, (ClientData)argv[i]);
-       }
-    }
+
+       /*
+        * See if the rest of the arguments are variable assignments and
+        * perform them if so. Else take them to be targets and stuff them
+        * on the end of the "create" list.
+        */
+       for (argv += optind, argc -= optind; *argv; ++argv, --argc)
+               if (Parse_IsVar(*argv))
+                       Parse_DoVar(*argv, VAR_CMD);
+               else {
+                       if (!**argv)
+                               Punt("illegal (null) argument.");
+                       if (**argv == '-') {
+                               if ((*argv)[1])
+                                       optind = 0;     /* -flag... */
+                               else
+                                       optind = 1;     /* - */
+                               goto rearg;
+                       }
+                       (void)Lst_AtEnd(create, (ClientData)*argv);
+               }
 }
 
 /*-
 }
 
 /*-
- *----------------------------------------------------------------------
  * Main_ParseArgLine --
  *     Used by the parse module when a .MFLAGS or .MAKEFLAGS target
  *     is encountered and by main() when reading the .MAKEFLAGS envariable.
  * Main_ParseArgLine --
  *     Used by the parse module when a .MFLAGS or .MAKEFLAGS target
  *     is encountered and by main() when reading the .MAKEFLAGS envariable.
@@ -388,27 +326,26 @@ MainParseArgs (argc, argv)
  *
  * Side Effects:
  *     Only those that come from the various arguments.
  *
  * Side Effects:
  *     Only those that come from the various arguments.
- *-----------------------------------------------------------------------
  */
 void
  */
 void
-Main_ParseArgLine (line)
-    char         *line;      /* Line to fracture */
+Main_ParseArgLine(line)
+       char *line;                     /* Line to fracture */
 {
 {
-    char         **argv;     /* Manufactured argument vector */
-    int          argc;       /* Number of arguments in argv */
-
-    if (line == NULL) return;
-    while (*line == ' ') line++;
+       char **argv;                    /* Manufactured argument vector */
+       int argc;                       /* Number of arguments in argv */
 
 
-    argv = Str_BreakString (line, " \t", "\n", &argc);
-
-    MainParseArgs(argc, argv);
+       if (line == NULL)
+               return;
+       for (; *line == ' '; ++line)
+               continue;
+       if (!*line)
+               return;
 
 
-    Str_FreeVec(argc, argv);
+       argv = brk_string(line, &argc);
+       MainParseArgs(argc, argv);
 }
 
 /*-
 }
 
 /*-
- *----------------------------------------------------------------------
  * main --
  *     The main function, for obvious reasons. Initializes variables
  *     and a few modules, then parses the arguments give it in the
  * main --
  *     The main function, for obvious reasons. Initializes variables
  *     and a few modules, then parses the arguments give it in the
@@ -424,304 +361,313 @@ 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.
- *
- *----------------------------------------------------------------------
  */
  */
-main (argc, argv)
-    int           argc;
-    char          **argv;
+int
+main(argc, argv)
+       int argc;
+       char **argv;
 {
 {
-    Lst             targs;             /* list of target nodes to create. Passed to
-                                * Make_Init */
-    Boolean         outOfDate;         /* FALSE if all targets up to date */
-    char           *cp;
-    extern int     optind;
-
-
-    create = Lst_Init (FALSE);
-    makefiles = Lst_Init(FALSE);
-
-    beSilent = FALSE;          /* Print commands as executed */
-    ignoreErrors = FALSE;      /* Pay attention to non-zero returns */
-    noExecute = FALSE;         /* Execute all commands */
-    keepgoing = FALSE;         /* Stop on error */
-    allPrecious = FALSE;       /* Remove targets when interrupted */
-    queryFlag = FALSE;         /* This is not just a check-run */
-    noBuiltins = FALSE;                /* Read the built-in rules */
-    touchFlag = FALSE;         /* Actually update targets */
-    usePipes = TRUE;           /* Catch child output in pipes */
-    debug = 0;                 /* No debug verbosity, please. */
-    noWarnings = FALSE;                /* Print warning messages */
-    sysVmake = FALSE;          /* Don't be System V compatible */
-
-    jobsRunning = FALSE;
-
-    maxJobs = DEFMAXJOBS;      /* Set the default maximum concurrency */
-    maxLocal = DEFMAXLOCAL;    /* Set the default local max concurrency */
-    
-    /*
-     * Deal with disagreement between different getopt's as to what
-     * the initial value of optind should be by simply saving the
-     * damn thing.
-     */
-    initOptInd = optind;
-    
-    /*
-     * See what the user calls us. If s/he calls us (yuck) "make", then
-     * act like it. Otherwise act like our normal, cheerful self.
-     */
-    cp = rindex (argv[0], '/');
-    if (cp != (char *)NULL) {
-       cp += 1;
-    } else {
-       cp = argv[0];
-    }
-    progName = cp;
-
-    if (strcmp (cp, "make") == 0) {
-       amMake = TRUE;          /* Be like make */
-       backwards = TRUE;       /* Do things the old-fashioned way */
-       oldVars = TRUE;         /* Same with variables */
-    } else if (strcmp(cp, "smake") == 0 || strcmp(cp, "vmake") == 0) {
-       sysVmake = oldVars = backwards = TRUE;
-    } else {
-       amMake = FALSE;
-       backwards = FALSE;      /* Do things MY way, not MAKE's */
-#ifdef DEF_OLD_VARS
-       oldVars = TRUE;
+       Lst targs;      /* target nodes to create -- passed to Make_Init */
+       Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
+       struct stat sb, sa;
+       char *p, *path, *pwd, *getenv(), *getwd();
+       char mdpath[MAXPATHLEN + 1];
+       char obpath[MAXPATHLEN + 1];
+       char cdpath[MAXPATHLEN + 1];
+
+       /*
+        * Find where we are and take care of PWD for the automounter...
+        * All this code is so that we know where we are when we start up
+        * on a different machine with pmake.
+        */
+       curdir = cdpath;
+       if (getwd(curdir) == NULL) {
+               (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
+        * exists, change into it and build there.  Once things are
+        * initted, have to add the original directory to the search path,
+        * and modify the paths for the Makefiles apropriately.  The
+        * current directory is also placed as a variable for make scripts.
+        */
+       if (!(path = getenv("MAKEOBJDIR"))) {
+               path = _PATH_OBJDIR;
+               (void) sprintf(mdpath, "%s.%s", path, MACHINE);
+       }
+       else
+               (void) strncpy(mdpath, path, MAXPATHLEN + 1);
+       
+       if (stat(mdpath, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+
+               if (chdir(mdpath)) {
+                       (void)fprintf(stderr, "make warning: %s: %s.\n",
+                                     mdpath, strerror(errno));
+                       objdir = curdir;
+               }
+               else {
+                       if (mdpath[0] != '/') {
+                               (void) sprintf(obpath, "%s/%s", curdir, mdpath);
+                               objdir = obpath;
+                       }
+                       else
+                               objdir = mdpath;
+               }
+       }
+       else {
+               if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+
+                       if (chdir(path)) {
+                               (void)fprintf(stderr, "make warning: %s: %s.\n",
+                                             path, strerror(errno));
+                               objdir = curdir;
+                       }
+                       else {
+                               if (path[0] != '/') {
+                                       (void) sprintf(obpath, "%s/%s", curdir,
+                                                      path);
+                                       objdir = obpath;
+                               }
+                               else
+                                       objdir = obpath;
+                       }
+               }
+               else
+                       objdir = curdir;
+       }
+
+       setenv("PWD", objdir, 1);
+
+       create = Lst_Init(FALSE);
+       makefiles = Lst_Init(FALSE);
+       beSilent = FALSE;               /* Print commands as executed */
+       ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
+       noExecute = FALSE;              /* Execute all commands */
+       keepgoing = FALSE;              /* Stop on error */
+       allPrecious = FALSE;            /* Remove targets when interrupted */
+       queryFlag = FALSE;              /* This is not just a check-run */
+       noBuiltins = FALSE;             /* Read the built-in rules */
+       touchFlag = FALSE;              /* Actually update targets */
+       usePipes = TRUE;                /* Catch child output in pipes */
+       debug = 0;                      /* No debug verbosity, please. */
+       jobsRunning = FALSE;
+
+       maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
+       maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
+#ifdef notyet
+       compatMake = FALSE;             /* No compat mode */
 #else
 #else
-       oldVars = FALSE;        /* don't substitute for undefined variables */
+       compatMake = TRUE;              /* No compat mode */
 #endif
 #endif
-    }
-
-    /*
-     * Initialize the parsing, directory and variable modules to prepare
-     * for the reading of inclusion paths and variable settings on the
-     * command line 
-     */
-    Dir_Init ();               /* Initialize directory structures so -I flags
+    
+
+       /*
+        * Initialize the parsing, directory and variable modules to prepare
+        * for the reading of inclusion paths and variable settings on the
+        * command line
+        */
+       Dir_Init();             /* Initialize directory structures so -I flags
                                 * can be processed correctly */
                                 * can be processed correctly */
-    Parse_Init ();             /* Need to initialize the paths of #include
+       Parse_Init();           /* Need to initialize the paths of #include
                                 * directories */
                                 * directories */
-    Var_Init ();               /* As well as the lists of variables for
+       Var_Init();             /* As well as the lists of variables for
                                 * parsing arguments */
                                 * parsing arguments */
+       if (objdir != curdir)
+               Dir_AddDir(dirSearchPath, curdir);
+       Var_Set(".CURDIR", curdir, VAR_GLOBAL);
+       Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
 
 
-    /*
-     * Initialize various variables.
-     * .PMAKE gets how we were executed.
-     * MAKE also gets this name, for compatibility
-     * .MAKEFLAGS gets set to the empty string just in case.
-     *  MFLAGS also gets initialized empty, for compatibility.
-     */
-    Var_Set (".PMAKE", argv[0], VAR_GLOBAL);
-    Var_Set ("MAKE", argv[0], VAR_GLOBAL);
-    Var_Set (MAKEFLAGS, "", VAR_GLOBAL);
-    Var_Set ("MFLAGS", "", VAR_GLOBAL);
-
-    /*
-     * First snag any flags out of the PMAKE environment variable.
-     * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's in
-     * a different format).
-     */
+       /*
+        * Initialize various variables.
+        *      MAKE also gets this name, for compatibility
+        *      .MAKEFLAGS gets set to the empty string just in case.
+        *      MFLAGS also gets initialized empty, for compatibility.
+        */
+       Var_Set("MAKE", argv[0], VAR_GLOBAL);
+       Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
+       Var_Set("MFLAGS", "", VAR_GLOBAL);
+#ifdef MACHINE
+       Var_Set("MACHINE", MACHINE, VAR_GLOBAL);
+#endif
+#ifdef MACHINE_ARCH
+       Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL);
+#endif
+
+       /*
+        * First snag any flags out of the MAKE environment variable.
+        * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
+        * in a different format).
+        */
 #ifdef POSIX
 #ifdef POSIX
-    Main_ParseArgLine(getenv("MAKEFLAGS"));
+       Main_ParseArgLine(getenv("MAKEFLAGS"));
 #else
 #else
-    Main_ParseArgLine (getenv("PMAKE"));
+       Main_ParseArgLine(getenv("MAKE"));
 #endif
     
 #endif
     
-    MainParseArgs (argc, argv);
+       MainParseArgs(argc, argv);
 
 
-    /*
-     * Initialize archive, target and suffix modules in preparation for
-     * parsing the makefile(s) 
-     */
-    Arch_Init ();
-    Targ_Init ();
-    Suff_Init ();
+       /*
+        * Initialize archive, target and suffix modules in preparation for
+        * parsing the makefile(s)
+        */
+       Arch_Init();
+       Targ_Init();
+       Suff_Init();
 
 
-    DEFAULT = NILGNODE;
+       DEFAULT = NILGNODE;
+       (void)time(&now);
 
 
-    now = time(0);
+       /*
+        * Set up the .TARGETS variable to contain the list of targets to be
+        * created. If none specified, make the variable empty -- the parser
+        * will fill the thing in with the default or .MAIN target.
+        */
+       if (!Lst_IsEmpty(create)) {
+               LstNode ln;
 
 
-    /*
-     * Set up the .TARGETS variable to contain the list of targets to be
-     * created. If none specified, make the variable empty -- the parser
-     * will fill the thing in with the default or .MAIN target.
-     */
-    if (!Lst_IsEmpty(create)) {
-       LstNode ln;
+               for (ln = Lst_First(create); ln != NILLNODE;
+                   ln = Lst_Succ(ln)) {
+                       char *name = (char *)Lst_Datum(ln);
 
 
-       for (ln = Lst_First(create); ln != NILLNODE; ln = Lst_Succ(ln)) {
-           char    *name = (char *)Lst_Datum(ln);
+                       Var_Append(".TARGETS", name, VAR_GLOBAL);
+               }
+       } else
+               Var_Set(".TARGETS", "", VAR_GLOBAL);
 
 
-           Var_Append(".TARGETS", name, VAR_GLOBAL);
-       }
-    } else {
-       Var_Set(".TARGETS", "", VAR_GLOBAL);
-    }
-
-    /*
-     * Read in the built-in rules first, followed by the specified makefile,
-     * if it was (makefile != (char *) NULL), or the default Makefile and
-     * makefile, in that order, if it wasn't. 
-     */
-    if (!noBuiltins && !ReadMakefile (DEFSYSMK)) {
-       Fatal ("Could not open system rules (%s)", DEFSYSMK);
-    }
-
-    if (!Lst_IsEmpty(makefiles)) {
-       LstNode ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
-
-       if (ln != NILLNODE) {
-           Fatal ("Cannot open %s", (char *)Lst_Datum(ln));
-       }
-    } else {
-#ifdef POSIX
-       if (!ReadMakefile("makefile")) {
-           (void)ReadMakefile("Makefile");
-       }
-#else
-       if (!ReadMakefile ((amMake || sysVmake) ? "makefile" : "Makefile")) {
-           (void) ReadMakefile ((amMake||sysVmake) ? "Makefile" : "makefile");
-       }
-#endif
-    }
-
-    /*
-     * Figure "noExport" out based on the current mode. Since exporting each
-     * command in make mode is rather inefficient, we only export if the -x
-     * flag was given. In regular mode though, we only refuse to export if
-     * -X was given. In case the operative flag was given in the environment,
-     * however, the opposite one may be given on the command line and cancel
-     * the action.
-     */
-    if (amMake) {
-       noExport = !xFlag || XFlag;
-    } else {
-       noExport = XFlag && !xFlag;
-    }
-    
-    Var_Append ("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
+       /*
+        * Read in the built-in rules first, followed by the specified makefile,
+        * if it was (makefile != (char *) NULL), or the default Makefile and
+        * makefile, in that order, if it wasn't.
+        */
+        if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
+               Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
+
+       if (!Lst_IsEmpty(makefiles)) {
+               LstNode ln;
+
+               ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
+               if (ln != NILLNODE)
+                       Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
+       } else if (!ReadMakefile("makefile"))
+               (void)ReadMakefile("Makefile");
+
+       (void)ReadMakefile(".depend");
+
+       Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
 
 
-    /*
-     * Install all the flags into the PMAKE envariable.
-     */
+       /* Install all the flags into the MAKE envariable. */
+       if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
 #ifdef POSIX
 #ifdef POSIX
-    setenv("MAKEFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL));
+               setenv("MAKEFLAGS", p, 1);
 #else
 #else
-    setenv("PMAKE", Var_Value(MAKEFLAGS, VAR_GLOBAL));
+               setenv("MAKE", p, 1);
 #endif
 
 #endif
 
-    /*
-     * For compatibility, look at the directories in the VPATH variable
-     * and add them to the search path, if the variable is defined. The
-     * variable's value is in the same format as the PATH envariable, i.e.
-     * <directory>:<directory>:<directory>...
-     */
-    if (Var_Exists ("VPATH", VAR_CMD)) {
-       char      *vpath;
-       char      *path;
-       char      *cp;
-       char      savec;
-       static char VPATH[] = "${VPATH}";   /* GCC stores string constants in
-                                            * read-only memory, but Var_Subst
-                                            * will want to write this thing,
-                                            * so store it in an array */
-       
-       vpath = Var_Subst (VPATH, VAR_CMD, FALSE);
-
-       path = vpath;
-       do {
-           /*
-            * Skip to end of directory
-            */
-           for (cp = path; *cp != ':' && *cp != '\0'; cp++) {
-               continue;
-           }
-           /*
-            * Save terminator character to figure out when to stop
-            */
-           savec = *cp;
-           *cp = '\0';
-           /*
-            * Add directory to search path
-            */
-           Dir_AddDir (dirSearchPath, path);
-           *cp = savec;
-           path = cp + 1;
-       } while (savec == ':');
-       free((Address)vpath);
-    }
-           
-    /*
-     * Now that all search paths have been read for suffixes et al, it's
-     * time to add the default search path to their lists...
-     */
-    Suff_DoPaths();
-
-    /*
-     * Print the initial graph, if the user requested it
-     */
-    if (printGraph & 1) {
-       Targ_PrintGraph (1);
-    }
-
-    Rmt_Init();
-
-    /*
-     * Have now read the entire graph and need to make a list of targets to
-     * create. If none was given on the command line, we consult the parsing
-     * module to find the main target(s) to create.
-     */
-    if (Lst_IsEmpty (create)) {
-       targs = Parse_MainName ();
-    } else {
-       targs = Targ_FindList (create, TARG_CREATE);
-    }
-
-    if (!amMake) {
        /*
        /*
-        * Initialize job module before traversing the graph, now that any
-        * .BEGIN and .END targets have been read. This is done only if the
-        * -q flag wasn't given (to prevent the .BEGIN from being executed
-        * should it exist).
+        * For compatibility, look at the directories in the VPATH variable
+        * and add them to the search path, if the variable is defined. The
+        * variable's value is in the same format as the PATH envariable, i.e.
+        * <directory>:<directory>:<directory>...
         */
         */
-       if (!queryFlag) {
-           if (maxLocal == -1) {
-               maxLocal = maxJobs;
-           }
-           Job_Init (maxJobs, maxLocal);
-           jobsRunning = TRUE;
+       if (Var_Exists("VPATH", VAR_CMD)) {
+               char *vpath, *path, *cp, savec;
+               /*
+                * GCC stores string constants in read-only memory, but
+                * Var_Subst will want to write this thing, so store it
+                * in an array
+                */
+               static char VPATH[] = "${VPATH}";
+
+               vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
+               path = vpath;
+               do {
+                       /* skip to end of directory */
+                       for (cp = path; *cp != ':' && *cp != '\0'; cp++)
+                               continue;
+                       /* Save terminator character so know when to stop */
+                       savec = *cp;
+                       *cp = '\0';
+                       /* Add directory to search path */
+                       Dir_AddDir(dirSearchPath, path);
+                       *cp = savec;
+                       path = cp + 1;
+               } while (savec == ':');
+               (void)free((Address)vpath);
        }
        }
-       
+
        /*
        /*
-        * Traverse the graph, checking on all the targets 
+        * Now that all search paths have been read for suffixes et al, it's
+        * time to add the default search path to their lists...
         */
         */
-       outOfDate = Make_Run (targs);
-    } else {
+       Suff_DoPaths();
+
+       /* print the initial graph, if the user requested it */
+       if (DEBUG(GRAPH1))
+               Targ_PrintGraph(1);
+
        /*
        /*
-        * Compat_Init will take care of creating all the targets as well
-        * as initializing the module.
+        * Have now read the entire graph and need to make a list of targets
+        * to create. If none was given on the command line, we consult the
+        * parsing module to find the main target(s) to create.
         */
         */
-       Compat_Run(targs);
-    }
+       if (Lst_IsEmpty(create))
+               targs = Parse_MainName();
+       else
+               targs = Targ_FindList(create, TARG_CREATE);
+
+/*
+ * this was original amMake -- want to allow parallelism, so put this
+ * back in, eventually.
+ */
+       if (!compatMake) {
+               /*
+                * Initialize job module before traversing the graph, now that
+                * any .BEGIN and .END targets have been read.  This is done
+                * only if the -q flag wasn't given (to prevent the .BEGIN from
+                * being executed should it exist).
+                */
+               if (!queryFlag) {
+                       if (maxLocal == -1)
+                               maxLocal = maxJobs;
+                       Job_Init(maxJobs, maxLocal);
+                       jobsRunning = TRUE;
+               }
+
+               /* Traverse the graph, checking on all the targets */
+               outOfDate = Make_Run(targs);
+       } else
+               /*
+                * Compat_Init will take care of creating all the targets as
+                * well as initializing the module.
+                */
+               Compat_Run(targs);
     
     
-    /*
-     * Print the graph now it's been processed if the user requested it
-     */
-    if (printGraph & 2) {
-       Targ_PrintGraph (2);
-    }
-
-    if (queryFlag && outOfDate) {
-       exit (1);
-    } else {
-       exit (0);
-    }
+       /* print the graph now it's been processed if the user requested it */
+       if (DEBUG(GRAPH2))
+               Targ_PrintGraph(2);
+
+       if (queryFlag && outOfDate)
+               return(1);
+       else
+               return(0);
 }
 
 /*-
 }
 
 /*-
- *-----------------------------------------------------------------------
  * ReadMakefile  --
  *     Open and parse the given makefile.
  *
  * ReadMakefile  --
  *     Open and parse the given makefile.
  *
@@ -730,89 +676,83 @@ main (argc, argv)
  *
  * Side Effects:
  *     lots
  *
  * Side Effects:
  *     lots
- *-----------------------------------------------------------------------
  */
 static Boolean
  */
 static Boolean
-ReadMakefile (fname)
-    char          *fname;     /* makefile to read */
+ReadMakefile(fname)
+       char *fname;            /* makefile to read */
 {
 {
-    if (strcmp (fname, "-") == 0) {
-       Parse_File ("(stdin)", stdin);
-       Var_Set("MAKEFILE", "", VAR_GLOBAL);
-       return (TRUE);
-    } else {
-       FILE *    stream;
        extern Lst parseIncPath, sysIncPath;
        extern Lst parseIncPath, sysIncPath;
-       
-       stream = fopen (fname, "r");
-    
-       if (stream == (FILE *) NULL) {
-           /*
-            * Look in -I directories...
-            */
-           char    *name = Dir_FindFile(fname, parseIncPath);
+       FILE *stream;
+       char *name, path[MAXPATHLEN + 1];
 
 
-           if (name == NULL) {
+       if (!strcmp(fname, "-")) {
+               Parse_File("(stdin)", stdin);
+               Var_Set("MAKEFILE", "", VAR_GLOBAL);
+       } else {
+               if ((stream = fopen(fname, "r")) != NULL)
+                       goto found;
+               /* if we've chdir'd, rebuild the path name */
+               if (curdir != objdir && *fname != '/') {
+                       (void)sprintf(path, "%s/%s", curdir, fname);
+                       if ((stream = fopen(path, "r")) != NULL) {
+                               fname = path;
+                               goto found;
+                       }
+               }
+               /* look in -I and system include directories. */
+               name = Dir_FindFile(fname, parseIncPath);
+               if (!name)
+                       name = Dir_FindFile(fname, sysIncPath);
+               if (!name || !(stream = fopen(name, "r")))
+                       return(FALSE);
+               fname = name;
                /*
                /*
-                * Last-ditch: look in system include directories.
+                * set the MAKEFILE variable desired by System V fans -- the
+                * placement of the setting here means it gets set to the last
+                * makefile specified, as it is set by SysV make.
                 */
                 */
-               name = Dir_FindFile(fname, sysIncPath);
-               if (name == NULL) {
-                   return (FALSE);
-               }
-           }
-           stream = fopen(name, "r");
-           if (stream == (FILE *)NULL) {
-               /* Better safe than sorry... */
-               return(FALSE);
-           }
-           fname = name;
+found:         Var_Set("MAKEFILE", fname, VAR_GLOBAL);
+               Parse_File(fname, stream);
+               (void)fclose(stream);
        }
        }
-       /*
-        * Set the MAKEFILE variable desired by System V fans -- the placement
-        * of the setting here means it gets set to the last makefile
-        * specified, as it is set by SysV make...
-        */
-       Var_Set("MAKEFILE", fname, VAR_GLOBAL);
-       Parse_File (fname, stream);
-       fclose (stream);
-       return (TRUE);
-    }
+       return(TRUE);
 }
 
 /*-
 }
 
 /*-
- *-----------------------------------------------------------------------
  * Error --
  * Error --
- *     Print an error message given its format and 0, 1, 2 or 3 arguments.
+ *     Print an error message given its format.
  *
  * Results:
  *     None.
  *
  * Side Effects:
  *     The message is printed.
  *
  * Results:
  *     None.
  *
  * Side Effects:
  *     The message is printed.
- *
- *-----------------------------------------------------------------------
  */
  */
-/*VARARGS1*/
+/* VARARGS */
 void
 void
-Error (fmt, arg1, arg2, arg3)
-    char         *fmt;             /* Format string */
-    int                  arg1,             /* First optional argument */
-                 arg2,             /* Second optional argument */
-                 arg3;             /* Third optional argument */
+#if __STDC__
+Error(const char *fmt, ...)
+#else
+Error(va_alist)
+       va_dcl
+#endif
 {
 {
-    static char   estr[BSIZE];     /* output string */
-
-    sprintf (estr, "%s: ", Var_Value(".PMAKE", VAR_GLOBAL));
-    sprintf (&estr[strlen (estr)], fmt, arg1, arg2, arg3);
-    (void) strcat (estr, "\n");
+       va_list ap;
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       char *fmt;
 
 
-    fputs (estr, stderr);
-    fflush (stderr);
+       va_start(ap);
+       fmt = va_arg(ap, char *);
+#endif
+       (void)vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       (void)fprintf(stderr, "\n");
+       (void)fflush(stderr);
 }
 
 /*-
 }
 
 /*-
- *-----------------------------------------------------------------------
  * Fatal --
  *     Produce a Fatal error message. If jobs are running, waits for them
  *     to finish.
  * Fatal --
  *     Produce a Fatal error message. If jobs are running, waits for them
  *     to finish.
@@ -822,29 +762,39 @@ Error (fmt, arg1, arg2, arg3)
  *
  * Side Effects:
  *     The program exits
  *
  * Side Effects:
  *     The program exits
- *-----------------------------------------------------------------------
  */
  */
-/* VARARGS1 */
+/* VARARGS */
 void
 void
-Fatal (fmt, arg1, arg2)
-    char          *fmt;                  /* format string */
-    int           arg1;                  /* first optional argument */
-    int           arg2;                  /* second optional argument */
+#if __STDC__
+Fatal(const char *fmt, ...)
+#else
+Fatal(va_alist)
+       va_dcl
+#endif
 {
 {
-    if (jobsRunning) {
-       Job_Wait();
-    }
-    
-    Error (fmt, arg1, arg2);
+       va_list ap;
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       char *fmt;
+
+       va_start(ap);
+       fmt = va_arg(ap, char *);
+#endif
+       if (jobsRunning)
+               Job_Wait();
 
 
-    if (printGraph & 2) {
-       Targ_PrintGraph(2);
-    }
-    exit (2);                  /* Not 1 so -q can distinguish error */
+       (void)vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       (void)fprintf(stderr, "\n");
+       (void)fflush(stderr);
+
+       if (DEBUG(GRAPH2))
+               Targ_PrintGraph(2);
+       exit(2);                /* Not 1 so -q can distinguish error */
 }
 
 /*
 }
 
 /*
- *-----------------------------------------------------------------------
  * Punt --
  *     Major exception once jobs are being created. Kills all jobs, prints
  *     a message and exits.
  * Punt --
  *     Major exception once jobs are being created. Kills all jobs, prints
  *     a message and exits.
@@ -854,22 +804,36 @@ Fatal (fmt, arg1, arg2)
  *
  * Side Effects:
  *     All children are killed indiscriminately and the program Lib_Exits
  *
  * Side Effects:
  *     All children are killed indiscriminately and the program Lib_Exits
- *-----------------------------------------------------------------------
  */
  */
-/* VARARGS1 */
+/* VARARGS */
 void
 void
-Punt (fmt, arg1, arg2)
-    char          *fmt;        /* format string */
-    int           arg1;        /* optional argument */
-    int                  arg2; /* optional second argument */
+#if __STDC__
+Punt(const char *fmt, ...)
+#else
+Punt(va_alist)
+       va_dcl
+#endif
 {
 {
-    Error (fmt, arg1, arg2);
+       va_list ap;
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       char *fmt;
 
 
-    DieHorribly();
+       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)fflush(stderr);
+
+       DieHorribly();
 }
 
 /*-
 }
 
 /*-
- *-----------------------------------------------------------------------
  * DieHorribly --
  *     Exit without giving a message.
  *
  * DieHorribly --
  *     Exit without giving a message.
  *
@@ -878,23 +842,18 @@ Punt (fmt, arg1, arg2)
  *
  * Side Effects:
  *     A big one...
  *
  * Side Effects:
  *     A big one...
- *-----------------------------------------------------------------------
  */
 void
 DieHorribly()
 {
  */
 void
 DieHorribly()
 {
-    if (jobsRunning) {
-       Job_AbortAll ();
-    }
-    if (printGraph & 2) {
-       Targ_PrintGraph(2);
-    }
-    
-    exit (2);                  /* Not 1, so -q can distinguish error */
+       if (jobsRunning)
+               Job_AbortAll();
+       if (DEBUG(GRAPH2))
+               Targ_PrintGraph(2);
+       exit(2);                /* Not 1, so -q can distinguish error */
 }
 
 /*
 }
 
 /*
- *-----------------------------------------------------------------------
  * Finish --
  *     Called when aborting due to errors in child shell to signal
  *     abnormal exit. 
  * Finish --
  *     Called when aborting due to errors in child shell to signal
  *     abnormal exit. 
@@ -904,11 +863,49 @@ DieHorribly()
  *
  * Side Effects:
  *     The program exits
  *
  * Side Effects:
  *     The program exits
- * -----------------------------------------------------------------------
  */
 void
  */
 void
-Finish (errors)
-    int             errors;    /* number of errors encountered in Make_Make */
+Finish(errors)
+       int errors;     /* number of errors encountered in Make_Make */
+{
+       Fatal("%d error%s", errors, errors == 1 ? "" : "s");
+}
+
+/*
+ * emalloc --
+ *     malloc, but die on error.
+ */
+char *
+emalloc(len)
+       u_int len;
+{
+       char *p;
+
+       if (!(p = malloc(len)))
+               enomem();
+       return(p);
+}
+
+/*
+ * enomem --
+ *     die when out of memory.
+ */
+void
+enomem()
+{
+       (void)fprintf(stderr, "make: %s.\n", strerror(errno));
+       exit(2);
+}
+
+/*
+ * usage --
+ *     exit with usage message
+ */
+static void
+usage()
 {
 {
-    Fatal ("%d error%s", errors, errors == 1 ? "" : "s");
+       (void)fprintf(stderr,
+"usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
+            [-I directory] [-j max_jobs] [variable=value]\n");
+       exit(2);
 }
 }