Back to index

glibc  2.9
rpc_hout.c
Go to the documentation of this file.
00001 /*
00002  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00003  * unrestricted use provided that this legend is included on all tape
00004  * media and as a part of the software program in whole or part.  Users
00005  * may copy or modify Sun RPC without charge, but are not authorized
00006  * to license or distribute it to anyone else except as part of a product or
00007  * program developed by the user or with the express written consent of
00008  * Sun Microsystems, Inc.
00009  *
00010  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00011  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00012  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00013  *
00014  * Sun RPC is provided with no support and without any obligation on the
00015  * part of Sun Microsystems, Inc. to assist in its use, correction,
00016  * modification or enhancement.
00017  *
00018  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00019  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00020  * OR ANY PART THEREOF.
00021  *
00022  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00023  * or profits or other special, indirect and consequential damages, even if
00024  * Sun has been advised of the possibility of such damages.
00025  *
00026  * Sun Microsystems, Inc.
00027  * 2550 Garcia Avenue
00028  * Mountain View, California  94043
00029  */
00030 
00031 /*
00032  * From: @(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI
00033  */
00034 
00035 /*
00036  * rpc_hout.c, Header file outputter for the RPC protocol compiler
00037  */
00038 #include <stdio.h>
00039 #include <ctype.h>
00040 #include "rpc_parse.h"
00041 #include "rpc_util.h"
00042 #include "proto.h"
00043 
00044 static void pconstdef (definition * def);
00045 static void pargdef (definition * def);
00046 static void pstructdef (definition * def);
00047 static void puniondef (definition * def);
00048 static void pdefine (const char *name, const char *num);
00049 static int define_printed (proc_list * stop, version_list * start);
00050 static void pprogramdef (definition * def);
00051 static void parglist (proc_list * proc, const char *addargtype);
00052 static void penumdef (definition * def);
00053 static void ptypedef (definition * def);
00054 static int undefined2 (const char *type, const char *stop);
00055 
00056 /* store away enough information to allow the XDR functions to be spat
00057     out at the end of the file */
00058 
00059 static void
00060 storexdrfuncdecl (const char *name, int pointerp)
00061 {
00062   xdrfunc * xdrptr;
00063 
00064   xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
00065 
00066   xdrptr->name = (char *)name;
00067   xdrptr->pointerp = pointerp;
00068   xdrptr->next = NULL;
00069 
00070   if (xdrfunc_tail == NULL)
00071     {
00072       xdrfunc_head = xdrptr;
00073       xdrfunc_tail = xdrptr;
00074     }
00075   else
00076     {
00077       xdrfunc_tail->next = xdrptr;
00078       xdrfunc_tail = xdrptr;
00079     }
00080 }
00081 
00082 /*
00083  * Print the C-version of an xdr definition
00084  */
00085 void
00086 print_datadef (definition *def)
00087 {
00088 
00089   if (def->def_kind == DEF_PROGRAM)       /* handle data only */
00090     return;
00091 
00092   if (def->def_kind != DEF_CONST)
00093     {
00094       f_print (fout, "\n");
00095     }
00096   switch (def->def_kind)
00097     {
00098     case DEF_STRUCT:
00099       pstructdef (def);
00100       break;
00101     case DEF_UNION:
00102       puniondef (def);
00103       break;
00104     case DEF_ENUM:
00105       penumdef (def);
00106       break;
00107     case DEF_TYPEDEF:
00108       ptypedef (def);
00109       break;
00110     case DEF_PROGRAM:
00111       pprogramdef (def);
00112       break;
00113     case DEF_CONST:
00114       pconstdef (def);
00115       break;
00116     }
00117   if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST)
00118     {
00119       storexdrfuncdecl(def->def_name,
00120                      def->def_kind != DEF_TYPEDEF ||
00121                      !isvectordef(def->def.ty.old_type,
00122                                 def->def.ty.rel));
00123     }
00124 }
00125 
00126 
00127 void
00128 print_funcdef (definition *def)
00129 {
00130   switch (def->def_kind)
00131     {
00132     case DEF_PROGRAM:
00133       f_print (fout, "\n");
00134       pprogramdef (def);
00135       break;
00136     default:
00137       break;
00138       /* ?... shouldn't happen I guess */
00139     }
00140 }
00141 
00142 void
00143 print_xdr_func_def (char *name, int pointerp, int i)
00144 {
00145   if (i == 2)
00146     {
00147       f_print (fout, "extern bool_t xdr_%s ();\n", name);
00148       return;
00149     }
00150   else
00151     f_print(fout, "extern  bool_t xdr_%s (XDR *, %s%s);\n", name,
00152            name, pointerp ? "*" : "");
00153 }
00154 
00155 static void
00156 pconstdef (definition *def)
00157 {
00158   pdefine (def->def_name, def->def.co);
00159 }
00160 
00161 /* print out the definitions for the arguments of functions in the
00162    header file
00163  */
00164 static void
00165 pargdef (definition * def)
00166 {
00167   decl_list *l;
00168   version_list *vers;
00169   const char *name;
00170   proc_list *plist;
00171 
00172   for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
00173     {
00174       for (plist = vers->procs; plist != NULL;
00175           plist = plist->next)
00176        {
00177 
00178          if (!newstyle || plist->arg_num < 2)
00179            {
00180              continue;             /* old style or single args */
00181            }
00182          name = plist->args.argname;
00183          f_print (fout, "struct %s {\n", name);
00184          for (l = plist->args.decls;
00185               l != NULL; l = l->next)
00186            {
00187              pdeclaration (name, &l->decl, 1, ";\n");
00188            }
00189          f_print (fout, "};\n");
00190          f_print (fout, "typedef struct %s %s;\n", name, name);
00191          storexdrfuncdecl (name, 1);
00192          f_print (fout, "\n");
00193        }
00194     }
00195 
00196 }
00197 
00198 static void
00199 pstructdef (definition *def)
00200 {
00201   decl_list *l;
00202   const char *name = def->def_name;
00203 
00204   f_print (fout, "struct %s {\n", name);
00205   for (l = def->def.st.decls; l != NULL; l = l->next)
00206     {
00207       pdeclaration (name, &l->decl, 1, ";\n");
00208     }
00209   f_print (fout, "};\n");
00210   f_print (fout, "typedef struct %s %s;\n", name, name);
00211 }
00212 
00213 static void
00214 puniondef (definition *def)
00215 {
00216   case_list *l;
00217   const char *name = def->def_name;
00218   declaration *decl;
00219 
00220   f_print (fout, "struct %s {\n", name);
00221   decl = &def->def.un.enum_decl;
00222   if (streq (decl->type, "bool"))
00223     {
00224       f_print (fout, "\tbool_t %s;\n", decl->name);
00225     }
00226   else
00227     {
00228       f_print (fout, "\t%s %s;\n", decl->type, decl->name);
00229     }
00230   f_print (fout, "\tunion {\n");
00231   for (l = def->def.un.cases; l != NULL; l = l->next)
00232     {
00233       if (l->contflag == 0)
00234        pdeclaration (name, &l->case_decl, 2, ";\n");
00235     }
00236   decl = def->def.un.default_decl;
00237   if (decl && !streq (decl->type, "void"))
00238     {
00239       pdeclaration (name, decl, 2, ";\n");
00240     }
00241   f_print (fout, "\t} %s_u;\n", name);
00242   f_print (fout, "};\n");
00243   f_print (fout, "typedef struct %s %s;\n", name, name);
00244 }
00245 
00246 static void
00247 pdefine (const char *name, const char *num)
00248 {
00249   f_print (fout, "#define %s %s\n", name, num);
00250 }
00251 
00252 static int
00253 define_printed (proc_list *stop, version_list *start)
00254 {
00255   version_list *vers;
00256   proc_list *proc;
00257 
00258   for (vers = start; vers != NULL; vers = vers->next)
00259     {
00260       for (proc = vers->procs; proc != NULL; proc = proc->next)
00261        {
00262          if (proc == stop)
00263            {
00264              return 0;
00265            }
00266          else if (streq (proc->proc_name, stop->proc_name))
00267            {
00268              return 1;
00269            }
00270        }
00271     }
00272   abort ();
00273   /* NOTREACHED */
00274 }
00275 
00276 static void
00277 pfreeprocdef (const char *name, const char *vers, int mode)
00278 {
00279   f_print (fout, "extern int ");
00280   pvname (name, vers);
00281   if (mode == 1)
00282     f_print (fout,"_freeresult (SVCXPRT *, xdrproc_t, caddr_t);\n");
00283   else
00284     f_print (fout,"_freeresult ();\n");
00285 }
00286 
00287 static void
00288 pprogramdef (definition *def)
00289 {
00290   version_list *vers;
00291   proc_list *proc;
00292   int i;
00293   const char *ext;
00294 
00295   pargdef (def);
00296 
00297   pdefine (def->def_name, def->def.pr.prog_num);
00298   for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
00299     {
00300       if (tblflag)
00301        {
00302          f_print (fout, "extern struct rpcgen_table %s_%s_table[];\n",
00303                  locase (def->def_name), vers->vers_num);
00304          f_print (fout, "extern %s_%s_nproc;\n",
00305                  locase (def->def_name), vers->vers_num);
00306        }
00307       pdefine (vers->vers_name, vers->vers_num);
00308 
00309       /*
00310        * Print out 2 definitions, one for ANSI-C, another for
00311        * old K & R C
00312        */
00313 
00314       if(!Cflag)
00315        {
00316          ext = "extern  ";
00317          for (proc = vers->procs; proc != NULL;
00318               proc = proc->next)
00319            {
00320              if (!define_printed(proc, def->def.pr.versions))
00321               {
00322                 pdefine (proc->proc_name, proc->proc_num);
00323               }
00324              f_print (fout, "%s", ext);
00325              pprocdef (proc, vers, NULL, 0, 2);
00326 
00327              if (mtflag)
00328               {
00329                 f_print(fout, "%s", ext);
00330                 pprocdef (proc, vers, NULL, 1, 2);
00331               }
00332            }
00333          pfreeprocdef (def->def_name, vers->vers_num, 2);
00334        }
00335       else
00336        {
00337          for (i = 1; i < 3; i++)
00338            {
00339              if (i == 1)
00340               {
00341                 f_print (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
00342                 ext = "extern  ";
00343               }
00344              else
00345               {
00346                 f_print (fout, "\n#else /* K&R C */\n");
00347                 ext = "extern  ";
00348               }
00349 
00350              for (proc = vers->procs; proc != NULL; proc = proc->next)
00351               {
00352                 if (!define_printed(proc, def->def.pr.versions))
00353                   {
00354                     pdefine(proc->proc_name, proc->proc_num);
00355                   }
00356                 f_print (fout, "%s", ext);
00357                 pprocdef (proc, vers, "CLIENT *", 0, i);
00358                 f_print (fout, "%s", ext);
00359                 pprocdef (proc, vers, "struct svc_req *", 1, i);
00360               }
00361              pfreeprocdef (def->def_name, vers->vers_num, i);
00362            }
00363          f_print (fout, "#endif /* K&R C */\n");
00364        }
00365     }
00366 }
00367 
00368 void
00369 pprocdef (proc_list * proc, version_list * vp,
00370          const char *addargtype, int server_p, int mode)
00371 {
00372   if (mtflag)
00373     {/* Print MT style stubs */
00374       if (server_p)
00375        f_print (fout, "bool_t ");
00376       else
00377        f_print (fout, "enum clnt_stat ");
00378     }
00379   else
00380     {
00381       ptype (proc->res_prefix, proc->res_type, 1);
00382       f_print (fout, "* ");
00383     }
00384   if (server_p)
00385     pvname_svc (proc->proc_name, vp->vers_num);
00386   else
00387     pvname (proc->proc_name, vp->vers_num);
00388 
00389   /*
00390    * mode  1 = ANSI-C, mode 2 = K&R C
00391    */
00392   if (mode == 1)
00393     parglist (proc, addargtype);
00394   else
00395     f_print (fout, "();\n");
00396 }
00397 
00398 /* print out argument list of procedure */
00399 static void
00400 parglist (proc_list *proc, const char *addargtype)
00401 {
00402   decl_list *dl;
00403 
00404   f_print(fout,"(");
00405   if (proc->arg_num < 2 && newstyle &&
00406       streq (proc->args.decls->decl.type, "void"))
00407     {
00408       /* 0 argument in new style:  do nothing */
00409     }
00410   else
00411     {
00412       for (dl = proc->args.decls; dl != NULL; dl = dl->next)
00413        {
00414          ptype (dl->decl.prefix, dl->decl.type, 1);
00415          if (!newstyle)
00416            f_print (fout, "*");    /* old style passes by reference */
00417 
00418          f_print (fout, ", ");
00419        }
00420     }
00421   if (mtflag)
00422     {
00423       ptype(proc->res_prefix, proc->res_type, 1);
00424       f_print(fout, "*, ");
00425     }
00426 
00427   f_print (fout, "%s);\n", addargtype);
00428 }
00429 
00430 static void
00431 penumdef (definition *def)
00432 {
00433   const char *name = def->def_name;
00434   enumval_list *l;
00435   const char *last = NULL;
00436   int count = 0;
00437 
00438   f_print (fout, "enum %s {\n", name);
00439   for (l = def->def.en.vals; l != NULL; l = l->next)
00440     {
00441       f_print (fout, "\t%s", l->name);
00442       if (l->assignment)
00443        {
00444          f_print (fout, " = %s", l->assignment);
00445          last = l->assignment;
00446          count = 1;
00447        }
00448       else
00449        {
00450          if (last == NULL)
00451            {
00452              f_print (fout, " = %d", count++);
00453            }
00454          else
00455            {
00456              f_print (fout, " = %s + %d", last, count++);
00457            }
00458        }
00459       f_print (fout, ",\n");
00460     }
00461   f_print (fout, "};\n");
00462   f_print (fout, "typedef enum %s %s;\n", name, name);
00463 }
00464 
00465 static void
00466 ptypedef (definition *def)
00467 {
00468   const char *name = def->def_name;
00469   const char *old = def->def.ty.old_type;
00470   char prefix[8];      /* enough to contain "struct ", including NUL */
00471   relation rel = def->def.ty.rel;
00472 
00473   if (!streq (name, old))
00474     {
00475       if (streq (old, "string"))
00476        {
00477          old = "char";
00478          rel = REL_POINTER;
00479        }
00480       else if (streq (old, "opaque"))
00481        {
00482          old = "char";
00483        }
00484       else if (streq (old, "bool"))
00485        {
00486          old = "bool_t";
00487        }
00488       if (undefined2 (old, name) && def->def.ty.old_prefix)
00489        {
00490          s_print (prefix, "%s ", def->def.ty.old_prefix);
00491        }
00492       else
00493        {
00494          prefix[0] = 0;
00495        }
00496       f_print (fout, "typedef ");
00497       switch (rel)
00498        {
00499        case REL_ARRAY:
00500          f_print (fout, "struct {\n");
00501          f_print (fout, "\tu_int %s_len;\n", name);
00502          f_print (fout, "\t%s%s *%s_val;\n", prefix, old, name);
00503          f_print (fout, "} %s", name);
00504          break;
00505        case REL_POINTER:
00506          f_print (fout, "%s%s *%s", prefix, old, name);
00507          break;
00508        case REL_VECTOR:
00509          f_print (fout, "%s%s %s[%s]", prefix, old, name,
00510                  def->def.ty.array_max);
00511          break;
00512        case REL_ALIAS:
00513          f_print (fout, "%s%s %s", prefix, old, name);
00514          break;
00515        }
00516       f_print (fout, ";\n");
00517     }
00518 }
00519 
00520 void
00521 pdeclaration (const char *name, declaration * dec, int tab,
00522              const char *separator)
00523 {
00524   char buf[8];                     /* enough to hold "struct ", include NUL */
00525   const char *prefix;
00526   const char *type;
00527 
00528   if (streq (dec->type, "void"))
00529     {
00530       return;
00531     }
00532   tabify (fout, tab);
00533   if (streq (dec->type, name) && !dec->prefix)
00534     {
00535       f_print (fout, "struct ");
00536     }
00537   if (streq (dec->type, "string"))
00538     {
00539       f_print (fout, "char *%s", dec->name);
00540     }
00541   else
00542     {
00543       prefix = "";
00544       if (streq (dec->type, "bool"))
00545        {
00546          type = "bool_t";
00547        }
00548       else if (streq (dec->type, "opaque"))
00549        {
00550          type = "char";
00551        }
00552       else
00553        {
00554          if (dec->prefix)
00555            {
00556              s_print (buf, "%s ", dec->prefix);
00557              prefix = buf;
00558            }
00559          type = dec->type;
00560        }
00561       switch (dec->rel)
00562        {
00563        case REL_ALIAS:
00564          f_print (fout, "%s%s %s", prefix, type, dec->name);
00565          break;
00566        case REL_VECTOR:
00567          f_print (fout, "%s%s %s[%s]", prefix, type, dec->name,
00568                  dec->array_max);
00569          break;
00570        case REL_POINTER:
00571          f_print (fout, "%s%s *%s", prefix, type, dec->name);
00572          break;
00573        case REL_ARRAY:
00574          f_print (fout, "struct {\n");
00575          tabify (fout, tab);
00576          f_print (fout, "\tu_int %s_len;\n", dec->name);
00577          tabify (fout, tab);
00578          f_print (fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
00579          tabify (fout, tab);
00580          f_print (fout, "} %s", dec->name);
00581          break;
00582        }
00583     }
00584   f_print (fout, separator);
00585 }
00586 
00587 static int
00588 undefined2 (const char *type, const char *stop)
00589 {
00590   list *l;
00591   definition *def;
00592 
00593   for (l = defined; l != NULL; l = l->next)
00594     {
00595       def = (definition *) l->val;
00596       if (def->def_kind != DEF_PROGRAM)
00597        {
00598          if (streq (def->def_name, stop))
00599            {
00600              return 1;
00601            }
00602          else if (streq (def->def_name, type))
00603            {
00604              return 0;
00605            }
00606        }
00607     }
00608   return 1;
00609 }