PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/kernel/src/mig/utils.c

https://github.com/Prajna/mach
C | 482 lines | 319 code | 52 blank | 111 comment | 39 complexity | 681364a690a547e375ed8a6c7799a073 MD5 | raw file
  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 Software.Distribution@CS.CMU.EDU
  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. * HISTORY
  28. * $Log: utils.c,v $
  29. * Revision 2.9 93/05/10 17:50:19 rvb
  30. * Fix include to use < vs " for new ode shadowing
  31. * [93/05/10 10:30:03 rvb]
  32. *
  33. * Revision 2.8 93/01/14 17:59:30 danner
  34. * Converted file and generated code to ANSI C.
  35. * Changed code to always use static message types.
  36. * [92/12/08 pds]
  37. *
  38. * Fixed bug checking for the Hi-C compiler: hc -> __HC__.
  39. * Made text on #endif/#else lines into comments.
  40. * [92/08/06 pds]
  41. *
  42. * Revision 2.7 92/01/14 16:47:08 rpd
  43. * Modified WriteTypeDeclIn and WriteTypeDeclOut to disable
  44. * the deallocate flag on Indefinite arguments.
  45. * [92/01/09 rpd]
  46. *
  47. * Revision 2.6 92/01/03 20:30:51 dbg
  48. * Change argByReferenceUser and argByReferenceServer to fields in
  49. * argument_t.
  50. * [91/08/29 dbg]
  51. *
  52. * Revision 2.5 91/07/31 18:11:45 dbg
  53. * Accept new dealloc_t argument type in WriteStaticDecl,
  54. * WritePackMsgType.
  55. *
  56. * Don't need to zero last character of C string. Mig_strncpy does
  57. * the proper work.
  58. *
  59. * Add SkipVFPrintf, so that WriteCopyType doesn't print fields in
  60. * comments.
  61. * [91/07/17 dbg]
  62. *
  63. * Revision 2.4 91/06/25 10:32:36 rpd
  64. * Changed WriteVarDecl to WriteUserVarDecl.
  65. * Added WriteServerVarDecl.
  66. * [91/05/23 rpd]
  67. *
  68. * Revision 2.3 91/02/05 17:56:28 mrt
  69. * Changed to new Mach copyright
  70. * [91/02/01 17:56:39 mrt]
  71. *
  72. * Revision 2.2 90/06/02 15:06:11 rpd
  73. * Created for new IPC.
  74. * [90/03/26 21:14:54 rpd]
  75. *
  76. * 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
  77. * Extensive revamping. Added polymorphic arguments.
  78. * Allow multiple variable-sized inline arguments in messages.
  79. *
  80. * 21-Aug-87 Mary Thompson (mrt) at Carnegie-Mellon University
  81. * Added deallocflag to the WritePackMsg routines.
  82. *
  83. * 29-Jul-87 Mary Thompson (mrt) at Carnegie-Mellon University
  84. * Changed WriteVarDecl to not automatically write
  85. * semi-colons between items, so that it can be
  86. * used to write C++ argument lists.
  87. *
  88. * 27-May-87 Richard Draves (rpd) at Carnegie-Mellon University
  89. * Created.
  90. */
  91. #include <mach/message.h>
  92. #include <stdarg.h>
  93. #include <write.h>
  94. #include <utils.h>
  95. extern int vfprintf(FILE *file, const char *fmt, va_list);
  96. void
  97. WriteImport(FILE *file, const_string_t filename)
  98. {
  99. fprintf(file, "#include %s\n", filename);
  100. }
  101. void
  102. WriteRCSDecl(FILE *file, identifier_t name, const_string_t rcs)
  103. {
  104. fprintf(file, "#ifndef\tlint\n");
  105. fprintf(file, "#if\tUseExternRCSId\n");
  106. fprintf(file, "char %s_rcsid[] = %s;\n", name, rcs);
  107. fprintf(file, "#else\t/* UseExternRCSId */\n");
  108. fprintf(file, "static char rcsid[] = %s;\n", rcs);
  109. fprintf(file, "#endif\t/* UseExternRCSId */\n");
  110. fprintf(file, "#endif\t/* lint */\n");
  111. fprintf(file, "\n");
  112. }
  113. void
  114. WriteBogusDefines(FILE *file)
  115. {
  116. fprintf(file, "#ifndef\tmig_internal\n");
  117. fprintf(file, "#define\tmig_internal\tstatic\n");
  118. fprintf(file, "#endif\n");
  119. fprintf(file, "\n");
  120. fprintf(file, "#ifndef\tmig_external\n");
  121. fprintf(file, "#define mig_external\n");
  122. fprintf(file, "#endif\n");
  123. fprintf(file, "\n");
  124. fprintf(file, "#ifndef\tTypeCheck\n");
  125. fprintf(file, "#define\tTypeCheck 1\n");
  126. fprintf(file, "#endif\n");
  127. fprintf(file, "\n");
  128. fprintf(file, "#ifndef\tUseExternRCSId\n");
  129. fprintf(file, "#define\tUseExternRCSId\t\t1\n");
  130. fprintf(file, "#endif\n");
  131. fprintf(file, "\n");
  132. }
  133. void
  134. WriteList(FILE *file, const argument_t *args, write_list_fn_t *func, u_int mask,
  135. const char *between, const char *after)
  136. {
  137. register const argument_t *arg;
  138. register boolean_t sawone = FALSE;
  139. for (arg = args; arg != argNULL; arg = arg->argNext)
  140. if (akCheckAll(arg->argKind, mask))
  141. {
  142. if (sawone)
  143. fprintf(file, "%s", between);
  144. sawone = TRUE;
  145. (*func)(file, arg);
  146. }
  147. if (sawone)
  148. fprintf(file, "%s", after);
  149. }
  150. static boolean_t
  151. WriteReverseListPrim(FILE *file, register const argument_t *arg,
  152. write_list_fn_t *func, u_int mask, const char *between)
  153. {
  154. boolean_t sawone = FALSE;
  155. if (arg != argNULL)
  156. {
  157. sawone = WriteReverseListPrim(file, arg->argNext, func, mask, between);
  158. if (akCheckAll(arg->argKind, mask))
  159. {
  160. if (sawone)
  161. fprintf(file, "%s", between);
  162. sawone = TRUE;
  163. (*func)(file, arg);
  164. }
  165. }
  166. return sawone;
  167. }
  168. void
  169. WriteReverseList(FILE *file, const argument_t *args, write_list_fn_t *func,
  170. u_int mask, const char *between, const char *after)
  171. {
  172. boolean_t sawone;
  173. sawone = WriteReverseListPrim(file, args, func, mask, between);
  174. if (sawone)
  175. fprintf(file, "%s", after);
  176. }
  177. void
  178. WriteNameDecl(FILE *file, const argument_t *arg)
  179. {
  180. fprintf(file, "%s", arg->argVarName);
  181. }
  182. void
  183. WriteUserVarDecl(FILE *file, const argument_t *arg)
  184. {
  185. const char *ref = arg->argByReferenceUser ? "*" : "";
  186. fprintf(file, "\t%s %s%s", arg->argType->itUserType, ref, arg->argVarName);
  187. }
  188. void
  189. WriteServerVarDecl(FILE *file, const argument_t *arg)
  190. {
  191. const char *ref = arg->argByReferenceServer ? "*" : "";
  192. fprintf(file, "\t%s %s%s",
  193. arg->argType->itTransType, ref, arg->argVarName);
  194. }
  195. void
  196. WriteTypeDeclIn(FILE *file, register const argument_t *arg)
  197. {
  198. WriteStaticDecl(file, arg->argType,
  199. arg->argType->itIndefinite ? d_NO : arg->argDeallocate,
  200. arg->argLongForm, TRUE, arg->argTTName);
  201. }
  202. void
  203. WriteTypeDeclOut(FILE *file, register const argument_t *arg)
  204. {
  205. WriteStaticDecl(file, arg->argType,
  206. arg->argType->itIndefinite ? d_NO : arg->argDeallocate,
  207. arg->argLongForm, FALSE, arg->argTTName);
  208. }
  209. void
  210. WriteCheckDecl(FILE *file, register const argument_t *arg)
  211. {
  212. register const ipc_type_t *it = arg->argType;
  213. /* We'll only be called for short-form types.
  214. Note we use itOutNameStr instead of itInNameStr, because
  215. this declaration will be used to check received types. */
  216. fprintf(file, "\tstatic mach_msg_type_t %sCheck = {\n", arg->argVarName);
  217. fprintf(file, "\t\t/* msgt_name = */\t\t%s,\n", it->itOutNameStr);
  218. fprintf(file, "\t\t/* msgt_size = */\t\t%d,\n", it->itSize);
  219. fprintf(file, "\t\t/* msgt_number = */\t\t%d,\n", it->itNumber);
  220. fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n",
  221. strbool(it->itInLine));
  222. fprintf(file, "\t\t/* msgt_longform = */\t\tFALSE,\n");
  223. fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n",
  224. strbool(!it->itInLine));
  225. fprintf(file, "\t\t/* msgt_unused = */\t\t0\n");
  226. fprintf(file, "\t};\n");
  227. }
  228. const char *
  229. ReturnTypeStr(const routine_t *rt)
  230. {
  231. if (rt->rtReturn == argNULL)
  232. return "void";
  233. else
  234. return rt->rtReturn->argType->itUserType;
  235. }
  236. const char *
  237. FetchUserType(const ipc_type_t *it)
  238. {
  239. return it->itUserType;
  240. }
  241. const char *
  242. FetchServerType(const ipc_type_t *it)
  243. {
  244. return it->itServerType;
  245. }
  246. void
  247. WriteFieldDeclPrim(FILE *file, const argument_t *arg,
  248. const char *(*tfunc)(const ipc_type_t *))
  249. {
  250. register const ipc_type_t *it = arg->argType;
  251. fprintf(file, "\t\tmach_msg_type_%st %s;\n",
  252. arg->argLongForm ? "long_" : "", arg->argTTName);
  253. if (it->itInLine && it->itVarArray)
  254. {
  255. register ipc_type_t *btype = it->itElement;
  256. /*
  257. * Build our own declaration for a varying array:
  258. * use the element type and maximum size specified.
  259. * Note arg->argCount->argMultiplier == btype->itNumber.
  260. */
  261. fprintf(file, "\t\t%s %s[%d];",
  262. (*tfunc)(btype),
  263. arg->argMsgField,
  264. it->itNumber/btype->itNumber);
  265. }
  266. else
  267. fprintf(file, "\t\t%s %s;", (*tfunc)(it), arg->argMsgField);
  268. if (it->itPadSize != 0)
  269. fprintf(file, "\n\t\tchar %s[%d];", arg->argPadName, it->itPadSize);
  270. }
  271. void
  272. WriteStructDecl(FILE *file, const argument_t *args, write_list_fn_t *func,
  273. u_int mask, const char *name)
  274. {
  275. fprintf(file, "\ttypedef struct {\n");
  276. fprintf(file, "\t\tmach_msg_header_t Head;\n");
  277. WriteList(file, args, func, mask, "\n", "\n");
  278. fprintf(file, "\t} %s;\n", name);
  279. fprintf(file, "\n");
  280. }
  281. static void
  282. WriteStaticLongDecl(FILE *file, register const ipc_type_t *it,
  283. dealloc_t dealloc, boolean_t inname, identifier_t name)
  284. {
  285. fprintf(file, "\tstatic mach_msg_type_long_t %s = {\n", name);
  286. fprintf(file, "\t{\n");
  287. fprintf(file, "\t\t/* msgt_name = */\t\t0,\n");
  288. fprintf(file, "\t\t/* msgt_size = */\t\t0,\n");
  289. fprintf(file, "\t\t/* msgt_number = */\t\t0,\n");
  290. fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n",
  291. strbool(it->itInLine));
  292. fprintf(file, "\t\t/* msgt_longform = */\t\tTRUE,\n");
  293. fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n",
  294. strdealloc(dealloc));
  295. fprintf(file, "\t\t/* msgt_unused = */\t\t0\n");
  296. fprintf(file, "\t},\n");
  297. fprintf(file, "\t\t/* msgtl_name = */\t%s,\n",
  298. inname ? it->itInNameStr : it->itOutNameStr);
  299. fprintf(file, "\t\t/* msgtl_size = */\t%d,\n", it->itSize);
  300. fprintf(file, "\t\t/* msgtl_number = */\t%d,\n", it->itNumber);
  301. fprintf(file, "\t};\n");
  302. }
  303. static void
  304. WriteStaticShortDecl(FILE *file, register const ipc_type_t *it,
  305. dealloc_t dealloc, boolean_t inname, identifier_t name)
  306. {
  307. fprintf(file, "\tstatic mach_msg_type_t %s = {\n", name);
  308. fprintf(file, "\t\t/* msgt_name = */\t\t%s,\n",
  309. inname ? it->itInNameStr : it->itOutNameStr);
  310. fprintf(file, "\t\t/* msgt_size = */\t\t%d,\n", it->itSize);
  311. fprintf(file, "\t\t/* msgt_number = */\t\t%d,\n", it->itNumber);
  312. fprintf(file, "\t\t/* msgt_inline = */\t\t%s,\n",
  313. strbool(it->itInLine));
  314. fprintf(file, "\t\t/* msgt_longform = */\t\tFALSE,\n");
  315. fprintf(file, "\t\t/* msgt_deallocate = */\t\t%s,\n",
  316. strdealloc(dealloc));
  317. fprintf(file, "\t\t/* msgt_unused = */\t\t0\n");
  318. fprintf(file, "\t};\n");
  319. }
  320. void
  321. WriteStaticDecl(FILE *file, const ipc_type_t *it, dealloc_t dealloc,
  322. boolean_t longform, boolean_t inname, identifier_t name)
  323. {
  324. if (longform)
  325. WriteStaticLongDecl(file, it, dealloc, inname, name);
  326. else
  327. WriteStaticShortDecl(file, it, dealloc, inname, name);
  328. }
  329. /*
  330. * Like vfprintf, but omits a leading comment in the format string
  331. * and skips the items that would be printed by it. Only %s, %d,
  332. * and %f are recognized.
  333. */
  334. static void
  335. SkipVFPrintf(FILE *file, register const char *fmt, va_list pvar)
  336. {
  337. if (*fmt == 0)
  338. return; /* degenerate case */
  339. if (fmt[0] == '/' && fmt[1] == '*') {
  340. /* Format string begins with C comment. Scan format
  341. string until end-comment delimiter, skipping the
  342. items in pvar that the enclosed format items would
  343. print. */
  344. register int c;
  345. fmt += 2;
  346. for (;;) {
  347. c = *fmt++;
  348. if (c == 0)
  349. return; /* nothing to format */
  350. if (c == '*') {
  351. if (*fmt == '/') {
  352. break;
  353. }
  354. }
  355. else if (c == '%') {
  356. /* Field to skip */
  357. c = *fmt++;
  358. switch (c) {
  359. case 's':
  360. (void) va_arg(pvar, char *);
  361. break;
  362. case 'd':
  363. (void) va_arg(pvar, int);
  364. break;
  365. case 'f':
  366. (void) va_arg(pvar, double);
  367. break;
  368. case '\0':
  369. return; /* error - fmt ends with '%' */
  370. default:
  371. break;
  372. }
  373. }
  374. }
  375. /* End of comment. To be pretty, skip
  376. the space that follows. */
  377. fmt++;
  378. if (*fmt == ' ')
  379. fmt++;
  380. }
  381. /* Now format the string. */
  382. (void) vfprintf(file, fmt, pvar);
  383. }
  384. void
  385. WriteCopyType(FILE *file, const ipc_type_t *it, const char *left,
  386. const char *right, ...)
  387. {
  388. va_list pvar;
  389. va_start(pvar, right);
  390. if (it->itStruct)
  391. {
  392. fprintf(file, "\t");
  393. SkipVFPrintf(file, left, pvar);
  394. fprintf(file, " = ");
  395. SkipVFPrintf(file, right, pvar);
  396. fprintf(file, ";\n");
  397. }
  398. else if (it->itString)
  399. {
  400. fprintf(file, "\t(void) mig_strncpy(");
  401. SkipVFPrintf(file, left, pvar);
  402. fprintf(file, ", ");
  403. SkipVFPrintf(file, right, pvar);
  404. fprintf(file, ", %d);\n", it->itTypeSize);
  405. }
  406. else
  407. {
  408. fprintf(file, "\t{ typedef struct { char data[%d]; } *sp; * (sp) ",
  409. it->itTypeSize);
  410. SkipVFPrintf(file, left, pvar);
  411. fprintf(file, " = * (sp) ");
  412. SkipVFPrintf(file, right, pvar);
  413. fprintf(file, "; }\n");
  414. }
  415. va_end(pvar);
  416. }
  417. void
  418. WritePackMsgType(FILE *file, const ipc_type_t *it, dealloc_t dealloc,
  419. boolean_t longform, boolean_t inname, const char *left,
  420. const char *right, ...)
  421. {
  422. va_list pvar;
  423. va_start(pvar, right);
  424. fprintf(file, "\t");
  425. SkipVFPrintf(file, left, pvar);
  426. fprintf(file, " = ");
  427. SkipVFPrintf(file, right, pvar);
  428. fprintf(file, ";\n");
  429. va_end(pvar);
  430. }