bootstrap_cmds/migcom.tproj/header.c

bootstrap_cmds source @ c71d2d7 2025-04-30 · 596 lines · view on GitHub
1/* 2 * Copyright (c) 1999-2018 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Mach Operating System 25 * Copyright (c) 1991,1990 Carnegie Mellon University 26 * All Rights Reserved. 27 * 28 * Permission to use, copy, modify and distribute this software and its 29 * documentation is hereby granted, provided that both the copyright 30 * notice and this permission notice appear in all copies of the 31 * software, derivative works or modified versions, and any portions 32 * thereof, and that both notices appear in supporting documentation. 33 * 34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 37 * 38 * Carnegie Mellon requests users of this software to return to 39 * 40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 41 * School of Computer Science 42 * Carnegie Mellon University 43 * Pittsburgh PA 15213-3890 44 * 45 * any improvements or extensions that they make and grant Carnegie the 46 * rights to redistribute these changes. 47 */ 48 49#include "write.h" 50#include "utils.h" 51#include "global.h" 52#include "strdefs.h" 53#include "error.h" 54#include <stdlib.h> 55 56void 57WriteIncludes(FILE *file, boolean_t isuser, boolean_t isdef) 58{ 59 if (EmitCountAnnotations) { 60 fprintf(file, "#include <sys/cdefs.h>\n"); 61 } 62 if (isdef) { 63 fprintf(file, "#include <mach/port.h>\n"); 64 fprintf(file, "#include <mach/machine/kern_return.h>\n"); 65 if (!isuser) 66 fprintf(file, "#include <mach/mig_errors.h>\n"); 67 } 68 else { 69 fprintf(file, "#include <string.h>\n"); 70 fprintf(file, "#include <mach/ndr.h>\n"); 71 fprintf(file, "#include <mach/boolean.h>\n"); 72 fprintf(file, "#include <mach/kern_return.h>\n"); 73 fprintf(file, "#include <mach/notify.h>\n"); 74 fprintf(file, "#include <mach/mach_types.h>\n"); 75 fprintf(file, "#include <mach/message.h>\n"); 76 fprintf(file, "#include <mach/mig_errors.h>\n"); 77 fprintf(file, "#include <mach/port.h>\n"); 78 79 if (IsVoucherCodeAllowed && !IsKernelUser && !IsKernelServer) { 80 fprintf(file, "\t\n/* BEGIN VOUCHER CODE */\n\n"); 81 fprintf(file, "#ifndef KERNEL\n"); 82 fprintf(file, "#if defined(__has_include)\n"); 83 fprintf(file, "#if __has_include(<mach/mig_voucher_support.h>)\n"); 84 fprintf(file, "#ifndef USING_VOUCHERS\n"); 85 fprintf(file, "#define USING_VOUCHERS\n"); 86 fprintf(file, "#endif\n"); 87 88 89 fprintf(file, "#ifndef __VOUCHER_FORWARD_TYPE_DECLS__\n"); 90 fprintf(file, "#define __VOUCHER_FORWARD_TYPE_DECLS__\n"); 91 92 fprintf(file, "#ifdef __cplusplus\n"); 93 fprintf(file, "extern \"C\" {\n"); 94 fprintf(file, "#endif\n"); 95 96 fprintf(file, "#ifndef __VOUCHER_FOWARD_TYPE_DECLS_SINGLE_ATTR\n"); 97 fprintf(file, "#define __VOUCHER_FOWARD_TYPE_DECLS_SINGLE_ATTR __unsafe_indexable\n"); 98 fprintf(file, "#endif\n"); 99 fprintf(file, "\textern boolean_t voucher_mach_msg_set(mach_msg_header_t *%s msg) __attribute__((weak_import));\n", EmitCountAnnotations ? "__VOUCHER_FOWARD_TYPE_DECLS_SINGLE_ATTR" : ""); 100 101 fprintf(file, "#ifdef __cplusplus\n"); 102 fprintf(file, "}\n"); 103 fprintf(file, "#endif\n"); 104 105 fprintf(file, "#endif // __VOUCHER_FORWARD_TYPE_DECLS__\n"); 106 fprintf(file, "#endif // __has_include(<mach/mach_voucher_types.h>)\n"); 107 fprintf(file, "#endif // __has_include\n"); 108 fprintf(file, "#endif // !KERNEL\n"); 109 110 fprintf(file, "\t\n/* END VOUCHER CODE */\n\n"); 111 } 112 113 fprintf(file, "\t\n/* BEGIN MIG_STRNCPY_ZEROFILL CODE */\n\n"); 114 fprintf(file, "#if defined(__has_include)\n"); 115 fprintf(file, "#if __has_include(<mach/mig_strncpy_zerofill_support.h>)\n"); 116 fprintf(file, "#ifndef USING_MIG_STRNCPY_ZEROFILL\n"); 117 fprintf(file, "#define USING_MIG_STRNCPY_ZEROFILL\n"); 118 fprintf(file, "#endif\n"); 119 120 fprintf(file, "#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__\n"); 121 fprintf(file, "#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__\n"); 122 123 fprintf(file, "#ifdef __cplusplus\n"); 124 fprintf(file, "extern \"C\" {\n"); 125 fprintf(file, "#endif\n"); 126 127 fprintf(file, "#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS_CSTRING_ATTR\n"); 128 fprintf(file, "#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS_CSTRING_COUNTEDBY_ATTR(C) __unsafe_indexable\n"); 129 fprintf(file, "#endif\n"); 130 const char *countAttr = EmitCountAnnotations ? "__MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS_CSTRING_COUNTEDBY_ATTR(len)" : ""; 131 fprintf(file, "\textern int mig_strncpy_zerofill(char *%s dest, const char *%s src, int len) __attribute__((weak_import));\n", countAttr, countAttr); 132 133 fprintf(file, "#ifdef __cplusplus\n"); 134 fprintf(file, "}\n"); 135 fprintf(file, "#endif\n"); 136 137 fprintf(file, "#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */\n"); 138 fprintf(file, "#endif /* __has_include(<mach/mig_strncpy_zerofill_support.h>) */\n"); 139 fprintf(file, "#endif /* __has_include */\n"); 140 fprintf(file, "\t\n/* END MIG_STRNCPY_ZEROFILL CODE */\n\n"); 141 142 if (ShortCircuit) 143 fprintf(file, "#include <mach/rpc.h>\n"); 144 if (isuser && IsKernelUser) { 145 fprintf(file, "#if\t(__MigKernelSpecificCode) || (_MIG_KERNEL_SPECIFIC_CODE_)\n"); 146 fprintf(file, "#include <kern/ipc_mig.h>\n"); 147 fprintf(file, "#endif /* __MigKernelSpecificCode */\n"); 148 } 149 } 150 fprintf(file, "\n"); 151} 152 153static void 154WriteETAPDefines(FILE *file) 155{ 156 statement_t *stat; 157 int fnum; 158 char *fname; 159 int first = TRUE; 160 161 fprintf(file, "\n#ifndef subsystem_to_name_map_%s\n", SubsystemName); 162 fprintf(file, "#define subsystem_to_name_map_%s \\\n", SubsystemName); 163 for (stat = stats; stat != stNULL; stat = stat->stNext) 164 if (stat->stKind == skRoutine) { 165 fnum = SubsystemBase + stat->stRoutine->rtNumber; 166 fname = stat->stRoutine->rtName; 167 if (! first) 168 fprintf(file, ",\\\n"); 169 fprintf(file, " { \"%s\", %d }", fname, fnum); 170 first = FALSE; 171 } 172 fprintf(file, "\n#endif\n"); 173} 174 175static void 176WriteProlog(FILE *file, char *protect, boolean_t more, boolean_t isuser) 177{ 178 if (protect != strNULL) { 179 fprintf(file, "#ifndef\t_%s\n", protect); 180 fprintf(file, "#define\t_%s\n", protect); 181 fprintf(file, "\n"); 182 } 183 184 fprintf(file, "/* Module %s */\n", SubsystemName); 185 fprintf(file, "\n"); 186 187 if (more) { 188 WriteIncludes(file, isuser, UseSplitHeaders); 189 } 190 fprintf(file, "#ifdef AUTOTEST\n"); 191 fprintf(file, "#ifndef FUNCTION_PTR_T\n"); 192 fprintf(file, "#define FUNCTION_PTR_T\n"); 193 fprintf(file, "typedef void (*function_ptr_t)"); 194 fprintf(file, "(mach_port_t, char *%s, mach_msg_type_number_t);\n", EmitCountAnnotations ? "__unsafe_indexable" : ""); 195 fprintf(file, "typedef struct {\n"); 196 fprintf(file, " char *%s name;\n", EmitCountAnnotations ? "__unsafe_indexable" : ""); 197 fprintf(file, " function_ptr_t function;\n"); 198 fprintf(file, "} function_table_entry;\n"); 199 fprintf(file, "typedef function_table_entry *function_table_t;\n"); 200 fprintf(file, "#endif /* FUNCTION_PTR_T */\n"); 201 fprintf(file, "#endif /* AUTOTEST */\n"); 202 fprintf(file, "\n#ifndef\t%s_MSG_COUNT\n", SubsystemName); 203 fprintf(file, "#define\t%s_MSG_COUNT\t%d\n", SubsystemName, rtNumber); 204 fprintf(file, "#endif\t/* %s_MSG_COUNT */\n\n", SubsystemName); 205} 206 207static void 208WriteEpilog(FILE *file, char *protect, boolean_t isuser) 209{ 210 char *defname = isuser ? "__AfterMigUserHeader" : "__AfterMigServerHeader"; 211 212 WriteETAPDefines(file); 213 fprintf(file, "\n#ifdef %s\n%s\n#endif /* %s */\n", defname, defname, defname); 214 if (protect != strNULL) { 215 fprintf(file, "\n"); 216 fprintf(file, "#endif\t /* _%s */\n", protect); 217 } 218} 219 220static void 221WriteUserRoutine(FILE *file, routine_t *rt) 222{ 223 fprintf(file, "\n"); 224 fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName); 225 WriteMigExternal(file); 226 fprintf(file, "%s %s\n", ReturnTypeStr(rt), rt->rtUserName); 227 if (BeLint) { 228 fprintf(file, "#if\t%s\n", LintLib); 229 fprintf(file, " ("); 230 WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", " , ""); 231 fprintf(file, ")\n"); 232 WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ";\n", ";\n"); 233 fprintf(file, "{ "); 234 fprintf(file, "return "); 235 fprintf(file, "%s(", rt->rtUserName); 236 WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", ", ""); 237 fprintf(file, "); }\n"); 238 fprintf(file, "#else\n"); 239 } 240 if (BeAnsiC) { 241 fprintf(file, "(\n"); 242 WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n"); 243 fprintf(file, ");\n"); 244 } 245 else { 246 fprintf(file, "#if\t%s\n", NewCDecl); 247 fprintf(file, "(\n"); 248 WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n"); 249 fprintf(file, ");\n"); 250 fprintf(file, "#else\n"); 251 252 fprintf(file, " ();\n"); 253 fprintf(file, "#endif\t/* %s */\n", NewCDecl); 254 } 255 if (BeLint) { 256 fprintf(file, "#endif\t/* %s */\n", LintLib); 257 } 258} 259 260void 261WriteUserRequestUnion(FILE *file, statement_t *stats) 262{ 263 statement_t *stat; 264 265 fprintf(file, "/* union of all requests */\n\n"); 266 fprintf(file, "#ifndef __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName); 267 fprintf(file, "#define __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName); 268 fprintf(file, "union __RequestUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName); 269 for (stat = stats; stat != stNULL; stat = stat->stNext) { 270 if (stat->stKind == skRoutine) { 271 routine_t *rt; 272 273 rt = stat->stRoutine; 274 fprintf(file, "\t__Request__%s_t Request_%s;\n", rt->rtName, rt->rtUserName); 275 } 276 } 277 fprintf(file, "};\n"); 278 fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName); 279} 280 281void 282WriteUserReplyUnion(FILE *file, statement_t *stats) 283{ 284 statement_t *stat; 285 286 fprintf(file, "/* union of all replies */\n\n"); 287 fprintf(file, "#ifndef __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName); 288 fprintf(file, "#define __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName); 289 fprintf(file, "union __ReplyUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName); 290 for (stat = stats; stat != stNULL; stat = stat->stNext) { 291 if (stat->stKind == skRoutine) { 292 routine_t *rt; 293 294 rt = stat->stRoutine; 295 fprintf(file, "\t__Reply__%s_t Reply_%s;\n", rt->rtName, rt->rtUserName); 296 } 297 } 298 fprintf(file, "};\n"); 299 fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName); 300} 301 302void 303WriteUserHeader(FILE *file, statement_t *stats) 304{ 305 statement_t *stat; 306 char *protect = strconcat(SubsystemName, "_user_"); 307 308 WriteProlog(file, protect, TRUE, TRUE); 309 for (stat = stats; stat != stNULL; stat = stat->stNext) 310 switch (stat->stKind) { 311 312 case skImport: 313 case skUImport: 314 case skDImport: 315 WriteImport(file, stat->stFileName); 316 break; 317 318 case skRoutine: 319 case skSImport: 320 case skIImport: 321 break; 322 323 default: 324 fatal("WriteHeader(): bad statement_kind_t (%d)", (int) stat->stKind); 325 } 326 fprintf(file, "\n"); 327 fprintf(file, "#ifdef __BeforeMigUserHeader\n"); 328 fprintf(file, "__BeforeMigUserHeader\n"); 329 fprintf(file, "#endif /* __BeforeMigUserHeader */\n"); 330 fprintf(file, "\n"); 331 fprintf(file, "#include <sys/cdefs.h>\n"); 332 fprintf(file, "__BEGIN_DECLS\n"); 333 fprintf(file, "\n"); 334 for (stat = stats; stat != stNULL; stat = stat->stNext) { 335 if (stat->stKind == skRoutine) 336 WriteUserRoutine(file, stat->stRoutine); 337 } 338 fprintf(file, "\n"); 339 fprintf(file, "__END_DECLS\n"); 340 341 fprintf(file, "\n"); 342 fprintf(file, "/********************** Caution **************************/\n"); 343 fprintf(file, "/* The following data types should be used to calculate */\n"); 344 fprintf(file, "/* maximum message sizes only. The actual message may be */\n"); 345 fprintf(file, "/* smaller, and the position of the arguments within the */\n"); 346 fprintf(file, "/* message layout may vary from what is presented here. */\n"); 347 fprintf(file, "/* For example, if any of the arguments are variable- */\n"); 348 fprintf(file, "/* sized, and less than the maximum is sent, the data */\n"); 349 fprintf(file, "/* will be packed tight in the actual message to reduce */\n"); 350 fprintf(file, "/* the presence of holes. */\n"); 351 fprintf(file, "/********************** Caution **************************/\n"); 352 fprintf(file, "\n"); 353 354 WriteRequestTypes(file, stats); 355 WriteUserRequestUnion(file, stats); 356 357 WriteReplyTypes(file, stats); 358 WriteUserReplyUnion(file, stats); 359 360 WriteEpilog(file, protect, TRUE); 361} 362 363static void 364WriteDefinesRoutine(FILE *file, routine_t *rt) 365{ 366 char *up = (char *)malloc(strlen(rt->rtName)+1); 367 368 up = toupperstr(strcpy(up, rt->rtName)); 369 fprintf(file, "#define\tMACH_ID_%s\t\t%d\t/* %s() */\n", up, rt->rtNumber + SubsystemBase, rt->rtName); 370 if (rt->rtKind == rkRoutine) 371 fprintf(file, "#define\tMACH_ID_%s_REPLY\t\t%d\t/* %s() */\n", up, rt->rtNumber + SubsystemBase + 100, rt->rtName); 372 fprintf(file, "\n"); 373} 374 375void 376WriteServerRoutine(FILE *file, routine_t *rt) 377{ 378 fprintf(file, "\n"); 379 fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName); 380 WriteMigExternal(file); 381 382 // MIG_SERVER_ROUTINE can be defined by system headers to resolve to an attribute that 383 // tells the compiler that this is a MIG server routine. Useful for static analysis. 384 fprintf(file, "MIG_SERVER_ROUTINE\n%s %s\n", ReturnTypeStr(rt), rt->rtServerName); 385 386 if (BeLint) { 387 fprintf(file, "#if\t%s\n", LintLib); 388 fprintf(file, " ("); 389 WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", " , ""); 390 fprintf(file, ")\n"); 391 WriteList(file, rt->rtArgs, WriteServerVarDecl, akbServerArg, ";\n", ";\n"); 392 fprintf(file, "{ "); 393 fprintf(file, "return "); 394 fprintf(file, "%s(", rt->rtServerName); 395 WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", ", ""); 396 fprintf(file, "); }\n"); 397 fprintf(file, "#else /* %s */\n",LintLib); 398 } 399 if (BeAnsiC) { 400 fprintf(file, "(\n"); 401 WriteList(file, rt->rtArgs, WriteServerVarDecl, akbServerArg, ",\n", "\n"); 402 fprintf(file, ");\n"); 403 } 404 else { 405 fprintf(file, "#if\t%s\n", NewCDecl); 406 fprintf(file, "(\n"); 407 WriteList(file, rt->rtArgs, WriteServerVarDecl, akbServerArg, ",\n", "\n"); 408 fprintf(file, ");\n"); 409 fprintf(file, "#else\n"); 410 411 fprintf(file, " ();\n"); 412 fprintf(file, "#endif\t/* %s */\n", NewCDecl); 413 } 414 if (BeLint) { 415 fprintf(file, "#endif\t/* %s */\n", LintLib); 416 } 417} 418 419static void 420WriteDispatcher(FILE *file) 421{ 422 statement_t *stat; 423 int descr_count = 0; 424 char *kern_ = ""; 425 char *k = ""; 426 char *kernel = ""; 427 428 if (UseMachMsg2) { 429 kern_ = "kern_"; 430 k = "k"; 431 kernel = "kernel "; 432 } 433 434 for (stat = stats; stat != stNULL; stat = stat->stNext) 435 if (stat->stKind == skRoutine) { 436 routine_t *rt = stat->stRoutine; 437 descr_count += rtCountArgDescriptors(rt->rtArgs, (int *) 0); 438 } 439 fprintf(file, "\n"); 440 441 WriteMigExternal(file); 442 fprintf(file, "boolean_t %s(", ServerDemux); 443 fprintf(file, "\n\t\tmach_msg_header_t *InHeadP,"); 444 if (!UseMachMsg2) { 445 fprintf(file, "\n\t\tmach_msg_header_t *OutHeadP"); 446 } else { 447 fprintf(file, "\n\t\tvoid *InDataP,"); 448 fprintf(file, "\n\t\tmach_msg_max_trailer_t *InTrailerP,"); 449 fprintf(file, "\n\t\tmach_msg_header_t *OutHeadP,"); 450 fprintf(file, "\n\t\tvoid *OutDataP"); 451 } 452 fprintf(file, ");\n\n"); 453 454 WriteMigExternal(file); 455 fprintf(file, "mig_%sroutine_t %s_routine(\n", kern_, ServerDemux); 456 fprintf(file, "\t\tmach_msg_header_t *InHeadP);\n\n"); 457 458 fprintf(file, "\n/* Description of this %ssubsystem, for use in direct RPC */\n", kernel); 459 fprintf(file, "extern const struct %s {\n", ServerSubsys); 460 if (UseRPCTrap) { 461 fprintf(file, "\tstruct subsystem *\tsubsystem;\t/* Reserved for system use */\n"); 462 } 463 else { 464 fprintf(file, "\tmig_%sserver_routine_t\t%sserver;\t/* Server routine */\n", kern_, k); 465 } 466 fprintf(file, "\tmach_msg_id_t\tstart;\t/* Min routine number */\n"); 467 fprintf(file, "\tmach_msg_id_t\tend;\t/* Max routine number + 1 */\n"); 468 fprintf(file, "\tunsigned int\tmaxsize;\t/* Max msg size */\n"); 469 if (UseRPCTrap) { 470 fprintf(file, "\tvm_address_t\tbase_addr;\t/* Base address */\n"); 471 fprintf(file, "\tstruct rpc_routine_descriptor\t/* Array of routine descriptors */\n"); 472 } 473 else { 474 fprintf(file, "\tvm_address_t\treserved;\t/* Reserved */\n"); 475 fprintf(file, "\tstruct %sroutine_descriptor\t/* Array of routine descriptors */\n", kern_); 476 } 477 fprintf(file, "\t\t%sroutine[%d];\n", k, rtNumber); 478 if (UseRPCTrap) { 479 fprintf(file, "\tstruct rpc_routine_arg_descriptor\t/*Array of arg descriptors */\n"); 480 fprintf(file, "\t\targ_descriptor[%d];\n", descr_count); 481 } 482 fprintf(file, "} %s;\n", ServerSubsys); 483 fprintf(file, "\n"); 484} 485 486void 487WriteBogusServerRoutineAnnotationDefine(FILE *file) { 488 // MIG_SERVER_ROUTINE can be defined by system headers to resolve to 489 // an attribute that tells the compiler that this is a MIG server routine. 490 // Useful for static analysis. 491 fprintf(file, "#ifndef MIG_SERVER_ROUTINE\n"); 492 fprintf(file, "#define MIG_SERVER_ROUTINE\n"); 493 fprintf(file, "#endif\n"); 494 fprintf(file, "\n"); 495} 496 497void 498WriteServerHeader(FILE *file, statement_t *stats) 499{ 500 statement_t *stat; 501 char *protect = strconcat(SubsystemName, "_server_"); 502 503 WriteProlog(file, protect, TRUE, FALSE); 504 for (stat = stats; stat != stNULL; stat = stat->stNext) 505 switch (stat->stKind) { 506 507 case skImport: 508 case skSImport: 509 case skDImport: 510 WriteImport(file, stat->stFileName); 511 break; 512 513 case skRoutine: 514 case skUImport: 515 case skIImport: 516 break; 517 518 default: 519 fatal("WriteServerHeader(): bad statement_kind_t (%d)", (int) stat->stKind); 520 } 521 fprintf(file, "\n#ifdef __BeforeMigServerHeader\n"); 522 fprintf(file, "__BeforeMigServerHeader\n"); 523 fprintf(file, "#endif /* __BeforeMigServerHeader */\n\n"); 524 525 WriteBogusServerRoutineAnnotationDefine(file); 526 527 for (stat = stats; stat != stNULL; stat = stat->stNext) { 528 if (stat->stKind == skRoutine) 529 WriteServerRoutine(file, stat->stRoutine); 530 } 531 WriteDispatcher(file); 532 533 WriteRequestTypes(file, stats); 534 WriteServerRequestUnion(file, stats); 535 536 WriteReplyTypes(file, stats); 537 WriteServerReplyUnion(file, stats); 538 539 WriteEpilog(file, protect, FALSE); 540} 541 542static void 543WriteInternalRedefine(FILE *file, routine_t *rt) 544{ 545 fprintf(file, "#define %s %s_external\n", rt->rtUserName, rt->rtUserName); 546} 547 548void 549WriteInternalHeader(FILE *file, statement_t *stats) 550{ 551 statement_t *stat; 552 553 for (stat = stats; stat != stNULL; stat = stat->stNext) 554 switch (stat->stKind) { 555 556 case skRoutine: 557 WriteInternalRedefine(file, stat->stRoutine); 558 break; 559 560 case skImport: 561 case skUImport: 562 case skSImport: 563 case skDImport: 564 case skIImport: 565 break; 566 567 default: 568 fatal("WriteInternalHeader(): bad statement_kind_t (%d)", (int) stat->stKind); 569 } 570} 571 572void 573WriteDefinesHeader(FILE *file, statement_t *stats) 574{ 575 statement_t *stat; 576 char *protect = strconcat(SubsystemName, "_defines"); 577 578 WriteProlog(file, protect, FALSE, FALSE); 579 fprintf(file, "\n/*\tDefines related to the Subsystem %s\t*/\n\n", SubsystemName); 580 for (stat = stats; stat != stNULL; stat = stat->stNext) 581 switch (stat->stKind) { 582 583 case skRoutine: 584 WriteDefinesRoutine(file, stat->stRoutine); 585 break; 586 587 case skImport: 588 case skSImport: 589 case skUImport: 590 break; 591 592 default: 593 fatal("WriteDefinesHeader(): bad statement_kind_t (%d)", (int) stat->stKind); 594 } 595 WriteEpilog(file, protect, FALSE); 596}