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