* consist of alnums and '-'. We don't permit whitespace between the '@'
* and the name. */
dynstr_init(d);
- if(input == end || !isalnum((unsigned char)*input))
- fatal(0, "%s:%d: invalid expansion", filename, e->line);
+ if(input == end)
+ fatal(0, "%s:%d: invalid expansion syntax (truncated)",
+ filename, e->line);
+ if(!isalnum((unsigned char)*input))
+ fatal(0, "%s:%d: invalid expansion syntax (unexpected %#x)",
+ filename, e->line, (unsigned char)*input);
while(input < end && (isalnum((unsigned char)*input) || *input == '-'))
dynstr_append(d, *input++);
dynstr_terminate(d);
case '(': cbracket = ')'; break;
case '[': cbracket = ']'; break;
case '{': cbracket = '}'; break;
- default: obracket = -1; break; /* no arguments */
+ default: cbracket = obracket = -1; break; /* no arguments */
}
mx_node_vector_init(v);
if(obracket >= 0) {
e->args = args;
e->callback = callback;
e->definition = definition;
- return hash_add(expansions, name, &e,
- ((flags & EXP_TYPE_MASK) == EXP_MACRO)
- ? HASH_INSERT : HASH_INSERT_OR_REPLACE);
+ return hash_add(expansions, name, &e, HASH_INSERT_OR_REPLACE);
}
/** @brief Register a simple expansion rule
const struct mx_node *definition) {
if(mx__register(EXP_MACRO, name, nargs, nargs, args, 0/*callback*/,
definition)) {
+#if 0
/* This locates the error to the definition, which may be a line or two
* beyond the @define command itself. The backtrace generated by
* mx_expand() may help more. */
error(0, "%s:%d: duplicate definition of '%s'",
definition->filename, definition->line, name);
+#endif
return -2;
}
return 0;
*/
const struct mx_node *mx_rewrite(const struct mx_node *definition,
hash *h) {
- const struct mx_node *head = 0, **tailp = &head, *argvalue, *m, *mm;
+ const struct mx_node *head = 0, **tailp = &head, *argvalue, *m, *mm, **ap;
struct mx_node *nm;
int n;
break;
case MX_EXPANSION:
if(m->nargs == 0
- && (argvalue = *(const struct mx_node **)hash_find(h, m->name))) {
+ && (ap = hash_find(h, m->name))) {
/* This expansion has no arguments and its name matches one of the
* macro arguments. (Even if it's a valid expansion name we override
* it.) We insert its value at this point. We do NOT recursively
* We need to recreate the list structure but a shallow copy will
* suffice here.
*/
+ argvalue = *ap;
for(mm = argvalue; mm; mm = mm->next) {
nm = xmalloc(sizeof *nm);
*nm = *mm;