]> git.draconx.ca Git - cdecl99.git/blobdiff - src/explain.c
Don't gratuitously reject inline specifiers.
[cdecl99.git] / src / explain.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;
 }
 
 /*