]> Zhao Yanbai Git Server - minix.git/commitdiff
Make: Updates from NetBSD
authorArun Thomas <arun@minix3.org>
Fri, 25 Jun 2010 23:25:48 +0000 (23:25 +0000)
committerArun Thomas <arun@minix3.org>
Fri, 25 Jun 2010 23:25:48 +0000 (23:25 +0000)
Needed for pkgsrc

13 files changed:
commands/make/Makefile
commands/make/Makefile.netbsd
commands/make/compat.c
commands/make/for.c
commands/make/job.c
commands/make/main.c
commands/make/make.1
commands/make/make.c
commands/make/make.h
commands/make/nonints.h
commands/make/parse.c
commands/make/util.c
commands/make/var.c

index f837ec73f80c5714a730791a0aa255d06f5a7302..3c451ccaea5842d679a7e818fb08b685b3c69e3c 100644 (file)
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.49 2009/04/14 22:15:23 lukem Exp $
+#      $NetBSD: Makefile,v 1.50 2010/04/22 19:15:23 sjg Exp $
 #      @(#)Makefile    5.2 (Berkeley) 12/28/90
 
 PROG=  make
@@ -35,4 +35,4 @@ CPPFLAGS+= -DTARGET_MACHINE=\"${MACHINE}\" \
 
 # A simple unit-test driver to help catch regressions
 accept test:
-       cd ${.CURDIR}/unit-tests && ${.MAKE:S,^./,${.CURDIR}/,} TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
+       cd ${.CURDIR}/unit-tests && ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
index 51cbda3717e0e8b40c41eaa1f9f6906f4cb1fec2..acbe83aa7c800159bf73b9f835ad13a3b96f780a 100644 (file)
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.49 2009/04/14 22:15:23 lukem Exp $
+#      $NetBSD: Makefile,v 1.50 2010/04/22 19:15:23 sjg Exp $
 #      @(#)Makefile    5.2 (Berkeley) 12/28/90
 
 PROG=  make
@@ -37,4 +37,4 @@ DPADD+=${LIBUTIL}
 
 # A simple unit-test driver to help catch regressions
 accept test:
-       cd ${.CURDIR}/unit-tests && ${.MAKE:S,^./,${.CURDIR}/,} TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
+       cd ${.CURDIR}/unit-tests && ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
index 42c5fe2f6dfdcc967c216ca7c82c1f9f5318772c..054cfd75e9b60e7cdc161c623c4eb0908d63d3de 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $     */
+/*     $NetBSD: compat.c,v 1.79 2010/06/03 15:40:15 sjg Exp $  */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.79 2010/06/03 15:40:15 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)compat.c   8.2 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $");
+__RCSID("$NetBSD: compat.c,v 1.79 2010/06/03 15:40:15 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -355,11 +355,7 @@ again:
     /*
      * Fork and execute the single command. If the fork fails, we abort.
      */
-#if defined(__minix)
-    cpid = fork();
-#else
-    cpid = vfork();
-#endif
+    cpid = vFork();
     if (cpid < 0) {
        Fatal("Could not fork");
     }
@@ -578,7 +574,7 @@ Compat_Make(void *gnp, void *pgnp)
        } else if (keepgoing) {
            pgn->flags &= ~REMAKE;
        } else {
-           PrintOnError("\n\nStop.");
+           PrintOnError(gn, "\n\nStop.");
            exit(1);
        }
     } else if (gn->made == ERROR) {
@@ -645,17 +641,17 @@ Compat_Run(Lst targs)
 
     Compat_Init();
 
-    if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
-       signal(SIGINT, CompatInterrupt);
+    if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) {
+       bmake_signal(SIGINT, CompatInterrupt);
     }
-    if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
-       signal(SIGTERM, CompatInterrupt);
+    if (bmake_signal(SIGTERM, SIG_IGN) != SIG_IGN) {
+       bmake_signal(SIGTERM, CompatInterrupt);
     }
-    if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
-       signal(SIGHUP, CompatInterrupt);
+    if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN) {
+       bmake_signal(SIGHUP, CompatInterrupt);
     }
-    if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
-       signal(SIGQUIT, CompatInterrupt);
+    if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
+       bmake_signal(SIGQUIT, CompatInterrupt);
     }
 
     ENDNode = Targ_FindNode(".END", TARG_CREATE);
@@ -669,7 +665,7 @@ Compat_Run(Lst targs)
        if (gn != NULL) {
            Compat_Make(gn, gn);
             if (gn->made == ERROR) {
-                PrintOnError("\n\nStop.");
+                PrintOnError(gn, "\n\nStop.");
                 exit(1);
             }
        }
@@ -710,7 +706,7 @@ Compat_Run(Lst targs)
     if (errors == 0) {
        Compat_Make(ENDNode, ENDNode);
        if (gn->made == ERROR) {
-           PrintOnError("\n\nStop.");
+           PrintOnError(gn, "\n\nStop.");
            exit(1);
        }
     }
