Module Name:    src
Committed By:   sjg
Date:           Wed Apr  7 00:11:28 UTC 2010

Modified Files:
        src/usr.bin/make: compat.c job.c main.c make.1 make.c make.h nonints.h
            parse.c

Log Message:
Add:

.error "message"
.warning "message"
        based on FreeBSD implementation.
        add .info while were at it.

.ERROR: a target to run on error.
        We pass the failing GNode to PrintOnError so it can set
        .ERROR_TARGET.

.MAKE.MAKEFILE_PREFERENCE
        As a means to control make's list of prefered makefile names.
        (Default: "makefile Makefile")

.MAKE.DEPENDFILE
        Names the file to read dependencies from
        (Default ".depend")

.MAKE.MODE
        Processed after all makefiles are read.
        Can put make into "compat" mode (more to come).

Fix:

compat.c: Error code should not be sent to debug_file.
Make_DoAllVar: use DONE_ALLSRC to avoid processing a node multiple times.
ReadMakefile: we can simply use doing_depend to control setting MAKEFILE.


To generate a diff of this commit:
cvs rdiff -u -r1.76 -r1.77 src/usr.bin/make/compat.c
cvs rdiff -u -r1.146 -r1.147 src/usr.bin/make/job.c
cvs rdiff -u -r1.175 -r1.176 src/usr.bin/make/main.c
cvs rdiff -u -r1.167 -r1.168 src/usr.bin/make/make.1
cvs rdiff -u -r1.78 -r1.79 src/usr.bin/make/make.c
cvs rdiff -u -r1.79 -r1.80 src/usr.bin/make/make.h
cvs rdiff -u -r1.57 -r1.58 src/usr.bin/make/nonints.h
cvs rdiff -u -r1.160 -r1.161 src/usr.bin/make/parse.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/compat.c
diff -u src/usr.bin/make/compat.c:1.76 src/usr.bin/make/compat.c:1.77
--- src/usr.bin/make/compat.c:1.76	Sun Feb 22 07:33:00 2009
+++ src/usr.bin/make/compat.c	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $	*/
+/*	$NetBSD: compat.c,v 1.77 2010/04/07 00:11:27 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
  */
 
 #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.77 2010/04/07 00:11:27 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.77 2010/04/07 00:11:27 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -407,7 +407,7 @@
 		        }
 			fprintf(debug_file, "\n");
 		    }
-		    fprintf(debug_file, "*** Error code %d", status);
+		    printf("*** Error code %d", status);
 		}
 	    } else {
 		status = WTERMSIG(reason);		/* signaled */
@@ -574,7 +574,7 @@
 	} else if (keepgoing) {
 	    pgn->flags &= ~REMAKE;
 	} else {
-	    PrintOnError("\n\nStop.");
+	    PrintOnError(gn, "\n\nStop.");
 	    exit(1);
 	}
     } else if (gn->made == ERROR) {
@@ -665,7 +665,7 @@
 	if (gn != NULL) {
 	    Compat_Make(gn, gn);
             if (gn->made == ERROR) {
-                PrintOnError("\n\nStop.");
+                PrintOnError(gn, "\n\nStop.");
                 exit(1);
             }
 	}
@@ -706,7 +706,7 @@
     if (errors == 0) {
 	Compat_Make(ENDNode, ENDNode);
 	if (gn->made == ERROR) {
-	    PrintOnError("\n\nStop.");
+	    PrintOnError(gn, "\n\nStop.");
 	    exit(1);
 	}
     }

Index: src/usr.bin/make/job.c
diff -u src/usr.bin/make/job.c:1.146 src/usr.bin/make/job.c:1.147
--- src/usr.bin/make/job.c:1.146	Fri Jun 26 01:26:32 2009
+++ src/usr.bin/make/job.c	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: job.c,v 1.146 2009/06/26 01:26:32 sjg Exp $	*/
+/*	$NetBSD: job.c,v 1.147 2010/04/07 00:11:27 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
  */
 
 #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.147 2010/04/07 00:11:27 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.147 2010/04/07 00:11:27 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -1225,8 +1225,8 @@
 	    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;
 	    }
 
@@ -1897,7 +1897,7 @@
 #else
     Compat_Make(targ, targ);
     if (targ->made == ERROR) {
-	PrintOnError("\n\nStop.");
+	PrintOnError(targ, "\n\nStop.");
 	exit(1);
     }
 #endif
@@ -2227,7 +2227,7 @@
     if (begin != NULL) {
 	JobRun(begin);
 	if (begin->made == ERROR) {
-	    PrintOnError("\n\nStop.");
+	    PrintOnError(begin, "\n\nStop.");
 	    exit(1);
 	}
     }

Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.175 src/usr.bin/make/main.c:1.176
--- src/usr.bin/make/main.c:1.175	Mon Jan  4 17:05:25 2010
+++ src/usr.bin/make/main.c	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.175 2010/01/04 17:05:25 sjg Exp $	*/
+/*	$NetBSD: main.c,v 1.176 2010/04/07 00:11:27 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.175 2010/01/04 17:05:25 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.176 2010/04/07 00:11:27 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
@@ -81,7 +81,7 @@
 #if 0
 static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.175 2010/01/04 17:05:25 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.176 2010/04/07 00:11:27 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -184,6 +184,7 @@
 static char curdir[MAXPATHLEN + 1];	/* startup directory */
 static char objdir[MAXPATHLEN + 1];	/* where we chdir'ed to */
 char *progname;				/* the program name */
+char *makeDependfile;
 
 Boolean forceJobs = FALSE;
 
@@ -680,6 +681,22 @@
 	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
@@ -696,6 +713,27 @@
 }
 #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
