Back to index

glibc  2.9
rpc_util.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_util.c 1.11 89/02/22 (C) 1987 SMI
00033  */
00034 
00035 /*
00036  * rpc_util.c, Utility routines for the RPC protocol compiler
00037  */
00038 #include <stdio.h>
00039 #include <ctype.h>
00040 #include <string.h>
00041 #include <unistd.h>
00042 #include "rpc_scan.h"
00043 #include "rpc_parse.h"
00044 #include "rpc_util.h"
00045 #include "proto.h"
00046 
00047 #define ARGEXT "argument"
00048 
00049 char curline[MAXLINESIZE];  /* current read line */
00050 const char *where = curline;       /* current point in line */
00051 int linenum = 0;            /* current line number */
00052 
00053 const char *infilename;            /* input filename */
00054 
00055 #define NFILES 7
00056 const char *outfiles[NFILES];      /* output file names */
00057 int nfiles;
00058 
00059 FILE *fout;                 /* file pointer of current output */
00060 FILE *fin;                  /* file pointer of current input */
00061 
00062 list *defined;                     /* list of defined things */
00063 
00064 static int findit (const definition * def, const char *type);
00065 static const char *fixit (const char *type, const char *orig);
00066 static int typedefed (const definition * def, const char *type);
00067 static const char *toktostr (tok_kind kind);
00068 static void printbuf (void);
00069 static void printwhere (void);
00070 
00071 /*
00072  * Reinitialize the world
00073  */
00074 void
00075 reinitialize (void)
00076 {
00077   memset (curline, 0, MAXLINESIZE);
00078   where = curline;
00079   linenum = 0;
00080   defined = NULL;
00081 }
00082 
00083 /*
00084  * string equality
00085  */
00086 int
00087 streq (const char *a, const char *b)
00088 {
00089   return strcmp (a, b) == 0;
00090 }
00091 
00092 /*
00093  * find a value in a list
00094  */
00095 definition *
00096 findval (list *lst, const char *val,
00097         int (*cmp) (const definition *, const char *))
00098 {
00099 
00100   for (; lst != NULL; lst = lst->next)
00101     {
00102       if (cmp (lst->val, val))
00103        {
00104          return lst->val;
00105        }
00106     }
00107   return NULL;
00108 }
00109 
00110 /*
00111  * store a value in a list
00112  */
00113 void
00114 storeval (list **lstp, definition *val)
00115 {
00116   list **l;
00117   list *lst;
00118 
00119 
00120   for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
00121   lst = ALLOC (list);
00122   lst->val = val;
00123   lst->next = NULL;
00124   *l = lst;
00125 }
00126 
00127 static int
00128 findit (const definition * def, const char *type)
00129 {
00130   return streq (def->def_name, type);
00131 }
00132 
00133 static const char *
00134 fixit (const char *type, const char *orig)
00135 {
00136   definition *def;
00137 
00138   def = findval (defined, type, findit);
00139   if (def == NULL || def->def_kind != DEF_TYPEDEF)
00140     {
00141       return orig;
00142     }
00143   switch (def->def.ty.rel)
00144     {
00145     case REL_VECTOR:
00146       if (streq (def->def.ty.old_type, "opaque"))
00147        return ("char");
00148       else
00149        return (def->def.ty.old_type);
00150     case REL_ALIAS:
00151       return (fixit (def->def.ty.old_type, orig));
00152     default:
00153       return orig;
00154     }
00155 }
00156 
00157 const char *
00158 fixtype (const char *type)
00159 {
00160   return fixit (type, type);
00161 }
00162 
00163 const char *
00164 stringfix (const char *type)
00165 {
00166   if (streq (type, "string"))
00167     {
00168       return "wrapstring";
00169     }
00170   else
00171     {
00172       return type;
00173     }
00174 }
00175 
00176 void
00177 ptype (const char *prefix, const char *type, int follow)
00178 {
00179   if (prefix != NULL)
00180     {
00181       if (streq (prefix, "enum"))
00182        {
00183          f_print (fout, "enum ");
00184        }
00185       else
00186        {
00187          f_print (fout, "struct ");
00188        }
00189     }
00190   if (streq (type, "bool"))
00191     {
00192       f_print (fout, "bool_t ");
00193     }
00194   else if (streq (type, "string"))
00195     {
00196       f_print (fout, "char *");
00197     }
00198   else
00199     {
00200       f_print (fout, "%s ", follow ? fixtype (type) : type);
00201     }
00202 }
00203 
00204 static int
00205 typedefed (const definition * def, const char *type)
00206 {
00207   if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
00208     {
00209       return 0;
00210     }
00211   else
00212     {
00213       return streq (def->def_name, type);
00214     }
00215 }
00216 
00217 int
00218 isvectordef (const char *type, relation rel)
00219 {
00220   definition *def;
00221 
00222   for (;;)
00223     {
00224       switch (rel)
00225        {
00226        case REL_VECTOR:
00227          return !streq (type, "string");
00228        case REL_ARRAY:
00229          return 0;
00230        case REL_POINTER:
00231          return 0;
00232        case REL_ALIAS:
00233          def = findval (defined, type, typedefed);
00234          if (def == NULL)
00235            {
00236              return 0;
00237            }
00238          type = def->def.ty.old_type;
00239          rel = def->def.ty.rel;
00240        }
00241     }
00242 }
00243 
00244 char *
00245 locase (const char *str)
00246 {
00247   char c;
00248   static char buf[100];
00249   char *p = buf;
00250 
00251   while ((c = *str++) != 0)
00252     {
00253       *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
00254     }
00255   *p = 0;
00256   return buf;
00257 }
00258 
00259 void
00260 pvname_svc (const char *pname, const char *vnum)
00261 {
00262   f_print (fout, "%s_%s_svc", locase (pname), vnum);
00263 }
00264 
00265 void
00266 pvname (const char *pname, const char *vnum)
00267 {
00268   f_print (fout, "%s_%s", locase (pname), vnum);
00269 }
00270 
00271 /*
00272  * print a useful (?) error message, and then die
00273  */
00274 void
00275 error (const char *msg)
00276 {
00277   printwhere ();
00278   f_print (stderr, "%s, line %d: ", infilename, linenum);
00279   f_print (stderr, "%s\n", msg);
00280   crash ();
00281 }
00282 
00283 /*
00284  * Something went wrong, unlink any files that we may have created and then
00285  * die.
00286  */
00287 void
00288 crash (void)
00289 {
00290   int i;
00291 
00292   for (i = 0; i < nfiles; i++)
00293     {
00294       unlink (outfiles[i]);
00295     }
00296   exit (1);
00297 }
00298 
00299 void
00300 record_open (const char *file)
00301 {
00302   if (nfiles < NFILES)
00303     {
00304       outfiles[nfiles++] = file;
00305     }
00306   else
00307     {
00308       f_print (stderr, "too many files!\n");
00309       crash ();
00310     }
00311 }
00312 
00313 static char expectbuf[100];
00314 
00315 /*
00316  * error, token encountered was not the expected one
00317  */
00318 void
00319 expected1 (tok_kind exp1)
00320 {
00321   s_print (expectbuf, "expected '%s'",
00322           toktostr (exp1));
00323   error (expectbuf);
00324 }
00325 
00326 /*
00327  * error, token encountered was not one of two expected ones
00328  */
00329 void
00330 expected2 (tok_kind exp1, tok_kind exp2)
00331 {
00332   s_print (expectbuf, "expected '%s' or '%s'",
00333           toktostr (exp1),
00334           toktostr (exp2));
00335   error (expectbuf);
00336 }
00337 
00338 /*
00339  * error, token encountered was not one of 3 expected ones
00340  */
00341 void
00342 expected3 (tok_kind exp1, tok_kind exp2, tok_kind exp3)
00343 {
00344   s_print (expectbuf, "expected '%s', '%s' or '%s'",
00345           toktostr (exp1),
00346           toktostr (exp2),
00347           toktostr (exp3));
00348   error (expectbuf);
00349 }
00350 
00351 void
00352 tabify (FILE * f, int tab)
00353 {
00354   while (tab--)
00355     {
00356       (void) fputc ('\t', f);
00357     }
00358 }
00359 
00360 
00361 static const token tokstrings[] =
00362 {
00363   {TOK_IDENT, "identifier"},
00364   {TOK_CONST, "const"},
00365   {TOK_RPAREN, ")"},
00366   {TOK_LPAREN, "("},
00367   {TOK_RBRACE, "}"},
00368   {TOK_LBRACE, "{"},
00369   {TOK_LBRACKET, "["},
00370   {TOK_RBRACKET, "]"},
00371   {TOK_STAR, "*"},
00372   {TOK_COMMA, ","},
00373   {TOK_EQUAL, "="},
00374   {TOK_COLON, ":"},
00375   {TOK_SEMICOLON, ";"},
00376   {TOK_UNION, "union"},
00377   {TOK_STRUCT, "struct"},
00378   {TOK_SWITCH, "switch"},
00379   {TOK_CASE, "case"},
00380   {TOK_DEFAULT, "default"},
00381   {TOK_ENUM, "enum"},
00382   {TOK_TYPEDEF, "typedef"},
00383   {TOK_INT, "int"},
00384   {TOK_SHORT, "short"},
00385   {TOK_LONG, "long"},
00386   {TOK_UNSIGNED, "unsigned"},
00387   {TOK_DOUBLE, "double"},
00388   {TOK_FLOAT, "float"},
00389   {TOK_CHAR, "char"},
00390   {TOK_STRING, "string"},
00391   {TOK_OPAQUE, "opaque"},
00392   {TOK_BOOL, "bool"},
00393   {TOK_VOID, "void"},
00394   {TOK_PROGRAM, "program"},
00395   {TOK_VERSION, "version"},
00396   {TOK_EOF, "??????"}
00397 };
00398 
00399 static const char *
00400 toktostr (tok_kind kind)
00401 {
00402   const token *sp;
00403 
00404   for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
00405   return sp->str;
00406 }
00407 
00408 static void
00409 printbuf (void)
00410 {
00411   char c;
00412   int i;
00413   int cnt;
00414 
00415 #define TABSIZE 4
00416 
00417   for (i = 0; (c = curline[i]) != 0; i++)
00418     {
00419       if (c == '\t')
00420        {
00421          cnt = 8 - (i % TABSIZE);
00422          c = ' ';
00423        }
00424       else
00425        {
00426          cnt = 1;
00427        }
00428       while (cnt--)
00429        {
00430          (void) fputc (c, stderr);
00431        }
00432     }
00433 }
00434 
00435 static void
00436 printwhere (void)
00437 {
00438   int i;
00439   char c;
00440   int cnt;
00441 
00442   printbuf ();
00443   for (i = 0; i < where - curline; i++)
00444     {
00445       c = curline[i];
00446       if (c == '\t')
00447        {
00448          cnt = 8 - (i % TABSIZE);
00449        }
00450       else
00451        {
00452          cnt = 1;
00453        }
00454       while (cnt--)
00455        {
00456          (void) fputc ('^', stderr);
00457        }
00458     }
00459   (void) fputc ('\n', stderr);
00460 }
00461 
00462 char *
00463 make_argname (const char *pname, const char *vname)
00464 {
00465   char *name;
00466 
00467   name = malloc (strlen (pname) + strlen (vname) + strlen (ARGEXT) + 3);
00468   if (!name)
00469     {
00470       fprintf (stderr, "failed in malloc");
00471       exit (1);
00472     }
00473   sprintf (name, "%s_%s_%s", locase (pname), vname, ARGEXT);
00474   return name;
00475 }
00476 
00477 bas_type *typ_list_h;
00478 bas_type *typ_list_t;
00479 
00480 void
00481 add_type (int len, const char *type)
00482 {
00483   bas_type *ptr;
00484 
00485 
00486   if ((ptr = malloc (sizeof (bas_type))) == NULL)
00487     {
00488       fprintf (stderr, "failed in malloc");
00489       exit (1);
00490     }
00491 
00492   ptr->name = type;
00493   ptr->length = len;
00494   ptr->next = NULL;
00495   if (typ_list_t == NULL)
00496     {
00497 
00498       typ_list_t = ptr;
00499       typ_list_h = ptr;
00500     }
00501   else
00502     {
00503 
00504       typ_list_t->next = ptr;
00505       typ_list_t = ptr;
00506     }
00507 
00508 }
00509 
00510 
00511 bas_type *
00512 find_type (const char *type)
00513 {
00514   bas_type *ptr;
00515 
00516   ptr = typ_list_h;
00517 
00518 
00519   while (ptr != NULL)
00520     {
00521       if (strcmp (ptr->name, type) == 0)
00522        return ptr;
00523       else
00524        ptr = ptr->next;
00525     };
00526   return NULL;
00527 }