index 62f483d72547289cfcfddf6b5fbd01d406bf6cd8..4a320a38a8f1e4f67295fa14329fbdd53788fa72 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: for.c,v 1.46 2009/01/17 13:29:37 dsl Exp $     */
+/*     $NetBSD: for.c,v 1.47 2010/02/06 20:37:13 dholland Exp $        */
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.46 2009/01/17 13:29:37 dsl Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.47 2010/02/06 20:37:13 dholland Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)for.c      8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: for.c,v 1.46 2009/01/17 13:29:37 dsl Exp $");
+__RCSID("$NetBSD: for.c,v 1.47 2010/02/06 20:37:13 dholland Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -237,7 +237,8 @@ For_Eval(char *line)
 
     if (strlist_num(&new_for->items) % strlist_num(&new_for->vars)) {
        Parse_Error(PARSE_FATAL,
-               "Wrong number of words in .for substitution list %d %d",
+               "Wrong number of words (%d) in .for substitution list"
+               " with %d vars",
                strlist_num(&new_for->items), strlist_num(&new_for->vars));
        /*
         * Return 'success' so that the body of the .for loop is accumulated.
index a8a94433d2c9baf72bf295180d1fc70668d3f05f..aeda9da9344fc7f8f084f9dcc4c765ac3bc05f0c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: job.c,v 1.146 2009/06/26 01:26:32 sjg Exp $    */
+/*     $NetBSD: job.c,v 1.151 2010/06/17 03:36:05 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: job.c,v 1.146 2009/06/26 01:26:32 sjg Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.151 2010/06/17 03:36:05 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)job.c      8.2 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: job.c,v 1.146 2009/06/26 01:26:32 sjg Exp $");
+__RCSID("$NetBSD: job.c,v 1.151 2010/06/17 03:36:05 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -342,8 +342,6 @@ static sigset_t caught_signals;     /* Set of signals we handle */
 #define KILLPG(pid, sig)       killpg((pid), (sig))
 #endif
 
-static char *tmpdir;           /* directory name, always ending with "/" */
-
 static void JobChildSig(int);
 static void JobContinueSig(int);
 static Job *JobFindPid(int, int);
@@ -1022,8 +1020,11 @@ JobFinish(Job *job, int status)
                                job->node->name,
                               WEXITSTATUS(status),
                               (job->flags & JOB_IGNERR) ? "(ignored)" : "");
-               if (job->flags & JOB_IGNERR)
+               if (job->flags & JOB_IGNERR) {
                    status = 0;
+               } else {
+                   PrintOnError(job->node, NULL);
+               }
            } else if (DEBUG(JOB)) {
                if (job->node != lastNode) {
                    MESSAGE(stdout, job->node);
@@ -1225,8 +1226,8 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
            static const char msg[] = ": don't know how to make";
 
            if (gn->flags & FROM_DEPEND) {
-               fprintf(stdout, "%s: ignoring stale .depend for %s\n",
-                       progname, gn->name);
+               fprintf(stdout, "%s: ignoring stale %s for %s\n",
+                       progname, makeDependfile, gn->name);
                return TRUE;
            }
 
@@ -1301,11 +1302,7 @@ JobExec(Job *job, char **argv)
     /* Pre-emptively mark job running, pid still zero though */
     job->job_state = JOB_ST_RUNNING;
 
-#if defined(__minix)
-    cpid = fork();
-#else
-    cpid = vfork();
-#endif
+    cpid = vFork();
     if (cpid == -1)
        Punt("Cannot vfork: %s", strerror(errno));
 
@@ -1559,11 +1556,7 @@ JobStart(GNode *gn, int flags)
        }
 
        JobSigLock(&mask);
-       tfile = bmake_malloc(strlen(tmpdir) + sizeof(TMPPAT));
-       strcpy(tfile, tmpdir);
-       strcat(tfile, TMPPAT);
-       if ((tfd = mkstemp(tfile)) == -1)
-           Punt("Could not create temporary file %s", strerror(errno));
+       tfd = mkTempFile(TMPPAT, &tfile);
        if (!DEBUG(SCRIPT))
                (void)eunlink(tfile);
        JobSigUnlock(&mask);
@@ -1901,7 +1894,7 @@ JobRun(GNode *targ)
 #else
     Compat_Make(targ, targ);
     if (targ->made == ERROR) {
-       PrintOnError("\n\nStop.");
+       PrintOnError(targ, "\n\nStop.");
        exit(1);
     }
 #endif
@@ -2126,8 +2119,6 @@ void
 Job_Init(void)
 {
     GNode         *begin;     /* node for commands to do at the very start */
-    const char    *p;
-    size_t        len;
 
     /* Allocate space for all the job info */
     job_table = bmake_malloc(maxJobs * sizeof *job_table);
@@ -2140,18 +2131,6 @@ Job_Init(void)
 
     lastNode =   NULL;
 
-    /* set tmpdir, and ensure that it ends with "/" */
-    p = getenv("TMPDIR");
-    if (p == NULL || *p == '\0') {
-       p = _PATH_TMP;
-    }
-    len = strlen(p);
-    tmpdir = bmake_malloc(len + 2);
-    strcpy(tmpdir, p);
-    if (tmpdir[len - 1] != '/') {
-       strcat(tmpdir, "/");
-    }
-
     if (maxJobs == 1) {
        /*
         * If only one job can run at a time, there's no need for a banner,
@@ -2195,13 +2174,13 @@ Job_Init(void)
     /*
      * Install a SIGCHLD handler.
      */
-    (void)signal(SIGCHLD, JobChildSig);
+    (void)bmake_signal(SIGCHLD, JobChildSig);
     sigaddset(&caught_signals, SIGCHLD);
 
 #define ADDSIG(s,h)                            \
-    if (signal(s, SIG_IGN) != SIG_IGN) {       \
+    if (bmake_signal(s, SIG_IGN) != SIG_IGN) { \
        sigaddset(&caught_signals, s);          \
-       (void)signal(s, h);                     \
+       (void)bmake_signal(s, h);                       \
     }
 
     /*
@@ -2231,7 +2210,7 @@ Job_Init(void)
     if (begin != NULL) {
        JobRun(begin);
        if (begin->made == ERROR) {
-           PrintOnError("\n\nStop.");
+           PrintOnError(begin, "\n\nStop.");
            exit(1);
        }
     }
@@ -2242,7 +2221,7 @@ static void JobSigReset(void)
 {
 #define DELSIG(s)                                      \
     if (sigismember(&caught_signals, s)) {             \
-       (void)signal(s, SIG_DFL);                       \
+       (void)bmake_signal(s, SIG_DFL);                 \
     }
 
     DELSIG(SIGINT)
@@ -2255,7 +2234,7 @@ static void JobSigReset(void)
     DELSIG(SIGWINCH)
     DELSIG(SIGCONT)
 #undef DELSIG
-    (void)signal(SIGCHLD, SIG_DFL);
+    (void)bmake_signal(SIGCHLD, SIG_DFL);
 }
 
 /*-
index 54f4e674460011ac2f9950b8c1590595f83499aa..169778c10c4fa29fbf761f6daaa603a1930ba4ed 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.174 2009/09/09 17:09:49 sjg Exp $   */
+/*     $NetBSD: main.c,v 1.188 2010/06/03 15:40:16 sjg Exp $   */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.174 2009/09/09 17:09:49 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.188 2010/06/03 15:40:16 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
 #if 0
 static char sccsid[] = "@(#)main.c     8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.174 2009/09/09 17:09:49 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.188 2010/06/03 15:40:16 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -184,6 +184,8 @@ static Boolean              ignorePWD;      /* if we use -C, PWD is meaningless */
 static char curdir[MAXPATHLEN + 1];    /* startup directory */
 static char objdir[MAXPATHLEN + 1];    /* where we chdir'ed to */
 char *progname;                                /* the program name */
+char *makeDependfile;
+pid_t myPid;
 
 Boolean forceJobs = FALSE;
 
@@ -384,6 +386,7 @@ rearg:
                case 'B':
                        compatMake = TRUE;
                        Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
+                       Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0);
                        break;
                case 'C':
                        if (chdir(argvalue) == -1) {
@@ -393,6 +396,10 @@ rearg:
                                              strerror(errno));
                                exit(1);
                        }
+                       if (getcwd(curdir, MAXPATHLEN) == NULL) {
+                               (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
+                               exit(2);
+                       }
                        ignorePWD = TRUE;
                        break;
                case 'D':
@@ -495,6 +502,7 @@ rearg:
                        }
                        Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
                        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+                       Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0);
                        maxJobTokens = maxJobs;
                        break;
                case 'k':
@@ -509,7 +517,6 @@ rearg:
                                    found_path, sizeof(found_path)))
                                        break;          /* nothing doing */
                                (void)Dir_AddDir(sysIncPath, found_path);
