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