From e745d25d7f109057962c6904be98f5f35e874ecc Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 25 Oct 2023 21:28:17 -0400 Subject: [PATCH] libcdecl: Simplify loop in cdecl__normalize_specs. Restructure the code a bit to make this loop a bit more straightforward. --- src/normalize.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/normalize.c b/src/normalize.c index 8cd0020..b326e2d 100644 --- a/src/normalize.c +++ b/src/normalize.c @@ -107,6 +107,12 @@ sort_specs(struct cdecl_declspec *l1, size_t n) return merge_specs(l1, l2); } +/* + * Mask to clear the type/storage specifier bits on one side of the comparison + * to ensure that only function specifiers and qualifiers comapare equal below. + */ +#define SPEC_DUP_MASK (~(CDECL_SPEC_TYPE|CDECL_SPEC_STOR|0u)) + /* * C allows declaration specifiers to appear in any order, and allows arbitrary * repetition of some kinds of specifiers. Normalize the specifier lists by @@ -120,16 +126,16 @@ struct cdecl_declspec *cdecl__normalize_specs(struct cdecl_declspec *specs) for (c = specs; c; c = c->next) count++; - specs = sort_specs(specs, count); - for (c = specs, l = NULL; c; l = c, c = c->next) { - if (!(c->type & (CDECL_SPEC_QUAL|CDECL_SPEC_FUNC))) - continue; + if (!(l = specs = sort_specs(specs, count))) + return NULL; - if (l && l->type == c->type) { + while ((c = l->next)) { + if ((l->type & SPEC_DUP_MASK) == c->type) { l->next = c->next; free(c); - c = l; + } else { + l = c; } } -- 2.43.2