-                               
                        } else {
                                (void)Dir_AddDir(sysIncPath, argvalue);
                        }
@@ -677,6 +684,22 @@ ReadAllMakefiles(const void *p, const void *q)
        return (ReadMakefile(p, q) == 0);
 }
 
+static int
+str2Lst_Append(Lst lp, char *str, const char *sep)
+{
+    char *cp;
+    int n;
+
+    if (!sep)
+       sep = " \t";
+
+    for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
+       (void)Lst_AtEnd(lp, cp);
+       n++;
+    }
+    return (n);
+}
+
 #ifdef SIGINFO
 /*ARGSUSED*/
 static void
@@ -693,6 +716,27 @@ siginfo(int signo)
 }
 #endif
 
+/*
+ * Allow makefiles some control over the mode we run in.
+ */
+void
+MakeMode(const char *mode)
+{
+    char *mp = NULL;
+
+    if (!mode)
+       mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0);
+
+    if (mode && *mode) {
+       if (strstr(mode, "compat")) {
+           compatMake = TRUE;
+           forceJobs = FALSE;
+       }
+    }
+    if (mp)
+       free(mp);
+}
+
 /*-
  * main --
  *     The main function, for obvious reasons. Initializes variables
@@ -735,7 +779,7 @@ main(int argc, char **argv)
        debug_file = stderr;
 
 #ifdef SIGINFO
-       (void)signal(SIGINFO, siginfo);
+       (void)bmake_signal(SIGINFO, siginfo);
 #endif
        /*
         * Set the seed to produce a different random sequence
@@ -799,6 +843,8 @@ main(int argc, char **argv)
 #endif
        }
 
+       myPid = getpid();               /* remember this for vFork() */
+
        /*
         * Just in case MAKEOBJDIR wants us to do something tricky.
         */
@@ -810,6 +856,15 @@ main(int argc, char **argv)
        Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
 #endif
        Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
+       /*
+        * This is the traditional preference for makefiles.
+        */
+#ifndef MAKEFILE_PREFERENCE_LIST
+# define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
+#endif
+       Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
+               VAR_GLOBAL, 0);
+       Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0);
 
        create = Lst_Init(FALSE);
        makefiles = Lst_Init(FALSE);
@@ -845,8 +900,24 @@ main(int argc, char **argv)
         *      MFLAGS also gets initialized empty, for compatibility.
         */
        Parse_Init();
-       Var_Set("MAKE", argv[0], VAR_GLOBAL, 0);
-       Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0);
+       if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) {
+           /*
+            * Leave alone if it is an absolute path, or if it does
+            * not contain a '/' in which case we need to find it in
+            * the path, like execvp(3) and the shells do.
+            */
+           p1 = argv[0];
+       } else {
+           /*
+            * A relative path, canonicalize it.
+            */
+           p1 = realpath(argv[0], mdpath);
+           if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
+               p1 = argv[0];           /* realpath failed */
+           }
+       }
+       Var_Set("MAKE", p1, VAR_GLOBAL, 0);
+       Var_Set(".MAKE", p1, VAR_GLOBAL, 0);
        Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
        Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
        Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
@@ -863,7 +934,7 @@ main(int argc, char **argv)
                ep = "0";
            }
            Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
-           snprintf(tmp, sizeof(tmp), "%u", getpid());
+           snprintf(tmp, sizeof(tmp), "%u", myPid);
            Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
            snprintf(tmp, sizeof(tmp), "%u", getppid());
            Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
@@ -881,18 +952,20 @@ main(int argc, char **argv)
        Main_ParseArgLine(getenv("MAKE"));
 #endif
 
