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 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)misc.c 5.6 (Berkeley) 02/26/91"; 13 #endif /* not lint */ 14 15 /* 16 * misc.c 17 * Facility: m4 macro processor 18 * by: oz 19 */ 20 21 #include <unistd.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include "mdef.h" 26 #include "extr.h" 27 #include "pathnames.h" 28 29 /* 30 * indx - find the index of second str in the 31 * first str. 32 */ 33 indx(s1, s2) 34 char *s1; 35 char *s2; 36 { 37 register char *t; 38 register char *p; 39 register char *m; 40 41 for (p = s1; *p; p++) { 42 for (t = p, m = s2; *m && *m == *t; m++, t++) 43 ; 44 if (!*m) 45 return(p - s1); 46 } 47 return (-1); 48 } 49 50 /* 51 * putback - push character back onto input 52 * 53 */ 54 putback (c) 55 char c; 56 { 57 if (bp < endpbb) 58 *bp++ = c; 59 else 60 error("m4: too many characters pushed back"); 61 } 62 63 /* 64 * pbstr - push string back onto input 65 * putback is replicated to improve 66 * performance. 67 * 68 */ 69 pbstr(s) 70 register char *s; 71 { 72 register char *es; 73 register char *zp; 74 75 es = s; 76 zp = bp; 77 78 while (*es) 79 es++; 80 es--; 81 while (es >= s) 82 if (zp < endpbb) 83 *zp++ = *es--; 84 if ((bp = zp) == endpbb) 85 error("m4: too many characters pushed back"); 86 } 87 88 /* 89 * pbnum - convert number to string, push back on input. 90 * 91 */ 92 pbnum (n) 93 int n; 94 { 95 register int num; 96 97 num = (n < 0) ? -n : n; 98 do { 99 putback(num % 10 + '0'); 100 } 101 while ((num /= 10) > 0); 102 103 if (n < 0) putback('-'); 104 } 105 106 /* 107 * chrsave - put single char on string space 108 * 109 */ 110 chrsave (c) 111 char c; 112 { 113 /*** if (sp < 0) 114 putc(c, active); 115 else ***/ if (ep < endest) 116 *ep++ = c; 117 else 118 error("m4: string space overflow"); 119 } 120 121 /* 122 * getdiv - read in a diversion file, and 123 * trash it. 124 */ 125 getdiv(ind) { 126 register int c; 127 register FILE *dfil; 128 129 if (active == outfile[ind]) 130 error("m4: undivert: diversion still active."); 131 (void) fclose(outfile[ind]); 132 outfile[ind] = NULL; 133 m4temp[UNIQUE] = ind + '0'; 134 if ((dfil = fopen(m4temp, "r")) == NULL) 135 error("m4: cannot undivert."); 136 else 137 while((c = getc(dfil)) != EOF) 138 putc(c, active); 139 (void) fclose(dfil); 140 141 if (unlink(m4temp) == -1) 142 error("m4: cannot unlink."); 143 } 144 145 /* 146 * Very fatal error. Close all files 147 * and die hard. 148 */ 149 error(s) 150 char *s; 151 { 152 killdiv(); 153 fprintf(stderr,"%s\n",s); 154 exit(1); 155 } 156 157 /* 158 * Interrupt handling 159 */ 160 static char *msg = "\ninterrupted."; 161 162 void 163 onintr() { 164 error(msg); 165 } 166 167 /* 168 * killdiv - get rid of the diversion files 169 * 170 */ 171 killdiv() { 172 register int n; 173 174 for (n = 0; n < MAXOUT; n++) 175 if (outfile[n] != NULL) { 176 (void) fclose (outfile[n]); 177 m4temp[UNIQUE] = n + '0'; 178 (void) unlink (m4temp); 179 } 180 } 181 182 usage() { 183 fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n"); 184 exit(1); 185 } 186