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