X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/056280bf2e3188551539d87852ddbdaf322eae52..0b2a2978f09f5d9b56d8655dd60eaffbe9006b7a:/src/explain.c diff --git a/src/explain.c b/src/explain.c index 4deadac..e6b4f16 100644 --- a/src/explain.c +++ b/src/explain.c @@ -27,21 +27,18 @@ #define PRE_SPECS (CDECL_SPEC_FUNC|CDECL_SPEC_STOR) #define POST_SPECS (CDECL_SPEC_QUAL|CDECL_SPEC_TYPE) -static size_t explain_specs(char **dst, size_t *dstlen, struct cdecl_declspec *s, unsigned mask) +static size_t explain_specs(struct output_state *dst, struct cdecl_declspec *s, unsigned mask) { - size_t rc; + size_t ret; - rc = cdecl__explain_specs(*dst, *dstlen, s, mask); - return cdecl__advance(dst, dstlen, rc); + ret = cdecl__emit_specs(dst, s, mask); + return ret + cdecl__emit(dst, " " + !ret); } static size_t -explain_specs_post(char **dst, size_t *dstlen, struct cdecl_declspec *s) +explain_specs_post(struct output_state *dst, struct cdecl_declspec *s) { - size_t rc; - - rc = cdecl__explain_specs(*dst, *dstlen, s, POST_SPECS); - return cdecl__advance_(dst, dstlen, rc); + return cdecl__emit_specs(dst, s, POST_SPECS); } /* @@ -49,7 +46,7 @@ explain_specs_post(char **dst, size_t *dstlen, struct cdecl_declspec *s) * emit nothing. */ static size_t -explain_name(char **dst, size_t *dstlen, struct cdecl_declarator *d) +explain_name(struct output_state *dst, struct cdecl_declarator *d) { size_t ret; @@ -59,8 +56,8 @@ explain_name(char **dst, size_t *dstlen, struct cdecl_declarator *d) if (d->type != CDECL_DECL_IDENT) return 0; - ret = cdecl__emit(dst, dstlen, d->u.ident); - return ret + cdecl__emit(dst, dstlen, " as "); + ret = cdecl__emit(dst, d->u.ident); + return ret + cdecl__emit(dst, " as "); } /* @@ -68,12 +65,12 @@ explain_name(char **dst, size_t *dstlen, struct cdecl_declarator *d) * QUAL is the (possibly empty) list of qualifiers. */ static size_t -explain_pointer(char **dst, size_t *dstlen, struct cdecl_pointer *p) +explain_pointer(struct output_state *dst, struct cdecl_pointer *p) { size_t ret; - ret = explain_specs(dst, dstlen, p->qualifiers, -1); - return ret + cdecl__emit(dst, dstlen, "pointer to "); + ret = explain_specs(dst, p->qualifiers, -1); + return ret + cdecl__emit(dst, "pointer to "); } /* @@ -82,36 +79,36 @@ explain_pointer(char **dst, size_t *dstlen, struct cdecl_pointer *p) * and for normal arrays X is the (possibly omitted) length. */ static size_t -explain_array(char **dst, size_t *dstlen, struct cdecl_array *a) +explain_array(struct output_state *dst, struct cdecl_array *a) { size_t ret = 0, rc = 0; if (a->vla) - ret += cdecl__emit(dst, dstlen, "variable-length "); - ret += cdecl__emit(dst, dstlen, "array "); + ret += cdecl__emit(dst, "variable-length "); + ret += cdecl__emit(dst, "array "); if (a->vla) { - rc = cdecl__emit(dst, dstlen, a->vla); + rc = cdecl__emit(dst, a->vla); ret += rc; } else { - rc = snprintf(*dst, *dstlen, "%.0" PRIuMAX, a->length); - ret += cdecl__advance_(dst, dstlen, rc); + rc = snprintf(dst->dst, dst->dstlen, "%.0" PRIuMAX, a->length); + ret += cdecl__advance(dst, rc); } - return ret + cdecl__emit(dst, dstlen, " of " + !rc); + return ret + cdecl__emit(dst, " of " + !rc); } static size_t -explain_declarators(char **dst, size_t *dstlen, struct cdecl_declarator *decl); +explain_declarators(struct output_state *dst, struct cdecl_declarator *decl); -static size_t explain_decl(char **dst, size_t *dstlen, struct cdecl *decl) +static size_t explain_decl(struct output_state *dst, struct cdecl *decl) { size_t ret; - ret = explain_name(dst, dstlen, decl->declarators); - ret += explain_specs(dst, dstlen, decl->specifiers, PRE_SPECS); - ret += explain_declarators(dst, dstlen, decl->declarators); - ret += explain_specs_post(dst, dstlen, decl->specifiers); + ret = explain_name(dst, decl->declarators); + ret += explain_specs(dst, decl->specifiers, PRE_SPECS); + ret += explain_declarators(dst, decl->declarators); + ret += explain_specs_post(dst, decl->specifiers); return ret; } @@ -122,49 +119,49 @@ static size_t explain_decl(char **dst, size_t *dstlen, struct cdecl *decl) * list) parameter or identifier lists enclosed in parentheses. */ static size_t -explain_function(char **dst, size_t *dstlen, struct cdecl_function *f) +explain_function(struct output_state *dst, struct cdecl_function *f) { size_t ret = 0; - ret += cdecl__emit(dst, dstlen, "function "); + ret += cdecl__emit(dst, "function "); if (f->parameters) { struct cdecl *p; - ret += cdecl__emit(dst, dstlen, "("); + ret += cdecl__emit(dst, "("); for (p = f->parameters; p; p = p->next) { - ret += explain_decl(dst, dstlen, p); + ret += explain_decl(dst, p); if (p->next) - ret += cdecl__emit(dst, dstlen, ", "); + ret += cdecl__emit(dst, ", "); } if (f->variadic) - ret += cdecl__emit(dst, dstlen, ", ...) "); + ret += cdecl__emit(dst, ", ...) "); else - ret += cdecl__emit(dst, dstlen, ") "); + ret += cdecl__emit(dst, ") "); } - return ret + cdecl__emit(dst, dstlen, "returning "); + return ret + cdecl__emit(dst, "returning "); } static size_t -explain_declarators(char **dst, size_t *dstlen, struct cdecl_declarator *d) +explain_declarators(struct output_state *dst, struct cdecl_declarator *d) { size_t ret; if (d->type == CDECL_DECL_IDENT || d->type == CDECL_DECL_NULL) return 0; - ret = explain_declarators(dst, dstlen, d->child); + ret = explain_declarators(dst, d->child); switch (d->type) { case CDECL_DECL_POINTER: - return ret + explain_pointer(dst, dstlen, &d->u.pointer); + return ret + explain_pointer(dst, &d->u.pointer); case CDECL_DECL_ARRAY: - return ret + explain_array(dst, dstlen, &d->u.array); + return ret + explain_array(dst, &d->u.array); case CDECL_DECL_FUNCTION: - return ret + explain_function(dst, dstlen, &d->u.function); + return ret + explain_function(dst, &d->u.function); default: assert(0); } @@ -172,12 +169,13 @@ explain_declarators(char **dst, size_t *dstlen, struct cdecl_declarator *d) size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl) { + struct output_state dst = { buf, n }; size_t ret; if (cdecl_is_abstract(decl->declarators)) - ret = cdecl__emit(&buf, &n, "type "); + ret = cdecl__emit(&dst, "type "); else - ret = cdecl__emit(&buf, &n, "declare "); + ret = cdecl__emit(&dst, "declare "); - return ret + explain_decl(&buf, &n, decl); + return ret + explain_decl(&dst, decl); }