Commit | Line | Data |
---|---|---|
d48b7960 KB |
1 | /* |
2 | * Copyright (c) 1989 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Ozan Yigit. | |
7 | * | |
8 | * Redistribution and use in source and binary forms are permitted | |
9 | * provided that the above copyright notice and this paragraph are | |
10 | * duplicated in all such forms and that any documentation, | |
11 | * advertising materials, and other materials related to such | |
12 | * distribution and use acknowledge that the software was developed | |
13 | * by the University of California, Berkeley. The name of the | |
14 | * University may not be used to endorse or promote products derived | |
15 | * from this software without specific prior written permission. | |
16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
19 | */ | |
20 | ||
21 | #ifndef lint | |
22 | static char sccsid[] = "@(#)misc.c 5.1 (Berkeley) %G%"; | |
23 | #endif /* not lint */ | |
24 | ||
25 | /* | |
26 | * misc.c | |
27 | * Facility: m4 macro processor | |
28 | * by: oz | |
29 | */ | |
30 | ||
31 | #include "mdef.h" | |
32 | #include "extr.h" | |
33 | ||
34 | extern char *malloc(); | |
35 | ||
36 | /* | |
37 | * indx - find the index of second str in the | |
38 | * first str. | |
39 | */ | |
40 | indx(s1, s2) | |
41 | char *s1; | |
42 | char *s2; | |
43 | { | |
44 | register char *t; | |
45 | register char *p; | |
46 | register char *m; | |
47 | ||
48 | for (p = s1; *p; p++) { | |
49 | for (t = p, m = s2; *m && *m == *t; m++, t++) | |
50 | ; | |
51 | if (!*m) | |
52 | return(p - s1); | |
53 | } | |
54 | return (-1); | |
55 | } | |
56 | ||
57 | /* | |
58 | * putback - push character back onto input | |
59 | * | |
60 | */ | |
61 | putback (c) | |
62 | char c; | |
63 | { | |
64 | if (bp < endpbb) | |
65 | *bp++ = c; | |
66 | else | |
67 | error("m4: too many characters pushed back"); | |
68 | } | |
69 | ||
70 | /* | |
71 | * pbstr - push string back onto input | |
72 | * putback is replicated to improve | |
73 | * performance. | |
74 | * | |
75 | */ | |
76 | pbstr(s) | |
77 | register char *s; | |
78 | { | |
79 | register char *es; | |
80 | register char *zp; | |
81 | ||
82 | es = s; | |
83 | zp = bp; | |
84 | ||
85 | while (*es) | |
86 | es++; | |
87 | es--; | |
88 | while (es >= s) | |
89 | if (zp < endpbb) | |
90 | *zp++ = *es--; | |
91 | if ((bp = zp) == endpbb) | |
92 | error("m4: too many characters pushed back"); | |
93 | } | |
94 | ||
95 | /* | |
96 | * pbnum - convert number to string, push back on input. | |
97 | * | |
98 | */ | |
99 | pbnum (n) | |
100 | int n; | |
101 | { | |
102 | register int num; | |
103 | ||
104 | num = (n < 0) ? -n : n; | |
105 | do { | |
106 | putback(num % 10 + '0'); | |
107 | } | |
108 | while ((num /= 10) > 0); | |
109 | ||
110 | if (n < 0) putback('-'); | |
111 | } | |
112 | ||
113 | /* | |
114 | * chrsave - put single char on string space | |
115 | * | |
116 | */ | |
117 | chrsave (c) | |
118 | char c; | |
119 | { | |
120 | /*** if (sp < 0) | |
121 | putc(c, active); | |
122 | else ***/ if (ep < endest) | |
123 | *ep++ = c; | |
124 | else | |
125 | error("m4: string space overflow"); | |
126 | } | |
127 | ||
128 | /* | |
129 | * getdiv - read in a diversion file, and | |
130 | * trash it. | |
131 | */ | |
132 | getdiv(ind) { | |
133 | register int c; | |
134 | register FILE *dfil; | |
135 | ||
136 | if (active == outfile[ind]) | |
137 | error("m4: undivert: diversion still active."); | |
138 | (void) fclose(outfile[ind]); | |
139 | outfile[ind] = NULL; | |
140 | m4temp[UNIQUE] = ind + '0'; | |
141 | if ((dfil = fopen(m4temp, "r")) == NULL) | |
142 | error("m4: cannot undivert."); | |
143 | else | |
144 | while((c = getc(dfil)) != EOF) | |
145 | putc(c, active); | |
146 | (void) fclose(dfil); | |
147 | ||
148 | #if vms | |
149 | if (remove(m4temp)) | |
150 | #else | |
151 | if (unlink(m4temp) == -1) | |
152 | #endif | |
153 | error("m4: cannot unlink."); | |
154 | } | |
155 | ||
156 | /* | |
157 | * Very fatal error. Close all files | |
158 | * and die hard. | |
159 | */ | |
160 | error(s) | |
161 | char *s; | |
162 | { | |
163 | killdiv(); | |
164 | fprintf(stderr,"%s\n",s); | |
165 | exit(1); | |
166 | } | |
167 | ||
168 | /* | |
169 | * Interrupt handling | |
170 | */ | |
171 | static char *msg = "\ninterrupted."; | |
172 | ||
173 | onintr() { | |
174 | error(msg); | |
175 | } | |
176 | ||
177 | /* | |
178 | * killdiv - get rid of the diversion files | |
179 | * | |
180 | */ | |
181 | killdiv() { | |
182 | register int n; | |
183 | ||
184 | for (n = 0; n < MAXOUT; n++) | |
185 | if (outfile[n] != NULL) { | |
186 | (void) fclose (outfile[n]); | |
187 | m4temp[UNIQUE] = n + '0'; | |
188 | #if vms | |
189 | (void) remove (m4temp); | |
190 | #else | |
191 | (void) unlink (m4temp); | |
192 | #endif | |
193 | } | |
194 | } | |
195 | ||
196 | /* | |
197 | * save a string somewhere.. | |
198 | * | |
199 | */ | |
200 | char *strsave(s) | |
201 | char *s; | |
202 | { | |
203 | register int n; | |
204 | char *p; | |
205 | ||
206 | if ((p = malloc (n = strlen(s)+1)) != NULL) | |
207 | (void) memcpy(p, s, n); | |
208 | return (p); | |
209 | } | |
210 | ||
211 | usage() { | |
212 | fprintf(stderr, "Usage: m4 [-Dname[=val]] [-Uname]\n"); | |
213 | exit(1); | |
214 | } | |
215 | ||
216 | #ifdef GETOPT | |
217 | /* | |
218 | * H. Spencer getopt - get option letter from argv | |
219 | * | |
220 | * | |
221 | #include <stdio.h> | |
222 | * | |
223 | */ | |
224 | ||
225 | char *optarg; /* Global argument pointer. */ | |
226 | int optind = 0; /* Global argv index. */ | |
227 | ||
228 | static char *scan = NULL; /* Private scan pointer. */ | |
229 | ||
230 | extern char *index(); | |
231 | ||
232 | int | |
233 | getopt(argc, argv, optstring) | |
234 | int argc; | |
235 | char *argv[]; | |
236 | char *optstring; | |
237 | { | |
238 | register char c; | |
239 | register char *place; | |
240 | ||
241 | optarg = NULL; | |
242 | ||
243 | if (scan == NULL || *scan == '\0') { | |
244 | if (optind == 0) | |
245 | optind++; | |
246 | ||
247 | if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') | |
248 | return(EOF); | |
249 | if (strcmp(argv[optind], "--")==0) { | |
250 | optind++; | |
251 | return(EOF); | |
252 | } | |
253 | ||
254 | scan = argv[optind]+1; | |
255 | optind++; | |
256 | } | |
257 | ||
258 | c = *scan++; | |
259 | place = index(optstring, c); | |
260 | ||
261 | if (place == NULL || c == ':') { | |
262 | fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); | |
263 | return('?'); | |
264 | } | |
265 | ||
266 | place++; | |
267 | if (*place == ':') { | |
268 | if (*scan != '\0') { | |
269 | optarg = scan; | |
270 | scan = NULL; | |
271 | } else { | |
272 | optarg = argv[optind]; | |
273 | optind++; | |
274 | } | |
275 | } | |
276 | ||
277 | return(c); | |
278 | } | |
279 | ||
280 | #endif | |
281 | ||
282 | #ifdef DUFFCP | |
283 | /* | |
284 | * This code uses Duff's Device (tm Tom Duff) | |
285 | * to unroll the copying loop: | |
286 | * while (count-- > 0) | |
287 | * *to++ = *from++; | |
288 | */ | |
289 | ||
290 | #define COPYBYTE *to++ = *from++ | |
291 | ||
292 | memcpy(to, from, count) | |
293 | register char *from, *to; | |
294 | register int count; | |
295 | { | |
296 | if (count > 0) { | |
297 | register int loops = (count+8-1) >> 3; /* div 8 round up */ | |
298 | ||
299 | switch (count&(8-1)) { /* mod 8 */ | |
300 | case 0: do { | |
301 | COPYBYTE; | |
302 | case 7: COPYBYTE; | |
303 | case 6: COPYBYTE; | |
304 | case 5: COPYBYTE; | |
305 | case 4: COPYBYTE; | |
306 | case 3: COPYBYTE; | |
307 | case 2: COPYBYTE; | |
308 | case 1: COPYBYTE; | |
309 | } while (--loops > 0); | |
310 | } | |
311 | ||
312 | } | |
313 | } | |
314 | ||
315 | #endif |