diff options
Diffstat (limited to 'src/tree.c')
-rw-r--r-- | src/tree.c | 63 |
1 files changed, 43 insertions, 20 deletions
@@ -62,6 +62,19 @@ grecs_value_free(struct grecs_value *val) grecs_free(val); } +const char * +grecs_value_type_string(int t) +{ + static const char *types[] = { + [GRECS_TYPE_STRING] = N_("string"), + [GRECS_TYPE_LIST] = N_("list"), + [GRECS_TYPE_ARRAY] = N_("one or more arguments") + }; + if (t >= 0 && t < sizeof(types) / sizeof(types[0])) + return types[t]; + return N_("unrecognized type; please report"); +} + struct grecs_node * grecs_node_create(enum grecs_node_type type, grecs_locus_t *loc) { @@ -286,14 +299,32 @@ static struct grecs_keyword fake = { }; static struct grecs_keyword * -find_keyword(struct grecs_keyword *cursect, const char *ident) +find_keyword(struct grecs_keyword *cursect, grecs_node_t *node) { - struct grecs_keyword *kwp; - if (cursect && cursect->kwd && cursect != &fake) { - for (kwp = cursect->kwd; kwp->ident; kwp++) - if (strcmp(kwp->ident, ident) == 0) - return kwp; + struct grecs_keyword *found = NULL, *kwp; + char const *msg; + + for (kwp = cursect->kwd; kwp->ident; kwp++) { + if (strcmp(kwp->ident, node->ident) == 0) { + found = kwp; + if (kwp->callback + || node->down + ? kwp->type == grecs_type_section + : kwp->type != grecs_type_section) + return kwp; + } + } + if (found) { + if (found->type == grecs_type_section) { + msg = N_("section keyword used as a scalar"); + } else { + msg = N_("scalar keyword used as a section"); + } + } else { + msg = N_("unknown keyword"); + } + grecs_error(&node->idloc, 0, "%s", gettext(msg)); } else { return &fake; } @@ -915,21 +946,17 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) switch (op) { case grecs_tree_recurse_set: - kwp = find_keyword(clos->cursect, node->ident); - if (!kwp) { - grecs_error(&node->idloc, 0, _("Unknown keyword")); + kwp = find_keyword(clos->cursect, node); + if (!kwp) return grecs_tree_recurse_skip; - } grecs_process_ident(kwp, node->v.value, CURRENT_BASE(clos), &node->idloc); break; case grecs_tree_recurse_pre: - kwp = find_keyword(clos->cursect, node->ident); - if (!kwp) { - grecs_error(&node->locus, 0, _("Unknown keyword")); + kwp = find_keyword(clos->cursect, node); + if (!kwp) return grecs_tree_recurse_skip; - } stmt_begin(clos, kwp, node); break; @@ -1136,13 +1163,9 @@ reduceproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) } else { struct grecs_keyword *kwp = NULL; if (clos->cursect) { - kwp = find_keyword(clos->cursect, node->ident); - if (!kwp) { - grecs_error(&node->locus, 0, - _("%s: unknown keyword"), - node->ident); + kwp = find_keyword(clos->cursect, node); + if (!kwp) return grecs_tree_recurse_skip; - } if (kwp->flags & GRECS_INAC) return grecs_tree_recurse_skip; if (!(kwp->flags & GRECS_MULT) && |