1 /* $OpenBSD: util.c,v 1.15 2014/05/29 16:38:23 tedu 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 <stdarg.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 52 #include "config.h" 53 54 static void nomem(void); 55 static void vxerror(const char *, int, const char *, va_list); 56 57 /* 58 * Malloc, with abort on error. 59 */ 60 void * 61 emalloc(size_t size) 62 { 63 void *p; 64 65 if ((p = calloc(1, size)) == NULL) 66 nomem(); 67 return (p); 68 } 69 70 /* 71 * Reallocarray, with abort on error. 72 */ 73 void * 74 ereallocarray(void *p, size_t sz1, size_t sz2) 75 { 76 77 if ((p = reallocarray(p, sz1, sz2)) == NULL) 78 nomem(); 79 return (p); 80 } 81 82 /* 83 * Calloc, with abort on error. 84 */ 85 void * 86 ecalloc(size_t sz1, size_t sz2) 87 { 88 void *p; 89 90 if ((p = calloc(sz1, sz2)) == NULL) 91 nomem(); 92 return (p); 93 } 94 95 static void 96 nomem(void) 97 { 98 99 (void)fprintf(stderr, "config: out of memory\n"); 100 exit(1); 101 } 102 103 /* 104 * Prepend the source path to a file name. 105 */ 106 char * 107 sourcepath(const char *file) 108 { 109 char *cp; 110 int len = strlen(srcdir) + 1 + strlen(file) + 1; 111 112 cp = emalloc(len); 113 (void)snprintf(cp, len, "%s/%s", srcdir, file); 114 return (cp); 115 } 116 117 static struct nvlist *nvhead; 118 119 struct nvlist * 120 newnv(const char *name, const char *str, void *ptr, int i, struct nvlist *next) 121 { 122 struct nvlist *nv; 123 124 if ((nv = nvhead) == NULL) 125 nv = emalloc(sizeof(*nv)); 126 else 127 nvhead = nv->nv_next; 128 nv->nv_next = next; 129 nv->nv_name = (char *)name; 130 if (ptr == NULL) 131 nv->nv_str = str; 132 else { 133 if (str != NULL) 134 panic("newnv"); 135 nv->nv_ptr = ptr; 136 } 137 nv->nv_int = i; 138 return (nv); 139 } 140 141 /* 142 * Free an nvlist structure (just one). 143 */ 144 void 145 nvfree(struct nvlist *nv) 146 { 147 148 nv->nv_next = nvhead; 149 nvhead = nv; 150 } 151 152 /* 153 * Free an nvlist (the whole list). 154 */ 155 void 156 nvfreel(struct nvlist *nv) 157 { 158 struct nvlist *next; 159 160 for (; nv != NULL; nv = next) { 161 next = nv->nv_next; 162 nv->nv_next = nvhead; 163 nvhead = nv; 164 } 165 } 166 167 /* 168 * External (config file) error. Complain, using current file 169 * and line number. 170 */ 171 void 172 error(const char *fmt, ...) 173 { 174 va_list ap; 175 extern const char *yyfile; 176 177 va_start(ap, fmt); 178 vxerror(yyfile, currentline(), fmt, ap); 179 va_end(ap); 180 } 181 182 /* 183 * Delayed config file error (i.e., something was wrong but we could not 184 * find out about it until later). 185 */ 186 void 187 xerror(const char *file, int line, const char *fmt, ...) 188 { 189 va_list ap; 190 191 va_start(ap, fmt); 192 vxerror(file, line, fmt, ap); 193 va_end(ap); 194 } 195 196 /* 197 * Internal form of error() and xerror(). 198 */ 199 static void 200 vxerror(const char *file, int line, const char *fmt, va_list ap) 201 { 202 203 (void)fprintf(stderr, "%s:%d: ", file, line); 204 (void)vfprintf(stderr, fmt, ap); 205 (void)putc('\n', stderr); 206 errors++; 207 } 208 209 /* 210 * Internal error, abort. 211 */ 212 __dead void 213 panic(const char *fmt, ...) 214 { 215 va_list ap; 216 217 va_start(ap, fmt); 218 (void)fprintf(stderr, "config: panic: "); 219 (void)vfprintf(stderr, fmt, ap); 220 (void)putc('\n', stderr); 221 va_end(ap); 222 exit(2); 223 } 224