1 /* $NetBSD: misc.c,v 1.7 1997/10/19 04:40:03 lukem 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 #include <sys/cdefs.h> 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93"; 43 #else 44 __RCSID("$NetBSD: misc.c,v 1.7 1997/10/19 04:40:03 lukem Exp $"); 45 #endif 46 #endif /* not lint */ 47 48 #include <sys/types.h> 49 #include <err.h> 50 #include <errno.h> 51 #include <unistd.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include "mdef.h" 56 #include "stdd.h" 57 #include "extern.h" 58 #include "pathnames.h" 59 60 /* 61 * find the index of second str in the first str. 62 */ 63 int 64 indx(s1, s2) 65 char *s1; 66 char *s2; 67 { 68 char *t; 69 70 t = strstr(s1, s2); 71 if (t == NULL) 72 return (-1); 73 return (t - s1); 74 } 75 76 /* 77 * putback - push character back onto input 78 */ 79 void 80 putback(c) 81 char c; 82 { 83 if (bp < endpbb) 84 *bp++ = c; 85 else 86 errx(1, "too many characters pushed back"); 87 } 88 89 /* 90 * pbstr - push string back onto input 91 * putback is replicated to improve 92 * performance. 93 */ 94 void 95 pbstr(s) 96 char *s; 97 { 98 char *es; 99 char *zp; 100 101 es = s; 102 zp = bp; 103 104 while (*es) 105 es++; 106 es--; 107 while (es >= s) 108 if (zp < endpbb) 109 *zp++ = *es--; 110 if ((bp = zp) == endpbb) 111 errx(1, "too many characters pushed back"); 112 } 113 114 /* 115 * pbnum - convert number to string, push back on input. 116 */ 117 void 118 pbnum(n) 119 int n; 120 { 121 int num; 122 123 num = (n < 0) ? -n : n; 124 do { 125 putback(num % 10 + '0'); 126 } 127 while ((num /= 10) > 0); 128 129 if (n < 0) 130 putback('-'); 131 } 132 133 /* 134 * chrsave - put single char on string space 135 */ 136 void 137 chrsave(c) 138 char c; 139 { 140 if (ep < endest) 141 *ep++ = c; 142 else 143 errx(1, "string space overflow"); 144 } 145 146 /* 147 * read in a diversion file, and dispose it. 148 */ 149 void 150 getdiv(n) 151 int n; 152 { 153 int c; 154 FILE *dfil; 155 156 if (active == outfile[n]) 157 errx(1, "undivert: diversion still active"); 158 (void) fclose(outfile[n]); 159 outfile[n] = NULL; 160 m4temp[UNIQUE] = n + '0'; 161 if ((dfil = fopen(m4temp, "r")) == NULL) 162 err(1, "%s: cannot undivert", m4temp); 163 else 164 while ((c = getc(dfil)) != EOF) 165 putc(c, active); 166 (void) fclose(dfil); 167 168 #ifdef vms 169 if (remove(m4temp)) 170 #else 171 if (unlink(m4temp) == -1) 172 #endif 173 err(1, "%s: cannot unlink", m4temp); 174 } 175 176 void 177 onintr(signo) 178 int signo; 179 { 180 errx(1, "interrupted"); 181 } 182 183 /* 184 * killdiv - get rid of the diversion files 185 */ 186 void 187 killdiv() 188 { 189 int n; 190 191 for (n = 0; n < MAXOUT; n++) 192 if (outfile[n] != NULL) { 193 (void) fclose(outfile[n]); 194 m4temp[UNIQUE] = n + '0'; 195 #ifdef vms 196 (void) remove(m4temp); 197 #else 198 (void) unlink(m4temp); 199 #endif 200 } 201 } 202 203 char * 204 xalloc(n) 205 unsigned long n; 206 { 207 char *p = malloc(n); 208 209 if (p == NULL) 210 err(1, "malloc"); 211 return p; 212 } 213 214 char * 215 xstrdup(s) 216 const char *s; 217 { 218 char *p = strdup(s); 219 if (p == NULL) 220 err(1, "strdup"); 221 return p; 222 } 223 224 char * 225 basename(s) 226 char *s; 227 { 228 char *p; 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