1 /* $OpenBSD: rpc_util.c,v 1.17 2015/08/20 22:32:41 deraadt Exp $ */ 2 /* $NetBSD: rpc_util.c,v 1.6 1995/08/29 23:05:57 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 2010, Oracle America, Inc. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials 16 * provided with the distribution. 17 * * Neither the name of the "Oracle America, Inc." nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* 36 * rpc_util.c, Utility routines for the RPC protocol compiler 37 */ 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <ctype.h> 42 #include <unistd.h> 43 #include "rpc_scan.h" 44 #include "rpc_parse.h" 45 #include "rpc_util.h" 46 47 #define ARGEXT "argument" 48 49 static void printwhere(void); 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 /* 67 * Reinitialize the world 68 */ 69 void 70 reinitialize() 71 { 72 memset(curline, 0, MAXLINESIZE); 73 where = curline; 74 linenum = 0; 75 defined = NULL; 76 } 77 78 /* 79 * string equality 80 */ 81 int 82 streq(a, b) 83 char *a; 84 char *b; 85 { 86 return (strcmp(a, b) == 0); 87 } 88 89 /* 90 * find a value in a list 91 */ 92 definition * 93 findval(lst, val, cmp) 94 list *lst; 95 char *val; 96 int (*cmp) (definition *, char *); 97 { 98 99 for (; lst != NULL; lst = lst->next) { 100 if ((*cmp) (lst->val, val)) { 101 return (lst->val); 102 } 103 } 104 return (NULL); 105 } 106 107 /* 108 * store a value in a list 109 */ 110 void 111 storeval(lstp, val) 112 list **lstp; 113 definition *val; 114 { 115 list **l; 116 list *lst; 117 118 for (l = lstp; *l != NULL; l = (list **) & (*l)->next) 119 ; 120 lst = malloc(sizeof(list)); 121 if (lst == NULL) { 122 fprintf(stderr, "failed in alloc\n"); 123 exit(1); 124 } 125 lst->val = val; 126 lst->next = NULL; 127 *l = lst; 128 } 129 130 static int 131 findit(definition *def, char *type) 132 { 133 return (streq(def->def_name, type)); 134 } 135 136 static char * 137 fixit(char *type, char *orig) 138 { 139 definition *def; 140 141 def = (definition *) FINDVAL(defined, type, findit); 142 if (def == NULL || def->def_kind != DEF_TYPEDEF) { 143 return (orig); 144 } 145 switch (def->def.ty.rel) { 146 case REL_VECTOR: 147 return (def->def.ty.old_type); 148 case REL_ALIAS: 149 return (fixit(def->def.ty.old_type, orig)); 150 default: 151 return (orig); 152 } 153 } 154 155 char * 156 fixtype(type) 157 char *type; 158 { 159 return (fixit(type, type)); 160 } 161 162 char * 163 stringfix(type) 164 char *type; 165 { 166 if (streq(type, "string")) { 167 return ("wrapstring"); 168 } else { 169 return (type); 170 } 171 } 172 173 void 174 ptype(prefix, type, follow) 175 char *prefix; 176 char *type; 177 int follow; 178 { 179 if (prefix != NULL) { 180 if (streq(prefix, "enum")) { 181 fprintf(fout, "enum "); 182 } else { 183 fprintf(fout, "struct "); 184 } 185 } 186 if (streq(type, "bool")) { 187 fprintf(fout, "bool_t "); 188 } else if (streq(type, "string")) { 189 fprintf(fout, "char *"); 190 } else { 191 fprintf(fout, "%s ", follow ? fixtype(type) : type); 192 } 193 } 194 195 static int 196 typedefed(definition *def, char *type) 197 { 198 if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) 199 return (0); 200 else 201 return (streq(def->def_name, type)); 202 } 203 204 int 205 isvectordef(type, rel) 206 char *type; 207 relation rel; 208 { 209 definition *def; 210 211 for (;;) { 212 switch (rel) { 213 case REL_VECTOR: 214 return (!streq(type, "string")); 215 case REL_ARRAY: 216 return (0); 217 case REL_POINTER: 218 return (0); 219 case REL_ALIAS: 220 def = (definition *) FINDVAL(defined, type, typedefed); 221 if (def == NULL) 222 return (0); 223 type = def->def.ty.old_type; 224 rel = def->def.ty.rel; 225 } 226 } 227 } 228 229 char * 230 locase(str) 231 char *str; 232 { 233 char c; 234 static char buf[100]; 235 char *p = buf; 236 237 while ((c = *str++)) 238 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; 239 *p = 0; 240 return (buf); 241 } 242 243 void 244 pvname_svc(pname, vnum) 245 char *pname; 246 char *vnum; 247 { 248 fprintf(fout, "%s_%s_svc", locase(pname), vnum); 249 } 250 251 void 252 pvname(pname, vnum) 253 char *pname; 254 char *vnum; 255 { 256 fprintf(fout, "%s_%s", locase(pname), vnum); 257 } 258 259 /* 260 * print a useful (?) error message, and then die 261 */ 262 void 263 error(msg) 264 char *msg; 265 { 266 printwhere(); 267 fprintf(stderr, "%s, line %d: ", infilename, linenum); 268 fprintf(stderr, "%s\n", msg); 269 crash(); 270 } 271 272 /* 273 * Something went wrong, unlink any files that we may have created and then 274 * die. 275 */ 276 void 277 crash() 278 { 279 int i; 280 281 for (i = 0; i < nfiles; i++) { 282 (void) unlink(outfiles[i]); 283 } 284 exit(1); 285 } 286 287 void 288 record_open(file) 289 char *file; 290 { 291 if (nfiles < NFILES) { 292 outfiles[nfiles++] = file; 293 } else { 294 fprintf(stderr, "too many files!\n"); 295 crash(); 296 } 297 } 298 299 static char expectbuf[100]; 300 static char *toktostr(tok_kind); 301 302 /* 303 * error, token encountered was not the expected one 304 */ 305 void 306 expected1(exp1) 307 tok_kind exp1; 308 { 309 snprintf(expectbuf, sizeof expectbuf, "expected '%s'", 310 toktostr(exp1)); 311 error(expectbuf); 312 } 313 314 /* 315 * error, token encountered was not one of two expected ones 316 */ 317 void 318 expected2(exp1, exp2) 319 tok_kind exp1, exp2; 320 { 321 snprintf(expectbuf, sizeof expectbuf, "expected '%s' or '%s'", 322 toktostr(exp1), toktostr(exp2)); 323 error(expectbuf); 324 } 325 326 /* 327 * error, token encountered was not one of 3 expected ones 328 */ 329 void 330 expected3(exp1, exp2, exp3) 331 tok_kind exp1, exp2, exp3; 332 { 333 snprintf(expectbuf, sizeof expectbuf, "expected '%s', '%s' or '%s'", 334 toktostr(exp1), toktostr(exp2), toktostr(exp3)); 335 error(expectbuf); 336 } 337 338 void 339 tabify(f, tab) 340 FILE *f; 341 int tab; 342 { 343 while (tab--) { 344 (void) fputc('\t', f); 345 } 346 } 347 348 static token tokstrings[] = { 349 {TOK_IDENT, "identifier"}, 350 {TOK_CONST, "const"}, 351 {TOK_RPAREN, ")"}, 352 {TOK_LPAREN, "("}, 353 {TOK_RBRACE, "}"}, 354 {TOK_LBRACE, "{"}, 355 {TOK_LBRACKET, "["}, 356 {TOK_RBRACKET, "]"}, 357 {TOK_STAR, "*"}, 358 {TOK_COMMA, ","}, 359 {TOK_EQUAL, "="}, 360 {TOK_COLON, ":"}, 361 {TOK_SEMICOLON, ";"}, 362 {TOK_UNION, "union"}, 363 {TOK_STRUCT, "struct"}, 364 {TOK_SWITCH, "switch"}, 365 {TOK_CASE, "case"}, 366 {TOK_DEFAULT, "default"}, 367 {TOK_ENUM, "enum"}, 368 {TOK_TYPEDEF, "typedef"}, 369 {TOK_INT, "int"}, 370 {TOK_SHORT, "short"}, 371 {TOK_LONG, "long"}, 372 {TOK_UNSIGNED, "unsigned"}, 373 {TOK_DOUBLE, "double"}, 374 {TOK_FLOAT, "float"}, 375 {TOK_CHAR, "char"}, 376 {TOK_STRING, "string"}, 377 {TOK_OPAQUE, "opaque"}, 378 {TOK_BOOL, "bool"}, 379 {TOK_VOID, "void"}, 380 {TOK_PROGRAM, "program"}, 381 {TOK_VERSION, "version"}, 382 {TOK_EOF, "??????"} 383 }; 384 385 static char * 386 toktostr(tok_kind kind) 387 { 388 token *sp; 389 390 for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++) 391 ; 392 return (sp->str); 393 } 394 395 static void 396 printbuf(void) 397 { 398 char c; 399 int i; 400 int cnt; 401 402 # define TABSIZE 4 403 404 for (i = 0; (c = curline[i]); i++) { 405 if (c == '\t') { 406 cnt = 8 - (i % TABSIZE); 407 c = ' '; 408 } else { 409 cnt = 1; 410 } 411 while (cnt--) { 412 (void) fputc(c, stderr); 413 } 414 } 415 } 416 417 static void 418 printwhere() 419 { 420 int i; 421 char c; 422 int cnt; 423 424 printbuf(); 425 for (i = 0; i < where - curline; i++) { 426 c = curline[i]; 427 if (c == '\t') { 428 cnt = 8 - (i % TABSIZE); 429 } else { 430 cnt = 1; 431 } 432 while (cnt--) { 433 (void) fputc('^', stderr); 434 } 435 } 436 (void) fputc('\n', stderr); 437 } 438 439 char * 440 make_argname(pname, vname) 441 char *pname; 442 char *vname; 443 { 444 char *name; 445 int len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3; 446 447 name = malloc(len); 448 if (!name) { 449 fprintf(stderr, "failed in malloc\n"); 450 exit(1); 451 } 452 snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT); 453 return(name); 454 } 455 456 bas_type *typ_list_h; 457 bas_type *typ_list_t; 458 459 void 460 add_type(len, type) 461 int len; 462 char *type; 463 { 464 bas_type *ptr; 465 466 if ((ptr = malloc(sizeof(bas_type))) == (bas_type *)NULL) { 467 fprintf(stderr, "failed in malloc\n"); 468 exit(1); 469 } 470 471 ptr->name = type; 472 ptr->length = len; 473 ptr->next = NULL; 474 if (typ_list_t == NULL) { 475 typ_list_t = ptr; 476 typ_list_h = ptr; 477 } else { 478 typ_list_t->next = ptr; 479 typ_list_t = ptr; 480 } 481 } 482 483 bas_type * 484 find_type(type) 485 char *type; 486 { 487 bas_type * ptr; 488 489 ptr = typ_list_h; 490 491 while (ptr != NULL) { 492 if (strcmp(ptr->name, type) == 0) 493 return(ptr); 494 else 495 ptr = ptr->next; 496 } 497 return(NULL); 498 } 499 500