-       MainParseArgs(argc, argv);
-
        /*
-        * Find where we are (now) 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.
+        * Find where we are (now).
+        * We take care of PWD for the automounter below...
         */
        if (getcwd(curdir, MAXPATHLEN) == NULL) {
                (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
                exit(2);
        }
 
+       MainParseArgs(argc, argv);
+
+       /*
+        * Verify that cwd is sane.
+        */
        if (stat(curdir, &sa) == -1) {
            (void)fprintf(stderr, "%s: %s: %s.\n",
                 progname, curdir, strerror(errno));
@@ -900,6 +973,8 @@ main(int argc, char **argv)
        }
 
        /*
+        * All this code is so that we know where we are when we start up
+        * on a different machine with pmake.
         * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
         * since the value of curdir can vary depending on how we got
         * here.  Ie sitting at a shell prompt (shell that provides $PWD)
@@ -1044,16 +1119,27 @@ main(int argc, char **argv)
                if (ln != NULL)
                        Fatal("%s: cannot open %s.", progname, 
                            (char *)Lst_Datum(ln));
-       } else if (ReadMakefile("makefile", NULL) != 0)
-               (void)ReadMakefile("Makefile", NULL);
+       } else {
+           p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
+               VAR_CMD, 0);
+           if (p1) {
+               (void)str2Lst_Append(makefiles, p1, NULL);
+               (void)Lst_Find(makefiles, NULL, ReadMakefile);
+               free(p1);
+           }
+       }
 
        /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
        if (!noBuiltins || !printVars) {
-               doing_depend = TRUE;
-               (void)ReadMakefile(".depend", NULL);
-               doing_depend = FALSE;
+           makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
+               VAR_CMD, 0);
+           doing_depend = TRUE;
+           (void)ReadMakefile(makeDependfile, NULL);
+           doing_depend = FALSE;
        }
 
+       MakeMode(NULL);
+
        Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
        if (p1)
            free(p1);
@@ -1212,14 +1298,11 @@ ReadMakefile(const void *p, const void *q __unused)
        int fd;
        size_t len = MAXPATHLEN;
        char *name, *path = bmake_malloc(len);
-       int setMAKEFILE;
 
        if (!strcmp(fname, "-")) {
                Parse_File("(stdin)", dup(fileno(stdin)));
                Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
        } else {
-               setMAKEFILE = strcmp(fname, ".depend");
-
                /* if we've chdir'd, rebuild the path name */
                if (strcmp(curdir, objdir) && *fname != '/') {
                        size_t plen = strlen(curdir) + strlen(fname) + 2;
@@ -1266,7 +1349,7 @@ ReadMakefile(const void *p, const void *q __unused)
                 * makefile specified, as it is set by SysV make.
                 */
 found:
-               if (setMAKEFILE)
+               if (!doing_depend)
                        Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
                Parse_File(fname, fd);
        }
@@ -1509,11 +1592,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
     /*
      * Fork
      */
-#if defined(__minix)
-    switch (cpid = fork()) {
-#else
-    switch (cpid = vfork()) {
-#endif
+    switch (cpid = vFork()) {
     case 0:
        /*
         * Close input side of pipe
@@ -1624,6 +1703,7 @@ Error(const char *fmt, ...)
        err_file = debug_file;
        if (err_file == stdout)
                err_file = stderr;
+       (void)fflush(stdout);
        for (;;) {
                va_start(ap, fmt);
                fprintf(err_file, "%s: ", progname);
@@ -1658,12 +1738,13 @@ Fatal(const char *fmt, ...)
        if (jobsRunning)
                Job_Wait();
 
+       (void)fflush(stdout);
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
        (void)fflush(stderr);
 
-       PrintOnError(NULL);
+       PrintOnError(NULL, NULL);
 
        if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
                Targ_PrintGraph(2);
@@ -1689,13 +1770,14 @@ Punt(const char *fmt, ...)
        va_list ap;
 
        va_start(ap, fmt);
+       (void)fflush(stdout);
        (void)fprintf(stderr, "%s: ", progname);
        (void)vfprintf(stderr, fmt, ap);
        va_end(ap);
        (void)fprintf(stderr, "\n");
        (void)fflush(stderr);
 
-       PrintOnError(NULL);
+       PrintOnError(NULL, NULL);
 
        DieHorribly();
 }
@@ -1816,22 +1898,40 @@ PrintAddr(void *a, void *b)
 
 
 void
-PrintOnError(const char *s)
+PrintOnError(GNode *gn, const char *s)
 {
+    static GNode *en = NULL;
     char tmp[64];
     char *cp;
 
     if (s)
-           printf("%s", s);
+       printf("%s", s);
        
     printf("\n%s: stopped in %s\n", progname, curdir);
+
+    if (en)
+       return;                         /* we've been here! */
+    if (gn) {
+       /*
+        * We can print this even if there is no .ERROR target.
+        */
+       Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
+    }
     strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
            sizeof(tmp) - 1);
     cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
     if (cp) {
-           if (*cp)
-                   printf("%s", cp);
-           free(cp);
+       if (*cp)
+           printf("%s", cp);
+       free(cp);
+    }
+    /*
+     * Finally, see if there is a .ERROR target, and run it if so.
+     */
+    en = Targ_FindNode(".ERROR", TARG_NOCREATE);
+    if (en) {
+       en->type |= OP_SPECIAL;
+       Compat_Make(en, en);
     }
 }
 
@@ -1857,3 +1957,46 @@ Main_ExportMAKEFLAGS(Boolean first)
 #endif
     }
 }
