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 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static char sccsid[] = "@(#)eval.c 8.2 (Berkeley) 4/27/95";
41 static char rcsid[] = "$OpenBSD: eval.c,v 1.44 2002/04/26 16:15:16 espie Exp $";
46 #include <sys/cdefs.h>
47 __FBSDID("$FreeBSD$");
51 * Facility: m4 macro processor
55 #include <sys/types.h>
67 #include "pathnames.h"
69 #define BUILTIN_MARKER "__builtin_"
71 static void dodefn(const char *);
72 static void dopushdef(const char *, const char *);
73 static void dodump(const char *[], int);
74 static void dotrace(const char *[], int, int);
75 static void doifelse(const char *[], int);
76 static int doincl(const char *);
77 static int dopaste(const char *);
78 static void gnu_dochq(const char *[], int);
79 static void dochq(const char *[], int);
80 static void gnu_dochc(const char *[], int);
81 static void dochc(const char *[], int);
82 static void dodiv(int);
83 static void doundiv(const char *[], int);
84 static void dosub(const char *[], int);
85 static void map(char *, const char *, const char *, const char *);
86 static const char *handledash(char *, char *, const char *);
87 static void expand_builtin(const char *[], int, int);
88 static void expand_macro(const char *[], int);
89 static void dump_one_def(ndptr);
91 unsigned long expansion_id;
94 * eval - eval all macros and builtins calls
95 * argc - number of elements in argv.
96 * argv - element vector :
97 * argv[0] = definition of a user
98 * macro or nil if built-in.
99 * argv[1] = name of the macro or
101 * argv[2] = parameters to user-defined
102 * . macro or built-in.
105 * A call in the form of macro-or-builtin() will result in:
107 * argv[1] = macro-or-builtin
110 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
113 eval(const char *argv[], int argc, int td)
119 errx(1, "%s at line %lu: expanding recursive definition for %s",
120 CURRENT_NAME, CURRENT_LINE, argv[1]);
121 if (traced_macros && is_traced(argv[1]))
122 mark = trace(argv, argc, infile+ilevel);
124 expand_macro(argv, argc);
126 expand_builtin(argv, argc, td);
132 * expand_builtin - evaluate built-in macros.
135 expand_builtin(const char *argv[], int argc, int td)
139 static int sysval = 0;
142 printf("argc = %d\n", argc);
143 for (n = 0; n < argc; n++)
144 printf("argv[%d] = %s\n", n, argv[n]);
149 * if argc == 3 and argv[2] is null, then we
150 * have macro-or-builtin() type call. We adjust
151 * argc to avoid further checking..
155 if (argc == 3 && !*(argv[2]))
158 switch (td & TYPEMASK) {
162 dodefine(argv[2], (argc > 3) ? argv[3] : null);
167 dopushdef(argv[2], (argc > 3) ? argv[3] : null);
175 dotrace(argv, argc, 1);
179 dotrace(argv, argc, 0);
184 * doexpr - evaluate arithmetic
188 pbnum(expr(argv[2]));
193 doifelse(argv, argc);
198 * doifdef - select one of two
199 * alternatives based on the existence of
203 if (lookup(argv[2]) != nil)
212 * dolen - find the length of the
215 pbnum((argc > 2) ? strlen(argv[2]) : 0);
220 * doincr - increment the value of the
224 pbnum(atoi(argv[2]) + 1);
229 * dodecr - decrement the value of the
233 pbnum(atoi(argv[2]) - 1);
238 * dosys - execute system command
242 sysval = system(argv[2]);
248 * dosysval - return value of the last
261 if (!doincl(argv[2]))
262 err(1, "%s at line %lu: include(%s)",
263 CURRENT_NAME, CURRENT_LINE, argv[2]);
268 (void) doincl(argv[2]);
273 if (!dopaste(argv[2]))
274 err(1, "%s at line %lu: paste(%s)",
275 CURRENT_NAME, CURRENT_LINE, argv[2]);
280 (void) dopaste(argv[2]);
299 * dosub - select substring
308 * doshift - push back all arguments
309 * except the first one (i.e. skip
313 for (n = argc - 1; n > 3; n--) {
326 if (argc > 2 && (n = atoi(argv[2])) != 0)
340 * dodivnum - return the number of
341 * current output diversion
348 * doundefine - undefine a previously
349 * defined macro(s) or m4 keyword(s).
352 for (n = 2; n < argc; n++)
353 remhash(argv[n], ALL);
358 * dopopdef - remove the topmost
359 * definitions of macro(s) or m4
363 for (n = 2; n < argc; n++)
364 remhash(argv[n], TOP);
369 * dotemp - create a temporary file
375 temp = xstrdup(argv[2]);
380 "%s at line %lu: couldn't make temp file %s",
381 CURRENT_NAME, CURRENT_LINE, argv[2]);
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.
398 temp = xalloc(strlen(argv[2])+1);
400 map(temp, argv[2], argv[3], argv[4]);
402 map(temp, argv[2], argv[3], null);
411 * doindex - find the index of the second
412 * argument string in the first argument
413 * string. -1 if not present.
415 pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
420 * doerrp - print the arguments to stderr
424 for (n = 2; n < argc; n++)
425 fprintf(stderr, "%s ", argv[n]);
426 fprintf(stderr, "\n");
432 * dodnl - eat-up-to and including
435 while ((c = gpbc()) != '\n' && c != EOF)
441 * dom4wrap - set up for
442 * wrap-up/wind-down activity
444 m4wraps = (argc > 2) ? xstrdup(argv[2]) : null;
449 * doexit - immediate exit from m4.
452 exit((argc > 2) ? atoi(argv[2]) : 0);
457 for (n = 2; n < argc; n++)
461 case INDIRTYPE: /* Indirect call */
466 case BUILTINTYPE: /* Builtins only */
468 dobuiltin(argv, argc);
473 dopatsubst(argv, argc);
477 doregexp(argv, argc);
480 doprintlineno(infile+ilevel);
483 doprintfilename(infile+ilevel);
491 errx(1, "%s at line %lu: eval: major botch.",
492 CURRENT_NAME, CURRENT_LINE);
498 * expand_macro - user-defined macro expansion
501 expand_macro(const char *argv[], int argc)
508 t = argv[0]; /* defn string as a whole */
512 p--; /* last character of defn */
514 if (*(p - 1) != ARGFLAG)
532 if ((argno = *p - '0') < argc - 1)
533 pbstr(argv[argno + 1]);
537 for (n = argc - 1; n > 2; n--) {
546 for (n = argc - 1; n > 2; n--) {
566 if (p == t) /* do last character */
571 * dodefine - install definition in the table
574 dodefine(const char *name, const char *defn)
580 errx(1, "%s at line %lu: null definition.", CURRENT_NAME,
582 if ((p = lookup(name)) == nil)
584 else if (p->defn != null)
585 free((char *) p->defn);
586 if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0) {
587 n = builtin_type(defn+sizeof(BUILTIN_MARKER)-1);
589 p->type = n & TYPEMASK;
590 if ((n & NOARGS) == 0)
599 p->defn = xstrdup(defn);
601 if (STREQ(name, defn))
606 * dodefn - push back a quoted definition of
610 dodefn(const char *name)
615 if ((p = lookup(name)) != nil) {
616 if (p->defn != null) {
620 } else if ((real = builtin_realname(p->type)) != NULL) {
622 pbstr(BUILTIN_MARKER);
628 * dopushdef - install a definition in the hash table
629 * without removing a previous definition. Since
630 * each new entry is entered in *front* of the
631 * hash bucket, it hides a previous definition from
635 dopushdef(const char *name, const char *defn)
640 errx(1, "%s at line %lu: null definition", CURRENT_NAME,
646 p->defn = xstrdup(defn);
648 if (STREQ(name, defn))
653 * dump_one_def - dump the specified definition.
656 dump_one_def(ndptr p)
661 if ((p->type & TYPEMASK) == MACRTYPE)
662 fprintf(traceout, "%s:\t%s\n", p->name, p->defn);
664 real = builtin_realname(p->type);
667 fprintf(traceout, "%s:\t<%s>\n", p->name, real);
670 fprintf(traceout, "`%s'\t`%s'\n", p->name, p->defn);
674 * dodumpdef - dump the specified definitions in the hash
675 * table to stderr. If nothing is specified, the entire
676 * hash table is dumped.
679 dodump(const char *argv[], int argc)
685 for (n = 2; n < argc; n++)
686 if ((p = lookup(argv[n])) != nil)
689 for (n = 0; n < HASHSIZE; n++)
690 for (p = hashtab[n]; p != nil; p = p->nxtptr)
696 * dotrace - mark some macros as traced/untraced depending upon on.
699 dotrace(const char *argv[], int argc, int on)
704 for (n = 2; n < argc; n++)
705 mark_traced(argv[n], on);
707 mark_traced(NULL, on);
711 * doifelse - select one of two alternatives - loop.
714 doifelse(const char *argv[], int argc)
717 if (STREQ(argv[2], argv[3]))
731 * doinclude - include a given file.
734 doincl(const char *ifile)
736 if (ilevel + 1 == MAXINP)
737 errx(1, "%s at line %lu: too many include files.",
738 CURRENT_NAME, CURRENT_LINE);
739 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
741 if ((inname[ilevel] = strdup(ifile)) == NULL)
743 inlineno[ilevel] = 1;
744 bbase[ilevel] = bufbase = bp;
753 * dopaste - include a given file without any
757 dopaste(const char *pfile)
762 if ((pf = fopen(pfile, "r")) != NULL) {
763 fprintf(active, "#line 1 \"%s\"\n", pfile);
764 while ((c = getc(pf)) != EOF)
775 gnu_dochq(const char *argv[], int ac)
777 /* In gnu-m4 mode, the only way to restore quotes is to have no
778 * arguments at all. */
780 lquote[0] = LQUOTE, lquote[1] = EOS;
781 rquote[0] = RQUOTE, rquote[1] = EOS;
783 strlcpy(lquote, argv[2], sizeof(lquote));
785 strlcpy(rquote, argv[3], sizeof(rquote));
792 * dochq - change quote characters
795 dochq(const char *argv[], int argc)
799 strlcpy(lquote, argv[2], sizeof(lquote));
806 strlcpy(rquote, argv[3], sizeof(rquote));
808 strcpy(rquote, lquote);
810 lquote[0] = LQUOTE, lquote[1] = EOS;
811 rquote[0] = RQUOTE, rquote[1] = EOS;
816 gnu_dochc(const char *argv[], int ac)
818 /* In gnu-m4 mode, no arguments mean no comment
819 * arguments at all. */
825 strlcpy(scommt, argv[2], sizeof(scommt));
827 scommt[0] = SCOMMT, scommt[1] = EOS;
828 if(ac > 3 && *argv[3])
829 strlcpy(ecommt, argv[3], sizeof(ecommt));
831 ecommt[0] = ECOMMT, ecommt[1] = EOS;
835 * dochc - change comment characters
838 dochc(const char *argv[], int argc)
842 strlcpy(scommt, argv[2], sizeof(scommt));
845 strlcpy(ecommt, argv[3], sizeof(ecommt));
848 ecommt[0] = ECOMMT, ecommt[1] = EOS;
851 scommt[0] = SCOMMT, scommt[1] = EOS;
852 ecommt[0] = ECOMMT, ecommt[1] = EOS;
857 * dodivert - divert the output to a temporary file
869 n = 0; /* bitbucket */
873 n = 0; /* bitbucket */
874 if (outfile[n] == NULL) {
875 char fname[] = _PATH_DIVNAME;
877 if ((fd = mkstemp(fname)) < 0 ||
878 (outfile[n] = fdopen(fd, "w+")) == NULL)
879 err(1, "%s: cannot divert", fname);
880 if (unlink(fname) == -1)
881 err(1, "%s: cannot unlink", fname);
887 * doundivert - undivert a specified output, or all
888 * other outputs, in numerical order.
891 doundiv(const char *argv[], int argc)
897 for (ind = 2; ind < argc; ind++) {
899 if (n > 0 && n < maxout && outfile[n] != NULL)
905 for (n = 1; n < maxout; n++)
906 if (outfile[n] != NULL)
911 * dosub - select substring
914 dosub(const char *argv[], int argc)
916 const char *ap, *fc, *k;
919 ap = argv[2]; /* target string */
921 fc = ap + expr(argv[3]); /* first char */
923 fc = ap + atoi(argv[3]); /* first char */
928 nc = min(nc, expr(argv[4]));
930 nc = min(nc, atoi(argv[4]));
932 if (fc >= ap && fc < ap + strlen(ap))
933 for (k = fc + nc - 1; k >= fc; k--)
939 * map every character of s1 that is specified in from
940 * into s3 and replace in s. (source s1 remains untouched)
942 * This is a standard implementation of map(s,from,to) function of ICON
943 * language. Within mapvec, we replace every character of "from" with
944 * the corresponding character in "to". If "to" is shorter than "from",
945 * than the corresponding entries are null, which means that those
946 * characters dissapear altogether. Furthermore, imagine
947 * map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
948 * `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
949 * ultimately maps to `*'. In order to achieve this effect in an efficient
950 * manner (i.e. without multiple passes over the destination string), we
951 * loop over mapvec, starting with the initial source character. if the
952 * character value (dch) in this location is different than the source
953 * character (sch), sch becomes dch, once again to index into mapvec, until
954 * the character value stabilizes (i.e. sch = dch, in other words
955 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
956 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
957 * end, we restore mapvec* back to normal where mapvec[n] == n for
958 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
959 * about 5 times faster than any algorithm that makes multiple passes over
960 * destination string.
963 map(char *dest, const char *src, const char *from, const char *to)
966 unsigned char sch, dch;
967 static char frombis[257];
968 static char tobis[257];
969 static unsigned char mapvec[256] = {
970 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
971 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
972 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
973 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
974 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
975 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
976 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
977 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
978 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
979 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
980 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
981 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
982 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
983 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
984 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
985 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
986 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
987 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
993 * expand character ranges on the fly
995 from = handledash(frombis, frombis + 256, from);
996 to = handledash(tobis, tobis + 256, to);
1000 * create a mapping between "from" and
1004 mapvec[(unsigned char)(*from++)] = (*to) ?
1005 (unsigned char)(*to++) : 0;
1008 sch = (unsigned char)(*src++);
1010 while (dch != sch) {
1014 if ((*dest = (char)dch))
1018 * restore all the changed characters
1021 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp);
1031 * use buffer to copy the src string, expanding character ranges
1035 handledash(char *buffer, char *end, const char *src)
1041 if (src[1] == '-' && src[2]) {
1043 for (i = (unsigned char)src[0];
1044 i <= (unsigned char)src[2]; i++) {