xref: /original-bsd/usr.bin/m4/misc.c (revision c3e32dec)
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  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)misc.c	8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14 
15 #include <sys/types.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "mdef.h"
22 #include "stdd.h"
23 #include "extern.h"
24 #include "pathnames.h"
25 
26 /*
27  * find the index of second str in the first str.
28  */
29 int
30 indx(s1, s2)
31 char *s1;
32 char *s2;
33 {
34 	register char *t;
35 	register char *p;
36 	register char *m;
37 
38 	for (p = s1; *p; p++) {
39 		for (t = p, m = s2; *m && *m == *t; m++, t++);
40 		if (!*m)
41 			return (p - s1);
42 	}
43 	return (-1);
44 }
45 /*
46  *  putback - push character back onto input
47  */
48 void
49 putback(c)
50 char c;
51 {
52 	if (bp < endpbb)
53 		*bp++ = c;
54 	else
55 		oops("too many characters pushed back");
56 }
57 
58 /*
59  *  pbstr - push string back onto input
60  *          putback is replicated to improve
61  *          performance.
62  */
63 void
64 pbstr(s)
65 register char *s;
66 {
67 	register char *es;
68 	register char *zp;
69 
70 	es = s;
71 	zp = bp;
72 
73 	while (*es)
74 		es++;
75 	es--;
76 	while (es >= s)
77 		if (zp < endpbb)
78 			*zp++ = *es--;
79 	if ((bp = zp) == endpbb)
80 		oops("too many characters pushed back");
81 }
82 
83 /*
84  *  pbnum - convert number to string, push back on input.
85  */
86 void
87 pbnum(n)
88 int n;
89 {
90 	register int num;
91 
92 	num = (n < 0) ? -n : n;
93 	do {
94 		putback(num % 10 + '0');
95 	}
96 	while ((num /= 10) > 0);
97 
98 	if (n < 0)
99 		putback('-');
100 }
101 
102 /*
103  *  chrsave - put single char on string space
104  */
105 void
106 chrsave(c)
107 char c;
108 {
109 	if (ep < endest)
110 		*ep++ = c;
111 	else
112 		oops("string space overflow");
113 }
114 
115 /*
116  * read in a diversion file, and dispose it.
117  */
118 void
119 getdiv(n)
120 int n;
121 {
122 	register int c;
123 	register FILE *dfil;
124 
125 	if (active == outfile[n])
126 		oops("%s: diversion still active.", "undivert");
127 	(void) fclose(outfile[n]);
128 	outfile[n] = NULL;
129 	m4temp[UNIQUE] = n + '0';
130 	if ((dfil = fopen(m4temp, "r")) == NULL)
131 		oops("%s: cannot undivert.", m4temp);
132 	else
133 		while ((c = getc(dfil)) != EOF)
134 			putc(c, active);
135 	(void) fclose(dfil);
136 
137 #ifdef vms
138 	if (remove(m4temp))
139 #else
140 	if (unlink(m4temp) == -1)
141 #endif
142 		oops("%s: cannot unlink.", m4temp);
143 }
144 
145 void
146 onintr(signo)
147 	int signo;
148 {
149 	oops("interrupted.");
150 }
151 
152 /*
153  * killdiv - get rid of the diversion files
154  */
155 void
156 killdiv()
157 {
158 	register int n;
159 
160 	for (n = 0; n < MAXOUT; n++)
161 		if (outfile[n] != NULL) {
162 			(void) fclose(outfile[n]);
163 			m4temp[UNIQUE] = n + '0';
164 #ifdef vms
165 			(void) remove(m4temp);
166 #else
167 			(void) unlink(m4temp);
168 #endif
169 		}
170 }
171 
172 char *
173 xalloc(n)
174 unsigned long n;
175 {
176 	register char *p = malloc(n);
177 
178 	if (p == NULL)
179 		oops("malloc: %s", strerror(errno));
180 	return p;
181 }
182 
183 char *
184 xstrdup(s)
185 const char *s;
186 {
187 	register char *p = strdup(s);
188 	if (p == NULL)
189 		oops("strdup: %s", strerror(errno));
190 	return p;
191 }
192 
193 char *
194 basename(s)
195 register char *s;
196 {
197 	register char *p;
198 	extern char *strrchr();
199 
200 	if ((p = strrchr(s, '/')) == NULL)
201 		return s;
202 
203 	return ++p;
204 }
205 
206 void
207 usage()
208 {
209 	fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n");
210 	exit(1);
211 }
212 
213 #if __STDC__
214 #include <stdarg.h>
215 #else
216 #include <varargs.h>
217 #endif
218 
219 void
220 #if __STDC__
221 oops(const char *fmt, ...)
222 #else
223 oops(fmt, va_alist)
224 	char *fmt;
225 	va_dcl
226 #endif
227 {
228 	va_list ap;
229 #if __STDC__
230 	va_start(ap, fmt);
231 #else
232 	va_start(ap);
233 #endif
234 	(void)fprintf(stderr, "%s: ", progname);
235 	(void)vfprintf(stderr, fmt, ap);
236 	va_end(ap);
237 	(void)fprintf(stderr, "\n");
238 	exit(1);
239 	/* NOTREACHED */
240 }
241