1 /* $OpenBSD: eval.c,v 1.66 2008/08/21 21:01:47 espie Exp $ */
2 /* $NetBSD: eval.c,v 1.23 2015/01/29 19:26:20 christos 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.23 2015/01/29 19:26:20 christos Exp $");
47 #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
= strtoi(argv
[3], NULL
, 0, 2, 36, &e
);
189 m4errx(1, "expr: base %s invalid.", argv
[3]);
193 maxdigits
= strtoi(argv
[4], NULL
, 0, 0, INT_MAX
, &e
);
195 m4errx(1, "expr: maxdigits %s invalid.", argv
[4]);
199 pbnumbase(expr(argv
[2]), base
, maxdigits
);
205 doifelse(argv
, argc
);
210 * doifdef - select one of two
211 * alternatives based on the existence of
215 if (lookup_macro_definition(argv
[2]) != NULL
)
224 * dolen - find the length of the
227 pbnum((argc
> 2) ? strlen(argv
[2]) : 0);
232 * doincr - increment the value of the
236 pbnum(atoi(argv
[2]) + 1);
241 * dodecr - decrement the value of the
245 pbnum(atoi(argv
[2]) - 1);
250 * dosys - execute system command
254 sysval
= system(argv
[2]);
260 * dosysval - return value of the last
273 if (!doincl(argv
[2]))
274 err(1, "%s at line %lu: include(%s)",
275 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
280 (void) doincl(argv
[2]);
285 if (!dopaste(argv
[2]))
286 err(1, "%s at line %lu: paste(%s)",
287 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
292 (void) dopaste(argv
[2]);
295 doformat(argv
, argc
);
308 * dosub - select substring
317 * doshift - push back all arguments
318 * except the first one (i.e. skip
322 for (n
= argc
- 1; n
> 3; n
--) {
335 if (argc
> 2 && (n
= atoi(argv
[2])) != 0)
349 * dodivnum - return the number of
350 * current output diversion
357 * doundefine - undefine a previously
358 * defined macro(s) or m4 keyword(s).
361 for (n
= 2; n
< argc
; n
++)
362 macro_undefine(argv
[n
]);
367 * dopopdef - remove the topmost
368 * definitions of macro(s) or m4
372 for (n
= 2; n
< argc
; n
++)
373 macro_popdef(argv
[n
]);
378 * dotemp - create a temporary file
384 temp
= xstrdup(argv
[2]);
389 "%s at line %lu: couldn't make temp file %s",
390 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
399 * dotranslit - replace all characters in
400 * the source string that appears in the
401 * "from" string with the corresponding
402 * characters in the "to" string.
407 temp
= xalloc(strlen(argv
[2])+1, NULL
);
409 map(temp
, argv
[2], argv
[3], argv
[4]);
411 map(temp
, argv
[2], argv
[3], null
);
420 * doindex - find the index of the second
421 * argument string in the first argument
422 * string. -1 if not present.
424 pbnum((argc
> 3) ? indx(argv
[2], argv
[3]) : -1);
429 * doerrp - print the arguments to stderr
433 for (n
= 2; n
< argc
; n
++)
434 fprintf(stderr
, "%s%s",
435 mimic_gnu
&& n
== 2 ? "" : " ",
438 fprintf(stderr
, "\n");
444 * dodnl - eat-up-to and including
447 while ((c
= gpbc()) != '\n' && c
!= EOF
)
453 * dom4wrap - set up for
454 * wrap-up/wind-down activity
462 * doexit - immediate exit from m4.
465 exit((argc
> 2) ? atoi(argv
[2]) : 0);
470 for (n
= 2; n
< argc
; n
++)
474 case INDIRTYPE
: /* Indirect call */
479 case BUILTINTYPE
: /* Builtins only */
481 dobuiltin(argv
, argc
);
486 dopatsubst(argv
, argc
);
490 doregexp(argv
, argc
);
493 doprintlineno(infile
+ilevel
);
496 doprintfilename(infile
+ilevel
);
504 m4errx(1, "eval: major botch.");
510 * expand_macro - user-defined macro expansion
513 expand_macro(const char *argv
[], int argc
)
520 t
= argv
[0]; /* defn string as a whole */
524 p
--; /* last character of defn */
526 if (*(p
- 1) != ARGFLAG
)
544 if ((argno
= *p
- '0') < argc
- 1)
545 pbstr(argv
[argno
+ 1]);
549 for (n
= argc
- 1; n
> 2; n
--) {
558 for (n
= argc
- 1; n
> 2; n
--) {
578 if (p
== t
) /* do last character */
584 * dodefine - install definition in the table
587 dodefine(const char *name
, const char *defn
)
589 if (!*name
&& !mimic_gnu
)
590 m4errx(1, "null definition.");
592 macro_define(name
, defn
);
596 * dodefn - push back a quoted definition of
600 dodefn(const char *name
)
602 struct macro_definition
*p
;
604 if ((p
= lookup_macro_definition(name
)) != NULL
) {
605 if ((p
->type
& TYPEMASK
) == MACRTYPE
) {
611 pbstr(BUILTIN_MARKER
);
617 * dopushdef - install a definition in the hash table
618 * without removing a previous definition. Since
619 * each new entry is entered in *front* of the
620 * hash bucket, it hides a previous definition from
624 dopushdef(const char *name
, const char *defn
)
626 if (!*name
&& !mimic_gnu
)
627 m4errx(1, "null definition.");
629 macro_pushdef(name
, defn
);
633 * dump_one_def - dump the specified definition.
636 dump_one_def(const char *name
, struct macro_definition
*p
)
641 if ((p
->type
& TYPEMASK
) == MACRTYPE
)
642 fprintf(traceout
, "%s:\t%s\n", name
, p
->defn
);
644 fprintf(traceout
, "%s:\t<%s>\n", name
, p
->defn
);
647 fprintf(traceout
, "`%s'\t`%s'\n", name
, p
->defn
);
651 * dodumpdef - dump the specified definitions in the hash
652 * table to stderr. If nothing is specified, the entire
653 * hash table is dumped.
656 dodump(const char *argv
[], int argc
)
659 struct macro_definition
*p
;
662 for (n
= 2; n
< argc
; n
++)
663 if ((p
= lookup_macro_definition(argv
[n
])) != NULL
)
664 dump_one_def(argv
[n
], p
);
666 macro_for_all(dump_one_def
);
670 * dotrace - mark some macros as traced/untraced depending upon on.
673 dotrace(const char *argv
[], int argc
, int on
)
678 for (n
= 2; n
< argc
; n
++)
679 mark_traced(argv
[n
], on
);
681 mark_traced(NULL
, on
);
685 * doifelse - select one of two alternatives - loop.
688 doifelse(const char *argv
[], int argc
)
691 if (STREQ(argv
[2], argv
[3]))
705 * doinclude - include a given file.
708 doincl(const char *ifile
)
710 if (ilevel
+ 1 == MAXINP
)
711 m4errx(1, "too many include files.");
712 if (fopen_trypath(infile
+ilevel
+1, ifile
) != NULL
) {
714 bbase
[ilevel
] = bufbase
= bp
;
722 * dopaste - include a given file without any
726 dopaste(const char *pfile
)
731 if ((pf
= fopen(pfile
, "r")) != NULL
) {
733 fprintf(active
, "#line 1 \"%s\"\n", pfile
);
734 while ((c
= getc(pf
)) != EOF
)
745 * dochq - change quote characters
748 dochq(const char *argv
[], int ac
)
751 lquote
[0] = LQUOTE
; lquote
[1] = EOS
;
752 rquote
[0] = RQUOTE
; rquote
[1] = EOS
;
754 strlcpy(lquote
, argv
[2], sizeof(lquote
));
756 strlcpy(rquote
, argv
[3], sizeof(rquote
));
758 rquote
[0] = ECOMMT
; rquote
[1] = EOS
;
764 * dochc - change comment characters
767 dochc(const char *argv
[], int argc
)
769 /* XXX Note that there is no difference between no argument and a single
776 strlcpy(scommt
, argv
[2], sizeof(scommt
));
778 ecommt
[0] = ECOMMT
; ecommt
[1] = EOS
;
780 strlcpy(ecommt
, argv
[3], sizeof(ecommt
));
786 * dom4wrap - expand text at EOF
789 dom4wrap(const char *text
)
791 if (wrapindex
>= maxwraps
) {
796 m4wraps
= xrealloc(m4wraps
, maxwraps
* sizeof(*m4wraps
),
799 m4wraps
[wrapindex
++] = xstrdup(text
);
803 * dodivert - divert the output to a temporary file
815 n
= 0; /* bitbucket */
819 n
= 0; /* bitbucket */
820 if (outfile
[n
] == NULL
) {
821 char fname
[] = _PATH_DIVNAME
;
823 if ((fd
= mkstemp(fname
)) < 0 ||
824 (outfile
[n
] = fdopen(fd
, "w+")) == NULL
)
825 err(1, "%s: cannot divert", fname
);
826 if (unlink(fname
) == -1)
827 err(1, "%s: cannot unlink", fname
);
833 * doundivert - undivert a specified output, or all
834 * other outputs, in numerical order.
837 doundiv(const char *argv
[], int argc
)
843 for (ind
= 2; ind
< argc
; ind
++) {
845 n
= strtoi(argv
[ind
], NULL
, 0, 1, INT_MAX
, &e
);
847 if (errno
== EINVAL
&& mimic_gnu
)
848 getdivfile(argv
[ind
]);
850 if (n
< maxout
&& outfile
[n
] != NULL
)
856 for (n
= 1; n
< maxout
; n
++)
857 if (outfile
[n
] != NULL
)
862 * dosub - select substring
865 dosub(const char *argv
[], int argc
)
867 const char *ap
, *fc
, *k
;
870 ap
= argv
[2]; /* target string */
872 fc
= ap
+ expr(argv
[3]); /* first char */
874 fc
= ap
+ atoi(argv
[3]); /* first char */
879 nc
= min(nc
, expr(argv
[4]));
881 nc
= min(nc
, atoi(argv
[4]));
883 if (fc
>= ap
&& fc
< ap
+ strlen(ap
))
884 for (k
= fc
+ nc
- 1; k
>= fc
; k
--)
890 * map every character of s1 that is specified in from
891 * into s3 and replace in s. (source s1 remains untouched)
893 * This is a standard implementation of map(s,from,to) function of ICON
894 * language. Within mapvec, we replace every character of "from" with
895 * the corresponding character in "to". If "to" is shorter than "from",
896 * than the corresponding entries are null, which means that those
897 * characters dissapear altogether. Furthermore, imagine
898 * map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
899 * `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
900 * ultimately maps to `*'. In order to achieve this effect in an efficient
901 * manner (i.e. without multiple passes over the destination string), we
902 * loop over mapvec, starting with the initial source character. if the
903 * character value (dch) in this location is different than the source
904 * character (sch), sch becomes dch, once again to index into mapvec, until
905 * the character value stabilizes (i.e. sch = dch, in other words
906 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
907 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
908 * end, we restore mapvec* back to normal where mapvec[n] == n for
909 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
910 * about 5 times faster than any algorithm that makes multiple passes over
911 * destination string.
914 map(char *dest
, const char *src
, const char *from
, const char *to
)
917 unsigned char sch
, dch
;
918 static char frombis
[257];
919 static char tobis
[257];
920 static unsigned char mapvec
[256] = {
921 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
922 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
923 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
924 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
925 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
926 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
927 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
928 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
929 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
930 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
931 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
932 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
933 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
934 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
935 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
936 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
937 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
938 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
944 * expand character ranges on the fly
946 from
= handledash(frombis
, frombis
+ 256, from
);
947 to
= handledash(tobis
, tobis
+ 256, to
);
951 * create a mapping between "from" and
955 mapvec
[(unsigned char)(*from
++)] = (*to
) ?
956 (unsigned char)(*to
++) : 0;
959 sch
= (unsigned char)(*src
++);
965 if ((*dest
= (char)dch
))
969 * restore all the changed characters
972 mapvec
[(unsigned char)(*tmp
)] = (unsigned char)(*tmp
);
982 * use buffer to copy the src string, expanding character ranges
986 handledash(char *buffer
, char *end
, const char *src
)
992 if (src
[1] == '-' && src
[2]) {
994 if ((unsigned char)src
[0] <= (unsigned char)src
[2]) {
995 for (i
= (unsigned char)src
[0];
996 i
<= (unsigned char)src
[2]; i
++) {
1004 for (i
= (unsigned char)src
[0];
1005 i
>= (unsigned char)src
[2]; i
--) {