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