ce192dbea3229fe84e3563d0949bca078cbb490e
[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.10 2004/12/17 21:09:04 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
86         va_start(ap, fmt);
87         vfprintf(stderr, fmt, ap);
88         va_end(ap);
89         fprintf(stderr, "\n");
90         fflush(stderr);
91 }
92
93 /*-
94  * Fatal --
95  *      Produce a Fatal error message. If jobs are running, waits for them
96  *      to finish.
97  *
98  * Results:
99  *      None
100  *
101  * Side Effects:
102  *      The program exits
103  */
104 /* VARARGS */
105 void
106 Fatal(const char *fmt, ...)
107 {
108         va_list ap;
109
110         va_start(ap, fmt);
111         if (jobsRunning)
112                 Job_Wait();
113
114         vfprintf(stderr, fmt, ap);
115         va_end(ap);
116         fprintf(stderr, "\n");
117         fflush(stderr);
118
119         if (DEBUG(GRAPH2))
120                 Targ_PrintGraph(2);
121         exit(2);                /* Not 1 so -q can distinguish error */
122 }
123
124 /*
125  * Punt --
126  *      Major exception once jobs are being created. Kills all jobs, prints
127  *      a message and exits.
128  *
129  * Results:
130  *      None
131  *
132  * Side Effects:
133  *      All children are killed indiscriminately and the program Lib_Exits
134  */
135 /* VARARGS */
136 void
137 Punt(const char *fmt, ...)
138 {
139         va_list ap;
140
141         va_start(ap, fmt);
142         fprintf(stderr, "make: ");
143         vfprintf(stderr, fmt, ap);
144         va_end(ap);
145         fprintf(stderr, "\n");
146         fflush(stderr);
147
148         DieHorribly();
149 }
150
151 /*-
152  * DieHorribly --
153  *      Exit without giving a message.
154  *
155  * Results:
156  *      None
157  *
158  * Side Effects:
159  *      A big one...
160  */
161 void
162 DieHorribly(void)
163 {
164         if (jobsRunning)
165                 Job_AbortAll();
166         if (DEBUG(GRAPH2))
167                 Targ_PrintGraph(2);
168         exit(2);                /* Not 1, so -q can distinguish error */
169 }
170
171 /*
172  * Finish --
173  *      Called when aborting due to errors in child shell to signal
174  *      abnormal exit, with the number of errors encountered in Make_Make.
175  *
176  * Results:
177  *      None
178  *
179  * Side Effects:
180  *      The program exits
181  */
182 void
183 Finish(int errors)
184 {
185
186         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
187 }
188
189 /*
190  * emalloc --
191  *      malloc, but die on error.
192  */
193 void *
194 emalloc(size_t len)
195 {
196         void *p;
197
198         if ((p = malloc(len)) == NULL)
199                 enomem();
200         return (p);
201 }
202
203 /*
204  * estrdup --
205  *      strdup, but die on error.
206  */
207 char *
208 estrdup(const char *str)
209 {
210         char *p;
211
212         if ((p = strdup(str)) == NULL)
213                 enomem();
214         return (p);
215 }
216
217 /*
218  * erealloc --
219  *      realloc, but die on error.
220  */
221 void *
222 erealloc(void *ptr, size_t size)
223 {
224
225         if ((ptr = realloc(ptr, size)) == NULL)
226                 enomem();
227         return (ptr);
228 }
229
230 /*
231  * enomem --
232  *      die when out of memory.
233  */
234 void
235 enomem(void)
236 {
237         err(2, NULL);
238 }
239
240 /*
241  * enunlink --
242  *      Remove a file carefully, avoiding directories.
243  */
244 int
245 eunlink(const char *file)
246 {
247         struct stat st;
248
249         if (lstat(file, &st) == -1)
250                 return (-1);
251
252         if (S_ISDIR(st.st_mode)) {
253                 errno = EISDIR;
254                 return (-1);
255         }
256         return (unlink(file));
257 }
258
259 /*
260  * Printaddr --
261  *      Print the address of a node, used as an interative function.
262  */
263 int
264 PrintAddr(void *a, void *b __unused)
265 {
266
267     printf("%p ", a);
268     return (0);
269 }