@@ -813,6 +851,15 @@
 	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);
@@ -1051,16 +1098,27 @@
 		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);
@@ -1219,14 +1277,11 @@
 	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;
@@ -1273,7 +1328,7 @@
 		 * 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);
 	}
@@ -1666,7 +1721,7 @@
 	(void)fprintf(stderr, "\n");
 	(void)fflush(stderr);
 
-	PrintOnError(NULL);
+	PrintOnError(NULL, NULL);
 
 	if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
 		Targ_PrintGraph(2);
@@ -1698,7 +1753,7 @@
 	(void)fprintf(stderr, "\n");
 	(void)fflush(stderr);
 
-	PrintOnError(NULL);
+	PrintOnError(NULL, NULL);
 
 	DieHorribly();
 }
@@ -1819,15 +1874,32 @@
 
 
 void
-PrintOnError(const char *s)
+PrintOnError(GNode *gn, const char *s)
 {
+    GNode *en;
     char tmp[64];
     char *cp;
 
     if (s)
-	    printf("%s", s);
+	printf("%s", s);
 	
     printf("\n%s: stopped in %s\n", progname, curdir);
+
+    if (gn) {
+	/*
+	 * We can print this even if there is no .ERROR target.
+	 */
+	Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
+    }
+    /*
+     * 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);
+    }
+    
     strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v...@$v='${$v}'\...@}",
 	    sizeof(tmp) - 1);
     cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);

Index: src/usr.bin/make/make.1
diff -u src/usr.bin/make/make.1:1.167 src/usr.bin/make/make.1:1.168
--- src/usr.bin/make/make.1:1.167	Mon Feb 22 19:20:33 2010
+++ src/usr.bin/make/make.1	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.167 2010/02/22 19:20:33 joerg Exp $
+.\"	$NetBSD: make.1,v 1.168 2010/04/07 00:11:27 sjg 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 April 6, 2010
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -652,14 +652,34 @@
 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.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 .MAKE.LEVEL
 The recursion depth of
 .Nm .
@@ -1274,6 +1294,11 @@
 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 +1311,8 @@
 Appending a variable name to
 .Va .MAKE.EXPORTED
 is equivalent to exporting a variable.
+.It Ic .info Ar message
+The message is printed along with the name of the makefile and line number.
 .It Ic .unexport Ar variable ...
 The opposite of
 .Ql .export .
@@ -1325,6 +1352,10 @@
 .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 +1658,13 @@
 .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

Index: src/usr.bin/make/make.c
diff -u src/usr.bin/make/make.c:1.78 src/usr.bin/make/make.c:1.79
--- src/usr.bin/make/make.c:1.78	Fri Jan 23 21:26:30 2009
+++ src/usr.bin/make/make.c	Wed Apr  7 00:11:27 2010
@@ -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
@@ -69,14 +69,14 @@
  */
 
 #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 @@
 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 @@
 	if (p1)
 	    free(p1);
     }
+    gn->flags |= DONE_ALLSRC;
 }
 
 /*-

Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.79 src/usr.bin/make/make.h:1.80
--- src/usr.bin/make/make.h:1.79	Tue Sep  8 17:29:20 2009
+++ src/usr.bin/make/make.h	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.h,v 1.79 2009/09/08 17:29:20 sjg Exp $	*/
+/*	$NetBSD: make.h,v 1.80 2010/04/07 00:11:27 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -164,6 +164,7 @@
 #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,7 @@
 extern Lst	defIncPath;	/* The default include path. */
 
 extern char	*progname;	/* The program name */
+extern char	*makeDependfile; /* .depend */
 
 #define	MAKEFLAGS	".MAKEFLAGS"
 #define	MAKEOVERRIDES	".MAKEOVERRIDES"
@@ -399,6 +401,9 @@
 #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,7 +447,7 @@
 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 *);
 

Index: src/usr.bin/make/nonints.h
diff -u src/usr.bin/make/nonints.h:1.57 src/usr.bin/make/nonints.h:1.58
--- src/usr.bin/make/nonints.h:1.57	Thu Nov 19 00:30:24 2009
+++ src/usr.bin/make/nonints.h	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: nonints.h,v 1.57 2009/11/19 00:30:24 sjg Exp $	*/
+/*	$NetBSD: nonints.h,v 1.58 2010/04/07 00:11:27 sjg Exp $	*/
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -108,6 +108,7 @@
 
 /* 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)));

Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.160 src/usr.bin/make/parse.c:1.161
--- src/usr.bin/make/parse.c:1.160	Thu Nov 19 00:30:25 2009
+++ src/usr.bin/make/parse.c	Wed Apr  7 00:11:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.160 2009/11/19 00:30:25 sjg Exp $	*/
+/*	$NetBSD: parse.c,v 1.161 2010/04/07 00:11:27 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #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.161 2010/04/07 00:11:27 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.161 2010/04/07 00:11:27 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -497,6 +497,50 @@
 	}
 }
 
+
+/*
+ * 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 void
+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;
+    }
+
+    while (!isspace((u_char)*line))
+	line++;
+    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);
+    }
+}
+
 /*-
  *---------------------------------------------------------------------
  * ParseLinkSrc  --
@@ -2513,7 +2557,12 @@
 		} 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) {
+		    ParseMessage(cp);
+		    continue;
+		}		    
 	    }
 
 	    if (*line == '\t') {
@@ -2661,7 +2710,7 @@
 	(void)fprintf(stderr,
 	    "%s: Fatal errors encountered -- cannot continue\n",
 	    progname);
-	PrintOnError(NULL);
+	PrintOnError(NULL, NULL);
 	exit(1);
     }
 }

Reply via email to