1 /* $OpenBSD: eval.c,v 1.76 2017/10/23 15:21:19 espie 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);
204 doifelse(argv, argc);
209 * doifdef - select one of two
210 * alternatives based on the existence of
214 if (lookup_macro_definition(argv[2]) != NULL)
223 * dolen - find the length of the
226 pbnum((argc > 2) ? strlen(argv[2]) : 0);
231 * doincr - increment the value of the
235 pbnum(atoi(argv[2]) + 1);
240 * dodecr - decrement the value of the
244 pbnum(atoi(argv[2]) - 1);
249 * dosys - execute system command
253 sysval = system(argv[2]);
259 * dosysval - return value of the last
272 if (!doincl(argv[2])) {
274 warn("%s at line %lu: include(%s)",
275 CURRENT_NAME, CURRENT_LINE, argv[2]);
282 err(1, "%s at line %lu: include(%s)",
283 CURRENT_NAME, CURRENT_LINE, argv[2]);
290 (void) doincl(argv[2]);
295 if (!dopaste(argv[2]))
296 err(1, "%s at line %lu: paste(%s)",
297 CURRENT_NAME, CURRENT_LINE, argv[2]);
302 (void) dopaste(argv[2]);
305 doformat(argv, argc);
318 * dosub - select substring
327 * doshift - push back all arguments
328 * except the first one (i.e. skip
332 for (n = argc - 1; n > 3; n--) {
345 if (argc > 2 && (n = atoi(argv[2])) != 0)
359 * dodivnum - return the number of
360 * current output diversion
367 * doundefine - undefine a previously
368 * defined macro(s) or m4 keyword(s).
371 for (n = 2; n < argc; n++)
372 macro_undefine(argv[n]);
377 * dopopdef - remove the topmost
378 * definitions of macro(s) or m4
382 for (n = 2; n < argc; n++)
383 macro_popdef(argv[n]);
388 * dotemp - create a temporary file
394 temp = xstrdup(argv[2]);
399 "%s at line %lu: couldn't make temp file %s",
400 CURRENT_NAME, CURRENT_LINE, argv[2]);
409 * dotranslit - replace all characters in
410 * the source string that appears in the
411 * "from" string with the corresponding
412 * characters in the "to" string.
417 temp = xalloc(strlen(argv[2])+1, NULL);
419 map(temp, argv[2], argv[3], argv[4]);
421 map(temp, argv[2], argv[3], null);
430 * doindex - find the index of the second
431 * argument string in the first argument
432 * string. -1 if not present.
434 pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
439 * doerrp - print the arguments to stderr
443 for (n = 2; n < argc; n++)
444 fprintf(stderr, "%s ", argv[n]);
445 fprintf(stderr, "\n");
451 * dodnl - eat-up-to and including
454 while ((c = gpbc()) != '\n' && c != EOF)
460 * dom4wrap - set up for
461 * wrap-up/wind-down activity
469 * doexit - immediate exit from m4.
472 exit((argc > 2) ? atoi(argv[2]) : 0);
477 for (n = 2; n < argc; n++)
481 case INDIRTYPE: /* Indirect call */
486 case BUILTINTYPE: /* Builtins only */
488 dobuiltin(argv, argc);
493 dopatsubst(argv, argc);
497 doregexp(argv, argc);
500 doprintlineno(infile+ilevel);
503 doprintfilename(infile+ilevel);
511 m4errx(1, "eval: major botch.");
517 * expand_macro - user-defined macro expansion
520 expand_macro(const char *argv[], int argc)
527 t = argv[0]; /* defn string as a whole */
531 p--; /* last character of defn */
533 if (*(p - 1) != ARGFLAG)
551 if ((argno = *p - '0') < argc - 1)
552 pbstr(argv[argno + 1]);
556 for (n = argc - 1; n > 2; n--) {
565 for (n = argc - 1; n > 2; n--) {
585 if (p == t) /* do last character */
591 * dodefine - install definition in the table
594 dodefine(const char *name, const char *defn)
596 if (!*name && !mimic_gnu)
597 m4errx(1, "null definition.");
599 macro_define(name, defn);
603 * dodefn - push back a quoted definition of
607 dodefn(const char *name)
609 struct macro_definition *p;
611 if ((p = lookup_macro_definition(name)) != NULL) {
612 if ((p->type & TYPEMASK) == MACRTYPE) {
618 pbstr(BUILTIN_MARKER);
624 * dopushdef - install a definition in the hash table
625 * without removing a previous definition. Since
626 * each new entry is entered in *front* of the
627 * hash bucket, it hides a previous definition from
631 dopushdef(const char *name, const char *defn)
633 if (!*name && !mimic_gnu)
634 m4errx(1, "null definition.");
636 macro_pushdef(name, defn);
640 * dump_one_def - dump the specified definition.
643 dump_one_def(const char *name, struct macro_definition *p)
648 if ((p->type & TYPEMASK) == MACRTYPE)
649 fprintf(traceout, "%s:\t%s\n", name, p->defn);
651 fprintf(traceout, "%s:\t<%s>\n", name, p->defn);
654 fprintf(traceout, "`%s'\t`%s'\n", name, p->defn);
658 * dodumpdef - dump the specified definitions in the hash
659 * table to stderr. If nothing is specified, the entire
660 * hash table is dumped.
663 dodump(const char *argv[], int argc)
666 struct macro_definition *p;
669 for (n = 2; n < argc; n++)
670 if ((p = lookup_macro_definition(argv[n])) != NULL)
671 dump_one_def(argv[n], p);
673 macro_for_all(dump_one_def);
677 * dotrace - mark some macros as traced/untraced depending upon on.
680 dotrace(const char *argv[], int argc, int on)
685 for (n = 2; n < argc; n++)
686 mark_traced(argv[n], on);
688 mark_traced(NULL, on);
692 * doifelse - select one of two alternatives - loop.
695 doifelse(const char *argv[], int argc)
698 if (STREQ(argv[2], argv[3])) {
701 } else if (argc == 6) {
712 * doinclude - include a given file.
715 doincl(const char *ifile)
717 if (ilevel + 1 == MAXINP)
718 m4errx(1, "too many include files.");
719 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
721 bbase[ilevel] = bufbase = bp;
729 * dopaste - include a given file without any
733 dopaste(const char *pfile)
738 if ((pf = fopen(pfile, "r")) != NULL) {
740 fprintf(active, "#line 1 \"%s\"\n", pfile);
741 while ((c = getc(pf)) != EOF)
752 * dochq - change quote characters
755 dochq(const char *argv[], int ac)
758 lquote[0] = LQUOTE; lquote[1] = EOS;
759 rquote[0] = RQUOTE; rquote[1] = EOS;
761 strlcpy(lquote, argv[2], sizeof(lquote));
763 strlcpy(rquote, argv[3], sizeof(rquote));
765 rquote[0] = ECOMMT; rquote[1] = EOS;
771 * dochc - change comment characters
774 dochc(const char *argv[], int argc)
776 /* XXX Note that there is no difference between no argument and a single
783 strlcpy(scommt, argv[2], sizeof(scommt));
785 ecommt[0] = ECOMMT; ecommt[1] = EOS;
787 strlcpy(ecommt, argv[3], sizeof(ecommt));
793 * dom4wrap - expand text at EOF
796 dom4wrap(const char *text)
798 if (wrapindex >= maxwraps) {
803 m4wraps = xreallocarray(m4wraps, maxwraps, sizeof(*m4wraps),
806 m4wraps[wrapindex++] = xstrdup(text);
810 * dodivert - divert the output to a temporary file
822 n = 0; /* bitbucket */
826 n = 0; /* bitbucket */
827 if (outfile[n] == NULL) {
828 char fname[] = _PATH_DIVNAME;
830 if ((fd = mkstemp(fname)) < 0 ||
831 unlink(fname) == -1 ||
832 (outfile[n] = fdopen(fd, "w+")) == NULL)
833 err(1, "%s: cannot divert", fname);
839 * doundivert - undivert a specified output, or all
840 * other outputs, in numerical order.
843 doundiv(const char *argv[], int argc)
849 for (ind = 2; ind < argc; ind++) {
851 n = strtonum(argv[ind], 1, INT_MAX, &errstr);
853 if (errno == EINVAL && mimic_gnu)
854 getdivfile(argv[ind]);
856 if (n < maxout && outfile[n] != NULL)
862 for (n = 1; n < maxout; n++)
863 if (outfile[n] != NULL)
868 * dosub - select substring
871 dosub(const char *argv[], int argc)
873 const char *ap, *fc, *k;
876 ap = argv[2]; /* target string */
878 fc = ap + expr(argv[3]); /* first char */
880 fc = ap + atoi(argv[3]); /* first char */
885 nc = min(nc, expr(argv[4]));
887 nc = min(nc, atoi(argv[4]));
889 if (fc >= ap && fc < ap + strlen(ap))
890 for (k = fc + nc - 1; k >= fc; k--)
896 * map every character of s1 that is specified in from
897 * into s3 and replace in s. (source s1 remains untouched)
899 * This is derived from the a standard implementation of map(s,from,to)
900 * function of ICON language. Within mapvec, we replace every character
901 * of "from" with the corresponding character in "to".
902 * If "to" is shorter than "from", than the corresponding entries are null,
903 * which means that those characters disappear altogether.
906 map(char *dest, const char *src, const char *from, const char *to)
909 unsigned char sch, dch;
910 static char frombis[257];
911 static char tobis[257];
914 static unsigned char mapvec[256] = {
915 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
916 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
917 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
918 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
919 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
920 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
921 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
922 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
923 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
924 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
925 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
926 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
927 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
928 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
929 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
930 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
931 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
932 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
938 * expand character ranges on the fly
940 from = handledash(frombis, frombis + 256, from);
941 to = handledash(tobis, tobis + 256, to);
945 * create a mapping between "from" and
948 for (i = 0; i < 256; i++)
951 if (!seen[(unsigned char)(*from)]) {
952 mapvec[(unsigned char)(*from)] = (unsigned char)(*to);
953 seen[(unsigned char)(*from)] = 1;
961 sch = (unsigned char)(*src++);
963 if ((*dest = (char)dch))
967 * restore all the changed characters
970 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp);
980 * use buffer to copy the src string, expanding character ranges
984 handledash(char *buffer, char *end, const char *src)
990 if (src[1] == '-' && src[2]) {
992 if ((unsigned char)src[0] <= (unsigned char)src[2]) {
993 for (i = (unsigned char)src[0];
994 i <= (unsigned char)src[2]; i++) {
1002 for (i = (unsigned char)src[0];
1003 i >= (unsigned char)src[2]; i--) {