1 /* $NetBSD: rpc_util.c,v 1.11 2011/08/31 16:24:58 plunky Exp $ */ 2 /* 3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 * unrestricted use provided that this legend is included on all tape 5 * media and as a part of the software program in whole or part. Users 6 * may copy or modify Sun RPC without charge, but are not authorized 7 * to license or distribute it to anyone else except as part of a product or 8 * program developed by the user or with the express written consent of 9 * Sun Microsystems, Inc. 10 * 11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 * 15 * Sun RPC is provided with no support and without any obligation on the 16 * part of Sun Microsystems, Inc. to assist in its use, correction, 17 * modification or enhancement. 18 * 19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 * OR ANY PART THEREOF. 22 * 23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 * or profits or other special, indirect and consequential damages, even if 25 * Sun has been advised of the possibility of such damages. 26 * 27 * Sun Microsystems, Inc. 28 * 2550 Garcia Avenue 29 * Mountain View, California 94043 30 */ 31 32 #if HAVE_NBTOOL_CONFIG_H 33 #include "nbtool_config.h" 34 #endif 35 36 #include <sys/cdefs.h> 37 #if defined(__RCSID) && !defined(lint) 38 #if 0 39 static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI"; 40 #else 41 __RCSID("$NetBSD: rpc_util.c,v 1.11 2011/08/31 16:24:58 plunky Exp $"); 42 #endif 43 #endif 44 45 /* 46 * rpc_util.c, Utility routines for the RPC protocol compiler 47 */ 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <unistd.h> 51 #include <string.h> 52 #include <ctype.h> 53 #include "rpc_scan.h" 54 #include "rpc_parse.h" 55 #include "rpc_util.h" 56 57 #define ARGEXT "argument" 58 59 static void printwhere __P((void)); 60 61 char curline[MAXLINESIZE]; /* current read line */ 62 char *where = curline; /* current point in line */ 63 int linenum = 0; /* current line number */ 64 65 char *infilename; /* input filename */ 66 67 #define NFILES 7 68 char *outfiles[NFILES]; /* output file names */ 69 int nfiles; 70 71 FILE *fout; /* file pointer of current output */ 72 FILE *fin; /* file pointer of current input */ 73 74 list *defined; /* list of defined things */ 75 76 static char *toktostr __P((tok_kind)); 77 static void printbuf __P((void)); 78 static void printwhere __P((void)); 79 static int findit __P((definition *, char *)); 80 static char *fixit __P((char *, char *)); 81 static int typedefed __P((definition *, char *)); 82 83 /* 84 * Reinitialize the world 85 */ 86 void 87 reinitialize() 88 { 89 memset(curline, 0, MAXLINESIZE); 90 where = curline; 91 linenum = 0; 92 defined = NULL; 93 } 94 /* 95 * string equality 96 */ 97 int 98 streq(a, b) 99 char *a; 100 char *b; 101 { 102 return (strcmp(a, b) == 0); 103 } 104 /* 105 * find a value in a list 106 */ 107 definition * 108 findval(lst, val, cmp) 109 list *lst; 110 char *val; 111 int (*cmp) __P((definition *, char *)); 112 113 { 114 115 for (; lst != NULL; lst = lst->next) { 116 if ((*cmp) (lst->val, val)) { 117 return (lst->val); 118 } 119 } 120 return (NULL); 121 } 122 /* 123 * store a value in a list 124 */ 125 void 126 storeval(lstp, val) 127 list **lstp; 128 definition *val; 129 { 130 list **l; 131 list *lst; 132 133 134 for (l = lstp; *l != NULL; l = (list **) & (*l)->next); 135 lst = ALLOC(list); 136 lst->val = val; 137 lst->next = NULL; 138 *l = lst; 139 } 140 141 static int 142 findit(def, type) 143 definition *def; 144 char *type; 145 { 146 return (streq(def->def_name, type)); 147 } 148 149 static char * 150 fixit(type, orig) 151 char *type; 152 char *orig; 153 { 154 definition *def; 155 156 def = (definition *) FINDVAL(defined, type, findit); 157 if (def == NULL || def->def_kind != DEF_TYPEDEF) { 158 return (orig); 159 } 160 switch (def->def.ty.rel) { 161 case REL_VECTOR: 162 return (def->def.ty.old_type); 163 case REL_ALIAS: 164 return (fixit(def->def.ty.old_type, orig)); 165 default: 166 return (orig); 167 } 168 } 169 170 char * 171 fixtype(type) 172 char *type; 173 { 174 return (fixit(type, type)); 175 } 176 177 char * 178 stringfix(type) 179 char *type; 180 { 181 if (streq(type, "string")) { 182 return ("wrapstring"); 183 } else { 184 return (type); 185 } 186 } 187 188 void 189 ptype(prefix, type, follow) 190 char *prefix; 191 char *type; 192 int follow; 193 { 194 if (prefix != NULL) { 195 if (streq(prefix, "enum")) { 196 f_print(fout, "enum "); 197 } else { 198 f_print(fout, "struct "); 199 } 200 } 201 if (streq(type, "bool")) { 202 f_print(fout, "bool_t "); 203 } else 204 if (streq(type, "string")) { 205 f_print(fout, "char *"); 206 } else { 207 f_print(fout, "%s ", follow ? fixtype(type) : type); 208 } 209 } 210 211 static int 212 typedefed(def, type) 213 definition *def; 214 char *type; 215 { 216 if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { 217 return (0); 218 } else { 219 return (streq(def->def_name, type)); 220 } 221 } 222 223 int 224 isvectordef(type, rel) 225 char *type; 226 relation rel; 227 { 228 definition *def; 229 230 for (;;) { 231 switch (rel) { 232 case REL_VECTOR: 233 return (!streq(type, "string")); 234 case REL_ARRAY: 235 return (0); 236 case REL_POINTER: 237 return (0); 238 case REL_ALIAS: 239 def = (definition *) FINDVAL(defined, type, typedefed); 240 if (def == NULL) { 241 return (0); 242 } 243 type = def->def.ty.old_type; 244 rel = def->def.ty.rel; 245 } 246 } 247 } 248 249 char * 250 locase(str) 251 char *str; 252 { 253 char c; 254 static char buf[100]; 255 char *p = buf; 256 257 while ((c = *str++) != '\0') { 258 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; 259 } 260 *p = 0; 261 return (buf); 262 } 263 264 void 265 pvname_svc(pname, vnum) 266 char *pname; 267 char *vnum; 268 { 269 f_print(fout, "%s_%s_svc", locase(pname), vnum); 270 } 271 272 void 273 pvname(pname, vnum) 274 char *pname; 275 char *vnum; 276 { 277 f_print(fout, "%s_%s", locase(pname), vnum); 278 } 279 /* 280 * print a useful (?) error message, and then die 281 */ 282 void 283 error(msg) 284 char *msg; 285 { 286 printwhere(); 287 f_print(stderr, "%s, line %d: ", infilename, linenum); 288 f_print(stderr, "%s\n", msg); 289 crash(); 290 } 291 /* 292 * Something went wrong, unlink any files that we may have created and then 293 * die. 294 */ 295 void 296 crash() 297 { 298 int i; 299 300 for (i = 0; i < nfiles; i++) { 301 (void) unlink(outfiles[i]); 302 } 303 exit(1); 304 } 305 306 void 307 record_open(file) 308 char *file; 309 { 310 if (nfiles < NFILES) { 311 outfiles[nfiles++] = file; 312 } else { 313 f_print(stderr, "too many files!\n"); 314 crash(); 315 } 316 } 317 318 static char expectbuf[100]; 319 320 /* 321 * error, token encountered was not the expected one 322 */ 323 void 324 expected1(exp1) 325 tok_kind exp1; 326 { 327 s_print(expectbuf, "expected '%s'", 328 toktostr(exp1)); 329 error(expectbuf); 330 } 331 /* 332 * error, token encountered was not one of two expected ones 333 */ 334 void 335 expected2(exp1, exp2) 336 tok_kind exp1, exp2; 337 { 338 s_print(expectbuf, "expected '%s' or '%s'", 339 toktostr(exp1), 340 toktostr(exp2)); 341 error(expectbuf); 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]) != '\0'; 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 = (char *) malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3); 467 if (!name) { 468 fprintf(stderr, "failed in malloc"); 469 exit(1); 470 } 471 sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT); 472 return (name); 473 } 474 475 bas_type *typ_list_h; 476 bas_type *typ_list_t; 477 478 void 479 add_type(len, type) 480 int len; 481 char *type; 482 { 483 bas_type *ptr; 484 485 if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == NULL) { 486 fprintf(stderr, "failed in malloc"); 487 exit(1); 488 } 489 ptr->name = type; 490 ptr->length = len; 491 ptr->next = NULL; 492 if (typ_list_t == NULL) { 493 typ_list_t = ptr; 494 typ_list_h = ptr; 495 } else { 496 typ_list_t->next = ptr; 497 typ_list_t = ptr; 498 } 499 } 500 501 bas_type * 502 find_type(type) 503 char *type; 504 { 505 bas_type *ptr; 506 507 ptr = typ_list_h; 508 509 510 while (ptr != NULL) { 511 if (strcmp(ptr->name, type) == 0) 512 return (ptr); 513 else 514 ptr = ptr->next; 515 } 516 return (NULL); 517 } 518