Pristine Ack-5.5
[Ack-5.5.git] / modules / src / idf / idf_pkg.body
1 /*      SYMBOL TABLE HANDLING   */
2
3 #include        <alloc.h>
4
5 #define IDF_HASHSIZE    307     /* size of hashtable, must be odd */
6
7 #define IDF_STARTHASH(hs)       (hs = 0)
8 #define IDF_ENHASH(hs,ch)       (hs = (hs << 2) + ch)
9 #define IDF_STOPHASH(hs)        (hs = hs % IDF_HASHSIZE)
10
11 static struct idf *IDF_hashtable[IDF_HASHSIZE];
12         /*      All identifiers can in principle be reached through
13                 IDF_hashtable; IDF_hashtable[hc] is the start of a chain of
14                 idf's whose tags all hash to hc.
15                 Any identifier is entered into this
16                 list, regardless of the nature of its declaration
17                 (variable, selector, structure tag, etc.).
18         */
19
20 _PROTOTYPE(static struct idf *IDF_new, (char *, int, int));
21
22 void
23 init_idf()
24 {
25 }
26
27 static struct idf *
28 IDF_new(tg, size, cpy)
29         register char *tg;
30         register int size;
31 {
32         static int nidf;
33         static struct idf *pidf;
34         static struct idf null_idf;
35         register struct idf *id;
36 #define NIDS 50
37 #define IBUFSIZ 2048
38         static unsigned int icnt;
39         static char *ip;
40         register char *p;
41
42
43         if (! nidf--) {
44                 nidf += NIDS;
45                 pidf = (struct idf *) Malloc(NIDS * sizeof (struct idf));
46         }
47
48         id = pidf;
49         pidf++;
50         *id = null_idf;
51
52         if (cpy) {
53                 if (size > icnt) {
54                         icnt =  size > IBUFSIZ ? size : IBUFSIZ;
55                         p = Malloc(icnt);
56                 }
57                 else p = ip;
58                 icnt -= size;
59                 id->id_text = p;
60                 while (size--) {
61                         *p++ = *tg++;
62                 }
63                 ip = p;
64         }
65         else    id->id_text = tg;
66         return id;
67 }
68
69 #ifdef  IDF_DEBUG
70 void
71 hash_stat()
72 {
73         register int i;
74         int total_count = 0;
75
76         print("Hash table tally:\n");
77         for (i = 0; i < IDF_HASHSIZE; i++)      {
78                 register struct idf *notch = IDF_hashtable[i];
79                 register int cnt = 0;
80
81                 print ("%d ", i);
82                 while (notch)   {
83                         cnt++;
84                         print("'%s' ", notch->id_text);
85                         notch = notch->id_next;
86                 }
87                 print("%d\n", cnt);
88                 total_count += cnt;
89         }
90         print("total = %d\n", total_count);
91         print("End hash table tally\n");
92 }
93
94 void
95 idfappfun(fun, opt)
96         int     (*fun)();
97         int     opt;
98 {
99         register int    i;
100
101         for (i = 0; i < IDF_HASHSIZE; i++) {
102                 register struct idf *notch = IDF_hashtable[i];
103
104                 while (notch) {
105                         (*fun)(notch, opt);
106                         notch = notch->id_next;
107                 }
108         }
109 }
110 #endif  /* IDF_DEBUG */
111
112 struct idf *
113 str2idf(tg, cpy)
114         char tg[];
115 {
116         /*      str2idf() returns an entry in the symbol table for the
117                 identifier tg.  If necessary, an entry is created.
118         */
119         register char *cp = tg;
120         struct idf **hook;
121         register struct idf *notch;
122         register unsigned int hash;
123         register int c;
124         int size;
125
126         IDF_STARTHASH(hash);
127         while (c = *cp++) {
128                 IDF_ENHASH(hash, c);
129         }
130         IDF_STOPHASH(hash);
131         size = cp - tg;
132
133         /*      The tag tg with length size and known hash value hash is
134                 looked up in the identifier table; if not found, it is
135                 entered if cpy >= 0. A pointer to it is returned.
136                 Notice that the chains of idf's are sorted alphabetically.
137         */
138         hook = &IDF_hashtable[hash];
139
140         while ((notch = *hook)) {
141                 register char *s1 = tg;
142
143                 cp = notch->id_text;
144
145                 while (!(c = (*s1 - *cp++))) {
146                         if (*s1++ == '\0') {
147                                 break;
148                         }
149                 }
150
151                 if (c == 0) return notch;
152                 if (c < 0) break;
153                 hook = &notch->id_next;
154         }
155         /* a new struct idf must be inserted at the hook */
156         if (cpy < 0) return 0;
157         notch = IDF_new(tg, size, cpy);
158         notch->id_next = *hook;
159         *hook = notch;          /* hooked in */
160         return notch;
161 }