xref: /openbsd-src/usr.bin/m4/misc.c (revision 62a742911104f98b9185b2c6b6007d9b1c36396c)
1 /*	$OpenBSD: misc.c,v 1.6 1997/12/10 20:24:17 deraadt Exp $	*/
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
44 static char rcsid[] = "$OpenBSD: misc.c,v 1.6 1997/12/10 20:24:17 deraadt Exp $";
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>
53 #include <string.h>
54 #include "mdef.h"
55 #include "stdd.h"
56 #include "extern.h"
57 #include "pathnames.h"
58 
59 /*
60  * find the index of second str in the first str.
61  */
62 int
63 indx(s1, s2)
64 char *s1;
65 char *s2;
66 {
67 	register char *t;
68 	register char *p;
69 	register char *m;
70 
71 	for (p = s1; *p; p++) {
72 		for (t = p, m = s2; *m && *m == *t; m++, t++);
73 		if (!*m)
74 			return (p - s1);
75 	}
76 	return (-1);
77 }
78 /*
79  *  putback - push character back onto input
80  */
81 void
82 putback(c)
83 pbent c;
84 {
85 	if (bp < endpbb)
86 		*bp++ = c;
87 	else
88 		oops("too many characters pushed back");
89 }
90 
91 /*
92  *  pbstr - push string back onto input
93  *          putback is replicated to improve
94  *          performance.
95  */
96 void
97 pbstr(s)
98 register char *s;
99 {
100 	register char *es;
101 	pbent *zp;
102 
103 	es = s;
104 	zp = bp;
105 
106 	while (*es)
107 		es++;
108 	es--;
109 	while (es >= s)
110 		if (zp < endpbb)
111 			*zp++ = *es--;
112 	if ((bp = zp) == endpbb)
113 		oops("too many characters pushed back");
114 }
115 
116 /*
117  *  pbnum - convert number to string, push back on input.
118  */
119 void
120 pbnum(n)
121 int n;
122 {
123 	register int num;
124 
125 	num = (n < 0) ? -n : n;
126 	do {
127 		putback(num % 10 + '0');
128 	}
129 	while ((num /= 10) > 0);
130 
131 	if (n < 0)
132 		putback('-');
133 }
134 
135 /*
136  *  chrsave - put single char on string space
137  */
138 void
139 chrsave(c)
140 char c;
141 {
142 	if (ep < endest)
143 		*ep++ = c;
144 	else
145 		oops("string space overflow");
146 }
147 
148 /*
149  * read in a diversion file, and dispose it.
150  */
151 void
152 getdiv(n)
153 int n;
154 {
155 	register int c;
156 	register FILE *dfil;
157 
158 	if (active == outfile[n])
159 		oops("%s: diversion still active.", "undivert");
160 	(void) fclose(outfile[n]);
161 	outfile[n] = NULL;
162 	m4temp[UNIQUE] = n + '0';
163 	if ((dfil = fopen(m4temp, "r")) == NULL)
164 		oops("%s: cannot undivert.", m4temp);
165 	else
166 		while ((c = getc(dfil)) != EOF)
167 			putc(c, active);
168 	(void) fclose(dfil);
169 
170 #ifdef vms
171 	if (remove(m4temp))
172 #else
173 	if (unlink(m4temp) == -1)
174 #endif
175 		oops("%s: cannot unlink.", m4temp);
176 }
177 
178 void
179 onintr(signo)
180 	int signo;
181 {
182 	oops("interrupted.");
183 }
184 
185 /*
186  * killdiv - get rid of the diversion files
187  */
188 void
189 killdiv()
190 {
191 	register int n;
192 
193 	for (n = 0; n < MAXOUT; n++)
194 		if (outfile[n] != NULL) {
195 			(void) fclose(outfile[n]);
196 			m4temp[UNIQUE] = n + '0';
197 #ifdef vms
198 			(void) remove(m4temp);
199 #else
200 			(void) unlink(m4temp);
201 #endif
202 		}
203 }
204 
205 char *
206 xalloc(n)
207 unsigned long n;
208 {
209 	register char *p = malloc(n);
210 
211 	if (p == NULL)
212 		oops("malloc: %s", strerror(errno));
213 	return p;
214 }
215 
216 char *
217 xstrdup(s)
218 const char *s;
219 {
220 	register char *p = strdup(s);
221 	if (p == NULL)
222 		oops("strdup: %s", strerror(errno));
223 	return p;
224 }
225 
226 char *
227 basename(s)
228 register char *s;
229 {
230 	register char *p;
231 	extern char *strrchr();
232 
233 	if ((p = strrchr(s, '/')) == NULL)
234 		return s;
235 
236 	return ++p;
237 }
238 
239 void
240 usage()
241 {
242 	fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n");
243 	exit(1);
244 }
245 
246 #ifdef __STDC__
247 #include <stdarg.h>
248 #else
249 #include <varargs.h>
250 #endif
251 
252 void
253 #ifdef __STDC__
254 oops(const char *fmt, ...)
255 #else
256 oops(fmt, va_alist)
257 	char *fmt;
258 	va_dcl
259 #endif
260 {
261 	va_list ap;
262 #ifdef __STDC__
263 	va_start(ap, fmt);
264 #else
265 	va_start(ap);
266 #endif
267 	(void)fprintf(stderr, "%s: ", progname);
268 	(void)vfprintf(stderr, fmt, ap);
269 	va_end(ap);
270 	(void)fprintf(stderr, "\n");
271 	exit(1);
272 	/* NOTREACHED */
273 }
274