symtab_gen.c
References to this file elsewhere.
1 /* symtab.c
2
3 Symbol Table Handler -- Generic
4
5 The routine symget() returns a pointer to a C structure matching a
6 given lexeme. If the lexeme does not already exist in the symbol
7 table, the routine will create a new symbol structure, store it, and
8 then return a pointer to the newly created structure.
9
10 It is up to the calling module to declare the symbol structure as
11 well as several routines for manipulating the symbol structure. The
12 routines are passed to symget as pointers.
13
14 name type description
15
16 newnode() *char returns a pointer to a symbol structure.
17
18 nodename() **char retrieves the lexeme name from a symbol
19 structure, returned as a pointer to a
20 character array.
21
22 nodenext() **char retrieves pointer to the next field of
23 the symbol structure (the next field
24 is itself a pointer to a symbol structure)
25
26 For a sample main or calling program see the end of this file.
27
28 ****
29 REVISED 2-19-90. Added code to make hashtable interchangible.
30 new routine: create_ht() creates new hashtable
31 rev routine: symget() added parameter to pass hash table
32 */
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <strings.h>
37
38 #define HASHSIZE 1024
39
40 /* commented out 2-29-90
41 static char * symtab[HASHSIZE] ;
42 */
43
44 void * malloc() ;
45 void * calloc() ;
46
47 char * symget(name,newnode,nodename,nodenext,symtab,flag)
48 char *name ;
49 char *(*newnode)(), **(*nodename)(), **(*nodenext)() ;
50 char *symtab[] ;
51 int flag ; /* 1 is create if not there, 0 return NULL if not there */
52 {
53 int index ;
54 int found ;
55 register char *s ;
56 register char *t ;
57 char **x ;
58 char *p ;
59
60 index = hash( name ) ;
61 p = symtab[index] ;
62 found = 0 ;
63
64 while (p) {
65 s = name ;
66 t = *(*nodename)(p) ;
67 while (*s && *t && *s == *t ) {
68 s++ ;
69 t++ ;
70 }
71 if (!*s && !*t) {
72 found = 1 ;
73 break ;
74 }
75 p = *(*nodenext)(p) ;
76 }
77
78 if (!found ) {
79 if (flag ) {
80 p = (*newnode)() ;
81 x = (*nodename)(p) ;
82 *x = (char *) malloc(strlen(name)+1) ;
83 strcpy(*x,name) ;
84 x = (*nodenext)(p) ;
85 *x = symtab[index] ;
86 symtab[index] = p ;
87 } else {
88 return(NULL) ;
89 }
90 }
91
92 return(p) ;
93 }
94
95 hash(name)
96 char * name ;
97 {
98 register int result = 0 ;
99 register char * p = name ;
100
101 while (*p)
102 result = 3*result + (int)*p++ ;
103
104 result = result % HASHSIZE ;
105 while (result < 0)
106 result = result + HASHSIZE ;
107 return(result) ;
108 }
109
110
111 /* added 2-19-90, attaches a new hash table to pointer */
112
113 int
114 create_ht( p )
115 char *** p ;
116 {
117 *p = (char **) calloc( HASHSIZE , sizeof( char * ) ) ;
118 return(0) ;
119 }
120
121
122 /* added 4-15-92.
123
124 This is a generic routine that, given a hash table pointer,
125 will traverse the hash table and apply a caller supplied
126 function to each entry
127
128 */
129
130 int
131 sym_traverse( ht, nodenext, f )
132 char *ht[] ;
133 char **(*nodenext)() ;
134 void (*f)() ;
135 {
136 char * p, **x ;
137 int i ;
138 for ( i = 0 ; i < HASHSIZE ; i++ )
139 {
140 if ( ( p = ht[i] ) != NULL )
141 {
142 while ( p )
143 {
144 (*f)(p) ;
145 x = (*nodenext)(p) ;
146 p = *x ;
147 }
148 }
149 }
150 return(0) ;
151 }
152
153 /**********************************************************************/
154 /**********************************************************************/
155 /**********************************************************************/
156
157 #ifdef COMMENTOUTSAMPLE
158 /* sample_main.c
159
160 sample main program for symget() in the file symtab.c
161
162 */
163
164 #include <stdio.h>
165
166 struct symnode {
167 char * name ;
168 struct symnode *next ;
169 } ;
170
171 extern struct symnode * symget() ;
172
173 struct symnode *
174 newnode()
175 {
176 struct symnode * malloc() ;
177 return( malloc( sizeof( struct symnode ) ) ) ;
178 }
179
180 char **
181 nodename(p)
182 struct symnode *p ;
183 {
184 char ** x ;
185 x = &(p->name) ;
186 return( x ) ;
187 }
188
189 struct symnode **
190 nodenext(p)
191 struct symnode *p ;
192 {
193 struct symnode **x ;
194 x = &(p->next) ;
195 return( x ) ;
196 }
197
198 #endif
199
200 /**********************************************************************/
201 /**********************************************************************/
202 /**********************************************************************/
203