* @param h Hash mapping argument names to argument values
* @return Rewritten parse tree
*/
-static const struct mx_node *mx__rewrite(const struct mx_node *m,
+static const struct mx_node *mx__rewrite(const struct mx_node *definition,
hash *h) {
- const struct mx_node *head = 0, **tailp = &head, *argvalue, *mm;
+ const struct mx_node *head = 0, **tailp = &head, *argvalue, *m, *mm;
struct mx_node *nm;
int n;
- for(; m; m = m->next) {
+ for(m = definition; m; m = m->next) {
switch(m->type) {
case MX_TEXT:
nm = xmalloc(sizeof *nm);
* values according to h. */
nm = xmalloc(sizeof *nm);
*nm = *m;
+ nm->args = xcalloc(nm->nargs, sizeof (struct mx_node *));
for(n = 0; n < nm->nargs; ++n)
nm->args[n] = mx__rewrite(m->args[n], h);
nm->next = 0;
check_integer(mx_expandstr(m, &s, 0/*u*/, NAME), 0); \
if(s && strcmp(s, OUTPUT)) { \
fprintf(stderr, "%s:%d: test %s\n" \
- " INPUT: %s\n" \
+ " INPUT:\n%s\n" \
" EXPECTED: '%s'\n" \
" GOT: '%s'\n", \
__FILE__, __LINE__, NAME, INPUT, OUTPUT, s); \
check_macro("macro1", "@define{m}{a b c}{@c@ @b@ @a@}@"
"@m{1}{2}{3}",
"3 2 1");
+ check_macro("macro2", "@m{b}{c}{a}",
+ "a c b");
+ check_macro("macro3", "@m{@eq{z}{z}}{p}{q}",
+ "q p true");
+ check_macro("macro4",
+ "@discard{\n"
+ " @define{n}{a b c}\n"
+ " {@if{@eq{@a@}{@b@}} {@c@} {no}}\n"
+ "}@"
+ "@n{x}{y}{z}",
+ "no");
+ check_macro("macro5",
+ "@n{x}{x}{z}",
+ "z");
+
}
TEST(macros);