- switch (s->type) {
- /* Function specifiers */
- case CDECL_FUNC_INLINE:
- return snprintf(buf, n, "inline");
- /* Storage-class specifiers */
- 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");
- /* Type qualifiers */
- case CDECL_QUAL_RESTRICT:
- return snprintf(buf, n, "restrict");
- case CDECL_QUAL_VOLATILE:
- return snprintf(buf, n, "volatile");
- case CDECL_QUAL_CONST:
- return snprintf(buf, n, "const");
- /* Type specifiers */
- case CDECL_TYPE_VOID:
- return snprintf(buf, n, "void");
- case CDECL_TYPE_CHAR:
- return snprintf(buf, n, "char");
- case CDECL_TYPE_SHORT:
- return snprintf(buf, n, "short");
- case CDECL_TYPE_INT:
- return snprintf(buf, n, "int");
- case CDECL_TYPE_LONG:
- return snprintf(buf, n, "long");
- case CDECL_TYPE_FLOAT:
- return snprintf(buf, n, "float");
- case CDECL_TYPE_DOUBLE:
- return snprintf(buf, n, "double");
- case CDECL_TYPE_SIGNED:
- return snprintf(buf, n, "signed");
- case CDECL_TYPE_UNSIGNED:
- return snprintf(buf, n, "unsigned");
- case CDECL_TYPE_BOOL:
- return snprintf(buf, n, "_Bool");
- case CDECL_TYPE_COMPLEX:
- return snprintf(buf, n, "_Complex");
- case CDECL_TYPE_IMAGINARY:
- return snprintf(buf, n, "_Imaginary");
- case CDECL_TYPE_STRUCT:
- return snprintf(buf, n, "struct %s", s->ident);
- case CDECL_TYPE_UNION:
- return snprintf(buf, n, "union %s", s->ident);
- case CDECL_TYPE_ENUM:
- return snprintf(buf, n, "enum %s", s->ident);
- case CDECL_TYPE_IDENT:
- return snprintf(buf, n, "%s", s->ident);
- default:
- assert(0);
+ size_t rc = cdecl__strlcpy(dst->dst, src, dst->dstlen);
+ return cdecl__advance(dst, rc);
+}
+
+enum {
+ /*
+ * upper bound on number of decimal digits required to convert
+ * cdecl_uintmax.
+ */
+ MAX_UINT_DIGITS = (CHAR_BIT * sizeof (cdecl_uintmax) + 2)/3
+};
+
+size_t cdecl__emit_uint(struct output_state *dst, cdecl_uintmax val)
+{
+ char buf[MAX_UINT_DIGITS + 1], *p = &buf[sizeof buf];
+
+ *(--p) = 0;
+ while (val > 0) {
+ *(--p) = '0' + val % 10;
+ val /= 10;
+ }
+
+ return cdecl__emit(dst, p);
+}
+
+static void explain_spec(struct output_state *dst, struct cdecl_declspec *s)
+{
+ size_t rc;
+
+ rc = cdecl__emit(dst, spec_string(s->type));
+ if (s->ident) {
+ cdecl__emit(dst, " " + !rc);
+ cdecl__emit(dst, s->ident);