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 1996-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <limits.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30
31 #include "stabs.h"
32
33 static struct tdesc *hash_table[BUCKETS];
34 static struct tdesc *name_table[BUCKETS];
35
36 static void reset(void);
37 static jmp_buf resetbuf;
38
39 static char *get_line(void);
40 static void parseline(char *cp);
41 static char *soudef(char *cp, enum type type, struct tdesc **rtdp);
42 static void enumdef(char *cp, struct tdesc **rtdp);
43 static int compute_sum(char *w);
44 static struct tdesc *lookup(int h);
45
46 static char *number(char *cp, int *n);
47 static char *name(char *cp, char **w);
48 static char *id(char *cp, int *h);
49 static char *offsize(char *cp, struct mlist *mlp);
50 static char *whitesp(char *cp);
51 static void addhash(struct tdesc *tdp, int num);
52 static void tagadd(char *w, int h, struct tdesc *tdp);
53 static void tagdecl(char *cp, struct tdesc **rtdp, int h, char *w);
54 static char *tdefdecl(char *cp, int h, struct tdesc **rtdp);
55 static char *intrinsic(char *cp, struct tdesc **rtdp);
56 static char *arraydef(char *cp, struct tdesc **rtdp);
57
58 static int line_number = 0;
59 static int debug_line = 0;
60 static char linebuf[MAXLINE];
61
62 extern int debug_level;
63
64 static void
debug(int level,char * cp,char * fmt,...)65 debug(int level, char *cp, char *fmt, ...)
66 {
67 va_list ap;
68 char buf[1024];
69 char tmp[32];
70 int i;
71
72 if (level > debug_level)
73 return;
74
75 if (cp != NULL) {
76 for (i = 0; i < 30; i++) {
77 if (cp[i] == '\0')
78 break;
79 if (!iscntrl(cp[i]))
80 tmp[i] = cp[i];
81 }
82 tmp[i] = '\0';
83 (void) snprintf(buf, sizeof (buf), "%s [cp='%s']\n", fmt, tmp);
84 } else {
85 (void) snprintf(buf, sizeof (buf), "%s\n", fmt);
86 }
87
88 va_start(ap, fmt);
89 (void) vfprintf(stderr, buf, ap);
90 va_end(ap);
91 }
92
93
94 /* Report unexpected syntax in stabs. */
95 static void
expected(char * who,char * what,char * where)96 expected(
97 char *who, /* what function, or part thereof, is reporting */
98 char *what, /* what was expected */
99 char *where) /* where we were in the line of input */
100 {
101 fprintf(stderr, "%s, input line %d: expecting \"%s\" at \"%s\"\n",
102 who, line_number, what, where);
103 exit(1);
104 }
105
106 /* Read a line from stdin into linebuf and increment line_number. */
107 static char *
get_line(void)108 get_line(void)
109 {
110 char *cp = fgets(linebuf, MAXLINE, stdin);
111 line_number++;
112
113 /* For debugging, you can set debug_line to a line to stop on. */
114 if (line_number == debug_line) {
115 fprintf(stderr, "Hit debug line number %d\n", line_number);
116 for (;;)
117 (void) sleep(1);
118 }
119 return (cp);
120 }
121
122 /* Get the continuation of the current input line. */
123 static char *
get_continuation(void)124 get_continuation(void)
125 {
126 char *cp = get_line();
127 if (!cp) {
128 fprintf(stderr, "expecting continuation line, "
129 "got end of input\n");
130 exit(1);
131 }
132
133 /* Skip to the quoted stuff. */
134 while (*cp++ != '"')
135 ;
136 return (cp);
137 }
138
139 void
parse_input(void)140 parse_input(void)
141 {
142 char *cp;
143 int i = 0;
144
145 for (i = 0; i < BUCKETS; i++) {
146 hash_table[i] = NULL;
147 name_table[i] = NULL;
148 }
149
150 /*
151 * get a line at a time from the .s stabs file and parse.
152 */
153 while ((cp = get_line()) != NULL)
154 parseline(cp);
155 }
156
157 /*
158 * Parse each line of the .s file (stabs entry) gather meaningful information
159 * like name of type, size, offsets of fields etc.
160 */
161 static void
parseline(char * cp)162 parseline(char *cp)
163 {
164 struct tdesc *tdp;
165 char c, *w;
166 int h, tagdef;
167
168 /*
169 * setup for reset()
170 */
171 if (setjmp(resetbuf))
172 return;
173
174 /*
175 * Look for lines of the form
176 * .stabs "str",n,n,n,n
177 * The part in '"' is then parsed.
178 */
179 cp = whitesp(cp);
180 #define STLEN 6
181 debug(2, cp, "parseline");
182 if (strncmp(cp, ".stabs", STLEN) != 0)
183 reset();
184 cp += STLEN;
185 #undef STLEN
186 cp = whitesp(cp);
187 if (*cp++ != '"')
188 reset();
189
190 /*
191 * name:type variable (ignored)
192 * name:ttype typedef
193 * name:Ttype struct tag define
194 */
195 cp = whitesp(cp);
196 cp = name(cp, &w);
197
198 tagdef = 0;
199 switch (c = *cp++) {
200 case 't': /* type */
201 break;
202 case 'T': /* struct, union, enum */
203 tagdef = 1;
204 break;
205 default:
206 reset();
207 }
208
209 /*
210 * The type id and definition follow.
211 */
212 cp = id(cp, &h);
213 if (*cp == '"') {
214 struct tdesc *ntdp;
215
216 cp++;
217 ntdp = lookup(h);
218 if (ntdp == NULL) { /* if that type isn't defined yet */
219 if (*cp++ != '=') /* better be defining it now */
220 expected("parseline/'0-9'", "=", cp - 1);
221 cp = tdefdecl(cp, h, &tdp);
222 addhash(tdp, h); /* for *(x,y) types */
223 } else { /* that type is already defined */
224 tdp = malloc(sizeof (*tdp));
225 tdp->type = TYPEOF;
226 tdp->name = (w != NULL) ? strdup(w) : NULL;
227 tdp->data.tdesc = ntdp;
228 addhash(tdp, h); /* for *(x,y) types */
229 debug(3, NULL, " %s defined as %s(%d)", w,
230 (ntdp->name != NULL) ? ntdp->name : "anon", h);
231 }
232 return;
233 } else if (*cp++ != '=') {
234 expected("parseline", "=", cp - 1);
235 }
236 if (tagdef) {
237 tagdecl(cp, &tdp, h, w);
238 } else {
239 (void) tdefdecl(cp, h, &tdp);
240 tagadd(w, h, tdp);
241 }
242 }
243
244 /*
245 * Check if we have this node in the hash table already
246 */
247 static struct tdesc *
lookup(int h)248 lookup(int h)
249 {
250 int hash = HASH(h);
251 struct tdesc *tdp = hash_table[hash];
252
253 while (tdp != NULL) {
254 if (tdp->id == h)
255 return (tdp);
256 tdp = tdp->hash;
257 }
258 return (NULL);
259 }
260
261 static char *
whitesp(char * cp)262 whitesp(char *cp)
263 {
264 char c;
265
266 for (c = *cp++; isspace(c); c = *cp++)
267 ;
268 --cp;
269 return (cp);
270 }
271
272 static char *
name(char * cp,char ** w)273 name(char *cp, char **w)
274 {
275 char *new, *orig, c;
276 int len;
277
278 orig = cp;
279 c = *cp++;
280 if (c == ':')
281 *w = NULL;
282 else if (isalpha(c) || c == '_') {
283 for (c = *cp++; isalnum(c) || c == ' ' || c == '_'; c = *cp++)
284 ;
285 if (c != ':')
286 reset();
287 len = cp - orig;
288 new = malloc(len);
289 while (orig < cp - 1)
290 *new++ = *orig++;
291 *new = '\0';
292 *w = new - (len - 1);
293 } else
294 reset();
295
296 return (cp);
297 }
298
299 static char *
number(char * cp,int * n)300 number(char *cp, int *n)
301 {
302 char *next;
303
304 *n = (int)strtol(cp, &next, 10);
305 if (next == cp)
306 expected("number", "<number>", cp);
307 return (next);
308 }
309
310 static char *
id(char * cp,int * h)311 id(char *cp, int *h)
312 {
313 int n1, n2;
314
315 if (*cp == '(') { /* SunPro style */
316 cp++;
317 cp = number(cp, &n1);
318 if (*cp++ != ',')
319 expected("id", ",", cp - 1);
320 cp = number(cp, &n2);
321 if (*cp++ != ')')
322 expected("id", ")", cp - 1);
323 *h = n1 * 1000 + n2;
324 } else if (isdigit(*cp)) { /* gcc style */
325 cp = number(cp, &n1);
326 *h = n1;
327 } else {
328 expected("id", "(/0-9", cp);
329 }
330 return (cp);
331 }
332
333 static void
tagadd(char * w,int h,struct tdesc * tdp)334 tagadd(char *w, int h, struct tdesc *tdp)
335 {
336 struct tdesc *otdp;
337
338 tdp->name = w;
339 if (!(otdp = lookup(h)))
340 addhash(tdp, h);
341 else if (otdp != tdp) {
342 fprintf(stderr, "duplicate entry\n");
343 fprintf(stderr, "old: %s %d %d %d\n",
344 otdp->name ? otdp->name : "NULL",
345 otdp->type, otdp->id / 1000, otdp->id % 1000);
346 fprintf(stderr, "new: %s %d %d %d\n",
347 tdp->name ? tdp->name : "NULL",
348 tdp->type, tdp->id / 1000, tdp->id % 1000);
349 }
350 }
351
352 static void
tagdecl(char * cp,struct tdesc ** rtdp,int h,char * w)353 tagdecl(char *cp, struct tdesc **rtdp, int h, char *w)
354 {
355 debug(1, NULL, "tagdecl: declaring '%s'", w ? w : "(anon)");
356 if ((*rtdp = lookup(h)) != NULL) {
357 if (w != NULL) {
358 if ((*rtdp)->name != NULL &&
359 strcmp((*rtdp)->name, w) != 0) {
360 struct tdesc *tdp;
361
362 tdp = malloc(sizeof (*tdp));
363 tdp->name = strdup(w);
364 tdp->type = TYPEOF;
365 tdp->data.tdesc = *rtdp;
366 addhash(tdp, h); /* for *(x,y) types */
367 debug(3, NULL, " %s defined as %s(%d)", w,
368 ((*rtdp)->name != NULL) ?
369 (*rtdp)->name : "anon", h);
370 } else if ((*rtdp)->name == NULL) {
371 (*rtdp)->name = w;
372 addhash(*rtdp, h);
373 }
374 }
375 } else {
376 *rtdp = malloc(sizeof (**rtdp));
377 (*rtdp)->name = w;
378 addhash(*rtdp, h);
379 }
380
381 switch (*cp++) {
382 case 's':
383 (void) soudef(cp, STRUCT, rtdp);
384 break;
385 case 'u':
386 (void) soudef(cp, UNION, rtdp);
387 break;
388 case 'e':
389 enumdef(cp, rtdp);
390 break;
391 default:
392 expected("tagdecl", "<tag type s/u/e>", cp - 1);
393 break;
394 }
395 }
396
397 static char *
tdefdecl(char * cp,int h,struct tdesc ** rtdp)398 tdefdecl(char *cp, int h, struct tdesc **rtdp)
399 {
400 struct tdesc *ntdp;
401 char *w;
402 int c, h2;
403 char type;
404
405 debug(3, cp, "tdefdecl h=%d", h);
406
407 /* Type codes */
408 switch (type = *cp) {
409 case 'b': /* integer */
410 c = *++cp;
411 if (c != 's' && c != 'u')
412 expected("tdefdecl/b", "[su]", cp - 1);
413 c = *++cp;
414 if (c == 'c')
415 cp++;
416 cp = intrinsic(cp, rtdp);
417 break;
418 case 'R': /* fp */
419 /* skip up to and past ';' */
420 while (*cp++ != ';')
421 /* NULL */;
422 cp = intrinsic(cp, rtdp);
423 break;
424 case '(': /* equiv to another type */
425 cp = id(cp, &h2);
426 ntdp = lookup(h2);
427 if (ntdp == NULL) { /* if that type isn't defined yet */
428 if (*cp++ != '=') /* better be defining it now */
429 expected("tdefdecl/'('", "=", cp - 1);
430 cp = tdefdecl(cp, h2, rtdp);
431 ntdp = malloc(sizeof (*ntdp));
432 ntdp->type = TYPEOF;
433 ntdp->data.tdesc = *rtdp;
434 addhash(ntdp, h2);
435 } else { /* that type is already defined */
436 *rtdp = malloc(sizeof (**rtdp));
437 (*rtdp)->type = TYPEOF;
438 (*rtdp)->data.tdesc = ntdp;
439 }
440 break;
441 case '*':
442 ntdp = NULL;
443 cp = tdefdecl(cp + 1, h, &ntdp);
444 if (ntdp == NULL)
445 expected("tdefdecl/*", "id", cp);
446
447 *rtdp = malloc(sizeof (**rtdp));
448 (*rtdp)->type = POINTER;
449 (*rtdp)->size = model->pointersize;
450 (*rtdp)->name = "pointer";
451 (*rtdp)->data.tdesc = ntdp;
452 break;
453 case 'f':
454 cp = tdefdecl(cp + 1, h, &ntdp);
455 *rtdp = malloc(sizeof (**rtdp));
456 (*rtdp)->type = FUNCTION;
457 (*rtdp)->size = model->pointersize;
458 (*rtdp)->name = "function";
459 (*rtdp)->data.tdesc = ntdp;
460 break;
461 case 'a':
462 cp++;
463 if (*cp++ != 'r')
464 expected("tdefdecl/a", "r", cp - 1);
465 *rtdp = malloc(sizeof (**rtdp));
466 (*rtdp)->type = ARRAY;
467 (*rtdp)->name = "array";
468 cp = arraydef(cp, rtdp);
469 break;
470 case 'x':
471 c = *++cp;
472 if (c != 's' && c != 'u' && c != 'e')
473 expected("tdefdecl/x", "[sue]", cp - 1);
474 cp = name(cp + 1, &w);
475 *rtdp = malloc(sizeof (**rtdp));
476 (*rtdp)->type = FORWARD;
477 (*rtdp)->name = w;
478 break;
479 case 'B': /* volatile */
480 cp = tdefdecl(cp + 1, h, &ntdp);
481 *rtdp = malloc(sizeof (**rtdp));
482 (*rtdp)->type = VOLATILE;
483 (*rtdp)->size = 0;
484 (*rtdp)->name = "volatile";
485 (*rtdp)->data.tdesc = ntdp;
486 break;
487 case 'k': /* const */
488 cp = tdefdecl(cp + 1, h, &ntdp);
489 *rtdp = malloc(sizeof (**rtdp));
490 (*rtdp)->type = CONST;
491 (*rtdp)->size = 0;
492 (*rtdp)->name = "const";
493 (*rtdp)->data.tdesc = ntdp;
494 break;
495 case '0': case '1': case '2': case '3': case '4':
496 case '5': case '6': case '7': case '8': case '9':
497 /* gcc equiv to another type */
498 cp = id(cp, &h2);
499 ntdp = lookup(h2);
500 if (ntdp == NULL) { /* if that type isn't defined yet */
501 /* better be defining it now */
502 if (*cp++ != '=') {
503 if (h != h2)
504 expected("tdefdecl/'0-9'", "=", cp - 1);
505 /* defined in terms of itself */
506 *rtdp = malloc(sizeof (**rtdp));
507 (*rtdp)->type = INTRINSIC;
508 (*rtdp)->name = "void";
509 (*rtdp)->size = 0;
510 } else {
511 cp = tdefdecl(cp, h2, rtdp);
512 ntdp = malloc(sizeof (*ntdp));
513 ntdp->type = TYPEOF;
514 ntdp->data.tdesc = *rtdp;
515 addhash(ntdp, h2);
516 }
517 } else { /* that type is already defined */
518 *rtdp = malloc(sizeof (**rtdp));
519 (*rtdp)->type = TYPEOF;
520 (*rtdp)->data.tdesc = ntdp;
521 }
522 break;
523 case 'u':
524 case 's':
525 cp++;
526
527 *rtdp = malloc(sizeof (**rtdp));
528 (*rtdp)->name = NULL;
529 cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp);
530 break;
531 default:
532 expected("tdefdecl", "<type code>", cp);
533 }
534 return (cp);
535 }
536
537 static char *
intrinsic(char * cp,struct tdesc ** rtdp)538 intrinsic(char *cp, struct tdesc **rtdp)
539 {
540 struct tdesc *tdp;
541 int size;
542
543 cp = number(cp, &size);
544 tdp = malloc(sizeof (*tdp));
545 tdp->type = INTRINSIC;
546 tdp->size = size;
547 tdp->name = NULL;
548 debug(3, NULL, "intrinsic: size=%ld", size);
549 *rtdp = tdp;
550 return (cp);
551 }
552
553 static char *
soudef(char * cp,enum type type,struct tdesc ** rtdp)554 soudef(char *cp, enum type type, struct tdesc **rtdp)
555 {
556 struct mlist **next_pp, *prev_p = NULL;
557 char *w;
558 int size;
559 struct tdesc *tdp;
560
561 cp = number(cp, &size);
562 (*rtdp)->size = size;
563 (*rtdp)->type = type; /* s or u */
564
565 /*
566 * An '@' here indicates a bitmask follows. This is so the
567 * compiler can pass information to debuggers about how structures
568 * are passed in the v9 world. We don't need this information
569 * so we skip over it.
570 */
571 if (cp[0] == '@')
572 cp += 3;
573
574 debug(3, cp, "soudef: %s size=%d",
575 (*rtdp)->name ? (*rtdp)->name : "(anonsou)",
576 (*rtdp)->size);
577
578 next_pp = &((*rtdp)->data.members.forw); /* head for forward linklist */
579 /* fill up the fields */
580 while ((*cp != '"') && (*cp != ';')) { /* signifies end of fields */
581 int h;
582 struct mlist *mlp = malloc(sizeof (*mlp));
583
584 mlp->prev = prev_p; /* links for the backward list */
585 prev_p = mlp;
586 *next_pp = mlp; /* links for the forward list */
587 next_pp = &mlp->next;
588
589 cp = name(cp, &w);
590 mlp->name = w;
591 cp = id(cp, &h);
592 /*
593 * find the tdesc struct in the hash table for this type
594 * and stick a ptr in here
595 */
596 tdp = lookup(h);
597 if (tdp == NULL) { /* not in hash list */
598 debug(3, NULL, " defines %s (%d)", w, h);
599 if (*cp++ != '=')
600 expected("soudef", "=", cp - 1);
601 cp = tdefdecl(cp, h, &tdp);
602 addhash(tdp, h);
603 debug(4, cp, " soudef now looking at ");
604 cp++;
605
606 } else {
607 debug(3, NULL, " refers to %s (%d, %s)",
608 w ? w : "anon", h, tdp->name ? tdp->name : "anon");
609 }
610
611 mlp->fdesc = tdp;
612 cp = offsize(cp, mlp); /* cp is now pointing to next field */
613 if (*cp == '\\') /* could be a continuation */
614 cp = get_continuation();
615 }
616 (*rtdp)->data.members.back = prev_p; /* head for backward linklist */
617 return (cp);
618 }
619
620 static char *
offsize(char * cp,struct mlist * mlp)621 offsize(char *cp, struct mlist *mlp)
622 {
623 int offset, size;
624
625 if (*cp == ',')
626 cp++;
627 cp = number(cp, &offset);
628 if (*cp++ != ',')
629 expected("offsize/2", ",", cp - 1);
630 cp = number(cp, &size);
631 if (*cp++ != ';')
632 expected("offsize/3", ";", cp - 1);
633 mlp->offset = offset;
634 mlp->size = size;
635 return (cp);
636 }
637
638 static char *
arraydef(char * cp,struct tdesc ** rtdp)639 arraydef(char *cp, struct tdesc **rtdp)
640 {
641 int h;
642 int start, end;
643
644 cp = id(cp, &h);
645 if (*cp++ != ';')
646 expected("arraydef/1", ";", cp - 1);
647
648 (*rtdp)->data.ardef = malloc(sizeof (struct ardef));
649 (*rtdp)->data.ardef->indices = malloc(sizeof (struct element));
650 (*rtdp)->data.ardef->indices->index_type = lookup(h);
651
652 cp = number(cp, &start); /* lower */
653 if (*cp++ != ';')
654 expected("arraydef/2", ";", cp - 1);
655 cp = number(cp, &end); /* upper */
656 if (*cp++ != ';')
657 expected("arraydef/3", ";", cp - 1);
658 (*rtdp)->data.ardef->indices->range_start = start;
659 (*rtdp)->data.ardef->indices->range_end = end;
660 #if 0
661 if (isdigit(*cp)) {
662 cp = number(cp, &contents_type); /* lower */
663 tdp = lookup(contents_type);
664 if (tdp != NULL) {
665 (*rtdp)->data.ardef->contents = tdp;
666 } else {
667 if (*cp != '=')
668 expected("arraydef/4", "=", cp);
669 cp = tdefdecl(cp + 1, h, &tdp);
670 addhash(tdp, h); /* for *(x,y) types */
671 (*rtdp)->data.ardef->contents = tdp;
672 }
673 } /* else */
674 #endif
675 cp = tdefdecl(cp, h, &((*rtdp)->data.ardef->contents));
676 return (cp);
677 }
678
679 static void
enumdef(char * cp,struct tdesc ** rtdp)680 enumdef(char *cp, struct tdesc **rtdp)
681 {
682 struct elist *elp, **prev;
683 char *w;
684
685 (*rtdp)->type = ENUM;
686 (*rtdp)->data.emem = NULL;
687
688 prev = &((*rtdp)->data.emem);
689 while (*cp != ';') {
690 elp = malloc(sizeof (*elp));
691 elp->next = NULL;
692 *prev = elp;
693 cp = name(cp, &w);
694 elp->name = w;
695 cp = number(cp, &elp->number);
696 debug(3, NULL, "enum %s: %s=%ld",
697 (*rtdp)->name ? (*rtdp)->name : "(anon enum)",
698 elp->name, elp->number);
699 prev = &elp->next;
700 if (*cp++ != ',')
701 expected("enumdef", ",", cp - 1);
702 if (*cp == '\\')
703 cp = get_continuation();
704 }
705 }
706
707 /*
708 * Add a node to the hash queues.
709 */
710 static void
addhash(struct tdesc * tdp,int num)711 addhash(struct tdesc *tdp, int num)
712 {
713 int hash = HASH(num);
714 struct tdesc *ttdp;
715 char added_num = 0, added_name = 0;
716
717 /*
718 * If it already exists in the hash table don't add it again
719 * (but still check to see if the name should be hashed).
720 */
721 ttdp = lookup(num);
722 if (ttdp == NULL) {
723 tdp->id = num;
724 tdp->hash = hash_table[hash];
725 hash_table[hash] = tdp;
726 added_num = 1;
727 }
728
729 if (tdp->name != NULL) {
730 ttdp = lookupname(tdp->name);
731 if (ttdp == NULL) {
732 hash = compute_sum(tdp->name);
733 tdp->next = name_table[hash];
734 name_table[hash] = tdp;
735 added_name = 1;
736 }
737 }
738 if (!added_num && !added_name) {
739 fprintf(stderr, "stabs: broken hash\n");
740 exit(1);
741 }
742 }
743
744 struct tdesc *
lookupname(char * name)745 lookupname(char *name)
746 {
747 int hash = compute_sum(name);
748 struct tdesc *tdp, *ttdp = NULL;
749
750 for (tdp = name_table[hash]; tdp != NULL; tdp = tdp->next) {
751 if (tdp->name != NULL && strcmp(tdp->name, name) == 0) {
752 if (tdp->type == STRUCT || tdp->type == UNION ||
753 tdp->type == ENUM || tdp->type == INTRINSIC)
754 return (tdp);
755 if (tdp->type == TYPEOF)
756 ttdp = tdp;
757 }
758 }
759 return (ttdp);
760 }
761
762 static int
compute_sum(char * w)763 compute_sum(char *w)
764 {
765 char c;
766 int sum;
767
768 for (sum = 0; (c = *w) != '\0'; sum += c, w++)
769 ;
770 return (HASH(sum));
771 }
772
773 static void
reset(void)774 reset(void)
775 {
776 longjmp(resetbuf, 1);
777 /* NOTREACHED */
778 }
779