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
indx(s1,s2)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
putback(c)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
pbstr(s)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
pbnum(n)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
chrsave(c)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
getdiv(n)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
onintr(signo)146 onintr(signo)
147 int signo;
148 {
149 oops("interrupted.");
150 }
151
152 /*
153 * killdiv - get rid of the diversion files
154 */
155 void
killdiv()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 *
xalloc(n)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 *
xstrdup(s)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 *
basename(s)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
usage()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__
oops(const char * fmt,...)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