X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/54ca2ed1ca173c7818792b6b06d12b8536acb6f3..9abf0eb2e74d0fb3a4f652499571cb35697d3036:/src/output.c?ds=sidebyside
diff --git a/src/output.c b/src/output.c
index 8c2cd0b..f691765 100644
--- a/src/output.c
+++ b/src/output.c
@@ -1,5 +1,26 @@
+/*
+ * Helper functions for outputting text.
+ * Copyright © 2011, 2021 Nick Bowler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include
#include
-#include "output.h"
+#include
+
+#include "cdecl.h"
+#include "cdecl-internal.h"
size_t cdecl__advance_(char **buf, size_t *n, size_t amount)
{
@@ -25,3 +46,52 @@ size_t cdecl__advance(char **buf, size_t *n, size_t amount)
rc = snprintf(*buf, *n, " ");
return ret + cdecl__advance_(buf, n, rc);
}
+
+#include "specstr.h"
+
+static size_t explain_spec(char *buf, size_t n, struct cdecl_declspec *s)
+{
+ const char *keyword = spec_string(s->type);
+
+ if (keyword[0] && s->ident)
+ return snprintf(buf, n, "%s %s", keyword, s->ident);
+ else if (s->ident)
+ return snprintf(buf, n, "%s", s->ident);
+ return snprintf(buf, n, "%s", keyword);
+}
+
+/*
+ * Render a list of declaration specifiers. Only the declaration specifiers
+ * listed in mask, which is the bitwise OR of the desired specifier kinds, are
+ * printed.
+ */
+size_t cdecl__explain_specs(char *buf, size_t n, struct cdecl_declspec *s,
+ unsigned mask)
+{
+ size_t ret = 0, rc = 0;
+
+ for (struct cdecl_declspec *c = s; c; c = c->next) {
+ switch (cdecl_spec_kind(c) & mask) {
+ case CDECL_SPEC_FUNC:
+ case CDECL_SPEC_STOR:
+ case CDECL_SPEC_QUAL:
+ case CDECL_SPEC_TYPE:
+ ret += cdecl__advance(&buf, &n, rc);
+ rc = explain_spec(buf, n, c);
+ }
+ }
+
+ return ret + rc;
+}
+
+/* Renders the storage-class and function specifiers in canonical form. */
+size_t cdecl__explain_pre_specs(char *buf, size_t n, struct cdecl_declspec *s)
+{
+ return cdecl__explain_specs(buf, n, s, CDECL_SPEC_FUNC|CDECL_SPEC_STOR);
+}
+
+/* Renders the type qualifiers and type specifiers in canonical form. */
+size_t cdecl__explain_post_specs(char *buf, size_t n, struct cdecl_declspec *s)
+{
+ return cdecl__explain_specs(buf, n, s, CDECL_SPEC_QUAL|CDECL_SPEC_TYPE);
+}