2 * Helper functions for outputting text.
3 * Copyright © 2011 Nick Bowler
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 size_t cdecl__advance_(char **buf, size_t *n, size_t amount)
39 size_t cdecl__advance(char **buf, size_t *n, size_t amount)
46 ret = cdecl__advance_(buf, n, amount);
47 rc = snprintf(*buf, *n, " ");
48 return ret + cdecl__advance_(buf, n, rc);
51 static size_t explain_spec(char *buf, size_t n, struct cdecl_declspec *s)
54 /* Function specifiers */
55 case CDECL_FUNC_INLINE:
56 return snprintf(buf, n, "inline");
57 /* Storage-class specifiers */
58 case CDECL_STOR_TYPEDEF:
59 return snprintf(buf, n, "typedef");
60 case CDECL_STOR_EXTERN:
61 return snprintf(buf, n, "extern");
62 case CDECL_STOR_STATIC:
63 return snprintf(buf, n, "static");
65 return snprintf(buf, n, "auto");
66 case CDECL_STOR_REGISTER:
67 return snprintf(buf, n, "register");
69 case CDECL_QUAL_RESTRICT:
70 return snprintf(buf, n, "restrict");
71 case CDECL_QUAL_VOLATILE:
72 return snprintf(buf, n, "volatile");
73 case CDECL_QUAL_CONST:
74 return snprintf(buf, n, "const");
77 return snprintf(buf, n, "void");
79 return snprintf(buf, n, "char");
80 case CDECL_TYPE_SHORT:
81 return snprintf(buf, n, "short");
83 return snprintf(buf, n, "int");
85 return snprintf(buf, n, "long");
86 case CDECL_TYPE_FLOAT:
87 return snprintf(buf, n, "float");
88 case CDECL_TYPE_DOUBLE:
89 return snprintf(buf, n, "double");
90 case CDECL_TYPE_SIGNED:
91 return snprintf(buf, n, "signed");
92 case CDECL_TYPE_UNSIGNED:
93 return snprintf(buf, n, "unsigned");
95 return snprintf(buf, n, "_Bool");
96 case CDECL_TYPE_COMPLEX:
97 return snprintf(buf, n, "_Complex");
98 case CDECL_TYPE_IMAGINARY:
99 return snprintf(buf, n, "_Imaginary");
100 case CDECL_TYPE_STRUCT:
101 return snprintf(buf, n, "struct %s", s->ident);
102 case CDECL_TYPE_UNION:
103 return snprintf(buf, n, "union %s", s->ident);
104 case CDECL_TYPE_ENUM:
105 return snprintf(buf, n, "enum %s", s->ident);
106 case CDECL_TYPE_IDENT:
107 return snprintf(buf, n, "%s", s->ident);
114 * Render a list of declaration specifiers. Only the declaration specifiers
115 * listed in mask, which is the bitwise OR of the desired specifier kinds, are
118 size_t cdecl__explain_specs(char *buf, size_t n, struct cdecl_declspec *s,
121 size_t ret = 0, rc = 0;
123 for (struct cdecl_declspec *c = s; c; c = c->next) {
124 switch (cdecl_spec_kind(c) & mask) {
125 case CDECL_SPEC_FUNC:
126 case CDECL_SPEC_STOR:
127 case CDECL_SPEC_QUAL:
128 case CDECL_SPEC_TYPE:
129 ret += cdecl__advance(&buf, &n, rc);
130 rc = explain_spec(buf, n, c);
137 /* Renders the storage-class and function specifiers in canonical form. */
138 size_t cdecl__explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
140 return cdecl__explain_specs(buf, n, s, CDECL_SPEC_FUNC|CDECL_SPEC_STOR);
143 /* Renders the type qualifiers and type specifiers in canonical form. */
144 size_t cdecl__explain_post_specs(char *buf, size_t n, struct cdecl_declspec *s)
146 return cdecl__explain_specs(buf, n, s, CDECL_SPEC_QUAL|CDECL_SPEC_TYPE);