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