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