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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1997-1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #include <stdio.h> 28 #include <string.h> 29 #include <limits.h> 30 #include <malloc.h> 31 #include "parser.h" 32 #include "trace.h" 33 #include "util.h" 34 #include "symtab.h" 35 #include "errlog.h" 36 37 /* Types */ 38 enum kind_t { PRIMITIVE = 0, COMPOSITE, VARARG }; 39 40 struct entry_t { 41 char *e_name; 42 int e_valid; 43 int e_line; 44 char *e_file; 45 int e_kind; /* PRIMITIVE, COMPOSITE... */ 46 char *e_type; /* where kind == PRIMITIVE */ 47 /* base type, ie. char if e_type is char */ 48 char *e_basetype; 49 int e_levels; /* levels of indirection */ 50 char *e_attribute; /* kind == COMPOSITE or VARARG. */ 51 char *e_assertion; /* reserved for kind == VARARG. */ 52 char *e_comment; /* reserved for per-element comments. */ 53 int e_pre_uses; 54 int e_post_uses; 55 }; 56 57 typedef struct entry_head_t { 58 int used; 59 int n_entries; 60 ENTRY entry[1]; /* Actually entry[n_entries]. */ 61 } EHEAD; 62 63 static struct symtab_t { 64 ENTRY *Function; 65 EHEAD *Args; 66 EHEAD *Varargs; 67 EHEAD *Globals; 68 ENTRY *Errval; 69 70 /* Includes */ 71 table_t *Includes; 72 73 /* Bindings */ 74 ENTRY *Exception; 75 76 /* Types */ 77 table_t *Print_Types; 78 79 /* Error-message information. */ 80 int Line; 81 char Filename[MAXLINE]; 82 83 /* Trace additions */ 84 char Prototype[MAXLINE]; 85 char Formals[MAXLINE]; 86 char Actuals[MAXLINE]; 87 char Cast[MAXLINE]; 88 int Nonreturn; 89 int Skip; 90 91 /* Adl additions */ 92 /* various assertions, one hopes */ 93 } Symtab; 94 95 /* File Globals. */ 96 static EHEAD *create_entry_table(int); 97 static EHEAD *add_entry_table(EHEAD *, 98 char *, int, char *, int, char *, char *, int, char *, int, int); 99 static ENTRY *get_entry_table(EHEAD *, int); 100 static EHEAD *free_entry_table(EHEAD *); 101 static void clear_entries(EHEAD *, int, int); 102 static ENTRY *allocate_entry(ENTRY *, char *, int, char *, int, 103 char *, char *, int, char *, int, int); 104 static ENTRY *set_entry(ENTRY *, 105 char *, int, char *, int, char *, char *, int, char *, int, int); 106 static ENTRY *free_entry(ENTRY *); 107 static void symtab_clear_varargs(void); 108 static void symtab_clear_globals(void); 109 static void symtab_clear_print_types(void); 110 static void symtab_set_nonreturn(int); 111 static table_t *symtab_free_print_types(table_t *); 112 113 /* 114 * symtab_new_function -- clear counts, variables for a new function. 115 */ 116 void 117 symtab_new_function(const int line, const char *file) 118 { 119 errlog(BEGIN, "symtab_new_function() {"); 120 Symtab.Line = line; /* Set, don't clear. */ 121 symtab_set_filename(file); 122 123 symtab_clear_function(); 124 symtab_clear_varargs(); 125 symtab_clear_globals(); 126 symtab_clear_errval(); 127 symtab_clear_exception(); 128 symtab_clear_print_types(); 129 130 symtab_set_nonreturn(NO); 131 symtab_set_skip(NO); 132 errlog(END, "}"); 133 } 134 135 136 /* 137 * symtab_clear_function -- clear function-prototype-derived 138 * values. Called on each prototype line and at beginning 139 * of interface. 140 */ 141 void 142 symtab_clear_function(void) 143 { 144 145 errlog(BEGIN, "symtab_clear_function() {"); 146 Symtab.Function = free_entry(Symtab.Function); 147 Symtab.Args = free_entry_table(Symtab.Args); 148 Symtab.Prototype[0] = '\0'; 149 Symtab.Formals[0] = '\0'; 150 Symtab.Actuals[0] = '\0'; 151 Symtab.Cast[0] = '\0'; 152 errlog(END, "}"); 153 } 154 155 156 /* 157 * symtab_clear_varargs -- called only at end 158 */ 159 static void 160 symtab_clear_varargs(void) 161 { 162 163 errlog(BEGIN, "symtab_clear_varargs() {"); 164 Symtab.Varargs = free_entry_table(Symtab.Varargs); 165 errlog(END, "}"); 166 } 167 168 /* 169 * symtab_clear_includes -- clear only at end of file (union++) 170 */ 171 void 172 symtab_clear_includes(void) 173 { 174 175 errlog(BEGIN, "symtab_clear_includes() {"); 176 Symtab.Includes = free_string_table(Symtab.Includes); 177 errlog(END, "}"); 178 } 179 180 static void 181 symtab_clear_globals(void) 182 { 183 184 errlog(BEGIN, "symtab_clear_globals() {"); 185 Symtab.Globals = free_entry_table(Symtab.Globals); 186 errlog(END, "}"); 187 } 188 189 void 190 symtab_clear_errval(void) 191 { 192 193 errlog(BEGIN, "symtab_clear_errval() {"); 194 Symtab.Errval = free_entry(Symtab.Errval); 195 errlog(END, "}"); 196 } 197 198 void 199 symtab_clear_exception(void) 200 { 201 202 errlog(BEGIN, "symtab_clear_exception() {"); 203 Symtab.Exception = free_entry(Symtab.Exception); 204 errlog(END, "}"); 205 } 206 207 static void 208 symtab_clear_print_types(void) 209 { 210 211 errlog(BEGIN, "symtab_clear_print_types() {"); 212 Symtab.Print_Types = symtab_free_print_types(Symtab.Print_Types); 213 errlog(END, "}"); 214 } 215 216 217 /* Generated by m4 -- character string values */ 218 219 void 220 symtab_set_prototype(char *p) 221 { 222 223 errlog(BEGIN, "symtab_set_prototype(void) {"); 224 (void) strncpy(Symtab.Prototype, p, sizeof (Symtab.Prototype)); 225 Symtab.Prototype[sizeof (Symtab.Prototype)-1] = '\0'; 226 errlog(END, "}"); 227 } 228 229 char * 230 symtab_get_prototype(void) 231 { 232 errlog(BEGIN, "symtab_get_prototype() {"); errlog(END, "}"); 233 return (Symtab.Prototype); 234 } 235 236 void 237 symtab_set_formals(char *p) 238 { 239 errlog(BEGIN, "symtab_set_formals() {"); 240 errlog(VERBOSE, "p = %s", p); 241 (void) strncpy(Symtab.Formals, p, sizeof (Symtab.Formals)); 242 Symtab.Formals[sizeof (Symtab.Formals)-1] = '\0'; 243 errlog(END, "}"); 244 } 245 246 char * 247 symtab_get_formals(void) 248 { 249 errlog(BEGIN, "symtab_get_formals() {"); errlog(END, "}"); 250 return (Symtab.Formals); 251 } 252 253 void 254 symtab_set_actuals(char *p) 255 { 256 errlog(BEGIN, "symtab_set_actuals() {"); errlog(END, "}"); 257 errlog(VERBOSE, "p = %s", p); 258 (void) strncpy(Symtab.Actuals, p, sizeof (Symtab.Actuals)); 259 Symtab.Actuals[sizeof (Symtab.Actuals)-1] = '\0'; 260 } 261 262 char * 263 symtab_get_actuals(void) 264 { 265 errlog(BEGIN, "symtab_get_actuals() {"); errlog(END, "}"); 266 return (Symtab.Actuals); 267 } 268 269 void 270 symtab_set_cast(char *p) 271 { 272 errlog(BEGIN, "symtab_set_cast() {"); errlog(END, "}"); 273 (void) strncpy(Symtab.Cast, p, sizeof (Symtab.Cast)); 274 Symtab.Cast[sizeof (Symtab.Cast)-1] = '\0'; 275 } 276 277 char * 278 symtab_get_cast(void) 279 { 280 errlog(BEGIN, "symtab_get_cast() {"); errlog(END, "}"); 281 return (Symtab.Cast); 282 } 283 284 285 void 286 symtab_set_filename(const char *p) 287 { 288 errlog(BEGIN, "symtab_set_filename() {"); errlog(END, "}"); 289 (void) strncpy(Symtab.Filename, p, sizeof (Symtab.Filename)); 290 Symtab.Filename[sizeof (Symtab.Filename)-1] = '\0'; 291 } 292 293 char * 294 symtab_get_filename(void) 295 { 296 errlog(BEGIN, "symtab_get_filename() {"); errlog(END, "}"); 297 return (Symtab.Filename); 298 } 299 300 301 /* Generated by m4 -- int values */ 302 303 static void 304 symtab_set_nonreturn(int val) 305 { 306 errlog(BEGIN, "symtab_set_nonreturn() {"); errlog(END, "}"); 307 Symtab.Nonreturn = val; 308 } 309 310 int 311 symtab_get_nonreturn(void) 312 { 313 errlog(BEGIN, "symtab_get_nonreturn() {"); errlog(END, "}"); 314 return (Symtab.Nonreturn); 315 } 316 317 void 318 symtab_set_line(int val) 319 { 320 errlog(BEGIN, "symtab_set_line() {"); errlog(END, "}"); 321 Symtab.Line = val; 322 } 323 324 int 325 symtab_get_line(void) 326 { 327 errlog(BEGIN, "symtab_get_line() {"); errlog(END, "}"); 328 return (Symtab.Line); 329 } 330 331 332 void 333 symtab_set_skip(int value) 334 { 335 errlog(BEGIN, "symtab_set_skip() {"); errlog(END, "}"); 336 Symtab.Skip = value; 337 } 338 339 int 340 symtab_get_skip(void) 341 { 342 errlog(BEGIN, "symtab_get_skip() {"); errlog(END, "}"); 343 return (Symtab.Skip); 344 } 345 346 /* 347 * Manually written access functions for ENTRY * variables. 348 */ 349 350 void 351 symtab_set_function(char *name, int line, char *file, 352 char *type, char *basetype, int levels) 353 { 354 355 errlog(BEGIN, "symtab_set_function() {"); 356 Symtab.Function = allocate_entry(Symtab.Function, 357 name, line, file, PRIMITIVE, type, basetype, levels, "", -1, -1); 358 errlog(END, "}"); 359 } 360 361 ENTRY * 362 symtab_get_function(void) 363 { 364 errlog(BEGIN, "symtab_get_function() {"); errlog(END, "}"); 365 if (Symtab.Function == NULL) 366 return (NULL); 367 else 368 return ((Symtab.Function->e_valid)? Symtab.Function: NULL); 369 } 370 371 void 372 symtab_set_exception(char *value, int line, char *file) 373 { 374 375 errlog(BEGIN, "symtab_set_exception() {"); 376 Symtab.Exception = allocate_entry(Symtab.Exception, 377 value, line, file, COMPOSITE, "", "", 0, "", -1, -1); 378 errlog(END, "}"); 379 } 380 381 ENTRY * 382 symtab_get_exception(void) 383 { 384 385 errlog(BEGIN, "symtab_get_exception() {"); errlog(END, "}"); 386 if (Symtab.Exception == NULL) 387 return (NULL); 388 else 389 return ((Symtab.Exception->e_valid)? Symtab.Exception: NULL); 390 } 391 392 void 393 symtab_set_errval(char *name, int line, char *file, char *type, char *basetype, 394 int levels) 395 { 396 397 errlog(BEGIN, "symtab_set_errval() {"); 398 Symtab.Errval = allocate_entry(Symtab.Errval, 399 name, line, file, PRIMITIVE, type, basetype, levels, 400 "", -1, -1); 401 errlog(END, "}"); 402 } 403 404 ENTRY * 405 symtab_get_errval(void) 406 { 407 408 errlog(BEGIN, "symtab_get_errval() {"); errlog(END, "}"); 409 if (Symtab.Errval == NULL) 410 return (NULL); 411 else 412 return ((Symtab.Errval->e_valid)? Symtab.Errval: NULL); 413 } 414 415 /* 416 * Manually written access function for tables of ENTRYs 417 */ 418 void 419 symtab_add_args(char *name, int line, char *file, 420 char *type, char *basetype, int levels) 421 { 422 423 errlog(BEGIN, "symtab_add_args() {"); 424 if (Symtab.Args == NULL) { 425 Symtab.Args = create_entry_table(10); 426 } 427 Symtab.Args = add_entry_table(Symtab.Args, 428 name, line, file, PRIMITIVE, type, basetype, levels, "", -1, -1); 429 errlog(END, "}"); 430 } 431 432 static int curr_arg; 433 434 ENTRY * 435 symtab_get_first_arg(void) 436 { 437 438 errlog(BEGIN, "symtab_get_first_arg() {"); errlog(END, "}"); 439 curr_arg = 1; 440 return (get_entry_table(Symtab.Args, 0)); 441 } 442 443 ENTRY * 444 symtab_get_next_arg(void) 445 { 446 447 errlog(BEGIN, "symtab_get_next_arg() {"); errlog(END, "}"); 448 return (get_entry_table(Symtab.Args, curr_arg++)); 449 } 450 451 ENTRY * 452 symtab_get_last_arg(void) 453 { 454 455 errlog(BEGIN, "symtab_get_last_arg() {"); errlog(END, "}"); 456 return (get_entry_table(Symtab.Args, Symtab.Args->used)); 457 } 458 459 void 460 symtab_add_varargs(char *name, int line, char *file, char *type, char *print) 461 { 462 463 errlog(BEGIN, "symtab_add_varargs() {"); 464 if (Symtab.Varargs == NULL) { 465 Symtab.Varargs = create_entry_table(10); 466 } 467 Symtab.Varargs = add_entry_table(Symtab.Varargs, 468 name, line, file, PRIMITIVE, type, print, 0, "", -1, -1); 469 errlog(END, "}"); 470 } 471 472 static int curr_vararg; 473 474 ENTRY * 475 symtab_get_first_vararg(void) 476 { 477 478 errlog(BEGIN, "symtab_get_first_vararg() {"); errlog(END, "}"); 479 curr_vararg = 1; 480 return (get_entry_table(Symtab.Varargs, 0)); 481 } 482 483 ENTRY * 484 symtab_get_next_vararg(void) 485 { 486 487 errlog(BEGIN, "symtab_get_next_vararg() {"); errlog(END, "}"); 488 return (get_entry_table(Symtab.Varargs, curr_vararg++)); 489 } 490 491 void 492 symtab_add_globals(char *name, int line, char *file, char *type, 493 char *basetype, int levels) 494 { 495 496 errlog(BEGIN, "symtab_add_globals() {"); 497 if (Symtab.Globals == NULL) { 498 Symtab.Globals = create_entry_table(10); 499 } 500 Symtab.Globals = add_entry_table(Symtab.Globals, 501 name, line, file, PRIMITIVE, type, basetype, levels, "", -1, -1); 502 errlog(END, "}"); 503 } 504 505 506 static int curr_global; 507 508 ENTRY * 509 symtab_get_first_global(void) 510 { 511 512 errlog(BEGIN, "symtab_get_first_global() {"); errlog(END, "}"); 513 curr_global = 1; 514 return (get_entry_table(Symtab.Globals, 0)); 515 } 516 517 ENTRY * 518 symtab_get_next_global(void) 519 { 520 521 errlog(BEGIN, "symtab_get_next_global() {"); errlog(END, "}"); 522 return (get_entry_table(Symtab.Globals, curr_global++)); 523 } 524 525 /* 526 * manually written functions for accessing tables of strings 527 */ 528 529 /* 530 * symtab_add_print_types -- add only non-void print types (due to 531 * parser errors in collect.c, yuck). Also note trick compare... 532 * TBD : common code in db, symtab needs to be 533 * pulled out, as they're getting out of sync. 534 */ 535 void 536 symtab_add_print_types(char *print_type, char *c_type) 537 { 538 char buffer[MAXLINE]; 539 540 errlog(BEGIN, "symtab_add_print_types() {"); 541 #ifdef notdef 542 if (strcmp(print_type, "void") == 0 || *print_type == NULL) { 543 errlog(END, "}"); 544 return; 545 } 546 #endif 547 (void) snprintf(buffer, sizeof (buffer), "%s, %s", print_type, c_type); 548 if (Symtab.Print_Types == NULL) { 549 Symtab.Print_Types = create_string_table(50); 550 } 551 if (in_string_table(Symtab.Print_Types, print_type) == NO) { 552 Symtab.Print_Types = add_string_table(Symtab.Print_Types, 553 &buffer[0]); 554 } 555 errlog(END, "}"); 556 } 557 558 static table_t * 559 symtab_free_print_types(table_t *t) 560 { 561 errlog(BEGIN, "symtab_free_print_types() {"); errlog(END, "}"); 562 return (free_string_table(t)); 563 } 564 565 566 static int curr_print_type; 567 568 char * 569 symtab_get_first_print_type(void) 570 { 571 572 errlog(BEGIN, "symtab_get_first_print_type() {"); errlog(END, "}"); 573 curr_print_type = 1; 574 return (get_string_table(Symtab.Print_Types, 0)); 575 } 576 577 char * 578 symtab_get_next_print_type(void) 579 { 580 581 errlog(BEGIN, "symtab_get_next_print_type() {"); errlog(END, "}"); 582 return (get_string_table(Symtab.Print_Types, curr_print_type++)); 583 } 584 585 void 586 symtab_add_includes(char *value) 587 { 588 589 errlog(BEGIN, "symtab_add_includes() {"); 590 if (Symtab.Includes == NULL) { 591 Symtab.Includes = create_string_table(50); 592 } 593 if (in_string_table(Symtab.Includes, value) == NO) { 594 Symtab.Includes = add_string_table(Symtab.Includes, value); 595 } 596 errlog(END, "}"); 597 } 598 599 static int curr_include; 600 601 char * 602 symtab_get_first_include(void) 603 { 604 605 errlog(BEGIN, "symtab_get_first_include() {"); errlog(END, "}"); 606 curr_include = 1; 607 return (get_string_table(Symtab.Includes, 0)); 608 } 609 610 char * 611 symtab_get_next_include(void) 612 { 613 614 errlog(BEGIN, "symtab_get_next_include() {"); errlog(END, "}"); 615 return (get_string_table(Symtab.Includes, curr_include++)); 616 } 617 618 619 void 620 symtab_sort_includes(void) 621 { 622 errlog(BEGIN, "symtab_sort_includes() {"); 623 sort_string_table(Symtab.Includes); 624 errlog(END, "}"); 625 } 626 627 /* 628 * ENTRYs -- access functions to contents of an entry. 629 */ 630 631 char * 632 name_of(ENTRY *e) 633 { 634 return (e->e_name); 635 } 636 637 int 638 validity_of(ENTRY *e) 639 { 640 641 if (e == NULL) 642 return (NO); 643 else 644 return (e->e_valid); 645 } 646 647 int 648 line_of(ENTRY *e) 649 { 650 return (e->e_line); 651 } 652 653 654 char * 655 file_of(ENTRY *e) 656 { 657 return (e->e_file); 658 } 659 660 /* 661 * x_type_of -- return (type with an extension: an embedded %s where 662 * the name goes. 663 */ 664 char * 665 x_type_of(ENTRY *e) 666 { 667 if (e != NULL && (e->e_kind == PRIMITIVE || e->e_kind == VARARG)) 668 return (e->e_type); 669 else 670 return (NULL); 671 } 672 673 674 /* 675 * type_of -- return (just the type, with the %s removed. This is the common 676 * case, and its also the slowest... TBD. 677 */ 678 char * 679 type_of(ENTRY *e) 680 { 681 static char buffer[MAXLINE]; 682 char *p, *q; 683 684 if (e != NULL && (e->e_kind == PRIMITIVE || e->e_kind == VARARG)) { 685 p = e->e_type; 686 q = &buffer[0]; 687 while (*p != '\0') { 688 if (*p == '%') { 689 p += 2; 690 } else { 691 *q++ = *p++; 692 } 693 } 694 *q = '\0'; 695 return (strtrim(&buffer[0])); 696 } 697 else 698 return (NULL); 699 } 700 701 char * 702 basetype_of(ENTRY *e) 703 { 704 if (e != NULL && (e->e_kind == PRIMITIVE || e->e_kind == VARARG)) 705 return (e->e_basetype); 706 else 707 return (NULL); 708 } 709 710 int 711 levels_of(ENTRY *e) 712 { 713 if (e != NULL && (e->e_kind == PRIMITIVE || e->e_kind == VARARG)) 714 return (e->e_levels); 715 else 716 return (0); 717 } 718 719 char * 720 inverse_of(ENTRY *e) 721 { 722 723 if (e != NULL && e->e_kind == COMPOSITE) 724 return (e->e_attribute); 725 else 726 return (NULL); 727 } 728 729 char * 730 selector_of(ENTRY *e) 731 { 732 733 if (e != NULL && e->e_kind == VARARG) 734 return (e->e_attribute); 735 else 736 return (NULL); 737 } 738 739 int 740 preuses_of(ENTRY *e) 741 { 742 743 if (e) 744 return (e->e_pre_uses); 745 else 746 return (-1); 747 } 748 749 int 750 postuses_of(ENTRY *e) 751 { 752 753 if (e) 754 return (e->e_post_uses); 755 else 756 return (-1); 757 } 758 759 760 /* 761 * allocate_entry -- make a parameter list into a complete 762 * ENTRY struct, allocated dynamically. 763 */ 764 /* ARGSUSED -- lint bug */ 765 static ENTRY * 766 allocate_entry(ENTRY *e, 767 char *name, int line, char *file, 768 int kind, char *type, char *basetype, int levels, char *attribute, 769 int npre, int npost) 770 { 771 772 errlog(BEGIN, "allocate_entry() {"); 773 if (e == NULL) { 774 if ((e = (ENTRY *)calloc(1, sizeof (ENTRY))) == NULL) { 775 errlog(FATAL, "can't allocate space for an ENTRY"); 776 } 777 } 778 errlog(END, "}"); 779 return (set_entry(e, name, line, file, kind, type, basetype, levels, 780 attribute, npre, npost)); 781 } 782 783 /* 784 * set_entry -- set a passed-in entry, using 785 * passed parameters, to values suitable for a 786 * symtab entry 787 */ 788 static ENTRY * 789 set_entry(ENTRY *e, 790 char *name, int line, char *file, 791 int kind, char *type, char *basetype, int levels, char *attribute, 792 int npre, int npost) 793 { 794 795 errlog(BEGIN, "set_entry() {"); 796 if (e == NULL) { 797 errlog(FATAL, "programmer error: passed a NULL ENTRY"); 798 } 799 e->e_name = strset(e->e_name, name); 800 e->e_valid = YES; 801 e->e_line = line, 802 e->e_file = strset(e->e_file, file); 803 e->e_kind = kind; 804 switch (kind) { 805 case PRIMITIVE: 806 e->e_type = strset(e->e_type, type); 807 e->e_basetype = strset(e->e_basetype, basetype); 808 e->e_levels = levels; 809 break; 810 case COMPOSITE: 811 e->e_attribute = strset(e->e_attribute, attribute); 812 break; 813 case VARARG: 814 e->e_attribute = strset(e->e_attribute, attribute); 815 break; 816 default: 817 errlog(FATAL, "programmer error: impossible kind of ENTRY"); 818 } 819 820 e->e_pre_uses = npre; 821 e->e_post_uses = npost; 822 errlog(END, "}"); 823 return (e); 824 } 825 826 827 /* 828 * free_entry -- really just mark an entry as invalid 829 */ 830 static ENTRY * 831 free_entry(ENTRY *e) 832 { 833 if (e != NULL) 834 e->e_valid = NO; 835 return (e); 836 } 837 838 839 /* 840 * ENTRY tables. 841 */ 842 #define ENTRY_INCREMENT 10 843 844 static EHEAD * 845 create_entry_table(int n) 846 { 847 EHEAD *p; 848 849 errlog(BEGIN, "create_entry_table() {"); 850 if ((p = (EHEAD *)calloc(1, 851 sizeof (EHEAD)+(n*sizeof (ENTRY)))) == NULL) { 852 errlog(FATAL, "can't allocate space for an ENTRY table"); 853 } 854 p->used = -1; 855 p->n_entries = n; 856 errlog(END, "}"); 857 return (p); 858 } 859 860 static EHEAD * 861 add_entry_table(EHEAD *t, char *name, int line, char *file, 862 int kind, char *type, char *basetype, int levels, char *attribute, 863 int npre, int npost) 864 { 865 EHEAD *t2; 866 867 errlog(BEGIN, "add_entry_table() {"); 868 if (t == NULL) { 869 errlog(FATAL, "programmer error: tried to add to NULL EHEAD"); 870 } 871 t->used++; 872 if (t->used >= t->n_entries) { 873 if ((t2 = (EHEAD *)realloc(t, 874 sizeof (EHEAD)+(sizeof (ENTRY)* 875 (t->n_entries+ENTRY_INCREMENT)))) == NULL) { 876 errlog(FATAL, "out of memory extending an EHEAD"); 877 } 878 t = t2; 879 clear_entries(t, t->n_entries, (t->n_entries+ENTRY_INCREMENT)); 880 t->n_entries += ENTRY_INCREMENT; 881 } 882 (void) set_entry(&t->entry[t->used], 883 name, line, file, kind, type, basetype, levels, 884 attribute, npre, npost); 885 errlog(END, "}"); 886 return (t); 887 } 888 889 static ENTRY * 890 get_entry_table(EHEAD *t, int index) 891 { 892 if (t == NULL) { 893 return (NULL); 894 } else if (index > t->used) { 895 return (NULL); 896 } else { 897 return (&(t->entry[index])); 898 } 899 } 900 901 static EHEAD * 902 free_entry_table(EHEAD *t) 903 { 904 if (t != NULL) 905 t->used = -1; 906 return (t); 907 } 908 909 static void 910 clear_entries(EHEAD *t, int start, int end) 911 { 912 int i; 913 914 for (i = start; i < end; i++) { 915 (void) memset(&t->entry[i], 0, sizeof (ENTRY)); 916 } 917 } 918