Annotation of src/usr.bin/m4/misc.c, Revision 1.28
1.28 ! espie 1: /* $OpenBSD: misc.c,v 1.27 2002/04/26 16:15:16 espie Exp $ */
1.1 deraadt 2: /* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */
3:
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
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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:
40: #ifndef lint
41: #if 0
42: static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93";
43: #else
1.28 ! espie 44: static char rcsid[] = "$OpenBSD: misc.c,v 1.27 2002/04/26 16:15:16 espie Exp $";
1.1 deraadt 45: #endif
46: #endif /* not lint */
47:
48: #include <sys/types.h>
49: #include <errno.h>
50: #include <unistd.h>
51: #include <stdio.h>
52: #include <stdlib.h>
1.7 espie 53: #include <stddef.h>
1.1 deraadt 54: #include <string.h>
1.7 espie 55: #include <err.h>
1.1 deraadt 56: #include "mdef.h"
57: #include "stdd.h"
58: #include "extern.h"
59: #include "pathnames.h"
60:
1.9 espie 61:
62: char *ep; /* first free char in strspace */
63: static char *strspace; /* string space for evaluation */
1.24 espie 64: char *endest; /* end of string space */
1.9 espie 65: static size_t strsize = STRSPMAX;
66: static size_t bufsize = BUFSIZE;
67:
1.17 espie 68: char *buf; /* push-back buffer */
69: char *bufbase; /* the base for current ilevel */
70: char *bbase[MAXINP]; /* the base for each ilevel */
71: char *bp; /* first available character */
1.24 espie 72: char *endpbb; /* end of push-back buffer */
1.9 espie 73:
74:
1.1 deraadt 75: /*
76: * find the index of second str in the first str.
77: */
1.7 espie 78: ptrdiff_t
1.27 espie 79: indx(const char *s1, const char *s2)
1.1 deraadt 80: {
1.12 espie 81: char *t;
1.7 espie 82:
1.12 espie 83: t = strstr(s1, s2);
84: if (t == NULL)
85: return (-1);
1.7 espie 86: else
1.12 espie 87: return (t - s1);
1.1 deraadt 88: }
89: /*
90: * putback - push character back onto input
91: */
92: void
1.27 espie 93: putback(int c)
1.1 deraadt 94: {
1.17 espie 95: if (c == EOF)
96: return;
1.9 espie 97: if (bp >= endpbb)
98: enlarge_bufspace();
99: *bp++ = c;
1.1 deraadt 100: }
101:
102: /*
103: * pbstr - push string back onto input
104: * putback is replicated to improve
105: * performance.
106: */
107: void
1.27 espie 108: pbstr(const char *s)
1.1 deraadt 109: {
1.9 espie 110: size_t n;
1.1 deraadt 111:
1.9 espie 112: n = strlen(s);
1.12 espie 113: while (endpbb - bp <= n)
1.9 espie 114: enlarge_bufspace();
115: while (n > 0)
116: *bp++ = s[--n];
1.1 deraadt 117: }
118:
119: /*
120: * pbnum - convert number to string, push back on input.
121: */
122: void
1.27 espie 123: pbnum(int n)
1.1 deraadt 124: {
1.12 espie 125: int num;
1.1 deraadt 126:
127: num = (n < 0) ? -n : n;
128: do {
129: putback(num % 10 + '0');
130: }
131: while ((num /= 10) > 0);
132:
133: if (n < 0)
134: putback('-');
135: }
136:
1.18 espie 137: /*
138: * pbunsigned - convert unsigned long to string, push back on input.
139: */
140: void
1.27 espie 141: pbunsigned(unsigned long n)
1.18 espie 142: {
143: do {
144: putback(n % 10 + '0');
145: }
146: while ((n /= 10) > 0);
147: }
1.9 espie 148:
149: void
150: initspaces()
151: {
152: int i;
153:
154: strspace = xalloc(strsize+1);
155: ep = strspace;
156: endest = strspace+strsize;
1.17 espie 157: buf = (char *)xalloc(bufsize);
1.9 espie 158: bufbase = buf;
159: bp = buf;
160: endpbb = buf + bufsize;
161: for (i = 0; i < MAXINP; i++)
162: bbase[i] = buf;
163: }
164:
1.24 espie 165: void
1.17 espie 166: enlarge_strspace()
1.9 espie 167: {
168: char *newstrspace;
1.19 espie 169: int i;
1.9 espie 170:
171: strsize *= 2;
172: newstrspace = malloc(strsize + 1);
173: if (!newstrspace)
174: errx(1, "string space overflow");
175: memcpy(newstrspace, strspace, strsize/2);
1.19 espie 176: for (i = 0; i <= sp; i++)
177: if (sstack[i])
178: mstack[i].sstr = (mstack[i].sstr - strspace)
179: + newstrspace;
1.9 espie 180: ep = (ep-strspace) + newstrspace;
1.19 espie 181: free(strspace);
1.9 espie 182: strspace = newstrspace;
183: endest = strspace + strsize;
184: }
185:
1.24 espie 186: void
1.17 espie 187: enlarge_bufspace()
1.9 espie 188: {
1.17 espie 189: char *newbuf;
1.9 espie 190: int i;
191:
192: bufsize *= 2;
1.17 espie 193: newbuf = realloc(buf, bufsize);
1.9 espie 194: if (!newbuf)
195: errx(1, "too many characters pushed back");
196: for (i = 0; i < MAXINP; i++)
197: bbase[i] = (bbase[i]-buf)+newbuf;
198: bp = (bp-buf)+newbuf;
199: bufbase = (bufbase-buf)+newbuf;
200: buf = newbuf;
1.10 espie 201: endpbb = buf+bufsize;
1.9 espie 202: }
203:
1.1 deraadt 204: /*
205: * chrsave - put single char on string space
206: */
207: void
1.27 espie 208: chrsave(int c)
1.1 deraadt 209: {
1.9 espie 210: if (ep >= endest)
211: enlarge_strspace();
212: *ep++ = c;
1.1 deraadt 213: }
214:
215: /*
216: * read in a diversion file, and dispose it.
217: */
218: void
1.27 espie 219: getdiv(int n)
1.1 deraadt 220: {
1.12 espie 221: int c;
1.1 deraadt 222:
223: if (active == outfile[n])
1.7 espie 224: errx(1, "undivert: diversion still active");
1.8 espie 225: rewind(outfile[n]);
226: while ((c = getc(outfile[n])) != EOF)
227: putc(c, active);
1.1 deraadt 228: (void) fclose(outfile[n]);
1.13 espie 229: outfile[n] = NULL;
1.1 deraadt 230: }
231:
232: void
1.27 espie 233: onintr(int signo)
1.1 deraadt 234: {
1.21 espie 235: #define intrmessage "m4: interrupted.\n"
1.26 deraadt 236: write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1);
1.21 espie 237: _exit(1);
1.1 deraadt 238: }
239:
240: /*
241: * killdiv - get rid of the diversion files
242: */
243: void
244: killdiv()
245: {
1.12 espie 246: int n;
1.1 deraadt 247:
1.20 espie 248: for (n = 0; n < maxout; n++)
1.1 deraadt 249: if (outfile[n] != NULL) {
250: (void) fclose(outfile[n]);
251: }
1.20 espie 252: }
253:
254: /*
255: * resizedivs: allocate more diversion files */
256: void
1.27 espie 257: resizedivs(int n)
1.20 espie 258: {
259: int i;
260:
261: outfile = (FILE **)realloc(outfile, sizeof(FILE *) * n);
262: if (outfile == NULL)
263: errx(1, "too many diverts %d", n);
264: for (i = maxout; i < n; i++)
265: outfile[i] = NULL;
266: maxout = n;
1.1 deraadt 267: }
268:
1.18 espie 269: void *
1.27 espie 270: xalloc(size_t n)
1.1 deraadt 271: {
1.12 espie 272: char *p = malloc(n);
1.1 deraadt 273:
274: if (p == NULL)
1.7 espie 275: err(1, "malloc");
1.1 deraadt 276: return p;
277: }
278:
279: char *
1.27 espie 280: xstrdup(const char *s)
1.1 deraadt 281: {
1.12 espie 282: char *p = strdup(s);
1.1 deraadt 283: if (p == NULL)
1.7 espie 284: err(1, "strdup");
1.1 deraadt 285: return p;
286: }
287:
288: void
289: usage()
290: {
1.28 ! espie 291: fprintf(stderr, "usage: m4 [-gs] [-d flags] [-t macro] [-o file] [-Dname[=val]] [-Uname] [-I dirname...]\n");
1.1 deraadt 292: exit(1);
293: }
294:
1.15 espie 295: int
1.27 espie 296: obtain_char(struct input_file *f)
1.15 espie 297: {
1.17 espie 298: if (f->c == EOF)
299: return EOF;
300: else if (f->c == '\n')
1.15 espie 301: f->lineno++;
302:
303: f->c = fgetc(f->file);
304: return f->c;
305: }
306:
307: void
1.27 espie 308: set_input(struct input_file *f, FILE *real, const char *name)
1.15 espie 309: {
310: f->file = real;
311: f->lineno = 1;
312: f->c = 0;
313: f->name = xstrdup(name);
1.28 ! espie 314: emit_synchline();
! 315: }
! 316:
! 317: void
! 318: do_emit_synchline()
! 319: {
! 320: fprintf(active, "#line %lu \"%s\"\n",
! 321: infile[ilevel].lineno, infile[ilevel].name);
! 322: infile[ilevel].synch_lineno = infile[ilevel].lineno;
1.15 espie 323: }
324:
325: void
1.27 espie 326: release_input(struct input_file *f)
1.15 espie 327: {
328: if (f->file != stdin)
329: fclose(f->file);
1.17 espie 330: f->c = EOF;
1.16 espie 331: /*
332: * XXX can't free filename, as there might still be
333: * error information pointing to it.
334: */
1.18 espie 335: }
336:
337: void
1.27 espie 338: doprintlineno(struct input_file *f)
1.18 espie 339: {
340: pbunsigned(f->lineno);
341: }
342:
343: void
1.27 espie 344: doprintfilename(struct input_file *f)
1.18 espie 345: {
1.25 espie 346: pbstr(rquote);
1.18 espie 347: pbstr(f->name);
1.25 espie 348: pbstr(lquote);
1.22 espie 349: }
350:
351: /*
352: * buffer_mark/dump_buffer: allows one to save a mark in a buffer,
353: * and later dump everything that was added since then to a file.
354: */
355: size_t
356: buffer_mark()
357: {
358: return bp - buf;
359: }
360:
361:
362: void
1.27 espie 363: dump_buffer(FILE *f, size_t m)
1.22 espie 364: {
365: char *s;
366:
1.23 espie 367: for (s = bp; s-buf > m;)
1.22 espie 368: fputc(*--s, f);
1.15 espie 369: }