1 /* $OpenBSD: eval.c,v 1.66 2008/08/21 21:01:47 espie Exp $ */
2 /* $NetBSD: eval.c,v 1.20 2009/10/26 21:11:28 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.20 2009/10/26 21:11:28 christos Exp $");
47 #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]))
272 err(1, "%s at line %lu: include(%s)",
273 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
278 (void) doincl(argv
[2]);
283 if (!dopaste(argv
[2]))
284 err(1, "%s at line %lu: paste(%s)",
285 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
290 (void) dopaste(argv
[2]);
293 doformat(argv
, argc
);
306 * dosub - select substring
315 * doshift - push back all arguments
316 * except the first one (i.e. skip
320 for (n
= argc
- 1; n
> 3; n
--) {
333 if (argc
> 2 && (n
= atoi(argv
[2])) != 0)
347 * dodivnum - return the number of
348 * current output diversion
355 * doundefine - undefine a previously
356 * defined macro(s) or m4 keyword(s).
359 for (n
= 2; n
< argc
; n
++)
360 macro_undefine(argv
[n
]);
365 * dopopdef - remove the topmost
366 * definitions of macro(s) or m4
370 for (n
= 2; n
< argc
; n
++)
371 macro_popdef(argv
[n
]);
376 * dotemp - create a temporary file
382 temp
= xstrdup(argv
[2]);
387 "%s at line %lu: couldn't make temp file %s",
388 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
397 * dotranslit - replace all characters in
398 * the source string that appears in the
399 * "from" string with the corresponding
400 * characters in the "to" string.
405 temp
= xalloc(strlen(argv
[2])+1, NULL
);
407 map(temp
, argv
[2], argv
[3], argv
[4]);
409 map(temp
, argv
[2], argv
[3], null
);
418 * doindex - find the index of the second
419 * argument string in the first argument
420 * string. -1 if not present.
422 pbnum((argc
> 3) ? indx(argv
[2], argv
[3]) : -1);
427 * doerrp - print the arguments to stderr
431 for (n
= 2; n
< argc
; n
++)
432 fprintf(stderr
, "%s ", argv
[n
]);
433 fprintf(stderr
, "\n");
439 * dodnl - eat-up-to and including
442 while ((c
= gpbc()) != '\n' && c
!= EOF
)
448 * dom4wrap - set up for
449 * wrap-up/wind-down activity
457 * doexit - immediate exit from m4.
460 exit((argc
> 2) ? atoi(argv
[2]) : 0);
465 for (n
= 2; n
< argc
; n
++)
469 case INDIRTYPE
: /* Indirect call */
474 case BUILTINTYPE
: /* Builtins only */
476 dobuiltin(argv
, argc
);
481 dopatsubst(argv
, argc
);
485 doregexp(argv
, argc
);
488 doprintlineno(infile
+ilevel
);
491 doprintfilename(infile
+ilevel
);
499 m4errx(1, "eval: major botch.");
505 * expand_macro - user-defined macro expansion
508 expand_macro(const char *argv
[], int argc
)
515 t
= argv
[0]; /* defn string as a whole */
519 p
--; /* last character of defn */
521 if (*(p
- 1) != ARGFLAG
)
539 if ((argno
= *p
- '0') < argc
- 1)
540 pbstr(argv
[argno
+ 1]);
544 for (n
= argc
- 1; n
> 2; n
--) {
553 for (n
= argc
- 1; n
> 2; n
--) {
573 if (p
== t
) /* do last character */
579 * dodefine - install definition in the table
582 dodefine(const char *name
, const char *defn
)
584 if (!*name
&& !mimic_gnu
)
585 m4errx(1, "null definition.");
587 macro_define(name
, defn
);
591 * dodefn - push back a quoted definition of
595 dodefn(const char *name
)
597 struct macro_definition
*p
;
599 if ((p
= lookup_macro_definition(name
)) != NULL
) {
600 if ((p
->type
& TYPEMASK
) == MACRTYPE
) {
606 pbstr(BUILTIN_MARKER
);
612 * dopushdef - install a definition in the hash table
613 * without removing a previous definition. Since
614 * each new entry is entered in *front* of the
615 * hash bucket, it hides a previous definition from
619 dopushdef(const char *name
, const char *defn
)
621 if (!*name
&& !mimic_gnu
)
622 m4errx(1, "null definition.");
624 macro_pushdef(name
, defn
);
628 * dump_one_def - dump the specified definition.
631 dump_one_def(const char *name
, struct macro_definition
*p
)
636 if ((p
->type
& TYPEMASK
) == MACRTYPE
)
637 fprintf(traceout
, "%s:\t%s\n", name
, p
->defn
);
639 fprintf(traceout
, "%s:\t<%s>\n", name
, p
->defn
);
642 fprintf(traceout
, "`%s'\t`%s'\n", name
, p
->defn
);
646 * dodumpdef - dump the specified definitions in the hash
647 * table to stderr. If nothing is specified, the entire
648 * hash table is dumped.
651 dodump(const char *argv
[], int argc
)
654 struct macro_definition
*p
;
657 for (n
= 2; n
< argc
; n
++)
658 if ((p
= lookup_macro_definition(argv
[n
])) != NULL
)
659 dump_one_def(argv
[n
], p
);
661 macro_for_all(dump_one_def
);
665 * dotrace - mark some macros as traced/untraced depending upon on.
668 dotrace(const char *argv
[], int argc
, int on
)
673 for (n
= 2; n
< argc
; n
++)
674 mark_traced(argv
[n
], on
);
676 mark_traced(NULL
, on
);
680 * doifelse - select one of two alternatives - loop.
683 doifelse(const char *argv
[], int argc
)
686 if (STREQ(argv
[2], argv
[3]))
700 * doinclude - include a given file.
703 doincl(const char *ifile
)
705 if (ilevel
+ 1 == MAXINP
)
706 m4errx(1, "too many include files.");
707 if (fopen_trypath(infile
+ilevel
+1, ifile
) != NULL
) {
709 bbase
[ilevel
] = bufbase
= bp
;
717 * dopaste - include a given file without any
721 dopaste(const char *pfile
)
726 if ((pf
= fopen(pfile
, "r")) != NULL
) {
728 fprintf(active
, "#line 1 \"%s\"\n", pfile
);
729 while ((c
= getc(pf
)) != EOF
)
740 * dochq - change quote characters
743 dochq(const char *argv
[], int ac
)
746 lquote
[0] = LQUOTE
; lquote
[1] = EOS
;
747 rquote
[0] = RQUOTE
; rquote
[1] = EOS
;
749 strlcpy(lquote
, argv
[2], sizeof(lquote
));
751 strlcpy(rquote
, argv
[3], sizeof(rquote
));
753 rquote
[0] = ECOMMT
; rquote
[1] = EOS
;
759 * dochc - change comment characters
762 dochc(const char *argv
[], int argc
)
764 /* XXX Note that there is no difference between no argument and a single
771 strlcpy(scommt
, argv
[2], sizeof(scommt
));
773 ecommt
[0] = ECOMMT
; ecommt
[1] = EOS
;
775 strlcpy(ecommt
, argv
[3], sizeof(ecommt
));
781 * dom4wrap - expand text at EOF
784 dom4wrap(const char *text
)
786 if (wrapindex
>= maxwraps
) {
791 m4wraps
= xrealloc(m4wraps
, maxwraps
* sizeof(*m4wraps
),
794 m4wraps
[wrapindex
++] = xstrdup(text
);
798 * dodivert - divert the output to a temporary file
810 n
= 0; /* bitbucket */
814 n
= 0; /* bitbucket */
815 if (outfile
[n
] == NULL
) {
816 char fname
[] = _PATH_DIVNAME
;
818 if ((fd
= mkstemp(fname
)) < 0 ||
819 (outfile
[n
] = fdopen(fd
, "w+")) == NULL
)
820 err(1, "%s: cannot divert", fname
);
821 if (unlink(fname
) == -1)
822 err(1, "%s: cannot unlink", fname
);
828 * doundivert - undivert a specified output, or all
829 * other outputs, in numerical order.
832 doundiv(const char *argv
[], int argc
)
838 for (ind
= 2; ind
< argc
; ind
++) {
840 n
= strtonum(argv
[ind
], 1, INT_MAX
, &errstr
);
842 if (errno
== EINVAL
&& mimic_gnu
)
843 getdivfile(argv
[ind
]);
845 if (n
< maxout
&& outfile
[n
] != NULL
)
851 for (n
= 1; n
< maxout
; n
++)
852 if (outfile
[n
] != NULL
)
857 * dosub - select substring
860 dosub(const char *argv
[], int argc
)
862 const char *ap
, *fc
, *k
;
865 ap
= argv
[2]; /* target string */
867 fc
= ap
+ expr(argv
[3]); /* first char */
869 fc
= ap
+ atoi(argv
[3]); /* first char */
874 nc
= min(nc
, expr(argv
[4]));
876 nc
= min(nc
, atoi(argv
[4]));
878 if (fc
>= ap
&& fc
< ap
+ strlen(ap
))
879 for (k
= fc
+ nc
- 1; k
>= fc
; k
--)
885 * map every character of s1 that is specified in from
886 * into s3 and replace in s. (source s1 remains untouched)
888 * This is a standard implementation of map(s,from,to) function of ICON
889 * language. Within mapvec, we replace every character of "from" with
890 * the corresponding character in "to". If "to" is shorter than "from",
891 * than the corresponding entries are null, which means that those
892 * characters dissapear altogether. Furthermore, imagine
893 * map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
894 * `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
895 * ultimately maps to `*'. In order to achieve this effect in an efficient
896 * manner (i.e. without multiple passes over the destination string), we
897 * loop over mapvec, starting with the initial source character. if the
898 * character value (dch) in this location is different than the source
899 * character (sch), sch becomes dch, once again to index into mapvec, until
900 * the character value stabilizes (i.e. sch = dch, in other words
901 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
902 * character, it will stabilize, since mapvec[0] == 0 at all times. At the
903 * end, we restore mapvec* back to normal where mapvec[n] == n for
904 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
905 * about 5 times faster than any algorithm that makes multiple passes over
906 * destination string.
909 map(char *dest
, const char *src
, const char *from
, const char *to
)
912 unsigned char sch
, dch
;
913 static char frombis
[257];
914 static char tobis
[257];
915 static unsigned char mapvec
[256] = {
916 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
917 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
918 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
919 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
920 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
921 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
922 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
923 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
924 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
925 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
926 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
927 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
928 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
929 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
930 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
931 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
932 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
933 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
939 * expand character ranges on the fly
941 from
= handledash(frombis
, frombis
+ 256, from
);
942 to
= handledash(tobis
, tobis
+ 256, to
);
946 * create a mapping between "from" and
950 mapvec
[(unsigned char)(*from
++)] = (*to
) ?
951 (unsigned char)(*to
++) : 0;
954 sch
= (unsigned char)(*src
++);
960 if ((*dest
= (char)dch
))
964 * restore all the changed characters
967 mapvec
[(unsigned char)(*tmp
)] = (unsigned char)(*tmp
);
977 * use buffer to copy the src string, expanding character ranges
981 handledash(char *buffer
, char *end
, const char *src
)
987 if (src
[1] == '-' && src
[2]) {
989 if ((unsigned char)src
[0] <= (unsigned char)src
[2]) {
990 for (i
= (unsigned char)src
[0];
991 i
<= (unsigned char)src
[2]; i
++) {
999 for (i
= (unsigned char)src
[0];
1000 i
>= (unsigned char)src
[2]; i
--) {