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