Deleted Added
full compact
eval.c (94957) eval.c (95060)
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

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

29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
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
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

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

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

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

234 if (argc > 2)
235 pbnum(atoi(argv[2]) - 1);
236 break;
237
238 case SYSCTYPE:
239 /*
240 * dosys - execute system command
241 */
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.
242 if (argc > 2)
243 sysval = system(argv[2]);
244 break;
245
246 case SYSVTYPE:
247 /*
248 * dosysval - return value of the last
249 * system call.
189 *
250 *
190 */
191 pbnum(sysval);
192 break;
193
251 */
252 pbnum(sysval);
253 break;
254
255 case ESYSCMDTYPE:
256 if (argc > 2)
257 doesyscmd(argv[2]);
258 break;
194 case INCLTYPE:
195 if (argc > 2)
196 if (!doincl(argv[2]))
259 case INCLTYPE:
260 if (argc > 2)
261 if (!doincl(argv[2]))
197 err(1, "%s", argv[2]);
262 err(1, "%s at line %lu: include(%s)",
263 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]))
264 break;
265
266 case SINCTYPE:
267 if (argc > 2)
268 (void) doincl(argv[2]);
269 break;
270#ifdef EXTENDED
271 case PASTTYPE:
272 if (argc > 2)
273 if (!dopaste(argv[2]))
208 err(1, "%s", argv[2]);
274 err(1, "%s at line %lu: paste(%s)",
275 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:
276 break;
277
278 case SPASTYPE:
279 if (argc > 2)
280 (void) dopaste(argv[2]);
281 break;
282#endif
283 case CHNQTYPE:
217 dochq(argv, argc);
284 if (mimic_gnu)
285 gnu_dochq(argv, ac);
286 else
287 dochq(argv, argc);
218 break;
219
220 case CHNCTYPE:
288 break;
289
290 case CHNCTYPE:
221 dochc(argv, argc);
291 if (mimic_gnu)
292 gnu_dochc(argv, ac);
293 else
294 dochc(argv, argc);
222 break;
223
224 case SUBSTYPE:
225 /*
226 * dosub - select substring
295 break;
296
297 case SUBSTYPE:
298 /*
299 * dosub - select substring
227 *
300 *
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--) {
301 */
302 if (argc > 3)
303 dosub(argv, argc);
304 break;
305
306 case SHIFTYPE:
307 /*
308 * doshift - push back all arguments
309 * except the first one (i.e. skip
310 * argv[2])
311 */
312 if (argc > 3) {
313 for (n = argc - 1; n > 3; n--) {
241 putback(rquote);
314 pbstr(rquote);
242 pbstr(argv[n]);
315 pbstr(argv[n]);
243 putback(lquote);
244 putback(',');
316 pbstr(lquote);
317 putback(COMMA);
245 }
318 }
246 putback(rquote);
319 pbstr(rquote);
247 pbstr(argv[3]);
320 pbstr(argv[3]);
248 putback(lquote);
321 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 */
322 }
323 break;
324
325 case DIVRTYPE:
326 if (argc > 2 && (n = atoi(argv[2])) != 0)
327 dodiv(n);
328 else {
329 active = stdout;

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

363 for (n = 2; n < argc; n++)
364 remhash(argv[n], TOP);
365 break;
366
367 case MKTMTYPE:
368 /*
369 * dotemp - create a temporary file
370 */
298 if (argc > 2)
299 pbstr(mktemp(argv[2]));
371 if (argc > 2) {
372 int fd;
373 char *temp;
374
375 temp = xstrdup(argv[2]);
376
377 fd = mkstemp(temp);
378 if (fd == -1)
379 err(1,
380 "%s at line %lu: couldn't make temp file %s",
381 CURRENT_NAME, CURRENT_LINE, argv[2]);
382 close(fd);
383 pbstr(temp);
384 free(temp);
385 }
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) {
386 break;
387
388 case TRNLTYPE:
389 /*
390 * dotranslit - replace all characters in
391 * the source string that appears in the
392 * "from" string with the corresponding
393 * characters in the "to" string.
394 */
395 if (argc > 3) {
310 char temp[STRSPMAX+1];
396 char *temp;
397
398 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);
399 if (argc > 4)
400 map(temp, argv[2], argv[3], argv[4]);
401 else
402 map(temp, argv[2], argv[3], null);
403 pbstr(temp);
316 }
317 else if (argc > 2)
404 free(temp);
405 } 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 */
406 pbstr(argv[2]);
407 break;
408
409 case INDXTYPE:
410 /*
411 * doindex - find the index of the second
412 * argument string in the first argument
413 * string. -1 if not present.

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

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

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

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

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

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

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

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