#include "cdecl.h"
#include "typemap.h"
-/* declare [ident] as [storage] [function specs] [other crap] [qualifiers] [type specs] */
-
-static size_t
-voutput(char *buf, size_t n, size_t off, const char *fmt, va_list ap)
-{
- if (off >= n)
- return vsnprintf(NULL, 0, fmt, ap);
- return vsnprintf(buf+off, n-off, fmt, ap);
-}
-
-static size_t output(char *buf, size_t n, size_t off, const char *fmt, ...)
-{
- va_list ap;
- size_t ret;
-
- va_start(ap, fmt);
- ret = voutput(buf, n, off, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
static size_t advance_(char **buf, size_t *n, size_t amount)
{
if (amount >= *n) {
return ret + rc;
}
-static const char *explain_storage(unsigned spec)
+static size_t explain_storage(char *buf, size_t n, unsigned spec)
{
switch (spec) {
case CDECL_STOR_TYPEDEF:
- return "typedef";
+ return snprintf(buf, n, "typedef");
case CDECL_STOR_EXTERN:
- return "extern";
+ return snprintf(buf, n, "extern");
case CDECL_STOR_STATIC:
- return "static";
+ return snprintf(buf, n, "static");
case CDECL_STOR_AUTO:
- return "auto";
+ return snprintf(buf, n, "auto");
case CDECL_STOR_REGISTER:
- return "register";
+ return snprintf(buf, n, "register");
default:
assert(0);
}
static size_t explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
{
unsigned long funcmap = 0;
- const char *storage = NULL;
- size_t ret = 0;
+ size_t ret = 0, rc = 0;
for (struct cdecl_declspec *c = s; c; c = c->next) {
switch (cdecl_spec_kind(c)) {
case CDECL_SPEC_STOR:
/* Valid C declarations have at most one
* storage-class specifier. */
- storage = explain_storage(c->type);
+ rc = explain_storage(buf, n, c->type);
break;
}
}
- if (storage)
- ret += output(buf, n, ret, "%s", storage);
- if (funcmap & (1ul << (CDECL_FUNC_INLINE & 0xff)))
- ret += output(buf, n, ret, "%.*s%s", !!ret, "", "inline");
- return ret;
+ if (funcmap & (1ul << (CDECL_FUNC_INLINE & 0xff))) {
+ ret += advance(&buf, &n, rc);
+ rc = snprintf(buf, n, "inline");
+ }
+
+ return ret + rc;
}
/*