1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2014 Garrett D'Amore <garrett@damore.org> 24 * 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 /* 41 * rpc_cout.c, XDR routine outputter for the RPC protocol compiler 42 */ 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <ctype.h> 47 #include "rpc_parse.h" 48 #include "rpc_util.h" 49 50 extern void crash(void); 51 52 static void print_header(definition *); 53 static void print_trailer(void); 54 static void emit_enum(definition *); 55 static void emit_program(definition *); 56 static void emit_union(definition *); 57 static void emit_struct(definition *); 58 static void emit_typedef(definition *); 59 static void print_stat(int, declaration *); 60 static void emit_inline(int, declaration *, int); 61 static void emit_inline64(int, declaration *, int); 62 static void emit_single_in_line(int, declaration *, int, relation); 63 static void emit_single_in_line64(int, declaration *, int, relation); 64 static char *upcase(char *); 65 66 /* 67 * Emit the C-routine for the given definition 68 */ 69 void 70 emit(definition *def) 71 { 72 if (def->def_kind == DEF_CONST) 73 return; 74 if (def->def_kind == DEF_PROGRAM) { 75 emit_program(def); 76 return; 77 } 78 if (def->def_kind == DEF_TYPEDEF) { 79 /* 80 * now we need to handle declarations like 81 * struct typedef foo foo; 82 * since we dont want this to be expanded into 2 calls 83 * to xdr_foo 84 */ 85 86 if (strcmp(def->def.ty.old_type, def->def_name) == 0) 87 return; 88 }; 89 print_header(def); 90 switch (def->def_kind) { 91 case DEF_UNION: 92 emit_union(def); 93 break; 94 case DEF_ENUM: 95 emit_enum(def); 96 break; 97 case DEF_STRUCT: 98 emit_struct(def); 99 break; 100 case DEF_TYPEDEF: 101 emit_typedef(def); 102 break; 103 } 104 print_trailer(); 105 } 106 107 static int 108 findtype(definition *def, char *type) 109 { 110 111 if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) 112 return (0); 113 return (streq(def->def_name, type)); 114 } 115 116 static int 117 undefined(char *type) 118 { 119 definition *def; 120 121 def = (definition *)FINDVAL(defined, type, findtype); 122 return (def == NULL); 123 } 124 125 126 static void 127 print_generic_header(char *procname, int pointerp) 128 { 129 f_print(fout, "\n"); 130 f_print(fout, "bool_t\n"); 131 f_print(fout, "xdr_%s(", procname); 132 f_print(fout, "XDR *xdrs, "); 133 f_print(fout, "%s ", procname); 134 if (pointerp) 135 f_print(fout, "*"); 136 f_print(fout, "objp)\n{\n\n"); 137 } 138 139 static void 140 print_header(definition *def) 141 { 142 print_generic_header(def->def_name, 143 def->def_kind != DEF_TYPEDEF || 144 !isvectordef(def->def.ty.old_type, def->def.ty.rel)); 145 /* Now add Inline support */ 146 147 if (inlinelen == 0) 148 return; 149 /* May cause lint to complain. but ... */ 150 f_print(fout, "\trpc_inline_t *buf;\n\n"); 151 } 152 153 static void 154 print_prog_header(proc_list *plist) 155 { 156 print_generic_header(plist->args.argname, 1); 157 } 158 159 static void 160 print_trailer(void) 161 { 162 f_print(fout, "\treturn (TRUE);\n"); 163 f_print(fout, "}\n"); 164 } 165 166 167 static void 168 print_ifopen(int indent, char *name) 169 { 170 tabify(fout, indent); 171 if (streq(name, "rpcprog_t") || 172 streq(name, "rpcvers_t") || 173 streq(name, "rpcproc_t") || 174 streq(name, "rpcprot_t") || 175 streq(name, "rpcport_t")) 176 (void) strtok(name, "_"); 177 f_print(fout, "if (!xdr_%s(xdrs", name); 178 } 179 180 static void 181 print_ifarg(char *arg) 182 { 183 f_print(fout, ", %s", arg); 184 } 185 186 static void 187 print_ifsizeof(int indent, char *prefix, char *type) 188 { 189 if (indent) { 190 f_print(fout, ",\n"); 191 tabify(fout, indent); 192 } else { 193 f_print(fout, ", "); 194 } 195 if (streq(type, "bool")) { 196 f_print(fout, "sizeof (bool_t), (xdrproc_t)xdr_bool"); 197 } else { 198 f_print(fout, "sizeof ("); 199 if (undefined(type) && prefix) { 200 f_print(fout, "%s ", prefix); 201 } 202 f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type); 203 } 204 } 205 206 static void 207 print_ifclose(int indent) 208 { 209 f_print(fout, "))\n"); 210 tabify(fout, indent); 211 f_print(fout, "\treturn (FALSE);\n"); 212 } 213 214 static void 215 print_ifstat(int indent, char *prefix, char *type, relation rel, 216 char *amax, char *objname, char *name) 217 { 218 char *alt = NULL; 219 220 switch (rel) { 221 case REL_POINTER: 222 print_ifopen(indent, "pointer"); 223 print_ifarg("(char **)"); 224 f_print(fout, "%s", objname); 225 print_ifsizeof(0, prefix, type); 226 break; 227 case REL_VECTOR: 228 if (streq(type, "string")) 229 alt = "string"; 230 else if (streq(type, "opaque")) 231 alt = "opaque"; 232 if (alt) { 233 print_ifopen(indent, alt); 234 print_ifarg(objname); 235 } else { 236 print_ifopen(indent, "vector"); 237 print_ifarg("(char *)"); 238 f_print(fout, "%s", objname); 239 } 240 print_ifarg(amax); 241 if (!alt) 242 print_ifsizeof(indent + 1, prefix, type); 243 break; 244 case REL_ARRAY: 245 if (streq(type, "string")) 246 alt = "string"; 247 else if (streq(type, "opaque")) 248 alt = "bytes"; 249 if (streq(type, "string")) { 250 print_ifopen(indent, alt); 251 print_ifarg(objname); 252 } else { 253 if (alt) 254 print_ifopen(indent, alt); 255 else 256 print_ifopen(indent, "array"); 257 print_ifarg("(char **)"); 258 if (*objname == '&') 259 f_print(fout, "%s.%s_val, (u_int *) %s.%s_len", 260 objname, name, objname, name); 261 else 262 f_print(fout, 263 "&%s->%s_val, (u_int *) &%s->%s_len", 264 objname, name, objname, name); 265 } 266 print_ifarg(amax); 267 if (!alt) 268 print_ifsizeof(indent + 1, prefix, type); 269 break; 270 case REL_ALIAS: 271 print_ifopen(indent, type); 272 print_ifarg(objname); 273 break; 274 } 275 print_ifclose(indent); 276 } 277 278 /* ARGSUSED */ 279 static void 280 emit_enum(definition *def) 281 { 282 print_ifopen(1, "enum"); 283 print_ifarg("(enum_t *)objp"); 284 print_ifclose(1); 285 } 286 287 static void 288 emit_program(definition *def) 289 { 290 decl_list *dl; 291 version_list *vlist; 292 proc_list *plist; 293 294 for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next) 295 for (plist = vlist->procs; plist != NULL; plist = plist->next) { 296 if (!newstyle || plist->arg_num < 2) 297 continue; /* old style, or single argument */ 298 print_prog_header(plist); 299 for (dl = plist->args.decls; dl != NULL; 300 dl = dl->next) 301 print_stat(1, &dl->decl); 302 print_trailer(); 303 } 304 } 305 306 307 static void 308 emit_union(definition *def) 309 { 310 declaration *dflt; 311 case_list *cl; 312 declaration *cs; 313 char *object; 314 315 print_stat(1, &def->def.un.enum_decl); 316 f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); 317 for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { 318 319 f_print(fout, "\tcase %s:\n", cl->case_name); 320 if (cl->contflag == 1) /* a continued case statement */ 321 continue; 322 cs = &cl->case_decl; 323 if (!streq(cs->type, "void")) { 324 size_t len = strlen(def->def_name) + 325 strlen("&objp->%s_u.%s") + 326 strlen(cs->name) + 1; 327 object = malloc(len); 328 if (isvectordef(cs->type, cs->rel)) 329 (void) snprintf(object, len, "objp->%s_u.%s", 330 def->def_name, cs->name); 331 else 332 (void) snprintf(object, len, "&objp->%s_u.%s", 333 def->def_name, cs->name); 334 print_ifstat(2, cs->prefix, cs->type, cs->rel, 335 cs->array_max, object, cs->name); 336 free(object); 337 } 338 f_print(fout, "\t\tbreak;\n"); 339 } 340 dflt = def->def.un.default_decl; 341 if (dflt != NULL) { 342 if (!streq(dflt->type, "void")) { 343 size_t len = strlen(def->def_name) + 344 strlen("&objp->%s_u.%s") + 345 strlen(dflt->name) + 1; 346 f_print(fout, "\tdefault:\n"); 347 object = malloc(len); 348 if (isvectordef(dflt->type, dflt->rel)) 349 (void) snprintf(object, len, "objp->%s_u.%s", 350 def->def_name, dflt->name); 351 else 352 (void) snprintf(object, len, "&objp->%s_u.%s", 353 def->def_name, dflt->name); 354 355 print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, 356 dflt->array_max, object, dflt->name); 357 free(object); 358 f_print(fout, "\t\tbreak;\n"); 359 } 360 } else { 361 f_print(fout, "\tdefault:\n"); 362 f_print(fout, "\t\treturn (FALSE);\n"); 363 } 364 365 f_print(fout, "\t}\n"); 366 } 367 368 static void 369 expand_inline(int indent, const char *sizestr, 370 int size, int flag, decl_list *dl, decl_list *cur) 371 { 372 decl_list *psav; 373 374 /* 375 * were already looking at a xdr_inlineable structure 376 */ 377 tabify(fout, indent + 1); 378 if (sizestr == NULL) 379 f_print(fout, 380 "buf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);", 381 size); 382 else if (size == 0) 383 f_print(fout, 384 "buf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);", 385 sizestr); 386 else 387 f_print(fout, 388 "buf = XDR_INLINE(xdrs, (%d + (%s)) " 389 "* BYTES_PER_XDR_UNIT);", size, sizestr); 390 391 f_print(fout, "\n"); 392 tabify(fout, indent + 1); 393 f_print(fout, "if (buf == NULL) {\n"); 394 395 psav = cur; 396 while (cur != dl) { 397 print_stat(indent + 2, 398 &cur->decl); 399 cur = cur->next; 400 } 401 402 tabify(fout, indent+1); 403 f_print(fout, "} else {\n"); 404 405 f_print(fout, "#if defined(_LP64) || defined(_KERNEL)\n"); 406 cur = psav; 407 while (cur != dl) { 408 emit_inline64(indent + 2, &cur->decl, flag); 409 cur = cur->next; 410 } 411 f_print(fout, "#else\n"); 412 cur = psav; 413 while (cur != dl) { 414 emit_inline(indent + 2, &cur->decl, flag); 415 cur = cur->next; 416 } 417 f_print(fout, "#endif\n"); 418 419 tabify(fout, indent + 1); 420 f_print(fout, "}\n"); 421 } 422 423 /* 424 * An inline type is a base type (interger type) or a vector of base types. 425 */ 426 static int 427 inline_type(declaration *dc, int *size) 428 { 429 bas_type *ptr; 430 431 *size = 0; 432 433 if (dc->prefix == NULL && 434 (dc->rel == REL_ALIAS || dc->rel == REL_VECTOR)) { 435 ptr = find_type(dc->type); 436 if (ptr != NULL) { 437 *size = ptr->length; 438 return (1); 439 } 440 } 441 442 return (0); 443 } 444 445 static char * 446 arraysize(char *sz, declaration *dc, int elsize) 447 { 448 int len; 449 int elsz = elsize; 450 int digits; 451 int slen = 0; 452 char *plus = ""; 453 char *tmp; 454 size_t tlen; 455 456 /* 457 * Calculate the size of a string to hold the size of all arrays 458 * to be inlined. 459 * 460 * We have the string representation of the total size that has already 461 * been seen. (Null if this is the first array). 462 * We have the string representation of array max from the declaration, 463 * optionally the plus string, " + ", if this is not the first array, 464 * and the number of digits for the element size for this declaration. 465 */ 466 if (sz != NULL) { 467 plus = " + "; 468 slen = strlen(sz); 469 } 470 471 /* Calculate the number of digits to hold the element size */ 472 for (digits = 1; elsz >= 10; digits++) 473 elsz /= 10; 474 475 /* 476 * If elsize != 1 the allocate 3 extra bytes for the times 477 * string, " * ", the "()" below, and the digits. One extra 478 * for the trailing NULL 479 */ 480 len = strlen(dc->array_max) + (elsize == 1 ? 0 : digits + 5) + 1; 481 tlen = slen + len + strlen(plus); 482 tmp = realloc(sz, tlen); 483 if (tmp == NULL) { 484 f_print(stderr, "Fatal error : no memory\n"); 485 crash(); 486 } 487 488 if (elsize == 1) 489 (void) snprintf(tmp + slen, tlen - slen, "%s%s", 490 plus, dc->array_max); 491 else 492 (void) snprintf(tmp + slen, tlen - slen, "%s(%s) * %d", 493 plus, dc->array_max, elsize); 494 495 return (tmp); 496 } 497 498 static void 499 inline_struct(decl_list *dl, decl_list *last, int flag, int indent) 500 { 501 int size, tsize; 502 decl_list *cur; 503 char *sizestr; 504 505 cur = NULL; 506 tsize = 0; 507 sizestr = NULL; 508 for (; dl != last; dl = dl->next) { 509 if (inline_type(&dl->decl, &size)) { 510 if (cur == NULL) 511 cur = dl; 512 513 if (dl->decl.rel == REL_ALIAS) 514 tsize += size; 515 else { 516 /* this code is required to handle arrays */ 517 sizestr = arraysize(sizestr, &dl->decl, size); 518 } 519 } else { 520 if (cur != NULL) 521 if (sizestr == NULL && tsize < inlinelen) { 522 /* 523 * don't expand into inline code 524 * if tsize < inlinelen 525 */ 526 while (cur != dl) { 527 print_stat(indent + 1, 528 &cur->decl); 529 cur = cur->next; 530 } 531 } else { 532 expand_inline(indent, sizestr, 533 tsize, flag, dl, cur); 534 } 535 tsize = 0; 536 cur = NULL; 537 sizestr = NULL; 538 print_stat(indent + 1, &dl->decl); 539 } 540 } 541 542 if (cur == NULL) 543 return; 544 if (sizestr == NULL && tsize < inlinelen) { 545 /* don't expand into inline code if tsize < inlinelen */ 546 while (cur != dl) { 547 print_stat(indent + 1, &cur->decl); 548 cur = cur->next; 549 } 550 } else { 551 expand_inline(indent, sizestr, tsize, flag, dl, cur); 552 } 553 } 554 555 /* 556 * Check if we can inline this structure. While we are at it check if the 557 * declaration list has any vectors defined of "basic" types. 558 */ 559 static int 560 check_inline(decl_list *dl, int inlinelen, int *have_vector) 561 { 562 int tsize = 0; 563 int size; 564 int doinline = 0; 565 566 *have_vector = 0; 567 if (inlinelen == 0) 568 return (0); 569 570 for (; dl != NULL; dl = dl->next) { 571 if (!inline_type(&dl->decl, &size)) { 572 tsize = 0; 573 continue; 574 } 575 if (dl->decl.rel == REL_VECTOR) { 576 *have_vector = 1; 577 return (1); 578 } 579 tsize += size; 580 if (tsize >= inlinelen) 581 doinline = 1; 582 } 583 584 return (doinline); 585 } 586 587 588 static void 589 emit_struct_tail_recursion(definition *defp, int can_inline) 590 { 591 int indent = 3; 592 struct_def *sp = &defp->def.st; 593 decl_list *dl; 594 595 596 f_print(fout, "\t%s *tmp_%s;\n", 597 defp->def_name, defp->def_name); 598 599 f_print(fout, "\tbool_t more_data = TRUE;\n"); 600 f_print(fout, "\tbool_t first_objp = TRUE;\n\n"); 601 602 f_print(fout, "\n\tif (xdrs->x_op == XDR_DECODE) {\n"); 603 f_print(fout, "\n\t\twhile (more_data) {\n"); 604 f_print(fout, "\n\t\t\tvoid bzero();\n\n"); 605 606 if (can_inline) 607 inline_struct(sp->decls, sp->tail, GET, indent); 608 else 609 for (dl = sp->decls; dl != NULL && dl != sp->tail; 610 dl = dl->next) 611 print_stat(indent, &dl->decl); 612 613 f_print(fout, "\t\t\tif (!xdr_bool(xdrs, " 614 "&more_data))\n\t\t\t\treturn (FALSE);\n"); 615 616 f_print(fout, "\n\t\t\tif (!more_data) {\n"); 617 f_print(fout, "\t\t\t\tobjp->%s = NULL;\n", sp->tail->decl.name); 618 f_print(fout, "\t\t\t\tbreak;\n"); 619 f_print(fout, "\t\t\t}\n\n"); 620 f_print(fout, "\t\t\tif (objp->%s == NULL) {\n", sp->tail->decl.name); 621 f_print(fout, "\t\t\t\tobjp->%s = " 622 "(%s *)\n\t\t\t\t\tmem_alloc(sizeof (%s));\n", 623 sp->tail->decl.name, defp->def_name, defp->def_name); 624 625 f_print(fout, "\t\t\t\tif (objp->%s == NULL)\n" 626 "\t\t\t\t\treturn (FALSE);\n", sp->tail->decl.name); 627 f_print(fout, "\t\t\t\tbzero(objp->%s, sizeof (%s));\n", 628 sp->tail->decl.name, defp->def_name); 629 f_print(fout, "\t\t\t}\n"); 630 f_print(fout, "\t\t\tobjp = objp->%s;\n", sp->tail->decl.name); 631 f_print(fout, "\t\t}\n"); 632 633 f_print(fout, "\n\t} else if (xdrs->x_op == XDR_ENCODE) {\n"); 634 f_print(fout, "\n\t\twhile (more_data) {\n"); 635 636 if (can_inline) 637 inline_struct(sp->decls, sp->tail, PUT, indent); 638 else 639 for (dl = sp->decls; dl != NULL && dl != sp->tail; 640 dl = dl->next) 641 print_stat(indent, &dl->decl); 642 643 f_print(fout, "\t\t\tobjp = objp->%s;\n", sp->tail->decl.name); 644 f_print(fout, "\t\t\tif (objp == NULL)\n"); 645 f_print(fout, "\t\t\t\tmore_data = FALSE;\n"); 646 647 f_print(fout, "\t\t\tif (!xdr_bool(xdrs, &more_data))\n" 648 "\t\t\t\treturn (FALSE);\n"); 649 650 f_print(fout, "\t\t}\n"); 651 652 f_print(fout, "\n\t} else {\n"); 653 f_print(fout, "\n\t\twhile (more_data) {\n"); 654 655 for (dl = sp->decls; dl != NULL && dl != sp->tail; dl = dl->next) 656 print_stat(indent, &dl->decl); 657 658 f_print(fout, "\t\t\ttmp_%s = objp;\n", defp->def_name); 659 f_print(fout, "\t\t\tobjp = objp->%s;\n", sp->tail->decl.name); 660 661 f_print(fout, "\t\t\tif (objp == NULL)\n"); 662 f_print(fout, "\t\t\t\tmore_data = FALSE;\n"); 663 664 f_print(fout, "\t\t\tif (!first_objp)\n"); 665 666 f_print(fout, "\t\t\t\tmem_free(tmp_%s, sizeof (%s));\n", 667 defp->def_name, defp->def_name); 668 669 f_print(fout, "\t\t\telse\n\t\t\t\tfirst_objp = FALSE;\n\t\t}\n"); 670 671 f_print(fout, "\n\t}\n"); 672 } 673 674 static void 675 emit_struct(definition *def) 676 { 677 decl_list *dl = def->def.st.decls; 678 int can_inline, have_vector; 679 680 681 can_inline = check_inline(dl, inlinelen, &have_vector); 682 if (have_vector) 683 f_print(fout, "\tint i;\n"); 684 685 686 if (rflag && def->def.st.self_pointer) { 687 /* Handle tail recursion elimination */ 688 emit_struct_tail_recursion(def, can_inline); 689 return; 690 } 691 692 693 if (can_inline) { 694 f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n"); 695 inline_struct(dl, NULL, PUT, 1); 696 697 f_print(fout, "\t\treturn (TRUE);\n\t}" 698 " else if (xdrs->x_op == XDR_DECODE) {\n"); 699 700 inline_struct(dl, NULL, GET, 1); 701 f_print(fout, "\t\treturn (TRUE);\n\t}\n\n"); 702 } 703 704 /* now take care of XDR_FREE inline case or the non-inline cases */ 705 706 for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 707 print_stat(1, &dl->decl); 708 709 } 710 711 static void 712 emit_typedef(definition *def) 713 { 714 char *prefix = def->def.ty.old_prefix; 715 char *type = def->def.ty.old_type; 716 char *amax = def->def.ty.array_max; 717 relation rel = def->def.ty.rel; 718 719 print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); 720 } 721 722 static void 723 print_stat(int indent, declaration *dec) 724 { 725 char *prefix = dec->prefix; 726 char *type = dec->type; 727 char *amax = dec->array_max; 728 relation rel = dec->rel; 729 char name[256]; 730 731 if (isvectordef(type, rel)) 732 (void) snprintf(name, sizeof (name), "objp->%s", dec->name); 733 else 734 (void) snprintf(name, sizeof (name), "&objp->%s", dec->name); 735 print_ifstat(indent, prefix, type, rel, amax, name, dec->name); 736 } 737 738 739 static void 740 emit_inline(int indent, declaration *decl, int flag) 741 { 742 switch (decl->rel) { 743 case REL_ALIAS : 744 emit_single_in_line(indent, decl, flag, REL_ALIAS); 745 break; 746 case REL_VECTOR : 747 tabify(fout, indent); 748 f_print(fout, "{\n"); 749 tabify(fout, indent + 1); 750 f_print(fout, "%s *genp;\n\n", decl->type); 751 tabify(fout, indent + 1); 752 f_print(fout, 753 "for (i = 0, genp = objp->%s;\n", decl->name); 754 tabify(fout, indent + 2); 755 f_print(fout, "i < %s; i++) {\n", decl->array_max); 756 emit_single_in_line(indent + 2, decl, flag, REL_VECTOR); 757 tabify(fout, indent + 1); 758 f_print(fout, "}\n"); 759 tabify(fout, indent); 760 f_print(fout, "}\n"); 761 } 762 } 763 764 static void 765 emit_inline64(int indent, declaration *decl, int flag) 766 { 767 switch (decl->rel) { 768 case REL_ALIAS : 769 emit_single_in_line64(indent, decl, flag, REL_ALIAS); 770 break; 771 case REL_VECTOR : 772 tabify(fout, indent); 773 f_print(fout, "{\n"); 774 tabify(fout, indent + 1); 775 f_print(fout, "%s *genp;\n\n", decl->type); 776 tabify(fout, indent + 1); 777 f_print(fout, 778 "for (i = 0, genp = objp->%s;\n", decl->name); 779 tabify(fout, indent + 2); 780 f_print(fout, "i < %s; i++) {\n", decl->array_max); 781 emit_single_in_line64(indent + 2, decl, flag, REL_VECTOR); 782 tabify(fout, indent + 1); 783 f_print(fout, "}\n"); 784 tabify(fout, indent); 785 f_print(fout, "}\n"); 786 } 787 } 788 789 static void 790 emit_single_in_line(int indent, declaration *decl, int flag, relation rel) 791 { 792 char *upp_case; 793 int freed = 0; 794 795 tabify(fout, indent); 796 if (flag == PUT) 797 f_print(fout, "IXDR_PUT_"); 798 else 799 if (rel == REL_ALIAS) 800 f_print(fout, "objp->%s = IXDR_GET_", decl->name); 801 else 802 f_print(fout, "*genp++ = IXDR_GET_"); 803 804 upp_case = upcase(decl->type); 805 806 /* hack - XX */ 807 if (strcmp(upp_case, "INT") == 0) { 808 free(upp_case); 809 freed = 1; 810 upp_case = "LONG"; 811 } 812 if ((strcmp(upp_case, "U_INT") == 0) || 813 (strcmp(upp_case, "RPCPROG") == 0) || 814 (strcmp(upp_case, "RPCVERS") == 0) || 815 (strcmp(upp_case, "RPCPROC") == 0) || 816 (strcmp(upp_case, "RPCPROT") == 0) || 817 (strcmp(upp_case, "RPCPORT") == 0)) { 818 free(upp_case); 819 freed = 1; 820 upp_case = "U_LONG"; 821 } 822 823 if (flag == PUT) 824 if (rel == REL_ALIAS) 825 f_print(fout, 826 "%s(buf, objp->%s);\n", upp_case, decl->name); 827 else 828 f_print(fout, "%s(buf, *genp++);\n", upp_case); 829 830 else 831 f_print(fout, "%s(buf);\n", upp_case); 832 if (!freed) 833 free(upp_case); 834 } 835 836 static void 837 emit_single_in_line64(int indent, declaration *decl, int flag, relation rel) 838 { 839 char *upp_case; 840 int freed = 0; 841 842 tabify(fout, indent); 843 if (flag == PUT) 844 f_print(fout, "IXDR_PUT_"); 845 else 846 if (rel == REL_ALIAS) 847 f_print(fout, "objp->%s = IXDR_GET_", decl->name); 848 else 849 f_print(fout, "*genp++ = IXDR_GET_"); 850 851 upp_case = upcase(decl->type); 852 853 /* hack - XX */ 854 if ((strcmp(upp_case, "INT") == 0)||(strcmp(upp_case, "LONG") == 0)) { 855 free(upp_case); 856 freed = 1; 857 upp_case = "INT32"; 858 } 859 if ((strcmp(upp_case, "U_INT") == 0) || 860 (strcmp(upp_case, "U_LONG") == 0) || 861 (strcmp(upp_case, "RPCPROG") == 0) || 862 (strcmp(upp_case, "RPCVERS") == 0) || 863 (strcmp(upp_case, "RPCPROC") == 0) || 864 (strcmp(upp_case, "RPCPROT") == 0) || 865 (strcmp(upp_case, "RPCPORT") == 0)) { 866 free(upp_case); 867 freed = 1; 868 upp_case = "U_INT32"; 869 } 870 871 if (flag == PUT) 872 if (rel == REL_ALIAS) 873 f_print(fout, 874 "%s(buf, objp->%s);\n", upp_case, decl->name); 875 else 876 f_print(fout, "%s(buf, *genp++);\n", upp_case); 877 878 else 879 f_print(fout, "%s(buf);\n", upp_case); 880 if (!freed) 881 free(upp_case); 882 } 883 884 static char * 885 upcase(char *str) 886 { 887 char *ptr, *hptr; 888 889 ptr = malloc(strlen(str)+1); 890 if (ptr == NULL) { 891 f_print(stderr, "malloc failed\n"); 892 exit(1); 893 }; 894 895 hptr = ptr; 896 while (*str != '\0') 897 *ptr++ = toupper(*str++); 898 899 *ptr = '\0'; 900 return (hptr); 901 }