+
+/*
+ * Create and open a temp file using "pattern".
+ * If "fnamep" is provided set it to a copy of the filename created.
+ * Otherwise unlink the file once open.
+ */
+int
+mkTempFile(const char *pattern, char **fnamep)
+{
+    static char *tmpdir = NULL;
+    char tfile[MAXPATHLEN];
+    int fd;
+    
+    if (!pattern)
+       pattern = TMPPAT;
+
+    if (!tmpdir) {
+       struct stat st;
+
+       /*
+        * Honor $TMPDIR but only if it is valid.
+        * Ensure it ends with /.
+        */
+       tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0);
+       if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
+           free(tmpdir);
+           tmpdir = bmake_strdup(_PATH_TMP);
+       }
+    }
+    if (pattern[0] == '/') {
+       snprintf(tfile, sizeof(tfile), "%s", pattern);
+    } else {
+       snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern);
+    }
+    if ((fd = mkstemp(tfile)) < 0)
+       Punt("Could not create temporary file %s: %s", tfile, strerror(errno));
+    if (fnamep) {
+       *fnamep = bmake_strdup(tfile);
+    } else {
+       unlink(tfile);                  /* we just want the descriptor */
+    }
+    return fd;
+}
index ccc90e229fdbd3bcec1f340cb4079cdfcc8646b7..a5aed6740034e041590a546ec4ba00aee2cb2546 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: make.1,v 1.166 2009/11/19 06:48:37 wiz Exp $
+.\"    $NetBSD: make.1,v 1.176 2010/06/10 18:35:22 wiz Exp $
 .\"
 .\" Copyright (c) 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"    from: @(#)make.1        8.4 (Berkeley) 3/19/94
 .\"
-.Dd November 15, 2009
+.Dd June 9, 2010
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -536,11 +536,48 @@ If the result of expanding a variable contains a dollar sign
 .Pq Ql \&$
 the string is expanded again.
 .Pp
-Variable substitution occurs at two distinct times, depending on where
+Variable substitution occurs at three distinct times, depending on where
 the variable is being used.
+.Bl -enum
+.It
 Variables in dependency lines are expanded as the line is read.
+.It
 Variables in shell commands are expanded when the shell command is
 executed.
+.It
+.Dq .for
+loop index variables are expanded on each loop iteration.
+Note that other variables are not expanded inside loops so
+the following example code:
+.Bd -literal -offset indent
+
+.Dv .for i in 1 2 3
+a+=     ${i}
+j=      ${i}
+b+=     ${j}
+.Dv .endfor
+
+all:
+       @echo ${a}
+       @echo ${b}
+
+.Ed
+will print:
+.Bd -literal -offset indent
+1 2 3
+3 3 3
+
+.Ed
+Because while ${a} contains
+.Dq 1 2 3
+after the loop is executed, ${b}
+contains
+.Dq ${j} ${j} ${j}
+which expands to
+.Dq 3 3 3
+since after the loop completes ${j} contains
+.Dq 3 .
+.El
 .Ss Variable classes
 The four different classes of variables (in order of increasing precedence)
 are:
@@ -652,31 +689,17 @@ The preferred variable to use is the environment variable
 because it is more compatible with other versions of
 .Nm
 and cannot be confused with the special target with the same name.
+.It Va .MAKE.DEPENDFILE
+Names the makefile (default
+.Ql Pa .depend )
+from which generated dependencies are read.
 .It Va .MAKE.EXPORTED
 The list of variables exported by
 .Nm .
-.It Va .MAKE.MAKEFILES
-The list of makefiles read by
-.Nm ,
-which is useful for tracking dependencies.
-Each makefile is recorded only once, regardless of the number of times read.
-.It Va .MAKE.LEVEL
-The recursion depth of
-.Nm .
-The initial instance of
-.Nm
-will be 0, and an incremented value is put into the environment
-to be seen by the next generation.
-This allows tests like:
-.Li .if ${.MAKE.LEVEL} == 0
-to protect things which should only be evaluated in the initial instance of
-.Nm .
-.It Va .MAKE.PID
-The process-id of
-.Nm .
-.It Va .MAKE.PPID
-The parent process-id of
-.Nm .
+.It Va .MAKE.JOBS
+The argument to the
+.Fl j
+option.
 .It Va .MAKE.JOB.PREFIX
 If
 .Nm
@@ -707,6 +730,38 @@ variable which is then
 entered into the environment for all programs which
 .Nm
 executes.
+.It Va .MAKE.LEVEL
+The recursion depth of
+.Nm .
+The initial instance of
+.Nm
+will be 0, and an incremented value is put into the environment
+to be seen by the next generation.
+This allows tests like:
+.Li .if ${.MAKE.LEVEL} == 0
+to protect things which should only be evaluated in the initial instance of
+.Nm .
+.It Va .MAKE.MAKEFILE_PREFERENCE
+The ordered list of makefile names
+(default
+.Ql Pa makefile ,
+.Ql Pa Makefile )
+that
+.Nm
+will look for.
+.It Va .MAKE.MAKEFILES
+The list of makefiles read by
+.Nm ,
+which is useful for tracking dependencies.
+Each makefile is recorded only once, regardless of the number of times read.
+.It Va .MAKE.MODE
+Processed after reading all makefiles.
+Can affect the mode that
+.Nm
+runs in.
+Currently just
+.Ql Pa compat
+mode.
 .It Va .MAKEOVERRIDES
 This variable is used to record the names of variables assigned to
 on the command line, so that they may be exported as part of
@@ -721,6 +776,12 @@ by appending their names to
 is re-exported whenever
 .Ql Va .MAKEOVERRIDES
 is modified.
+.It Va .MAKE.PID
+The process-id of
+.Nm .
+.It Va .MAKE.PPID
+The parent process-id of
+.Nm .
 .It Va MAKE_PRINT_VAR_ON_ERROR
 When
 .Nm
@@ -767,8 +828,10 @@ is set in the environment or on the command line.)
 .Pp
 Variable expansion is performed on the value before it's used,
 so expressions such as
-.Dl ${.CURDIR:C,^/usr/src,/var/obj,}
+.Dl ${.CURDIR:S,^/usr/src,/var/obj,}
 may be used.
+This is especially useful with
+.Ql Ev MAKEOBJDIR .
 .Pp
 .Ql Va .OBJDIR
 may be modified in the makefile as a global variable.
@@ -878,7 +941,7 @@ The standard shell wildcard characters
 .Pf ( Ql * ,
 .Ql \&? ,
 and
-.Ql Op )
+.Ql Oo Oc )
 may
 be used.
 The wildcard characters may be escaped with a backslash
@@ -925,6 +988,10 @@ safely through recursive invocations of
 .Nm .
 .It Cm \&:R
 Replaces each word in the variable with everything but its suffix.
+.It Cm \&:tA
+Attempt to convert variable to an absolute path using
+.Xr realpath 3 ,
+if that fails, the value is unchanged.
 .It Cm \&:tl
 Converts variable to lower-case letters.
 .It Cm \&:ts Ns Ar c
@@ -934,6 +1001,7 @@ This modifier sets the separator to the character
 If
 .Ar c
 is omitted, then no separator is used.
+The common escapes (including octal numeric codes), work as expected.
 .It Cm \&:tu
 Converts variable to upper-case letters.
 .It Cm \&:tW
@@ -1274,6 +1342,11 @@ Conditional expressions are also preceded by a single dot as the first
 character of a line.
 The possible conditionals are as follows:
 .Bl -tag -width Ds
