1 /* $OpenBSD: eval.c,v 1.74 2015/02/05 12:59:57 millert Exp $ */
2 /* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */
5 * SPDX-License-Identifier: BSD-3-Clause
7 * Copyright (c) 1989, 1993
8 * The Regents of the University of California. All rights reserved.
10 * This code is derived from software contributed to Berkeley by
11 * Ozan Yigit at York University.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
44 * Facility: m4 macro processor
48 #include <sys/types.h>
62 #include "pathnames.h"
64 static void dodefn(const char *);
65 static void dopushdef(const char *, const char *);
66 static void dodump(const char *[], int);
67 static void dotrace(const char *[], int, int);
68 static void doifelse(const char *[], int);
69 static int doincl(const char *);
70 static int dopaste(const char *);
71 static void dochq(const char *[], int);
72 static void dochc(const char *[], int);
73 static void dom4wrap(const char *);
74 static void dodiv(int);
75 static void doundiv(const char *[], int);
76 static void dosub(const char *[], int);
77 static void map(char *, const char *, const char *, const char *);
78 static const char *handledash(char *, char *, const char *);
79 static void expand_builtin(const char *[], int, int);
80 static void expand_macro(const char *[], int);
81 static void dump_one_def(const char *, struct macro_definition *);
83 unsigned long expansion_id;
86 * eval - eval all macros and builtins calls
87 * argc - number of elements in argv.
88 * argv - element vector :
89 * argv[0] = definition of a user
90 * macro or NULL if built-in.
91 * argv[1] = name of the macro or
93 * argv[2] = parameters to user-defined
94 * . macro or built-in.
97 * A call in the form of macro-or-builtin() will result in:
99 * argv[1] = macro-or-builtin
102 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
105 eval(const char *argv[], int argc, int td, int is_traced)
107 size_t mark = SIZE_MAX;
111 m4errx(1, "expanding recursive definition for %s.", argv[1]);
113 mark = trace(argv, argc, infile+ilevel);
115 expand_macro(argv, argc);
117 expand_builtin(argv, argc, td);
118 if (mark != SIZE_MAX)
123 * expand_builtin - evaluate built-in macros.
126 expand_builtin(const char *argv[], int argc, int td)
130 static int sysval = 0;
133 printf("argc = %d\n", argc);
134 for (n = 0; n < argc; n++)
135 printf("argv[%d] = %s\n", n, argv[n]);
140 * if argc == 3 and argv[2] is null, then we
141 * have macro-or-builtin() type call. We adjust
142 * argc to avoid further checking..
144 /* we keep the initial value for those built-ins that differentiate
145 * between builtin() and builtin.
149 if (argc == 3 && !*(argv[2]) && !mimic_gnu)
152 switch (td & TYPEMASK) {
156 dodefine(argv[2], (argc > 3) ? argv[3] : null);
161 dopushdef(argv[2], (argc > 3) ? argv[3] : null);
169 dotrace(argv, argc, 1);
173 dotrace(argv, argc, 0);
178 * doexpr - evaluate arithmetic
187 base = strtonum(argv[3], 2, 36, &errstr);
189 m4errx(1, "expr: base %s invalid.", argv[3]);
193 maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
195 m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
199 pbnumbase(expr(argv[2]), base, maxdigits);
205 doifelse(argv, argc);
210 * doifdef - select one of two
211 * alternatives based on the existence of
215 if (lookup_macro_definition(argv[2]) != NULL)
224 * dolen - find the length of the
227 pbnum((argc > 2) ? strlen(argv[2]) : 0);
232 * doincr - increment the value of the
236 pbnum(atoi(argv[2]) + 1);
241 * dodecr - decrement the value of the
245 pbnum(atoi(argv[2]) - 1);
250 * dosys - execute system command
254 sysval = system(argv[2]);
260 * dosysval - return value of the last
273 if (!doincl(argv[2])) {
275 warn("%s at line %lu: include(%s)",
276 CURRENT_NAME, CURRENT_LINE, argv[2]);
279 err(1, "%s at line %lu: include(%s)",
280 CURRENT_NAME, CURRENT_LINE, argv[2]);
287 (void) doincl(argv[2]);
292 if (!dopaste(argv[2]))
293 err(1, "%s at line %lu: paste(%s)",
294 CURRENT_NAME, CURRENT_LINE, argv[2]);
299 (void) dopaste(argv[2]);
302 doformat(argv, argc);
315 * dosub - select substring
324 * doshift - push back all arguments
325 * except the first one (i.e. skip
329 for (n = argc - 1; n > 3; n--) {
342 if (argc > 2 && (n = atoi(argv[2])) != 0)
356 * dodivnum - return the number of
357 * current output diversion
364 * doundefine - undefine a previously
365 * defined macro(s) or m4 keyword(s).
368 for (n = 2; n < argc; n++)
369 macro_undefine(argv[n]);
374 * dopopdef - remove the topmost
375 * definitions of macro(s) or m4
379 for (n = 2; n < argc; n++)
380 macro_popdef(argv[n]);
385 * dotemp - create a temporary file
391 temp = xstrdup(argv[2]);
396 "%s at line %lu: couldn't make temp file %s",
397 CURRENT_NAME, CURRENT_LINE, argv[2]);
406 * dotranslit - replace all characters in
407 * the source string that appears in the
408 * "from" string with the corresponding
409 * characters in the "to" string.
414 temp = xalloc(strlen(argv[2])+1, NULL);
416 map(temp, argv[2], argv[3], argv[4]);
418 map(temp, argv[2], argv[3], null);
427 * doindex - find the index of the second
428 * argument string in the first argument
429 * string. -1 if not present.
431 pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
436 * doerrp - print the arguments to stderr
440 for (n = 2; n < argc; n++)
441 fprintf(stderr, "%s ", argv[n]);
442 fprintf(stderr, "\n");
448 * dodnl - eat-up-to and including
451 while ((c = gpbc()) != '\n' && c != EOF)
457 * dom4wrap - set up for
458 * wrap-up/wind-down activity
466 * doexit - immediate exit from m4.
469 exit((argc > 2) ? atoi(argv[2]) : 0);
474 for (n = 2; n < argc; n++)
478 case INDIRTYPE: /* Indirect call */
483 case BUILTINTYPE: /* Builtins only */
485 dobuiltin(argv, argc);
490 dopatsubst(argv, argc);
494 doregexp(argv, argc);
497 doprintlineno(infile+ilevel);
500 doprintfilename(infile+ilevel);
508 m4errx(1, "eval: major botch.");
514 * expand_macro - user-defined macro expansion
517 expand_macro(const char *argv[], int argc)
524 t = argv[0]; /* defn string as a whole */
528 p--; /* last character of defn */
530 if (*(p - 1) != ARGFLAG)
548 if ((argno = *p - '0') < argc - 1)
549 pbstr(argv[argno + 1]);
553 for (n = argc - 1; n > 2; n--) {
562 for (n = argc - 1; n > 2; n--) {
582 if (p == t) /* do last character */
588 * dodefine - install definition in the table
591 dodefine(const char *name, const char *defn)
593 if (!*name && !mimic_gnu)
594 m4errx(1, "null definition.");
596 macro_define(name, defn);
600 * dodefn - push back a quoted definition of
604 dodefn(const char *name)
606 struct macro_definition *p;
608 if ((p = lookup_macro_definition(name)) != NULL) {
609 if ((p->type & TYPEMASK) == MACRTYPE) {
615 pbstr(BUILTIN_MARKER);
621 * dopushdef - install a definition in the hash table
622 * without removing a previous definition. Since
623 * each new entry is entered in *front* of the
624 * hash bucket, it hides a previous definition from
628 dopushdef(const char *name, const char *defn)
630 if (!*name && !mimic_gnu)
631 m4errx(1, "null definition.");
633 macro_pushdef(name, defn);
637 * dump_one_def - dump the specified definition.
640 dump_one_def(const char *name, struct macro_definition *p)
645 if ((p->type & TYPEMASK) == MACRTYPE)
646 fprintf(traceout, "%s:\t%s\n", name, p->defn);
648 fprintf(traceout, "%s:\t<%s>\n", name, p->defn);
651 fprintf(traceout, "`%s'\t`%s'\n", name, p->defn);
655 * dodumpdef - dump the specified definitions in the hash
656 * table to stderr. If nothing is specified, the entire
657 * hash table is dumped.
660 dodump(const char *argv[], int argc)
663 struct macro_definition *p;
666 for (n = 2; n < argc; n++)
667 if ((p = lookup_macro_definition(argv[n])) != NULL)
668 dump_one_def(argv[n], p);
670 macro_for_all(dump_one_def);
674 * dotrace - mark some macros as traced/untraced depending upon on.
677 dotrace(const char *argv[], int argc, int on)
682 for (n = 2; n < argc; n++)
683 mark_traced(argv[n], on);
685 mark_traced(NULL, on);
689 * doifelse - select one of two alternatives - loop.
692 doifelse(const char *argv[], int argc)
695 if (STREQ(argv[2], argv[3]))
709 * doinclude - include a given file.
712 doincl(const char *ifile)
714 if (ilevel + 1 == MAXINP)
715 m4errx(1, "too many include files.");
716 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
718 bbase[ilevel] = bufbase = bp;
726 * dopaste - include a given file without any
730 dopaste(const char *pfile)
735 if ((pf = fopen(pfile, "r")) != NULL) {
737 fprintf(active, "#line 1 \"%s\"\n", pfile);
738 while ((c = getc(pf)) != EOF)
749 * dochq - change quote characters
752 dochq(const char *argv[], int ac)
755 lquote[0] = LQUOTE; lquote[1] = EOS;
756 rquote[0] = RQUOTE; rquote[1] = EOS;
758 strlcpy(lquote, argv[2], sizeof(lquote));
760 strlcpy(rquote, argv[3], sizeof(rquote));
762 rquote[0] = ECOMMT; rquote[1] = EOS;
768 * dochc - change comment characters
771 dochc(const char *argv[], int argc)
773 /* XXX Note that there is no difference between no argument and a single
780 strlcpy(scommt, argv[2], sizeof(scommt));
782 ecommt[0] = ECOMMT; ecommt[1] = EOS;
784 strlcpy(ecommt, argv[3], sizeof(ecommt));
790 * dom4wrap - expand text at EOF
793 dom4wrap(const char *text)
795 if (wrapindex >= maxwraps) {
800 m4wraps = xreallocarray(m4wraps, maxwraps, sizeof(*m4wraps),
803 m4wraps[wrapindex++] = xstrdup(text);
807 * dodivert - divert the output to a temporary file
819 n = 0; /* bitbucket */
823 n = 0; /* bitbucket */
824 if (outfile[n] == NULL) {
825 char fname[] = _PATH_DIVNAME;
827 if ((fd = mkstemp(fname)) < 0 ||
828 unlink(fname) == -1 ||
829 (outfile[n] = fdopen(fd, "w+")) == NULL)
830 err(1, "%s: cannot divert", fname);
836 * doundivert - undivert a specified output, or all
837 * other outputs, in numerical order.
840 doundiv(const char *argv[], int argc)
846 for (ind = 2; ind < argc; ind++) {
848 n = strtonum(argv[ind], 1, INT_MAX, &errstr);
850 if (errno == EINVAL && mimic_gnu)
851 getdivfile(argv[ind]);
853 if (n < maxout && outfile[n] != NULL)
859 for (n = 1; n < maxout; n++)
860 if (outfile[n] != NULL)
865 * dosub - select substring
868 dosub(const char *argv[], int argc)
870 const char *ap, *fc, *k;
873 ap = argv[2]; /* target string */
875 fc = ap + expr(argv[3]); /* first char */
877 fc = ap + atoi(argv[3]); /* first char */
882 nc = min(nc, expr(argv[4]));
884 nc = min(nc, atoi(argv[4]));
886 if (fc >= ap && fc < ap + strlen(ap))
887 for (k = fc + nc - 1; k >= fc; k--)
893 * map every character of s1 that is specified in from
894 * into s3 and replace in s. (source s1 remains untouched)
896 * This is derived from the a standard implementation of map(s,from,to)
897 * function of ICON language. Within mapvec, we replace every character
898 * of "from" with the corresponding character in "to".
899 * If "to" is shorter than "from", than the corresponding entries are null,
900 * which means that those characters disappear altogether.
903 map(char *dest, const char *src, const char *from, const char *to)
906 unsigned char sch, dch;
907 static char frombis[257];
908 static char tobis[257];
911 static unsigned char mapvec[256] = {
912 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
913 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
914 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
915 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
916 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
917 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
918 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
919 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
920 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
921 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
922 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
923 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
924 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
925 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
926 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
927 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
928 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
929 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
935 * expand character ranges on the fly
937 from = handledash(frombis, frombis + 256, from);
938 to = handledash(tobis, tobis + 256, to);
942 * create a mapping between "from" and
945 for (i = 0; i < 256; i++)
948 if (!seen[(unsigned char)(*from)]) {
949 mapvec[(unsigned char)(*from)] = (unsigned char)(*to);
950 seen[(unsigned char)(*from)] = 1;
958 sch = (unsigned char)(*src++);
960 if ((*dest = (char)dch))
964 * restore all the changed characters
967 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp);
977 * use buffer to copy the src string, expanding character ranges
981 handledash(char *buffer, char *end, const char *src)
987 if (src[1] == '-' && src[2]) {
989 if ((unsigned char)src[0] <= (unsigned char)src[2]) {
990 for (i = (unsigned char)src[0];
991 i <= (unsigned char)src[2]; i++) {
999 for (i = (unsigned char)src[0];
1000 i >= (unsigned char)src[2]; i--) {