Annotation of src/usr.bin/m4/misc.c, Revision 1.18
1.18 ! espie 1: /* $OpenBSD: misc.c,v 1.17 2000/01/15 14:26:00 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.18 ! espie 44: static char rcsid[] = "$OpenBSD: misc.c,v 1.17 2000/01/15 14:26:00 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 */
64: static char *endest; /* end of string space */
65: static size_t strsize = STRSPMAX;
66: static size_t bufsize = BUFSIZE;
67: static int low_sp = 0;
68:
1.17 espie 69: char *buf; /* push-back buffer */
70: char *bufbase; /* the base for current ilevel */
71: char *bbase[MAXINP]; /* the base for each ilevel */
72: char *bp; /* first available character */
73: static char *endpbb; /* end of push-back buffer */
1.9 espie 74:
75:
1.14 espie 76: static void enlarge_bufspace __P((void));
77: static void enlarge_strspace __P((void));
1.1 deraadt 78: /*
79: * find the index of second str in the first str.
80: */
1.7 espie 81: ptrdiff_t
1.1 deraadt 82: indx(s1, s2)
1.12 espie 83: const char *s1;
84: const char *s2;
1.1 deraadt 85: {
1.12 espie 86: char *t;
1.7 espie 87:
1.12 espie 88: t = strstr(s1, s2);
89: if (t == NULL)
90: return (-1);
1.7 espie 91: else
1.12 espie 92: return (t - s1);
1.1 deraadt 93: }
94: /*
95: * putback - push character back onto input
96: */
97: void
98: putback(c)
1.17 espie 99: int c;
1.1 deraadt 100: {
1.17 espie 101: if (c == EOF)
102: return;
1.9 espie 103: if (bp >= endpbb)
104: enlarge_bufspace();
105: *bp++ = c;
1.1 deraadt 106: }
107:
108: /*
109: * pbstr - push string back onto input
110: * putback is replicated to improve
111: * performance.
112: */
113: void
114: pbstr(s)
1.14 espie 115: const char *s;
1.1 deraadt 116: {
1.9 espie 117: size_t n;
1.1 deraadt 118:
1.9 espie 119: n = strlen(s);
1.12 espie 120: while (endpbb - bp <= n)
1.9 espie 121: enlarge_bufspace();
122: while (n > 0)
123: *bp++ = s[--n];
1.1 deraadt 124: }
125:
126: /*
127: * pbnum - convert number to string, push back on input.
128: */
129: void
130: pbnum(n)
1.12 espie 131: int n;
1.1 deraadt 132: {
1.12 espie 133: int num;
1.1 deraadt 134:
135: num = (n < 0) ? -n : n;
136: do {
137: putback(num % 10 + '0');
138: }
139: while ((num /= 10) > 0);
140:
141: if (n < 0)
142: putback('-');
143: }
144:
1.18 ! espie 145: /*
! 146: * pbunsigned - convert unsigned long to string, push back on input.
! 147: */
! 148: void
! 149: pbunsigned(n)
! 150: unsigned long n;
! 151: {
! 152: do {
! 153: putback(n % 10 + '0');
! 154: }
! 155: while ((n /= 10) > 0);
! 156: }
1.9 espie 157:
158: void
159: initspaces()
160: {
161: int i;
162:
163: strspace = xalloc(strsize+1);
164: ep = strspace;
165: endest = strspace+strsize;
1.17 espie 166: buf = (char *)xalloc(bufsize);
1.9 espie 167: bufbase = buf;
168: bp = buf;
169: endpbb = buf + bufsize;
170: for (i = 0; i < MAXINP; i++)
171: bbase[i] = buf;
172: }
173:
174: /* XXX when chrsave is called, the current argument is
175: * always topmost on the stack. We make use of this to
176: * duplicate it transparently, and to reclaim the correct
177: * space when the stack is unwound.
178: */
1.17 espie 179: static void
180: enlarge_strspace()
1.9 espie 181: {
182: char *newstrspace;
183:
184: low_sp = sp;
185: strsize *= 2;
186: newstrspace = malloc(strsize + 1);
187: if (!newstrspace)
188: errx(1, "string space overflow");
189: memcpy(newstrspace, strspace, strsize/2);
190: /* reclaim memory in the easy, common case. */
191: if (ep == strspace)
192: free(strspace);
193: mstack[sp].sstr = (mstack[sp].sstr-strspace) + newstrspace;
194: ep = (ep-strspace) + newstrspace;
195: strspace = newstrspace;
196: endest = strspace + strsize;
197: }
198:
1.17 espie 199: static void
200: enlarge_bufspace()
1.9 espie 201: {
1.17 espie 202: char *newbuf;
1.9 espie 203: int i;
204:
205: bufsize *= 2;
1.17 espie 206: newbuf = realloc(buf, bufsize);
1.9 espie 207: if (!newbuf)
208: errx(1, "too many characters pushed back");
209: for (i = 0; i < MAXINP; i++)
210: bbase[i] = (bbase[i]-buf)+newbuf;
211: bp = (bp-buf)+newbuf;
212: bufbase = (bufbase-buf)+newbuf;
213: buf = newbuf;
1.10 espie 214: endpbb = buf+bufsize;
1.9 espie 215: }
216:
1.1 deraadt 217: /*
218: * chrsave - put single char on string space
219: */
220: void
221: chrsave(c)
1.14 espie 222: int c;
1.1 deraadt 223: {
1.9 espie 224: if (ep >= endest)
225: enlarge_strspace();
226: *ep++ = c;
227: }
228:
229: /*
230: * so we reclaim what string space we can
231: */
232: char *
233: compute_prevep()
234: {
235: if (fp+3 <= low_sp)
236: {
237: return strspace;
238: }
1.1 deraadt 239: else
1.9 espie 240: {
241: return mstack[fp+3].sstr;
242: }
1.1 deraadt 243: }
244:
245: /*
246: * read in a diversion file, and dispose it.
247: */
248: void
249: getdiv(n)
1.12 espie 250: int n;
1.1 deraadt 251: {
1.12 espie 252: int c;
1.1 deraadt 253:
254: if (active == outfile[n])
1.7 espie 255: errx(1, "undivert: diversion still active");
1.8 espie 256: rewind(outfile[n]);
257: while ((c = getc(outfile[n])) != EOF)
258: putc(c, active);
1.1 deraadt 259: (void) fclose(outfile[n]);
1.13 espie 260: outfile[n] = NULL;
1.1 deraadt 261: }
262:
263: void
264: onintr(signo)
265: int signo;
266: {
1.7 espie 267: errx(1, "interrupted.");
1.1 deraadt 268: }
269:
270: /*
271: * killdiv - get rid of the diversion files
272: */
273: void
274: killdiv()
275: {
1.12 espie 276: int n;
1.1 deraadt 277:
278: for (n = 0; n < MAXOUT; n++)
279: if (outfile[n] != NULL) {
280: (void) fclose(outfile[n]);
281: }
282: }
283:
1.18 ! espie 284: void *
1.1 deraadt 285: xalloc(n)
1.14 espie 286: size_t n;
1.1 deraadt 287: {
1.12 espie 288: char *p = malloc(n);
1.1 deraadt 289:
290: if (p == NULL)
1.7 espie 291: err(1, "malloc");
1.1 deraadt 292: return p;
293: }
294:
295: char *
296: xstrdup(s)
1.12 espie 297: const char *s;
1.1 deraadt 298: {
1.12 espie 299: char *p = strdup(s);
1.1 deraadt 300: if (p == NULL)
1.7 espie 301: err(1, "strdup");
1.1 deraadt 302: return p;
303: }
304:
305: void
306: usage()
307: {
1.11 espie 308: fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname] [-I dirname...]\n");
1.1 deraadt 309: exit(1);
310: }
311:
1.15 espie 312: int
313: obtain_char(f)
314: struct input_file *f;
315: {
1.17 espie 316: if (f->c == EOF)
317: return EOF;
318: else if (f->c == '\n')
1.15 espie 319: f->lineno++;
320:
321: f->c = fgetc(f->file);
322: return f->c;
323: }
324:
325: void
326: set_input(f, real, name)
327: struct input_file *f;
328: FILE *real;
329: const char *name;
330: {
331: f->file = real;
332: f->lineno = 1;
333: f->c = 0;
334: f->name = xstrdup(name);
335: }
336:
337: void
338: release_input(f)
339: struct input_file *f;
340: {
341: if (f->file != stdin)
342: fclose(f->file);
1.17 espie 343: f->c = EOF;
1.16 espie 344: /*
345: * XXX can't free filename, as there might still be
346: * error information pointing to it.
347: */
1.18 ! espie 348: }
! 349:
! 350: void
! 351: doprintlineno(f)
! 352: struct input_file *f;
! 353: {
! 354: pbunsigned(f->lineno);
! 355: }
! 356:
! 357: void
! 358: doprintfilename(f)
! 359: struct input_file *f;
! 360: {
! 361: pbstr(f->name);
1.15 espie 362: }