From: Nick Bowler Date: Fri, 24 Jun 2011 13:42:53 +0000 (-0400) Subject: Split out qualifier explanations from explain_post_specs. X-Git-Tag: v1~166 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/fcd93c0b8e80cad01140edba2bfb57252b11cfbc Split out qualifier explanations from explain_post_specs. They'll be needed on their own for pointer explanations. --- diff --git a/src/explain.c b/src/explain.c index d7edc74..823cb3a 100644 --- a/src/explain.c +++ b/src/explain.c @@ -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) {