+.It Ic .error Ar message
+The message is printed along with the name of the makefile and line number,
+then
+.Nm
+will exit.
 .It Ic .export Ar variable ...
 Export the specified global variable.
 If no variable list is provided, all globals are exported
@@ -1286,6 +1359,20 @@ flag, so should be used with caution.
 Appending a variable name to
 .Va .MAKE.EXPORTED
 is equivalent to exporting a variable.
+.It Ic .export-env Ar variable ...
+The same as
+.Ql .export ,
+except that the variable is not appended to
+.Va .MAKE.EXPORTED .
+This allows exporting a value to the environment which is different from that
+used by
+.Nm
+internally.
+.It Ic .info Ar message
+The message is printed along with the name of the makefile and line number.
+.It Ic .undef Ar variable
+Un-define the specified global variable.
+Only global variables may be un-defined.
 .It Ic .unexport Ar variable ...
 The opposite of
 .Ql .export .
@@ -1322,9 +1409,10 @@ which is the minimal useful environment.
 Actually
 .Ql Ev .MAKE.LEVEL
 will also be pushed into the new environment.
-.It Ic .undef Ar variable
-Un-define the specified global variable.
-Only global variables may be un-defined.
+.It Ic .warning Ar message
+The message prefixed by
+.Ql Pa warning:
+is printed along with the name of the makefile and line number.
 .It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ...
 Test the value of an expression.
 .It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
@@ -1627,6 +1715,13 @@ to the target's own name.
 .It Ic .END
 Any command lines attached to this target are executed after everything
 else is done.
+.It Ic .ERROR
+Any command lines attached to this target are executed when another target fails.
+The
+.Ic .ERROR_TARGET
+variable is set to the target that failed.
+See also
+.Ic MAKE_PRINT_VAR_ON_ERROR .
 .It Ic .IGNORE
 Mark each of the sources with the
 .Ic .IGNORE
@@ -1750,10 +1845,10 @@ character when used outside of any quoting characters.
 .El
 Example:
 .Bd -literal
-\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \\
-       check="set -e" ignore="set +e" \\
-       echo="set -v" quiet="set +v" filter="set +v" \\
-       echoFlag=v errFlag=e newline="'\\n'"
+\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
+       check="set -e" ignore="set +e" \e
+       echo="set -v" quiet="set +v" filter="set +v" \e
+       echoFlag=v errFlag=e newline="'\en'"
 .Ed
 .It Ic .SILENT
 Apply the
index aa8f8bcd739700f5c0390cbbe81422e22084e937..11e2ca8cba3ac0fb68cf00b020b89133a531e552 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: make.c,v 1.78 2009/01/23 21:26:30 dsl Exp $    */
+/*     $NetBSD: make.c,v 1.79 2010/04/07 00:11:27 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: make.c,v 1.78 2009/01/23 21:26:30 dsl Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.79 2010/04/07 00:11:27 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)make.c     8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: make.c,v 1.78 2009/01/23 21:26:30 dsl Exp $");
+__RCSID("$NetBSD: make.c,v 1.79 2010/04/07 00:11:27 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -958,6 +958,9 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
 void
 Make_DoAllVar(GNode *gn)
 {
+    if (gn->flags & DONE_ALLSRC)
+       return;
+    
     Lst_ForEach(gn->children, MakeUnmark, gn);
     Lst_ForEach(gn->children, MakeAddAllSrc, gn);
 
@@ -974,6 +977,7 @@ Make_DoAllVar(GNode *gn)
        if (p1)
            free(p1);
     }
+    gn->flags |= DONE_ALLSRC;
 }
 \f
 /*-
index 582dae4c335fb111355d626873414ef3ceab0a91..d770586d60a29727529fed284169787278929de9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: make.h,v 1.79 2009/09/08 17:29:20 sjg Exp $    */
+/*     $NetBSD: make.h,v 1.82 2010/04/23 00:18:50 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -164,6 +164,7 @@ typedef struct GNode {
 #define DONE_WAIT      0x8     /* Set by Make_ProcessWait() */
 #define DONE_ORDER     0x10    /* Build requested by .ORDER processing */
 #define FROM_DEPEND    0x20    /* Node created from .depend */
