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