Annotation of src/usr.bin/m4/misc.c, Revision 1.25
1.25 ! espie 1: /* $OpenBSD: misc.c,v 1.24 2001/09/19 13:14:18 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.25 ! espie 44: static char rcsid[] = "$OpenBSD: misc.c,v 1.24 2001/09/19 13:14:18 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.1 deraadt 79: indx(s1, s2)
1.12 espie 80: const char *s1;
81: const char *s2;
1.1 deraadt 82: {
1.12 espie 83: char *t;
1.7 espie 84:
1.12 espie 85: t = strstr(s1, s2);
86: if (t == NULL)
87: return (-1);
1.7 espie 88: else
1.12 espie 89: return (t - s1);
1.1 deraadt 90: }
91: /*
92: * putback - push character back onto input
93: */
94: void
95: putback(c)
1.17 espie 96: int c;
1.1 deraadt 97: {
1.17 espie 98: if (c == EOF)
99: return;
1.9 espie 100: if (bp >= endpbb)
101: enlarge_bufspace();
102: *bp++ = c;
1.1 deraadt 103: }
104:
105: /*
106: * pbstr - push string back onto input
107: * putback is replicated to improve
108: * performance.
109: */
110: void
111: pbstr(s)
1.14 espie 112: const char *s;
1.1 deraadt 113: {
1.9 espie 114: size_t n;
1.1 deraadt 115:
1.9 espie 116: n = strlen(s);
1.12 espie 117: while (endpbb - bp <= n)
1.9 espie 118: enlarge_bufspace();
119: while (n > 0)
120: *bp++ = s[--n];
1.1 deraadt 121: }
122:
123: /*
124: * pbnum - convert number to string, push back on input.
125: */
126: void
127: pbnum(n)
1.12 espie 128: int n;
1.1 deraadt 129: {
1.12 espie 130: int num;
1.1 deraadt 131:
132: num = (n < 0) ? -n : n;
133: do {
134: putback(num % 10 + '0');
135: }
136: while ((num /= 10) > 0);
137:
138: if (n < 0)
139: putback('-');
140: }
141:
1.18 espie 142: /*
143: * pbunsigned - convert unsigned long to string, push back on input.
144: */
145: void
146: pbunsigned(n)
147: unsigned long n;
148: {
149: do {
150: putback(n % 10 + '0');
151: }
152: while ((n /= 10) > 0);
153: }
1.9 espie 154:
155: void
156: initspaces()
157: {
158: int i;
159:
160: strspace = xalloc(strsize+1);
161: ep = strspace;
162: endest = strspace+strsize;
1.17 espie 163: buf = (char *)xalloc(bufsize);
1.9 espie 164: bufbase = buf;
165: bp = buf;
166: endpbb = buf + bufsize;
167: for (i = 0; i < MAXINP; i++)
168: bbase[i] = buf;
169: }
170:
1.24 espie 171: void
1.17 espie 172: enlarge_strspace()
1.9 espie 173: {
174: char *newstrspace;
1.19 espie 175: int i;
1.9 espie 176:
177: strsize *= 2;
178: newstrspace = malloc(strsize + 1);
179: if (!newstrspace)
180: errx(1, "string space overflow");
181: memcpy(newstrspace, strspace, strsize/2);
1.19 espie 182: for (i = 0; i <= sp; i++)
183: if (sstack[i])
184: mstack[i].sstr = (mstack[i].sstr - strspace)
185: + newstrspace;
1.9 espie 186: ep = (ep-strspace) + newstrspace;
1.19 espie 187: free(strspace);
1.9 espie 188: strspace = newstrspace;
189: endest = strspace + strsize;
190: }
191:
1.24 espie 192: void
1.17 espie 193: enlarge_bufspace()
1.9 espie 194: {
1.17 espie 195: char *newbuf;
1.9 espie 196: int i;
197:
198: bufsize *= 2;
1.17 espie 199: newbuf = realloc(buf, bufsize);
1.9 espie 200: if (!newbuf)
201: errx(1, "too many characters pushed back");
202: for (i = 0; i < MAXINP; i++)
203: bbase[i] = (bbase[i]-buf)+newbuf;
204: bp = (bp-buf)+newbuf;
205: bufbase = (bufbase-buf)+newbuf;
206: buf = newbuf;
1.10 espie 207: endpbb = buf+bufsize;
1.9 espie 208: }
209:
1.1 deraadt 210: /*
211: * chrsave - put single char on string space
212: */
213: void
214: chrsave(c)
1.14 espie 215: int c;
1.1 deraadt 216: {
1.9 espie 217: if (ep >= endest)
218: enlarge_strspace();
219: *ep++ = c;
1.1 deraadt 220: }
221:
222: /*
223: * read in a diversion file, and dispose it.
224: */
225: void
226: getdiv(n)
1.12 espie 227: int n;
1.1 deraadt 228: {
1.12 espie 229: int c;
1.1 deraadt 230:
231: if (active == outfile[n])
1.7 espie 232: errx(1, "undivert: diversion still active");
1.8 espie 233: rewind(outfile[n]);
234: while ((c = getc(outfile[n])) != EOF)
235: putc(c, active);
1.1 deraadt 236: (void) fclose(outfile[n]);
1.13 espie 237: outfile[n] = NULL;
1.1 deraadt 238: }
239:
240: void
241: onintr(signo)
242: int signo;
243: {
1.21 espie 244: #define intrmessage "m4: interrupted.\n"
245: write(STDERR_FILENO, intrmessage, sizeof(intrmessage));
246: _exit(1);
1.1 deraadt 247: }
248:
249: /*
250: * killdiv - get rid of the diversion files
251: */
252: void
253: killdiv()
254: {
1.12 espie 255: int n;
1.1 deraadt 256:
1.20 espie 257: for (n = 0; n < maxout; n++)
1.1 deraadt 258: if (outfile[n] != NULL) {
259: (void) fclose(outfile[n]);
260: }
1.20 espie 261: }
262:
263: /*
264: * resizedivs: allocate more diversion files */
265: void
266: resizedivs(n)
267: int n;
268: {
269: int i;
270:
271: outfile = (FILE **)realloc(outfile, sizeof(FILE *) * n);
272: if (outfile == NULL)
273: errx(1, "too many diverts %d", n);
274: for (i = maxout; i < n; i++)
275: outfile[i] = NULL;
276: maxout = n;
1.1 deraadt 277: }
278:
1.18 espie 279: void *
1.1 deraadt 280: xalloc(n)
1.14 espie 281: size_t n;
1.1 deraadt 282: {
1.12 espie 283: char *p = malloc(n);
1.1 deraadt 284:
285: if (p == NULL)
1.7 espie 286: err(1, "malloc");
1.1 deraadt 287: return p;
288: }
289:
290: char *
291: xstrdup(s)
1.12 espie 292: const char *s;
1.1 deraadt 293: {
1.12 espie 294: char *p = strdup(s);
1.1 deraadt 295: if (p == NULL)
1.7 espie 296: err(1, "strdup");
1.1 deraadt 297: return p;
298: }
299:
300: void
301: usage()
302: {
1.11 espie 303: fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname] [-I dirname...]\n");
1.1 deraadt 304: exit(1);
305: }
306:
1.15 espie 307: int
308: obtain_char(f)
309: struct input_file *f;
310: {
1.17 espie 311: if (f->c == EOF)
312: return EOF;
313: else if (f->c == '\n')
1.15 espie 314: f->lineno++;
315:
316: f->c = fgetc(f->file);
317: return f->c;
318: }
319:
320: void
321: set_input(f, real, name)
322: struct input_file *f;
323: FILE *real;
324: const char *name;
325: {
326: f->file = real;
327: f->lineno = 1;
328: f->c = 0;
329: f->name = xstrdup(name);
330: }
331:
332: void
333: release_input(f)
334: struct input_file *f;
335: {
336: if (f->file != stdin)
337: fclose(f->file);
1.17 espie 338: f->c = EOF;
1.16 espie 339: /*
340: * XXX can't free filename, as there might still be
341: * error information pointing to it.
342: */
1.18 espie 343: }
344:
345: void
346: doprintlineno(f)
347: struct input_file *f;
348: {
349: pbunsigned(f->lineno);
350: }
351:
352: void
353: doprintfilename(f)
354: struct input_file *f;
355: {
1.25 ! espie 356: pbstr(rquote);
1.18 espie 357: pbstr(f->name);
1.25 ! espie 358: pbstr(lquote);
1.22 espie 359: }
360:
361: /*
362: * buffer_mark/dump_buffer: allows one to save a mark in a buffer,
363: * and later dump everything that was added since then to a file.
364: */
365: size_t
366: buffer_mark()
367: {
368: return bp - buf;
369: }
370:
371:
372: void
373: dump_buffer(f, m)
374: FILE *f;
375: size_t m;
376: {
377: char *s;
378:
1.23 espie 379: for (s = bp; s-buf > m;)
1.22 espie 380: fputc(*--s, f);
1.15 espie 381: }