From: Nick Bowler Date: Thu, 7 Jul 2011 00:39:47 +0000 (-0400) Subject: Don't gratuitously reject inline specifiers. X-Git-Tag: v1~147 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/e378d431539e029bdf2fc87f56ccb59d48608b97 Don't gratuitously reject inline specifiers. 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. --- diff --git a/src/explain.c b/src/explain.c index 8c86530..a0b1449 100644 --- a/src/explain.c +++ b/src/explain.c @@ -24,28 +24,6 @@ #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; } /* diff --git a/src/parse-decl.c b/src/parse-decl.c index bedd30e..b5212ec 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -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); }