+#define DONE_ALLSRC    0x40    /* We do it once only */
 #define CYCLE          0x1000  /* Used by MakePrintStatus */
 #define DONECYCLE      0x2000  /* Used by MakePrintStatus */
     enum enum_made {
@@ -392,6 +393,18 @@ extern Lst sysIncPath;     /* The system include path. */
 extern Lst     defIncPath;     /* The default include path. */
 
 extern char    *progname;      /* The program name */
+extern char    *makeDependfile; /* .depend */
+
+/*
+ * We cannot vfork() in a child of vfork().
+ * Most systems do not enforce this but some do.
+ */
+#if defined(__minix)
+#define vFork() fork()
+#else
+#define vFork() ((getpid() == myPid) ? vfork() : fork())
+#endif
+extern pid_t   myPid;
 
 #define        MAKEFLAGS       ".MAKEFLAGS"
 #define        MAKEOVERRIDES   ".MAKEOVERRIDES"
@@ -399,6 +412,9 @@ extern char *progname;      /* The program name */
 #define        MAKE_EXPORTED   ".MAKE.EXPORTED"   /* variables we export */
 #define        MAKE_MAKEFILES  ".MAKE.MAKEFILES"  /* all the makefiles we read */
 #define        MAKE_LEVEL      ".MAKE.LEVEL"      /* recursion level */
+#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
+#define MAKE_DEPENDFILE        ".MAKE.DEPENDFILE" /* .depend */
+#define MAKE_MODE      ".MAKE.MODE"
 
 /*
  * debug control:
@@ -442,9 +458,10 @@ void Make_DoAllVar(GNode *);
 Boolean Make_Run(Lst);
 char * Check_Cwd_Cmd(const char *);
 void Check_Cwd(const char **);
-void PrintOnError(const char *);
+void PrintOnError(GNode *, const char *);
 void Main_ExportMAKEFLAGS(Boolean);
 Boolean Main_SetObjdir(const char *);
+int mkTempFile(const char *, char **);
 
 #ifdef __GNUC__
 #define UNCONST(ptr)   ({              \
index c22307cb536457aa75e80818ccdfbdaaf469bde4..f49759a708ce95bed5dd814b40d4a1903269da1e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: nonints.h,v 1.57 2009/11/19 00:30:24 sjg Exp $ */
+/*     $NetBSD: nonints.h,v 1.59 2010/06/03 15:40:16 sjg Exp $ */
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -108,6 +108,7 @@ void For_Run(int);
 
 /* main.c */
 void Main_ParseArgLine(const char *);
+void MakeMode(const char *);
 int main(int, char **);
 char *Cmd_Exec(const char *, const char **);
 void Error(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
@@ -194,3 +195,6 @@ void Var_Dump(GNode *);
 void Var_ExportVars(void);
 void Var_Export(char *, int);
 void Var_UnExport(char *);
+
+/* util.c */
+void (*bmake_signal(int, void (*)(int)))(int);
index 49bc79cd9e398a20e847a3f45b3d23d2084f2ff9..7c6538e096f3c730c3df0ed1a5a231bb5940b7a9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: parse.c,v 1.160 2009/11/19 00:30:25 sjg Exp $  */
+/*     $NetBSD: parse.c,v 1.164 2010/05/24 21:04:49 sjg Exp $  */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.160 2009/11/19 00:30:25 sjg Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.164 2010/05/24 21:04:49 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)parse.c    8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: parse.c,v 1.160 2009/11/19 00:30:25 sjg Exp $");
+__RCSID("$NetBSD: parse.c,v 1.164 2010/05/24 21:04:49 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -191,6 +191,7 @@ typedef enum {
     Begin,         /* .BEGIN */
     Default,       /* .DEFAULT */
     End,           /* .END */
+    dotError,      /* .ERROR */
     Ignore,        /* .IGNORE */
     Includes,      /* .INCLUDES */
     Interrupt,     /* .INTERRUPT */
@@ -245,6 +246,7 @@ static struct {
 { ".BEGIN",      Begin,        0 },
 { ".DEFAULT",    Default,      0 },
 { ".END",        End,          0 },
+{ ".ERROR",      dotError,     0 },
 { ".EXEC",       Attribute,    OP_EXEC },
 { ".IGNORE",     Ignore,       OP_IGNORE },
 { ".INCLUDES",   Includes,     0 },
@@ -449,6 +451,7 @@ ParseErrorInternal(const char *cfname, size_t clineno, int type,
        va_list ap;
 
        va_start(ap, fmt);
+       (void)fflush(stdout);
        ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap);
        va_end(ap);
 
@@ -487,6 +490,7 @@ Parse_Error(int type, const char *fmt, ...)
        }
 
        va_start(ap, fmt);
+       (void)fflush(stdout);
        ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
        va_end(ap);
 
@@ -497,6 +501,53 @@ Parse_Error(int type, const char *fmt, ...)
        }
 }
 
+
+/*
+ * ParseMessage
+ *     Parse a .info .warning or .error directive
+ *
+ *     The input is the line minus the ".".  We substitute
+ *     variables, print the message and exit(1) (for .error) or just print
+ *     a warning if the directive is malformed.
+ */
+static Boolean
+ParseMessage(char *line)
+{
+    int mtype;
+
+    switch(*line) {
+    case 'i':
+       mtype = 0;
+       break;
+    case 'w':
+       mtype = PARSE_WARNING;
+       break;
+    case 'e':
+       mtype = PARSE_FATAL;
+       break;
+    default:
+       Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line);
+       return FALSE;
+    }
+
+    while (isalpha((u_char)*line))
+       line++;
+    if (!isspace((u_char)*line))
+       return FALSE;                   /* not for us */
+    while (isspace((u_char)*line))
+       line++;
+
+    line = Var_Subst(NULL, line, VAR_CMD, 0);
+    Parse_Error(mtype, "%s", line);
+    free(line);
+
+    if (mtype == PARSE_FATAL) {
+       /* Terminate immediately. */
+       exit(1);
+    }
+    return TRUE;
+}
+
 /*-
  *---------------------------------------------------------------------
  * ParseLinkSrc  --
@@ -973,6 +1024,7 @@ ParseDoDependency(char *line)
                 *      .NOPATH         Don't search for file in the path
                 *      .BEGIN
                 *      .END
+                *      .ERROR
                 *      .INTERRUPT      Are not to be considered the
                 *                      main target.
                 *      .NOTPARALLEL    Make only one target at a time.
@@ -993,6 +1045,7 @@ ParseDoDependency(char *line)
                        break;
                    case Begin:
                    case End:
+                   case dotError:
                    case Interrupt:
                        gn = Targ_FindNode(line, TARG_CREATE);
                        gn->type |= OP_NOTMAIN|OP_SPECIAL;
@@ -1122,6 +1175,7 @@ ParseDoDependency(char *line)
            case Default:
            case Begin:
            case End:
+           case dotError:
            case Interrupt:
                /*
                 * These four create nodes on which to hang commands, so
@@ -2513,7 +2567,12 @@ Parse_File(const char *name, int fd)
                } else if (strncmp(cp, "unexport", 8) == 0) {
                    Var_UnExport(cp);
                    continue;
-               }
+               } else if (strncmp(cp, "info", 4) == 0 ||
+                          strncmp(cp, "error", 5) == 0 ||
+                          strncmp(cp, "warning", 7) == 0) {
+                   if (ParseMessage(cp))
+                       continue;
+               }                   
            }
 
            if (*line == '\t') {
@@ -2658,10 +2717,11 @@ Parse_File(const char *name, int fd)
     } while (ParseEOF() == CONTINUE);
 
     if (fatals) {
+       (void)fflush(stdout);
        (void)fprintf(stderr,
            "%s: Fatal errors encountered -- cannot continue\n",
            progname);
-       PrintOnError(NULL);
+       PrintOnError(NULL, NULL);
        exit(1);
     }
 }
index 5b51e2c2b56e6452c0dde5f1ceead74302db0e79..3c27089d3cc6b04ac90ba16f8b5490bf9296284f 100644 (file)
@@ -1,15 +1,15 @@
-/*     $NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $       */
+/*     $NetBSD: util.c,v 1.50 2010/06/03 15:40:16 sjg Exp $    */
 
 /*
  * Missing stuff from OS's
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $";
+static char rcsid[] = "$NetBSD: util.c,v 1.50 2010/06/03 15:40:16 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $");
+__RCSID("$NetBSD: util.c,v 1.50 2010/06/03 15:40:16 sjg Exp $");
 #endif
 #endif
 
@@ -18,6 +18,7 @@ __RCSID("$NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $");
 #include <errno.h>
 #include <stdio.h>
 #include <time.h>
+#include <signal.h>
 
 #include "make.h"
 
@@ -231,24 +232,6 @@ random(void)
 }
 #endif
 
-/* turn into bsd signals */
-void (*
-signal(int s, void (*a)(int)))(int)
-{
-    struct sigvec osv, sv;
-
-    (void)sigvector(s, NULL, &osv);
-    sv = osv;
-    sv.sv_handler = a;
-#ifdef SV_BSDSIG
-    sv.sv_flags = SV_BSDSIG;
-#endif
-
-    if (sigvector(s, &sv, NULL) == -1)
-        return (BADSIG);
-    return (osv.sv_handler);
-}
-
 #if !defined(__hpux__) && !defined(__hpux)
 int
 utimes(char *file, struct timeval tvp[2])
