1 /* $OpenBSD: util.c,v 1.18 2016/10/16 09:35:40 tb Exp $ */ 2 /* $NetBSD: util.c,v 1.5 1996/08/31 20:58:29 mycroft Exp $ */ 3 4 /* 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This software was developed by the Computer Systems Engineering group 9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 * contributed to Berkeley. 11 * 12 * All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by the University of 15 * California, Lawrence Berkeley Laboratories. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * from: @(#)util.c 8.1 (Berkeley) 6/6/93 42 */ 43 44 #include <sys/types.h> 45 46 #include <ctype.h> 47 #include <err.h> 48 #include <stdarg.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 53 #include "config.h" 54 55 static void vxerror(const char *, int, const char *, va_list) 56 __attribute__((__format__ (printf, 3, 0))); 57 58 /* 59 * Malloc, with abort on error. 60 */ 61 void * 62 emalloc(size_t size) 63 { 64 void *p; 65 66 if ((p = calloc(1, size)) == NULL) 67 err(1, NULL); 68 return p; 69 } 70 71 /* 72 * Reallocarray, with abort on error. 73 */ 74 void * 75 ereallocarray(void *p, size_t sz1, size_t sz2) 76 { 77 78 if ((p = reallocarray(p, sz1, sz2)) == NULL) 79 err(1, NULL); 80 return p; 81 } 82 83 /* 84 * Calloc, with abort on error. 85 */ 86 void * 87 ecalloc(size_t sz1, size_t sz2) 88 { 89 void *p; 90 91 if ((p = calloc(sz1, sz2)) == NULL) 92 err(1, NULL); 93 return p; 94 } 95 96 /* 97 * Prepend the source path to a file name. 98 */ 99 char * 100 sourcepath(const char *file) 101 { 102 char *cp; 103 104 if (asprintf(&cp, "%s/%s", srcdir, file) == -1) 105 err(1, NULL); 106 107 return cp; 108 } 109 110 static struct nvlist *nvhead; 111 112 struct nvlist * 113 newnv(const char *name, const char *str, void *ptr, int i, struct nvlist *next) 114 { 115 struct nvlist *nv; 116 117 if ((nv = nvhead) == NULL) 118 nv = emalloc(sizeof(*nv)); 119 else 120 nvhead = nv->nv_next; 121 nv->nv_next = next; 122 nv->nv_name = (char *)name; 123 if (ptr == NULL) 124 nv->nv_str = str; 125 else { 126 if (str != NULL) 127 panic("newnv"); 128 nv->nv_ptr = ptr; 129 } 130 nv->nv_int = i; 131 return nv; 132 } 133 134 /* 135 * Free an nvlist structure (just one). 136 */ 137 void 138 nvfree(struct nvlist *nv) 139 { 140 141 nv->nv_next = nvhead; 142 nvhead = nv; 143 } 144 145 /* 146 * Free an nvlist (the whole list). 147 */ 148 void 149 nvfreel(struct nvlist *nv) 150 { 151 struct nvlist *next; 152 153 for (; nv != NULL; nv = next) { 154 next = nv->nv_next; 155 nv->nv_next = nvhead; 156 nvhead = nv; 157 } 158 } 159 160 /* 161 * External (config file) error. Complain, using current file 162 * and line number. 163 */ 164 void 165 error(const char *fmt, ...) 166 { 167 va_list ap; 168 extern const char *yyfile; 169 170 va_start(ap, fmt); 171 vxerror(yyfile, currentline(), fmt, ap); 172 va_end(ap); 173 } 174 175 /* 176 * Delayed config file error (i.e., something was wrong but we could not 177 * find out about it until later). 178 */ 179 void 180 xerror(const char *file, int line, const char *fmt, ...) 181 { 182 va_list ap; 183 184 va_start(ap, fmt); 185 vxerror(file, line, fmt, ap); 186 va_end(ap); 187 } 188 189 /* 190 * Internal form of error() and xerror(). 191 */ 192 static void 193 vxerror(const char *file, int line, const char *fmt, va_list ap) 194 { 195 196 (void)fprintf(stderr, "%s:%d: ", file, line); 197 (void)vfprintf(stderr, fmt, ap); 198 (void)putc('\n', stderr); 199 errors++; 200 } 201 202 /* 203 * Internal error, abort. 204 */ 205 __dead void 206 panic(const char *fmt, ...) 207 { 208 va_list ap; 209 210 va_start(ap, fmt); 211 (void)fprintf(stderr, "config: panic: "); 212 (void)vfprintf(stderr, fmt, ap); 213 (void)putc('\n', stderr); 214 va_end(ap); 215 exit(2); 216 } 217