]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Simplify loop in cdecl__normalize_specs.
authorNick Bowler <nbowler@draconx.ca>
Thu, 26 Oct 2023 01:28:17 +0000 (21:28 -0400)
committerNick Bowler <nbowler@draconx.ca>
Thu, 26 Oct 2023 01:28:17 +0000 (21:28 -0400)
Restructure the code a bit to make this loop a bit more straightforward.

src/normalize.c

index 8cd002047a4fc5cbabd590b007bbddd01d593d1e..b326e2d12c0374800669d3aa66a5056190685e85 100644 (file)
@@ -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;
                }
        }