@@ -370,12 +353,9 @@ getwd(char *pathname)
 } /* end getwd */
 #endif /* __hpux */
 
-#if defined(sun) && defined(__svr4__)
-#include <signal.h>
-
-/* turn into bsd signals */
+/* force posix signals */
 void (*
-signal(int s, void (*a)(int)))(int)
+bmake_signal(int s, void (*a)(int)))(int)
 {
     struct sigaction sa, osa;
 
@@ -388,7 +368,6 @@ signal(int s, void (*a)(int)))(int)
     else
        return osa.sa_handler;
 }
-#endif
 
 #if !defined(MAKE_NATIVE) && !defined(HAVE_VSNPRINTF)
 #include <stdarg.h>
index ec5a576227b448320acbfcca217d82407e9b009d..d644674c7acda9d31a6de86c40ccfcf8b56a57c5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: var.c,v 1.155 2009/11/19 00:30:25 sjg Exp $    */
+/*     $NetBSD: var.c,v 1.159 2010/06/06 01:13:12 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.155 2009/11/19 00:30:25 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.159 2010/06/06 01:13:12 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)var.c      8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: var.c,v 1.155 2009/11/19 00:30:25 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.159 2010/06/06 01:13:12 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -123,6 +123,7 @@ __RCSID("$NetBSD: var.c,v 1.155 2009/11/19 00:30:25 sjg Exp $");
  * XXX: There's a lot of duplication in these functions.
  */
 
+#include    <sys/stat.h>
 #ifndef NO_REGEX
 #include    <sys/types.h>
 #include    <regex.h>
@@ -590,6 +591,13 @@ Var_Export1(const char *name, int parent)
            v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
            return 1;
        }
+       if (v->flags & VAR_IN_USE) {
+           /*
+            * We recursed while exporting in a child.
+            * This isn't going to end well, just skip it.
+            */
+           return 0;
+       }
        n = snprintf(tmp, sizeof(tmp), "${%s}", name);
        if (n < (int)sizeof(tmp)) {
            val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
@@ -674,6 +682,7 @@ Var_Export(char *str, int isExport)
     char *val;
     char **av;
     char *as;
+    int track;
     int ac;
     int i;
 
@@ -682,6 +691,12 @@ Var_Export(char *str, int isExport)
        return;
     }
 
+    if (strncmp(str, "-env", 4) == 0) {
+       track = 0;
+       str += 4;
+    } else {
+       track = VAR_EXPORT_PARENT;
+    }
     val = Var_Subst(NULL, str, VAR_GLOBAL, 0);
     av = brk_string(val, &ac, FALSE, &as);
     for (i = 0; i < ac; i++) {
@@ -701,10 +716,10 @@ Var_Export(char *str, int isExport)
                continue;
            }
        }
-       if (Var_Export1(name, VAR_EXPORT_PARENT)) {
+       if (Var_Export1(name, track)) {
            if (VAR_EXPORTED_ALL != var_exportedVars)
                var_exportedVars = VAR_EXPORTED_YES;
-           if (isExport) {
+           if (isExport && track) {
                Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
            }
        }
@@ -1859,6 +1874,33 @@ VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
     return Buf_Destroy(&buf, FALSE);
 }
 
+
+/*-
+ * VarRealpath --
+ *     Replace each word with the result of realpath()
+ *     if successful.
+ */
+static Boolean
+VarRealpath(GNode *ctx __unused, Var_Parse_State *vpstate,
+           char *word, Boolean addSpace, Buffer *buf,
+           void *patternp __unused)
+{
+       struct stat st;
+       char rbuf[MAXPATHLEN];
+       char *rp;
+                           
+       if (addSpace && vpstate->varSpace) {
+           Buf_AddByte(buf, vpstate->varSpace);
+       }
+       addSpace = TRUE;
+       rp = realpath(word, rbuf);
+       if (rp && *rp == '/' && stat(rp, &st) == 0)
+               word = rp;
+       
+       Buf_AddBytes(buf, strlen(word), word);
+       return(addSpace);
+}
+
 /*-
  *-----------------------------------------------------------------------
  * VarModify --
@@ -2849,7 +2891,12 @@ ApplyModifiers(char *nstr, const char *tstr,
                         * Check for two-character options:
                         * ":tu", ":tl"
                         */
-                       if (tstr[1] == 'u' || tstr[1] == 'l') {
+                       if (tstr[1] == 'A') { /* absolute path */
+                           newStr = VarModify(ctxt, &parsestate, nstr,
+                                              VarRealpath, NULL);
+                           cp = tstr + 2;
+                           termc = *cp;
+                       } else if (tstr[1] == 'u' || tstr[1] == 'l') {
                            newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
                            cp = tstr + 2;
                            termc = *cp;