misc.c (94957) | misc.c (95060) |
---|---|
1/* $OpenBSD: misc.c,v 1.26 2001/11/16 23:50:40 deraadt Exp $ */ 2/* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */ 3 |
|
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 --- 20 unchanged lines hidden (view full) --- 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 | 4/* 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Ozan Yigit at York University. 10 * 11 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 39 |
37#ifndef lint 38#if 0 39static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93"; 40#endif 41static const char rcsid[] = 42 "$FreeBSD: head/usr.bin/m4/misc.c 94957 2002-04-17 17:26:32Z jmallett $"; 43#endif /* not lint */ | 40#include <sys/cdefs.h> 41__SCCSID("@(#)misc.c 8.1 (Berkeley) 6/6/93"); 42__RCSID_SOURCE("$OpenBSD: misc.c,v 1.26 2001/11/16 23:50:40 deraadt Exp $"); 43__FBSDID("$FreeBSD: head/usr.bin/m4/misc.c 95060 2002-04-19 17:26:21Z jmallett $"); |
44 45#include <sys/types.h> | 44 45#include <sys/types.h> |
46#include | 46#include <errno.h> 47#include <unistd.h> |
47#include <stdio.h> 48#include <stdlib.h> | 48#include <stdio.h> 49#include <stdlib.h> |
50#include <stddef.h> |
|
49#include <string.h> | 51#include <string.h> |
50#include <unistd.h> | 52#include <err.h> |
51#include "mdef.h" 52#include "stdd.h" 53#include "extern.h" 54#include "pathnames.h" 55 | 53#include "mdef.h" 54#include "stdd.h" 55#include "extern.h" 56#include "pathnames.h" 57 |
58 59char *ep; /* first free char in strspace */ 60static char *strspace; /* string space for evaluation */ 61char *endest; /* end of string space */ 62static size_t strsize = STRSPMAX; 63static size_t bufsize = BUFSIZE; 64 65char *buf; /* push-back buffer */ 66char *bufbase; /* the base for current ilevel */ 67char *bbase[MAXINP]; /* the base for each ilevel */ 68char *bp; /* first available character */ 69char *endpbb; /* end of push-back buffer */ 70 71 |
|
56/* 57 * find the index of second str in the first str. 58 */ | 72/* 73 * find the index of second str in the first str. 74 */ |
59int | 75ptrdiff_t |
60indx(s1, s2) | 76indx(s1, s2) |
61char *s1; 62char *s2; | 77 const char *s1; 78 const char *s2; |
63{ | 79{ |
64 register char *t; 65 register char *p; 66 register char *m; | 80 char *t; |
67 | 81 |
68 for (p = s1; *p; p++) { 69 for (t = p, m = s2; *m && *m == *t; m++, t++); 70 if (!*m) 71 return (p - s1); 72 } 73 return (-1); | 82 t = strstr(s1, s2); 83 if (t == NULL) 84 return (-1); 85 else 86 return (t - s1); |
74} 75/* 76 * putback - push character back onto input 77 */ 78void 79putback(c) | 87} 88/* 89 * putback - push character back onto input 90 */ 91void 92putback(c) |
80int c; | 93 int c; |
81{ 82 if (c == EOF) | 94{ 95 if (c == EOF) |
83 c = 0; 84 else if (c == 0) | |
85 return; | 96 return; |
86 if (bp < endpbb) 87 *bp++ = c; 88 else 89 errx(1, "too many characters pushed back"); | 97 if (bp >= endpbb) 98 enlarge_bufspace(); 99 *bp++ = c; |
90} 91 92/* 93 * pbstr - push string back onto input 94 * putback is replicated to improve 95 * performance. 96 */ 97void 98pbstr(s) | 100} 101 102/* 103 * pbstr - push string back onto input 104 * putback is replicated to improve 105 * performance. 106 */ 107void 108pbstr(s) |
99register unsigned char *s; | 109 const char *s; |
100{ | 110{ |
101 register unsigned char *es; 102 register unsigned char *zp; | 111 size_t n; |
103 | 112 |
104 es = s; 105 zp = bp; 106 107 while (*es) 108 es++; 109 es--; 110 while (es >= s) 111 if (zp < endpbb) 112 *zp++ = *es--; 113 if ((bp = zp) == endpbb) 114 errx(1, "too many characters pushed back"); | 113 n = strlen(s); 114 while (endpbb - bp <= n) 115 enlarge_bufspace(); 116 while (n > 0) 117 *bp++ = s[--n]; |
115} 116 117/* 118 * pbnum - convert number to string, push back on input. 119 */ 120void 121pbnum(n) | 118} 119 120/* 121 * pbnum - convert number to string, push back on input. 122 */ 123void 124pbnum(n) |
122int n; | 125 int n; |
123{ | 126{ |
124 register int num; | 127 int num; |
125 126 num = (n < 0) ? -n : n; 127 do { 128 putback(num % 10 + '0'); 129 } 130 while ((num /= 10) > 0); 131 132 if (n < 0) 133 putback('-'); 134} 135 136/* | 128 129 num = (n < 0) ? -n : n; 130 do { 131 putback(num % 10 + '0'); 132 } 133 while ((num /= 10) > 0); 134 135 if (n < 0) 136 putback('-'); 137} 138 139/* |
140 * pbunsigned - convert unsigned long to string, push back on input. 141 */ 142void 143pbunsigned(n) 144 unsigned long n; 145{ 146 do { 147 putback(n % 10 + '0'); 148 } 149 while ((n /= 10) > 0); 150} 151 152void 153initspaces() 154{ 155 int i; 156 157 strspace = xalloc(strsize+1); 158 ep = strspace; 159 endest = strspace+strsize; 160 buf = (char *)xalloc(bufsize); 161 bufbase = buf; 162 bp = buf; 163 endpbb = buf + bufsize; 164 for (i = 0; i < MAXINP; i++) 165 bbase[i] = buf; 166} 167 168void 169enlarge_strspace() 170{ 171 char *newstrspace; 172 int i; 173 174 strsize *= 2; 175 newstrspace = malloc(strsize + 1); 176 if (!newstrspace) 177 errx(1, "string space overflow"); 178 memcpy(newstrspace, strspace, strsize/2); 179 for (i = 0; i <= sp; i++) 180 if (sstack[i]) 181 mstack[i].sstr = (mstack[i].sstr - strspace) 182 + newstrspace; 183 ep = (ep-strspace) + newstrspace; 184 free(strspace); 185 strspace = newstrspace; 186 endest = strspace + strsize; 187} 188 189void 190enlarge_bufspace() 191{ 192 char *newbuf; 193 int i; 194 195 bufsize *= 2; 196 newbuf = realloc(buf, bufsize); 197 if (!newbuf) 198 errx(1, "too many characters pushed back"); 199 for (i = 0; i < MAXINP; i++) 200 bbase[i] = (bbase[i]-buf)+newbuf; 201 bp = (bp-buf)+newbuf; 202 bufbase = (bufbase-buf)+newbuf; 203 buf = newbuf; 204 endpbb = buf+bufsize; 205} 206 207/* |
|
137 * chrsave - put single char on string space 138 */ 139void 140chrsave(c) | 208 * chrsave - put single char on string space 209 */ 210void 211chrsave(c) |
141char c; | 212 int c; |
142{ | 213{ |
143 if (ep < endest) 144 *ep++ = c; 145 else 146 errx(1, "string space overflow"); | 214 if (ep >= endest) 215 enlarge_strspace(); 216 *ep++ = c; |
147} 148 149/* 150 * read in a diversion file, and dispose it. 151 */ 152void 153getdiv(n) | 217} 218 219/* 220 * read in a diversion file, and dispose it. 221 */ 222void 223getdiv(n) |
154int n; | 224 int n; |
155{ | 225{ |
156 register int c; 157 register FILE *dfil; | 226 int c; |
158 159 if (active == outfile[n]) 160 errx(1, "undivert: diversion still active"); | 227 228 if (active == outfile[n]) 229 errx(1, "undivert: diversion still active"); |
230 rewind(outfile[n]); 231 while ((c = getc(outfile[n])) != EOF) 232 putc(c, active); |
|
161 (void) fclose(outfile[n]); 162 outfile[n] = NULL; | 233 (void) fclose(outfile[n]); 234 outfile[n] = NULL; |
163 m4temp[UNIQUE] = n + '0'; 164 if ((dfil = fopen(m4temp, "r")) == NULL) 165 errx(1, "%s: cannot undivert", m4temp); 166 else 167 while ((c = getc(dfil)) != EOF) 168 putc(c, active); 169 (void) fclose(dfil); 170 171#ifdef vms 172 if (remove(m4temp)) 173#else 174 if (unlink(m4temp) == -1) 175#endif 176 errx(1, "%s: cannot unlink", m4temp); | |
177} 178 179void 180onintr(signo) 181 int signo; 182{ | 235} 236 237void 238onintr(signo) 239 int signo; 240{ |
183 errx(1, "interrupted"); | 241#define intrmessage "m4: interrupted.\n" 242 write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1); 243 _exit(1); |
184} 185 186/* 187 * killdiv - get rid of the diversion files 188 */ 189void 190killdiv() 191{ | 244} 245 246/* 247 * killdiv - get rid of the diversion files 248 */ 249void 250killdiv() 251{ |
192 register int n; | 252 int n; |
193 | 253 |
194 for (n = 0; n < MAXOUT; n++) | 254 for (n = 0; n < maxout; n++) |
195 if (outfile[n] != NULL) { 196 (void) fclose(outfile[n]); | 255 if (outfile[n] != NULL) { 256 (void) fclose(outfile[n]); |
197 m4temp[UNIQUE] = n + '0'; 198#ifdef vms 199 (void) remove(m4temp); 200#else 201 (void) unlink(m4temp); 202#endif | |
203 } 204} 205 | 257 } 258} 259 |
260/* 261 * resizedivs: allocate more diversion files */ |
|
206void | 262void |
207cleanup(n) 208int n; | 263resizedivs(n) 264 int n; |
209{ | 265{ |
210 if (outfile[0] != NULL) { 211 (void) fclose(outfile[0]); 212 outfile[0] = NULL; 213 m4temp[UNIQUE] = '0'; 214 (void) remove(m4temp); 215 } 216 (void) remove(m4dir); | 266 int i; 267 268 outfile = (FILE **)realloc(outfile, sizeof(FILE *) * n); 269 if (outfile == NULL) 270 errx(1, "too many diverts %d", n); 271 for (i = maxout; i < n; i++) 272 outfile[i] = NULL; 273 maxout = n; |
217} 218 | 274} 275 |
276void * 277xalloc(n) 278 size_t n; 279{ 280 char *p = malloc(n); 281 282 if (p == NULL) 283 err(1, "malloc"); 284 return p; 285} 286 287char * 288xstrdup(s) 289 const char *s; 290{ 291 char *p = strdup(s); 292 if (p == NULL) 293 err(1, "strdup"); 294 return p; 295} 296 |
|
219void 220usage() 221{ 222 fprintf(stderr, | 297void 298usage() 299{ 300 fprintf(stderr, |
223"usage: m4 [-s] [-D name[=val]]... [-U name]... file...\n"); | 301"usage: m4 [-d flags] [-t name] [-gs] [-D name[=value]]...\n" 302" [-U name]... [-I dirname]... file...\n"); |
224 exit(1); 225} | 303 exit(1); 304} |
305 306int 307obtain_char(f) 308 struct input_file *f; 309{ 310 if (f->c == EOF) 311 return EOF; 312 else if (f->c == '\n') 313 f->lineno++; 314 315 f->c = fgetc(f->file); 316 return f->c; 317} 318 319void 320set_input(f, real, name) 321 struct input_file *f; 322 FILE *real; 323 const char *name; 324{ 325 f->file = real; 326 f->lineno = 1; 327 f->c = 0; 328 f->name = xstrdup(name); 329} 330 331void 332release_input(f) 333 struct input_file *f; 334{ 335 if (f->file != stdin) 336 fclose(f->file); 337 f->c = EOF; 338 /* 339 * XXX can't free filename, as there might still be 340 * error information pointing to it. 341 */ 342} 343 344void 345doprintlineno(f) 346 struct input_file *f; 347{ 348 pbunsigned(f->lineno); 349} 350 351void 352doprintfilename(f) 353 struct input_file *f; 354{ 355 pbstr(rquote); 356 pbstr(f->name); 357 pbstr(lquote); 358} 359 360/* 361 * buffer_mark/dump_buffer: allows one to save a mark in a buffer, 362 * and later dump everything that was added since then to a file. 363 */ 364size_t 365buffer_mark() 366{ 367 return bp - buf; 368} 369 370 371void 372dump_buffer(f, m) 373 FILE *f; 374 size_t m; 375{ 376 char *s; 377 378 for (s = bp; s-buf > m;) 379 fputc(*--s, f); 380} |
|