|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: ! 27: #include <stdarg.h> ! 28: ! 29: #include "write.h" ! 30: #include "utils.h" ! 31: #include "global.h" ! 32: ! 33: void ! 34: WriteImport(FILE *file, const_string_t filename) ! 35: { ! 36: fprintf(file, "#include %s\n", filename); ! 37: } ! 38: ! 39: void ! 40: WriteRCSDecl(FILE *file, identifier_t name, const_string_t rcs) ! 41: { ! 42: fprintf(file, "#ifndef\tlint\n"); ! 43: fprintf(file, "#if\tUseExternRCSId\n"); ! 44: fprintf(file, "char %s_rcsid[] = %s;\n", name, rcs); ! 45: fprintf(file, "#else\t/* UseExternRCSId */\n"); ! 46: fprintf(file, "static char rcsid[] = %s;\n", rcs); ! 47: fprintf(file, "#endif\t/* UseExternRCSId */\n"); ! 48: fprintf(file, "#endif\t/* lint */\n"); ! 49: fprintf(file, "\n"); ! 50: } ! 51: ! 52: void ! 53: WriteBogusDefines(FILE *file) ! 54: { ! 55: fprintf(file, "#ifndef\tmig_internal\n"); ! 56: fprintf(file, "#define\tmig_internal\tstatic\n"); ! 57: fprintf(file, "#endif\n"); ! 58: fprintf(file, "\n"); ! 59: ! 60: fprintf(file, "#ifndef\tmig_external\n"); ! 61: fprintf(file, "#define mig_external\n"); ! 62: fprintf(file, "#endif\n"); ! 63: fprintf(file, "\n"); ! 64: ! 65: fprintf(file, "#ifndef\tTypeCheck\n"); ! 66: fprintf(file, "#define\tTypeCheck 1\n"); ! 67: fprintf(file, "#endif\n"); ! 68: fprintf(file, "\n"); ! 69: ! 70: fprintf(file, "#ifndef\tUseExternRCSId\n"); ! 71: fprintf(file, "#define\tUseExternRCSId\t\t1\n"); ! 72: fprintf(file, "#endif\n"); ! 73: fprintf(file, "\n"); ! 74: } ! 75: ! 76: void ! 77: WriteList(FILE *file, const argument_t *args, write_list_fn_t *func, u_int mask, ! 78: const char *between, const char *after) ! 79: { ! 80: register const argument_t *arg; ! 81: register boolean_t sawone = FALSE; ! 82: ! 83: for (arg = args; arg != argNULL; arg = arg->argNext) ! 84: if (akCheckAll(arg->argKind, mask)) ! 85: { ! 86: if (sawone) ! 87: fprintf(file, "%s", between); ! 88: sawone = TRUE; ! 89: ! 90: (*func)(file, arg); ! 91: } ! 92: ! 93: if (sawone) ! 94: fprintf(file, "%s", after); ! 95: } ! 96: ! 97: static boolean_t ! 98: WriteReverseListPrim(FILE *file, register const argument_t *arg, ! 99: write_list_fn_t *func, u_int mask, const char *between) ! 100: { ! 101: boolean_t sawone = FALSE; ! 102: ! 103: if (arg != argNULL) ! 104: { ! 105: sawone = WriteReverseListPrim(file, arg->argNext, func, mask, between); ! 106: ! 107: if (akCheckAll(arg->argKind, mask)) ! 108: { ! 109: if (sawone) ! 110: fprintf(file, "%s", between); ! 111: sawone = TRUE; ! 112: ! 113: (*func)(file, arg); ! 114: } ! 115: } ! 116: ! 117: return sawone; ! 118: } ! 119: ! 120: void ! 121: WriteReverseList(FILE *file, const argument_t *args, write_list_fn_t *func, ! 122: u_int mask, const char *between, const char *after) ! 123: { ! 124: boolean_t sawone; ! 125: ! 126: sawone = WriteReverseListPrim(file, args, func, mask, between); ! 127: ! 128: if (sawone) ! 129: fprintf(file, "%s", after); ! 130: } ! 131: ! 132: void ! 133: WriteNameDecl(FILE *file, const argument_t *arg) ! 134: { ! 135: fprintf(file, "%s", arg->argVarName); ! 136: } ! 137: ! 138: void ! 139: WriteUserVarDecl(FILE *file, const argument_t *arg) ! 140: { ! 141: const char *ref = arg->argByReferenceUser ? "*" : ""; ! 142: ! 143: fprintf(file, "\t%s %s%s", arg->argType->itUserType, ref, arg->argVarName); ! 144: } ! 145: ! 146: void ! 147: WriteServerVarDecl(FILE *file, const argument_t *arg) ! 148: { ! 149: const char *ref = arg->argByReferenceServer ? "*" : ""; ! 150: ! 151: fprintf(file, "\t%s %s%s", ! 152: arg->argType->itTransType, ref, arg->argVarName); ! 153: } ! 154: ! 155: void ! 156: WriteTypeDeclIn(FILE *file, register const argument_t *arg) ! 157: { ! 158: WriteStaticDecl(file, arg->argType, ! 159: arg->argType->itIndefinite ? d_NO : arg->argDeallocate, ! 160: arg->argLongForm, TRUE, arg->argTTName); ! 161: } ! 162: ! 163: void ! 164: WriteTypeDeclOut(FILE *file, register const argument_t *arg) ! 165: { ! 166: WriteStaticDecl(file, arg->argType, ! 167: arg->argType->itIndefinite ? d_NO : arg->argDeallocate, ! 168: arg->argLongForm, FALSE, arg->argTTName); ! 169: } ! 170: ! 171: void ! 172: WriteCheckDecl(FILE *file, register const argument_t *arg) ! 173: { ! 174: register const ipc_type_t *it = arg->argType; ! 175: ! 176: /* We'll only be called for short-form types. ! 177: Note we use itOutNameStr instead of itInNameStr, because ! 178: this declaration will be used to check received types. */ ! 179: ! 180: fprintf(file, "\tstatic const mach_msg_type_t %sCheck = {\n", ! 181: arg->argVarName); ! 182: fprintf(file, "\t\t/* msgt_name = */\t\t%s,\n", it->itOutNameStr); ! 183: fprintf(file, "\t\t/* msgt_size = */\t\t%d,\n", it->itSize); ! 184: fprintf(file, "\t\t/* msgt_number = */\t\t%d,\n", it->itNumber); ! 185: fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n", ! 186: strbool(it->itInLine)); ! 187: fprintf(file, "\t\t/* msgt_longform = */\t\tFALSE,\n"); ! 188: fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n", ! 189: strbool(!it->itInLine)); ! 190: fprintf(file, "\t\t/* msgt_unused = */\t\t0\n"); ! 191: fprintf(file, "\t};\n"); ! 192: } ! 193: ! 194: const char * ! 195: ReturnTypeStr(const routine_t *rt) ! 196: { ! 197: if (rt->rtReturn == argNULL) ! 198: return "void"; ! 199: else ! 200: return rt->rtReturn->argType->itUserType; ! 201: } ! 202: ! 203: const char * ! 204: FetchUserType(const ipc_type_t *it) ! 205: { ! 206: return it->itUserType; ! 207: } ! 208: ! 209: const char * ! 210: FetchServerType(const ipc_type_t *it) ! 211: { ! 212: return it->itServerType; ! 213: } ! 214: ! 215: void ! 216: WriteFieldDeclPrim(FILE *file, const argument_t *arg, ! 217: const char *(*tfunc)(const ipc_type_t *)) ! 218: { ! 219: register const ipc_type_t *it = arg->argType; ! 220: ! 221: fprintf(file, "\t\tmach_msg_type_%st %s;\n", ! 222: arg->argLongForm ? "long_" : "", arg->argTTName); ! 223: ! 224: if (it->itInLine && it->itVarArray) ! 225: { ! 226: register ipc_type_t *btype = it->itElement; ! 227: ! 228: /* ! 229: * Build our own declaration for a varying array: ! 230: * use the element type and maximum size specified. ! 231: * Note arg->argCount->argMultiplier == btype->itNumber. ! 232: */ ! 233: fprintf(file, "\t\t%s %s[%d];", ! 234: (*tfunc)(btype), ! 235: arg->argMsgField, ! 236: it->itNumber/btype->itNumber); ! 237: } ! 238: else ! 239: fprintf(file, "\t\t%s %s;", (*tfunc)(it), arg->argMsgField); ! 240: ! 241: if (it->itPadSize != 0) ! 242: fprintf(file, "\n\t\tchar %s[%d];", arg->argPadName, it->itPadSize); ! 243: } ! 244: ! 245: void ! 246: WriteStructDecl(FILE *file, const argument_t *args, write_list_fn_t *func, ! 247: u_int mask, const char *name) ! 248: { ! 249: fprintf(file, "\ttypedef struct {\n"); ! 250: fprintf(file, "\t\tmach_msg_header_t Head;\n"); ! 251: WriteList(file, args, func, mask, "\n", "\n"); ! 252: fprintf(file, "\t} %s;\n", name); ! 253: fprintf(file, "\n"); ! 254: } ! 255: ! 256: static void ! 257: WriteStaticLongDecl(FILE *file, register const ipc_type_t *it, ! 258: dealloc_t dealloc, boolean_t inname, identifier_t name) ! 259: { ! 260: fprintf(file, "\tstatic const mach_msg_type_long_t %s = {\n", name); ! 261: fprintf(file, "\t{\n"); ! 262: fprintf(file, "\t\t/* msgt_name = */\t\t0,\n"); ! 263: fprintf(file, "\t\t/* msgt_size = */\t\t0,\n"); ! 264: fprintf(file, "\t\t/* msgt_number = */\t\t0,\n"); ! 265: fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n", ! 266: strbool(it->itInLine)); ! 267: fprintf(file, "\t\t/* msgt_longform = */\t\tTRUE,\n"); ! 268: fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n", ! 269: strdealloc(dealloc)); ! 270: fprintf(file, "\t\t/* msgt_unused = */\t\t0\n"); ! 271: fprintf(file, "\t},\n"); ! 272: fprintf(file, "\t\t/* msgtl_name = */\t%s,\n", ! 273: inname ? it->itInNameStr : it->itOutNameStr); ! 274: fprintf(file, "\t\t/* msgtl_size = */\t%d,\n", it->itSize); ! 275: fprintf(file, "\t\t/* msgtl_number = */\t%d,\n", it->itNumber); ! 276: fprintf(file, "\t};\n"); ! 277: } ! 278: ! 279: static void ! 280: WriteStaticShortDecl(FILE *file, register const ipc_type_t *it, ! 281: dealloc_t dealloc, boolean_t inname, identifier_t name) ! 282: { ! 283: fprintf(file, "\tstatic const mach_msg_type_t %s = {\n", name); ! 284: fprintf(file, "\t\t/* msgt_name = */\t\t%s,\n", ! 285: inname ? it->itInNameStr : it->itOutNameStr); ! 286: fprintf(file, "\t\t/* msgt_size = */\t\t%d,\n", it->itSize); ! 287: fprintf(file, "\t\t/* msgt_number = */\t\t%d,\n", it->itNumber); ! 288: fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n", ! 289: strbool(it->itInLine)); ! 290: fprintf(file, "\t\t/* msgt_longform = */\t\tFALSE,\n"); ! 291: fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n", ! 292: strdealloc(dealloc)); ! 293: fprintf(file, "\t\t/* msgt_unused = */\t\t0\n"); ! 294: fprintf(file, "\t};\n"); ! 295: } ! 296: ! 297: void ! 298: WriteStaticDecl(FILE *file, const ipc_type_t *it, dealloc_t dealloc, ! 299: boolean_t longform, boolean_t inname, identifier_t name) ! 300: { ! 301: if (longform) ! 302: WriteStaticLongDecl(file, it, dealloc, inname, name); ! 303: else ! 304: WriteStaticShortDecl(file, it, dealloc, inname, name); ! 305: } ! 306: ! 307: /* ! 308: * Like vfprintf, but omits a leading comment in the format string ! 309: * and skips the items that would be printed by it. Only %s, %d, ! 310: * and %f are recognized. ! 311: */ ! 312: static void ! 313: SkipVFPrintf(FILE *file, register const char *fmt, va_list pvar) ! 314: { ! 315: if (*fmt == 0) ! 316: return; /* degenerate case */ ! 317: ! 318: if (fmt[0] == '/' && fmt[1] == '*') { ! 319: /* Format string begins with C comment. Scan format ! 320: string until end-comment delimiter, skipping the ! 321: items in pvar that the enclosed format items would ! 322: print. */ ! 323: ! 324: register int c; ! 325: ! 326: fmt += 2; ! 327: for (;;) { ! 328: c = *fmt++; ! 329: if (c == 0) ! 330: return; /* nothing to format */ ! 331: if (c == '*') { ! 332: if (*fmt == '/') { ! 333: break; ! 334: } ! 335: } ! 336: else if (c == '%') { ! 337: /* Field to skip */ ! 338: c = *fmt++; ! 339: switch (c) { ! 340: case 's': ! 341: (void) va_arg(pvar, char *); ! 342: break; ! 343: case 'd': ! 344: (void) va_arg(pvar, int); ! 345: break; ! 346: case 'f': ! 347: (void) va_arg(pvar, double); ! 348: break; ! 349: case '\0': ! 350: return; /* error - fmt ends with '%' */ ! 351: default: ! 352: break; ! 353: } ! 354: } ! 355: } ! 356: /* End of comment. To be pretty, skip ! 357: the space that follows. */ ! 358: fmt++; ! 359: if (*fmt == ' ') ! 360: fmt++; ! 361: } ! 362: ! 363: /* Now format the string. */ ! 364: (void) vfprintf(file, fmt, pvar); ! 365: } ! 366: ! 367: void ! 368: WriteCopyType(FILE *file, const ipc_type_t *it, const char *left, ! 369: const char *right, ...) ! 370: { ! 371: va_list pvar; ! 372: va_start(pvar, right); ! 373: ! 374: if (it->itStruct) ! 375: { ! 376: fprintf(file, "\t"); ! 377: SkipVFPrintf(file, left, pvar); ! 378: fprintf(file, " = "); ! 379: SkipVFPrintf(file, right, pvar); ! 380: fprintf(file, ";\n"); ! 381: } ! 382: else if (it->itString) ! 383: { ! 384: fprintf(file, "\t(void) %smig_strncpy(", SubrPrefix); ! 385: SkipVFPrintf(file, left, pvar); ! 386: fprintf(file, ", "); ! 387: SkipVFPrintf(file, right, pvar); ! 388: fprintf(file, ", %d);\n", it->itTypeSize); ! 389: } ! 390: else ! 391: { ! 392: fprintf(file, "\t{ typedef struct { char data[%d]; } *sp; * (sp) ", ! 393: it->itTypeSize); ! 394: SkipVFPrintf(file, left, pvar); ! 395: fprintf(file, " = * (sp) "); ! 396: SkipVFPrintf(file, right, pvar); ! 397: fprintf(file, "; }\n"); ! 398: } ! 399: va_end(pvar); ! 400: } ! 401: ! 402: void ! 403: WritePackMsgType(FILE *file, const ipc_type_t *it, dealloc_t dealloc, ! 404: boolean_t longform, boolean_t inname, const char *left, ! 405: const char *right, ...) ! 406: { ! 407: va_list pvar; ! 408: va_start(pvar, right); ! 409: ! 410: fprintf(file, "\t"); ! 411: SkipVFPrintf(file, left, pvar); ! 412: fprintf(file, " = "); ! 413: SkipVFPrintf(file, right, pvar); ! 414: fprintf(file, ";\n"); ! 415: ! 416: va_end(pvar); ! 417: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.