Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "object.h"
33
#include "hash.h"
34
#include "type.h"
35
#include "utility.h"
36
 
37
 
38
/*
39
    STANDARD HASH TABLES
40
 
41
    These hash tables represent the various namespaces permitted in C
42
    plus the TDF token namespace.
43
*/
44
 
45
hash_table *exps ;
46
hash_table *files ;
47
hash_table *keywords ;
48
hash_table *subsets ;
49
hash_table *tags ;
50
hash_table *tag_fields ;
51
hash_table *tokens ;
52
hash_table *types ;
53
hash_table *type_fields ;
54
 
55
 
56
/*
57
    INITIALISATION ROUTINE
58
 
59
    This routine initialises the standard hash tables and sets a few
60
    miscellaneous variables.
61
*/
62
 
63
void init_hash
64
    PROTO_Z ()
65
{
66
    buffer = alloc_nof ( char, buffsize + 100 ) ;
67
    exps = make_hash_table ( "Expression" ) ;
68
    files = make_hash_table ( "Output file" ) ;
69
    keywords = make_hash_table ( "Keyword" ) ;
70
    subsets = make_hash_table ( "Set" ) ;
71
    tags = make_hash_table ( "Tag" ) ;
72
    tag_fields = make_hash_table ( "Field selector struct/union" ) ;
73
    tokens = make_hash_table ( "Token" ) ;
74
    types = make_hash_table ( "Type" ) ;
75
    type_fields = make_hash_table ( "Field selector" ) ;
76
    return ;
77
}
78
 
79
 
80
/*
81
    HASHING ROUTINE
82
 
83
    This routine finds the hash value of the string nm.  This value must
84
    lie in the range [ 0, hash_size ).
85
*/
86
 
87
static int hash
88
    PROTO_N ( ( nm ) )
89
    PROTO_T ( char *nm )
90
{
91
    char *s ;
92
    int n = 0 ;
93
    for ( s = nm ; *s ; s++ ) n += *s ;
94
    return ( n % hash_size ) ;
95
}
96
 
97
 
98
/*
99
    CREATE A NEW HASH TABLE
100
 
101
    This routine creates a new hash table called nm.
102
*/
103
 
104
hash_table *make_hash_table
105
    PROTO_N ( ( nm ) )
106
    PROTO_T ( char *nm )
107
{
108
    int i ;
109
    hash_table *t = alloc_nof ( hash_table, 1 ) ;
110
    t->name = nm ;
111
    for ( i = 0 ; i < hash_size ; i++ ) t->array [i] = null ;
112
    return ( t ) ;
113
}
114
 
115
 
116
/*
117
    LOOK UP A NAME IN A HASH TABLE
118
 
119
    This routine looks up the object nm (version v) in the hth column
120
    of hash table t.  It returns the object if it is found, or null
121
    otherwise.
122
*/
123
 
124
static object *lookup_hash
125
    PROTO_N ( ( t, nm, v, h ) )
126
    PROTO_T ( hash_table *t X char *nm X int v X int h )
127
{
128
    hash_elem *e = t->array [h] ;
129
    while ( e ) {
130
	if ( streq ( nm, e->obj->name ) ) {
131
	    if ( v == e->vers || v == any_version ) return ( e->obj ) ;
132
	}
133
	e = e->next ;
134
    }
135
    return ( null ) ;
136
}
137
 
138
 
139
/*
140
    ADD AN OBJECT TO A HASH TABLE
141
 
142
    This routine adds the object p (version v) to the hash table t,
143
    reporting an error and returning the old value if it is already
144
    defined.  Otherwise it returns p.
145
*/
146
 
147
object *add_hash
148
    PROTO_N ( ( t, p, v ) )
149
    PROTO_T ( hash_table *t X object *p X int v )
150
{
151
    hash_elem *e ;
152
    char *nm = p->name ;
153
    int h = hash ( nm ) ;
154
    object *q = lookup_hash ( t, nm, v, h ) ;
155
    if ( q != null ) {
156
	char *fn = q->filename ;
157
	if ( fn ) {
158
	    char *err = "%s '%s' already defined (%s, line %d)" ;
159
	    error ( ERR_SERIOUS, err, t->name, nm, fn, q->line_no ) ;
160
	} else {
161
	    error ( ERR_SERIOUS, "%s '%s' already defined", t->name, nm ) ;
162
	}
163
	return ( q ) ;
164
    }
165
    alloc_variable ( e, hash_elem, 1000 ) ;
166
    e->obj = p ;
167
    e->vers = v ;
168
    e->next = t->array [h] ;
169
    t->array [h] = e ;
170
    return ( p ) ;
171
}
172
 
173
 
174
/*
175
    SEARCH A HASH TABLE FOR AN OBJECT
176
 
177
    This routine searches the hash table t for the object named nm
178
    (version v), returning it if it is found.  If it is not found then
179
    null is returned.
180
*/
181
 
182
object *search_hash
183
    PROTO_N ( ( t, nm, v ) )
184
    PROTO_T ( hash_table *t X char *nm X int v )
185
{
186
    int h = hash ( nm ) ;
187
    return ( lookup_hash ( t, nm, v, h ) ) ;
188
}
189
 
190
 
191
/*
192
    SORT THE ELEMENTS OF A HASH LIST
193
 
194
    This routine sorts the elements of the hash table t into a single
195
    alphabetical list.  The table cannot be used subsequently.
196
*/
197
 
198
hash_elem *sort_hash
199
    PROTO_N ( ( t ) )
200
    PROTO_T ( hash_table *t )
201
{
202
    int i ;
203
    hash_elem *r = null ;
204
    for ( i = 0 ; i < hash_size ; i++ ) {
205
	hash_elem *p = t->array [i]  ;
206
	while ( p ) {
207
	    hash_elem *pn = p->next ;
208
	    hash_elem *q = r, *s = null ;
209
	    while ( q ) {
210
		if ( strcmp ( p->obj->name, q->obj->name ) <= 0 ) break ;
211
		s = q ;
212
		q = q->next ;
213
	    }
214
	    if ( s == null ) {
215
		p->next = r ;
216
		r = p ;
217
	    } else {
218
		p->next = s->next ;
219
		s->next = p ;
220
	    }
221
	    p = pn ;
222
	}
223
    }
224
    return ( r ) ;
225
}