1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** ddspell.c 82** 83** FACILITY: 84** 85** Interface Definition Language (IDL) Compiler 86** 87** ABSTRACT: 88** 89** Data Driven Backend - Support routines to spell C source vector definitions 90** and code to interface with a Marshalling Interpreter. 91** 92*/ 93 94#include <ddbe.h> 95#include <astp.h> 96#include <command.h> 97#include <message.h> 98#include <mtsbacke.h> 99#include <nidlmsg.h> 100#include <cspell.h> 101 102/* 103 * Conditional macro to spell a comment containing the current vector index. 104 */ 105#ifdef DUMPERS 106#define DDBE_SPELL_INDEX(_fid, _index) \ 107 fprintf(_fid, "/* %s */ ", DDBE_spell_long(_index)) 108#else 109#define DDBE_SPELL_INDEX(_fid, _index) 110#endif 111 112/* 113 * Conditional macro to spell a comment if the comment stringtable ID non-NULL. 114 */ 115#ifdef DUMPERS 116#define DDBE_SPELL_COMMENT(_fid, _comment_id, _comment_fmt, _comment_buf) \ 117 if (_comment_id != STRTAB_NULL_STR) \ 118 { \ 119 STRTAB_str_to_string(_comment_id, &_comment_buf); \ 120 fprintf(_fid, _comment_fmt, _comment_buf); \ 121 } 122#else 123#define DDBE_SPELL_COMMENT(_fid, _comment_id, _comment_fmt, _comment_buf) 124#endif 125 126/* 127 * Conditional macros to spell a string with zero, one, or two printf arguments. 128 */ 129#ifdef DUMPERS 130#define DDBE_SPELL_TEXT(_fid, _string) \ 131 fprintf(_fid, _string) 132 133#define DDBE_SPELL_TEXT_1ARG(_fid, _fmt, _arg) \ 134 fprintf(_fid, _fmt, _arg) 135 136#define DDBE_SPELL_TEXT_2ARG(_fid, _fmt, _arg1, _arg2) \ 137 fprintf(_fid, _fmt, _arg1, _arg2) 138#else 139#define DDBE_SPELL_TEXT(_fid, _string) 140#define DDBE_SPELL_TEXT_1ARG(_fid, _fmt, _arg) 141#define DDBE_SPELL_TEXT_2ARG(_fid, _fmt, _arg1, _arg2) 142#endif 143 144/**************************************/ 145/* Private speller support routines */ 146/**************************************/ 147 148/* 149 * D D B E _ s p e l l _ l o n g 150 * D D B E _ s p e l l _ l o n g _ n f 151 * 152 * Returns a string that represents a long integer in either hex or decimal. 153 * DDBE_spell_long spells the long with filler chars for right justification. 154 * DDBE_spell_long_nf spells the long with no filler chars. 155 * 156 * Implicit Input: DDBE_stub_hex - TRUE => return hex format, FALSE => decimal 157 * Restriction: 158 * For simplicity of implementation, the routine uses a global buffer. 159 * Thus routine is not reentrant and call will overwrite previous buffer 160 * contents. Do not code two calls to this routine in one printf call. 161 */ 162static char DDBE_long_buf[DDBE_MAX_EXPR]; 163 164static char *DDBE_spell_long 165( 166 long val /* [in] long value */ 167) 168{ 169 if (DDBE_stub_hex) 170 sprintf(DDBE_long_buf, "0x%04lx", val); 171 else 172 sprintf(DDBE_long_buf, "%6ld", val); 173 174 return DDBE_long_buf; 175} 176 177static char *DDBE_spell_long_nf 178( 179 long val /* [in] long value */ 180) 181{ 182 if (DDBE_stub_hex) 183 sprintf(DDBE_long_buf, "0x%lx", val); 184 else 185 sprintf(DDBE_long_buf, "%ld", val); 186 187 return DDBE_long_buf; 188} 189 190/* 191 * D D B E _ s p e l l _ l o n g _ v a l 192 * 193 * Spells a 'long' value as a series of bytes so that the resulting data 194 * encoding is not dependent on the platform's integer endianism. 195 */ 196static void DDBE_spell_long_val 197( 198 FILE *fid, /* [in] output file handle */ 199 DDBE_vec_rep_t *vec_p, /* [in] ptr to vector entry list */ 200 boolean little_endian ATTRIBUTE_UNUSED /* [in] T/F => spell as little/big endian */ 201) 202{ 203 byte *bp; 204 int i; 205#ifdef DUMPERS 206 char const *comment; 207#endif 208 209 bp = (byte *)&vec_p->val.long_val; 210 211 for (i = 0; i < 4 /*sizeof(idl_long_int)*/; i++) 212 fprintf(fid, "0x%02x,", bp[i]); 213 214#ifdef DUMPERS 215 STRTAB_str_to_string(vec_p->comment, &comment); 216 fprintf(fid, "\t/* long %s %s */", 217 DDBE_spell_long_nf(vec_p->val.long_val), comment); 218#endif 219 fprintf(fid, "\n"); 220} 221 222/* 223 * D D B E _ s p e l l _ s h o r t _ b y t e s 224 * 225 * Spells a 'short' value as a series of bytes so that the resulting data 226 * encoding is not dependent on the platform's integer endianism. 227 */ 228static void DDBE_spell_short_bytes 229( 230 FILE *fid, /* [in] output file handle */ 231 unsigned short *val, /* [in] value to print */ 232 boolean little_endian ATTRIBUTE_UNUSED /* [in] T/F => spell as little/big endian */ 233) 234{ 235 byte *bp; 236 int i; 237 238 bp = (byte *)val; 239 240 for (i = 0; i < 2 /*sizeof(idl_short_int)*/; i++) 241 fprintf(fid, "0x%02x,", bp[i]); 242} 243 244/* 245 * D D B E _ s p e l l _ l o n g _ b y t e s 246 * 247 * Spells a 'long' value as a series of bytes so that the resulting data 248 * encoding is not dependent on the platform's integer endianism. 249 */ 250static void DDBE_spell_long_bytes 251( 252 FILE *fid, /* [in] output file handle */ 253 unsigned long *val, /* [in] value to print */ 254 boolean little_endian ATTRIBUTE_UNUSED /* [in] T/F => spell as little/big endian */ 255) 256{ 257 byte *bp; 258 int i; 259 260 bp = (byte *)val; 261 262 for (i = 0; i < 4 /*sizeof(idl_long_int)*/; i++) 263 fprintf(fid, "0x%02x,", bp[i]); 264} 265 266/* 267 * D D B E _ s p e l l _ l o n g _ b o o l _ v a l 268 * 269 * Spells a 'long' representation of a boolean value as a series of bytes so 270 * that the resulting data encoding is not dependent on the platform's integer 271 * endianism. 272 */ 273static void DDBE_spell_long_bool_val 274( 275 FILE *fid, /* [in] output file handle */ 276 DDBE_vec_rep_t *vec_p, /* [in] ptr to vector entry list */ 277 boolean little_endian /* [in] T/F => spell as little/big endian */ 278) 279{ 280 const char *sym; 281#ifdef DUMPERS 282 char const *comment; 283#endif 284 285 if (vec_p->val.long_val == 0) 286 sym = "idl_false"; 287 else 288 sym = "idl_true"; 289 290 /* 291 * Regardless of whether we're running on little/big endian or spelling 292 * for little/big endian, the first byte spelt is the low-order byte. 293 */ 294 if (little_endian) 295 fprintf(fid, "%s,0x00,0x00,0x00,", sym); 296 else 297 fprintf(fid, "0x00,0x00,0x00,%s,", sym); 298#ifdef DUMPERS 299 STRTAB_str_to_string(vec_p->comment, &comment); 300 fprintf(fid, "\t/* long %s %s */", 301 DDBE_spell_long_nf(vec_p->val.long_val), comment); 302#endif 303 fprintf(fid, "\n"); 304} 305 306/* 307 * D D B E _ l a s t _ f i e l d 308 * 309 * Returns pointer to last field node in structure type. If last field is 310 * a nested struct returns the last field in the innermost struct. Also 311 * returns an field expression, e.g. "last_toplevel_field.last_nested_field". 312 * 313 * Assumption: Input type is a structure. 314 */ 315static void DDBE_last_field 316( 317 AST_type_n_t *type_p, /* [in] ptr to AST type node */ 318 AST_field_n_t **p_field_p,/*[out] ptr to AST field node */ 319 STRTAB_str_t *field_expr /*[out] field expression */ 320) 321{ 322 AST_structure_n_t *struct_p; 323 AST_field_n_t *field_p; 324 char const *field_name; 325 char expr[DDBE_MAX_EXPR]; 326 boolean nested; 327 328 expr[0] = '\0'; 329 nested = FALSE; 330 struct_p = type_p->type_structure.structure; 331 332 field_p = struct_p->fields; 333 while (field_p != NULL) 334 { 335 if (field_p->next == NULL) 336 { 337 *p_field_p = field_p; 338 NAMETABLE_id_to_string(field_p->name, &field_name); 339 if (nested) 340 strlcat(expr, ".", sizeof(expr)); 341 strlcat(expr, field_name, sizeof(expr)); 342 343 if (field_p->type->kind == AST_structure_k) 344 { 345 nested = TRUE; 346 field_p = field_p->type->type_structure.structure->fields; 347 continue; 348 } 349 } 350 field_p = field_p->next; 351 } 352 353 *field_expr = STRTAB_add_string(expr); 354} 355 356/* 357 * D D B E _ s i z e o f _ e x p r 358 * 359 * Spells an expression for the size of a data type. 360 */ 361static void DDBE_sizeof_expr 362( 363 FILE *fid, /* [in] output file handle */ 364 AST_type_n_t *type_p, /* [in] ptr to AST type node */ 365 STRTAB_str_t comment_id ATTRIBUTE_UNUSED /* [in] ID of comment string */ 366) 367{ 368#ifdef DUMPERS 369 char const *comment; /* Comment string */ 370#endif 371 372 if (AST_CONFORMANT_SET(type_p)) 373 { 374 AST_field_n_t *field_p; /* Ptr to conformant array field node */ 375 STRTAB_str_t field_expr; 376 char const *field_text; 377 378 if (type_p->kind != AST_structure_k) 379 { 380 INTERNAL_ERROR("sizeof conformant array not supported"); 381 return; 382 } 383 DDBE_last_field(type_p, &field_p, &field_expr); 384 STRTAB_str_to_string(field_expr, &field_text); 385#if defined(ultrix) 386 fprintf(fid, "IDL_offsetofarr("); 387#else 388 fprintf(fid, "offsetof("); 389#endif 390 CSPELL_typed_name(fid, type_p, NAMETABLE_NIL_ID /*instance name*/, 391 (AST_type_n_t *)NULL /*in_typedef*/, 392 TRUE /*in_struct*/, TRUE /*spell_tag*/, FALSE /*encoding_services*/ 393 ); 394 fprintf(fid, ", %s)", field_text); 395 } 396 else 397 { 398 fprintf(fid, "sizeof"); 399 CSPELL_cast_exp(fid, type_p); 400 } 401 402 DDBE_SPELL_COMMENT(fid, comment_id, "\t/* %s */", comment); 403} 404 405/* 406 * D D B E _ s i z e o f _ e x p r _ u s e _ i n s t 407 * 408 * Spells an expression for the size of a data type. Requires the instance 409 * declarations that are spelt by DDBE_spell_offset_instances. 410 */ 411static void DDBE_sizeof_expr_use_inst 412( 413 FILE *fid, /* [in] output file handle */ 414 AST_type_n_t *type_p, /* [in] ptr to AST type node */ 415 STRTAB_str_t comment_id ATTRIBUTE_UNUSED /* [in] ID of comment string */ 416) 417{ 418 char const *inst_name; /* Name of generated instance of type */ 419#ifdef DUMPERS 420 char const *comment; /* Comment string */ 421#endif 422 423 NAMETABLE_id_to_string(type_p->be_info.dd_type->inst_name, &inst_name); 424 425 if (AST_CONFORMANT_SET(type_p)) 426 { 427 AST_field_n_t *field_p; /* Ptr to conformant array field node */ 428 STRTAB_str_t field_expr; 429 char const *field_text; 430 431 if (type_p->kind != AST_structure_k) 432 { 433 INTERNAL_ERROR("sizeof conformant array not supported"); 434 return; 435 } 436 DDBE_last_field(type_p, &field_p, &field_expr); 437 STRTAB_str_to_string(field_expr, &field_text); 438 fprintf(fid, "(idl_byte *)%s.%s - (idl_byte *)&%s", 439 inst_name, field_text, inst_name); 440 } 441 else 442 fprintf(fid, "sizeof(%s)", inst_name); 443 444 DDBE_SPELL_COMMENT(fid, comment_id, "\t/* %s */", comment); 445} 446 447/*****************************/ 448/* Public utility routines */ 449/*****************************/ 450 451/* 452 * D D B E _ c f m t _ a r r _ l o c a l _ r e p 453 * 454 * Returns TRUE if a parameter's local representation is any form of 455 * a conformant array. 456 */ 457boolean DDBE_cfmt_arr_local_rep 458( 459 AST_parameter_n_t *param_p /* [in] Ptr to AST parameter node */ 460) 461{ 462 AST_type_n_t *type_p; 463 464 type_p = param_p->type; 465 466 /* A conformant array without represent_as */ 467 if (AST_CONFORMANT_SET(type_p) 468 && type_p->rep_as_type == NULL) 469 return TRUE; 470 471 /* A [ref] pointer to a conformant object without represent_as */ 472 if (AST_REF_SET(param_p) && type_p->kind == AST_pointer_k 473 && AST_CONFORMANT_SET(type_p->type_structure.pointer->pointee_type) 474 && type_p->type_structure.pointer->pointee_type->rep_as_type == NULL) 475 return TRUE; 476 477 /* An arrayified pointer whose array representation is conformant */ 478 if (DDBE_ARRAYIFIED(param_p) 479 && AST_CONFORMANT_SET( 480 type_p->type_structure.pointer->pointee_type->array_rep_type)) 481 return TRUE; 482 483 return FALSE; 484} 485 486/*************************************/ 487/* Public speller support routines */ 488/*************************************/ 489 490/* 491 * D D B E _ s p e l l _ o f f s e t _ i n s t a n c e s 492 * 493 * Spells an instance declaration of each type that is represented in the 494 * offset vector. This is necessary so that the data is portable. 495 */ 496void DDBE_spell_offset_instances 497( 498 FILE *fid, /* [in] output file handle */ 499 DDBE_vectors_t *vip, /* [in] vector information pointer */ 500 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 501 void **cmd_val ATTRIBUTE_UNUSED /* [in] array of cmd option values */ 502) 503{ 504 DDBE_vec_rep_t *vec_p; /* Ptr to offset vector entry list */ 505 AST_type_n_t *type_p; /* Ptr to AST structure type node */ 506 AST_rep_as_n_t *rep_p; /* Ptr to AST represent_as node */ 507 AST_cs_char_n_t *ichar_p; /* Ptr to AST cs_char node */ 508 boolean in_struct; /* T => in struct (for speller) */ 509 510 for (vec_p = vip->offset_p; vec_p != NULL; vec_p = vec_p->next) 511 { 512 if (vec_p->kind != DDBE_vec_sizeof_k) 513 continue; 514 515 type_p = vec_p->val.type_p; 516 517 if (type_p->kind == AST_disc_union_k && type_p-> 518 type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID) 519 in_struct = FALSE; 520 else 521 in_struct = TRUE; 522 fprintf(fid, "static "); 523 /* 524 * Null out and later restore represent_as node address, if any, 525 * to prevent spelling of local type - we want network type. 526 * Same for cs_char. 527 */ 528 rep_p = type_p->rep_as_type; 529 type_p->rep_as_type = NULL; 530 ichar_p = type_p->cs_char_type; 531 type_p->cs_char_type = NULL; 532 CSPELL_typed_name(fid, type_p, type_p->be_info.dd_type->inst_name, 533 (AST_type_n_t *)NULL, in_struct, TRUE /*spell_tag*/, 534 FALSE /*encoding_services*/); 535 type_p->rep_as_type = rep_p; 536 type_p->cs_char_type = ichar_p; 537 fprintf(fid, ";\n"); 538 } 539 540 fflush(fid); 541} 542 543/* 544 * D D B E _ s p e l l _ o f f s e t _ v e c 545 * 546 * Spells the offset vector definition and initialization. Does not require 547 * the instance declarations that are spelt by DDBE_spell_offset_instances, 548 * and thus is the most straightforward way of spelling the offset vector. 549 */ 550void DDBE_spell_offset_vec 551( 552 FILE *fid, /* [in] output file handle */ 553 DDBE_vectors_t *vip, /* [in] vector information pointer */ 554 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 555 void **cmd_val ATTRIBUTE_UNUSED /* [in] array of cmd option values */ 556) 557{ 558 DDBE_vec_rep_t *vec_p; /* Ptr to offset vector entry list */ 559 AST_type_n_t *type_p = NULL; /* Ptr to AST type node */ 560 AST_rep_as_n_t *rep_p = NULL; /* Ptr to AST represent_as node */ 561 AST_cs_char_n_t *ichar_p = NULL; /* Ptr to AST cs_char node */ 562#ifdef DUMPERS 563 char const *comment; /* Comment text */ 564#endif 565 boolean in_struct = false; /* T => in struct (for speller) */ 566 567 vec_p = vip->offset_p; 568 569 fprintf(fid, "static idl_ulong_int %soffset_vec[] = {\n", DDBE_PREFIX_IDL); 570 fprintf(fid, "0,"); 571 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 572 fprintf(fid, "\n"); 573 574 while (vec_p != NULL) 575 { 576 switch (vec_p->kind) 577 { 578 case DDBE_vec_comment_k: 579 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t\t/* %s */\n", comment); 580 break; 581 582 case DDBE_vec_expr_long_k: 583 { 584 /* Simple expression for long value */ 585 char const *long_expr; 586 587 STRTAB_str_to_string(vec_p->val.expr, &long_expr); 588 DDBE_SPELL_INDEX(fid, vec_p->index); 589 fprintf(fid, "(idl_ulong_int)%s,", long_expr); 590 591 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 592 fprintf(fid, "\n"); 593 break; 594 } 595 596 case DDBE_vec_sizeof_k: 597 type_p = vec_p->val.type_p; 598 /* 599 * Null out and later restore represent_as node address, if any, 600 * to prevent spelling of local type - we want network type. 601 * Same for cs_char. 602 */ 603 rep_p = type_p->rep_as_type; 604 type_p->rep_as_type = NULL; 605 ichar_p = type_p->cs_char_type; 606 type_p->cs_char_type = NULL; 607 DDBE_SPELL_INDEX(fid, vec_p->index); 608 DDBE_sizeof_expr(fid, type_p, vec_p->comment); 609 fprintf(fid, ",\n"); 610 type_p->rep_as_type = rep_p; 611 type_p->cs_char_type = ichar_p; 612 break; 613 614 case DDBE_vec_noop_k: 615 break; 616 617 case DDBE_vec_offset_begin_k: 618 type_p = vec_p->val.type_p; 619 if (type_p->kind == AST_disc_union_k && type_p-> 620 type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID) 621 in_struct = FALSE; 622 else 623 in_struct = TRUE; 624 /* 625 * Null out and later restore represent_as node address, if any, 626 * to prevent spelling of local type - we want network type. 627 * Same for cs_char. 628 */ 629 rep_p = type_p->rep_as_type; 630 type_p->rep_as_type = NULL; 631 ichar_p = type_p->cs_char_type; 632 type_p->cs_char_type = NULL; 633 break; 634 635 case DDBE_vec_offset_end_k: 636 /* Restore node addresses that were saved above */ 637 assert(type_p != NULL); 638 639 type_p->rep_as_type = rep_p; 640 type_p->cs_char_type = ichar_p; 641 break; 642 643 case DDBE_vec_expr_k: 644 case DDBE_vec_expr_arr_k: 645 { 646 /* 647 * field offset: &((type *)NULL)->field-expr - NULL 648 */ 649 char const *field_expr; 650 651 STRTAB_str_to_string(vec_p->val.expr, &field_expr); 652 DDBE_SPELL_INDEX(fid, vec_p->index); 653 654#if defined(ultrix) 655 if (vec_p->kind == DDBE_vec_expr_arr_k) 656 fprintf(fid, "IDL_offsetofarr("); 657 else 658#endif 659 fprintf(fid, "offsetof("); 660 CSPELL_typed_name(fid, type_p, NAMETABLE_NIL_ID /*instance name*/, 661 (AST_type_n_t *)NULL /*in_typedef*/, 662 in_struct, TRUE /*spell_tag*/, FALSE /*encoding_services*/); 663 fprintf(fid, ", %s),", field_expr); 664 665 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 666 fprintf(fid, "\n"); 667 break; 668 } 669 670 default: 671 INTERNAL_ERROR("Invalid offset vector entry kind"); 672 } 673 674 vec_p = vec_p->next; 675 } 676 677 fprintf(fid, "0"); 678 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 679 fprintf(fid, "\n};\n\n"); 680} 681 682/* 683 * D D B E _ s p e l l _ o f f s e t _ v e c _ u s e _ i n s t 684 * 685 * Spells the offset vector definition. Requires the instance declarations 686 * that are spelt by DDBE_spell_offset_instances. 687 * 688 * NOTE: 689 * The resulting declaration will not compile successfully under some C 690 * compilers. On those platforms it will be necessary to call DDBE_init_ 691 * offset_vec to spell a routine which must be called once per interface to 692 * initialize the offset vector. 693 */ 694void DDBE_spell_offset_vec_use_inst 695( 696 FILE *fid, /* [in] output file handle */ 697 DDBE_vectors_t *vip, /* [in] vector information pointer */ 698 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 699 void **cmd_val ATTRIBUTE_UNUSED /* [in] array of cmd option values */ 700) 701{ 702 DDBE_vec_rep_t *vec_p; /* Ptr to offset vector entry list */ 703 AST_type_n_t *type_p; /* Ptr to AST type node */ 704 char const *inst_name; /* Name of generated instance of type */ 705#ifdef DUMPERS 706 char const *comment; /* Comment text */ 707#endif 708 709 vec_p = vip->offset_p; 710 inst_name = NULL; 711 712 fprintf(fid, "static idl_ulong_int %soffset_vec[] = {\n", DDBE_PREFIX_IDL); 713 fprintf(fid, "0,"); 714 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 715 fprintf(fid, "\n"); 716 717 while (vec_p != NULL) 718 { 719 type_p = vec_p->val.type_p; 720 721 switch (vec_p->kind) 722 { 723 case DDBE_vec_comment_k: 724 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t\t/* %s */\n", comment); 725 break; 726 727 case DDBE_vec_expr_long_k: 728 { 729 /* Simple expression for long value */ 730 char const *long_expr; 731 732 STRTAB_str_to_string(vec_p->val.expr, &long_expr); 733 DDBE_SPELL_INDEX(fid, vec_p->index); 734 fprintf(fid, "%s,", long_expr); 735 736 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 737 fprintf(fid, "\n"); 738 break; 739 } 740 741 case DDBE_vec_sizeof_k: 742 DDBE_SPELL_INDEX(fid, vec_p->index); 743 DDBE_sizeof_expr_use_inst(fid, type_p, vec_p->comment); 744 fprintf(fid, ",\n"); 745 break; 746 747 case DDBE_vec_noop_k: 748 break; 749 750 case DDBE_vec_offset_end_k: 751 inst_name = NULL; 752 break; 753 754 case DDBE_vec_offset_begin_k: 755 /* Form instance name for struct */ 756 NAMETABLE_id_to_string(type_p->be_info.dd_type->inst_name, 757 &inst_name); 758 break; 759 760 case DDBE_vec_expr_k: 761 case DDBE_vec_expr_arr_k: 762 { 763 /* 764 * field offset: &inst.field-expr - &inst 765 */ 766 char const *field_expr; 767 768 STRTAB_str_to_string(vec_p->val.expr, &field_expr); 769 DDBE_SPELL_INDEX(fid, vec_p->index); 770 fprintf(fid, "(idl_byte *)%s%s.%s - (idl_byte *)&%s,", 771 (vec_p->kind == DDBE_vec_expr_arr_k) ? "" : "&", 772 inst_name, field_expr, inst_name); 773 774 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 775 fprintf(fid, "\n"); 776 break; 777 } 778 779 default: 780 INTERNAL_ERROR("Invalid offset vector entry kind"); 781 } 782 783 vec_p = vec_p->next; 784 } 785 786 fprintf(fid, "0"); 787 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 788 fprintf(fid, "\n};\n\n"); 789} 790 791/* 792 * D D B E _ i n i t _ o f f s e t _ v e c 793 * 794 * Spells an uninitialized definition of the offset vector and a routine 795 * IDL_init_offset_vec which must be called once per interface to initialize 796 * the offset vector. Alternative to using DDBE_spell_offset_vec_use_inst. 797 */ 798void DDBE_init_offset_vec 799( 800 FILE *fid, /* [in] output file handle */ 801 DDBE_vectors_t *vip, /* [in] vector information pointer */ 802 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 803 void **cmd_val ATTRIBUTE_UNUSED /* [in] array of cmd option values */ 804) 805{ 806 DDBE_vec_rep_t *vec_p; /* Ptr to offset vector entry list */ 807 AST_type_n_t *type_p; /* Ptr to AST type node */ 808 unsigned long last_index; /* Last index spelled */ 809 char const *inst_name; /* Name of generated instance of type */ 810#ifdef DUMPERS 811 char const *comment; /* Comment text */ 812#endif 813 814 vec_p = vip->offset_p; 815 inst_name = NULL; 816 817 fprintf(fid, "static idl_ulong_int %soffset_vec[%s];\n\n", 818 DDBE_PREFIX_IDL, DDBE_spell_long_nf(vip->offset_vec_size)); 819 820 fprintf(fid, "static void %sinit_offset_vec\n", DDBE_PREFIX_IDL); 821 fprintf(fid, "(void)\n"); 822 fprintf(fid, "{\n"); 823 824 fprintf(fid, "%soffset_vec[%s] = 0;", DDBE_PREFIX_IDL, DDBE_spell_long(0)); 825 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 826 fprintf(fid, "\n"); 827 last_index = 0; 828 829 while (vec_p != NULL) 830 { 831 type_p = vec_p->val.type_p; 832 833 switch (vec_p->kind) 834 { 835 case DDBE_vec_comment_k: 836 DDBE_SPELL_COMMENT(fid, vec_p->comment, "/*\n * %s\n */\n", comment); 837 break; 838 839 case DDBE_vec_expr_long_k: 840 { 841 /* Simple expression for long value */ 842 char const *long_expr; 843 844 STRTAB_str_to_string(vec_p->val.expr, &long_expr); 845 fprintf(fid, "%soffset_vec[%s] = ", DDBE_PREFIX_IDL, 846 DDBE_spell_long(vec_p->index)); 847 fprintf(fid, "%s;", long_expr); 848 last_index = vec_p->index; 849 850 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 851 fprintf(fid, "\n"); 852 break; 853 } 854 855 case DDBE_vec_sizeof_k: 856 fprintf(fid, "%soffset_vec[%s] = ", DDBE_PREFIX_IDL, 857 DDBE_spell_long(vec_p->index)); 858 DDBE_sizeof_expr_use_inst(fid, type_p, vec_p->comment); 859 fprintf(fid, ";\n"); 860 last_index = vec_p->index; 861 break; 862 863 case DDBE_vec_noop_k: 864 break; 865 866 case DDBE_vec_offset_end_k: 867 inst_name = NULL; 868 break; 869 870 case DDBE_vec_offset_begin_k: 871 /* Form instance name for struct */ 872 NAMETABLE_id_to_string(type_p->be_info.dd_type->inst_name, 873 &inst_name); 874 break; 875 876 case DDBE_vec_expr_k: 877 case DDBE_vec_expr_arr_k: 878 { 879 /* 880 * field offset: &inst.field-expr - &inst 881 */ 882 char const *field_expr; 883 884 STRTAB_str_to_string(vec_p->val.expr, &field_expr); 885 fprintf(fid, "%soffset_vec[%s] = ", DDBE_PREFIX_IDL, 886 DDBE_spell_long(vec_p->index)); 887 fprintf(fid, "(idl_byte *)%s%s.%s - (idl_byte *)&%s;", 888 (vec_p->kind == DDBE_vec_expr_arr_k) ? "" : "&", 889 inst_name, field_expr, inst_name); 890 last_index = vec_p->index; 891 892 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 893 fprintf(fid, "\n"); 894 break; 895 } 896 897 default: 898 INTERNAL_ERROR("Invalid offset vector entry kind"); 899 } 900 901 vec_p = vec_p->next; 902 } 903 904 fprintf(fid, "%soffset_vec[%s] = 0;", DDBE_PREFIX_IDL, 905 DDBE_spell_long(last_index+1)); 906 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 907 fprintf(fid, "\n}\n\n"); 908} 909 910/* 911 * D D B E _ s p e l l _ r t n _ v e c 912 * 913 * Spells the routine vector definition. 914 */ 915void DDBE_spell_rtn_vec 916( 917 FILE *fid, /* [in] output file handle */ 918 DDBE_vectors_t *vip, /* [in] vector information pointer */ 919 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 920 void **cmd_val ATTRIBUTE_UNUSED, /* [in] array of cmd option values */ 921 boolean client_side /* [in] T=>client only, F=>server only */ 922) 923{ 924 DDBE_vec_rep_t *vec_p; /* Ptr to routine vector entry list */ 925 char const *rtn_name; 926#ifdef DUMPERS 927 char const *comment; 928#endif 929 930 vec_p = vip->rtn_p; 931 932 fprintf(fid, "static IDL_rtn_func_t %srtn_vec[] = {\n", DDBE_PREFIX_IDL); 933 fprintf(fid, "(IDL_rtn_func_t)NULL,"); 934 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 935 fprintf(fid, "\n"); 936 937 for ( ; vec_p != NULL; vec_p = vec_p->next) 938 { 939 if (vec_p->kind == DDBE_vec_noop_k) 940 continue; 941 if (vec_p->kind == DDBE_vec_comment_k) 942 { 943 DDBE_SPELL_COMMENT(fid, vec_p->comment, "/* %s */\n", comment); 944 continue; 945 } 946 947 NAMETABLE_id_to_string(vec_p->val.name, &rtn_name); 948 DDBE_SPELL_INDEX(fid, vec_p->index); 949 if ( (vec_p->kind == DDBE_vec_name_client_k && !client_side) 950 || (vec_p->kind == DDBE_vec_name_server_k && client_side) ) 951 fprintf(fid, "(IDL_rtn_func_t)NULL,\n"); 952 else 953 fprintf(fid, "(IDL_rtn_func_t)%s,\n", rtn_name); 954 } 955 956 fprintf(fid, "(IDL_rtn_func_t)NULL"); 957 DDBE_SPELL_TEXT(fid, "\t/* sentinel */"); 958 fprintf(fid, "\n};\n\n"); 959} 960 961/* 962 * D D B E _ s p e l l _ t y p e _ v e c _ p r e a m b l e 963 * 964 * Spells the preamble portion of the type vector definition. 965 * Assumes: vip->type_vec_size is offset to addenda portion of type vector. 966 */ 967void DDBE_spell_type_vec_preamble 968( 969 FILE *fid, /* [in] output file handle */ 970 DDBE_vectors_t *vip /* [in] vector information pointer */ 971) 972{ 973 AST_interface_n_t *int_p; /* Ptr to AST interface node */ 974 AST_export_n_t *export_p; /* Ptr to AST export node */ 975 AST_operation_n_t *oper_p; /* Ptr to AST operation node */ 976 char const *int_name; /* Interface name */ 977 char const *oper_name; /* Operation name */ 978 byte *bp; /* Pointer to byte stream */ 979 char *getenvres; /* Environment variable translation */ 980 unsigned long index; /* Type vector index */ 981 unsigned long longint; /* 4-byte integer data */ 982 unsigned short shortint; /* 2-byte integer data */ 983 boolean spell_stg_info; /* TRUE => spell storage information list */ 984 985 int_p = vip->ast_int_p; 986 NAMETABLE_id_to_string(int_p->name, &int_name); 987 988 getenvres = getenv("IDL_GEN_INTF_DATA"); 989 spell_stg_info = (getenvres != NULL); 990 991 /* 992 * NOTE: Currently assume ASCII encodings. 993 */ 994 DDBE_SPELL_INDEX(fid, 0); 995 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 996 997 DDBE_SPELL_INDEX(fid, 4); 998 if (DDBE_little_endian){ 999 fprintf(fid, "1,"); 1000 DDBE_SPELL_TEXT(fid, "\t\t/* little endian */"); 1001 } 1002 else{ 1003 fprintf(fid, "0,"); 1004 DDBE_SPELL_TEXT(fid, "\t\t/* big endian */"); 1005 } 1006 fprintf(fid, "\n"); 1007 1008 DDBE_SPELL_INDEX(fid, 5); 1009 fprintf(fid, "0,"); 1010 DDBE_SPELL_TEXT(fid, "\t\t/* ASCII */"); 1011 fprintf(fid, "\n"); 1012 1013 DDBE_SPELL_INDEX(fid, 6); 1014 fprintf(fid, "0xff,0xff,\n"); 1015 1016 shortint = DDBE_VER_MAJOR; 1017 DDBE_SPELL_INDEX(fid, 8); 1018 DDBE_spell_short_bytes(fid, &shortint, DDBE_little_endian); 1019 DDBE_SPELL_TEXT_1ARG(fid, "\t/* interpreter encoding major version %d */", 1020 shortint); 1021 fprintf(fid, "\n"); 1022 1023 shortint = DDBE_VER_MINOR; 1024 DDBE_SPELL_INDEX(fid, 10); 1025 DDBE_spell_short_bytes(fid, &shortint, DDBE_little_endian); 1026 DDBE_SPELL_TEXT_1ARG(fid, "\t/* interpreter encoding minor version %d */", 1027 shortint); 1028 fprintf(fid, "\n"); 1029 1030 shortint = int_p->version % 65536; 1031 DDBE_SPELL_INDEX(fid, 12); 1032 DDBE_spell_short_bytes(fid, &shortint, DDBE_little_endian); 1033 DDBE_SPELL_TEXT_2ARG(fid, "\t/* interface %s major version %d */", 1034 int_name, shortint); 1035 fprintf(fid, "\n"); 1036 1037 shortint = int_p->version / 65536; 1038 DDBE_SPELL_INDEX(fid, 14); 1039 DDBE_spell_short_bytes(fid, &shortint, DDBE_little_endian); 1040 DDBE_SPELL_TEXT_2ARG(fid, "\t/* interface %s minor version %d */", 1041 int_name, shortint); 1042 fprintf(fid, "\n"); 1043 1044 longint = int_p->uuid.time_low; 1045 DDBE_SPELL_INDEX(fid, 16); 1046 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1047 DDBE_SPELL_TEXT(fid, "\t/* uuid time_low */"); 1048 fprintf(fid, "\n"); 1049 1050 shortint = int_p->uuid.time_mid; 1051 DDBE_SPELL_INDEX(fid, 20); 1052 DDBE_spell_short_bytes(fid, &shortint, DDBE_little_endian); 1053 DDBE_SPELL_TEXT(fid, "\t/* uuid time_mid */"); 1054 fprintf(fid, "\n"); 1055 1056 shortint = int_p->uuid.time_hi_and_version; 1057 DDBE_SPELL_INDEX(fid, 22); 1058 DDBE_spell_short_bytes(fid, &shortint, DDBE_little_endian); 1059 DDBE_SPELL_TEXT(fid, "\t/* uuid time_hi_and_version */"); 1060 fprintf(fid, "\n"); 1061 1062 DDBE_SPELL_INDEX(fid, 24); 1063 fprintf(fid, "0x%02x,", int_p->uuid.clock_seq_hi_and_reserved); 1064 DDBE_SPELL_TEXT(fid, "\t\t/* uuid clock_seq_hi_and_reserved */"); 1065 fprintf(fid, "\n"); 1066 1067 DDBE_SPELL_INDEX(fid, 25); 1068 fprintf(fid, "0x%02x,", int_p->uuid.clock_seq_low); 1069 DDBE_SPELL_TEXT(fid, "\t\t/* uuid clock_seq_low */"); 1070 fprintf(fid, "\n"); 1071 1072 bp = int_p->uuid.node; 1073 DDBE_SPELL_INDEX(fid, 26); 1074 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,", 1075 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5]); 1076 DDBE_SPELL_TEXT(fid, "\t/* uuid node */"); 1077 fprintf(fid, "\n"); 1078 1079 DDBE_SPELL_INDEX(fid, 32); 1080 if (spell_stg_info) 1081 { 1082 /* Assume storage info immediately follows bugs list */ 1083 longint = vip->type_vec_size + (NUM_BUGS/32 + 1) * 4; 1084 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1085 DDBE_SPELL_TEXT_1ARG(fid, "\t/* index of storage information = %s */", 1086 DDBE_spell_long_nf(longint)); 1087 } 1088 else 1089 { 1090 fprintf(fid, "0x00,0x00,0x00,0x00,"); 1091 DDBE_SPELL_TEXT(fid, "\t/* no storage information */"); 1092 } 1093 fprintf(fid, "\n"); 1094 1095 longint = NUM_BUGS; 1096 DDBE_SPELL_INDEX(fid, 36); 1097 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1098 DDBE_SPELL_TEXT_1ARG(fid, "\t/* number of bug flags = %ld */", longint); 1099 fprintf(fid, "\n"); 1100 1101 longint = vip->type_vec_size; 1102 DDBE_SPELL_INDEX(fid, 40); 1103 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1104 DDBE_SPELL_TEXT_1ARG(fid, "\t/* index of bug flags = %s */", 1105 DDBE_spell_long_nf(longint)); 1106 fprintf(fid, "\n"); 1107 1108 DDBE_SPELL_INDEX(fid, 44); 1109 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 1110 1111 DDBE_SPELL_INDEX(fid, 48); 1112 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 1113 1114 DDBE_SPELL_INDEX(fid, 52); 1115 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 1116 1117 DDBE_SPELL_INDEX(fid, 56); 1118 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 1119 1120 longint = int_p->op_count; 1121 DDBE_SPELL_INDEX(fid, 60); 1122 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1123 DDBE_SPELL_TEXT_1ARG(fid, "\t/* number of operations = %ld */", longint); 1124 fprintf(fid, "\n"); 1125 1126 index = DDBE_PARAM_START; 1127 ASSERTION(DDBE_PARAM_START == 64); 1128 1129 /* 1130 * Process each operation in the interface. 1131 */ 1132 for (export_p = int_p->exports; export_p != NULL; export_p = export_p->next) 1133 { 1134 if (export_p->kind == AST_operation_k) 1135 { 1136 oper_p = export_p->thing_p.exported_operation; 1137 NAMETABLE_id_to_string(oper_p->name, &oper_name); 1138 1139 DDBE_SPELL_INDEX(fid, index); 1140 longint = 0; 1141 /* 1142 * The following code assumes these definitions in rpcbase.idl: 1143 * const long rpc_c_call_brdcst = 0x00000001; 1144 * const long rpc_c_call_idempotent = 0x00000002; 1145 * const long rpc_c_call_maybe = 0x00000004; 1146 */ 1147 if (AST_BROADCAST_SET(oper_p)) longint |= 1; 1148 if (AST_IDEMPOTENT_SET(oper_p)) longint |= 2; 1149 if (AST_MAYBE_SET(oper_p)) longint |= 4; 1150 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1151 DDBE_SPELL_TEXT_1ARG(fid, "\t/* operation %s flags */", oper_name); 1152 fprintf(fid, "\n"); 1153 index += 4; /* 4 = sizeof(idl_long) */ 1154 1155 longint = oper_p->be_info.dd_oper->num_params; 1156 DDBE_SPELL_INDEX(fid, index); 1157 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1158 DDBE_SPELL_TEXT_2ARG(fid, "\t/* number of %s params = %ld */", 1159 oper_name, longint); 1160 fprintf(fid, "\n"); 1161 index += 4; /* 4 = sizeof(idl_long) */ 1162 1163 longint = oper_p->be_info.dd_oper->num_srv_ins; 1164 DDBE_SPELL_INDEX(fid, index); 1165 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1166 DDBE_SPELL_TEXT_2ARG(fid, "\t/* number of %s [in]s = %ld */", 1167 oper_name, longint); 1168 fprintf(fid, "\n"); 1169 index += 4; /* 4 = sizeof(idl_long) */ 1170 1171 if (oper_p->be_info.dd_oper->ins_type_vec_p == NULL) 1172 { 1173 DDBE_SPELL_INDEX(fid, index); 1174 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 1175 } 1176 else 1177 { 1178 longint = oper_p->be_info.dd_oper->ins_type_vec_p->index; 1179 DDBE_SPELL_INDEX(fid, index); 1180 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1181 DDBE_SPELL_TEXT_2ARG(fid, "\t/* index of %s [in]s = %s */", 1182 oper_name, DDBE_spell_long_nf(longint)); 1183 fprintf(fid, "\n"); 1184 } 1185 index += 4; /* 4 = sizeof(idl_long) */ 1186 1187 longint = oper_p->be_info.dd_oper->num_outs; 1188 DDBE_SPELL_INDEX(fid, index); 1189 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1190 DDBE_SPELL_TEXT_2ARG(fid, "\t/* number of %s [out]s = %ld */", 1191 oper_name, longint); 1192 fprintf(fid, "\n"); 1193 index += 4; /* 4 = sizeof(idl_long) */ 1194 1195 if (oper_p->be_info.dd_oper->outs_type_vec_p == NULL) 1196 { 1197 DDBE_SPELL_INDEX(fid, index); 1198 fprintf(fid, "0xff,0xff,0xff,0xff,\n"); 1199 } 1200 else 1201 { 1202 longint = oper_p->be_info.dd_oper->outs_type_vec_p->index; 1203 DDBE_SPELL_INDEX(fid, index); 1204 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1205 DDBE_SPELL_TEXT_2ARG(fid, "\t/* index of %s [out]s = %s */", 1206 oper_name, DDBE_spell_long_nf(longint)); 1207 fprintf(fid, "\n"); 1208 } 1209 index += 4; /* 4 = sizeof(idl_long) */ 1210 } 1211 } 1212} 1213 1214/* 1215 * D D B E _ s p e l l _ t y p e _ v e c _ a d d e n d a 1216 * 1217 * Spells the addenda portion of the type vector definition. 1218 * Assumes: vip->type_vec_size does not include the addenda on entry, 1219 * but does include alignment pad bytes before the addenda. 1220 * vip->type_vec_size does include the addenda on exit. 1221 */ 1222void DDBE_spell_type_vec_addenda 1223( 1224 FILE *fid, /* [in] output file handle */ 1225 DDBE_vectors_t *vip, /* [io] vector information pointer */ 1226 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 1227 void **cmd_val /* [in] array of cmd option values */ 1228) 1229{ 1230 unsigned long size,index,longint; /* 4-byte integer data */ 1231 byte *p4; /* Pointer to 4-byte integer */ 1232 boolean *do_bug; /* Pointer to array of bug flags */ 1233 char *getenvres; /* Environment variable translation */ 1234 DDBE_vec_rep_t *vec_p; /* Ptr to vector entry in list */ 1235 int bugnum; /* Current bug number being processed */ 1236 int i, j; 1237 boolean spell_stg_info; /* TRUE => spell storage information list */ 1238 1239 p4 = (byte *)&longint; 1240 1241 /* 1242 * Process bugs flags. Bug numbers start at 1, bug 0 value is a don't-care. 1243 */ 1244 do_bug = (boolean *)cmd_val[opt_do_bug]; 1245 index = vip->type_vec_size; 1246 bugnum = 0; 1247 for (i = 0; i <= NUM_BUGS/32; i++) 1248 { 1249 longint = 0; 1250 for (j = 0; j < 32 && bugnum <= NUM_BUGS; j++) 1251 { 1252 if (do_bug[bugnum]) 1253 longint |= (1 << j); 1254 bugnum++; 1255 } 1256 DDBE_SPELL_INDEX(fid, index); 1257 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,",p4[0], p4[1], p4[2], p4[3]); 1258 DDBE_SPELL_TEXT(fid, "\t/* bug flags */"); 1259 fprintf(fid, "\n"); 1260 index += 4; 1261 } 1262 1263 /* 1264 * Process storage information. 1265 */ 1266 getenvres = getenv("IDL_GEN_INTF_DATA"); 1267 spell_stg_info = (getenvres != NULL); 1268 if (!spell_stg_info) 1269 return; 1270 1271 /* Count type information entries; note guaranteed sentinel entry at head */ 1272 for (i = 0, vec_p = vip->type_info_p->next; 1273 vec_p != NULL; 1274 i++, vec_p = vec_p->next) 1275 ; 1276 1277 /* 1278 * Compute size of type vector and do initial information entries: 1279 * total size (in bytes) of type vector 1280 * total size (in idl_ulong_ints) of offset vector 1281 * total size (in pointer-sized words) of routine vector 1282 * number of 'offset types' 1283 * index of 'offset types' 1284 */ 1285 size = index + 20 /*5 entries above*/ + i*4 /*offset types list*/ 1286 + 1 /* single byte sentinel entry */; 1287 1288 longint = size; 1289 DDBE_SPELL_INDEX(fid, index); 1290 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,",p4[0], p4[1], p4[2], p4[3]); 1291 DDBE_SPELL_TEXT_1ARG(fid, "\t/* type vector size = %s */", 1292 DDBE_spell_long_nf(longint)); 1293 fprintf(fid, "\n"); 1294 index += 4; 1295 1296 longint = vip->offset_vec_size; 1297 DDBE_SPELL_INDEX(fid, index); 1298 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,",p4[0], p4[1], p4[2], p4[3]); 1299 DDBE_SPELL_TEXT_1ARG(fid, "\t/* offset vector size = %s */", 1300 DDBE_spell_long_nf(longint)); 1301 fprintf(fid, "\n"); 1302 index += 4; 1303 1304 longint = vip->rtn_vec_size; 1305 DDBE_SPELL_INDEX(fid, index); 1306 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,",p4[0], p4[1], p4[2], p4[3]); 1307 DDBE_SPELL_TEXT_1ARG(fid, "\t/* routine vector size = %s */", 1308 DDBE_spell_long_nf(longint)); 1309 fprintf(fid, "\n"); 1310 index += 4; 1311 1312 longint = i; 1313 DDBE_SPELL_INDEX(fid, index); 1314 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,",p4[0], p4[1], p4[2], p4[3]); 1315 DDBE_SPELL_TEXT_1ARG(fid, "\t/* number of offset types = %ld */", longint); 1316 fprintf(fid, "\n"); 1317 index += 4; 1318 1319 longint = index + 4; /* offset types list immediately follows this word */ 1320 DDBE_SPELL_INDEX(fid, index); 1321 fprintf(fid, "0x%02x,0x%02x,0x%02x,0x%02x,",p4[0], p4[1], p4[2], p4[3]); 1322 DDBE_SPELL_TEXT_1ARG(fid, "\t/* index of offset types = %s */", 1323 DDBE_spell_long_nf(longint)); 1324 fprintf(fid, "\n"); 1325 index += 4; 1326 1327 /* Walk type information list; note guaranteed sentinel entry at head */ 1328 for (vec_p = vip->type_info_p->next; vec_p != NULL; vec_p = vec_p->next) 1329 { 1330 DDBE_SPELL_INDEX(fid, index); 1331 longint = vec_p->val.ref_p->index; 1332 DDBE_spell_long_bytes(fid, &longint, DDBE_little_endian); 1333 DDBE_SPELL_TEXT_1ARG(fid, "\t/* %s */", DDBE_spell_long(longint)); 1334 fprintf(fid, "\n"); 1335 index += 4; 1336 } 1337 1338 vip->type_vec_size = size; 1339} 1340 1341/* 1342 * D D B E _ s p e l l _ t y p e _ v e c 1343 * 1344 * Spells the type vector definition. 1345 */ 1346void DDBE_spell_type_vec 1347( 1348 FILE *fid, /* [in] output file handle */ 1349 DDBE_vectors_t *vip, /* [in] vector information pointer */ 1350 boolean *cmd_opt, /* [in] array of cmd option flags */ 1351 void **cmd_val /* [in] array of cmd option values */ 1352) 1353{ 1354 DDBE_vec_rep_t *vec_p; /* Ptr to type vector entry list */ 1355 char const *name; 1356 char const *expr; 1357#ifdef DUMPERS 1358 char const *comment; 1359#endif 1360 int i; 1361 1362 vec_p = vip->type_p; 1363 1364 fprintf(fid, "static idl_byte %stype_vec[] = {\n", DDBE_PREFIX_IDL); 1365 DDBE_spell_type_vec_preamble(fid, vip); 1366 1367 while (vec_p != NULL) 1368 { 1369 switch (vec_p->kind) 1370 { 1371 case DDBE_vec_byte_k: 1372 case DDBE_vec_byte_3m4_k: 1373 DDBE_SPELL_INDEX(fid, vec_p->index); 1374 fprintf(fid, "%d,", vec_p->val.byte_val); 1375 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 1376 fprintf(fid, "\n"); 1377 break; 1378 1379 case DDBE_vec_comment_k: 1380 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t\t/* %s */\n", comment); 1381 break; 1382 1383 case DDBE_vec_expr_byte_k: 1384 STRTAB_str_to_string(vec_p->val.expr, &expr); 1385 DDBE_SPELL_INDEX(fid, vec_p->index); 1386 fprintf(fid, "%s,", expr); 1387 DDBE_SPELL_COMMENT(fid, vec_p->comment, "\t/* %s */", comment); 1388 fprintf(fid, "\n"); 1389 break; 1390 1391 case DDBE_vec_long_k: 1392 DDBE_SPELL_INDEX(fid, vec_p->index); 1393 DDBE_spell_long_val(fid, vec_p, DDBE_little_endian); 1394 break; 1395 1396 case DDBE_vec_long_bool_k: 1397 DDBE_SPELL_INDEX(fid, vec_p->index); 1398 DDBE_spell_long_bool_val(fid, vec_p, DDBE_little_endian); 1399 break; 1400 1401 case DDBE_vec_noop_k: 1402 break; 1403 1404 case DDBE_vec_pad_k: 1405 /* 1406 * A pad entry says to pad the vector with a number of filler bytes. 1407 * Spell out the proper number of filler bytes. 1408 */ 1409 DDBE_SPELL_INDEX(fid, vec_p->index); 1410 for (i = 0; i < vec_p->val.byte_val; i++) 1411 fprintf(fid, "0xff,"); 1412 DDBE_SPELL_TEXT(fid, "\t/* filler */"); 1413 fprintf(fid, "\n"); 1414 break; 1415 case DDBE_vec_short_k: 1416 DDBE_SPELL_INDEX(fid, vec_p->index); 1417 DDBE_spell_short_bytes(fid, (unsigned short *)&vec_p->val.short_val, 1418 DDBE_little_endian); 1419 fprintf(fid, "\n"); 1420 break; 1421 1422 case DDBE_vec_tag_k: 1423 DDBE_SPELL_INDEX(fid, vec_p->index); 1424 NAMETABLE_id_to_string(vec_p->val.name, &name); 1425 fprintf(fid, "%s,\n", name); 1426 break; 1427 1428 case DDBE_vec_type_kind_k: 1429 DDBE_SPELL_INDEX(fid, vec_p->index); 1430 DDBE_spell_type_kind(fid, vec_p); 1431 break; 1432 1433 case DDBE_vec_expr_arr_k: 1434 case DDBE_vec_expr_k: 1435 case DDBE_vec_name_k: 1436 case DDBE_vec_name_client_k: 1437 case DDBE_vec_name_server_k: 1438 case DDBE_vec_offset_begin_k: 1439 case DDBE_vec_offset_end_k: 1440 case DDBE_vec_sizeof_k: 1441 INTERNAL_ERROR("Vector entry not valid for type vector"); 1442 1443 case DDBE_vec_indirect_k: 1444 case DDBE_vec_reference_k: 1445 INTERNAL_ERROR("Unexpected indirect type vector entry"); 1446 1447 default: 1448 INTERNAL_ERROR("Invalid type vector entry"); 1449 } 1450 1451 vec_p = vec_p->next; 1452 } 1453 1454 DDBE_spell_type_vec_addenda(fid, vip, cmd_opt, cmd_val); 1455 1456 fprintf(fid, "0"); 1457 DDBE_SPELL_TEXT(fid, "\t\t/* sentinel */"); 1458 fprintf(fid, "\n};\n\n"); 1459} 1460 1461/* 1462 * D D B E _ s p e l l _ p a r a m _ v e c _ d e f 1463 * 1464 * Spell the definition of the parameter vector for an operation. 1465 */ 1466void DDBE_spell_param_vec_def 1467( 1468 FILE *fid, /* [in] output file handle */ 1469 AST_operation_n_t *oper_p, /* [in] ptr to AST operation node */ 1470 BE_side_t side, /* [in] client or server side code */ 1471 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 1472 void **cmd_val ATTRIBUTE_UNUSED /* [in] array of cmd option values */ 1473) 1474{ 1475 DDBE_oper_i_t *oper_i_p; /* Ptr to operation info node */ 1476 AST_parameter_n_t *param_p; /* Ptr to AST parameter node */ 1477 unsigned long param_num; /* Parameter number */ 1478 char const *param_name; /* Parameter name */ 1479 1480 oper_i_p = oper_p->be_info.dd_oper; 1481 1482 fprintf(fid, "rpc_void_p_t %sparam_vec[%ld];\n", DDBE_PREFIX_IDL, 1483 oper_i_p->num_params); 1484 /* 1485 * Any idl_short_float passed by value needs an idl_short_float stacklocal 1486 * on the client side which is assigned the parameter value in case the 1487 * parameter was promoted to an idl_long_float. 1488 */ 1489 if (side == BE_client_side) 1490 { 1491 for (param_num = 1, param_p = oper_p->parameters; 1492 param_p != NULL; 1493 param_num++, param_p = param_p->next) 1494 { 1495 if (param_p->type->kind == AST_short_float_k) 1496 { 1497 NAMETABLE_id_to_string(param_p->name, ¶m_name); 1498 fprintf(fid, "idl_short_float IDL_short_float_%ld = %s;\n", 1499 param_num, param_name); 1500 } 1501 } 1502 } 1503} 1504 1505/* 1506 * D D B E _ s p e l l _ p a r a m _ v e c _ i n i t 1507 * 1508 * Spell the initialization of the parameter vector for an operation. 1509 */ 1510void DDBE_spell_param_vec_init 1511( 1512 FILE *fid, /* [in] output file handle */ 1513 AST_operation_n_t *oper_p, /* [in] ptr to AST operation node */ 1514 BE_side_t side, /* [in] client or server side code */ 1515 boolean *cmd_opt ATTRIBUTE_UNUSED, /* [in] array of cmd option flags */ 1516 void **cmd_val ATTRIBUTE_UNUSED /* [in] array of cmd option values */ 1517) 1518{ 1519 AST_parameter_n_t *param_p; /* Ptr to AST parameter node */ 1520 DDBE_oper_i_t *oper_i_p; /* Ptr to operation info node */ 1521 unsigned long param_num; /* Parameter number */ 1522 char const *param_name; /* Parameter name */ 1523 boolean spell_value; /* TRUE => spell param value not address */ 1524 1525 oper_i_p = oper_p->be_info.dd_oper; 1526 1527 /* Function result is stored in a local variable, unless we are using an 1528 additional parameter on the client side for a non-C language or the 1529 function result is 'char' on the client side and -lang fortran. */ 1530 if (oper_p->result->type->kind != AST_void_k) 1531 fprintf(fid, "%sparam_vec[0] = (rpc_void_p_t)%cIDL_function_result;\n", 1532 DDBE_PREFIX_IDL, 1533 ( 1534 false 1535 ) ? ' ' : '&' ); 1536 1537 for (param_num = 1, param_p = oper_p->parameters; 1538 param_p != NULL; 1539 param_num++, param_p = param_p->next) 1540 { 1541 /* 1542 * Server side conformant parameters that do not have a represent_as 1543 * type are allocated from heap elsewhere in the server stub routine 1544 * so no initialization is needed here. 1545 */ 1546 if (side == BE_server_side && AST_REF_SET(param_p) 1547 && DDBE_cfmt_arr_local_rep(param_p) ) 1548 continue; 1549 1550 NAMETABLE_id_to_string(param_p->name, ¶m_name); 1551 fprintf(fid, "%sparam_vec[%ld] = (rpc_void_p_t)", 1552 DDBE_PREFIX_IDL, param_num); 1553 1554 if (AST_HEAP_SET(param_p) && side == BE_server_side 1555 && !AST_PTR_SET(param_p) && !AST_UNIQUE_SET(param_p) 1556 ) 1557 { 1558 fprintf(fid, "rpc_ss_mem_alloc(&IDL_ms.IDL_mem_handle, sizeof"); 1559 if (param_p->type->kind == AST_pointer_k && AST_REF_SET(param_p)) 1560 CSPELL_cast_exp(fid, 1561 param_p->type->type_structure.pointer->pointee_type); 1562 else 1563 CSPELL_cast_exp(fid, param_p->type); 1564 fprintf(fid, ");\n"); 1565 } 1566 else if (param_p->type->kind == AST_short_float_k 1567 && side == BE_client_side) 1568 { 1569 fprintf(fid, "&IDL_short_float_%ld;\n", param_num); 1570 } 1571 else 1572 { 1573 spell_value = 1574 ( (side == BE_client_side 1575 && !(param_p->type->kind == AST_pointer_k 1576 && param_p->type->type_structure.pointer 1577 ->pointee_type->kind == AST_interface_k) 1578 && (AST_REF_SET(param_p) 1579 )) 1580 || (side == BE_server_side && AST_REF_SET(param_p) 1581 && (param_p->type->kind == AST_array_k 1582 || (param_p->type->kind == AST_pointer_k 1583 && param_p->type->type_structure.pointer 1584 ->pointee_type->kind == AST_array_k))) ); 1585 fprintf(fid, "%s%s;\n", (spell_value) ? "" : "&", param_name); 1586 } 1587 } 1588 1589 if (param_num != oper_i_p->num_params) 1590 { 1591 INTERNAL_ERROR("Param count does not match param vec allocation"); 1592 } 1593} 1594 1595/* 1596 * D D B E _ s p e l l _ m a r s h _ o r _ u n m a r 1597 * 1598 * Spells the code to marshall or unmarshall the parameters in an operation. 1599 */ 1600void DDBE_spell_marsh_or_unmar 1601( 1602 FILE *fid, /* [in] output file handle */ 1603 AST_operation_n_t *oper_p, /* [in] ptr to AST operation node */ 1604 const char *interp_name, /* [in] marshalling interpreter rtn name */ 1605 const char *state_ptr_name,/* [in] name of state pointer variable */ 1606 BE_side_t side, /* [in] client or server side code */ 1607 BE_marshalling_k_t mar_or_unmar /* [in] spell marshall or unmarshall code */ 1608) 1609{ 1610 DDBE_oper_i_t *oper_i_p; /* Ptr to operation info node */ 1611 boolean in_params; /* TRUE => processing [in] parameters */ 1612 1613 oper_i_p = oper_p->be_info.dd_oper; 1614 1615 in_params = ((side == BE_client_side && mar_or_unmar == BE_marshalling_k) 1616 || (side == BE_server_side && mar_or_unmar == BE_unmarshalling_k)); 1617 1618 /* Marshalling interpreter routine name */ 1619 fprintf(fid, "%s(", interp_name); 1620 1621 /* Number of parameters */ 1622 fprintf(fid, "\n %ld,", 1623 (in_params) ? ((side == BE_server_side) ? 1624 oper_i_p->num_srv_ins : oper_i_p->num_ins) 1625 : oper_i_p->num_outs); 1626 DDBE_SPELL_TEXT_1ARG(fid, "\t/* number of [%s] parameters */", 1627 ((in_params) ? "in" : "out")); 1628 1629 /* Type vector index of first param */ 1630 fprintf(fid, "\n %s,", 1631 (in_params) ? DDBE_spell_long_nf(oper_i_p->ins_type_index) 1632 : DDBE_spell_long_nf(oper_i_p->outs_type_index)); 1633 DDBE_SPELL_TEXT_1ARG(fid, 1634 "\t/* type vector index of first [%s] parameter */", 1635 ((in_params) ? "in" : "out")); 1636 1637 /* Param vector, marshalling state */ 1638 fprintf(fid, "\n IDL_param_vec, %s", state_ptr_name); 1639 1640 /* End of routine call */ 1641 fprintf(fid, ");\n"); 1642} 1643