From 248d73924d6136eee0497a7456aba90bfef633e3 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Fri, 30 Jun 2023 01:24:12 -0400 Subject: [PATCH] libcdecl: Simplify reduce_parentheses implementation. Simplify the reduce_parentheses implementation so it operates in a much more straightforward way. We can also just call simplify_functions directly during the same tree traversal, instead of trying to predict what simplify_functions will do to a node on a later traversal. --- src/parse-decl.c | 76 ++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/src/parse-decl.c b/src/parse-decl.c index f156ba9..6ab624e 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -254,58 +254,52 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d) * simplify_functions pass. */ -static int -reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d) +static struct cdecl *fake_function_param(struct cdecl_declarator *d) { struct cdecl *param; if (d->type != CDECL_DECL_FUNCTION) - return 0; + return NULL; param = d->u.function.parameters; - if (param && param->specifiers == NULL) { - struct cdecl_declarator *decl; + if (!param || param->specifiers) + return NULL; - assert(!param->next); + assert(!param->next); + return param; +} - decl = param->declarators; - if (decl->type == CDECL_DECL_NULL) { - free(decl); - free(param); - d->u.function.parameters = NULL; - return 0; - } +static int +reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d) +{ + struct cdecl *param; + int fake = 0; + + while ((param = fake_function_param(d))) { + struct cdecl_declarator *decl = param->declarators; + d->u.function.parameters = NULL; + + if (decl->type != CDECL_DECL_NULL) { + if (d->child->type != CDECL_DECL_NULL) { + /* Found fake parameter on real function. */ + d->u.function.parameters = param; + cdecl__errmsg(CDECL__EBADPARAM); + return -1; + } - if (d->child->type != CDECL_DECL_NULL) { - cdecl__errmsg(CDECL__EBADPARAM); - return -1; + param->declarators = d; + *p = d = decl; + fake = 1; } - free(d->child); - free(param); - free(d); - *p = decl; - - /* - * We may have replaced d with another fake function which - * also needs to be eliminated. - */ - if (reduce_parentheses(p, decl) < 0) - return -1; - - /* - * If the remaining declarator is a function, make sure it's - * valid by checking its reducibility. - */ - decl = *p; - if (decl->type == CDECL_DECL_FUNCTION - && decl->child->type == CDECL_DECL_NULL - && !function_is_reducible(decl)) { - cdecl__errmsg(CDECL__EMANYPAREN); - return -1; - } + cdecl__free(param); + } - return 0; + simplify_functions(p, d); + if (fake && (*p)->type == CDECL_DECL_FUNCTION) { + /* Started with a fake function but ended with a real one. */ + cdecl__errmsg(CDECL__EMANYPAREN); + return -1; } return 0; @@ -512,8 +506,6 @@ static int do_postprocess(struct cdecl *decl, int english_mode) if (!english_mode) { if (forall_declarators(i, reduce_parentheses) < 0) return 0; - if (forall_declarators(i, simplify_functions) < 0) - return 0; } if (forall_declarators(i, postproc_common) < 0) -- 2.43.2