1 /*-
2 * Copyright (c) 2014, Matthew Macy <kmacy@FreeBSD.ORG>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27 /*
28 * Copyright 1991-1998 by Open Software Foundation, Inc.
29 * All Rights Reserved
30 *
31 * Permission to use, copy, modify, and distribute this software and
32 * its documentation for any purpose and without fee is hereby granted,
33 * provided that the above copyright notice appears in all copies and
34 * that both the copyright notice and this permission notice appear in
35 * supporting documentation.
36 *
37 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
39 * FOR A PARTICULAR PURPOSE.
40 *
41 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
42 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
43 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
44 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
45 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46 */
47 /*
48 * cmk1.1
49 */
50 /*
51 * Mach Operating System
52 * Copyright (c) 1991,1990 Carnegie Mellon University
53 * All Rights Reserved.
54 *
55 * Permission to use, copy, modify and distribute this software and its
56 * documentation is hereby granted, provided that both the copyright
57 * notice and this permission notice appear in all copies of the
58 * software, derivative works or modified versions, and any portions
59 * thereof, and that both notices appear in supporting documentation.
60 *
61 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
62 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
63 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
64 *
65 * Carnegie Mellon requests users of this software to return to
66 *
67 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
68 * School of Computer Science
69 * Carnegie Mellon University
70 * Pittsburgh PA 15213-3890
71 *
72 * any improvements or extensions that they make and grant Carnegie the
73 * rights to redistribute these changes.
74 */
75 /*
76 * 91/08/28 11:16:58 jsb
77 * Removed TrapRoutine support.
78 * [91/08/12 rpd]
79 *
80 * 91/06/26 14:39:37 rpd
81 * Removed the user initialization function and InitRoutineName.
82 * Fixed to use different symbolic constants to protect
83 * the user and server header files against multiple inclusion.
84 * [91/06/26 rpd]
85 *
86 * 91/06/25 10:31:21 rpd
87 * Restored prototype generation.
88 * Changed WriteHeader to WriteUserHeader.
89 * Added WriteServerHeader.
90 * [91/05/23 rpd]
91 *
92 * 91/02/05 17:54:33 mrt
93 * Changed to new Mach copyright
94 * [91/02/01 17:54:19 mrt]
95 *
96 * 90/12/20 17:04:47 jeffreyh
97 * Commented out code for prototype generation. This is a temporary solution
98 * to the longer term problem of the need
99 * for the generation of both a client and a server header file
100 * that have correct prototypes for strict ansi c and c++. The
101 * prototypes generated before anly were for the client and broke kernel
102 * files that included them if compiled under standard gcc
103 * [90/12/07 jeffreyh]
104 *
105 * 90/06/02 15:04:46 rpd
106 * Created for new IPC.
107 * [90/03/26 21:11:06 rpd]
108 *
109 * 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
110 * Extensive revamping. Added polymorphic arguments.
111 * Allow multiple variable-sized inline arguments in messages.
112 *
113 * 8-Jul-88 Mary Thompson (mrt) at Carnegie-Mellon University
114 * Conditionally defined mig_external to be extern and then defined
115 * all functions with the storage class mig_external.
116 * Mig_external can be changed
117 * when the generated code is compiled.
118 *
119 * 18-Jan-88 David Detlefs (dld) at Carnegie-Mellon University
120 * Modified to produce C++ compatible code via #ifdefs.
121 * All changes have to do with argument declarations.
122 *
123 * 3-Aug-87 Mary Thompson (mrt) at Carnegie-Mellon University
124 * Revision to make multi-threaded use work. Removed definitions for
125 * alloc_reply_port and init_msg_type as these routines are
126 * no longer generated.
127 *
128 * 30-Jul-87 Mary Thompson (mrt) at Carnegie-Mellon University
129 * Made changes to generate conditional code for C++ parameter lists
130 *
131 * 29-Jul-87 Mary Thompson (mrt) at Carnegie-Mellon University
132 * Changed WriteRoutine to produce conditional argument
133 * lists for C++
134 *
135 * 8-Jun-87 Mary Thompson (mrt) at Carnegie-Mellon University
136 * Changed the KERNEL include from ../h to sys/
137 * Removed extern from WriteHeader to make hi-c happy
138 *
139 * 28-May-87 Richard Draves (rpd) at Carnegie-Mellon University
140 * Created.
141 */
142
143 #include "write.h"
144 #include "utils.h"
145 #include "global.h"
146 #include "strdefs.h"
147 #include "error.h"
148 #include <stdlib.h>
149
150 void
WriteIncludes(FILE * file,boolean_t isuser,boolean_t isdef)151 WriteIncludes(FILE *file, boolean_t isuser, boolean_t isdef)
152 {
153 if (isdef) {
154 fprintf(file, "#include <mach/port.h>\n");
155 fprintf(file, "#include <machine/mach/kern_return.h>\n");
156 if (!isuser)
157 fprintf(file, "#include <mach/mig_errors.h>\n");
158 }
159 else {
160 fprintf(file, "#include <sys/cdefs.h>\n");
161 fprintf(file, "#include <sys/types.h>\n");
162 fprintf(file, "#ifdef _KERNEL\n");
163 fprintf(file, "#include <sys/mach/ndr.h>\n");
164 fprintf(file, "#include <sys/mach/kern_return.h>\n");
165 fprintf(file, "#include <sys/mach/notify.h>\n");
166 fprintf(file, "#include <sys/mach/mach_types.h>\n");
167 fprintf(file, "#include <sys/mach/message.h>\n");
168 fprintf(file, "#include <sys/mach/mig_errors.h>\n");
169 fprintf(file, "#else /* !_KERNEL */\n");
170 fprintf(file, "#include <string.h>\n");
171 fprintf(file, "#include <mach/ndr.h>\n");
172 fprintf(file, "#include <mach/boolean.h>\n");
173 fprintf(file, "#include <mach/kern_return.h>\n");
174 fprintf(file, "#include <mach/notify.h>\n");
175 fprintf(file, "#include <mach/mach_types.h>\n");
176 fprintf(file, "#include <mach/message.h>\n");
177 fprintf(file, "#include <mach/mig_errors.h>\n");
178 fprintf(file, "#endif /*_KERNEL */\n");
179 if (ShortCircuit)
180 fprintf(file, "#include <mach/rpc.h>\n");
181 if (isuser && IsKernelUser) {
182 fprintf(file, "#if\t(__MigKernelSpecificCode) || (_MIG_KERNEL_SPECIFIC_CODE_)\n");
183 fprintf(file, "#include <kern/ipc_mig.h>\n");
184 fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
185 }
186 }
187 fprintf(file, "\n");
188 }
189
190 static void
WriteETAPDefines(FILE * file)191 WriteETAPDefines(FILE *file)
192 {
193 register statement_t *stat;
194 int fnum;
195 const char *fname;
196 int first = TRUE;
197
198 fprintf(file, "\n#ifndef subsystem_to_name_map_%s\n", SubsystemName);
199 fprintf(file, "#define subsystem_to_name_map_%s \\\n", SubsystemName);
200 for (stat = defs_stats; stat != stNULL; stat = stat->stNext)
201 if (stat->stKind == skRoutine)
202 {
203 fnum = SubsystemBase + stat->stRoutine->rtNumber;
204 fname = stat->stRoutine->rtName;
205 if (! first)
206 fprintf(file, ",\\\n");
207 fprintf(file, " { \"%s\", %d }", fname, fnum);
208 first = FALSE;
209 }
210 fprintf(file, "\n#endif\n");
211 }
212
213 static void
WriteProlog(FILE * file,const char * protect,boolean_t more,boolean_t isuser)214 WriteProlog(FILE *file, const char *protect, boolean_t more, boolean_t isuser)
215 {
216 if (protect != strNULL) {
217 fprintf(file, "#ifndef\t_%s\n", protect);
218 fprintf(file, "#define\t_%s\n", protect);
219 fprintf(file, "\n");
220 }
221
222 fprintf(file, "/* Module %s */\n", SubsystemName);
223 fprintf(file, "\n");
224
225 if (more) {
226 WriteIncludes(file, isuser, UseSplitHeaders);
227 }
228 fprintf(file, "#ifdef AUTOTEST\n");
229 fprintf(file, "#ifndef FUNCTION_PTR_T\n");
230 fprintf(file, "#define FUNCTION_PTR_T\n");
231 fprintf(file, "typedef void (*function_ptr_t)");
232 fprintf(file, "(mach_port_t, char *, mach_msg_type_number_t);\n");
233 fprintf(file, "typedef struct {\n");
234 fprintf(file, " char *name;\n");
235 fprintf(file, " function_ptr_t function;\n");
236 fprintf(file, "} function_table_entry;\n");
237 fprintf(file, "typedef function_table_entry *function_table_t;\n");
238 fprintf(file, "#endif /* FUNCTION_PTR_T */\n");
239 fprintf(file, "#endif /* AUTOTEST */\n");
240 fprintf(file, "\n#ifndef\t%s_MSG_COUNT\n", SubsystemName);
241 fprintf(file, "#define\t%s_MSG_COUNT\t%d\n", SubsystemName, rtNumber);
242 fprintf(file, "#endif\t/* %s_MSG_COUNT */\n\n", SubsystemName);
243 }
244
245 static void
WriteEpilog(FILE * file,const char * protect,boolean_t isuser)246 WriteEpilog(FILE *file, const char *protect, boolean_t isuser)
247 {
248 const char *defname =
249 isuser ? "__AfterMigUserHeader" : "__AfterMigServerHeader";
250
251 WriteETAPDefines(file);
252 fprintf(file, "\n#ifdef %s\n%s\n#endif /* %s */\n",
253 defname, defname, defname);
254 if (protect != strNULL) {
255 fprintf(file, "\n");
256 fprintf(file, "#endif\t /* _%s */\n", protect);
257 }
258 }
259
260 static void
WriteUserRoutine(FILE * file,routine_t * rt)261 WriteUserRoutine(FILE *file, routine_t *rt)
262 {
263 fprintf(file, "\n");
264 fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
265 WriteMigExternal(file);
266 fprintf(file, "%s %s\n", ReturnTypeStr(rt), rt->rtUserName);
267 fprintf(file, "#if\t%s\n", LintLib);
268 fprintf(file, " (");
269 WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", " , "");
270 fprintf(file, ")\n");
271 WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ";\n", ";\n");
272 fprintf(file, "{ ");
273 fprintf(file, "return ");
274 fprintf(file, "%s(", rt->rtUserName);
275 WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", ", "");
276 fprintf(file, "); }\n");
277 fprintf(file, "#else\n");
278 if (BeAnsiC) {
279 fprintf(file, "(\n");
280 WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
281 fprintf(file, ");\n");
282 } else {
283 fprintf(file, "#if\t%s\n", NewCDecl);
284 fprintf(file, "(\n");
285 WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
286 fprintf(file, ");\n");
287 fprintf(file, "#else\n");
288
289 fprintf(file, " ();\n");
290 fprintf(file, "#endif\t/* %s */\n", NewCDecl);
291 }
292 fprintf(file, "#endif\t/* %s */\n", LintLib);
293 }
294
295 void
WriteUserRequestUnion(FILE * file,statement_t * stats)296 WriteUserRequestUnion(FILE *file, statement_t *stats)
297 {
298 register statement_t *stat;
299
300 fprintf(file, "/* union of all requests */\n\n");
301 fprintf(file, "#ifndef __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
302 fprintf(file, "#define __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
303 fprintf(file, "union __RequestUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName);
304 for (stat = stats; stat != stNULL; stat = stat->stNext) {
305 if (stat->stKind == skRoutine) {
306 register routine_t *rt;
307
308 rt = stat->stRoutine;
309 fprintf(file, "\t__Request__%s_t Request_%s;\n", rt->rtName, rt->rtUserName);
310 }
311 }
312 fprintf(file, "};\n");
313 fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName);
314 }
315
316 void
WriteUserReplyUnion(FILE * file,statement_t * stats)317 WriteUserReplyUnion(FILE *file, statement_t *stats)
318 {
319 register statement_t *stat;
320
321 fprintf(file, "/* union of all replies */\n\n");
322 fprintf(file, "#ifndef __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
323 fprintf(file, "#define __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
324 fprintf(file, "union __ReplyUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName);
325 for (stat = stats; stat != stNULL; stat = stat->stNext) {
326 if (stat->stKind == skRoutine) {
327 register routine_t *rt;
328
329 rt = stat->stRoutine;
330 fprintf(file, "\t__Reply__%s_t Reply_%s;\n", rt->rtName, rt->rtUserName);
331 }
332 }
333 fprintf(file, "};\n");
334 fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName);
335 }
336
337 void
WriteUserHeader(FILE * file,statement_t * stats)338 WriteUserHeader(FILE *file, statement_t *stats)
339 {
340 register statement_t *stat;
341 const char *protect = strconcat(SubsystemName, "_user_");
342
343 WriteProlog(file, protect, TRUE, TRUE);
344 for (stat = stats; stat != stNULL; stat = stat->stNext)
345 switch (stat->stKind)
346 {
347 case skImport:
348 case skUImport:
349 case skDImport:
350 WriteImport(file, stat->stFileName);
351 break;
352 case skRoutine:
353 case skSImport:
354 case skIImport:
355 break;
356 default:
357 fatal("WriteHeader(): bad statement_kind_t (%d)",
358 (int) stat->stKind);
359 }
360 fprintf(file, "\n#ifdef __BeforeMigUserHeader\n");
361 fprintf(file, "__BeforeMigUserHeader\n");
362 fprintf(file, "#endif /* __BeforeMigUserHeader */\n");
363 fprintf(file, "\n");
364 fprintf(file, "#include <sys/cdefs.h>\n");
365 fprintf(file, "__BEGIN_DECLS\n");
366 fprintf(file, "\n");
367 for (stat = stats; stat != stNULL; stat = stat->stNext) {
368 if (stat->stKind == skRoutine)
369 WriteUserRoutine(file, stat->stRoutine);
370 }
371 fprintf(file, "\n");
372 fprintf(file, "__END_DECLS\n");
373
374 fprintf(file, "\n");
375 fprintf(file, "/********************** Caution **************************/\n");
376 fprintf(file, "/* The following data types should be used to calculate */\n");
377 fprintf(file, "/* maximum message sizes only. The actual message may be */\n");
378 fprintf(file, "/* smaller, and the position of the arguments within the */\n");
379 fprintf(file, "/* message layout may vary from what is presented here. */\n");
380 fprintf(file, "/* For example, if any of the arguments are variable- */\n");
381 fprintf(file, "/* sized, and less than the maximum is sent, the data */\n");
382 fprintf(file, "/* will be packed tight in the actual message to reduce */\n");
383 fprintf(file, "/* the presence of holes. */\n");
384 fprintf(file, "/********************** Caution **************************/\n");
385 fprintf(file, "\n");
386
387 WriteRequestTypes(file, stats);
388 WriteUserRequestUnion(file, stats);
389
390 WriteReplyTypes(file, stats);
391 WriteUserReplyUnion(file, stats);
392
393 WriteEpilog(file, protect, TRUE);
394 }
395
396 static void
WriteDefinesRoutine(FILE * file,routine_t * rt)397 WriteDefinesRoutine(FILE *file, routine_t *rt)
398 {
399 char *up = (char *)malloc(strlen(rt->rtName)+1);
400
401 up = toupperstr(strcpy(up, rt->rtName));
402 fprintf(file, "#define\tMACH_ID_%s\t\t%d\t/* %s() */\n",
403 up, rt->rtNumber + SubsystemBase, rt->rtName);
404 if (rt->rtKind == rkRoutine)
405 fprintf(file, "#define\tMACH_ID_%s_REPLY\t\t%d\t/* %s() */\n",
406 up, rt->rtNumber + SubsystemBase + 100, rt->rtName);
407 fprintf(file, "\n");
408 }
409
410 void
WriteServerRoutine(FILE * file,routine_t * rt)411 WriteServerRoutine(FILE *file, routine_t *rt)
412 {
413 fprintf(file, "\n");
414 fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
415 WriteMigExternal(file);
416 fprintf(file, "%s %s\n", ReturnTypeStr(rt), rt->rtServerName);
417 fprintf(file, "#if\t%s\n", LintLib);
418 fprintf(file, " (");
419 WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", " , "");
420 fprintf(file, ")\n");
421 WriteList(file, rt->rtArgs, WriteServerVarDecl,
422 akbServerArg, ";\n", ";\n");
423 fprintf(file, "{ ");
424 fprintf(file, "return ");
425 fprintf(file, "%s(", rt->rtServerName);
426 WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", ", "");
427 fprintf(file, "); }\n");
428 fprintf(file, "#else\n");
429 if (BeAnsiC) {
430 fprintf(file, "(\n");
431 WriteList(file, rt->rtArgs, WriteServerVarDecl,
432 akbServerArg, ",\n", "\n");
433 fprintf(file, ");\n");
434 } else {
435 fprintf(file, "#if\t%s\n", NewCDecl);
436 fprintf(file, "(\n");
437 WriteList(file, rt->rtArgs, WriteServerVarDecl,
438 akbServerArg, ",\n", "\n");
439 fprintf(file, ");\n");
440 fprintf(file, "#else\n");
441
442 fprintf(file, " ();\n");
443 fprintf(file, "#endif\t/* %s */\n", NewCDecl);
444 }
445 fprintf(file, "#endif\t/* %s */\n", LintLib);
446 }
447
448 static void
WriteDispatcher(FILE * file)449 WriteDispatcher(FILE *file)
450 {
451 register statement_t *stat;
452 int descr_count = 0;
453
454 for (stat = defs_stats; stat != stNULL; stat = stat->stNext)
455 if (stat->stKind == skRoutine)
456 {
457 register routine_t *rt = stat->stRoutine;
458 descr_count += rtCountArgDescriptors(rt->rtArgs, (int *) 0);
459 }
460 fprintf(file, "\n");
461
462 WriteMigExternal(file);
463 fprintf(file, "boolean_t %s(\n", ServerDemux);
464 fprintf(file, "\t\tmach_msg_header_t *InHeadP,\n");
465 fprintf(file, "\t\tmach_msg_header_t *OutHeadP);\n\n");
466
467 WriteMigExternal(file);
468 fprintf(file, "mig_routine_t %s_routine(\n", ServerDemux);
469 fprintf(file, "\t\tmach_msg_header_t *InHeadP);\n\n");
470
471 fprintf(file, "\n/* Description of this subsystem, for use in direct RPC */\n");
472 fprintf(file, "extern const struct %s {\n", ServerSubsys);
473 if (UseRPCTrap) {
474 fprintf(file, "\tstruct subsystem *\tsubsystem;\t/* Reserved for system use */\n");
475 }
476 else {
477 fprintf(file, "\tmig_server_routine_t\tserver;\t/* Server routine */\n");
478 }
479 fprintf(file, "\tmach_msg_id_t\tstart;\t/* Min routine number */\n");
480 fprintf(file, "\tmach_msg_id_t\tend;\t/* Max routine number + 1 */\n");
481 fprintf(file, "\tunsigned int\tmaxsize;\t/* Max msg size */\n");
482 if (UseRPCTrap) {
483 fprintf(file, "\tvm_address_t\tbase_addr;\t/* Base address */\n");
484 fprintf(file, "\tstruct rpc_routine_descriptor\t/*Array of routine descriptors */\n");
485 }
486 else {
487 fprintf(file, "\tvm_address_t\treserved;\t/* Reserved */\n");
488 fprintf(file, "\tstruct routine_descriptor\t/*Array of routine descriptors */\n");
489 }
490 fprintf(file, "\t\troutine[%d];\n", rtNumber);
491 if (UseRPCTrap) {
492 fprintf(file, "\tstruct rpc_routine_arg_descriptor\t/*Array of arg descriptors */\n");
493 fprintf(file, "\t\targ_descriptor[%d];\n", descr_count);
494 }
495 fprintf(file, "} %s;\n", ServerSubsys);
496 fprintf(file, "\n");
497 }
498
499 void
WriteServerHeader(FILE * file,statement_t * stats)500 WriteServerHeader(FILE *file, statement_t *stats)
501 {
502 register statement_t *stat;
503 const char *protect = strconcat(SubsystemName, "_server_");
504
505 WriteProlog(file, protect, TRUE, FALSE);
506 for (stat = stats; stat != stNULL; stat = stat->stNext)
507 switch (stat->stKind)
508 {
509 case skImport:
510 case skSImport:
511 case skDImport:
512 WriteImport(file, stat->stFileName);
513 break;
514 case skRoutine:
515 case skUImport:
516 case skIImport:
517 break;
518 default:
519 fatal("WriteServerHeader(): bad statement_kind_t (%d)",
520 (int) stat->stKind);
521 }
522 fprintf(file, "\n#ifdef __BeforeMigServerHeader\n");
523 fprintf(file, "__BeforeMigServerHeader\n");
524 fprintf(file, "#endif /* __BeforeMigServerHeader */\n\n");
525 for (stat = stats; stat != stNULL; stat = stat->stNext) {
526 if (stat->stKind == skRoutine)
527 WriteServerRoutine(file, stat->stRoutine);
528 }
529
530 for (stat = stats; stat != stNULL; stat = stat->stNext) {
531 if (stat->stKind == skRoutine)
532 WriteServerRoutine(file, stat->stRoutine);
533 }
534 WriteDispatcher(file);
535
536 WriteRequestTypes(file, stats);
537 WriteServerRequestUnion(file, stats);
538
539 WriteReplyTypes(file, stats);
540 WriteServerReplyUnion(file, stats);
541
542 WriteEpilog(file, protect, FALSE);
543 }
544
545 static void
WriteInternalRedefine(FILE * file,register routine_t * rt)546 WriteInternalRedefine(FILE *file, register routine_t *rt)
547 {
548 fprintf(file, "#define %s %s_external\n",
549 rt->rtUserName, rt->rtUserName);
550 }
551
552 void
WriteInternalHeader(FILE * file,statement_t * stats)553 WriteInternalHeader(FILE *file, statement_t *stats)
554 {
555 register statement_t *stat;
556
557 for (stat = stats; stat != stNULL; stat = stat->stNext)
558 switch (stat->stKind)
559 {
560 case skRoutine:
561 WriteInternalRedefine(file, stat->stRoutine);
562 break;
563 case skImport:
564 case skUImport:
565 case skSImport:
566 case skDImport:
567 case skIImport:
568 break;
569 default:
570 fatal("WriteInternalHeader(): bad statement_kind_t (%d)",
571 (int) stat->stKind);
572 }
573 }
574
575 void
WriteDefinesHeader(FILE * file,statement_t * stats)576 WriteDefinesHeader(FILE *file, statement_t *stats)
577 {
578 register statement_t *stat;
579 const char *protect = strconcat(SubsystemName, "_defines");
580
581 WriteProlog(file, protect, FALSE, FALSE);
582 fprintf(file, "\n/*\tDefines related to the Subsystem %s\t*/\n\n", SubsystemName);
583 for (stat = stats; stat != stNULL; stat = stat->stNext) {
584 switch (stat->stKind)
585 {
586 case skRoutine:
587 WriteDefinesRoutine(file, stat->stRoutine);
588 break;
589 case skImport:
590 case skSImport:
591 case skUImport:
592 break;
593 default:
594 fatal("WriteDefinesHeader(): bad statement_kind_t (%d)",
595 (int) stat->stKind);
596 }
597 }
598 WriteEpilog(file, protect, FALSE);
599 }
600