rpc_hout.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /*
  2. * From: @(#)rpc_hout.c 1.12 89/02/22
  3. *
  4. * Copyright (c) 2010, Oracle America, Inc.
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are
  7. * met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above
  12. * copyright notice, this list of conditions and the following
  13. * disclaimer in the documentation and/or other materials
  14. * provided with the distribution.
  15. * * Neither the name of the "Oracle America, Inc." nor the names of its
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  24. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  26. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. /*
  33. * rpc_hout.c, Header file outputter for the RPC protocol compiler
  34. */
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include "rpc_parse.h"
  38. #include "rpc_util.h"
  39. #include "proto.h"
  40. static void pconstdef (definition * def);
  41. static void pargdef (definition * def);
  42. static void pstructdef (definition * def);
  43. static void puniondef (definition * def);
  44. static void pdefine (const char *name, const char *num);
  45. static int define_printed (proc_list * stop, version_list * start);
  46. static void pprogramdef (definition * def);
  47. static void parglist (proc_list * proc, const char *addargtype);
  48. static void penumdef (definition * def);
  49. static void ptypedef (definition * def);
  50. static int undefined2 (const char *type, const char *stop);
  51. /* store away enough information to allow the XDR functions to be spat
  52. out at the end of the file */
  53. static void
  54. storexdrfuncdecl (const char *name, int pointerp)
  55. {
  56. xdrfunc * xdrptr;
  57. xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
  58. xdrptr->name = (char *)name;
  59. xdrptr->pointerp = pointerp;
  60. xdrptr->next = NULL;
  61. if (xdrfunc_tail == NULL)
  62. {
  63. xdrfunc_head = xdrptr;
  64. xdrfunc_tail = xdrptr;
  65. }
  66. else
  67. {
  68. xdrfunc_tail->next = xdrptr;
  69. xdrfunc_tail = xdrptr;
  70. }
  71. }
  72. /*
  73. * Print the C-version of an xdr definition
  74. */
  75. void
  76. print_datadef (definition *def)
  77. {
  78. if (def->def_kind == DEF_PROGRAM) /* handle data only */
  79. return;
  80. if (def->def_kind != DEF_CONST)
  81. {
  82. f_print (fout, "\n");
  83. }
  84. switch (def->def_kind)
  85. {
  86. case DEF_STRUCT:
  87. pstructdef (def);
  88. break;
  89. case DEF_UNION:
  90. puniondef (def);
  91. break;
  92. case DEF_ENUM:
  93. penumdef (def);
  94. break;
  95. case DEF_TYPEDEF:
  96. ptypedef (def);
  97. break;
  98. case DEF_PROGRAM:
  99. pprogramdef (def);
  100. break;
  101. case DEF_CONST:
  102. pconstdef (def);
  103. break;
  104. }
  105. if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST)
  106. {
  107. storexdrfuncdecl(def->def_name,
  108. def->def_kind != DEF_TYPEDEF ||
  109. !isvectordef(def->def.ty.old_type,
  110. def->def.ty.rel));
  111. }
  112. }
  113. void
  114. print_funcdef (definition *def)
  115. {
  116. switch (def->def_kind)
  117. {
  118. case DEF_PROGRAM:
  119. f_print (fout, "\n");
  120. pprogramdef (def);
  121. break;
  122. default:
  123. break;
  124. /* ?... shouldn't happen I guess */
  125. }
  126. }
  127. void
  128. print_xdr_func_def (char *name, int pointerp, int i)
  129. {
  130. if (i == 2)
  131. {
  132. f_print (fout, "extern bool_t xdr_%s ();\n", name);
  133. return;
  134. }
  135. else
  136. f_print(fout, "extern bool_t xdr_%s (XDR *, %s%s);\n", name,
  137. name, pointerp ? "*" : "");
  138. }
  139. static void
  140. pconstdef (definition *def)
  141. {
  142. pdefine (def->def_name, def->def.co);
  143. }
  144. /* print out the definitions for the arguments of functions in the
  145. header file
  146. */
  147. static void
  148. pargdef (definition * def)
  149. {
  150. decl_list *l;
  151. version_list *vers;
  152. const char *name;
  153. proc_list *plist;
  154. for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
  155. {
  156. for (plist = vers->procs; plist != NULL;
  157. plist = plist->next)
  158. {
  159. if (!newstyle || plist->arg_num < 2)
  160. {
  161. continue; /* old style or single args */
  162. }
  163. name = plist->args.argname;
  164. f_print (fout, "struct %s {\n", name);
  165. for (l = plist->args.decls;
  166. l != NULL; l = l->next)
  167. {
  168. pdeclaration (name, &l->decl, 1, ";\n");
  169. }
  170. f_print (fout, "};\n");
  171. f_print (fout, "typedef struct %s %s;\n", name, name);
  172. storexdrfuncdecl (name, 1);
  173. f_print (fout, "\n");
  174. }
  175. }
  176. }
  177. static void
  178. pstructdef (definition *def)
  179. {
  180. decl_list *l;
  181. const char *name = def->def_name;
  182. f_print (fout, "struct %s {\n", name);
  183. for (l = def->def.st.decls; l != NULL; l = l->next)
  184. {
  185. pdeclaration (name, &l->decl, 1, ";\n");
  186. }
  187. f_print (fout, "};\n");
  188. f_print (fout, "typedef struct %s %s;\n", name, name);
  189. }
  190. static void
  191. puniondef (definition *def)
  192. {
  193. case_list *l;
  194. const char *name = def->def_name;
  195. declaration *decl;
  196. f_print (fout, "struct %s {\n", name);
  197. decl = &def->def.un.enum_decl;
  198. if (streq (decl->type, "bool"))
  199. {
  200. f_print (fout, "\tbool_t %s;\n", decl->name);
  201. }
  202. else
  203. {
  204. f_print (fout, "\t%s %s;\n", decl->type, decl->name);
  205. }
  206. f_print (fout, "\tunion {\n");
  207. for (l = def->def.un.cases; l != NULL; l = l->next)
  208. {
  209. if (l->contflag == 0)
  210. pdeclaration (name, &l->case_decl, 2, ";\n");
  211. }
  212. decl = def->def.un.default_decl;
  213. if (decl && !streq (decl->type, "void"))
  214. {
  215. pdeclaration (name, decl, 2, ";\n");
  216. }
  217. f_print (fout, "\t} %s_u;\n", name);
  218. f_print (fout, "};\n");
  219. f_print (fout, "typedef struct %s %s;\n", name, name);
  220. }
  221. static void
  222. pdefine (const char *name, const char *num)
  223. {
  224. f_print (fout, "#define %s %s\n", name, num);
  225. }
  226. static int
  227. define_printed (proc_list *stop, version_list *start)
  228. {
  229. version_list *vers;
  230. proc_list *proc;
  231. for (vers = start; vers != NULL; vers = vers->next)
  232. {
  233. for (proc = vers->procs; proc != NULL; proc = proc->next)
  234. {
  235. if (proc == stop)
  236. {
  237. return 0;
  238. }
  239. else if (streq (proc->proc_name, stop->proc_name))
  240. {
  241. return 1;
  242. }
  243. }
  244. }
  245. abort ();
  246. /* NOTREACHED */
  247. }
  248. static void
  249. pfreeprocdef (const char *name, const char *vers, int mode)
  250. {
  251. f_print (fout, "extern int ");
  252. pvname (name, vers);
  253. if (mode == 1)
  254. f_print (fout,"_freeresult (SVCXPRT *, xdrproc_t, caddr_t);\n");
  255. else
  256. f_print (fout,"_freeresult ();\n");
  257. }
  258. static void
  259. pprogramdef (definition *def)
  260. {
  261. version_list *vers;
  262. proc_list *proc;
  263. int i;
  264. const char *ext;
  265. pargdef (def);
  266. pdefine (def->def_name, def->def.pr.prog_num);
  267. for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
  268. {
  269. if (tblflag)
  270. {
  271. f_print (fout, "extern struct rpcgen_table %s_%s_table[];\n",
  272. locase (def->def_name), vers->vers_num);
  273. f_print (fout, "extern %s_%s_nproc;\n",
  274. locase (def->def_name), vers->vers_num);
  275. }
  276. pdefine (vers->vers_name, vers->vers_num);
  277. /*
  278. * Print out 2 definitions, one for ANSI-C, another for
  279. * old K & R C
  280. */
  281. if(!Cflag)
  282. {
  283. ext = "extern ";
  284. for (proc = vers->procs; proc != NULL;
  285. proc = proc->next)
  286. {
  287. if (!define_printed(proc, def->def.pr.versions))
  288. {
  289. pdefine (proc->proc_name, proc->proc_num);
  290. }
  291. f_print (fout, "%s", ext);
  292. pprocdef (proc, vers, NULL, 0, 2);
  293. if (mtflag)
  294. {
  295. f_print(fout, "%s", ext);
  296. pprocdef (proc, vers, NULL, 1, 2);
  297. }
  298. }
  299. pfreeprocdef (def->def_name, vers->vers_num, 2);
  300. }
  301. else
  302. {
  303. for (i = 1; i < 3; i++)
  304. {
  305. if (i == 1)
  306. {
  307. f_print (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
  308. ext = "extern ";
  309. }
  310. else
  311. {
  312. f_print (fout, "\n#else /* K&R C */\n");
  313. ext = "extern ";
  314. }
  315. for (proc = vers->procs; proc != NULL; proc = proc->next)
  316. {
  317. if (!define_printed(proc, def->def.pr.versions))
  318. {
  319. pdefine(proc->proc_name, proc->proc_num);
  320. }
  321. f_print (fout, "%s", ext);
  322. pprocdef (proc, vers, "CLIENT *", 0, i);
  323. f_print (fout, "%s", ext);
  324. pprocdef (proc, vers, "struct svc_req *", 1, i);
  325. }
  326. pfreeprocdef (def->def_name, vers->vers_num, i);
  327. }
  328. f_print (fout, "#endif /* K&R C */\n");
  329. }
  330. }
  331. }
  332. void
  333. pprocdef (proc_list * proc, version_list * vp,
  334. const char *addargtype, int server_p, int mode)
  335. {
  336. if (mtflag)
  337. {/* Print MT style stubs */
  338. if (server_p)
  339. f_print (fout, "bool_t ");
  340. else
  341. f_print (fout, "enum clnt_stat ");
  342. }
  343. else
  344. {
  345. ptype (proc->res_prefix, proc->res_type, 1);
  346. f_print (fout, "* ");
  347. }
  348. if (server_p)
  349. pvname_svc (proc->proc_name, vp->vers_num);
  350. else
  351. pvname (proc->proc_name, vp->vers_num);
  352. /*
  353. * mode 1 = ANSI-C, mode 2 = K&R C
  354. */
  355. if (mode == 1)
  356. parglist (proc, addargtype);
  357. else
  358. f_print (fout, "();\n");
  359. }
  360. /* print out argument list of procedure */
  361. static void
  362. parglist (proc_list *proc, const char *addargtype)
  363. {
  364. decl_list *dl;
  365. f_print(fout,"(");
  366. if (proc->arg_num < 2 && newstyle &&
  367. streq (proc->args.decls->decl.type, "void"))
  368. {
  369. /* 0 argument in new style: do nothing */
  370. }
  371. else
  372. {
  373. for (dl = proc->args.decls; dl != NULL; dl = dl->next)
  374. {
  375. ptype (dl->decl.prefix, dl->decl.type, 1);
  376. if (!newstyle)
  377. f_print (fout, "*"); /* old style passes by reference */
  378. f_print (fout, ", ");
  379. }
  380. }
  381. if (mtflag)
  382. {
  383. ptype(proc->res_prefix, proc->res_type, 1);
  384. f_print(fout, "*, ");
  385. }
  386. f_print (fout, "%s);\n", addargtype);
  387. }
  388. static void
  389. penumdef (definition *def)
  390. {
  391. const char *name = def->def_name;
  392. enumval_list *l;
  393. const char *last = NULL;
  394. int count = 0;
  395. f_print (fout, "enum %s {\n", name);
  396. for (l = def->def.en.vals; l != NULL; l = l->next)
  397. {
  398. f_print (fout, "\t%s", l->name);
  399. if (l->assignment)
  400. {
  401. f_print (fout, " = %s", l->assignment);
  402. last = l->assignment;
  403. count = 1;
  404. }
  405. else
  406. {
  407. if (last == NULL)
  408. {
  409. f_print (fout, " = %d", count++);
  410. }
  411. else
  412. {
  413. f_print (fout, " = %s + %d", last, count++);
  414. }
  415. }
  416. f_print (fout, ",\n");
  417. }
  418. f_print (fout, "};\n");
  419. f_print (fout, "typedef enum %s %s;\n", name, name);
  420. }
  421. static void
  422. ptypedef (definition *def)
  423. {
  424. const char *name = def->def_name;
  425. const char *old = def->def.ty.old_type;
  426. char prefix[8]; /* enough to contain "struct ", including NUL */
  427. relation rel = def->def.ty.rel;
  428. if (!streq (name, old))
  429. {
  430. if (streq (old, "string"))
  431. {
  432. old = "char";
  433. rel = REL_POINTER;
  434. }
  435. else if (streq (old, "opaque"))
  436. {
  437. old = "char";
  438. }
  439. else if (streq (old, "bool"))
  440. {
  441. old = "bool_t";
  442. }
  443. if (undefined2 (old, name) && def->def.ty.old_prefix)
  444. {
  445. s_print (prefix, "%s ", def->def.ty.old_prefix);
  446. }
  447. else
  448. {
  449. prefix[0] = 0;
  450. }
  451. f_print (fout, "typedef ");
  452. switch (rel)
  453. {
  454. case REL_ARRAY:
  455. f_print (fout, "struct {\n");
  456. f_print (fout, "\tu_int %s_len;\n", name);
  457. f_print (fout, "\t%s%s *%s_val;\n", prefix, old, name);
  458. f_print (fout, "} %s", name);
  459. break;
  460. case REL_POINTER:
  461. f_print (fout, "%s%s *%s", prefix, old, name);
  462. break;
  463. case REL_VECTOR:
  464. f_print (fout, "%s%s %s[%s]", prefix, old, name,
  465. def->def.ty.array_max);
  466. break;
  467. case REL_ALIAS:
  468. f_print (fout, "%s%s %s", prefix, old, name);
  469. break;
  470. }
  471. f_print (fout, ";\n");
  472. }
  473. }
  474. void
  475. pdeclaration (const char *name, declaration * dec, int tab,
  476. const char *separator)
  477. {
  478. char buf[8]; /* enough to hold "struct ", include NUL */
  479. const char *prefix;
  480. const char *type;
  481. if (streq (dec->type, "void"))
  482. {
  483. return;
  484. }
  485. tabify (fout, tab);
  486. if (streq (dec->type, name) && !dec->prefix)
  487. {
  488. f_print (fout, "struct ");
  489. }
  490. if (streq (dec->type, "string"))
  491. {
  492. f_print (fout, "char *%s", dec->name);
  493. }
  494. else
  495. {
  496. prefix = "";
  497. if (streq (dec->type, "bool"))
  498. {
  499. type = "bool_t";
  500. }
  501. else if (streq (dec->type, "opaque"))
  502. {
  503. type = "char";
  504. }
  505. else
  506. {
  507. if (dec->prefix)
  508. {
  509. s_print (buf, "%s ", dec->prefix);
  510. prefix = buf;
  511. }
  512. type = dec->type;
  513. }
  514. switch (dec->rel)
  515. {
  516. case REL_ALIAS:
  517. f_print (fout, "%s%s %s", prefix, type, dec->name);
  518. break;
  519. case REL_VECTOR:
  520. f_print (fout, "%s%s %s[%s]", prefix, type, dec->name,
  521. dec->array_max);
  522. break;
  523. case REL_POINTER:
  524. f_print (fout, "%s%s *%s", prefix, type, dec->name);
  525. break;
  526. case REL_ARRAY:
  527. f_print (fout, "struct {\n");
  528. tabify (fout, tab);
  529. f_print (fout, "\tu_int %s_len;\n", dec->name);
  530. tabify (fout, tab);
  531. f_print (fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
  532. tabify (fout, tab);
  533. f_print (fout, "} %s", dec->name);
  534. break;
  535. }
  536. }
  537. f_print (fout, "%s", separator);
  538. }
  539. static int
  540. undefined2 (const char *type, const char *stop)
  541. {
  542. list *l;
  543. definition *def;
  544. for (l = defined; l != NULL; l = l->next)
  545. {
  546. def = (definition *) l->val;
  547. if (def->def_kind != DEF_PROGRAM)
  548. {
  549. if (streq (def->def_name, stop))
  550. {
  551. return 1;
  552. }
  553. else if (streq (def->def_name, type))
  554. {
  555. return 0;
  556. }
  557. }
  558. }
  559. return 1;
  560. }