8 size_t cdecl__advance_(char **buf, size_t *n, size_t amount)
21 size_t cdecl__advance(char **buf, size_t *n, size_t amount)
28 ret = cdecl__advance_(buf, n, amount);
29 rc = snprintf(*buf, *n, " ");
30 return ret + cdecl__advance_(buf, n, rc);
33 static size_t explain_storage(char *buf, size_t n, unsigned spec)
36 case CDECL_STOR_TYPEDEF:
37 return snprintf(buf, n, "typedef");
38 case CDECL_STOR_EXTERN:
39 return snprintf(buf, n, "extern");
40 case CDECL_STOR_STATIC:
41 return snprintf(buf, n, "static");
43 return snprintf(buf, n, "auto");
44 case CDECL_STOR_REGISTER:
45 return snprintf(buf, n, "register");
51 /* Renders the storage-class and function specifiers in canonical form. */
52 size_t cdecl__explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
54 unsigned long funcmap = 0;
55 size_t ret = 0, rc = 0;
57 for (struct cdecl_declspec *c = s; c; c = c->next) {
58 switch (cdecl_spec_kind(c)) {
60 funcmap |= 1ul << (c->type & 0xff);
63 /* Valid C declarations have at most one
64 * storage-class specifier. */
65 rc = explain_storage(buf, n, c->type);
70 if (funcmap & (1ul << (CDECL_FUNC_INLINE & 0xff))) {
71 ret += cdecl__advance(&buf, &n, rc);
72 rc = snprintf(buf, n, "inline");
78 size_t cdecl__explain_qualifiers(char *buf, size_t n, struct cdecl_declspec *s)
80 unsigned long qualmap = 0;
81 size_t ret = 0, rc = 0;
83 for (struct cdecl_declspec *c = s; c; c = c->next) {
84 if (cdecl_spec_kind(c) != CDECL_SPEC_QUAL)
86 qualmap |= 1ul << (c->type & 0xff);
89 if (qualmap & (1ul << (CDECL_QUAL_RESTRICT & 0xff))) {
90 ret += cdecl__advance(&buf, &n, rc);
91 rc = snprintf(buf, n, "restrict");
93 if (qualmap & (1ul << (CDECL_QUAL_VOLATILE & 0xff))) {
94 ret += cdecl__advance(&buf, &n, rc);
95 rc = snprintf(buf, n, "volatile");
97 if (qualmap & (1ul << (CDECL_QUAL_CONST & 0xff))) {
98 ret += cdecl__advance(&buf, &n, rc);
99 rc = snprintf(buf, n, "const");
105 /* Renders the type qualifiers and type specifiers in canonical form. */
106 size_t cdecl__explain_post_specs(char *buf, size_t n, struct cdecl_declspec *s)
108 const char *tag = NULL;
109 unsigned long typemap;
112 typemap = cdecl__build_typemap(s);
116 for (struct cdecl_declspec *c = s; c; c = c->next) {
117 if (cdecl_spec_kind(c) != CDECL_SPEC_TYPE)
120 /* Valid C types have at most one identifier. */
125 rc = cdecl__explain_qualifiers(buf, n, s);
126 ret += cdecl__advance(&buf, &n, rc);
128 rc = snprintf(buf, n, "%s", cdecl__explain_typemap(typemap));
130 ret += cdecl__advance(&buf, &n, rc);
131 rc = snprintf(buf, n, "%s", tag);