diff options
Diffstat (limited to 'usr.bin/make/util.c')
-rw-r--r-- | usr.bin/make/util.c | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/usr.bin/make/util.c b/usr.bin/make/util.c new file mode 100644 index 0000000..3a27b0a --- /dev/null +++ b/usr.bin/make/util.c @@ -0,0 +1,316 @@ +/*- + * Copyright (c) 2002 Juli Mallett. All rights reserved. + * Copyright (c) 1988, 1989, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 1989 by Berkeley Softworks + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Adam de Boor. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)main.c 8.3 (Berkeley) 3/19/94 + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/*- + * util.c -- + * General utilitarian routines for make(1). + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <err.h> +#include <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "globals.h" +#include "job.h" +#include "targ.h" +#include "util.h" + +static void enomem(void) __dead2; + +/*- + * Debug -- + * Print a debugging message given its format. + * + * Results: + * None. + * + * Side Effects: + * The message is printed. + */ +/* VARARGS */ +void +Debug(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fflush(stderr); +} + +/*- + * Print a debugging message given its format and append the current + * errno description. Terminate with a newline. + */ +/* VARARGS */ +void +DebugM(const char *fmt, ...) +{ + va_list ap; + int e = errno; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": %s\n", strerror(e)); + va_end(ap); + fflush(stderr); +} + +/*- + * Error -- + * Print an error message given its format. + * + * Results: + * None. + * + * Side Effects: + * The message is printed. + */ +/* VARARGS */ +void +Error(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + fflush(stderr); +} + +/*- + * Fatal -- + * Produce a Fatal error message. If jobs are running, waits for them + * to finish. + * + * Results: + * None + * + * Side Effects: + * The program exits + */ +/* VARARGS */ +void +Fatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (jobsRunning) + Job_Wait(); + + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + fflush(stderr); + + if (DEBUG(GRAPH2)) + Targ_PrintGraph(2); + exit(2); /* Not 1 so -q can distinguish error */ +} + +/* + * Punt -- + * Major exception once jobs are being created. Kills all jobs, prints + * a message and exits. + * + * Results: + * None + * + * Side Effects: + * All children are killed indiscriminately and the program Lib_Exits + */ +/* VARARGS */ +void +Punt(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "make: "); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + fflush(stderr); + + DieHorribly(); +} + +/*- + * DieHorribly -- + * Exit without giving a message. + * + * Results: + * None + * + * Side Effects: + * A big one... + */ +void +DieHorribly(void) +{ + if (jobsRunning) + Job_AbortAll(); + if (DEBUG(GRAPH2)) + Targ_PrintGraph(2); + exit(2); /* Not 1, so -q can distinguish error */ +} + +/* + * Finish -- + * Called when aborting due to errors in child shell to signal + * abnormal exit, with the number of errors encountered in Make_Make. + * + * Results: + * None + * + * Side Effects: + * The program exits + */ +void +Finish(int errors) +{ + + Fatal("%d error%s", errors, errors == 1 ? "" : "s"); +} + +/* + * emalloc -- + * malloc, but die on error. + */ +void * +emalloc(size_t len) +{ + void *p; + + if ((p = malloc(len)) == NULL) + enomem(); + return (p); +} + +/* + * estrdup -- + * strdup, but die on error. + */ +char * +estrdup(const char *str) +{ + char *p; + + if ((p = strdup(str)) == NULL) + enomem(); + return (p); +} + +/* + * erealloc -- + * realloc, but die on error. + */ +void * +erealloc(void *ptr, size_t size) +{ + + if ((ptr = realloc(ptr, size)) == NULL) + enomem(); + return (ptr); +} + +/* + * enomem -- + * die when out of memory. + */ +static void +enomem(void) +{ + err(2, NULL); +} + +/* + * enunlink -- + * Remove a file carefully, avoiding directories. + */ +int +eunlink(const char *file) +{ + struct stat st; + + if (lstat(file, &st) == -1) + return (-1); + + if (S_ISDIR(st.st_mode)) { + errno = EISDIR; + return (-1); + } + return (unlink(file)); +} + +/* + * Convert a flag word to a printable thing and print it + */ +void +print_flags(FILE *fp, const struct flag2str *tab, u_int flags, int par) +{ + int first = 1; + + if (par) + fprintf(fp, "("); + while (tab->str != NULL) { + if (flags & tab->flag) { + if (!first) + fprintf(fp, par ? "|" : " "); + first = 0; + fprintf(fp, "%s", tab->str); + } + tab++; + } + if (par) + fprintf(fp, ")"); +} |