1 /* $OpenBSD: eval.c,v 1.74 2015/02/05 12:59:57 millert 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]);
285 (void) doincl(argv
[2]);
290 if (!dopaste(argv
[2]))
291 err(1, "%s at line %lu: paste(%s)",
292 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
297 (void) dopaste(argv
[2]);
300 doformat(argv
, argc
);
313 * dosub - select substring
322 * doshift - push back all arguments
323 * except the first one (i.e. skip
327 for (n
= argc
- 1; n
> 3; n
--) {
340 if (argc
> 2 && (n
= atoi(argv
[2])) != 0)
354 * dodivnum - return the number of
355 * current output diversion
362 * doundefine - undefine a previously
363 * defined macro(s) or m4 keyword(s).
366 for (n
= 2; n
< argc
; n
++)
367 macro_undefine(argv
[n
]);
372 * dopopdef - remove the topmost
373 * definitions of macro(s) or m4
377 for (n
= 2; n
< argc
; n
++)
378 macro_popdef(argv
[n
]);
383 * dotemp - create a temporary file
389 temp
= xstrdup(argv
[2]);
394 "%s at line %lu: couldn't make temp file %s",
395 CURRENT_NAME
, CURRENT_LINE
, argv
[2]);
404 * dotranslit - replace all characters in
405 * the source string that appears in the
406 * "from" string with the corresponding
407 * characters in the "to" string.
412 temp
= xalloc(strlen(argv
[2])+1, NULL
);
414 map(temp
, argv
[2], argv
[3], argv
[4]);
416 map(temp
, argv
[2], argv
[3], null
);
425 * doindex - find the index of the second
426 * argument string in the first argument
427 * string. -1 if not present.
429 pbnum((argc
> 3) ? indx(argv
[2], argv
[3]) : -1);
434 * doerrp - print the arguments to stderr
438 for (n
= 2; n
< argc
; n
++)
439 fprintf(stderr
, "%s ", argv
[n
]);
440 fprintf(stderr
, "\n");
446 * dodnl - eat-up-to and including
449 while ((c
= gpbc()) != '\n' && c
!= EOF
)
455 * dom4wrap - set up for
456 * wrap-up/wind-down activity
464 * doexit - immediate exit from m4.
467 exit((argc
> 2) ? atoi(argv
[2]) : 0);
472 for (n
= 2; n
< argc
; n
++)
476 case INDIRTYPE
: /* Indirect call */
481 case BUILTINTYPE
: /* Builtins only */
483 dobuiltin(argv
, argc
);
488 dopatsubst(argv
, argc
);
492 doregexp(argv
, argc
);
495 doprintlineno(infile
+ilevel
);
498 doprintfilename(infile
+ilevel
);
506 m4errx(1, "eval: major botch.");
512 * expand_macro - user-defined macro expansion
515 expand_macro(const char *argv
[], int argc
)
522 t
= argv
[0]; /* defn string as a whole */
526 p
--; /* last character of defn */
528 if (*(p
- 1) != ARGFLAG
)
546 if ((argno
= *p
- '0') < argc
- 1)
547 pbstr(argv
[argno
+ 1]);
551 for (n
= argc
- 1; n
> 2; n
--) {
560 for (n
= argc
- 1; n
> 2; n
--) {
580 if (p
== t
) /* do last character */
586 * dodefine - install definition in the table
589 dodefine(const char *name
, const char *defn
)
591 if (!*name
&& !mimic_gnu
)
592 m4errx(1, "null definition.");
594 macro_define(name
, defn
);
598 * dodefn - push back a quoted definition of
602 dodefn(const char *name
)
604 struct macro_definition
*p
;
606 if ((p
= lookup_macro_definition(name
)) != NULL
) {
607 if ((p
->type
& TYPEMASK
) == MACRTYPE
) {
613 pbstr(BUILTIN_MARKER
);
619 * dopushdef - install a definition in the hash table
620 * without removing a previous definition. Since
621 * each new entry is entered in *front* of the
622 * hash bucket, it hides a previous definition from
626 dopushdef(const char *name
, const char *defn
)
628 if (!*name
&& !mimic_gnu
)
629 m4errx(1, "null definition.");
631 macro_pushdef(name
, defn
);
635 * dump_one_def - dump the specified definition.
638 dump_one_def(const char *name
, struct macro_definition
*p
)
643 if ((p
->type
& TYPEMASK
) == MACRTYPE
)
644 fprintf(traceout
, "%s:\t%s\n", name
, p
->defn
);
646 fprintf(traceout
, "%s:\t<%s>\n", name
, p
->defn
);
649 fprintf(traceout
, "`%s'\t`%s'\n", name
, p
->defn
);
653 * dodumpdef - dump the specified definitions in the hash
654 * table to stderr. If nothing is specified, the entire
655 * hash table is dumped.
658 dodump(const char *argv
[], int argc
)
661 struct macro_definition
*p
;
664 for (n
= 2; n
< argc
; n
++)
665 if ((p
= lookup_macro_definition(argv
[n
])) != NULL
)
666 dump_one_def(argv
[n
], p
);
668 macro_for_all(dump_one_def
);
672 * dotrace - mark some macros as traced/untraced depending upon on.
675 dotrace(const char *argv
[], int argc
, int on
)
680 for (n
= 2; n
< argc
; n
++)
681 mark_traced(argv
[n
], on
);
683 mark_traced(NULL
, on
);
687 * doifelse - select one of two alternatives - loop.
690 doifelse(const char *argv
[], int argc
)
693 if (STREQ(argv
[2], argv
[3]))
707 * doinclude - include a given file.
710 doincl(const char *ifile
)
712 if (ilevel
+ 1 == MAXINP
)
713 m4errx(1, "too many include files.");
714 if (fopen_trypath(infile
+ilevel
+1, ifile
) != NULL
) {
716 bbase
[ilevel
] = bufbase
= bp
;
724 * dopaste - include a given file without any
728 dopaste(const char *pfile
)
733 if ((pf
= fopen(pfile
, "r")) != NULL
) {
735 fprintf(active
, "#line 1 \"%s\"\n", pfile
);
736 while ((c
= getc(pf
)) != EOF
)
747 * dochq - change quote characters
750 dochq(const char *argv
[], int ac
)
753 lquote
[0] = LQUOTE
; lquote
[1] = EOS
;
754 rquote
[0] = RQUOTE
; rquote
[1] = EOS
;
756 strlcpy(lquote
, argv
[2], sizeof(lquote
));
758 strlcpy(rquote
, argv
[3], sizeof(rquote
));
760 rquote
[0] = ECOMMT
; rquote
[1] = EOS
;
766 * dochc - change comment characters
769 dochc(const char *argv
[], int argc
)
771 /* XXX Note that there is no difference between no argument and a single
778 strlcpy(scommt
, argv
[2], sizeof(scommt
));
780 ecommt
[0] = ECOMMT
; ecommt
[1] = EOS
;
782 strlcpy(ecommt
, argv
[3], sizeof(ecommt
));
788 * dom4wrap - expand text at EOF
791 dom4wrap(const char *text
)
793 if (wrapindex
>= maxwraps
) {
798 m4wraps
= xreallocarray(m4wraps
, maxwraps
, sizeof(*m4wraps
),
801 m4wraps
[wrapindex
++] = xstrdup(text
);
805 * dodivert - divert the output to a temporary file
817 n
= 0; /* bitbucket */
821 n
= 0; /* bitbucket */
822 if (outfile
[n
] == NULL
) {
823 char fname
[] = _PATH_DIVNAME
;
825 if ((fd
= mkstemp(fname
)) < 0 ||
826 unlink(fname
) == -1 ||
827 (outfile
[n
] = fdopen(fd
, "w+")) == NULL
)
828 err(1, "%s: cannot divert", 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 disappear 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
--) {