1 /* $OpenBSD: eval.c,v 1.70 2012/04/12 17:00:11 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. 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
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
42 * Facility: m4 macro processor
46 #include <sys/types.h>
60 #include "pathnames.h"
62 static void dodefn(const char *);
63 static void dopushdef(const char *, const char *);
64 static void dodump(const char *[], int);
65 static void dotrace(const char *[], int, int);
66 static void doifelse(const char *[], int);
67 static int doincl(const char *);
68 static int dopaste(const char *);
69 static void dochq(const char *[], int);
70 static void dochc(const char *[], int);
71 static void dom4wrap(const char *);
72 static void dodiv(int);
73 static void doundiv(const char *[], int);
74 static void dosub(const char *[], int);
75 static void map(char *, const char *, const char *, const char *);
76 static const char *handledash(char *, char *, const char *);
77 static void expand_builtin(const char *[], int, int);
78 static void expand_macro(const char *[], int);
79 static void dump_one_def(const char *, struct macro_definition *);
81 unsigned long expansion_id;
84 * eval - eval all macros and builtins calls
85 * argc - number of elements in argv.
86 * argv - element vector :
87 * argv[0] = definition of a user
88 * macro or NULL if built-in.
89 * argv[1] = name of the macro or
91 * argv[2] = parameters to user-defined
92 * . macro or built-in.
95 * A call in the form of macro-or-builtin() will result in:
97 * argv[1] = macro-or-builtin
100 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
103 eval(const char *argv[], int argc, int td, int is_traced)
105 size_t mark = SIZE_MAX;
109 m4errx(1, "expanding recursive definition for %s.", argv[1]);
111 mark = trace(argv, argc, infile+ilevel);
113 expand_macro(argv, argc);
115 expand_builtin(argv, argc, td);
116 if (mark != SIZE_MAX)
121 * expand_builtin - evaluate built-in macros.
124 expand_builtin(const char *argv[], int argc, int td)
128 static int sysval = 0;
131 printf("argc = %d\n", argc);
132 for (n = 0; n < argc; n++)
133 printf("argv[%d] = %s\n", n, argv[n]);
138 * if argc == 3 and argv[2] is null, then we
139 * have macro-or-builtin() type call. We adjust
140 * argc to avoid further checking..
142 /* we keep the initial value for those built-ins that differentiate
143 * between builtin() and builtin.
147 if (argc == 3 && !*(argv[2]) && !mimic_gnu)
150 switch (td & TYPEMASK) {
154 dodefine(argv[2], (argc > 3) ? argv[3] : null);
159 dopushdef(argv[2], (argc > 3) ? argv[3] : null);
167 dotrace(argv, argc, 1);
171 dotrace(argv, argc, 0);
176 * doexpr - evaluate arithmetic
185 base = strtonum(argv[3], 2, 36, &errstr);
187 m4errx(1, "expr: base %s invalid.", argv[3]);
191 maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
193 m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
197 pbnumbase(expr(argv[2]), base, maxdigits);
203 doifelse(argv, argc);
208 * doifdef - select one of two
209 * alternatives based on the existence of
213 if (lookup_macro_definition(argv[2]) != NULL)
222 * dolen - find the length of the
225 pbnum((argc > 2) ? strlen(argv[2]) : 0);
230 * doincr - increment the value of the
234 pbnum(atoi(argv[2]) + 1);
239 * dodecr - decrement the value of the
243 pbnum(atoi(argv[2]) - 1);
248 * dosys - execute system command
252 sysval = system(argv[2]);
258 * dosysval - return value of the last
271 if (!doincl(argv[2])) {
273 warn("%s at line %lu: include(%s)",
274 CURRENT_NAME, CURRENT_LINE, argv[2]);
277 err(1, "%s at line %lu: include(%s)",
278 CURRENT_NAME, CURRENT_LINE, argv[2]);
284 (void) doincl(argv[2]);
289 if (!dopaste(argv[2]))
290 err(1, "%s at line %lu: paste(%s)",
291 CURRENT_NAME, CURRENT_LINE, argv[2]);
296 (void) dopaste(argv[2]);
299 doformat(argv, argc);
312 * dosub - select substring
321 * doshift - push back all arguments
322 * except the first one (i.e. skip
326 for (n = argc - 1; n > 3; n--) {
339 if (argc > 2 && (n = atoi(argv[2])) != 0)
353 * dodivnum - return the number of
354 * current output diversion
361 * doundefine - undefine a previously
362 * defined macro(s) or m4 keyword(s).
365 for (n = 2; n < argc; n++)
366 macro_undefine(argv[n]);
371 * dopopdef - remove the topmost
372 * definitions of macro(s) or m4
376 for (n = 2; n < argc; n++)
377 macro_popdef(argv[n]);
382 * dotemp - create a temporary file
388 temp = xstrdup(argv[2]);
393 "%s at line %lu: couldn't make temp file %s",
394 CURRENT_NAME, CURRENT_LINE, argv[2]);
403 * dotranslit - replace all characters in
404 * the source string that appears in the
405 * "from" string with the corresponding
406 * characters in the "to" string.
411 temp = xalloc(strlen(argv[2])+1, NULL);
413 map(temp, argv[2], argv[3], argv[4]);
415 map(temp, argv[2], argv[3], null);
424 * doindex - find the index of the second
425 * argument string in the first argument
426 * string. -1 if not present.
428 pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
433 * doerrp - print the arguments to stderr
437 for (n = 2; n < argc; n++)
438 fprintf(stderr, "%s ", argv[n]);
439 fprintf(stderr, "\n");
445 * dodnl - eat-up-to and including
448 while ((c = gpbc()) != '\n' && c != EOF)
454 * dom4wrap - set up for
455 * wrap-up/wind-down activity
463 * doexit - immediate exit from m4.
466 exit((argc > 2) ? atoi(argv[2]) : 0);
471 for (n = 2; n < argc; n++)
475 case INDIRTYPE: /* Indirect call */
480 case BUILTINTYPE: /* Builtins only */
482 dobuiltin(argv, argc);
487 dopatsubst(argv, argc);
491 doregexp(argv, argc);
494 doprintlineno(infile+ilevel);
497 doprintfilename(infile+ilevel);
505 m4errx(1, "eval: major botch.");
511 * expand_macro - user-defined macro expansion
514 expand_macro(const char *argv[], int argc)
521 t = argv[0]; /* defn string as a whole */
525 p--; /* last character of defn */
527 if (*(p - 1) != ARGFLAG)
545 if ((argno = *p - '0') < argc - 1)
546 pbstr(argv[argno + 1]);
550 for (n = argc - 1; n > 2; n--) {
559 for (n = argc - 1; n > 2; n--) {
579 if (p == t) /* do last character */
585 * dodefine - install definition in the table
588 dodefine(const char *name, const char *defn)
590 if (!*name && !mimic_gnu)
591 m4errx(1, "null definition.");
593 macro_define(name, defn);
597 * dodefn - push back a quoted definition of
601 dodefn(const char *name)
603 struct macro_definition *p;
605 if ((p = lookup_macro_definition(name)) != NULL) {
606 if ((p->type & TYPEMASK) == MACRTYPE) {
612 pbstr(BUILTIN_MARKER);
618 * dopushdef - install a definition in the hash table
619 * without removing a previous definition. Since
620 * each new entry is entered in *front* of the
621 * hash bucket, it hides a previous definition from
625 dopushdef(const char *name, const char *defn)
627 if (!*name && !mimic_gnu)
628 m4errx(1, "null definition.");
630 macro_pushdef(name, defn);
634 * dump_one_def - dump the specified definition.
637 dump_one_def(const char *name, struct macro_definition *p)
642 if ((p->type & TYPEMASK) == MACRTYPE)
643 fprintf(traceout, "%s:\t%s\n", name, p->defn);
645 fprintf(traceout, "%s:\t<%s>\n", name, p->defn);
648 fprintf(traceout, "`%s'\t`%s'\n", name, p->defn);
652 * dodumpdef - dump the specified definitions in the hash
653 * table to stderr. If nothing is specified, the entire
654 * hash table is dumped.
657 dodump(const char *argv[], int argc)
660 struct macro_definition *p;
663 for (n = 2; n < argc; n++)
664 if ((p = lookup_macro_definition(argv[n])) != NULL)
665 dump_one_def(argv[n], p);
667 macro_for_all(dump_one_def);
671 * dotrace - mark some macros as traced/untraced depending upon on.
674 dotrace(const char *argv[], int argc, int on)
679 for (n = 2; n < argc; n++)
680 mark_traced(argv[n], on);
682 mark_traced(NULL, on);
686 * doifelse - select one of two alternatives - loop.
689 doifelse(const char *argv[], int argc)
692 if (STREQ(argv[2], argv[3]))
706 * doinclude - include a given file.
709 doincl(const char *ifile)
711 if (ilevel + 1 == MAXINP)
712 m4errx(1, "too many include files.");
713 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
715 bbase[ilevel] = bufbase = bp;
723 * dopaste - include a given file without any
727 dopaste(const char *pfile)
732 if ((pf = fopen(pfile, "r")) != NULL) {
734 fprintf(active, "#line 1 \"%s\"\n", pfile);
735 while ((c = getc(pf)) != EOF)
746 * dochq - change quote characters
749 dochq(const char *argv[], int ac)
752 lquote[0] = LQUOTE; lquote[1] = EOS;
753 rquote[0] = RQUOTE; rquote[1] = EOS;
755 strlcpy(lquote, argv[2], sizeof(lquote));
757 strlcpy(rquote, argv[3], sizeof(rquote));
759 rquote[0] = ECOMMT; rquote[1] = EOS;
765 * dochc - change comment characters
768 dochc(const char *argv[], int argc)
770 /* XXX Note that there is no difference between no argument and a single
777 strlcpy(scommt, argv[2], sizeof(scommt));
779 ecommt[0] = ECOMMT; ecommt[1] = EOS;
781 strlcpy(ecommt, argv[3], sizeof(ecommt));
787 * dom4wrap - expand text at EOF
790 dom4wrap(const char *text)
792 if (wrapindex >= maxwraps) {
797 m4wraps = xrealloc(m4wraps, maxwraps * sizeof(*m4wraps),
800 m4wraps[wrapindex++] = xstrdup(text);
804 * dodivert - divert the output to a temporary file
816 n = 0; /* bitbucket */
820 n = 0; /* bitbucket */
821 if (outfile[n] == NULL) {
822 char fname[] = _PATH_DIVNAME;
824 if ((fd = mkstemp(fname)) < 0 ||
825 (outfile[n] = fdopen(fd, "w+")) == NULL)
826 err(1, "%s: cannot divert", fname);
827 if (unlink(fname) == -1)
828 err(1, "%s: cannot unlink", fname);
834 * doundivert - undivert a specified output, or all
835 * other outputs, in numerical order.
838 doundiv(const char *argv[], int argc)
844 for (ind = 2; ind < argc; ind++) {
846 n = strtonum(argv[ind], 1, INT_MAX, &errstr);
848 if (errno == EINVAL && mimic_gnu)
849 getdivfile(argv[ind]);
851 if (n < maxout && outfile[n] != NULL)
857 for (n = 1; n < maxout; n++)
858 if (outfile[n] != NULL)
863 * dosub - select substring
866 dosub(const char *argv[], int argc)
868 const char *ap, *fc, *k;
871 ap = argv[2]; /* target string */
873 fc = ap + expr(argv[3]); /* first char */
875 fc = ap + atoi(argv[3]); /* first char */
880 nc = min(nc, expr(argv[4]));
882 nc = min(nc, atoi(argv[4]));
884 if (fc >= ap && fc < ap + strlen(ap))
885 for (k = fc + nc - 1; k >= fc; k--)
891 * map every character of s1 that is specified in from
892 * into s3 and replace in s. (source s1 remains untouched)
894 * This is derived from the a standard implementation of map(s,from,to)
895 * function of ICON language. Within mapvec, we replace every character
896 * of "from" with the corresponding character in "to".
897 * If "to" is shorter than "from", than the corresponding entries are null,
898 * which means that those characters dissapear altogether.
901 map(char *dest, const char *src, const char *from, const char *to)
904 unsigned char sch, dch;
905 static char frombis[257];
906 static char tobis[257];
909 static unsigned char mapvec[256] = {
910 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
911 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
912 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
913 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
914 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
915 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
916 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
917 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
918 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
919 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
920 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
921 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
922 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
923 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
924 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
925 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
926 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
927 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
933 * expand character ranges on the fly
935 from = handledash(frombis, frombis + 256, from);
936 to = handledash(tobis, tobis + 256, to);
940 * create a mapping between "from" and
943 for (i = 0; i < 256; i++)
946 if (!seen[(unsigned char)(*from)]) {
947 mapvec[(unsigned char)(*from)] = (unsigned char)(*to);
948 seen[(unsigned char)(*from)] = 1;
956 sch = (unsigned char)(*src++);
958 if ((*dest = (char)dch))
962 * restore all the changed characters
965 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp);
975 * use buffer to copy the src string, expanding character ranges
979 handledash(char *buffer, char *end, const char *src)
985 if (src[1] == '-' && src[2]) {
987 if ((unsigned char)src[0] <= (unsigned char)src[2]) {
988 for (i = (unsigned char)src[0];
989 i <= (unsigned char)src[2]; i++) {
997 for (i = (unsigned char)src[0];
998 i >= (unsigned char)src[2]; i--) {