Stylification: missing spaces, extra space after function names,
[dragonfly.git] / usr.bin / make / util.c
1 /*
2  * Copyright (c) 2002 Juli Mallett.  All rights reserved.
3  * Copyright (c) 1988, 1989, 1990, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  * Copyright (c) 1989 by Berkeley Softworks
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Adam de Boor.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *      This product includes software developed by the University of
22  *      California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * $FreeBSD: src/usr.bin/make/util.c,v 1.5.2.2 2001/02/13 03:13:58 will Exp $
28  * $DragonFly: src/usr.bin/make/util.c,v 1.9 2004/12/10 19:22:24 okumoto Exp $
29  */
30
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <err.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdio.h>
38 #include <sysexits.h>
39 #include <stdarg.h>
40 #include <unistd.h>
41
42 #include "make.h"
43 #include "hash.h"
44 #include "dir.h"
45 #include "job.h"
46 #include "pathnames.h"
47
48 /*-
49  * Debug --
50  *      Print a debugging message given its format.
51  *
52  * Results:
53  *      None.
54  *
55  * Side Effects:
56  *      The message is printed.
57  */
58 /* VARARGS */
59 void
60 Debug(const char *fmt, ...)
61 {
62         va_list ap;
63
64         va_start(ap, fmt);
65         vfprintf(stderr, fmt, ap);
66         va_end(ap);
67         fflush(stderr);
68 }
69
70 /*-
71  * Error --
72  *      Print an error message given its format.
73  *
74  * Results:
75  *      None.
76  *
77  * Side Effects:
78  *      The message is printed.
79  */
80 /* VARARGS */
81 void
82 Error(const char *fmt, ...)
83 {
84         va_list ap;
85         va_start(ap, fmt);
86         vfprintf(stderr, fmt, ap);
87         va_end(ap);
88         fprintf(stderr, "\n");
89         fflush(stderr);
90 }
91
92 /*-
93  * Fatal --
94  *      Produce a Fatal error message. If jobs are running, waits for them
95  *      to finish.
96  *
97  * Results:
98  *      None
99  *
100  * Side Effects:
101  *      The program exits
102  */
103 /* VARARGS */
104 void
105 Fatal(const char *fmt, ...)
106 {
107         va_list ap;
108         va_start(ap, fmt);
109         if (jobsRunning)
110                 Job_Wait();
111
112         vfprintf(stderr, fmt, ap);
113         va_end(ap);
114         fprintf(stderr, "\n");
115         fflush(stderr);
116
117         if (DEBUG(GRAPH2))
118                 Targ_PrintGraph(2);
119         exit(2);                /* Not 1 so -q can distinguish error */
120 }
121
122 /*
123  * Punt --
124  *      Major exception once jobs are being created. Kills all jobs, prints
125  *      a message and exits.
126  *
127  * Results:
128  *      None
129  *
130  * Side Effects:
131  *      All children are killed indiscriminately and the program Lib_Exits
132  */
133 /* VARARGS */
134 void
135 Punt(const char *fmt, ...)
136 {
137         va_list ap;
138         va_start(ap, fmt);
139
140         fprintf(stderr, "make: ");
141         vfprintf(stderr, fmt, ap);
142         va_end(ap);
143         fprintf(stderr, "\n");
144         fflush(stderr);
145
146         DieHorribly();
147 }
148
149 /*-
150  * DieHorribly --
151  *      Exit without giving a message.
152  *
153  * Results:
154  *      None
155  *
156  * Side Effects:
157  *      A big one...
158  */
159 void
160 DieHorribly(void)
161 {
162         if (jobsRunning)
163                 Job_AbortAll();
164         if (DEBUG(GRAPH2))
165                 Targ_PrintGraph(2);
166         exit(2);                /* Not 1, so -q can distinguish error */
167 }
168
169 /*
170  * Finish --
171  *      Called when aborting due to errors in child shell to signal
172  *      abnormal exit, with the number of errors encountered in Make_Make.
173  *
174  * Results:
175  *      None
176  *
177  * Side Effects:
178  *      The program exits
179  */
180 void
181 Finish(int errors)
182 {
183
184         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
185 }
186
187 /*
188  * emalloc --
189  *      malloc, but die on error.
190  */
191 void *
192 emalloc(size_t len)
193 {
194         void *p;
195
196         if ((p = malloc(len)) == NULL)
197                 enomem();
198         return (p);
199 }
200
201 /*
202  * estrdup --
203  *      strdup, but die on error.
204  */
205 char *
206 estrdup(const char *str)
207 {
208         char *p;
209
210         if ((p = strdup(str)) == NULL)
211                 enomem();
212         return (p);
213 }
214
215 /*
216  * erealloc --
217  *      realloc, but die on error.
218  */
219 void *
220 erealloc(void *ptr, size_t size)
221 {
222
223         if ((ptr = realloc(ptr, size)) == NULL)
224                 enomem();
225         return (ptr);
226 }
227
228 /*
229  * enomem --
230  *      die when out of memory.
231  */
232 void
233 enomem(void)
234 {
235         err(2, NULL);
236 }
237
238 /*
239  * enunlink --
240  *      Remove a file carefully, avoiding directories.
241  */
242 int
243 eunlink(const char *file)
244 {
245         struct stat st;
246
247         if (lstat(file, &st) == -1)
248                 return (-1);
249
250         if (S_ISDIR(st.st_mode)) {
251                 errno = EISDIR;
252                 return (-1);
253         }
254         return (unlink(file));
255 }
256
257 /*
258  * Printaddr --
259  *      Print the address of a node, used as an interative function.
260  */
261 int
262 PrintAddr(void *a, void *b __unused)
263 {
264
265     printf("%p ", a);
266     return (0);
267 }