xref: /netbsd-src/usr.bin/m4/misc.c (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
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