1 /* $OpenBSD: eval.c,v 1.44 2002/04/26 16:15:16 espie Exp $ */
2 /* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */
5 * Copyright (c) 1989, 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Ozan Yigit at York University.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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
42 static char sccsid[] = "@(#)eval.c 8.2 (Berkeley) 4/27/95";
45 static char rcsid[] = "$OpenBSD: eval.c,v 1.44 2002/04/26 16:15:16 espie Exp $";
50 #include <sys/cdefs.h>
51 __FBSDID("$FreeBSD$");
55 * Facility: m4 macro processor
59 #include <sys/types.h>
71 #include "pathnames.h"
73 #define BUILTIN_MARKER "__builtin_"
75 static void dodefn(const char *);
76 static void dopushdef(const char *, const char *);
77 static void dodump(const char *[], int);
78 static void dotrace(const char *[], int, int);
79 static void doifelse(const char *[], int);
80 static int doincl(const char *);
81 static int dopaste(const char *);
82 static void gnu_dochq(const char *[], int);
83 static void dochq(const char *[], int);
84 static void gnu_dochc(const char *[], int);
85 static void dochc(const char *[], int);
86 static void dodiv(int);
87 static void doundiv(const char *[], int);
88 static void dosub(const char *[], int);
89 static void map(char *, const char *, const char *, const char *);
90 static const char *handledash(char *, char *, const char *);
91 static void expand_builtin(const char *[], int, int);
92 static void expand_macro(const char *[], int);
93 static void dump_one_def(ndptr);
95 unsigned long expansion_id;
98 * eval - eval all macros and builtins calls
99 * argc - number of elements in argv.
100 * argv - element vector :
101 * argv[0] = definition of a user
102 * macro or nil if built-in.
103 * argv[1] = name of the macro or
105 * argv[2] = parameters to user-defined
106 * . macro or built-in.
109 * A call in the form of macro-or-builtin() will result in:
111 * argv[1] = macro-or-builtin
114 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
117 eval(const char *argv[], int argc, int td)
123 errx(1, "%s at line %lu: expanding recursive definition for %s",
124 CURRENT_NAME, CURRENT_LINE, argv[1]);
125 if (traced_macros && is_traced(argv[1]))
126 mark = trace(argv, argc, infile+ilevel);
128 expand_macro(argv, argc);
130 expand_builtin(argv, argc, td);
136 * expand_builtin - evaluate built-in macros.
139 expand_builtin(const char *argv[], int argc, int td)
143 static int sysval = 0;
146 printf("argc = %d\n", argc);
147 for (n = 0; n < argc; n++)
148 printf("argv[%d] = %s\n", n, argv[n]);
153 * if argc == 3 and argv[2] is null, then we
154 * have macro-or-builtin() type call. We adjust
155 * argc to avoid further checking..
159 if (argc == 3 && !*(argv[2]))
162 switch (td & TYPEMASK) {
166 dodefine(argv[2], (argc > 3) ? argv[3] : null);
171 dopushdef(argv[2], (argc > 3) ? argv[3] : null);
179 dotrace(argv, argc, 1);
183 dotrace(argv, argc, 0);
188 * doexpr - evaluate arithmetic
192 pbnum(expr(argv[2]));
197 doifelse(argv, argc);
202 * doifdef - select one of two
203 * alternatives based on the existence of
207 if (lookup(argv[2]) != nil)
216 * dolen - find the length of the
219 pbnum((argc > 2) ? strlen(argv[2]) : 0);
224 * doincr - increment the value of the
228 pbnum(atoi(argv[2]) + 1);
233 * dodecr - decrement the value of the
237 pbnum(atoi(argv[2]) - 1);
242 * dosys - execute system command
246 sysval = system(argv[2]);
252 * dosysval - return value of the last
265 if (!doincl(argv[2]))
266 err(1, "%s at line %lu: include(%s)",
267 CURRENT_NAME, CURRENT_LINE, argv[2]);
272 (void) doincl(argv[2]);
277 if (!dopaste(argv[2]))
278 err(1, "%s at line %lu: paste(%s)",
279 CURRENT_NAME, CURRENT_LINE, argv[2]);
284 (void) dopaste(argv[2]);
303 * dosub - select substring
312 * doshift - push back all arguments
313 * except the first one (i.e. skip
317 for (n = argc - 1; n > 3; n--) {
330 if (argc > 2 && (n = atoi(argv[2])) != 0)
344 * dodivnum - return the number of
345 * current output diversion
352 * doundefine - undefine a previously
353 * defined macro(s) or m4 keyword(s).
356 for (n = 2; n < argc; n++)
357 remhash(argv[n], ALL);
362 * dopopdef - remove the topmost
363 * definitions of macro(s) or m4
367 for (n = 2; n < argc; n++)
368 remhash(argv[n], TOP);
373 * dotemp - create a temporary file
379 temp = xstrdup(argv[2]);
384 "%s at line %lu: couldn't make temp file %s",
385 CURRENT_NAME, CURRENT_LINE, argv[2]);
394 * dotranslit - replace all characters in
395 * the source string that appears in the
396 * "from" string with the corresponding
397 * characters in the "to" string.
402 temp = xalloc(strlen(argv[2])+1);
404 map(temp, argv[2], argv[3], argv[4]);
406 map(temp, argv[2], argv[3], null);
415 * doindex - find the index of the second
416 * argument string in the first argument
417 * string. -1 if not present.
419 pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
424 * doerrp - print the arguments to stderr
428 for (n = 2; n < argc; n++)
429 fprintf(stderr, "%s ", argv[n]);
430 fprintf(stderr, "\n");
436 * dodnl - eat-up-to and including
439 while ((c = gpbc()) != '\n' && c != EOF)
445 * dom4wrap - set up for
446 * wrap-up/wind-down activity
448 m4wraps = (argc > 2) ? xstrdup(argv[2]) : null;
453 * doexit - immediate exit from m4.
456 exit((argc > 2) ? atoi(argv[2]) : 0);
461 for (n = 2; n < argc; n++)
465 case INDIRTYPE: /* Indirect call */
470 case BUILTINTYPE: /* Builtins only */
472 dobuiltin(argv, argc);
477 dopatsubst(argv, argc);
481 doregexp(argv, argc);
484 doprintlineno(infile+ilevel);
487 doprintfilename(infile+ilevel);
495 errx(1, "%s at line %lu: eval: major botch.",
496 CURRENT_NAME, CURRENT_LINE);
502 * expand_macro - user-defined macro expansion
505 expand_macro(const char *argv[], int argc)
512 t = argv[0]; /* defn string as a whole */
516 p--; /* last character of defn */
518 if (*(p - 1) != ARGFLAG)
536 if ((argno = *p - '0') < argc - 1)
537 pbstr(argv[argno + 1]);
541 for (n = argc - 1; n > 2; n--) {
550 for (n = argc - 1; n > 2; n--) {
570 if (p == t) /* do last character */
575 * dodefine - install definition in the table
578 dodefine(const char *name, const char *defn)
584 errx(1, "%s at line %lu: null definition.", CURRENT_NAME,
586 if ((p = lookup(name)) == nil)
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);
593 p->type = n & TYPEMASK;
594 if ((n & NOARGS) == 0)
603 p->defn = xstrdup(defn);
605 if (STREQ(name, defn))
610 * dodefn - push back a quoted definition of
614 dodefn(const char *name)
619 if ((p = lookup(name)) != nil) {
620 if (p->defn != null) {
624 } else if ((real = builtin_realname(p->type)) != NULL) {
626 pbstr(BUILTIN_MARKER);
632 * dopushdef - install a definition in the hash table
633 * without removing a previous definition. Since
634 * each new entry is entered in *front* of the
635 * hash bucket, it hides a previous definition from
639 dopushdef(const char *name, const char *defn)
644 errx(1, "%s at line %lu: null definition", CURRENT_NAME,
650 p->defn = xstrdup(defn);
652 if (STREQ(name, defn))
657 * dump_one_def - dump the specified definition.
660 dump_one_def(ndptr p)
665 if ((p->type & TYPEMASK) == MACRTYPE)
666 fprintf(traceout, "%s:\t%s\n", p->name, p->defn);
668 real = builtin_realname(p->type);
671 fprintf(traceout, "%s:\t<%s>\n", p->name, real);
674 fprintf(traceout, "`%s'\t`%s'\n", p->name, p->defn);
678 * dodumpdef - dump the specified definitions in the hash
679 * table to stderr. If nothing is specified, the entire
680 * hash table is dumped.
683 dodump(const char *argv[], int argc)
689 for (n = 2; n < argc; n++)
690 if ((p = lookup(argv[n])) != nil)
693 for (n = 0; n < HASHSIZE; n++)
694 for (p = hashtab[n]; p != nil; p = p->nxtptr)
700 * dotrace - mark some macros as traced/untraced depending upon on.
703 dotrace(const char *argv[], int argc, int on)
708 for (n = 2; n < argc; n++)
709 mark_traced(argv[n], on);
711 mark_traced(NULL, on);
715 * doifelse - select one of two alternatives - loop.
718 doifelse(const char *argv[], int argc)
721 if (STREQ(argv[2], argv[3]))
735 * doinclude - include a given file.
738 doincl(const char *ifile)
740 if (ilevel + 1 == MAXINP)
741 errx(1, "%s at line %lu: too many include files.",
742 CURRENT_NAME, CURRENT_LINE);
743 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
745 if ((inname[ilevel] = strdup(ifile)) == NULL)
747 inlineno[ilevel] = 1;
748 bbase[ilevel] = bufbase = bp;
757 * dopaste - include a given file without any
761 dopaste(const char *pfile)
766 if ((pf = fopen(pfile, "r")) != NULL) {
767 fprintf(active, "#line 1 \"%s\"\n", pfile);
768 while ((c = getc(pf)) != EOF)
779 gnu_dochq(const char *argv[], int ac)
781 /* In gnu-m4 mode, the only way to restore quotes is to have no
782 * arguments at all. */
784 lquote[0] = LQUOTE, lquote[1] = EOS;
785 rquote[0] = RQUOTE, rquote[1] = EOS;
787 strlcpy(lquote, argv[2], sizeof(lquote));
789 strlcpy(rquote, argv[3], sizeof(rquote));
796 * dochq - change quote characters
799 dochq(const char *argv[], int argc)
803 strlcpy(lquote, argv[2], sizeof(lquote));
810 strlcpy(rquote, argv[3], sizeof(rquote));
812 strcpy(rquote, lquote);
814 lquote[0] = LQUOTE, lquote[1] = EOS;
815 rquote[0] = RQUOTE, rquote[1] = EOS;
820 gnu_dochc(const char *argv[], int ac)
822 /* In gnu-m4 mode, no arguments mean no comment
823 * arguments at all. */
829 strlcpy(scommt, argv[2], sizeof(scommt));
831 scommt[0] = SCOMMT, scommt[1] = EOS;
832 if(ac > 3 && *argv[3])
833 strlcpy(ecommt, argv[3], sizeof(ecommt));
835 ecommt[0] = ECOMMT, ecommt[1] = EOS;
839 * dochc - change comment characters
842 dochc(const char *argv[], int argc)
846 strlcpy(scommt, argv[2], sizeof(scommt));
849 strlcpy(ecommt, argv[3], sizeof(ecommt));
852 ecommt[0] = ECOMMT, ecommt[1] = EOS;
855 scommt[0] = SCOMMT, scommt[1] = EOS;
856 ecommt[0] = ECOMMT, ecommt[1] = EOS;
861 * dodivert - divert the output to a temporary file
873 n = 0; /* bitbucket */
877 n = 0; /* bitbucket */
878 if (outfile[n] == NULL) {
879 char fname[] = _PATH_DIVNAME;
881 if ((fd = mkstemp(fname)) < 0 ||
882 (outfile[n] = fdopen(fd, "w+")) == NULL)
883 err(1, "%s: cannot divert", fname);
884 if (unlink(fname) == -1)
885 err(1, "%s: cannot unlink", fname);
891 * doundivert - undivert a specified output, or all
892 * other outputs, in numerical order.
895 doundiv(const char *argv[], int argc)
901 for (ind = 2; ind < argc; ind++) {
903 if (n > 0 && n < maxout && outfile[n] != NULL)
909 for (n = 1; n < maxout; n++)
910 if (outfile[n] != NULL)
915 * dosub - select substring
918 dosub(const char *argv[], int argc)
920 const char *ap, *fc, *k;
923 ap = argv[2]; /* target string */
925 fc = ap + expr(argv[3]); /* first char */
927 fc = ap + atoi(argv[3]); /* first char */
932 nc = min(nc, expr(argv[4]));
934 nc = min(nc, atoi(argv[4]));
936 if (fc >= ap && fc < ap + strlen(ap))
937 for (k = fc + nc - 1; k >= fc; k--)
943 * map every character of s1 that is specified in from
944 * into s3 and replace in s. (source s1 remains untouched)
946 * This is a standard implementation of map(s,from,to) function of ICON
947 * language. Within mapvec, we replace every character of "from" with
948 * the corresponding character in "to". If "to" is shorter than "from",
949 * than the corresponding entries are null, which means that those
950 * characters dissapear altogether. Furthermore, imagine
951 * map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
952 * `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
953 * ultimately maps to `*'. In order to achieve this effect in an efficient
954 * manner (i.e. without multiple passes over the destination string), we
955 * loop over mapvec, starting with the initial source character. if the
956 * character value (dch) in this location is different than the source
957 * character (sch), sch becomes dch, once again to index into mapvec, until
958 * the character value stabilizes (i.e. sch = dch, in other words
959 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
960 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
961 * end, we restore mapvec* back to normal where mapvec[n] == n for
962 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
963 * about 5 times faster than any algorithm that makes multiple passes over
964 * destination string.
967 map(char *dest, const char *src, const char *from, const char *to)
970 unsigned char sch, dch;
971 static char frombis[257];
972 static char tobis[257];
973 static unsigned char mapvec[256] = {
974 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
975 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
976 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
977 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
978 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
979 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
980 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
981 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
982 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
983 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
984 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
985 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
986 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
987 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
988 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
989 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
990 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
991 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
997 * expand character ranges on the fly
999 from = handledash(frombis, frombis + 256, from);
1000 to = handledash(tobis, tobis + 256, to);
1004 * create a mapping between "from" and
1008 mapvec[(unsigned char)(*from++)] = (*to) ?
1009 (unsigned char)(*to++) : 0;
1012 sch = (unsigned char)(*src++);
1014 while (dch != sch) {
1018 if ((*dest = (char)dch))
1022 * restore all the changed characters
1025 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp);
1035 * use buffer to copy the src string, expanding character ranges
1039 handledash(char *buffer, char *end, const char *src)
1045 if (src[1] == '-' && src[2]) {
1047 for (i = (unsigned char)src[0];
1048 i <= (unsigned char)src[2]; i++) {