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