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