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
Error(const char * fmt,...)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
Fatal(const char * fmt,...)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
Punt(const char * fmt,...)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
Finish(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
ParseVErrorInternal(const Location * origin,int type,const char * fmt,va_list ap)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
Parse_Error(int type,const char * fmt,...)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