stdio.h defines BUFSIZ
[unix-history] / usr / src / usr.bin / make / main.c
index 416fdb0..913f6b5 100644 (file)
@@ -7,17 +7,7 @@
  * This code is derived from software contributed to Berkeley by
  * Adam de Boor.
  *
  * 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.
+ * %sccs.include.redist.c%
  */
 
 #ifndef lint
  */
 
 #ifndef lint
@@ -27,7 +17,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     5.24 (Berkeley) %G%";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -36,114 +26,69 @@ static char sccsid[] = "@(#)main.c 5.8 (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 */
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <varargs.h>
+#include "make.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                        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                        ignoreErrors;   /* -i flag */
-Boolean                        beSilent;       /* -s flag */
-Boolean                        sysVmake;       /* -v flag */
-Boolean                        oldVars;        /* variable substitution style */
-Boolean                        checkEnvFirst;  /* -e flag */
-static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
+Boolean                        beSilent;       /* -s flag */
+Boolean                        oldVars;        /* variable substitution style */
+Boolean                        checkEnvFirst;  /* -e flag */
+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;
-
-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).",
-"-W            Don't print warning messages.",
-"-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.",
-};
+static Boolean         ReadMakefile();
 
 
+static char *curdir;                   /* if chdir'd for an architecture */
 
 /*-
 
 /*-
- *----------------------------------------------------------------------
  * 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.
@@ -156,197 +101,162 @@ 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, "BCD:I:J:L:MPSWd:ef:iknp:qrstvh")) != -1) {
-       switch(c) {
-           case 'B':
-               backwards = TRUE;
-               Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
-               break;
-           case 'C':
-               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 'W':
-               noWarnings = TRUE;
-               Var_Append(MAKEFLAGS, "-W", 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;
+       register int i;
+       register char *cp;
+       char c;
+
+       optind = 1;     /* since we're called more than once */
+rearg: while((c = getopt(argc, argv, "D:I:d:ef:ij:knqrst")) != 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 notdef
+               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 '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;
+                               }
+                       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 = 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;
-    }
-    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]);
        }
        }
-    }
+
+       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 (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 == '-') {
+                               optind = 0;
+                               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.
@@ -360,27 +270,25 @@ 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);
+       if (line == NULL)
+               return;
+       for (; *line == ' '; ++line);
+       if (!*line)
+               return;
 
 
-    MainParseArgs(argc, argv);
-
-    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
@@ -396,282 +304,247 @@ 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;
+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;
+       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();
+
+       /*
+        * 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;
+       if (!lstat(path, &sb)) {
+               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 (chdir(path)) {
+                       (void)fprintf(stderr, "make: %s: %s.\n",
+                           path, strerror(errno));
+                       exit(2);
+               }
+       }
+
+       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 */
     
     
-    /*
-     * 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 */
-    } else if (strcmp(cp, "smake") == 0 || strcmp(cp, "vmake") == 0) {
-       sysVmake = backwards = TRUE;
-    } else {
-       amMake = FALSE;
-       backwards = FALSE;      /* Do things MY way, not MAKE's */
-    }
-
-    /*
-     * 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 */
 
-    /*
-     * 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).
-     */
+       if (curdir) {
+               Dir_AddDir(dirSearchPath, curdir);
+               Var_Set(".CURDIR", curdir, VAR_GLOBAL);
+       } else
+               Var_Set(".CURDIR", ".", VAR_GLOBAL);
+
+       /*
+        * 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);
+       Var_Set("MACHINE", MACHINE, VAR_GLOBAL);
+
+       /*
+        * 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);
+
+       /*
+        * 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;
 
 
-    now = time(0);
+               for (ln = Lst_First(create); ln != NILLNODE;
+                   ln = Lst_Succ(ln)) {
+                       char *name = (char *)Lst_Datum(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;
+                       Var_Append(".TARGETS", name, VAR_GLOBAL);
+               }
+       } else
+               Var_Set(".TARGETS", "", VAR_GLOBAL);
 
 
-       for (ln = Lst_First(create); ln != NILLNODE; ln = Lst_Succ(ln)) {
-           char    *name = (char *)Lst_Datum(ln);
+       /*
+        * 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);
 
 
-           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
-    }
+       if (!Lst_IsEmpty(makefiles)) {
+               LstNode ln;
 
 
-    Var_Append ("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
+               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");
 
 
-    /*
-     * Install all the flags into the PMAKE envariable.
-     */
+       (void)ReadMakefile(".depend");
+
+       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)
 #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);
-    }
-
-    /*
-     * 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(VPATH, VAR_CMD, FALSE);
+               path = vpath;
+               do {
+                       /* skip to end of directory */
+                       for (cp = path; *cp != ':' && *cp != '\0'; cp++);
+                       /* 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 (0) {
+               /*
+                * 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)
+               exit(1);
+       else
+               exit(0);
 }
 
 /*-
 }
 
 /*-
- *-----------------------------------------------------------------------
  * ReadMakefile  --
  *     Open and parse the given makefile.
  *
  * ReadMakefile  --
  *     Open and parse the given makefile.
  *
@@ -680,89 +553,75 @@ 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"))
+                       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")) {
+                               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 */
+Error(va_alist)
+       va_dcl
 {
 {
-    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");
-
-    fputs (estr, stderr);
-    fflush (stderr);
+       va_list ap;
+       char *fmt;
+
+       va_start(ap);
+       fmt = va_arg(ap, char *);
+       (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.
@@ -772,29 +631,31 @@ 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 */
+Fatal(va_alist)
+       va_dcl
 {
 {
-    if (jobsRunning) {
-       Job_Wait();
-    }
-    
-    Error (fmt, arg1, arg2);
-
-    if (printGraph & 2) {
-       Targ_PrintGraph(2);
-    }
-    exit (2);                  /* Not 1 so -q can distinguish error */
+       va_list ap;
+       char *fmt;
+
+       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)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.
@@ -804,22 +665,27 @@ 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 */
+Punt(va_alist)
+       va_dcl
 {
 {
-    Error (fmt, arg1, arg2);
-
-    DieHorribly();
+       va_list ap;
+       char *fmt;
+
+       (void)fprintf(stderr, "make: ");
+       va_start(ap);
+       fmt = va_arg(ap, char *);
+       (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.
  *
@@ -828,23 +694,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. 
@@ -854,11 +715,47 @@ 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, *malloc();
+
+       if (!(p = malloc(len)))
+               enomem();
+       return(p);
+}
+
+/*
+ * enomem --
+ *     die when out of memory.
+ */
+enomem()
+{
+       (void)fprintf(stderr, "make: %s.\n", strerror(errno));
+       exit(2);
+}
+
+/*
+ * usage --
+ *     exit with usage message
+ */
+usage()
 {
 {
-    Fatal ("%d error%s", errors, errors == 1 ? "" : "s");
+       (void)fprintf(stderr,
+"usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\t\
+[-I directory] [-j max_jobs] [variable=value]\n");
+       exit(2);
 }
 }