From 42f53d5e9ac7a02c1b899b0786194611eae56a56 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Thu, 22 Jun 2023 21:24:19 -0400 Subject: [PATCH] libcdecl: Rework cdecl_declare output logic. Instead of adjusting the output pointer/length values after each internal call, tweak all the functions in declare.c to take an extra level of indirection so they can just directly adjust the destination as they go. --- src/declare.c | 130 +++++++++++++++++++++----------------------------- 1 file changed, 55 insertions(+), 75 deletions(-) diff --git a/src/declare.c b/src/declare.c index 3b0b700..8f7d607 100644 --- a/src/declare.c +++ b/src/declare.c @@ -19,129 +19,111 @@ #include #include #include +#include #include #include "cdecl.h" #include "cdecl-internal.h" static size_t -declare_declarator(char *buf, size_t n, struct cdecl_declarator *d); +declare_declarator(char **dst, size_t *dstlen, struct cdecl_declarator *d); -static size_t declare_decl(char *buf, size_t n, struct cdecl *decl) +static size_t declare_decl(char **dst, size_t *dstlen, struct cdecl *decl) { - size_t ret = 0, rc; + size_t ret, rc; - rc = cdecl__explain_specs(buf, n, decl->specifiers, -1); + rc = cdecl__explain_specs(*dst, *dstlen, decl->specifiers, -1); if (decl->declarators->type != CDECL_DECL_NULL) - ret += cdecl__advance(&buf, &n, rc); + ret = cdecl__advance(dst, dstlen, rc); else - ret += cdecl__advance_(&buf, &n, rc); + ret = cdecl__advance_(dst, dstlen, rc); - return ret + declare_declarator(buf, n, decl->declarators); + return ret + declare_declarator(dst, dstlen, decl->declarators); } static size_t -declare_postfix_child(char *buf, size_t n, struct cdecl_declarator *d) +declare_postfix_child(char **dst, size_t *dstlen, struct cdecl_declarator *d) { - size_t ret = 0, rc; + size_t ret = 0; - if (d->type == CDECL_DECL_POINTER) { - rc = snprintf(buf, n, "("); - ret += cdecl__advance_(&buf, &n, rc); - } + if (d->type == CDECL_DECL_POINTER) + ret += cdecl__emit(dst, dstlen, "("); - rc = declare_declarator(buf, n, d); - ret += cdecl__advance_(&buf, &n, rc); + ret += declare_declarator(dst, dstlen, d); - if (d->type == CDECL_DECL_POINTER) { - rc = snprintf(buf, n, ")"); - ret += cdecl__advance_(&buf, &n, rc); - } + if (d->type == CDECL_DECL_POINTER) + ret += cdecl__emit(dst, dstlen, ")"); return ret; } -static size_t declare_pointer(char *buf, size_t n, struct cdecl_pointer *p) +static size_t +declare_pointer(char **dst, size_t *dstlen, struct cdecl_pointer *p) { - size_t ret = 0, rc; - - rc = snprintf(buf, n, "*"); - if (p->qualifiers) - ret += cdecl__advance(&buf, &n, rc); - else - ret += cdecl__advance_(&buf, &n, rc); - - rc = cdecl__explain_specs(buf, n, p->qualifiers, CDECL_SPEC_QUAL); - return ret + rc; -} + struct cdecl_declspec *q = p->qualifiers; -static bool pointer_needs_space(struct cdecl_declarator *d) -{ - assert(d->type == CDECL_DECL_POINTER); + if (q) { + size_t ret, rc; - if (d->u.pointer.qualifiers) - return d->child->type != CDECL_DECL_NULL; + ret = cdecl__emit(dst, dstlen, "* "); + rc = cdecl__explain_specs(*dst, *dstlen, q, -1); + return ret + cdecl__advance(dst, dstlen, rc); + } - return false; + return cdecl__emit(dst, dstlen, "*"); } -static size_t declare_array(char *buf, size_t n, struct cdecl_array *a) +static size_t declare_array(char **dst, size_t *dstlen, struct cdecl_array *a) { - size_t ret = 0, rc; + size_t ret; - rc = snprintf(buf, n, "["); - ret += cdecl__advance_(&buf, &n, rc); + ret = cdecl__emit(dst, dstlen, "["); - if (a->vla) - rc = snprintf(buf, n, "%s", a->vla[0] ? a->vla : "*"); - else - rc = snprintf(buf, n, "%.0ju", a->length); - ret += cdecl__advance_(&buf, &n, rc); + if (a->vla) { + const char *s = a->vla[0] ? a->vla : "*"; + ret += cdecl__emit(dst, dstlen, s); + } else { + size_t rc = snprintf(*dst, *dstlen, "%.0" PRIuMAX, a->length); + ret += cdecl__advance_(dst, dstlen, rc); + } - return ret + snprintf(buf, n, "]"); + return ret + cdecl__emit(dst, dstlen, "]"); } -static size_t declare_function(char *buf, size_t n, struct cdecl_function *f) +static size_t +declare_function(char **dst, size_t *dstlen, struct cdecl_function *f) { - size_t ret = 0, rc; + struct cdecl *p; + size_t ret; - rc = snprintf(buf, n, "("); - ret += cdecl__advance_(&buf, &n, rc); + ret = cdecl__emit(dst, dstlen, "("); - for (struct cdecl *p = f->parameters; p; p = p->next) { - rc = declare_decl(buf, n, p); - ret += cdecl__advance_(&buf, &n, rc); + for (p = f->parameters; p; p = p->next) { + ret += declare_decl(dst, dstlen, p); - rc = 0; if (p->next) - rc = snprintf(buf, n, ", "); + ret += cdecl__emit(dst, dstlen, ", "); else if (f->variadic) - rc = snprintf(buf, n, ", ..."); - ret += cdecl__advance_(&buf, &n, rc); + ret += cdecl__emit(dst, dstlen, ", ..."); } - return ret + snprintf(buf, n, ")"); + return ret + cdecl__emit(dst, dstlen, ")"); } static size_t -declare_declarator(char *buf, size_t n, struct cdecl_declarator *d) +declare_declarator(char **dst, size_t *dstlen, struct cdecl_declarator *d) { - size_t ret = 0, rc; + size_t ret = 0; for (; d; d = d->child) { switch (d->type) { case CDECL_DECL_NULL: break; case CDECL_DECL_IDENT: - rc = snprintf(buf, n, "%s", d->u.ident); - ret += cdecl__advance_(&buf, &n, rc); + ret += cdecl__emit(dst, dstlen, d->u.ident); break; case CDECL_DECL_POINTER: - rc = declare_pointer(buf, n, &d->u.pointer); - if (pointer_needs_space(d)) - ret += cdecl__advance(&buf, &n, rc); - else - ret += cdecl__advance_(&buf, &n, rc); + ret += declare_pointer(dst, dstlen, &d->u.pointer); break; /* * Arrays and functions are special: since they are postfix, @@ -149,13 +131,11 @@ declare_declarator(char *buf, size_t n, struct cdecl_declarator *d) * "bodies". */ case CDECL_DECL_ARRAY: - rc = declare_postfix_child(buf, n, d->child); - ret += cdecl__advance_(&buf, &n, rc); - return ret + declare_array(buf, n, &d->u.array); + ret += declare_postfix_child(dst, dstlen, d->child); + return ret + declare_array(dst, dstlen, &d->u.array); case CDECL_DECL_FUNCTION: - rc = declare_postfix_child(buf, n, d->child); - ret += cdecl__advance_(&buf, &n, rc); - return ret + declare_function(buf, n, &d->u.function); + ret += declare_postfix_child(dst, dstlen, d->child); + return ret + declare_function(dst, dstlen, &d->u.function); default: assert(0); } @@ -166,5 +146,5 @@ declare_declarator(char *buf, size_t n, struct cdecl_declarator *d) size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl) { - return declare_decl(buf, n, decl); + return declare_decl(&buf, &n, decl); } -- 2.43.2