summaryrefslogtreecommitdiff
path: root/mig/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'mig/utils.c')
-rw-r--r--mig/utils.c417
1 files changed, 417 insertions, 0 deletions
diff --git a/mig/utils.c b/mig/utils.c
new file mode 100644
index 0000000..f716e01
--- /dev/null
+++ b/mig/utils.c
@@ -0,0 +1,417 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <stdarg.h>
+
+#include "write.h"
+#include "utils.h"
+#include "global.h"
+
+void
+WriteImport(FILE *file, const_string_t filename)
+{
+ fprintf(file, "#include %s\n", filename);
+}
+
+void
+WriteRCSDecl(FILE *file, identifier_t name, const_string_t rcs)
+{
+ fprintf(file, "#ifndef\tlint\n");
+ fprintf(file, "#if\tUseExternRCSId\n");
+ fprintf(file, "char %s_rcsid[] = %s;\n", name, rcs);
+ fprintf(file, "#else\t/* UseExternRCSId */\n");
+ fprintf(file, "static char rcsid[] = %s;\n", rcs);
+ fprintf(file, "#endif\t/* UseExternRCSId */\n");
+ fprintf(file, "#endif\t/* lint */\n");
+ fprintf(file, "\n");
+}
+
+void
+WriteBogusDefines(FILE *file)
+{
+ fprintf(file, "#ifndef\tmig_internal\n");
+ fprintf(file, "#define\tmig_internal\tstatic\n");
+ fprintf(file, "#endif\n");
+ fprintf(file, "\n");
+
+ fprintf(file, "#ifndef\tmig_external\n");
+ fprintf(file, "#define mig_external\n");
+ fprintf(file, "#endif\n");
+ fprintf(file, "\n");
+
+ fprintf(file, "#ifndef\tTypeCheck\n");
+ fprintf(file, "#define\tTypeCheck 1\n");
+ fprintf(file, "#endif\n");
+ fprintf(file, "\n");
+
+ fprintf(file, "#ifndef\tUseExternRCSId\n");
+ fprintf(file, "#define\tUseExternRCSId\t\t1\n");
+ fprintf(file, "#endif\n");
+ fprintf(file, "\n");
+}
+
+void
+WriteList(FILE *file, const argument_t *args, write_list_fn_t *func, u_int mask,
+ const char *between, const char *after)
+{
+ register const argument_t *arg;
+ register boolean_t sawone = FALSE;
+
+ for (arg = args; arg != argNULL; arg = arg->argNext)
+ if (akCheckAll(arg->argKind, mask))
+ {
+ if (sawone)
+ fprintf(file, "%s", between);
+ sawone = TRUE;
+
+ (*func)(file, arg);
+ }
+
+ if (sawone)
+ fprintf(file, "%s", after);
+}
+
+static boolean_t
+WriteReverseListPrim(FILE *file, register const argument_t *arg,
+ write_list_fn_t *func, u_int mask, const char *between)
+{
+ boolean_t sawone = FALSE;
+
+ if (arg != argNULL)
+ {
+ sawone = WriteReverseListPrim(file, arg->argNext, func, mask, between);
+
+ if (akCheckAll(arg->argKind, mask))
+ {
+ if (sawone)
+ fprintf(file, "%s", between);
+ sawone = TRUE;
+
+ (*func)(file, arg);
+ }
+ }
+
+ return sawone;
+}
+
+void
+WriteReverseList(FILE *file, const argument_t *args, write_list_fn_t *func,
+ u_int mask, const char *between, const char *after)
+{
+ boolean_t sawone;
+
+ sawone = WriteReverseListPrim(file, args, func, mask, between);
+
+ if (sawone)
+ fprintf(file, "%s", after);
+}
+
+void
+WriteNameDecl(FILE *file, const argument_t *arg)
+{
+ fprintf(file, "%s", arg->argVarName);
+}
+
+void
+WriteUserVarDecl(FILE *file, const argument_t *arg)
+{
+ const char *ref = arg->argByReferenceUser ? "*" : "";
+
+ fprintf(file, "\t%s %s%s", arg->argType->itUserType, ref, arg->argVarName);
+}
+
+void
+WriteServerVarDecl(FILE *file, const argument_t *arg)
+{
+ const char *ref = arg->argByReferenceServer ? "*" : "";
+
+ fprintf(file, "\t%s %s%s",
+ arg->argType->itTransType, ref, arg->argVarName);
+}
+
+void
+WriteTypeDeclIn(FILE *file, register const argument_t *arg)
+{
+ WriteStaticDecl(file, arg->argType,
+ arg->argType->itIndefinite ? d_NO : arg->argDeallocate,
+ arg->argLongForm, TRUE, arg->argTTName);
+}
+
+void
+WriteTypeDeclOut(FILE *file, register const argument_t *arg)
+{
+ WriteStaticDecl(file, arg->argType,
+ arg->argType->itIndefinite ? d_NO : arg->argDeallocate,
+ arg->argLongForm, FALSE, arg->argTTName);
+}
+
+void
+WriteCheckDecl(FILE *file, register const argument_t *arg)
+{
+ register const ipc_type_t *it = arg->argType;
+
+ /* We'll only be called for short-form types.
+ Note we use itOutNameStr instead of itInNameStr, because
+ this declaration will be used to check received types. */
+
+ fprintf(file, "\tstatic const mach_msg_type_t %sCheck = {\n",
+ arg->argVarName);
+ fprintf(file, "\t\t/* msgt_name = */\t\t%s,\n", it->itOutNameStr);
+ fprintf(file, "\t\t/* msgt_size = */\t\t%d,\n", it->itSize);
+ fprintf(file, "\t\t/* msgt_number = */\t\t%d,\n", it->itNumber);
+ fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n",
+ strbool(it->itInLine));
+ fprintf(file, "\t\t/* msgt_longform = */\t\tFALSE,\n");
+ fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n",
+ strbool(!it->itInLine));
+ fprintf(file, "\t\t/* msgt_unused = */\t\t0\n");
+ fprintf(file, "\t};\n");
+}
+
+const char *
+ReturnTypeStr(const routine_t *rt)
+{
+ if (rt->rtReturn == argNULL)
+ return "void";
+ else
+ return rt->rtReturn->argType->itUserType;
+}
+
+const char *
+FetchUserType(const ipc_type_t *it)
+{
+ return it->itUserType;
+}
+
+const char *
+FetchServerType(const ipc_type_t *it)
+{
+ return it->itServerType;
+}
+
+void
+WriteFieldDeclPrim(FILE *file, const argument_t *arg,
+ const char *(*tfunc)(const ipc_type_t *))
+{
+ register const ipc_type_t *it = arg->argType;
+
+ fprintf(file, "\t\tmach_msg_type_%st %s;\n",
+ arg->argLongForm ? "long_" : "", arg->argTTName);
+
+ if (it->itInLine && it->itVarArray)
+ {
+ register ipc_type_t *btype = it->itElement;
+
+ /*
+ * Build our own declaration for a varying array:
+ * use the element type and maximum size specified.
+ * Note arg->argCount->argMultiplier == btype->itNumber.
+ */
+ fprintf(file, "\t\t%s %s[%d];",
+ (*tfunc)(btype),
+ arg->argMsgField,
+ it->itNumber/btype->itNumber);
+ }
+ else
+ fprintf(file, "\t\t%s %s;", (*tfunc)(it), arg->argMsgField);
+
+ if (it->itPadSize != 0)
+ fprintf(file, "\n\t\tchar %s[%d];", arg->argPadName, it->itPadSize);
+}
+
+void
+WriteStructDecl(FILE *file, const argument_t *args, write_list_fn_t *func,
+ u_int mask, const char *name)
+{
+ fprintf(file, "\ttypedef struct {\n");
+ fprintf(file, "\t\tmach_msg_header_t Head;\n");
+ WriteList(file, args, func, mask, "\n", "\n");
+ fprintf(file, "\t} %s;\n", name);
+ fprintf(file, "\n");
+}
+
+static void
+WriteStaticLongDecl(FILE *file, register const ipc_type_t *it,
+ dealloc_t dealloc, boolean_t inname, identifier_t name)
+{
+ fprintf(file, "\tstatic const mach_msg_type_long_t %s = {\n", name);
+ fprintf(file, "\t{\n");
+ fprintf(file, "\t\t/* msgt_name = */\t\t0,\n");
+ fprintf(file, "\t\t/* msgt_size = */\t\t0,\n");
+ fprintf(file, "\t\t/* msgt_number = */\t\t0,\n");
+ fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n",
+ strbool(it->itInLine));
+ fprintf(file, "\t\t/* msgt_longform = */\t\tTRUE,\n");
+ fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n",
+ strdealloc(dealloc));
+ fprintf(file, "\t\t/* msgt_unused = */\t\t0\n");
+ fprintf(file, "\t},\n");
+ fprintf(file, "\t\t/* msgtl_name = */\t%s,\n",
+ inname ? it->itInNameStr : it->itOutNameStr);
+ fprintf(file, "\t\t/* msgtl_size = */\t%d,\n", it->itSize);
+ fprintf(file, "\t\t/* msgtl_number = */\t%d,\n", it->itNumber);
+ fprintf(file, "\t};\n");
+}
+
+static void
+WriteStaticShortDecl(FILE *file, register const ipc_type_t *it,
+ dealloc_t dealloc, boolean_t inname, identifier_t name)
+{
+ fprintf(file, "\tstatic const mach_msg_type_t %s = {\n", name);
+ fprintf(file, "\t\t/* msgt_name = */\t\t%s,\n",
+ inname ? it->itInNameStr : it->itOutNameStr);
+ fprintf(file, "\t\t/* msgt_size = */\t\t%d,\n", it->itSize);
+ fprintf(file, "\t\t/* msgt_number = */\t\t%d,\n", it->itNumber);
+ fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n",
+ strbool(it->itInLine));
+ fprintf(file, "\t\t/* msgt_longform = */\t\tFALSE,\n");
+ fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n",
+ strdealloc(dealloc));
+ fprintf(file, "\t\t/* msgt_unused = */\t\t0\n");
+ fprintf(file, "\t};\n");
+}
+
+void
+WriteStaticDecl(FILE *file, const ipc_type_t *it, dealloc_t dealloc,
+ boolean_t longform, boolean_t inname, identifier_t name)
+{
+ if (longform)
+ WriteStaticLongDecl(file, it, dealloc, inname, name);
+ else
+ WriteStaticShortDecl(file, it, dealloc, inname, name);
+}
+
+/*
+ * Like vfprintf, but omits a leading comment in the format string
+ * and skips the items that would be printed by it. Only %s, %d,
+ * and %f are recognized.
+ */
+static void
+SkipVFPrintf(FILE *file, register const char *fmt, va_list pvar)
+{
+ if (*fmt == 0)
+ return; /* degenerate case */
+
+ if (fmt[0] == '/' && fmt[1] == '*') {
+ /* Format string begins with C comment. Scan format
+ string until end-comment delimiter, skipping the
+ items in pvar that the enclosed format items would
+ print. */
+
+ register int c;
+
+ fmt += 2;
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ return; /* nothing to format */
+ if (c == '*') {
+ if (*fmt == '/') {
+ break;
+ }
+ }
+ else if (c == '%') {
+ /* Field to skip */
+ c = *fmt++;
+ switch (c) {
+ case 's':
+ (void) va_arg(pvar, char *);
+ break;
+ case 'd':
+ (void) va_arg(pvar, int);
+ break;
+ case 'f':
+ (void) va_arg(pvar, double);
+ break;
+ case '\0':
+ return; /* error - fmt ends with '%' */
+ default:
+ break;
+ }
+ }
+ }
+ /* End of comment. To be pretty, skip
+ the space that follows. */
+ fmt++;
+ if (*fmt == ' ')
+ fmt++;
+ }
+
+ /* Now format the string. */
+ (void) vfprintf(file, fmt, pvar);
+}
+
+void
+WriteCopyType(FILE *file, const ipc_type_t *it, const char *left,
+ const char *right, ...)
+{
+ va_list pvar;
+ va_start(pvar, right);
+
+ if (it->itStruct)
+ {
+ fprintf(file, "\t");
+ SkipVFPrintf(file, left, pvar);
+ fprintf(file, " = ");
+ SkipVFPrintf(file, right, pvar);
+ fprintf(file, ";\n");
+ }
+ else if (it->itString)
+ {
+ fprintf(file, "\t(void) %smig_strncpy(", SubrPrefix);
+ SkipVFPrintf(file, left, pvar);
+ fprintf(file, ", ");
+ SkipVFPrintf(file, right, pvar);
+ fprintf(file, ", %d);\n", it->itTypeSize);
+ }
+ else
+ {
+ fprintf(file, "\t{ typedef struct { char data[%d]; } *sp; * (sp) ",
+ it->itTypeSize);
+ SkipVFPrintf(file, left, pvar);
+ fprintf(file, " = * (sp) ");
+ SkipVFPrintf(file, right, pvar);
+ fprintf(file, "; }\n");
+ }
+ va_end(pvar);
+}
+
+void
+WritePackMsgType(FILE *file, const ipc_type_t *it, dealloc_t dealloc,
+ boolean_t longform, boolean_t inname, const char *left,
+ const char *right, ...)
+{
+ va_list pvar;
+ va_start(pvar, right);
+
+ fprintf(file, "\t");
+ SkipVFPrintf(file, left, pvar);
+ fprintf(file, " = ");
+ SkipVFPrintf(file, right, pvar);
+ fprintf(file, ";\n");
+
+ va_end(pvar);
+}