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
symtab_new_function(const int line,const char * file)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
symtab_clear_function(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
symtab_clear_varargs(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
symtab_clear_includes(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
symtab_clear_globals(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
symtab_clear_errval(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
symtab_clear_exception(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
symtab_clear_print_types(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
symtab_set_prototype(char * p)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 *
symtab_get_prototype(void)232 symtab_get_prototype(void)
233 {
234 errlog(BEGIN, "symtab_get_prototype() {"); errlog(END, "}");
235 return (Symtab.Prototype);
236 }
237
238 void
symtab_set_formals(char * p)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 *
symtab_get_formals(void)249 symtab_get_formals(void)
250 {
251 errlog(BEGIN, "symtab_get_formals() {"); errlog(END, "}");
252 return (Symtab.Formals);
253 }
254
255 void
symtab_set_actuals(char * p)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 *
symtab_get_actuals(void)265 symtab_get_actuals(void)
266 {
267 errlog(BEGIN, "symtab_get_actuals() {"); errlog(END, "}");
268 return (Symtab.Actuals);
269 }
270
271 void
symtab_set_cast(char * p)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 *
symtab_get_cast(void)280 symtab_get_cast(void)
281 {
282 errlog(BEGIN, "symtab_get_cast() {"); errlog(END, "}");
283 return (Symtab.Cast);
284 }
285
286
287 void
symtab_set_filename(const char * p)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 *
symtab_get_filename(void)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
symtab_set_nonreturn(int val)306 symtab_set_nonreturn(int val)
307 {
308 errlog(BEGIN, "symtab_set_nonreturn() {"); errlog(END, "}");
309 Symtab.Nonreturn = val;
310 }
311
312 int
symtab_get_nonreturn(void)313 symtab_get_nonreturn(void)
314 {
315 errlog(BEGIN, "symtab_get_nonreturn() {"); errlog(END, "}");
316 return (Symtab.Nonreturn);
317 }
318
319 void
symtab_set_line(int val)320 symtab_set_line(int val)
321 {
322 errlog(BEGIN, "symtab_set_line() {"); errlog(END, "}");
323 Symtab.Line = val;
324 }
325
326 int
symtab_get_line(void)327 symtab_get_line(void)
328 {
329 errlog(BEGIN, "symtab_get_line() {"); errlog(END, "}");
330 return (Symtab.Line);
331 }
332
333
334 void
symtab_set_skip(int value)335 symtab_set_skip(int value)
336 {
337 errlog(BEGIN, "symtab_set_skip() {"); errlog(END, "}");
338 Symtab.Skip = value;
339 }
340
341 int
symtab_get_skip(void)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
symtab_set_function(char * name,int line,char * file,char * type,char * basetype,int levels)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 *
symtab_get_function(void)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
symtab_set_exception(char * value,int line,char * file)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 *
symtab_get_exception(void)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
symtab_set_errval(char * name,int line,char * file,char * type,char * basetype,int levels)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 *
symtab_get_errval(void)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
symtab_add_args(char * name,int line,char * file,char * type,char * basetype,int levels)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 *
symtab_get_first_arg(void)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 *
symtab_get_next_arg(void)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 *
symtab_get_last_arg(void)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
symtab_add_varargs(char * name,int line,char * file,char * type,char * print)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 *
symtab_get_first_vararg(void)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 *
symtab_get_next_vararg(void)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
symtab_add_globals(char * name,int line,char * file,char * type,char * basetype,int levels)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 *
symtab_get_first_global(void)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 *
symtab_get_next_global(void)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
symtab_add_print_types(char * print_type,char * c_type)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 *
symtab_free_print_types(table_t * 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 *
symtab_get_first_print_type(void)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 *
symtab_get_next_print_type(void)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
symtab_add_includes(char * value)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 *
symtab_get_first_include(void)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 *
symtab_get_next_include(void)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
symtab_sort_includes(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 *
name_of(ENTRY * e)634 name_of(ENTRY *e)
635 {
636 return (e->e_name);
637 }
638
639 int
validity_of(ENTRY * e)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
line_of(ENTRY * e)650 line_of(ENTRY *e)
651 {
652 return (e->e_line);
653 }
654
655
656 char *
file_of(ENTRY * e)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 *
x_type_of(ENTRY * e)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 *
type_of(ENTRY * e)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 *
basetype_of(ENTRY * e)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
levels_of(ENTRY * e)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 *
inverse_of(ENTRY * e)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 *
selector_of(ENTRY * e)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
preuses_of(ENTRY * e)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
postuses_of(ENTRY * e)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 *
allocate_entry(ENTRY * e,char * name,int line,char * file,int kind,char * type,char * basetype,int levels,char * attribute,int npre,int npost)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 *
set_entry(ENTRY * e,char * name,int line,char * file,int kind,char * type,char * basetype,int levels,char * attribute,int npre,int npost)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 *
free_entry(ENTRY * e)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 *
create_entry_table(int n)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 *
add_entry_table(EHEAD * t,char * name,int line,char * file,int kind,char * type,char * basetype,int levels,char * attribute,int npre,int npost)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 *
get_entry_table(EHEAD * t,int index)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 *
free_entry_table(EHEAD * t)904 free_entry_table(EHEAD *t)
905 {
906 if (t != NULL)
907 t->used = -1;
908 return (t);
909 }
910
911 static void
clear_entries(EHEAD * t,int start,int end)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