xref: /openbsd/usr.bin/make/error.c (revision 4fb9ab68)
1 /*	$OpenBSD: error.c,v 1.27 2024/06/18 02:11:03 millert Exp $ */
2 
3 /*
4  * Copyright (c) 2001 Marc Espie.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
19  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 
34 #include "defines.h"
35 #include "error.h"
36 #include "job.h"
37 #include "targ.h"
38 #include "var.h"
39 #ifndef LOCATION_TYPE
40 #include "location.h"
41 #endif
42 
43 #include "lowparse.h"
44 #include "dump.h"
45 
46 int fatal_errors = 0;
47 
48 static void ParseVErrorInternal(const Location *, int, const char *, va_list)
49 			__attribute__((__format__ (printf, 3, 0)));
50 /*-
51  * Error --
52  *	Print an error message given its format.
53  */
54 void
55 Error(const char *fmt, ...)
56 {
57 	va_list ap;
58 
59 	va_start(ap, fmt);
60 	(void)vfprintf(stderr, fmt, ap);
61 	va_end(ap);
62 	(void)fprintf(stderr, "\n");
63 }
64 
65 /*-
66  * Fatal --
67  *	Produce a Fatal error message. If jobs are running, waits for them
68  *	to finish.
69  *
70  * Side Effects:
71  *	The program exits
72  */
73 void
74 Fatal(const char *fmt, ...)
75 {
76 	va_list ap;
77 
78 	Job_Wait();
79 
80 	va_start(ap, fmt);
81 	(void)vfprintf(stderr, fmt, ap);
82 	va_end(ap);
83 	(void)fprintf(stderr, "\n");
84 
85 	if (DEBUG(GRAPH2))
86 		post_mortem();
87 	exit(2);		/* Not 1 so -q can distinguish error */
88 }
89 
90 /*
91  * Punt --
92  *	Major exception once jobs are being created. Kills all jobs, prints
93  *	a message and exits.
94  *
95  * Side Effects:
96  *	All children are killed indiscriminately and the program Lib_Exits
97  */
98 void
99 Punt(const char *fmt, ...)
100 {
101 	if (fmt) {
102 		va_list ap;
103 
104 		va_start(ap, fmt);
105 		(void)fprintf(stderr, "make: ");
106 		(void)vfprintf(stderr, fmt, ap);
107 		va_end(ap);
108 		(void)fprintf(stderr, "\n");
109 	}
110 
111 	Job_AbortAll();
112 	if (DEBUG(GRAPH2))
113 		post_mortem();
114 	exit(2);		/* Not 1, so -q can distinguish error */
115 }
116 
117 /*
118  * Finish --
119  *	Called when aborting due to errors in command or fatal signal
120  *
121  * Side Effects:
122  *	The program exits
123  */
124 void
125 Finish(void)
126 {
127 	Job_Wait();
128 	print_errors();
129 	if (DEBUG(GRAPH2))
130 		post_mortem();
131 	exit(2);		/* Not 1 so -q can distinguish error */
132 }
133 
134 
135 /*-
136  * ParseVErrorInternal	--
137  *	Error message abort function for parsing. Prints out the context
138  *	of the error (line number and file) as well as the message with
139  *	two optional arguments.
140  *
141  * Side Effects:
142  *	"fatals" is incremented if the level is PARSE_FATAL.
143  */
144 static void
145 ParseVErrorInternal(const Location *origin, int type, const char *fmt,
146     va_list ap)
147 {
148 	static bool first = true;
149 	fprintf(stderr, "*** %s",
150 	    type == PARSE_WARNING ? "Warning" : "Parse error");
151 	if (first) {
152 		fprintf(stderr, " in %s: ", Var_Value(".CURDIR"));
153 		first = false;
154 	} else
155 		fprintf(stderr, ": ");
156 	vfprintf(stderr, fmt, ap);
157 	va_end(ap);
158 	if (origin->fname)
159 	    	fprintf(stderr, " (%s:%lu)", origin->fname, origin->lineno);
160 	fprintf(stderr, "\n");
161 	if (type == PARSE_FATAL)
162 		fatal_errors ++;
163 }
164 
165 /*-
166  * Parse_Error	--
167  *	External interface to ParseVErrorInternal; uses the default filename
168  *	Line number.
169  */
170 void
171 Parse_Error(int type, const char *fmt, ...)
172 {
173 	va_list ap;
174 	Location l;
175 
176 	va_start(ap, fmt);
177 	Parse_FillLocation(&l);
178 	ParseVErrorInternal(&l, type, fmt, ap);
179 	va_end(ap);
180 }
181