Annotation of src/usr.bin/m4/misc.c, Revision 1.11
1.11 ! espie 1: /* $OpenBSD: misc.c,v 1.10 1999/09/09 22:18:19 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.11 ! espie 44: static char rcsid[] = "$OpenBSD: misc.c,v 1.10 1999/09/09 22:18:19 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:
69: pbent *buf; /* push-back buffer */
70: pbent *bufbase; /* the base for current ilevel */
71: pbent *bbase[MAXINP]; /* the base for each ilevel */
72: pbent *bp; /* first available character */
73: static pbent *endpbb; /* end of push-back buffer */
74:
75:
76: static void enlarge_bufspace();
77: static void enlarge_strspace();
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.7 espie 83: const char *s1;
84: const char *s2;
1.1 deraadt 85: {
1.7 espie 86: char *r;
87:
88: r = strstr(s1, s2);
89: if (r)
90: return (r - s1);
91: else
92: return (-1);
1.1 deraadt 93: }
94: /*
95: * putback - push character back onto input
96: */
97: void
98: putback(c)
1.6 deraadt 99: pbent c;
1.1 deraadt 100: {
1.9 espie 101: if (bp >= endpbb)
102: enlarge_bufspace();
103: *bp++ = c;
1.1 deraadt 104: }
105:
106: /*
107: * pbstr - push string back onto input
108: * putback is replicated to improve
109: * performance.
110: */
111: void
112: pbstr(s)
113: register char *s;
114: {
1.9 espie 115: size_t n;
1.1 deraadt 116:
1.9 espie 117: n = strlen(s);
118: while (endpbb - bp < n)
119: enlarge_bufspace();
120: while (n > 0)
121: *bp++ = s[--n];
1.1 deraadt 122: }
123:
124: /*
125: * pbnum - convert number to string, push back on input.
126: */
127: void
128: pbnum(n)
129: int n;
130: {
131: register int num;
132:
133: num = (n < 0) ? -n : n;
134: do {
135: putback(num % 10 + '0');
136: }
137: while ((num /= 10) > 0);
138:
139: if (n < 0)
140: putback('-');
141: }
142:
1.9 espie 143:
144: void
145: initspaces()
146: {
147: int i;
148:
149: strspace = xalloc(strsize+1);
150: ep = strspace;
151: endest = strspace+strsize;
152: buf = (pbent *)xalloc(bufsize * sizeof(pbent));
153: bufbase = buf;
154: bp = buf;
155: endpbb = buf + bufsize;
156: for (i = 0; i < MAXINP; i++)
157: bbase[i] = buf;
158: }
159:
160: /* XXX when chrsave is called, the current argument is
161: * always topmost on the stack. We make use of this to
162: * duplicate it transparently, and to reclaim the correct
163: * space when the stack is unwound.
164: */
165: static
166: void enlarge_strspace()
167: {
168: char *newstrspace;
169:
170: low_sp = sp;
171: strsize *= 2;
172: newstrspace = malloc(strsize + 1);
173: if (!newstrspace)
174: errx(1, "string space overflow");
175: memcpy(newstrspace, strspace, strsize/2);
176: /* reclaim memory in the easy, common case. */
177: if (ep == strspace)
178: free(strspace);
179: mstack[sp].sstr = (mstack[sp].sstr-strspace) + newstrspace;
180: ep = (ep-strspace) + newstrspace;
181: strspace = newstrspace;
182: endest = strspace + strsize;
183: }
184:
185: static
186: void enlarge_bufspace()
187: {
188: pbent *newbuf;
189: int i;
190:
191: bufsize *= 2;
192: newbuf = realloc(buf, bufsize*sizeof(pbent));
193: if (!newbuf)
194: errx(1, "too many characters pushed back");
195: for (i = 0; i < MAXINP; i++)
196: bbase[i] = (bbase[i]-buf)+newbuf;
197: bp = (bp-buf)+newbuf;
198: bufbase = (bufbase-buf)+newbuf;
199: buf = newbuf;
1.10 espie 200: endpbb = buf+bufsize;
1.9 espie 201: }
202:
1.1 deraadt 203: /*
204: * chrsave - put single char on string space
205: */
206: void
207: chrsave(c)
208: char c;
209: {
1.9 espie 210: if (ep >= endest)
211: enlarge_strspace();
212: *ep++ = c;
213: }
214:
215: /*
216: * so we reclaim what string space we can
217: */
218: char *
219: compute_prevep()
220: {
221: if (fp+3 <= low_sp)
222: {
223: return strspace;
224: }
1.1 deraadt 225: else
1.9 espie 226: {
227: return mstack[fp+3].sstr;
228: }
1.1 deraadt 229: }
230:
231: /*
232: * read in a diversion file, and dispose it.
233: */
234: void
235: getdiv(n)
236: int n;
237: {
238: register int c;
239:
240: if (active == outfile[n])
1.7 espie 241: errx(1, "undivert: diversion still active");
1.8 espie 242: rewind(outfile[n]);
243: while ((c = getc(outfile[n])) != EOF)
244: putc(c, active);
1.1 deraadt 245: (void) fclose(outfile[n]);
246: }
247:
248: void
249: onintr(signo)
250: int signo;
251: {
1.7 espie 252: errx(1, "interrupted.");
1.1 deraadt 253: }
254:
255: /*
256: * killdiv - get rid of the diversion files
257: */
258: void
259: killdiv()
260: {
261: register int n;
262:
263: for (n = 0; n < MAXOUT; n++)
264: if (outfile[n] != NULL) {
265: (void) fclose(outfile[n]);
266: }
267: }
268:
269: char *
270: xalloc(n)
271: unsigned long n;
272: {
273: register char *p = malloc(n);
274:
275: if (p == NULL)
1.7 espie 276: err(1, "malloc");
1.1 deraadt 277: return p;
278: }
279:
280: char *
281: xstrdup(s)
282: const char *s;
283: {
284: register char *p = strdup(s);
285: if (p == NULL)
1.7 espie 286: err(1, "strdup");
1.1 deraadt 287: return p;
288: }
289:
290: void
291: usage()
292: {
1.11 ! espie 293: fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname] [-I dirname...]\n");
1.1 deraadt 294: exit(1);
295: }
296: