eval.c (de9b3b9034ee0d39f3bff03b8368361d80cf728f) eval.c (e3d8671772982f3135d8d6997f3cd698cca4df19)
1/* $OpenBSD: eval.c,v 1.43 2002/02/16 21:27:48 millert Exp $ */
2/* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */
3
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

--- 22 unchanged lines hidden (view full) ---

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#if 0
4/*
5 * Copyright (c) 1989, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Ozan Yigit at York University.
10 *
11 * Redistribution and use in source and binary forms, with or without

--- 22 unchanged lines hidden (view full) ---

34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40#ifndef lint
41#if 0
39static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 6/6/93";
42static char sccsid[] = "@(#)eval.c 8.2 (Berkeley) 4/27/95";
43#else
44static char rcsid[] = "$OpenBSD: eval.c,v 1.43 2002/02/16 21:27:48 millert Exp $";
40#endif
45#endif
41static const char rcsid[] =
42 "$FreeBSD$";
43#endif /* not lint */
44
45/*
46 * eval.c
47 * Facility: m4 macro processor
48 * by: oz
49 */
50
51#include <sys/types.h>
46#endif /* not lint */
47
48/*
49 * eval.c
50 * Facility: m4 macro processor
51 * by: oz
52 */
53
54#include <sys/types.h>
52#include <err.h>
55#include <errno.h>
56#include <unistd.h>
53#include <stdio.h>
54#include <stdlib.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <stddef.h>
55#include <string.h>
60#include <string.h>
56#include <unistd.h>
61#include <fcntl.h>
62#include <err.h>
57#include "mdef.h"
58#include "stdd.h"
59#include "extern.h"
60#include "pathnames.h"
61
63#include "mdef.h"
64#include "stdd.h"
65#include "extern.h"
66#include "pathnames.h"
67
68#define BUILTIN_MARKER "__builtin_"
69
70static void dodefn(const char *);
71static void dopushdef(const char *, const char *);
72static void dodump(const char *[], int);
73static void dotrace(const char *[], int, int);
74static void doifelse(const char *[], int);
75static int doincl(const char *);
76static int dopaste(const char *);
77static void gnu_dochq(const char *[], int);
78static void dochq(const char *[], int);
79static void gnu_dochc(const char *[], int);
80static void dochc(const char *[], int);
81static void dodiv(int);
82static void doundiv(const char *[], int);
83static void dosub(const char *[], int);
84static void map(char *, const char *, const char *, const char *);
85static const char *handledash(char *, char *, const char *);
86static void expand_builtin(const char *[], int, int);
87static void expand_macro(const char *[], int);
88static void dump_one_def(ndptr);
89
90unsigned long expansion_id;
91
62/*
92/*
63 * eval - evaluate built-in macros.
93 * eval - eval all macros and builtins calls
64 * argc - number of elements in argv.
65 * argv - element vector :
66 * argv[0] = definition of a user
67 * macro or nil if built-in.
68 * argv[1] = name of the macro or
69 * built-in.
70 * argv[2] = parameters to user-defined
71 * . macro or built-in.
72 * .
73 *
94 * argc - number of elements in argv.
95 * argv - element vector :
96 * argv[0] = definition of a user
97 * macro or nil if built-in.
98 * argv[1] = name of the macro or
99 * built-in.
100 * argv[2] = parameters to user-defined
101 * . macro or built-in.
102 * .
103 *
74 * Note that the minimum value for argc is 3. A call in the form
75 * of macro-or-builtin() will result in:
104 * A call in the form of macro-or-builtin() will result in:
76 * argv[0] = nullstr
77 * argv[1] = macro-or-builtin
78 * argv[2] = nullstr
105 * argv[0] = nullstr
106 * argv[1] = macro-or-builtin
107 * argv[2] = nullstr
108 *
109 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
79 */
110 */
80
81void
82eval(argv, argc, td)
111void
112eval(argv, argc, td)
83register char *argv[];
84register int argc;
85register int td;
113 const char *argv[];
114 int argc;
115 int td;
86{
116{
87 register int c, n;
117 ssize_t mark = -1;
118
119 expansion_id++;
120 if (td & RECDEF)
121 errx(1, "%s at line %lu: expanding recursive definition for %s",
122 CURRENT_NAME, CURRENT_LINE, argv[1]);
123 if (traced_macros && is_traced(argv[1]))
124 mark = trace(argv, argc, infile+ilevel);
125 if (td == MACRTYPE)
126 expand_macro(argv, argc);
127 else
128 expand_builtin(argv, argc, td);
129 if (mark != -1)
130 finish_trace(mark);
131}
132
133/*
134 * expand_builtin - evaluate built-in macros.
135 */
136void
137expand_builtin(argv, argc, td)
138 const char *argv[];
139 int argc;
140 int td;
141{
142 int c, n;
143 int ac;
88 static int sysval = 0;
144 static int sysval = 0;
89 char *p;
90
91#ifdef DEBUG
92 printf("argc = %d\n", argc);
93 for (n = 0; n < argc; n++)
94 printf("argv[%d] = %s\n", n, argv[n]);
145
146#ifdef DEBUG
147 printf("argc = %d\n", argc);
148 for (n = 0; n < argc; n++)
149 printf("argv[%d] = %s\n", n, argv[n]);
150 fflush(stdout);
95#endif
151#endif
152
96 /*
97 * if argc == 3 and argv[2] is null, then we
98 * have macro-or-builtin() type call. We adjust
99 * argc to avoid further checking..
100 */
153 /*
154 * if argc == 3 and argv[2] is null, then we
155 * have macro-or-builtin() type call. We adjust
156 * argc to avoid further checking..
157 */
158 ac = argc;
159
101 if (argc == 3 && !*(argv[2]))
102 argc--;
103
160 if (argc == 3 && !*(argv[2]))
161 argc--;
162
104 switch (td & ~STATIC) {
163 switch (td & TYPEMASK) {
105
106 case DEFITYPE:
107 if (argc > 2)
108 dodefine(argv[2], (argc > 3) ? argv[3] : null);
109 break;
110
111 case PUSDTYPE:
112 if (argc > 2)
113 dopushdef(argv[2], (argc > 3) ? argv[3] : null);
114 break;
115
116 case DUMPTYPE:
117 dodump(argv, argc);
118 break;
119
164
165 case DEFITYPE:
166 if (argc > 2)
167 dodefine(argv[2], (argc > 3) ? argv[3] : null);
168 break;
169
170 case PUSDTYPE:
171 if (argc > 2)
172 dopushdef(argv[2], (argc > 3) ? argv[3] : null);
173 break;
174
175 case DUMPTYPE:
176 dodump(argv, argc);
177 break;
178
179 case TRACEONTYPE:
180 dotrace(argv, argc, 1);
181 break;
182
183 case TRACEOFFTYPE:
184 dotrace(argv, argc, 0);
185 break;
186
120 case EXPRTYPE:
121 /*
122 * doexpr - evaluate arithmetic
123 * expression
124 */
125 if (argc > 2)
126 pbnum(expr(argv[2]));
127 break;

--- 42 unchanged lines hidden (view full) ---

170 if (argc > 2)
171 pbnum(atoi(argv[2]) - 1);
172 break;
173
174 case SYSCTYPE:
175 /*
176 * dosys - execute system command
177 */
187 case EXPRTYPE:
188 /*
189 * doexpr - evaluate arithmetic
190 * expression
191 */
192 if (argc > 2)
193 pbnum(expr(argv[2]));
194 break;

--- 42 unchanged lines hidden (view full) ---

237 if (argc > 2)
238 pbnum(atoi(argv[2]) - 1);
239 break;
240
241 case SYSCTYPE:
242 /*
243 * dosys - execute system command
244 */
178 /* Make sure m4 output is NOT interrupted */
179 fflush(stdout);
180 fflush(stderr);
181 if (argc > 2)
182 sysval = system(argv[2]);
183 break;
184
185 case SYSVTYPE:
186 /*
187 * dosysval - return value of the last
188 * system call.
245 if (argc > 2)
246 sysval = system(argv[2]);
247 break;
248
249 case SYSVTYPE:
250 /*
251 * dosysval - return value of the last
252 * system call.
189 *
253 *
190 */
191 pbnum(sysval);
192 break;
193
254 */
255 pbnum(sysval);
256 break;
257
258 case ESYSCMDTYPE:
259 if (argc > 2)
260 doesyscmd(argv[2]);
261 break;
194 case INCLTYPE:
195 if (argc > 2)
196 if (!doincl(argv[2]))
262 case INCLTYPE:
263 if (argc > 2)
264 if (!doincl(argv[2]))
197 err(1, "%s", argv[2]);
265 err(1, "%s at line %lu: include(%s)",
266 CURRENT_NAME, CURRENT_LINE, argv[2]);
198 break;
199
200 case SINCTYPE:
201 if (argc > 2)
202 (void) doincl(argv[2]);
203 break;
204#ifdef EXTENDED
205 case PASTTYPE:
206 if (argc > 2)
207 if (!dopaste(argv[2]))
267 break;
268
269 case SINCTYPE:
270 if (argc > 2)
271 (void) doincl(argv[2]);
272 break;
273#ifdef EXTENDED
274 case PASTTYPE:
275 if (argc > 2)
276 if (!dopaste(argv[2]))
208 err(1, "%s", argv[2]);
277 err(1, "%s at line %lu: paste(%s)",
278 CURRENT_NAME, CURRENT_LINE, argv[2]);
209 break;
210
211 case SPASTYPE:
212 if (argc > 2)
213 (void) dopaste(argv[2]);
214 break;
215#endif
216 case CHNQTYPE:
279 break;
280
281 case SPASTYPE:
282 if (argc > 2)
283 (void) dopaste(argv[2]);
284 break;
285#endif
286 case CHNQTYPE:
217 dochq(argv, argc);
287 if (mimic_gnu)
288 gnu_dochq(argv, ac);
289 else
290 dochq(argv, argc);
218 break;
219
220 case CHNCTYPE:
291 break;
292
293 case CHNCTYPE:
221 dochc(argv, argc);
294 if (mimic_gnu)
295 gnu_dochc(argv, ac);
296 else
297 dochc(argv, argc);
222 break;
223
224 case SUBSTYPE:
225 /*
226 * dosub - select substring
298 break;
299
300 case SUBSTYPE:
301 /*
302 * dosub - select substring
227 *
303 *
228 */
229 if (argc > 3)
230 dosub(argv, argc);
231 break;
232
233 case SHIFTYPE:
234 /*
235 * doshift - push back all arguments
236 * except the first one (i.e. skip
237 * argv[2])
238 */
239 if (argc > 3) {
240 for (n = argc - 1; n > 3; n--) {
304 */
305 if (argc > 3)
306 dosub(argv, argc);
307 break;
308
309 case SHIFTYPE:
310 /*
311 * doshift - push back all arguments
312 * except the first one (i.e. skip
313 * argv[2])
314 */
315 if (argc > 3) {
316 for (n = argc - 1; n > 3; n--) {
241 putback(rquote);
317 pbstr(rquote);
242 pbstr(argv[n]);
318 pbstr(argv[n]);
243 putback(lquote);
244 putback(',');
319 pbstr(lquote);
320 putback(COMMA);
245 }
321 }
246 putback(rquote);
322 pbstr(rquote);
247 pbstr(argv[3]);
323 pbstr(argv[3]);
248 putback(lquote);
324 pbstr(lquote);
249 }
250 break;
251
252 case DIVRTYPE:
253 if (argc > 2 && (n = atoi(argv[2])) != 0)
254 dodiv(n);
255 else {
256 active = stdout;

--- 33 unchanged lines hidden (view full) ---

290 for (n = 2; n < argc; n++)
291 remhash(argv[n], TOP);
292 break;
293
294 case MKTMTYPE:
295 /*
296 * dotemp - create a temporary file
297 */
325 }
326 break;
327
328 case DIVRTYPE:
329 if (argc > 2 && (n = atoi(argv[2])) != 0)
330 dodiv(n);
331 else {
332 active = stdout;

--- 33 unchanged lines hidden (view full) ---

366 for (n = 2; n < argc; n++)
367 remhash(argv[n], TOP);
368 break;
369
370 case MKTMTYPE:
371 /*
372 * dotemp - create a temporary file
373 */
298 if (argc > 2)
299 pbstr(mktemp(argv[2]));
374 if (argc > 2) {
375 int fd;
376 char *temp;
377
378 temp = xstrdup(argv[2]);
379
380 fd = mkstemp(temp);
381 if (fd == -1)
382 err(1,
383 "%s at line %lu: couldn't make temp file %s",
384 CURRENT_NAME, CURRENT_LINE, argv[2]);
385 close(fd);
386 pbstr(temp);
387 free(temp);
388 }
300 break;
301
302 case TRNLTYPE:
303 /*
304 * dotranslit - replace all characters in
305 * the source string that appears in the
306 * "from" string with the corresponding
307 * characters in the "to" string.
308 */
309 if (argc > 3) {
389 break;
390
391 case TRNLTYPE:
392 /*
393 * dotranslit - replace all characters in
394 * the source string that appears in the
395 * "from" string with the corresponding
396 * characters in the "to" string.
397 */
398 if (argc > 3) {
310 char temp[STRSPMAX+1];
399 char *temp;
400
401 temp = xalloc(strlen(argv[2])+1);
311 if (argc > 4)
312 map(temp, argv[2], argv[3], argv[4]);
313 else
314 map(temp, argv[2], argv[3], null);
315 pbstr(temp);
402 if (argc > 4)
403 map(temp, argv[2], argv[3], argv[4]);
404 else
405 map(temp, argv[2], argv[3], null);
406 pbstr(temp);
316 }
317 else if (argc > 2)
407 free(temp);
408 } else if (argc > 2)
318 pbstr(argv[2]);
319 break;
320
321 case INDXTYPE:
322 /*
323 * doindex - find the index of the second
324 * argument string in the first argument
325 * string. -1 if not present.

--- 22 unchanged lines hidden (view full) ---

348 ;
349 break;
350
351 case M4WRTYPE:
352 /*
353 * dom4wrap - set up for
354 * wrap-up/wind-down activity
355 */
409 pbstr(argv[2]);
410 break;
411
412 case INDXTYPE:
413 /*
414 * doindex - find the index of the second
415 * argument string in the first argument
416 * string. -1 if not present.

--- 22 unchanged lines hidden (view full) ---

439 ;
440 break;
441
442 case M4WRTYPE:
443 /*
444 * dom4wrap - set up for
445 * wrap-up/wind-down activity
446 */
356 if ((p = strdup(argv[2])) == NULL)
357 err(1, "strdup");
358 m4wraps = (argc > 2) ? p : null;
447 m4wraps = (argc > 2) ? xstrdup(argv[2]) : null;
359 break;
360
361 case EXITTYPE:
362 /*
363 * doexit - immediate exit from m4.
364 */
365 killdiv();
366 exit((argc > 2) ? atoi(argv[2]) : 0);
367 break;
368
369 case DEFNTYPE:
370 if (argc > 2)
371 for (n = 2; n < argc; n++)
372 dodefn(argv[n]);
373 break;
374
448 break;
449
450 case EXITTYPE:
451 /*
452 * doexit - immediate exit from m4.
453 */
454 killdiv();
455 exit((argc > 2) ? atoi(argv[2]) : 0);
456 break;
457
458 case DEFNTYPE:
459 if (argc > 2)
460 for (n = 2; n < argc; n++)
461 dodefn(argv[n]);
462 break;
463
375 case MACRTYPE:
376 pbstr("");
464 case INDIRTYPE: /* Indirect call */
465 if (argc > 2)
466 doindir(argv, argc);
377 break;
467 break;
468
469 case BUILTINTYPE: /* Builtins only */
470 if (argc > 2)
471 dobuiltin(argv, argc);
472 break;
378
473
474 case PATSTYPE:
475 if (argc > 2)
476 dopatsubst(argv, argc);
477 break;
478 case REGEXPTYPE:
479 if (argc > 2)
480 doregexp(argv, argc);
481 break;
482 case LINETYPE:
483 doprintlineno(infile+ilevel);
484 break;
485 case FILENAMETYPE:
486 doprintfilename(infile+ilevel);
487 break;
488 case SELFTYPE:
489 pbstr(rquote);
490 pbstr(argv[1]);
491 pbstr(lquote);
492 break;
379 default:
493 default:
380 errx(1, "eval: major botch");
494 errx(1, "%s at line %lu: eval: major botch.",
495 CURRENT_NAME, CURRENT_LINE);
381 break;
382 }
383}
384
496 break;
497 }
498}
499
385const char dumpfmt[] = "`%s'\t`%s'\n"; /* format string for dumpdef */
386
387/*
500/*
388 * expand - user-defined macro expansion
501 * expand_macro - user-defined macro expansion
389 */
390void
502 */
503void
391expand(argv, argc)
392register char *argv[];
393register int argc;
504expand_macro(argv, argc)
505 const char *argv[];
506 int argc;
394{
507{
395 register unsigned char *t;
396 register unsigned char *p;
397 register int n;
398 register int argno;
508 const char *t;
509 const char *p;
510 int n;
511 int argno;
399
400 t = argv[0]; /* defn string as a whole */
401 p = t;
402 while (*p)
403 p++;
404 p--; /* last character of defn */
405 while (p > t) {
406 if (*(p - 1) != ARGFLAG)
512
513 t = argv[0]; /* defn string as a whole */
514 p = t;
515 while (*p)
516 p++;
517 p--; /* last character of defn */
518 while (p > t) {
519 if (*(p - 1) != ARGFLAG)
407 putback(*p);
520 PUTBACK(*p);
408 else {
409 switch (*p) {
410
411 case '#':
412 pbnum(argc - 2);
413 break;
414 case '0':
415 case '1':

--- 4 unchanged lines hidden (view full) ---

420 case '6':
421 case '7':
422 case '8':
423 case '9':
424 if ((argno = *p - '0') < argc - 1)
425 pbstr(argv[argno + 1]);
426 break;
427 case '*':
521 else {
522 switch (*p) {
523
524 case '#':
525 pbnum(argc - 2);
526 break;
527 case '0':
528 case '1':

--- 4 unchanged lines hidden (view full) ---

533 case '6':
534 case '7':
535 case '8':
536 case '9':
537 if ((argno = *p - '0') < argc - 1)
538 pbstr(argv[argno + 1]);
539 break;
540 case '*':
428 for (n = argc - 1; n > 2; n--) {
429 pbstr(argv[n]);
430 putback(',');
431 }
432 pbstr(argv[2]);
541 if (argc > 2) {
542 for (n = argc - 1; n > 2; n--) {
543 pbstr(argv[n]);
544 putback(COMMA);
545 }
546 pbstr(argv[2]);
547 }
433 break;
548 break;
434 case '@':
435 for( n = argc - 1; n >= 2; n-- )
436 {
437 putback(rquote);
438 pbstr(argv[n]);
439 putback(lquote);
440 if( n > 2 )
441 putback(',');
549 case '@':
550 if (argc > 2) {
551 for (n = argc - 1; n > 2; n--) {
552 pbstr(rquote);
553 pbstr(argv[n]);
554 pbstr(lquote);
555 putback(COMMA);
556 }
557 pbstr(rquote);
558 pbstr(argv[2]);
559 pbstr(lquote);
442 }
560 }
443 break;
561 break;
444 default:
562 default:
445 putback(*p);
446 putback('$');
563 PUTBACK(*p);
564 PUTBACK('$');
447 break;
448 }
449 p--;
450 }
451 p--;
452 }
453 if (p == t) /* do last character */
565 break;
566 }
567 p--;
568 }
569 p--;
570 }
571 if (p == t) /* do last character */
454 putback(*p);
572 PUTBACK(*p);
455}
456
457/*
458 * dodefine - install definition in the table
459 */
460void
461dodefine(name, defn)
573}
574
575/*
576 * dodefine - install definition in the table
577 */
578void
579dodefine(name, defn)
462register char *name;
463register char *defn;
580 const char *name;
581 const char *defn;
464{
582{
465 register ndptr p;
583 ndptr p;
584 int n;
466
467 if (!*name)
585
586 if (!*name)
468 errx(1, "null definition");
469 if (STREQ(name, defn))
470 errx(1, "%s: recursive definition", name);
587 errx(1, "%s at line %lu: null definition.", CURRENT_NAME,
588 CURRENT_LINE);
471 if ((p = lookup(name)) == nil)
472 p = addent(name);
473 else if (p->defn != null)
474 free((char *) p->defn);
589 if ((p = lookup(name)) == nil)
590 p = addent(name);
591 else if (p->defn != null)
592 free((char *) p->defn);
593 if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0) {
594 n = builtin_type(defn+sizeof(BUILTIN_MARKER)-1);
595 if (n != -1) {
596 p->type = n & TYPEMASK;
597 if ((n & NOARGS) == 0)
598 p->type |= NEEDARGS;
599 p->defn = null;
600 return;
601 }
602 }
475 if (!*defn)
476 p->defn = null;
477 else
603 if (!*defn)
604 p->defn = null;
605 else
478 if ((p->defn = strdup(defn)) == NULL)
479 err(1, "strdup");
606 p->defn = xstrdup(defn);
480 p->type = MACRTYPE;
607 p->type = MACRTYPE;
608 if (STREQ(name, defn))
609 p->type |= RECDEF;
481}
482
483/*
484 * dodefn - push back a quoted definition of
485 * the given name.
486 */
610}
611
612/*
613 * dodefn - push back a quoted definition of
614 * the given name.
615 */
487void
616static void
488dodefn(name)
617dodefn(name)
489char *name;
618 const char *name;
490{
619{
491 register ndptr p;
620 ndptr p;
621 char *real;
492
622
493 if ((p = lookup(name)) != nil && p->defn != null) {
494 putback(rquote);
495 pbstr(p->defn);
496 putback(lquote);
623 if ((p = lookup(name)) != nil) {
624 if (p->defn != null) {
625 pbstr(rquote);
626 pbstr(p->defn);
627 pbstr(lquote);
628 } else if ((real = builtin_realname(p->type)) != NULL) {
629 pbstr(real);
630 pbstr(BUILTIN_MARKER);
631 }
497 }
498}
499
500/*
501 * dopushdef - install a definition in the hash table
502 * without removing a previous definition. Since
503 * each new entry is entered in *front* of the
504 * hash bucket, it hides a previous definition from
505 * lookup.
506 */
632 }
633}
634
635/*
636 * dopushdef - install a definition in the hash table
637 * without removing a previous definition. Since
638 * each new entry is entered in *front* of the
639 * hash bucket, it hides a previous definition from
640 * lookup.
641 */
507void
642static void
508dopushdef(name, defn)
643dopushdef(name, defn)
509register char *name;
510register char *defn;
644 const char *name;
645 const char *defn;
511{
646{
512 register ndptr p;
647 ndptr p;
513
514 if (!*name)
648
649 if (!*name)
515 errx(1, "null definition");
516 if (STREQ(name, defn))
517 errx(1, "%s: recursive definition", name);
650 errx(1, "%s at line %lu: null definition", CURRENT_NAME,
651 CURRENT_LINE);
518 p = addent(name);
519 if (!*defn)
520 p->defn = null;
521 else
652 p = addent(name);
653 if (!*defn)
654 p->defn = null;
655 else
522 if ((p->defn = strdup(defn)) == NULL)
523 err(1, "strdup");
656 p->defn = xstrdup(defn);
524 p->type = MACRTYPE;
657 p->type = MACRTYPE;
658 if (STREQ(name, defn))
659 p->type |= RECDEF;
525}
526
527/*
660}
661
662/*
663 * dump_one_def - dump the specified definition.
664 */
665static void
666dump_one_def(p)
667 ndptr p;
668{
669 char *real;
670
671 if (mimic_gnu) {
672 if ((p->type & TYPEMASK) == MACRTYPE)
673 fprintf(traceout, "%s:\t%s\n", p->name, p->defn);
674 else {
675 real = builtin_realname(p->type);
676 if (real == NULL)
677 real = null;
678 fprintf(traceout, "%s:\t<%s>\n", p->name, real);
679 }
680 } else
681 fprintf(traceout, "`%s'\t`%s'\n", p->name, p->defn);
682}
683
684/*
528 * dodumpdef - dump the specified definitions in the hash
529 * table to stderr. If nothing is specified, the entire
530 * hash table is dumped.
531 */
685 * dodumpdef - dump the specified definitions in the hash
686 * table to stderr. If nothing is specified, the entire
687 * hash table is dumped.
688 */
532void
689static void
533dodump(argv, argc)
690dodump(argv, argc)
534register char *argv[];
535register int argc;
691 const char *argv[];
692 int argc;
536{
693{
537 register int n;
694 int n;
538 ndptr p;
539
540 if (argc > 2) {
541 for (n = 2; n < argc; n++)
542 if ((p = lookup(argv[n])) != nil)
695 ndptr p;
696
697 if (argc > 2) {
698 for (n = 2; n < argc; n++)
699 if ((p = lookup(argv[n])) != nil)
543 fprintf(stderr, dumpfmt, p->name,
544 p->defn);
545 }
546 else {
700 dump_one_def(p);
701 } else {
547 for (n = 0; n < HASHSIZE; n++)
548 for (p = hashtab[n]; p != nil; p = p->nxtptr)
702 for (n = 0; n < HASHSIZE; n++)
703 for (p = hashtab[n]; p != nil; p = p->nxtptr)
549 fprintf(stderr, dumpfmt, p->name,
550 p->defn);
704 dump_one_def(p);
551 }
552}
553
554/*
705 }
706}
707
708/*
709 * dotrace - mark some macros as traced/untraced depending upon on.
710 */
711static void
712dotrace(argv, argc, on)
713 const char *argv[];
714 int argc;
715 int on;
716{
717 int n;
718
719 if (argc > 2) {
720 for (n = 2; n < argc; n++)
721 mark_traced(argv[n], on);
722 } else
723 mark_traced(NULL, on);
724}
725
726/*
555 * doifelse - select one of two alternatives - loop.
556 */
727 * doifelse - select one of two alternatives - loop.
728 */
557void
729static void
558doifelse(argv, argc)
730doifelse(argv, argc)
559register char *argv[];
560register int argc;
731 const char *argv[];
732 int argc;
561{
562 cycle {
563 if (STREQ(argv[2], argv[3]))
564 pbstr(argv[4]);
565 else if (argc == 6)
566 pbstr(argv[5]);
567 else if (argc > 6) {
568 argv += 3;
569 argc -= 3;
570 continue;
571 }
572 break;
573 }
574}
575
576/*
577 * doinclude - include a given file.
578 */
733{
734 cycle {
735 if (STREQ(argv[2], argv[3]))
736 pbstr(argv[4]);
737 else if (argc == 6)
738 pbstr(argv[5]);
739 else if (argc > 6) {
740 argv += 3;
741 argc -= 3;
742 continue;
743 }
744 break;
745 }
746}
747
748/*
749 * doinclude - include a given file.
750 */
579int
751static int
580doincl(ifile)
752doincl(ifile)
581char *ifile;
753 const char *ifile;
582{
583 if (ilevel + 1 == MAXINP)
754{
755 if (ilevel + 1 == MAXINP)
584 errx(1, "too many include files");
585 if ((infile[ilevel + 1] = fopen(ifile, "r")) != NULL) {
756 errx(1, "%s at line %lu: too many include files.",
757 CURRENT_NAME, CURRENT_LINE);
758 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
586 ilevel++;
587 bbase[ilevel] = bufbase = bp;
588 return (1);
759 ilevel++;
760 bbase[ilevel] = bufbase = bp;
761 return (1);
589 }
590 else
762 } else
591 return (0);
592}
593
594#ifdef EXTENDED
595/*
596 * dopaste - include a given file without any
597 * macro processing.
598 */
763 return (0);
764}
765
766#ifdef EXTENDED
767/*
768 * dopaste - include a given file without any
769 * macro processing.
770 */
599int
771static int
600dopaste(pfile)
772dopaste(pfile)
601char *pfile;
773 const char *pfile;
602{
603 FILE *pf;
774{
775 FILE *pf;
604 register int c;
776 int c;
605
606 if ((pf = fopen(pfile, "r")) != NULL) {
607 while ((c = getc(pf)) != EOF)
608 putc(c, active);
609 (void) fclose(pf);
610 return (1);
777
778 if ((pf = fopen(pfile, "r")) != NULL) {
779 while ((c = getc(pf)) != EOF)
780 putc(c, active);
781 (void) fclose(pf);
782 return (1);
611 }
612 else
783 } else
613 return (0);
614}
615#endif
616
784 return (0);
785}
786#endif
787
788static void
789gnu_dochq(argv, ac)
790 const char *argv[];
791 int ac;
792{
793 /* In gnu-m4 mode, the only way to restore quotes is to have no
794 * arguments at all. */
795 if (ac == 2) {
796 lquote[0] = LQUOTE, lquote[1] = EOS;
797 rquote[0] = RQUOTE, rquote[1] = EOS;
798 } else {
799 strlcpy(lquote, argv[2], sizeof(lquote));
800 if(ac > 3)
801 strlcpy(rquote, argv[3], sizeof(rquote));
802 else
803 rquote[0] = EOS;
804 }
805}
806
617/*
618 * dochq - change quote characters
619 */
807/*
808 * dochq - change quote characters
809 */
620void
810static void
621dochq(argv, argc)
811dochq(argv, argc)
622register char *argv[];
623register int argc;
812 const char *argv[];
813 int argc;
624{
625 if (argc > 2) {
626 if (*argv[2])
814{
815 if (argc > 2) {
816 if (*argv[2])
627 lquote = *argv[2];
628 else
629 lquote = LQUOTE;
817 strlcpy(lquote, argv[2], sizeof(lquote));
818 else {
819 lquote[0] = LQUOTE;
820 lquote[1] = EOS;
821 }
630 if (argc > 3) {
631 if (*argv[3])
822 if (argc > 3) {
823 if (*argv[3])
632 rquote = *argv[3];
633 else
634 rquote = RQUOTE;
635 }
636 else
637 rquote = lquote;
824 strlcpy(rquote, argv[3], sizeof(rquote));
825 } else
826 strcpy(rquote, lquote);
827 } else {
828 lquote[0] = LQUOTE, lquote[1] = EOS;
829 rquote[0] = RQUOTE, rquote[1] = EOS;
638 }
830 }
639 else {
640 lquote = LQUOTE;
641 rquote = RQUOTE;
642 }
643}
644
831}
832
833static void
834gnu_dochc(argv, ac)
835 const char *argv[];
836 int ac;
837{
838 /* In gnu-m4 mode, no arguments mean no comment
839 * arguments at all. */
840 if (ac == 2) {
841 scommt[0] = EOS;
842 ecommt[0] = EOS;
843 } else {
844 if (*argv[2])
845 strlcpy(scommt, argv[2], sizeof(scommt));
846 else
847 scommt[0] = SCOMMT, scommt[1] = EOS;
848 if(ac > 3 && *argv[3])
849 strlcpy(ecommt, argv[3], sizeof(ecommt));
850 else
851 ecommt[0] = ECOMMT, ecommt[1] = EOS;
852 }
853}
645/*
646 * dochc - change comment characters
647 */
854/*
855 * dochc - change comment characters
856 */
648void
857static void
649dochc(argv, argc)
858dochc(argv, argc)
650register char *argv[];
651register int argc;
859 const char *argv[];
860 int argc;
652{
653 if (argc > 2) {
654 if (*argv[2])
861{
862 if (argc > 2) {
863 if (*argv[2])
655 scommt = *argv[2];
864 strlcpy(scommt, argv[2], sizeof(scommt));
656 if (argc > 3) {
657 if (*argv[3])
865 if (argc > 3) {
866 if (*argv[3])
658 ecommt = *argv[3];
867 strlcpy(ecommt, argv[3], sizeof(ecommt));
659 }
660 else
868 }
869 else
661 ecommt = ECOMMT;
870 ecommt[0] = ECOMMT, ecommt[1] = EOS;
662 }
663 else {
871 }
872 else {
664 scommt = SCOMMT;
665 ecommt = ECOMMT;
873 scommt[0] = SCOMMT, scommt[1] = EOS;
874 ecommt[0] = ECOMMT, ecommt[1] = EOS;
666 }
667}
668
669/*
670 * dodivert - divert the output to a temporary file
671 */
875 }
876}
877
878/*
879 * dodivert - divert the output to a temporary file
880 */
672void
881static void
673dodiv(n)
882dodiv(n)
674register int n;
883 int n;
675{
884{
885 int fd;
886
676 oindex = n;
887 oindex = n;
677 if (n < 0 || n >= MAXOUT)
888 if (n >= maxout) {
889 if (mimic_gnu)
890 resizedivs(n + 10);
891 else
892 n = 0; /* bitbucket */
893 }
894
895 if (n < 0)
678 n = 0; /* bitbucket */
679 if (outfile[n] == NULL) {
896 n = 0; /* bitbucket */
897 if (outfile[n] == NULL) {
680 m4temp[UNIQUE] = n + '0';
681 if ((outfile[n] = fopen(m4temp, "w")) == NULL)
682 errx(1, "%s: cannot divert", m4temp);
898 char fname[] = _PATH_DIVNAME;
899
900 if ((fd = mkstemp(fname)) < 0 ||
901 (outfile[n] = fdopen(fd, "w+")) == NULL)
902 err(1, "%s: cannot divert", fname);
903 if (unlink(fname) == -1)
904 err(1, "%s: cannot unlink", fname);
683 }
684 active = outfile[n];
685}
686
687/*
688 * doundivert - undivert a specified output, or all
689 * other outputs, in numerical order.
690 */
905 }
906 active = outfile[n];
907}
908
909/*
910 * doundivert - undivert a specified output, or all
911 * other outputs, in numerical order.
912 */
691void
913static void
692doundiv(argv, argc)
914doundiv(argv, argc)
693register char *argv[];
694register int argc;
915 const char *argv[];
916 int argc;
695{
917{
696 register int ind;
697 register int n;
918 int ind;
919 int n;
698
699 if (argc > 2) {
700 for (ind = 2; ind < argc; ind++) {
701 n = atoi(argv[ind]);
920
921 if (argc > 2) {
922 for (ind = 2; ind < argc; ind++) {
923 n = atoi(argv[ind]);
702 if (n > 0 && n < MAXOUT && outfile[n] != NULL)
924 if (n > 0 && n < maxout && outfile[n] != NULL)
703 getdiv(n);
704
705 }
706 }
707 else
925 getdiv(n);
926
927 }
928 }
929 else
708 for (n = 1; n < MAXOUT; n++)
930 for (n = 1; n < maxout; n++)
709 if (outfile[n] != NULL)
710 getdiv(n);
711}
712
713/*
714 * dosub - select substring
715 */
931 if (outfile[n] != NULL)
932 getdiv(n);
933}
934
935/*
936 * dosub - select substring
937 */
716void
938static void
717dosub(argv, argc)
939dosub(argv, argc)
718register char *argv[];
719register int argc;
940 const char *argv[];
941 int argc;
720{
942{
721 register unsigned char *ap, *fc, *k;
722 register int nc;
943 const char *ap, *fc, *k;
944 int nc;
723
724 ap = argv[2]; /* target string */
725#ifdef EXPR
726 fc = ap + expr(argv[3]); /* first char */
727#else
728 fc = ap + atoi(argv[3]); /* first char */
729#endif
945
946 ap = argv[2]; /* target string */
947#ifdef EXPR
948 fc = ap + expr(argv[3]); /* first char */
949#else
950 fc = ap + atoi(argv[3]); /* first char */
951#endif
730 if (argc < 5)
731 nc = strlen(fc);
732 else
952 nc = strlen(fc);
953 if (argc >= 5)
733#ifdef EXPR
954#ifdef EXPR
734 nc = expr(argv[4]);
955 nc = min(nc, expr(argv[4]));
735#else
956#else
736 nc = atoi(argv[4]);
957 nc = min(nc, atoi(argv[4]));
737#endif
738 if (fc >= ap && fc < ap + strlen(ap))
739 for (k = fc + nc - 1; k >= fc; k--)
740 putback(*k);
741}
742
743/*
744 * map:

--- 15 unchanged lines hidden (view full) ---

760 * the character value stabilizes (i.e. sch = dch, in other words
761 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
762 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
763 * end, we restore mapvec* back to normal where mapvec[n] == n for
764 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
765 * about 5 times faster than any algorithm that makes multiple passes over
766 * destination string.
767 */
958#endif
959 if (fc >= ap && fc < ap + strlen(ap))
960 for (k = fc + nc - 1; k >= fc; k--)
961 putback(*k);
962}
963
964/*
965 * map:

--- 15 unchanged lines hidden (view full) ---

981 * the character value stabilizes (i.e. sch = dch, in other words
982 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
983 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
984 * end, we restore mapvec* back to normal where mapvec[n] == n for
985 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
986 * about 5 times faster than any algorithm that makes multiple passes over
987 * destination string.
988 */
768void
989static void
769map(dest, src, from, to)
990map(dest, src, from, to)
770register char *dest;
771register char *src;
772register char *from;
773register char *to;
991 char *dest;
992 const char *src;
993 const char *from;
994 const char *to;
774{
995{
775 register char *tmp;
776 register char sch, dch;
777 static char mapvec[128] = {
778 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
779 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
780 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
781 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
782 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
783 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
784 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
785 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
786 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
787 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
788 120, 121, 122, 123, 124, 125, 126, 127
996 const char *tmp;
997 unsigned char sch, dch;
998 static char frombis[257];
999 static char tobis[257];
1000 static unsigned char mapvec[256] = {
1001 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
1002 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
1003 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
1004 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
1005 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
1006 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
1007 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
1008 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
1009 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
1010 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
1011 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
1012 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
1013 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
1014 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
1015 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
1016 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
1017 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
1018 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
789 };
790
791 if (*src) {
1019 };
1020
1021 if (*src) {
1022 if (mimic_gnu) {
1023 /*
1024 * expand character ranges on the fly
1025 */
1026 from = handledash(frombis, frombis + 256, from);
1027 to = handledash(tobis, tobis + 256, to);
1028 }
792 tmp = from;
793 /*
794 * create a mapping between "from" and
795 * "to"
796 */
797 while (*from)
1029 tmp = from;
1030 /*
1031 * create a mapping between "from" and
1032 * "to"
1033 */
1034 while (*from)
798 mapvec[*from++] = (*to) ? *to++ : (char) 0;
1035 mapvec[(unsigned char)(*from++)] = (*to) ?
1036 (unsigned char)(*to++) : 0;
799
800 while (*src) {
1037
1038 while (*src) {
801 sch = *src++;
1039 sch = (unsigned char)(*src++);
802 dch = mapvec[sch];
803 while (dch != sch) {
804 sch = dch;
805 dch = mapvec[sch];
806 }
1040 dch = mapvec[sch];
1041 while (dch != sch) {
1042 sch = dch;
1043 dch = mapvec[sch];
1044 }
807 if (*dest = dch)
1045 if ((*dest = (char)dch))
808 dest++;
809 }
810 /*
811 * restore all the changed characters
812 */
813 while (*tmp) {
1046 dest++;
1047 }
1048 /*
1049 * restore all the changed characters
1050 */
1051 while (*tmp) {
814 mapvec[*tmp] = *tmp;
1052 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp);
815 tmp++;
816 }
817 }
1053 tmp++;
1054 }
1055 }
818 *dest = (char) 0;
1056 *dest = '\0';
819}
1057}
1058
1059
1060/*
1061 * handledash:
1062 * use buffer to copy the src string, expanding character ranges
1063 * on the way.
1064 */
1065static const char *
1066handledash(buffer, end, src)
1067 char *buffer;
1068 char *end;
1069 const char *src;
1070{
1071 char *p;
1072
1073 p = buffer;
1074 while(*src) {
1075 if (src[1] == '-' && src[2]) {
1076 unsigned char i;
1077 for (i = (unsigned char)src[0];
1078 i <= (unsigned char)src[2]; i++) {
1079 *p++ = i;
1080 if (p == end) {
1081 *p = '\0';
1082 return buffer;
1083 }
1084 }
1085 src += 3;
1086 } else
1087 *p++ = *src++;
1088 if (p == end)
1089 break;
1090 }
1091 *p = '\0';
1092 return buffer;
1093}
1094