From: Nick Bowler Date: Thu, 26 Oct 2023 01:28:17 +0000 (-0400) Subject: libcdecl: Simplify loop in cdecl__normalize_specs. X-Git-Tag: v1.3~85 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/e745d25d7f109057962c6904be98f5f35e874ecc libcdecl: Simplify loop in cdecl__normalize_specs. Restructure the code a bit to make this loop a bit more straightforward. --- 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; } }