return head;
}
+static void mx__dump(struct dynstr *d, const struct mx_node *m) {
+ int n;
+
+ if(!m)
+ return;
+ switch(m->type) {
+ case MX_TEXT:
+ dynstr_append_string(d, m->text);
+ break;
+ case MX_EXPANSION:
+ dynstr_append(d, '@');
+ dynstr_append_string(d, m->name);
+ for(n = 0; n < m->nargs; ++n) {
+ dynstr_append(d, '{');
+ mx__dump(d, m->args[n]);
+ dynstr_append(d, '}');
+ }
+ dynstr_append(d, '@');
+ break;
+ default:
+ assert(!"invalid m->type");
+ }
+ mx__dump(d, m->next);
+}
+
+/** @brief Dump a parse macro expansion to a string */
+char *mx_dump(const struct mx_node *m) {
+ struct dynstr d[1];
+
+ dynstr_init(d);
+ mx__dump(d, m);
+ dynstr_terminate(d);
+ return d->vec;
+}
+
/*
Local Variables:
c-basic-offset:2
insist(m->line == 1);
check_string(m->text, L1 L2);
insist(m->next == 0);
+ check_string(mx_dump(m), plain);
/* Check that partial parses stop in the right place */
m = mx_parse("plaintext2", 5, plain, plain + strlen(L1));
insist(m->line == 5);
check_string(m->text, L1);
insist(m->next == 0);
+ check_string(mx_dump(m), L1);
/* The simplest possible expansion */
m = mx_parse("macro1", 1, "@macro@", NULL);
insist(m->nargs == 0);
insist(m->args == 0);
insist(m->next == 0);
+ check_string(mx_dump(m), "@macro@");
/* Spacing variants of the above */
m = mx_parse("macro2", 1, "@ macro@", NULL);
insist(m->nargs == 0);
insist(m->args == 0);
insist(m->next == 0);
+ check_string(mx_dump(m), "@macro@");
m = mx_parse("macro3", 1, "@macro @", NULL);
insist(m->type == MX_EXPANSION);
check_string(m->filename, "macro3");
insist(m->nargs == 0);
insist(m->args == 0);
insist(m->next == 0);
+ check_string(mx_dump(m), "@macro@");
/* Unterminated variants */
m = mx_parse("macro4", 1, "@macro", NULL);
insist(m->nargs == 0);
insist(m->args == 0);
insist(m->next == 0);
+ check_string(mx_dump(m), "@macro@");
m = mx_parse("macro5", 1, "@macro ", NULL);
insist(m->type == MX_EXPANSION);
check_string(m->filename, "macro5");
insist(m->nargs == 0);
insist(m->args == 0);
insist(m->next == 0);
+ check_string(mx_dump(m), "@macro@");
/* Macros with a :-separated argument */
m = mx_parse("macro5", 1, "@macro:arg@", NULL);
check_string(m->args[0]->text, "arg");
insist(m->args[0]->next == 0);
+ check_string(mx_dump(m), "@macro{arg}@");
+
/* Multiple :-separated arguments, and spacing, and newlines */
m = mx_parse("macro6", 1, "@macro : \n arg1 : \n arg2@", NULL);
insist(m->type == MX_EXPANSION);
check_string(m->args[1]->text, "arg2");
insist(m->args[1]->next == 0);
+ check_string(mx_dump(m), "@macro{arg1}{arg2}@");
+
+ /* Multiple bracketed arguments */
}