1 /* $OpenBSD: eval.c,v 1.69 2011/03/24 11:23:08 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
35 * $FreeBSD: src/usr.bin/m4/eval.c,v 1.28 2012/11/17 01:54:24 svnexp Exp $
41 * Facility: m4 macro processor
45 #include <sys/types.h>
59 #include "pathnames.h"
61 static void dodefn(const char *);
62 static void dopushdef(const char *, const char *);
63 static void dodump(const char *[], int);
64 static void dotrace(const char *[], int, int);
65 static void doifelse(const char *[], int);
66 static int doincl(const char *);
67 static int dopaste(const char *);
68 static void dochq(const char *[], int);
69 static void dochc(const char *[], int);
70 static void dom4wrap(const char *);
71 static void dodiv(int);
72 static void doundiv(const char *[], int);
73 static void dosub(const char *[], int);
74 static void map(char *, const char *, const char *, const char *);
75 static const char *handledash(char *, char *, const char *);
76 static void expand_builtin(const char *[], int, int);
77 static void expand_macro(const char *[], int);
78 static void dump_one_def(const char *, struct macro_definition
*);
80 unsigned long expansion_id
;
83 * eval - eval all macros and builtins calls
84 * argc - number of elements in argv.
85 * argv - element vector :
86 * argv[0] = definition of a user
87 * macro or NULL if built-in.
88 * argv[1] = name of the macro or
90 * argv[2] = parameters to user-defined
91 * . macro or built-in.
94 * A call in the form of macro-or-builtin() will result in:
96 * argv[1] = macro-or-builtin
99 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
102 eval(const char *argv
[], int argc
, int td
, int is_traced
)
104 size_t mark
= SIZE_MAX
;
108 m4errx(1, "expanding recursive definition for %s.", argv
[1]);
110 mark
= trace(argv
, argc
, infile
+ ilevel
);
112 expand_macro(argv
, argc
);
114 expand_builtin(argv
, argc
, td
);
115 if (mark
!= SIZE_MAX
)
120 * expand_builtin - evaluate built-in macros.
123 expand_builtin(const char *argv
[], int argc
, int td
)
127 static int sysval
= 0;
130 printf("argc = %d\n", argc
);
131 for (n
= 0; n
< argc
; n
++)
132 printf("argv[%d] = %s\n", n
, argv
[n
]);
137 * if argc == 3 and argv[2] is null, then we
138 * have macro-or-builtin() type call. We adjust
139 * argc to avoid further checking.
141 /* we keep the initial value for those built-ins that differentiate
142 * between builtin() and builtin.
146 if (argc
== 3 && !*(argv
[2]) && !mimic_gnu
)
149 switch (td
& TYPEMASK
) {
153 dodefine(argv
[2], (argc
> 3) ? argv
[3] : null
);
158 dopushdef(argv
[2], (argc
> 3) ? argv
[3] : null
);
166 dotrace(argv
, argc
, 1);
170 dotrace(argv
, argc
, 0);
175 * doexpr - evaluate arithmetic
184 base
= strtonum(argv
[3], 2, 36, &errstr
);
186 m4errx(1, "expr: base %s invalid.", argv
[3]);
190 maxdigits
= strtonum(argv
[4], 0, INT_MAX
, &errstr
);
192 m4errx(1, "expr: maxdigits %s invalid.", argv
[4]);
196 pbnumbase(expr(argv
[2]), base
, maxdigits
);
202 doifelse(argv
, argc
);
207 * doifdef - select one of two
208 * alternatives based on the existence of
212 if (lookup_macro_definition(argv
[2]) != NULL
)
221 * dolen - find the length of the
224 pbnum((argc
> 2) ? strlen(argv
[2]) : 0);
229 * doincr - increment the value of the
233 pbnum(atoi(argv
[2]) + 1);
238 * dodecr - decrement the value of the
242 pbnum(atoi(argv
[2]) - 1);
247 * dosys - execute system command
251 sysval
= system(argv
[2]);
257 * dosysval - return value of the last
270 if (!doincl(argv
[2])) {
272 warn("%s at line %lu: include(%s)",
273 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
276 err(1, "%s at line %lu: include(%s)",
277 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
288 if (!dopaste(argv
[2]))
289 err(1, "%s at line %lu: paste(%s)",
290 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
298 doformat(argv
, argc
);
311 * dosub - select substring
320 * doshift - push back all arguments
321 * except the first one (i.e. skip
325 for (n
= argc
- 1; n
> 3; n
--) {
338 if (argc
> 2 && (n
= atoi(argv
[2])) != 0)
352 * dodivnum - return the number of
353 * current output diversion
360 * doundefine - undefine a previously
361 * defined macro(s) or m4 keyword(s).
364 for (n
= 2; n
< argc
; n
++)
365 macro_undefine(argv
[n
]);
370 * dopopdef - remove the topmost
371 * definitions of macro(s) or m4
375 for (n
= 2; n
< argc
; n
++)
376 macro_popdef(argv
[n
]);
381 * dotemp - create a temporary file
387 temp
= xstrdup(argv
[2]);
392 "%s at line %lu: couldn't make temp file %s",
393 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
402 * dotranslit - replace all characters in
403 * the source string that appears in the
404 * "from" string with the corresponding
405 * characters in the "to" string.
410 temp
= xalloc(strlen(argv
[2]) + 1, NULL
);
412 map(temp
, argv
[2], argv
[3], argv
[4]);
414 map(temp
, argv
[2], argv
[3], null
);
423 * doindex - find the index of the second
424 * argument string in the first argument
425 * string. -1 if not present.
427 pbnum((argc
> 3) ? indx(argv
[2], argv
[3]) : -1);
432 * doerrp - print the arguments to stderr
436 for (n
= 2; n
< argc
; n
++)
437 fprintf(stderr
, "%s ", argv
[n
]);
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
);
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 derived from the a standard implementation of map(s,from,to)
893 * function of ICON language. Within mapvec, we replace every character
894 * of "from" with the corresponding character in "to".
895 * If "to" is shorter than "from", than the corresponding entries are null,
896 * which means that those characters dissapear altogether.
899 map(char *dest
, const char *src
, const char *from
, const char *to
)
902 unsigned char sch
, dch
;
903 static char frombis
[257];
904 static char tobis
[257];
907 static unsigned char mapvec
[256] = {
908 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
909 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
910 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
911 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
912 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
913 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
914 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
915 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
916 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
917 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
918 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
919 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
920 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
921 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
922 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
923 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
924 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
925 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
931 * expand character ranges on the fly
933 from
= handledash(frombis
, frombis
+ 256, from
);
934 to
= handledash(tobis
, tobis
+ 256, to
);
938 * create a mapping between "from" and
941 for (i
= 0; i
< 256; i
++)
944 if (!seen
[(unsigned char)(*from
)]) {
945 mapvec
[(unsigned char)(*from
)] = (unsigned char)(*to
);
946 seen
[(unsigned char)(*from
)] = 1;
954 sch
= (unsigned char)(*src
++);
956 if ((*dest
= (char)dch
))
960 * restore all the changed characters
963 mapvec
[(unsigned char)(*tmp
)] = (unsigned char)(*tmp
);
973 * use buffer to copy the src string, expanding character ranges
977 handledash(char *buffer
, char *end
, const char *src
)
983 if (src
[1] == '-' && src
[2]) {
985 if ((unsigned char)src
[0] <= (unsigned char)src
[2]) {
986 for (i
= (unsigned char)src
[0];
987 i
<= (unsigned char)src
[2]; i
++) {
995 for (i
= (unsigned char)src
[0];
996 i
>= (unsigned char)src
[2]; i
--) {