1 /* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Ozan Yigit at York University. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 #ifndef lint 40 #if 0 41 static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93"; 42 #else 43 static char rcsid[] = "$NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $"; 44 #endif 45 #endif /* not lint */ 46 47 #include <sys/types.h> 48 #include <errno.h> 49 #include <unistd.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include "mdef.h" 54 #include "stdd.h" 55 #include "extern.h" 56 #include "pathnames.h" 57 58 /* 59 * find the index of second str in the first str. 60 */ 61 int 62 indx(s1, s2) 63 char *s1; 64 char *s2; 65 { 66 register char *t; 67 register char *p; 68 register char *m; 69 70 for (p = s1; *p; p++) { 71 for (t = p, m = s2; *m && *m == *t; m++, t++); 72 if (!*m) 73 return (p - s1); 74 } 75 return (-1); 76 } 77 /* 78 * putback - push character back onto input 79 */ 80 void 81 putback(c) 82 char c; 83 { 84 if (bp < endpbb) 85 *bp++ = c; 86 else 87 oops("too many characters pushed back"); 88 } 89 90 /* 91 * pbstr - push string back onto input 92 * putback is replicated to improve 93 * performance. 94 */ 95 void 96 pbstr(s) 97 register char *s; 98 { 99 register char *es; 100 register char *zp; 101 102 es = s; 103 zp = bp; 104 105 while (*es) 106 es++; 107 es--; 108 while (es >= s) 109 if (zp < endpbb) 110 *zp++ = *es--; 111 if ((bp = zp) == endpbb) 112 oops("too many characters pushed back"); 113 } 114 115 /* 116 * pbnum - convert number to string, push back on input. 117 */ 118 void 119 pbnum(n) 120 int n; 121 { 122 register int num; 123 124 num = (n < 0) ? -n : n; 125 do { 126 putback(num % 10 + '0'); 127 } 128 while ((num /= 10) > 0); 129 130 if (n < 0) 131 putback('-'); 132 } 133 134 /* 135 * chrsave - put single char on string space 136 */ 137 void 138 chrsave(c) 139 char c; 140 { 141 if (ep < endest) 142 *ep++ = c; 143 else 144 oops("string space overflow"); 145 } 146 147 /* 148 * read in a diversion file, and dispose it. 149 */ 150 void 151 getdiv(n) 152 int n; 153 { 154 register int c; 155 register FILE *dfil; 156 157 if (active == outfile[n]) 158 oops("%s: diversion still active.", "undivert"); 159 (void) fclose(outfile[n]); 160 outfile[n] = NULL; 161 m4temp[UNIQUE] = n + '0'; 162 if ((dfil = fopen(m4temp, "r")) == NULL) 163 oops("%s: cannot undivert.", m4temp); 164 else 165 while ((c = getc(dfil)) != EOF) 166 putc(c, active); 167 (void) fclose(dfil); 168 169 #ifdef vms 170 if (remove(m4temp)) 171 #else 172 if (unlink(m4temp) == -1) 173 #endif 174 oops("%s: cannot unlink.", m4temp); 175 } 176 177 void 178 onintr(signo) 179 int signo; 180 { 181 oops("interrupted."); 182 } 183 184 /* 185 * killdiv - get rid of the diversion files 186 */ 187 void 188 killdiv() 189 { 190 register int n; 191 192 for (n = 0; n < MAXOUT; n++) 193 if (outfile[n] != NULL) { 194 (void) fclose(outfile[n]); 195 m4temp[UNIQUE] = n + '0'; 196 #ifdef vms 197 (void) remove(m4temp); 198 #else 199 (void) unlink(m4temp); 200 #endif 201 } 202 } 203 204 char * 205 xalloc(n) 206 unsigned long n; 207 { 208 register char *p = malloc(n); 209 210 if (p == NULL) 211 oops("malloc: %s", strerror(errno)); 212 return p; 213 } 214 215 char * 216 xstrdup(s) 217 const char *s; 218 { 219 register char *p = strdup(s); 220 if (p == NULL) 221 oops("strdup: %s", strerror(errno)); 222 return p; 223 } 224 225 char * 226 basename(s) 227 register char *s; 228 { 229 register char *p; 230 extern char *strrchr(); 231 232 if ((p = strrchr(s, '/')) == NULL) 233 return s; 234 235 return ++p; 236 } 237 238 void 239 usage() 240 { 241 fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n"); 242 exit(1); 243 } 244 245 #if __STDC__ 246 #include <stdarg.h> 247 #else 248 #include <varargs.h> 249 #endif 250 251 void 252 #if __STDC__ 253 oops(const char *fmt, ...) 254 #else 255 oops(fmt, va_alist) 256 char *fmt; 257 va_dcl 258 #endif 259 { 260 va_list ap; 261 #if __STDC__ 262 va_start(ap, fmt); 263 #else 264 va_start(ap); 265 #endif 266 (void)fprintf(stderr, "%s: ", progname); 267 (void)vfprintf(stderr, fmt, ap); 268 va_end(ap); 269 (void)fprintf(stderr, "\n"); 270 exit(1); 271 /* NOTREACHED */ 272 } 273