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