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