]> git.draconx.ca Git - cdecl99.git/commitdiff
Split out qualifier explanations from explain_post_specs.
authorNick Bowler <nbowler@draconx.ca>
Fri, 24 Jun 2011 13:42:53 +0000 (09:42 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 24 Jun 2011 13:42:53 +0000 (09:42 -0400)
They'll be needed on their own for pointer explanations.

src/explain.c

index d7edc741916c1222df40a9d79cbb583493afbb8f..823cb3a17fe23127ca64677981b9fb1a28120cdd 100644 (file)
@@ -26,42 +26,87 @@ static size_t output(char *buf, size_t n, size_t off, const char *fmt, ...)
        return ret;
 }
 
+static size_t advance(char **buf, size_t *n, size_t amount)
+{
+       if (!amount)
+               return 0;
+
+       if (amount >= *n) {
+               *n   = 0;
+               *buf = 0;
+       } else {
+               (*buf)[amount] = ' ';
+               if (amount + 1 >= *n) {
+                       *buf = 0;
+                       *n = 0;
+               } else {
+                       *buf += amount + 1;
+                       *n   -= amount + 1;
+               }
+       }
+
+       return amount + 1;
+}
+
+static size_t
+explain_qualifiers(char *buf, size_t n, struct cdecl_declspec *s)
+{
+       unsigned long qualmap = 0;
+       size_t ret = 0, rc = 0;
+
+       for (struct cdecl_declspec *c = s; c; c = c->next) {
+               if (cdecl_spec_kind(c) != CDECL_SPEC_QUAL)
+                       continue;
+               qualmap |= 1ul << (c->type & 0xff);
+       }
+
+       if (qualmap & (1ul << (CDECL_QUAL_RESTRICT & 0xff))) {
+               ret += advance(&buf, &n, rc);
+               rc = snprintf(buf, n, "restrict");
+       }
+       if (qualmap & (1ul << (CDECL_QUAL_VOLATILE & 0xff))) {
+               ret += advance(&buf, &n, rc);
+               rc = snprintf(buf, n, "volatile");
+       }
+       if (qualmap & (1ul << (CDECL_QUAL_CONST & 0xff))) {
+               ret += advance(&buf, &n, rc);
+               rc = snprintf(buf, n, "const");
+       }
+
+       return ret + rc;
+}
+
 /* Renders the type qualifiers and type specifiers in canonical form. */
 static size_t
 explain_post_specs(char *buf, size_t n, struct cdecl_declspec *s)
 {
-       unsigned long qualmap = 0, typemap;
        const char *tag = NULL;
-       size_t ret = 0;
+       unsigned long typemap;
+       size_t ret = 0, rc;
 
        typemap = cdecl__build_typemap(s);
        if (typemap == -1)
                return 0;
 
        for (struct cdecl_declspec *c = s; c; c = c->next) {
-               switch (cdecl_spec_kind(c)) {
-               case CDECL_SPEC_QUAL:
-                       qualmap |= 1ul << (c->type & 0xff);
-                       break;
-               case CDECL_SPEC_TYPE:
-                       /* Valid C types have at most one identifier. */
-                       if (c->ident)
-                               tag = c->ident;
-                       break;
-               }
+               if (cdecl_spec_kind(c) != CDECL_SPEC_TYPE)
+                       continue;
+
+               /* Valid C types have at most one identifier. */
+               if (c->ident)
+                       tag = c->ident;
        }
 
-       if (qualmap & (1ul << (CDECL_QUAL_RESTRICT & 0xff)))
-               ret += output(buf, n, ret, "restrict ");
-       if (qualmap & (1ul << (CDECL_QUAL_VOLATILE & 0xff)))
-               ret += output(buf, n, ret, "volatile ");
-       if (qualmap & (1ul << (CDECL_QUAL_CONST & 0xff)))
-               ret += output(buf, n, ret, "const ");
+       rc = explain_qualifiers(buf, n, s);
+       ret += advance(&buf, &n, rc);
 
-       ret += output(buf, n, ret, "%s", cdecl__explain_typemap(typemap));
-       if (tag)
-               ret += output(buf, n, ret, " %s", tag);
-       return ret;
+       rc = snprintf(buf, n, "%s", cdecl__explain_typemap(typemap));
+       if (tag) {
+               ret += advance(&buf, &n, rc);
+               rc = snprintf(buf, n, "%s", tag);
+       }
+
+       return ret + rc;
 }
 
 static const char *explain_storage(unsigned spec)
@@ -109,27 +154,6 @@ static size_t explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
        return ret;
 }
 
-static size_t advance(char **buf, size_t *n, size_t amount)
-{
-       if (!amount)
-               return 0;
-
-       if (amount >= *n) {
-               *n   = 0;
-               *buf = 0;
-       } else {
-               (*buf)[amount] = ' ';
-               if (amount + 1 >= *n) {
-                       *buf = 0;
-                       *n = 0;
-               } else {
-                       *buf += amount + 1;
-                       *n   -= amount + 1;
-               }
-       }
-
-       return amount + 1;
-}
 
 size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl)
 {