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