rpc_util.c revision 17142
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. 8 * 9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12 * 13 * Sun RPC is provided with no support and without any obligation on the 14 * part of Sun Microsystems, Inc. to assist in its use, correction, 15 * modification or enhancement. 16 * 17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 19 * OR ANY PART THEREOF. 20 * 21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 22 * or profits or other special, indirect and consequential damages, even if 23 * Sun has been advised of the possibility of such damages. 24 * 25 * Sun Microsystems, Inc. 26 * 2550 Garcia Avenue 27 * Mountain View, California 94043 28 */ 29 30#ident "@(#)rpc_util.c 1.14 93/07/05 SMI" 31 32#ifndef lint 33static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI"; 34#endif 35 36/* 37 * rpc_util.c, Utility routines for the RPC protocol compiler 38 * Copyright (C) 1989, Sun Microsystems, Inc. 39 */ 40#include <stdio.h> 41#include <string.h> 42#include <ctype.h> 43#include <unistd.h> 44#include "rpc_scan.h" 45#include "rpc_parse.h" 46#include "rpc_util.h" 47 48#define ARGEXT "argument" 49 50char curline[MAXLINESIZE]; /* current read line */ 51char *where = curline; /* current point in line */ 52int linenum = 0; /* current line number */ 53 54char *infilename; /* input filename */ 55 56#define NFILES 7 57char *outfiles[NFILES]; /* output file names */ 58int nfiles; 59 60FILE *fout; /* file pointer of current output */ 61FILE *fin; /* file pointer of current input */ 62 63list *defined; /* list of defined things */ 64 65static void printwhere __P(( void )); 66 67/* 68 * Reinitialize the world 69 */ 70void 71reinitialize() 72{ 73 memset(curline, 0, MAXLINESIZE); 74 where = curline; 75 linenum = 0; 76 defined = NULL; 77} 78 79/* 80 * string equality 81 */ 82int 83streq(a, b) 84 char *a; 85 char *b; 86{ 87 return (strcmp(a, b) == 0); 88} 89 90/* 91 * find a value in a list 92 */ 93definition * 94findval(lst, val, cmp) 95 list *lst; 96 char *val; 97 int (*cmp) (); 98 99{ 100 for (; lst != NULL; lst = lst->next) { 101 if ((*cmp) (lst->val, val)) { 102 return (lst->val); 103 } 104 } 105 return (NULL); 106} 107 108/* 109 * store a value in a list 110 */ 111void 112storeval(lstp, val) 113 list **lstp; 114 definition *val; 115{ 116 list **l; 117 list *lst; 118 119 for (l = lstp; *l != NULL; l = (list **) & (*l)->next); 120 lst = ALLOC(list); 121 lst->val = val; 122 lst->next = NULL; 123 *l = lst; 124} 125 126static int 127findit(def, type) 128 definition *def; 129 char *type; 130{ 131 return (streq(def->def_name, type)); 132} 133 134static char * 135fixit(type, orig) 136 char *type; 137 char *orig; 138{ 139 definition *def; 140 141 def = (definition *) FINDVAL(defined, type, findit); 142 if (def == NULL || def->def_kind != DEF_TYPEDEF) { 143 return (orig); 144 } 145 switch (def->def.ty.rel) { 146 case REL_VECTOR: 147 if (streq(def->def.ty.old_type, "opaque")) 148 return ("char"); 149 else 150 return (def->def.ty.old_type); 151 152 case REL_ALIAS: 153 return (fixit(def->def.ty.old_type, orig)); 154 default: 155 return (orig); 156 } 157} 158 159char * 160fixtype(type) 161 char *type; 162{ 163 return (fixit(type, type)); 164} 165 166char * 167stringfix(type) 168 char *type; 169{ 170 if (streq(type, "string")) { 171 return ("wrapstring"); 172 } else { 173 return (type); 174 } 175} 176 177void 178ptype(prefix, type, follow) 179 char *prefix; 180 char *type; 181 int follow; 182{ 183 if (prefix != NULL) { 184 if (streq(prefix, "enum")) { 185 f_print(fout, "enum "); 186 } else { 187 f_print(fout, "struct "); 188 } 189 } 190 if (streq(type, "bool")) { 191 f_print(fout, "bool_t "); 192 } else if (streq(type, "string")) { 193 f_print(fout, "char *"); 194 } else { 195 f_print(fout, "%s ", follow ? fixtype(type) : type); 196 } 197} 198 199static int 200typedefed(def, type) 201 definition *def; 202 char *type; 203{ 204 if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { 205 return (0); 206 } else { 207 return (streq(def->def_name, type)); 208 } 209} 210 211int 212isvectordef(type, rel) 213 char *type; 214 relation rel; 215{ 216 definition *def; 217 218 for (;;) { 219 switch (rel) { 220 case REL_VECTOR: 221 return (!streq(type, "string")); 222 case REL_ARRAY: 223 return (0); 224 case REL_POINTER: 225 return (0); 226 case REL_ALIAS: 227 def = (definition *) FINDVAL(defined, type, typedefed); 228 if (def == NULL) { 229 return (0); 230 } 231 type = def->def.ty.old_type; 232 rel = def->def.ty.rel; 233 } 234 } 235 236 return (0); 237} 238 239char * 240locase(str) 241 char *str; 242{ 243 char c; 244 static char buf[100]; 245 char *p = buf; 246 247 while ( (c = *str++) ) { 248 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; 249 } 250 *p = 0; 251 return (buf); 252} 253 254void 255pvname_svc(pname, vnum) 256 char *pname; 257 char *vnum; 258{ 259 f_print(fout, "%s_%s_svc", locase(pname), vnum); 260} 261 262void 263pvname(pname, vnum) 264 char *pname; 265 char *vnum; 266{ 267 f_print(fout, "%s_%s", locase(pname), vnum); 268} 269 270/* 271 * print a useful (?) error message, and then die 272 */ 273void 274error(msg) 275 char *msg; 276{ 277 printwhere(); 278 f_print(stderr, "%s, line %d: ", infilename, linenum); 279 f_print(stderr, "%s\n", msg); 280 crash(); 281} 282 283/* 284 * Something went wrong, unlink any files that we may have created and then 285 * die. 286 */ 287void 288crash() 289{ 290 int i; 291 292 for (i = 0; i < nfiles; i++) { 293 (void) unlink(outfiles[i]); 294 } 295 exit(1); 296} 297 298void 299record_open(file) 300 char *file; 301{ 302 if (nfiles < NFILES) { 303 outfiles[nfiles++] = file; 304 } else { 305 f_print(stderr, "too many files!\n"); 306 crash(); 307 } 308} 309 310static char expectbuf[100]; 311static char *toktostr(); 312 313/* 314 * error, token encountered was not the expected one 315 */ 316void 317expected1(exp1) 318 tok_kind exp1; 319{ 320 s_print(expectbuf, "expected '%s'", 321 toktostr(exp1)); 322 error(expectbuf); 323} 324 325/* 326 * error, token encountered was not one of two expected ones 327 */ 328void 329expected2(exp1, exp2) 330 tok_kind exp1, exp2; 331{ 332 s_print(expectbuf, "expected '%s' or '%s'", 333 toktostr(exp1), 334 toktostr(exp2)); 335 error(expectbuf); 336} 337 338/* 339 * error, token encountered was not one of 3 expected ones 340 */ 341void 342expected3(exp1, exp2, exp3) 343 tok_kind exp1, exp2, exp3; 344{ 345 s_print(expectbuf, "expected '%s', '%s' or '%s'", 346 toktostr(exp1), 347 toktostr(exp2), 348 toktostr(exp3)); 349 error(expectbuf); 350} 351 352void 353tabify(f, tab) 354 FILE *f; 355 int tab; 356{ 357 while (tab--) { 358 (void) fputc('\t', f); 359 } 360} 361 362 363static token tokstrings[] = { 364 {TOK_IDENT, "identifier"}, 365 {TOK_CONST, "const"}, 366 {TOK_RPAREN, ")"}, 367 {TOK_LPAREN, "("}, 368 {TOK_RBRACE, "}"}, 369 {TOK_LBRACE, "{"}, 370 {TOK_LBRACKET, "["}, 371 {TOK_RBRACKET, "]"}, 372 {TOK_STAR, "*"}, 373 {TOK_COMMA, ","}, 374 {TOK_EQUAL, "="}, 375 {TOK_COLON, ":"}, 376 {TOK_SEMICOLON, ";"}, 377 {TOK_UNION, "union"}, 378 {TOK_STRUCT, "struct"}, 379 {TOK_SWITCH, "switch"}, 380 {TOK_CASE, "case"}, 381 {TOK_DEFAULT, "default"}, 382 {TOK_ENUM, "enum"}, 383 {TOK_TYPEDEF, "typedef"}, 384 {TOK_INT, "int"}, 385 {TOK_SHORT, "short"}, 386 {TOK_LONG, "long"}, 387 {TOK_UNSIGNED, "unsigned"}, 388 {TOK_DOUBLE, "double"}, 389 {TOK_FLOAT, "float"}, 390 {TOK_CHAR, "char"}, 391 {TOK_STRING, "string"}, 392 {TOK_OPAQUE, "opaque"}, 393 {TOK_BOOL, "bool"}, 394 {TOK_VOID, "void"}, 395 {TOK_PROGRAM, "program"}, 396 {TOK_VERSION, "version"}, 397 {TOK_EOF, "??????"} 398}; 399 400static char * 401toktostr(kind) 402 tok_kind kind; 403{ 404 token *sp; 405 406 for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); 407 return (sp->str); 408} 409 410static void 411printbuf() 412{ 413 char c; 414 int i; 415 int cnt; 416 417# define TABSIZE 4 418 419 for (i = 0; (c = curline[i]); i++) { 420 if (c == '\t') { 421 cnt = 8 - (i % TABSIZE); 422 c = ' '; 423 } else { 424 cnt = 1; 425 } 426 while (cnt--) { 427 (void) fputc(c, stderr); 428 } 429 } 430} 431 432static void 433printwhere() 434{ 435 int i; 436 char c; 437 int cnt; 438 439 printbuf(); 440 for (i = 0; i < where - curline; i++) { 441 c = curline[i]; 442 if (c == '\t') { 443 cnt = 8 - (i % TABSIZE); 444 } else { 445 cnt = 1; 446 } 447 while (cnt--) { 448 (void) fputc('^', stderr); 449 } 450 } 451 (void) fputc('\n', stderr); 452} 453 454char * 455make_argname(pname, vname) 456 char *pname; 457 char *vname; 458{ 459 char *name; 460 461 name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3); 462 if (!name) { 463 fprintf(stderr, "failed in malloc"); 464 exit(1); 465 } 466 sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT); 467 return (name); 468} 469 470bas_type *typ_list_h; 471bas_type *typ_list_t; 472 473void 474add_type(len, type) 475int len; 476char *type; 477{ 478 bas_type *ptr; 479 480 if ((ptr = (bas_type *) malloc(sizeof (bas_type))) == 481 (bas_type *)NULL) { 482 fprintf(stderr, "failed in malloc"); 483 exit(1); 484 } 485 486 ptr->name = type; 487 ptr->length = len; 488 ptr->next = NULL; 489 if (typ_list_t == NULL) 490 { 491 492 typ_list_t = ptr; 493 typ_list_h = ptr; 494 } 495 else 496 { 497 typ_list_t->next = ptr; 498 typ_list_t = ptr; 499 }; 500} 501 502 503bas_type *find_type(type) 504char *type; 505{ 506 bas_type * ptr; 507 508 ptr = typ_list_h; 509 while (ptr != NULL) 510 { 511 if (strcmp(ptr->name, type) == 0) 512 return (ptr); 513 else 514 ptr = ptr->next; 515 }; 516 return (NULL); 517} 518