]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Simplify declarator traversal logic.
authorNick Bowler <nbowler@draconx.ca>
Wed, 28 Jun 2023 05:07:59 +0000 (01:07 -0400)
committerNick Bowler <nbowler@draconx.ca>
Sun, 2 Jul 2023 00:16:06 +0000 (20:16 -0400)
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

index b9685ffc673d180a280d7da2bbbddfb478cbc7d1..0f660295e6963d3aaeeccc5e5dc8f3cc081c4267 100644 (file)
@@ -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))