]> git.draconx.ca Git - cdecl99.git/commitdiff
Don't gratuitously reject inline specifiers.
authorNick Bowler <nbowler@draconx.ca>
Thu, 7 Jul 2011 00:39:47 +0000 (20:39 -0400)
committerNick Bowler <nbowler@draconx.ca>
Thu, 7 Jul 2011 00:52:11 +0000 (20:52 -0400)
We actually do support functions now, so we need to handle inline.
Turns out the last user of the old output routines (the code that
prints "inline") didn't actually work properly, so port it over to
the new interface.

src/explain.c
src/parse-decl.c

index 8c86530bc7318aeaafec3f97b0dd9da802cedc9a..a0b1449694fb1bb27be6079ea0327dcaffdd2ebf 100644 (file)
 #include "cdecl.h"
 #include "typemap.h"
 
-/* declare [ident] as [storage] [function specs] [other crap] [qualifiers] [type specs] */
-
-static size_t
-voutput(char *buf, size_t n, size_t off, const char *fmt, va_list ap)
-{
-       if (off >= n)
-               return vsnprintf(NULL, 0, fmt, ap);
-       return vsnprintf(buf+off, n-off, fmt, ap);
-}
-
-static size_t output(char *buf, size_t n, size_t off, const char *fmt, ...)
-{
-       va_list ap;
-       size_t ret;
-
-       va_start(ap, fmt);
-       ret = voutput(buf, n, off, fmt, ap);
-       va_end(ap);
-
-       return ret;
-}
-
 static size_t advance_(char **buf, size_t *n, size_t amount)
 {
        if (amount >= *n) {
@@ -132,19 +110,19 @@ explain_post_specs(char *buf, size_t n, struct cdecl_declspec *s)
        return ret + rc;
 }
 
-static const char *explain_storage(unsigned spec)
+static size_t explain_storage(char *buf, size_t n, unsigned spec)
 {
        switch (spec) {
        case CDECL_STOR_TYPEDEF:
-               return "typedef";
+               return snprintf(buf, n, "typedef");
        case CDECL_STOR_EXTERN:
-               return "extern";
+               return snprintf(buf, n, "extern");
        case CDECL_STOR_STATIC:
-               return "static";
+               return snprintf(buf, n, "static");
        case CDECL_STOR_AUTO:
-               return "auto";
+               return snprintf(buf, n, "auto");
        case CDECL_STOR_REGISTER:
-               return "register";
+               return snprintf(buf, n, "register");
        default:
                assert(0);
        }
@@ -154,8 +132,7 @@ static const char *explain_storage(unsigned spec)
 static size_t explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
 {
        unsigned long funcmap = 0;
-       const char *storage = NULL;
-       size_t ret = 0;
+       size_t ret = 0, rc = 0;
 
        for (struct cdecl_declspec *c = s; c; c = c->next) {
                switch (cdecl_spec_kind(c)) {
@@ -165,16 +142,17 @@ static size_t explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
                case CDECL_SPEC_STOR:
                        /* Valid C declarations have at most one
                         * storage-class specifier. */
-                       storage = explain_storage(c->type);
+                       rc = explain_storage(buf, n, c->type);
                        break;
                }
        }
 
-       if (storage)
-               ret += output(buf, n, ret, "%s", storage);
-       if (funcmap & (1ul << (CDECL_FUNC_INLINE & 0xff)))
-               ret += output(buf, n, ret, "%.*s%s", !!ret, "", "inline");
-       return ret;
+       if (funcmap & (1ul << (CDECL_FUNC_INLINE & 0xff))) {
+               ret += advance(&buf, &n, rc);
+               rc = snprintf(buf, n, "inline");
+       }
+
+       return ret + rc;
 }
 
 /*
index bedd30ebaa14eec8102e5a65216a5acb80508f7d..b5212ec2d0109da6776c7a2ab348340dcebfd040 100644 (file)
@@ -65,11 +65,11 @@ static bool valid_declspecs(struct cdecl *decl)
                        }
                        break;
                case CDECL_SPEC_FUNC:
-                       /*
-                        * We don't support functions yet.
-                        */
-                       fprintf(stderr, "only function declarations may have function specifiers.\n");
-                       return false;
+                       if (d->type != CDECL_DECL_FUNCTION) {
+                               fprintf(stderr, "only function declarations may have function specifiers.\n");
+                               return false;
+                       }
+                       break;
                default:
                        assert(0);
                }