misc.c revision 1.6 1 /* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */
2
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Ozan Yigit at York University.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39 #ifndef lint
40 #if 0
41 static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93";
42 #else
43 static char rcsid[] = "$NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $";
44 #endif
45 #endif /* not lint */
46
47 #include <sys/types.h>
48 #include <errno.h>
49 #include <unistd.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include "mdef.h"
54 #include "stdd.h"
55 #include "extern.h"
56 #include "pathnames.h"
57
58 /*
59 * find the index of second str in the first str.
60 */
61 int
62 indx(s1, s2)
63 char *s1;
64 char *s2;
65 {
66 register char *t;
67 register char *p;
68 register char *m;
69
70 for (p = s1; *p; p++) {
71 for (t = p, m = s2; *m && *m == *t; m++, t++);
72 if (!*m)
73 return (p - s1);
74 }
75 return (-1);
76 }
77 /*
78 * putback - push character back onto input
79 */
80 void
81 putback(c)
82 char c;
83 {
84 if (bp < endpbb)
85 *bp++ = c;
86 else
87 oops("too many characters pushed back");
88 }
89
90 /*
91 * pbstr - push string back onto input
92 * putback is replicated to improve
93 * performance.
94 */
95 void
96 pbstr(s)
97 register char *s;
98 {
99 register char *es;
100 register char *zp;
101
102 es = s;
103 zp = bp;
104
105 while (*es)
106 es++;
107 es--;
108 while (es >= s)
109 if (zp < endpbb)
110 *zp++ = *es--;
111 if ((bp = zp) == endpbb)
112 oops("too many characters pushed back");
113 }
114
115 /*
116 * pbnum - convert number to string, push back on input.
117 */
118 void
119 pbnum(n)
120 int n;
121 {
122 register int num;
123
124 num = (n < 0) ? -n : n;
125 do {
126 putback(num % 10 + '0');
127 }
128 while ((num /= 10) > 0);
129
130 if (n < 0)
131 putback('-');
132 }
133
134 /*
135 * chrsave - put single char on string space
136 */
137 void
138 chrsave(c)
139 char c;
140 {
141 if (ep < endest)
142 *ep++ = c;
143 else
144 oops("string space overflow");
145 }
146
147 /*
148 * read in a diversion file, and dispose it.
149 */
150 void
151 getdiv(n)
152 int n;
153 {
154 register int c;
155 register FILE *dfil;
156
157 if (active == outfile[n])
158 oops("%s: diversion still active.", "undivert");
159 (void) fclose(outfile[n]);
160 outfile[n] = NULL;
161 m4temp[UNIQUE] = n + '0';
162 if ((dfil = fopen(m4temp, "r")) == NULL)
163 oops("%s: cannot undivert.", m4temp);
164 else
165 while ((c = getc(dfil)) != EOF)
166 putc(c, active);
167 (void) fclose(dfil);
168
169 #ifdef vms
170 if (remove(m4temp))
171 #else
172 if (unlink(m4temp) == -1)
173 #endif
174 oops("%s: cannot unlink.", m4temp);
175 }
176
177 void
178 onintr(signo)
179 int signo;
180 {
181 oops("interrupted.");
182 }
183
184 /*
185 * killdiv - get rid of the diversion files
186 */
187 void
188 killdiv()
189 {
190 register int n;
191
192 for (n = 0; n < MAXOUT; n++)
193 if (outfile[n] != NULL) {
194 (void) fclose(outfile[n]);
195 m4temp[UNIQUE] = n + '0';
196 #ifdef vms
197 (void) remove(m4temp);
198 #else
199 (void) unlink(m4temp);
200 #endif
201 }
202 }
203
204 char *
205 xalloc(n)
206 unsigned long n;
207 {
208 register char *p = malloc(n);
209
210 if (p == NULL)
211 oops("malloc: %s", strerror(errno));
212 return p;
213 }
214
215 char *
216 xstrdup(s)
217 const char *s;
218 {
219 register char *p = strdup(s);
220 if (p == NULL)
221 oops("strdup: %s", strerror(errno));
222 return p;
223 }
224
225 char *
226 basename(s)
227 register char *s;
228 {
229 register char *p;
230 extern char *strrchr();
231
232 if ((p = strrchr(s, '/')) == NULL)
233 return s;
234
235 return ++p;
236 }
237
238 void
239 usage()
240 {
241 fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n");
242 exit(1);
243 }
244
245 #if __STDC__
246 #include <stdarg.h>
247 #else
248 #include <varargs.h>
249 #endif
250
251 void
252 #if __STDC__
253 oops(const char *fmt, ...)
254 #else
255 oops(fmt, va_alist)
256 char *fmt;
257 va_dcl
258 #endif
259 {
260 va_list ap;
261 #if __STDC__
262 va_start(ap, fmt);
263 #else
264 va_start(ap);
265 #endif
266 (void)fprintf(stderr, "%s: ", progname);
267 (void)vfprintf(stderr, fmt, ap);
268 va_end(ap);
269 (void)fprintf(stderr, "\n");
270 exit(1);
271 /* NOTREACHED */
272 }
273