From f522ffe295db90f2072c70ae3583a5f0d064677d Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 28 Jun 2023 01:07:59 -0400 Subject: [PATCH] libcdecl: Simplify declarator traversal logic. It seems unnecessary to handle the case where the traversal function modifies the subtree differently from the case where the function does not modify the subtree. So we only have to deal with two cases for the traversal function's return value, which allows us to simplify a bit. --- src/parse-decl.c | 51 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/parse-decl.c b/src/parse-decl.c index b9685ff..0f66029 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -230,7 +230,7 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d) free(d->child); free(d); - return 1; + return 0; } /* @@ -305,7 +305,7 @@ reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d) return -1; } - return 1; + return 0; } return 0; @@ -435,36 +435,37 @@ check_qualifiers(struct cdecl_declarator **p, struct cdecl_declarator *d) * depth-first preorder traversal. The function is given a pointer to the * declarator as well as to the pointer which was used to reach that * declarator: this can be used to rewrite entire subtrees. + * + * The called function may return a negative value to indicate an error + * which terminates traversal. + * + * Returns 0 on success, or a negative value on failure. */ -static bool forall_declarators(struct cdecl *decl, +static int forall_declarators(struct cdecl *decl, int f(struct cdecl_declarator **, struct cdecl_declarator *)) { struct cdecl_declarator *d, **p; - for (p = &decl->declarators, d = *p; d; p = &d->child, d = *p) { - switch (f(p, d)) { - case 0: - break; - case 1: - d = *p; - break; - case -1: - return false; - default: - assert(0); - } + for (p = &decl->declarators; *p; p = &d->child) { + int rc; + + rc = f(p, *p); + if (rc < 0) + return rc; + d = *p; if (d->type == CDECL_DECL_FUNCTION) { struct cdecl *i; for (i = d->u.function.parameters; i; i = i->next) { - if (!forall_declarators(i, f)) - return false; + rc = forall_declarators(i, f); + if (rc < 0) + return rc; } } } - return true; + return 0; } static struct cdecl *do_parse(const char *str, int english_mode) @@ -510,21 +511,21 @@ static int do_postprocess(struct cdecl *decl, int english_mode) for (i = decl; i; i = i->next) { if (!english_mode) { - if (!forall_declarators(i, reduce_parentheses)) + if (forall_declarators(i, reduce_parentheses) < 0) return 0; - if (!forall_declarators(i, simplify_functions)) + if (forall_declarators(i, simplify_functions) < 0) return 0; } - if (!forall_declarators(i, check_parameters)) + if (forall_declarators(i, check_parameters) < 0) return 0; - if (!forall_declarators(i, check_rettypes)) + if (forall_declarators(i, check_rettypes) < 0) return 0; - if (!forall_declarators(i, check_arrays)) + if (forall_declarators(i, check_arrays) < 0) return 0; - if (!forall_declarators(i, normalize_specs)) + if (forall_declarators(i, normalize_specs) < 0) return 0; - if (!forall_declarators(i, check_qualifiers)) + if (forall_declarators(i, check_qualifiers) < 0) return 0; if (!valid_declspecs(i, true)) -- 2.43.2