date and time created 89/08/28 15:14:22 by bostic
[unix-history] / usr / src / usr.bin / m4 / misc.c
CommitLineData
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
22static 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
34extern char *malloc();
35
36/*
37 * indx - find the index of second str in the
38 * first str.
39 */
40indx(s1, s2)
41char *s1;
42char *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 */
61putback (c)
62char 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 */
76pbstr(s)
77register 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 */
99pbnum (n)
100int 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 */
117chrsave (c)
118char 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 */
132getdiv(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 */
160error(s)
161char *s;
162{
163 killdiv();
164 fprintf(stderr,"%s\n",s);
165 exit(1);
166}
167
168/*
169 * Interrupt handling
170 */
171static char *msg = "\ninterrupted.";
172
173onintr() {
174 error(msg);
175}
176
177/*
178 * killdiv - get rid of the diversion files
179 *
180 */
181killdiv() {
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 */
200char *strsave(s)
201char *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
211usage() {
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
225char *optarg; /* Global argument pointer. */
226int optind = 0; /* Global argv index. */
227
228static char *scan = NULL; /* Private scan pointer. */
229
230extern char *index();
231
232int
233getopt(argc, argv, optstring)
234int argc;
235char *argv[];
236char *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
292memcpy(to, from, count)
293register char *from, *to;
294register 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