|
|
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.