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