1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ozan Yigit. 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 5.6 (Berkeley) 2/26/91"; 39 #endif /* not lint */ 40 41 /* 42 * misc.c 43 * Facility: m4 macro processor 44 * by: oz 45 */ 46 47 #include <unistd.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include "mdef.h" 52 #include "extr.h" 53 #include "pathnames.h" 54 55 /* 56 * indx - find the index of second str in the 57 * first str. 58 */ 59 indx(s1, s2) 60 char *s1; 61 char *s2; 62 { 63 register char *t; 64 register char *p; 65 register char *m; 66 67 for (p = s1; *p; p++) { 68 for (t = p, m = s2; *m && *m == *t; m++, t++) 69 ; 70 if (!*m) 71 return(p - s1); 72 } 73 return (-1); 74 } 75 76 /* 77 * putback - push character back onto input 78 * 79 */ 80 putback (c) 81 char c; 82 { 83 if (bp < endpbb) 84 *bp++ = c; 85 else 86 error("m4: 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 */ 95 pbstr(s) 96 register char *s; 97 { 98 register char *es; 99 register 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 error("m4: too many characters pushed back"); 112 } 113 114 /* 115 * pbnum - convert number to string, push back on input. 116 * 117 */ 118 pbnum (n) 119 int n; 120 { 121 register 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) putback('-'); 130 } 131 132 /* 133 * chrsave - put single char on string space 134 * 135 */ 136 chrsave (c) 137 char c; 138 { 139 /*** if (sp < 0) 140 putc(c, active); 141 else ***/ if (ep < endest) 142 *ep++ = c; 143 else 144 error("m4: string space overflow"); 145 } 146 147 /* 148 * getdiv - read in a diversion file, and 149 * trash it. 150 */ 151 getdiv(ind) { 152 register int c; 153 register FILE *dfil; 154 155 if (active == outfile[ind]) 156 error("m4: undivert: diversion still active."); 157 (void) fclose(outfile[ind]); 158 outfile[ind] = NULL; 159 m4temp[UNIQUE] = ind + '0'; 160 if ((dfil = fopen(m4temp, "r")) == NULL) 161 error("m4: cannot undivert."); 162 else 163 while((c = getc(dfil)) != EOF) 164 putc(c, active); 165 (void) fclose(dfil); 166 167 if (unlink(m4temp) == -1) 168 error("m4: cannot unlink."); 169 } 170 171 /* 172 * Very fatal error. Close all files 173 * and die hard. 174 */ 175 error(s) 176 char *s; 177 { 178 killdiv(); 179 fprintf(stderr,"%s\n",s); 180 exit(1); 181 } 182 183 /* 184 * Interrupt handling 185 */ 186 static char *msg = "\ninterrupted."; 187 188 void 189 onintr() { 190 error(msg); 191 } 192 193 /* 194 * killdiv - get rid of the diversion files 195 * 196 */ 197 killdiv() { 198 register int n; 199 200 for (n = 0; n < MAXOUT; n++) 201 if (outfile[n] != NULL) { 202 (void) fclose (outfile[n]); 203 m4temp[UNIQUE] = n + '0'; 204 (void) unlink (m4temp); 205 } 206 } 207 208 usage() { 209 fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n"); 210 exit(1); 211 } 212