1 /* $OpenBSD: eval.c,v 1.66 2008/08/21 21:01:47 espie Exp $ */
2 /* $NetBSD: eval.c,v 1.22 2011/08/21 23:38:43 dholland 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
38 * Facility: m4 macro processor
41 #if HAVE_NBTOOL_CONFIG_H
42 #include "nbtool_config.h"
44 #include <sys/cdefs.h>
45 __RCSID("$NetBSD: eval.c,v 1.22 2011/08/21 23:38:43 dholland Exp $");
47 #include <sys/types.h>
61 #include "pathnames.h"
63 static void dodefn(const char *);
64 static void dopushdef(const char *, const char *);
65 static void dodump(const char *[], int);
66 static void dotrace(const char *[], int, int);
67 static void doifelse(const char *[], int);
68 static int doincl(const char *);
69 static int dopaste(const char *);
70 static void dochq(const char *[], int);
71 static void dochc(const char *[], int);
72 static void dom4wrap(const char *);
73 static void dodiv(int);
74 static void doundiv(const char *[], int);
75 static void dosub(const char *[], int);
76 static void map(char *, const char *, const char *, const char *);
77 static const char *handledash(char *, char *, const char *);
78 static void expand_builtin(const char *[], int, int);
79 static void expand_macro(const char *[], int);
80 static void dump_one_def(const char *, struct macro_definition
*);
82 unsigned long expansion_id
;
85 * eval - eval all macros and builtins calls
86 * argc - number of elements in argv.
87 * argv - element vector :
88 * argv[0] = definition of a user
89 * macro or NULL if built-in.
90 * argv[1] = name of the macro or
92 * argv[2] = parameters to user-defined
93 * . macro or built-in.
96 * A call in the form of macro-or-builtin() will result in:
98 * argv[1] = macro-or-builtin
101 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
104 eval(const char *argv
[], int argc
, int td
, int is_traced
)
106 size_t mark
= SIZE_MAX
;
110 m4errx(1, "expanding recursive definition for %s.", argv
[1]);
112 mark
= trace(argv
, argc
, infile
+ilevel
);
114 expand_macro(argv
, argc
);
116 expand_builtin(argv
, argc
, td
);
117 if (mark
!= SIZE_MAX
)
122 * expand_builtin - evaluate built-in macros.
125 expand_builtin(const char *argv
[], int argc
, int td
)
129 static int sysval
= 0;
132 printf("argc = %d\n", argc
);
133 for (n
= 0; n
< argc
; n
++)
134 printf("argv[%d] = %s\n", n
, argv
[n
]);
139 * if argc == 3 and argv[2] is null, then we
140 * have macro-or-builtin() type call. We adjust
141 * argc to avoid further checking..
143 /* we keep the initial value for those built-ins that differentiate
144 * between builtin() and builtin.
148 if (argc
== 3 && !*(argv
[2]) && !mimic_gnu
)
151 switch (td
& TYPEMASK
) {
155 dodefine(argv
[2], (argc
> 3) ? argv
[3] : null
);
160 dopushdef(argv
[2], (argc
> 3) ? argv
[3] : null
);
168 dotrace(argv
, argc
, 1);
172 dotrace(argv
, argc
, 0);
177 * doexpr - evaluate arithmetic
186 base
= strtonum(argv
[3], 2, 36, &errstr
);
188 m4errx(1, "expr: base %s invalid.", argv
[3]);
192 maxdigits
= strtonum(argv
[4], 0, INT_MAX
, &errstr
);
194 m4errx(1, "expr: maxdigits %s invalid.", argv
[4]);
198 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]))
273 err(1, "%s at line %lu: include(%s)",
274 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
279 (void) doincl(argv
[2]);
284 if (!dopaste(argv
[2]))
285 err(1, "%s at line %lu: paste(%s)",
286 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
291 (void) dopaste(argv
[2]);
294 doformat(argv
, argc
);
307 * dosub - select substring
316 * doshift - push back all arguments
317 * except the first one (i.e. skip
321 for (n
= argc
- 1; n
> 3; n
--) {
334 if (argc
> 2 && (n
= atoi(argv
[2])) != 0)
348 * dodivnum - return the number of
349 * current output diversion
356 * doundefine - undefine a previously
357 * defined macro(s) or m4 keyword(s).
360 for (n
= 2; n
< argc
; n
++)
361 macro_undefine(argv
[n
]);
366 * dopopdef - remove the topmost
367 * definitions of macro(s) or m4
371 for (n
= 2; n
< argc
; n
++)
372 macro_popdef(argv
[n
]);
377 * dotemp - create a temporary file
383 temp
= xstrdup(argv
[2]);
388 "%s at line %lu: couldn't make temp file %s",
389 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
398 * dotranslit - replace all characters in
399 * the source string that appears in the
400 * "from" string with the corresponding
401 * characters in the "to" string.
406 temp
= xalloc(strlen(argv
[2])+1, NULL
);
408 map(temp
, argv
[2], argv
[3], argv
[4]);
410 map(temp
, argv
[2], argv
[3], null
);
419 * doindex - find the index of the second
420 * argument string in the first argument
421 * string. -1 if not present.
423 pbnum((argc
> 3) ? indx(argv
[2], argv
[3]) : -1);
428 * doerrp - print the arguments to stderr
432 for (n
= 2; n
< argc
; n
++)
433 fprintf(stderr
, "%s%s",
434 mimic_gnu
&& n
== 2 ? "" : " ",
437 fprintf(stderr
, "\n");
443 * dodnl - eat-up-to and including
446 while ((c
= gpbc()) != '\n' && c
!= EOF
)
452 * dom4wrap - set up for
453 * wrap-up/wind-down activity
461 * doexit - immediate exit from m4.
464 exit((argc
> 2) ? atoi(argv
[2]) : 0);
469 for (n
= 2; n
< argc
; n
++)
473 case INDIRTYPE
: /* Indirect call */
478 case BUILTINTYPE
: /* Builtins only */
480 dobuiltin(argv
, argc
);
485 dopatsubst(argv
, argc
);
489 doregexp(argv
, argc
);
492 doprintlineno(infile
+ilevel
);
495 doprintfilename(infile
+ilevel
);
503 m4errx(1, "eval: major botch.");
509 * expand_macro - user-defined macro expansion
512 expand_macro(const char *argv
[], int argc
)
519 t
= argv
[0]; /* defn string as a whole */
523 p
--; /* last character of defn */
525 if (*(p
- 1) != ARGFLAG
)
543 if ((argno
= *p
- '0') < argc
- 1)
544 pbstr(argv
[argno
+ 1]);
548 for (n
= argc
- 1; n
> 2; n
--) {
557 for (n
= argc
- 1; n
> 2; n
--) {
577 if (p
== t
) /* do last character */
583 * dodefine - install definition in the table
586 dodefine(const char *name
, const char *defn
)
588 if (!*name
&& !mimic_gnu
)
589 m4errx(1, "null definition.");
591 macro_define(name
, defn
);
595 * dodefn - push back a quoted definition of
599 dodefn(const char *name
)
601 struct macro_definition
*p
;
603 if ((p
= lookup_macro_definition(name
)) != NULL
) {
604 if ((p
->type
& TYPEMASK
) == MACRTYPE
) {
610 pbstr(BUILTIN_MARKER
);
616 * dopushdef - install a definition in the hash table
617 * without removing a previous definition. Since
618 * each new entry is entered in *front* of the
619 * hash bucket, it hides a previous definition from
623 dopushdef(const char *name
, const char *defn
)
625 if (!*name
&& !mimic_gnu
)
626 m4errx(1, "null definition.");
628 macro_pushdef(name
, defn
);
632 * dump_one_def - dump the specified definition.
635 dump_one_def(const char *name
, struct macro_definition
*p
)
640 if ((p
->type
& TYPEMASK
) == MACRTYPE
)
641 fprintf(traceout
, "%s:\t%s\n", name
, p
->defn
);
643 fprintf(traceout
, "%s:\t<%s>\n", name
, p
->defn
);
646 fprintf(traceout
, "`%s'\t`%s'\n", name
, p
->defn
);
650 * dodumpdef - dump the specified definitions in the hash
651 * table to stderr. If nothing is specified, the entire
652 * hash table is dumped.
655 dodump(const char *argv
[], int argc
)
658 struct macro_definition
*p
;
661 for (n
= 2; n
< argc
; n
++)
662 if ((p
= lookup_macro_definition(argv
[n
])) != NULL
)
663 dump_one_def(argv
[n
], p
);
665 macro_for_all(dump_one_def
);
669 * dotrace - mark some macros as traced/untraced depending upon on.
672 dotrace(const char *argv
[], int argc
, int on
)
677 for (n
= 2; n
< argc
; n
++)
678 mark_traced(argv
[n
], on
);
680 mark_traced(NULL
, on
);
684 * doifelse - select one of two alternatives - loop.
687 doifelse(const char *argv
[], int argc
)
690 if (STREQ(argv
[2], argv
[3]))
704 * doinclude - include a given file.
707 doincl(const char *ifile
)
709 if (ilevel
+ 1 == MAXINP
)
710 m4errx(1, "too many include files.");
711 if (fopen_trypath(infile
+ilevel
+1, ifile
) != NULL
) {
713 bbase
[ilevel
] = bufbase
= bp
;
721 * dopaste - include a given file without any
725 dopaste(const char *pfile
)
730 if ((pf
= fopen(pfile
, "r")) != NULL
) {
732 fprintf(active
, "#line 1 \"%s\"\n", pfile
);
733 while ((c
= getc(pf
)) != EOF
)
744 * dochq - change quote characters
747 dochq(const char *argv
[], int ac
)
750 lquote
[0] = LQUOTE
; lquote
[1] = EOS
;
751 rquote
[0] = RQUOTE
; rquote
[1] = EOS
;
753 strlcpy(lquote
, argv
[2], sizeof(lquote
));
755 strlcpy(rquote
, argv
[3], sizeof(rquote
));
757 rquote
[0] = ECOMMT
; rquote
[1] = EOS
;
763 * dochc - change comment characters
766 dochc(const char *argv
[], int argc
)
768 /* XXX Note that there is no difference between no argument and a single
775 strlcpy(scommt
, argv
[2], sizeof(scommt
));
777 ecommt
[0] = ECOMMT
; ecommt
[1] = EOS
;
779 strlcpy(ecommt
, argv
[3], sizeof(ecommt
));
785 * dom4wrap - expand text at EOF
788 dom4wrap(const char *text
)
790 if (wrapindex
>= maxwraps
) {
795 m4wraps
= xrealloc(m4wraps
, maxwraps
* sizeof(*m4wraps
),
798 m4wraps
[wrapindex
++] = xstrdup(text
);
802 * dodivert - divert the output to a temporary file
814 n
= 0; /* bitbucket */
818 n
= 0; /* bitbucket */
819 if (outfile
[n
] == NULL
) {
820 char fname
[] = _PATH_DIVNAME
;
822 if ((fd
= mkstemp(fname
)) < 0 ||
823 (outfile
[n
] = fdopen(fd
, "w+")) == NULL
)
824 err(1, "%s: cannot divert", fname
);
825 if (unlink(fname
) == -1)
826 err(1, "%s: cannot unlink", fname
);
832 * doundivert - undivert a specified output, or all
833 * other outputs, in numerical order.
836 doundiv(const char *argv
[], int argc
)
842 for (ind
= 2; ind
< argc
; ind
++) {
844 n
= strtonum(argv
[ind
], 1, INT_MAX
, &errstr
);
846 if (errno
== EINVAL
&& mimic_gnu
)
847 getdivfile(argv
[ind
]);
849 if (n
< maxout
&& outfile
[n
] != NULL
)
855 for (n
= 1; n
< maxout
; n
++)
856 if (outfile
[n
] != NULL
)
861 * dosub - select substring
864 dosub(const char *argv
[], int argc
)
866 const char *ap
, *fc
, *k
;
869 ap
= argv
[2]; /* target string */
871 fc
= ap
+ expr(argv
[3]); /* first char */
873 fc
= ap
+ atoi(argv
[3]); /* first char */
878 nc
= min(nc
, expr(argv
[4]));
880 nc
= min(nc
, atoi(argv
[4]));
882 if (fc
>= ap
&& fc
< ap
+ strlen(ap
))
883 for (k
= fc
+ nc
- 1; k
>= fc
; k
--)
889 * map every character of s1 that is specified in from
890 * into s3 and replace in s. (source s1 remains untouched)
892 * This is a standard implementation of map(s,from,to) function of ICON
893 * language. Within mapvec, we replace every character of "from" with
894 * the corresponding character in "to". If "to" is shorter than "from",
895 * than the corresponding entries are null, which means that those
896 * characters dissapear altogether. Furthermore, imagine
897 * map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
898 * `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
899 * ultimately maps to `*'. In order to achieve this effect in an efficient
900 * manner (i.e. without multiple passes over the destination string), we
901 * loop over mapvec, starting with the initial source character. if the
902 * character value (dch) in this location is different than the source
903 * character (sch), sch becomes dch, once again to index into mapvec, until
904 * the character value stabilizes (i.e. sch = dch, in other words
905 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
906 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
907 * end, we restore mapvec* back to normal where mapvec[n] == n for
908 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
909 * about 5 times faster than any algorithm that makes multiple passes over
910 * destination string.
913 map(char *dest
, const char *src
, const char *from
, const char *to
)
916 unsigned char sch
, dch
;
917 static char frombis
[257];
918 static char tobis
[257];
919 static unsigned char mapvec
[256] = {
920 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
921 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
922 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
923 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
924 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
925 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
926 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
927 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
928 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
929 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
930 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
931 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
932 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
933 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
934 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
935 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
936 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
937 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
943 * expand character ranges on the fly
945 from
= handledash(frombis
, frombis
+ 256, from
);
946 to
= handledash(tobis
, tobis
+ 256, to
);
950 * create a mapping between "from" and
954 mapvec
[(unsigned char)(*from
++)] = (*to
) ?
955 (unsigned char)(*to
++) : 0;
958 sch
= (unsigned char)(*src
++);
964 if ((*dest
= (char)dch
))
968 * restore all the changed characters
971 mapvec
[(unsigned char)(*tmp
)] = (unsigned char)(*tmp
);
981 * use buffer to copy the src string, expanding character ranges
985 handledash(char *buffer
, char *end
, const char *src
)
991 if (src
[1] == '-' && src
[2]) {
993 if ((unsigned char)src
[0] <= (unsigned char)src
[2]) {
994 for (i
= (unsigned char)src
[0];
995 i
<= (unsigned char)src
[2]; i
++) {
1003 for (i
= (unsigned char)src
[0];
1004 i
>= (unsigned char)src
[2]; i
--) {