X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/54ca2ed1ca173c7818792b6b06d12b8536acb6f3..41d0e2f8f2dc0ec50526ff6e4b8ff12936d1f90e:/src/explain.c diff --git a/src/explain.c b/src/explain.c index dadc65f..0d9c957 100644 --- a/src/explain.c +++ b/src/explain.c @@ -1,6 +1,6 @@ /* * Render C declarations as English. - * Copyright © 2011 Nick Bowler + * Copyright © 2011, 2021 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,121 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + +#include #include #include #include +#include #include #include #include "cdecl.h" -#include "typemap.h" -#include "output.h" - -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 += cdecl__advance(&buf, &n, rc); - rc = snprintf(buf, n, "restrict"); - } - if (qualmap & (1ul << (CDECL_QUAL_VOLATILE & 0xff))) { - ret += cdecl__advance(&buf, &n, rc); - rc = snprintf(buf, n, "volatile"); - } - if (qualmap & (1ul << (CDECL_QUAL_CONST & 0xff))) { - ret += cdecl__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) -{ - const char *tag = NULL; - 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) { - if (cdecl_spec_kind(c) != CDECL_SPEC_TYPE) - continue; - - /* Valid C types have at most one identifier. */ - if (c->ident) - tag = c->ident; - } - - rc = explain_qualifiers(buf, n, s); - ret += cdecl__advance(&buf, &n, rc); - - rc = snprintf(buf, n, "%s", cdecl__explain_typemap(typemap)); - if (tag) { - ret += cdecl__advance(&buf, &n, rc); - rc = snprintf(buf, n, "%s", tag); - } - - return ret + rc; -} - -static size_t explain_storage(char *buf, size_t n, unsigned spec) -{ - switch (spec) { - case CDECL_STOR_TYPEDEF: - return snprintf(buf, n, "typedef"); - case CDECL_STOR_EXTERN: - return snprintf(buf, n, "extern"); - case CDECL_STOR_STATIC: - return snprintf(buf, n, "static"); - case CDECL_STOR_AUTO: - return snprintf(buf, n, "auto"); - case CDECL_STOR_REGISTER: - return snprintf(buf, n, "register"); - default: - assert(0); - } -} - -/* Renders the storage-class and function specifiers in canonical form. */ -static size_t explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s) -{ - unsigned long funcmap = 0; - size_t ret = 0, rc = 0; - - for (struct cdecl_declspec *c = s; c; c = c->next) { - switch (cdecl_spec_kind(c)) { - case CDECL_SPEC_FUNC: - funcmap |= 1ul << (c->type & 0xff); - break; - case CDECL_SPEC_STOR: - /* Valid C declarations have at most one - * storage-class specifier. */ - rc = explain_storage(buf, n, c->type); - break; - } - } - - if (funcmap & (1ul << (CDECL_FUNC_INLINE & 0xff))) { - ret += cdecl__advance(&buf, &n, rc); - rc = snprintf(buf, n, "inline"); - } - - return ret + rc; -} +#include "cdecl-internal.h" /* * Renders the start of the thing being declared. If top is true, print @@ -155,6 +51,8 @@ explain_prologue(char *buf, size_t n, struct cdecl_declarator *d, bool top) d = d->child; } + + assert(0); } static size_t @@ -162,7 +60,7 @@ explain_pointer(char *buf, size_t n, struct cdecl_pointer *p) { size_t ret = 0, rc; - rc = explain_qualifiers(buf, n, p->qualifiers); + rc = cdecl__explain_specs(buf, n, p->qualifiers, CDECL_SPEC_QUAL); ret += cdecl__advance(&buf, &n, rc); return ret + snprintf(buf, n, "pointer to"); @@ -183,7 +81,7 @@ explain_array(char *buf, size_t n, struct cdecl_array *a) rc = snprintf(buf, n, "%s", a->vla); ret += cdecl__advance(&buf, &n, rc); } else if (a->length) { - rc = snprintf(buf, n, "%ju", a->length); + rc = snprintf(buf, n, "%" PRIuMAX, a->length); ret += cdecl__advance(&buf, &n, rc); } @@ -200,13 +98,13 @@ static size_t explain_decl(char *buf, size_t n, struct cdecl *decl, bool top) rc = explain_prologue(buf, n, decl->declarators, top); ret += cdecl__advance(&buf, &n, rc); - rc = explain_pre_specs(buf, n, decl->specifiers); + rc = cdecl__explain_pre_specs(buf, n, decl->specifiers); ret += cdecl__advance(&buf, &n, rc); rc = explain_declarators(buf, n, decl->declarators); ret += cdecl__advance(&buf, &n, rc); - return ret + explain_post_specs(buf, n, decl->specifiers); + return ret + cdecl__explain_post_specs(buf, n, decl->specifiers); } static size_t explain_function(char *buf, size_t n, struct cdecl_function *f)