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.new / rpc_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-12  |  13.5 KB  |  624 lines

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