home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / rpcgen / rpc_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-17  |  9.0 KB  |  424 lines

  1. /* @(#)rpc_parse.c    2.1 88/08/01 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #ifndef lint
  31. /*static char sccsid[] = "from: @(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";*/
  32. static char rcsid[] = "$Id: rpc_parse.c,v 1.3 1993/08/01 18:09:19 mycroft Exp $";
  33. #endif
  34.  
  35. /*
  36.  * rpc_parse.c, Parser for the RPC protocol compiler 
  37.  * Copyright (C) 1987 Sun Microsystems, Inc.
  38.  */
  39. #include <stdio.h>
  40. #include "rpc_util.h"
  41. #include "rpc_scan.h"
  42. #include "rpc_parse.h"
  43.  
  44. static int isdefined(), def_struct(), def_program(), def_enum(), def_const(),
  45.        def_union(), def_typedef(), get_declaration(), get_type(),
  46.        unsigned_dec();
  47. /*
  48.  * return the next definition you see
  49.  */
  50. definition *
  51. get_definition()
  52. {
  53.     definition *defp;
  54.     token tok;
  55.  
  56.     defp = ALLOC(definition);
  57.     get_token(&tok);
  58.     switch (tok.kind) {
  59.     case TOK_STRUCT:
  60.         def_struct(defp);
  61.         break;
  62.     case TOK_UNION:
  63.         def_union(defp);
  64.         break;
  65.     case TOK_TYPEDEF:
  66.         def_typedef(defp);
  67.         break;
  68.     case TOK_ENUM:
  69.         def_enum(defp);
  70.         break;
  71.     case TOK_PROGRAM:
  72.         def_program(defp);
  73.         break;
  74.     case TOK_CONST:
  75.         def_const(defp);
  76.         break;
  77.     case TOK_EOF:
  78.         return (NULL);
  79.         break;
  80.     default:
  81.         error("definition keyword expected");
  82.     }
  83.     scan(TOK_SEMICOLON, &tok);
  84.     isdefined(defp);
  85.     return (defp);
  86. }
  87.  
  88. static
  89. isdefined(defp)
  90.     definition *defp;
  91. {
  92.     STOREVAL(&defined, defp);
  93. }
  94.  
  95.  
  96. static
  97. def_struct(defp)
  98.     definition *defp;
  99. {
  100.     token tok;
  101.     declaration dec;
  102.     decl_list *decls;
  103.     decl_list **tailp;
  104.  
  105.     defp->def_kind = DEF_STRUCT;
  106.  
  107.     scan(TOK_IDENT, &tok);
  108.     defp->def_name = tok.str;
  109.     scan(TOK_LBRACE, &tok);
  110.     tailp = &defp->def.st.decls;
  111.     do {
  112.         get_declaration(&dec, DEF_STRUCT);
  113.         decls = ALLOC(decl_list);
  114.         decls->decl = dec;
  115.         *tailp = decls;
  116.         tailp = &decls->next;
  117.         scan(TOK_SEMICOLON, &tok);
  118.         peek(&tok);
  119.     } while (tok.kind != TOK_RBRACE);
  120.     get_token(&tok);
  121.     *tailp = NULL;
  122. }
  123.  
  124. static
  125. def_program(defp)
  126.     definition *defp;
  127. {
  128.     token tok;
  129.     version_list *vlist;
  130.     version_list **vtailp;
  131.     proc_list *plist;
  132.     proc_list **ptailp;
  133.  
  134.     defp->def_kind = DEF_PROGRAM;
  135.     scan(TOK_IDENT, &tok);
  136.     defp->def_name = tok.str;
  137.     scan(TOK_LBRACE, &tok);
  138.     vtailp = &defp->def.pr.versions;
  139.     scan(TOK_VERSION, &tok);
  140.     do {
  141.         scan(TOK_IDENT, &tok);
  142.         vlist = ALLOC(version_list);
  143.         vlist->vers_name = tok.str;
  144.         scan(TOK_LBRACE, &tok);
  145.         ptailp = &vlist->procs;
  146.         do {
  147.             plist = ALLOC(proc_list);
  148.             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
  149.             if (streq(plist->res_type, "opaque")) {
  150.                 error("illegal result type");
  151.             }
  152.             scan(TOK_IDENT, &tok);
  153.             plist->proc_name = tok.str;
  154.             scan(TOK_LPAREN, &tok);
  155.             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
  156.             if (streq(plist->arg_type, "opaque")) {
  157.                 error("illegal argument type");
  158.             }
  159.             scan(TOK_RPAREN, &tok);
  160.             scan(TOK_EQUAL, &tok);
  161.             scan_num(&tok);
  162.             scan(TOK_SEMICOLON, &tok);
  163.             plist->proc_num = tok.str;
  164.             *ptailp = plist;
  165.             ptailp = &plist->next;
  166.             peek(&tok);
  167.         } while (tok.kind != TOK_RBRACE);
  168.         *vtailp = vlist;
  169.         vtailp = &vlist->next;
  170.         scan(TOK_RBRACE, &tok);
  171.         scan(TOK_EQUAL, &tok);
  172.         scan_num(&tok);
  173.         vlist->vers_num = tok.str;
  174.         scan(TOK_SEMICOLON, &tok);
  175.         scan2(TOK_VERSION, TOK_RBRACE, &tok);
  176.     } while (tok.kind == TOK_VERSION);
  177.     scan(TOK_EQUAL, &tok);
  178.     scan_num(&tok);
  179.     defp->def.pr.prog_num = tok.str;
  180.     *vtailp = NULL;
  181. }
  182.  
  183. static
  184. def_enum(defp)
  185.     definition *defp;
  186. {
  187.     token tok;
  188.     enumval_list *elist;
  189.     enumval_list **tailp;
  190.  
  191.     defp->def_kind = DEF_ENUM;
  192.     scan(TOK_IDENT, &tok);
  193.     defp->def_name = tok.str;
  194.     scan(TOK_LBRACE, &tok);
  195.     tailp = &defp->def.en.vals;
  196.     do {
  197.         scan(TOK_IDENT, &tok);
  198.         elist = ALLOC(enumval_list);
  199.         elist->name = tok.str;
  200.         elist->assignment = NULL;
  201.         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
  202.         if (tok.kind == TOK_EQUAL) {
  203.             scan_num(&tok);
  204.             elist->assignment = tok.str;
  205.             scan2(TOK_COMMA, TOK_RBRACE, &tok);
  206.         }
  207.         *tailp = elist;
  208.         tailp = &elist->next;
  209.     } while (tok.kind != TOK_RBRACE);
  210.     *tailp = NULL;
  211. }
  212.  
  213. static
  214. def_const(defp)
  215.     definition *defp;
  216. {
  217.     token tok;
  218.  
  219.     defp->def_kind = DEF_CONST;
  220.     scan(TOK_IDENT, &tok);
  221.     defp->def_name = tok.str;
  222.     scan(TOK_EQUAL, &tok);
  223.     scan2(TOK_IDENT, TOK_STRCONST, &tok);
  224.     defp->def.co = tok.str;
  225. }
  226.  
  227. static
  228. def_union(defp)
  229.     definition *defp;
  230. {
  231.     token tok;
  232.     declaration dec;
  233.     case_list *cases;
  234.     case_list **tailp;
  235.  
  236.     defp->def_kind = DEF_UNION;
  237.     scan(TOK_IDENT, &tok);
  238.     defp->def_name = tok.str;
  239.     scan(TOK_SWITCH, &tok);
  240.     scan(TOK_LPAREN, &tok);
  241.     get_declaration(&dec, DEF_UNION);
  242.     defp->def.un.enum_decl = dec;
  243.     tailp = &defp->def.un.cases;
  244.     scan(TOK_RPAREN, &tok);
  245.     scan(TOK_LBRACE, &tok);
  246.     scan(TOK_CASE, &tok);
  247.     while (tok.kind == TOK_CASE) {
  248.         scan(TOK_IDENT, &tok);
  249.         cases = ALLOC(case_list);
  250.         cases->case_name = tok.str;
  251.         scan(TOK_COLON, &tok);
  252.         get_declaration(&dec, DEF_UNION);
  253.         cases->case_decl = dec;
  254.         *tailp = cases;
  255.         tailp = &cases->next;
  256.         scan(TOK_SEMICOLON, &tok);
  257.         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
  258.     }
  259.     *tailp = NULL;
  260.     if (tok.kind == TOK_DEFAULT) {
  261.         scan(TOK_COLON, &tok);
  262.         get_declaration(&dec, DEF_UNION);
  263.         defp->def.un.default_decl = ALLOC(declaration);
  264.         *defp->def.un.default_decl = dec;
  265.         scan(TOK_SEMICOLON, &tok);
  266.         scan(TOK_RBRACE, &tok);
  267.     } else {
  268.         defp->def.un.default_decl = NULL;
  269.     }
  270. }
  271.  
  272.  
  273. static
  274. def_typedef(defp)
  275.     definition *defp;
  276. {
  277.     declaration dec;
  278.  
  279.     defp->def_kind = DEF_TYPEDEF;
  280.     get_declaration(&dec, DEF_TYPEDEF);
  281.     defp->def_name = dec.name;
  282.     defp->def.ty.old_prefix = dec.prefix;
  283.     defp->def.ty.old_type = dec.type;
  284.     defp->def.ty.rel = dec.rel;
  285.     defp->def.ty.array_max = dec.array_max;
  286. }
  287.  
  288.  
  289. static
  290. get_declaration(dec, dkind)
  291.     declaration *dec;
  292.     defkind dkind;
  293. {
  294.     token tok;
  295.  
  296.     get_type(&dec->prefix, &dec->type, dkind);
  297.     dec->rel = REL_ALIAS;
  298.     if (streq(dec->type, "void")) {
  299.         return;
  300.     }
  301.     scan2(TOK_STAR, TOK_IDENT, &tok);
  302.     if (tok.kind == TOK_STAR) {
  303.         dec->rel = REL_POINTER;
  304.         scan(TOK_IDENT, &tok);
  305.     }
  306.     dec->name = tok.str;
  307.     if (peekscan(TOK_LBRACKET, &tok)) {
  308.         if (dec->rel == REL_POINTER) {
  309.             error("no array-of-pointer declarations -- use typedef");
  310.         }
  311.         dec->rel = REL_VECTOR;
  312.         scan_num(&tok);
  313.         dec->array_max = tok.str;
  314.         scan(TOK_RBRACKET, &tok);
  315.     } else if (peekscan(TOK_LANGLE, &tok)) {
  316.         if (dec->rel == REL_POINTER) {
  317.             error("no array-of-pointer declarations -- use typedef");
  318.         }
  319.         dec->rel = REL_ARRAY;
  320.         if (peekscan(TOK_RANGLE, &tok)) {
  321.             dec->array_max = "~0";    /* unspecified size, use max */
  322.         } else {
  323.             scan_num(&tok);
  324.             dec->array_max = tok.str;
  325.             scan(TOK_RANGLE, &tok);
  326.         }
  327.     }
  328.     if (streq(dec->type, "opaque")) {
  329.         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
  330.             error("array declaration expected");
  331.         }
  332.     } else if (streq(dec->type, "string")) {
  333.         if (dec->rel != REL_ARRAY) {
  334.             error("variable-length array declaration expected");
  335.         }
  336.     }
  337. }
  338.  
  339.  
  340. static
  341. get_type(prefixp, typep, dkind)
  342.     char **prefixp;
  343.     char **typep;
  344.     defkind dkind;
  345. {
  346.     token tok;
  347.  
  348.     *prefixp = NULL;
  349.     get_token(&tok);
  350.     switch (tok.kind) {
  351.     case TOK_IDENT:
  352.         *typep = tok.str;
  353.         break;
  354.     case TOK_STRUCT:
  355.     case TOK_ENUM:
  356.     case TOK_UNION:
  357.         *prefixp = tok.str;
  358.         scan(TOK_IDENT, &tok);
  359.         *typep = tok.str;
  360.         break;
  361.     case TOK_UNSIGNED:
  362.         unsigned_dec(typep);
  363.         break;
  364.     case TOK_SHORT:
  365.         *typep = "short";
  366.         (void) peekscan(TOK_INT, &tok);
  367.         break;
  368.     case TOK_LONG:
  369.         *typep = "long";
  370.         (void) peekscan(TOK_INT, &tok);
  371.         break;
  372.     case TOK_VOID:
  373.         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
  374.             error("voids allowed only inside union and program definitions");
  375.         }
  376.         *typep = tok.str;
  377.         break;
  378.     case TOK_STRING:
  379.     case TOK_OPAQUE:
  380.     case TOK_CHAR:
  381.     case TOK_INT:
  382.     case TOK_FLOAT:
  383.     case TOK_DOUBLE:
  384.     case TOK_BOOL:
  385.         *typep = tok.str;
  386.         break;
  387.     default:
  388.         error("expected type specifier");
  389.     }
  390. }
  391.  
  392.  
  393. static
  394. unsigned_dec(typep)
  395.     char **typep;
  396. {
  397.     token tok;
  398.  
  399.     peek(&tok);
  400.     switch (tok.kind) {
  401.     case TOK_CHAR:
  402.         get_token(&tok);
  403.         *typep = "u_char";
  404.         break;
  405.     case TOK_SHORT:
  406.         get_token(&tok);
  407.         *typep = "u_short";
  408.         (void) peekscan(TOK_INT, &tok);
  409.         break;
  410.     case TOK_LONG:
  411.         get_token(&tok);
  412.         *typep = "u_long";
  413.         (void) peekscan(TOK_INT, &tok);
  414.         break;
  415.     case TOK_INT:
  416.         get_token(&tok);
  417.         *typep = "u_int";
  418.         break;
  419.     default:
  420.         *typep = "u_int";
  421.         break;
  422.     }
  423. }
  424.