rpc_parse.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /*
  2. * From: @(#)rpc_parse.c 1.8 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_parse.c, Parser for the RPC protocol compiler
  34. * Copyright (C) 1987 Sun Microsystems, Inc.
  35. */
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include "rpc/types.h"
  39. #include "rpc_scan.h"
  40. #include "rpc_parse.h"
  41. #include "rpc_util.h"
  42. #include "proto.h"
  43. #define ARGNAME "arg"
  44. static void isdefined (definition * defp);
  45. static void def_struct (definition * defp);
  46. static void def_program (definition * defp);
  47. static void def_enum (definition * defp);
  48. static void def_const (definition * defp);
  49. static void def_union (definition * defp);
  50. static void check_type_name (const char *name, int new_type);
  51. static void def_typedef (definition * defp);
  52. static void get_declaration (declaration * dec, defkind dkind);
  53. static void get_prog_declaration (declaration * dec, defkind dkind, int num);
  54. static void get_type (const char **prefixp, const char **typep, defkind dkind);
  55. static void unsigned_dec (const char **typep);
  56. /*
  57. * return the next definition you see
  58. */
  59. definition *
  60. get_definition (void)
  61. {
  62. definition *defp;
  63. token tok;
  64. defp = ALLOC (definition);
  65. get_token (&tok);
  66. switch (tok.kind)
  67. {
  68. case TOK_STRUCT:
  69. def_struct (defp);
  70. break;
  71. case TOK_UNION:
  72. def_union (defp);
  73. break;
  74. case TOK_TYPEDEF:
  75. def_typedef (defp);
  76. break;
  77. case TOK_ENUM:
  78. def_enum (defp);
  79. break;
  80. case TOK_PROGRAM:
  81. def_program (defp);
  82. break;
  83. case TOK_CONST:
  84. def_const (defp);
  85. break;
  86. case TOK_EOF:
  87. free (defp);
  88. return (NULL);
  89. default:
  90. error ("definition keyword expected");
  91. }
  92. scan (TOK_SEMICOLON, &tok);
  93. isdefined (defp);
  94. return (defp);
  95. }
  96. static void
  97. isdefined (definition * defp)
  98. {
  99. STOREVAL (&defined, defp);
  100. }
  101. static void
  102. def_struct (definition * defp)
  103. {
  104. token tok;
  105. declaration dec;
  106. decl_list *decls;
  107. decl_list **tailp;
  108. defp->def_kind = DEF_STRUCT;
  109. scan (TOK_IDENT, &tok);
  110. defp->def_name = tok.str;
  111. scan (TOK_LBRACE, &tok);
  112. tailp = &defp->def.st.decls;
  113. do
  114. {
  115. get_declaration (&dec, DEF_STRUCT);
  116. decls = ALLOC (decl_list);
  117. decls->decl = dec;
  118. *tailp = decls;
  119. tailp = &decls->next;
  120. scan (TOK_SEMICOLON, &tok);
  121. peek (&tok);
  122. }
  123. while (tok.kind != TOK_RBRACE);
  124. get_token (&tok);
  125. *tailp = NULL;
  126. }
  127. static void
  128. def_program (definition * defp)
  129. {
  130. token tok;
  131. declaration dec;
  132. decl_list *decls;
  133. decl_list **tailp;
  134. version_list *vlist;
  135. version_list **vtailp;
  136. proc_list *plist;
  137. proc_list **ptailp;
  138. int num_args;
  139. bool_t isvoid = FALSE; /* whether first argument is void */
  140. defp->def_kind = DEF_PROGRAM;
  141. scan (TOK_IDENT, &tok);
  142. defp->def_name = tok.str;
  143. scan (TOK_LBRACE, &tok);
  144. vtailp = &defp->def.pr.versions;
  145. tailp = &defp->def.st.decls;
  146. scan (TOK_VERSION, &tok);
  147. do
  148. {
  149. scan (TOK_IDENT, &tok);
  150. vlist = ALLOC (version_list);
  151. vlist->vers_name = tok.str;
  152. scan (TOK_LBRACE, &tok);
  153. ptailp = &vlist->procs;
  154. do
  155. {
  156. /* get result type */
  157. plist = ALLOC (proc_list);
  158. get_type (&plist->res_prefix, &plist->res_type,
  159. DEF_PROGRAM);
  160. if (streq (plist->res_type, "opaque"))
  161. {
  162. error ("illegal result type");
  163. }
  164. scan (TOK_IDENT, &tok);
  165. plist->proc_name = tok.str;
  166. scan (TOK_LPAREN, &tok);
  167. /* get args - first one */
  168. num_args = 1;
  169. isvoid = FALSE;
  170. /* type of DEF_PROGRAM in the first
  171. * get_prog_declaration and DEF_STURCT in the next
  172. * allows void as argument if it is the only argument
  173. */
  174. get_prog_declaration (&dec, DEF_PROGRAM, num_args);
  175. if (streq (dec.type, "void"))
  176. isvoid = TRUE;
  177. decls = ALLOC (decl_list);
  178. plist->args.decls = decls;
  179. decls->decl = dec;
  180. tailp = &decls->next;
  181. /* get args */
  182. while (peekscan (TOK_COMMA, &tok))
  183. {
  184. num_args++;
  185. get_prog_declaration (&dec, DEF_STRUCT,
  186. num_args);
  187. decls = ALLOC (decl_list);
  188. decls->decl = dec;
  189. *tailp = decls;
  190. if (streq (dec.type, "void"))
  191. isvoid = TRUE;
  192. tailp = &decls->next;
  193. }
  194. /* multiple arguments are only allowed in newstyle */
  195. if (!newstyle && num_args > 1)
  196. {
  197. error ("only one argument is allowed");
  198. }
  199. if (isvoid && num_args > 1)
  200. {
  201. error ("illegal use of void in program definition");
  202. }
  203. *tailp = NULL;
  204. scan (TOK_RPAREN, &tok);
  205. scan (TOK_EQUAL, &tok);
  206. scan_num (&tok);
  207. scan (TOK_SEMICOLON, &tok);
  208. plist->proc_num = tok.str;
  209. plist->arg_num = num_args;
  210. *ptailp = plist;
  211. ptailp = &plist->next;
  212. peek (&tok);
  213. }
  214. while (tok.kind != TOK_RBRACE);
  215. *ptailp = NULL;
  216. *vtailp = vlist;
  217. vtailp = &vlist->next;
  218. scan (TOK_RBRACE, &tok);
  219. scan (TOK_EQUAL, &tok);
  220. scan_num (&tok);
  221. vlist->vers_num = tok.str;
  222. /* make the argument structure name for each arg */
  223. for (plist = vlist->procs; plist != NULL;
  224. plist = plist->next)
  225. {
  226. plist->args.argname = make_argname (plist->proc_name,
  227. vlist->vers_num);
  228. /* free the memory ?? */
  229. }
  230. scan (TOK_SEMICOLON, &tok);
  231. scan2 (TOK_VERSION, TOK_RBRACE, &tok);
  232. }
  233. while (tok.kind == TOK_VERSION);
  234. scan (TOK_EQUAL, &tok);
  235. scan_num (&tok);
  236. defp->def.pr.prog_num = tok.str;
  237. *vtailp = NULL;
  238. }
  239. static void
  240. def_enum (definition * defp)
  241. {
  242. token tok;
  243. enumval_list *elist;
  244. enumval_list **tailp;
  245. defp->def_kind = DEF_ENUM;
  246. scan (TOK_IDENT, &tok);
  247. defp->def_name = tok.str;
  248. scan (TOK_LBRACE, &tok);
  249. tailp = &defp->def.en.vals;
  250. do
  251. {
  252. scan (TOK_IDENT, &tok);
  253. elist = ALLOC (enumval_list);
  254. elist->name = tok.str;
  255. elist->assignment = NULL;
  256. scan3 (TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
  257. if (tok.kind == TOK_EQUAL)
  258. {
  259. scan_num (&tok);
  260. elist->assignment = tok.str;
  261. scan2 (TOK_COMMA, TOK_RBRACE, &tok);
  262. }
  263. *tailp = elist;
  264. tailp = &elist->next;
  265. }
  266. while (tok.kind != TOK_RBRACE);
  267. *tailp = NULL;
  268. }
  269. static void
  270. def_const (definition * defp)
  271. {
  272. token tok;
  273. defp->def_kind = DEF_CONST;
  274. scan (TOK_IDENT, &tok);
  275. defp->def_name = tok.str;
  276. scan (TOK_EQUAL, &tok);
  277. scan2 (TOK_IDENT, TOK_STRCONST, &tok);
  278. defp->def.co = tok.str;
  279. }
  280. static void
  281. def_union (definition *defp)
  282. {
  283. token tok;
  284. declaration dec;
  285. case_list *cases;
  286. /* case_list *tcase; */
  287. case_list **tailp;
  288. #if 0
  289. int flag;
  290. #endif
  291. defp->def_kind = DEF_UNION;
  292. scan (TOK_IDENT, &tok);
  293. defp->def_name = tok.str;
  294. scan (TOK_SWITCH, &tok);
  295. scan (TOK_LPAREN, &tok);
  296. get_declaration (&dec, DEF_UNION);
  297. defp->def.un.enum_decl = dec;
  298. tailp = &defp->def.un.cases;
  299. scan (TOK_RPAREN, &tok);
  300. scan (TOK_LBRACE, &tok);
  301. scan (TOK_CASE, &tok);
  302. while (tok.kind == TOK_CASE)
  303. {
  304. scan2 (TOK_IDENT, TOK_CHARCONST, &tok);
  305. cases = ALLOC (case_list);
  306. cases->case_name = tok.str;
  307. scan (TOK_COLON, &tok);
  308. /* now peek at next token */
  309. #if 0
  310. flag = 0;
  311. #endif
  312. if (peekscan (TOK_CASE, &tok))
  313. {
  314. do
  315. {
  316. scan2 (TOK_IDENT, TOK_CHARCONST, &tok);
  317. cases->contflag = 1; /* continued case statement */
  318. *tailp = cases;
  319. tailp = &cases->next;
  320. cases = ALLOC (case_list);
  321. cases->case_name = tok.str;
  322. scan (TOK_COLON, &tok);
  323. }
  324. while (peekscan (TOK_CASE, &tok));
  325. }
  326. #if 0
  327. else if (flag)
  328. {
  329. *tailp = cases;
  330. tailp = &cases->next;
  331. cases = ALLOC (case_list);
  332. };
  333. #endif
  334. get_declaration (&dec, DEF_UNION);
  335. cases->case_decl = dec;
  336. cases->contflag = 0; /* no continued case statement */
  337. *tailp = cases;
  338. tailp = &cases->next;
  339. scan (TOK_SEMICOLON, &tok);
  340. scan3 (TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
  341. }
  342. *tailp = NULL;
  343. if (tok.kind == TOK_DEFAULT)
  344. {
  345. scan (TOK_COLON, &tok);
  346. get_declaration (&dec, DEF_UNION);
  347. defp->def.un.default_decl = ALLOC (declaration);
  348. *defp->def.un.default_decl = dec;
  349. scan (TOK_SEMICOLON, &tok);
  350. scan (TOK_RBRACE, &tok);
  351. }
  352. else
  353. {
  354. defp->def.un.default_decl = NULL;
  355. }
  356. }
  357. static const char *reserved_words[] =
  358. {
  359. "array",
  360. "bytes",
  361. "destroy",
  362. "free",
  363. "getpos",
  364. "inline",
  365. "pointer",
  366. "reference",
  367. "setpos",
  368. "sizeof",
  369. "union",
  370. "vector",
  371. NULL
  372. };
  373. static const char *reserved_types[] =
  374. {
  375. "opaque",
  376. "string",
  377. NULL
  378. };
  379. /*
  380. * check that the given name is not one that would eventually result in
  381. * xdr routines that would conflict with internal XDR routines.
  382. */
  383. static void
  384. check_type_name (const char *name, int new_type)
  385. {
  386. int i;
  387. char tmp[100];
  388. for (i = 0; reserved_words[i] != NULL; i++)
  389. {
  390. if (strcmp (name, reserved_words[i]) == 0)
  391. {
  392. sprintf (tmp,
  393. "illegal (reserved) name :\'%s\' in type definition", name);
  394. error (tmp);
  395. }
  396. }
  397. if (new_type)
  398. {
  399. for (i = 0; reserved_types[i] != NULL; i++)
  400. {
  401. if (strcmp (name, reserved_types[i]) == 0)
  402. {
  403. sprintf (tmp,
  404. "illegal (reserved) name :\'%s\' in type definition", name);
  405. error (tmp);
  406. }
  407. }
  408. }
  409. }
  410. static void
  411. def_typedef (definition * defp)
  412. {
  413. declaration dec;
  414. defp->def_kind = DEF_TYPEDEF;
  415. get_declaration (&dec, DEF_TYPEDEF);
  416. defp->def_name = dec.name;
  417. check_type_name (dec.name, 1);
  418. defp->def.ty.old_prefix = dec.prefix;
  419. defp->def.ty.old_type = dec.type;
  420. defp->def.ty.rel = dec.rel;
  421. defp->def.ty.array_max = dec.array_max;
  422. }
  423. static void
  424. get_declaration (declaration * dec, defkind dkind)
  425. {
  426. token tok;
  427. get_type (&dec->prefix, &dec->type, dkind);
  428. dec->rel = REL_ALIAS;
  429. if (streq (dec->type, "void"))
  430. {
  431. return;
  432. }
  433. check_type_name (dec->type, 0);
  434. scan2 (TOK_STAR, TOK_IDENT, &tok);
  435. if (tok.kind == TOK_STAR)
  436. {
  437. dec->rel = REL_POINTER;
  438. scan (TOK_IDENT, &tok);
  439. }
  440. dec->name = tok.str;
  441. if (peekscan (TOK_LBRACKET, &tok))
  442. {
  443. if (dec->rel == REL_POINTER)
  444. {
  445. error ("no array-of-pointer declarations -- use typedef");
  446. }
  447. dec->rel = REL_VECTOR;
  448. scan_num (&tok);
  449. dec->array_max = tok.str;
  450. scan (TOK_RBRACKET, &tok);
  451. }
  452. else if (peekscan (TOK_LANGLE, &tok))
  453. {
  454. if (dec->rel == REL_POINTER)
  455. {
  456. error ("no array-of-pointer declarations -- use typedef");
  457. }
  458. dec->rel = REL_ARRAY;
  459. if (peekscan (TOK_RANGLE, &tok))
  460. {
  461. dec->array_max = "~0"; /* unspecified size, use max */
  462. }
  463. else
  464. {
  465. scan_num (&tok);
  466. dec->array_max = tok.str;
  467. scan (TOK_RANGLE, &tok);
  468. }
  469. }
  470. if (streq (dec->type, "opaque"))
  471. {
  472. if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR)
  473. {
  474. error ("array declaration expected");
  475. }
  476. }
  477. else if (streq (dec->type, "string"))
  478. {
  479. if (dec->rel != REL_ARRAY)
  480. {
  481. error ("variable-length array declaration expected");
  482. }
  483. }
  484. }
  485. static void
  486. get_prog_declaration (declaration * dec, defkind dkind, int num /* arg number */ )
  487. {
  488. token tok;
  489. char name[MAXLINESIZE]; /* argument name */
  490. if (dkind == DEF_PROGRAM)
  491. {
  492. peek (&tok);
  493. if (tok.kind == TOK_RPAREN)
  494. { /* no arguments */
  495. dec->rel = REL_ALIAS;
  496. dec->type = "void";
  497. dec->prefix = NULL;
  498. dec->name = NULL;
  499. return;
  500. }
  501. }
  502. get_type (&dec->prefix, &dec->type, dkind);
  503. dec->rel = REL_ALIAS;
  504. if (peekscan (TOK_IDENT, &tok)) /* optional name of argument */
  505. strcpy (name, tok.str);
  506. else
  507. sprintf (name, "%s%d", ARGNAME, num); /* default name of argument */
  508. dec->name = (char *) strdup (name);
  509. if (streq (dec->type, "void"))
  510. {
  511. return;
  512. }
  513. if (streq (dec->type, "opaque"))
  514. {
  515. error ("opaque -- illegal argument type");
  516. }
  517. if (peekscan (TOK_STAR, &tok))
  518. {
  519. if (streq (dec->type, "string"))
  520. {
  521. error ("pointer to string not allowed in program arguments\n");
  522. }
  523. dec->rel = REL_POINTER;
  524. if (peekscan (TOK_IDENT, &tok)) /* optional name of argument */
  525. dec->name = strdup (tok.str);
  526. }
  527. if (peekscan (TOK_LANGLE, &tok))
  528. {
  529. if (!streq (dec->type, "string"))
  530. {
  531. error ("arrays cannot be declared as arguments to procedures -- use typedef");
  532. }
  533. dec->rel = REL_ARRAY;
  534. if (peekscan (TOK_RANGLE, &tok))
  535. {
  536. dec->array_max = "~0"; /* unspecified size, use max */
  537. }
  538. else
  539. {
  540. scan_num (&tok);
  541. dec->array_max = tok.str;
  542. scan (TOK_RANGLE, &tok);
  543. }
  544. }
  545. if (streq (dec->type, "string"))
  546. {
  547. if (dec->rel != REL_ARRAY)
  548. { /* .x specifies just string as
  549. * type of argument
  550. * - make it string<>
  551. */
  552. dec->rel = REL_ARRAY;
  553. dec->array_max = "~0"; /* unspecified size, use max */
  554. }
  555. }
  556. }
  557. static void
  558. get_type (const char **prefixp, const char **typep, defkind dkind)
  559. {
  560. token tok;
  561. *prefixp = NULL;
  562. get_token (&tok);
  563. switch (tok.kind)
  564. {
  565. case TOK_IDENT:
  566. *typep = tok.str;
  567. break;
  568. case TOK_STRUCT:
  569. case TOK_ENUM:
  570. case TOK_UNION:
  571. *prefixp = tok.str;
  572. scan (TOK_IDENT, &tok);
  573. *typep = tok.str;
  574. break;
  575. case TOK_UNSIGNED:
  576. unsigned_dec (typep);
  577. break;
  578. case TOK_SHORT:
  579. *typep = "short";
  580. (void) peekscan (TOK_INT, &tok);
  581. break;
  582. case TOK_LONG:
  583. *typep = "long";
  584. (void) peekscan (TOK_INT, &tok);
  585. break;
  586. case TOK_HYPER:
  587. *typep = "quad_t";
  588. (void) peekscan(TOK_INT, &tok);
  589. break;
  590. case TOK_VOID:
  591. if (dkind != DEF_UNION && dkind != DEF_PROGRAM)
  592. {
  593. error ("voids allowed only inside union and program definitions with one argument");
  594. }
  595. *typep = tok.str;
  596. break;
  597. case TOK_STRING:
  598. case TOK_OPAQUE:
  599. case TOK_CHAR:
  600. case TOK_INT:
  601. case TOK_FLOAT:
  602. case TOK_DOUBLE:
  603. case TOK_BOOL:
  604. *typep = tok.str;
  605. break;
  606. default:
  607. error ("expected type specifier");
  608. }
  609. }
  610. static void
  611. unsigned_dec (const char **typep)
  612. {
  613. token tok;
  614. peek (&tok);
  615. switch (tok.kind)
  616. {
  617. case TOK_CHAR:
  618. get_token (&tok);
  619. *typep = "u_char";
  620. break;
  621. case TOK_SHORT:
  622. get_token (&tok);
  623. *typep = "u_short";
  624. (void) peekscan (TOK_INT, &tok);
  625. break;
  626. case TOK_LONG:
  627. get_token (&tok);
  628. *typep = "u_long";
  629. (void) peekscan (TOK_INT, &tok);
  630. break;
  631. case TOK_HYPER:
  632. get_token (&tok);
  633. *typep = "u_quad_t";
  634. (void) peekscan(TOK_INT, &tok);
  635. break;
  636. case TOK_INT:
  637. get_token (&tok);
  638. *typep = "u_int";
  639. break;
  640. default:
  641. *typep = "u_int";
  642. break;
  643. }
  644. }