Subversion Repositories tendra.SVN

Rev

Rev 6 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "object.h"
63
#include "hash.h"
64
#include "type.h"
65
#include "utility.h"
66
 
67
 
68
/*
69
    STANDARD HASH TABLES
70
 
71
    These hash tables represent the various namespaces permitted in C
72
    plus the TDF token namespace.
73
*/
74
 
6 7u83 75
hash_table *exps;
76
hash_table *files;
77
hash_table *keywords;
78
hash_table *subsets;
79
hash_table *tags;
80
hash_table *tag_fields;
81
hash_table *tokens;
82
hash_table *types;
83
hash_table *type_fields;
2 7u83 84
 
85
 
86
/*
87
    INITIALISATION ROUTINE
88
 
89
    This routine initialises the standard hash tables and sets a few
90
    miscellaneous variables.
91
*/
92
 
6 7u83 93
void
94
init_hash(void)
2 7u83 95
{
6 7u83 96
    buffer = alloc_nof(char, buffsize + 100);
97
    exps = make_hash_table("Expression");
98
    files = make_hash_table("Output file");
99
    keywords = make_hash_table("Keyword");
100
    subsets = make_hash_table("Set");
101
    tags = make_hash_table("Tag");
102
    tag_fields = make_hash_table("Field selector struct/union");
103
    tokens = make_hash_table("Token");
104
    types = make_hash_table("Type");
105
    type_fields = make_hash_table("Field selector");
106
    return;
2 7u83 107
}
108
 
109
 
110
/*
111
    HASHING ROUTINE
112
 
113
    This routine finds the hash value of the string nm.  This value must
114
    lie in the range [ 0, hash_size ).
115
*/
116
 
6 7u83 117
static int
118
hash(char *nm)
2 7u83 119
{
6 7u83 120
    char *s;
121
    int n = 0;
122
    for (s = nm; *s; s++)n += *s;
123
    return(n % hash_size);
2 7u83 124
}
125
 
126
 
127
/*
128
    CREATE A NEW HASH TABLE
129
 
130
    This routine creates a new hash table called nm.
131
*/
132
 
6 7u83 133
hash_table *
134
make_hash_table(char *nm)
2 7u83 135
{
6 7u83 136
    int i;
137
    hash_table *t = alloc_nof(hash_table, 1);
138
    t->name = nm;
139
    for (i = 0; i < hash_size; i++)t->array [i] = null;
140
    return(t);
2 7u83 141
}
142
 
143
 
144
/*
145
    LOOK UP A NAME IN A HASH TABLE
146
 
147
    This routine looks up the object nm (version v) in the hth column
148
    of hash table t.  It returns the object if it is found, or null
149
    otherwise.
150
*/
151
 
6 7u83 152
static object *
153
lookup_hash(hash_table *t, char *nm, int v, int h)
2 7u83 154
{
6 7u83 155
    hash_elem *e = t->array [h];
156
    while (e) {
157
	if (streq(nm, e->obj->name)) {
158
	    if (v == e->vers || v == any_version) return(e->obj);
2 7u83 159
	}
6 7u83 160
	e = e->next;
2 7u83 161
    }
6 7u83 162
    return(null);
2 7u83 163
}
164
 
165
 
166
/*
167
    ADD AN OBJECT TO A HASH TABLE
168
 
169
    This routine adds the object p (version v) to the hash table t,
170
    reporting an error and returning the old value if it is already
171
    defined.  Otherwise it returns p.
172
*/
173
 
6 7u83 174
object *
175
add_hash(hash_table *t, object *p, int v)
2 7u83 176
{
6 7u83 177
    hash_elem *e;
178
    char *nm = p->name;
179
    int h = hash(nm);
180
    object *q = lookup_hash(t, nm, v, h);
181
    if (q != null) {
182
	char *fn = q->filename;
183
	if (fn) {
184
	    char *err = "%s '%s' already defined (%s, line %d)";
185
	    error(ERR_SERIOUS, err, t->name, nm, fn, q->line_no);
2 7u83 186
	} else {
6 7u83 187
	    error(ERR_SERIOUS, "%s '%s' already defined", t->name, nm);
2 7u83 188
	}
6 7u83 189
	return(q);
2 7u83 190
    }
6 7u83 191
    alloc_variable(e, hash_elem, 1000);
192
    e->obj = p;
193
    e->vers = v;
194
    e->next = t->array [h];
195
    t->array [h] = e;
196
    return(p);
2 7u83 197
}
198
 
199
 
200
/*
201
    SEARCH A HASH TABLE FOR AN OBJECT
202
 
203
    This routine searches the hash table t for the object named nm
204
    (version v), returning it if it is found.  If it is not found then
205
    null is returned.
206
*/
207
 
6 7u83 208
object *
209
search_hash(hash_table *t, char *nm, int v)
2 7u83 210
{
6 7u83 211
    int h = hash(nm);
212
    return(lookup_hash(t, nm, v, h));
2 7u83 213
}
214
 
215
 
216
/*
217
    SORT THE ELEMENTS OF A HASH LIST
218
 
219
    This routine sorts the elements of the hash table t into a single
220
    alphabetical list.  The table cannot be used subsequently.
221
*/
222
 
6 7u83 223
hash_elem *
224
sort_hash(hash_table *t)
2 7u83 225
{
6 7u83 226
    int i;
227
    hash_elem *r = null;
228
    for (i = 0; i < hash_size; i++) {
229
	hash_elem *p = t->array [i] ;
230
	while (p) {
231
	    hash_elem *pn = p->next;
232
	    hash_elem *q = r, *s = null;
233
	    while (q) {
234
		if (strcmp(p->obj->name, q->obj->name) <= 0)break;
235
		s = q;
236
		q = q->next;
2 7u83 237
	    }
6 7u83 238
	    if (s == null) {
239
		p->next = r;
240
		r = p;
2 7u83 241
	    } else {
6 7u83 242
		p->next = s->next;
243
		s->next = p;
2 7u83 244
	    }
6 7u83 245
	    p = pn;
2 7u83 246
	}
247
    }
6 7u83 248
    return(r);
2 7u83 249
}