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