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
/*** table.c --- Identifier table ADT.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 *** Commentary:
66
 *
67
 * This file implements the identifier table routines used by SID.
68
 *
69
 *** Change Log:
70
 * $Log: table.c,v $
71
 * Revision 1.1.1.1  1998/01/17  15:57:47  release
72
 * First version to be checked into rolling release.
73
 *
74
 * Revision 1.3  1994/12/15  09:59:05  smf
75
 * Brought into line with OSSG C Coding Standards Document, as per
76
 * "CR94_178.sid+tld-update".
77
 *
78
 * Revision 1.2  1994/08/22  09:37:32  smf
79
 * Fixed bug DR114:ids-too-long.
80
 *
81
 * Revision 1.1.1.1  1994/07/25  16:04:43  smf
82
 * Initial import of SID 1.8 non shared files.
83
 *
84
**/
85
 
86
/****************************************************************************/
87
 
88
#include "table.h"
89
#include "action.h"
90
#include "basic.h"
91
#include "gen-errors.h"
92
#include "grammar.h"
93
#include "name.h"
94
#include "rule.h"
95
#include "type.h"
96
 
97
/*--------------------------------------------------------------------------*/
98
 
99
static unsigned
6 7u83 100
table_next_generated_key(void)
2 7u83 101
{
102
    static unsigned sequence = 0;
103
 
104
    if (sequence == UINT_MAX) {
6 7u83 105
	E_too_many_generated_ids();
2 7u83 106
	UNREACHED;
107
    }
6 7u83 108
    return(sequence++);
2 7u83 109
}
110
 
111
static EntryP
6 7u83 112
table_add_entry(TableP table, NStringP key, EntryTypeT type, BoolT *found_ref)
2 7u83 113
{
6 7u83 114
    unsigned hash   = (nstring_hash_value(key)% TABLE_SIZE);
115
    EntryP  *entryp = &(table->contents[hash]);
2 7u83 116
    EntryP   entry;
117
    unsigned number;
118
 
119
    *found_ref = FALSE;
6 7u83 120
    while ((entry = *entryp) != NIL(EntryP)) {
121
	KeyP ent_key = entry_key(entry);
2 7u83 122
 
6 7u83 123
	if ((key_is_string(ent_key)) &&
124
	   (nstring_equal(key_get_string(ent_key), key))) {
2 7u83 125
	    if (type == ET_NAME) {
6 7u83 126
		nstring_destroy(key);
127
		return(entry);
128
	    } else if (entry_type(entry) == ET_NAME) {
129
		nstring_destroy(key);
130
		entry_change_type(entry, type);
131
		return(entry);
132
	    } else if ((entry_type(entry) == type) &&
133
		      ((type == ET_ACTION) || (type == ET_RULE))) {
2 7u83 134
		*found_ref = TRUE;
6 7u83 135
		nstring_destroy(key);
136
		return(entry);
2 7u83 137
	    } else {
6 7u83 138
		return(NIL(EntryP));
2 7u83 139
	    }
140
	}
6 7u83 141
	entryp = entry_next_ref(entry);
2 7u83 142
    }
6 7u83 143
    number  = table_next_generated_key();
144
    entry   = entry_create_from_string(key, number, type);
2 7u83 145
    *entryp = entry;
6 7u83 146
    return(entry);
2 7u83 147
}
148
 
149
/*--------------------------------------------------------------------------*/
150
 
151
void
6 7u83 152
table_init(TableP table)
2 7u83 153
{
154
    unsigned i;
155
 
6 7u83 156
    for (i = 0; i < TABLE_SIZE; i++) {
157
	table->contents[i] = NIL(EntryP);
2 7u83 158
    }
159
}
160
 
161
EntryP
6 7u83 162
table_add_type(TableP table, NStringP key)
2 7u83 163
{
164
    BoolT  found;
6 7u83 165
    EntryP entry = table_add_entry(table, key, ET_TYPE, &found);
2 7u83 166
 
167
    if (entry) {
6 7u83 168
	entry_set_type(entry, type_create());
2 7u83 169
    }
6 7u83 170
    return(entry);
2 7u83 171
}
172
 
173
EntryP
6 7u83 174
table_add_basic(TableP table, NStringP key, GrammarP grammar, BoolT ignored)
2 7u83 175
{
176
    BoolT  found;
6 7u83 177
    EntryP entry = table_add_entry(table, key, ET_BASIC, &found);
2 7u83 178
 
179
    if (entry) {
6 7u83 180
	entry_set_basic(entry, basic_create(grammar, ignored));
2 7u83 181
    }
6 7u83 182
    return(entry);
2 7u83 183
}
184
 
185
EntryP
6 7u83 186
table_add_action(TableP table, NStringP key)
2 7u83 187
{
188
    BoolT  found;
6 7u83 189
    EntryP entry = table_add_entry(table, key, ET_ACTION, &found);
2 7u83 190
 
6 7u83 191
    if ((entry != NIL(EntryP)) && (!found)) {
192
	entry_set_action(entry, action_create());
2 7u83 193
    }
6 7u83 194
    return(entry);
2 7u83 195
}
196
 
197
EntryP
6 7u83 198
table_add_rule(TableP table, NStringP key)
2 7u83 199
{
200
    BoolT  found;
6 7u83 201
    EntryP entry = table_add_entry(table, key, ET_RULE, &found);
2 7u83 202
 
6 7u83 203
    if ((entry != NIL(EntryP)) && (!found)) {
204
	entry_set_rule(entry, rule_create(entry));
2 7u83 205
    }
6 7u83 206
    return(entry);
2 7u83 207
}
208
 
209
EntryP
6 7u83 210
table_add_generated_rule(TableP table, BoolT traced)
2 7u83 211
{
6 7u83 212
    unsigned sequence = table_next_generated_key();
2 7u83 213
    unsigned hash     = (sequence % TABLE_SIZE);
6 7u83 214
    EntryP  *entryp   = &(table->contents[hash]);
2 7u83 215
    EntryP   entry;
216
 
6 7u83 217
    entry = entry_create_from_number(sequence, ET_RULE, traced, *entryp);
218
    entry_set_rule(entry, rule_create(entry));
2 7u83 219
    *entryp = entry;
6 7u83 220
    return(entry);
2 7u83 221
}
222
 
223
EntryP
6 7u83 224
table_add_name(TableP table, NStringP key)
2 7u83 225
{
226
    BoolT found;
227
 
6 7u83 228
    return(table_add_entry(table, key, ET_NAME, &found));
2 7u83 229
}
230
 
231
EntryP
6 7u83 232
table_add_generated_name(TableP table)
2 7u83 233
{
6 7u83 234
    unsigned sequence = table_next_generated_key();
2 7u83 235
    unsigned hash     = (sequence % TABLE_SIZE);
6 7u83 236
    EntryP  *entryp   = &(table->contents[hash]);
2 7u83 237
    EntryP   entry;
238
 
6 7u83 239
    entry = entry_create_from_number(sequence, ET_NAME, FALSE, *entryp);
2 7u83 240
    *entryp = entry;
6 7u83 241
    return(entry);
2 7u83 242
}
243
 
244
EntryP
6 7u83 245
table_add_rename(TableP table)
2 7u83 246
{
6 7u83 247
    unsigned sequence = table_next_generated_key();
2 7u83 248
    unsigned hash     = (sequence % TABLE_SIZE);
6 7u83 249
    EntryP  *entryp   = &(table->contents[hash]);
2 7u83 250
    EntryP   entry;
251
 
6 7u83 252
    entry = entry_create_from_number(sequence, ET_RENAME, TRUE, *entryp);
2 7u83 253
    *entryp = entry;
6 7u83 254
    return(entry);
2 7u83 255
}
256
 
257
EntryP
6 7u83 258
table_add_non_local(TableP table, NStringP key, EntryP type)
2 7u83 259
{
260
    BoolT  found;
6 7u83 261
    EntryP entry = table_add_entry(table, key, ET_NON_LOCAL, &found);
2 7u83 262
 
263
    if (entry) {
6 7u83 264
	entry_set_non_local(entry, type);
2 7u83 265
    }
6 7u83 266
    return(entry);
2 7u83 267
}
268
 
269
EntryP
6 7u83 270
table_get_entry(TableP table, NStringP key)
2 7u83 271
{
6 7u83 272
    unsigned hash  = (nstring_hash_value(key)% TABLE_SIZE);
273
    EntryP   entry = (table->contents[hash]);
2 7u83 274
 
275
    while (entry) {
6 7u83 276
	KeyP ent_key = entry_key(entry);
2 7u83 277
 
6 7u83 278
	if ((key_is_string(ent_key)) &&
279
	   (nstring_equal(key_get_string(ent_key), key))) {
280
	    return(entry);
2 7u83 281
	}
282
	entry = entry->next;
283
    }
6 7u83 284
    return(NIL(EntryP));
2 7u83 285
}
286
 
287
EntryP
6 7u83 288
table_get_type(TableP table, NStringP key)
2 7u83 289
{
6 7u83 290
    EntryP entry = table_get_entry(table, key);
2 7u83 291
 
6 7u83 292
    if ((entry) && (entry_is_type(entry))) {
293
	return(entry);
2 7u83 294
    } else {
6 7u83 295
	return(NIL(EntryP));
2 7u83 296
    }
297
}
298
 
299
EntryP
6 7u83 300
table_get_basic(TableP table, NStringP key)
2 7u83 301
{
6 7u83 302
    EntryP entry = table_get_entry(table, key);
2 7u83 303
 
6 7u83 304
    if ((entry) && (entry_is_basic(entry))) {
305
	return(entry);
2 7u83 306
    } else {
6 7u83 307
	return(NIL(EntryP));
2 7u83 308
    }
309
}
310
 
311
EntryP
6 7u83 312
table_get_basic_by_number(TableP table, unsigned number)
2 7u83 313
{
314
    unsigned i;
315
 
6 7u83 316
    for (i = 0; i < TABLE_SIZE; i++) {
2 7u83 317
	EntryP entry;
318
 
6 7u83 319
	for (entry = table->contents[i]; entry; entry = entry_next(entry)) {
320
	    if (entry_is_basic(entry)) {
321
		BasicP basic = entry_get_basic(entry);
2 7u83 322
 
6 7u83 323
		if (basic_terminal(basic) == number) {
324
		    return(entry);
2 7u83 325
		}
326
	    }
327
	}
328
    }
6 7u83 329
    return(NIL(EntryP));
2 7u83 330
}
331
 
332
EntryP
6 7u83 333
table_get_action(TableP table, NStringP key)
2 7u83 334
{
6 7u83 335
    EntryP entry = table_get_entry(table, key);
2 7u83 336
 
6 7u83 337
    if ((entry) && (entry_is_action(entry))) {
338
	return(entry);
2 7u83 339
    } else {
6 7u83 340
	return(NIL(EntryP));
2 7u83 341
    }
342
}
343
 
344
EntryP
6 7u83 345
table_get_rule(TableP table, NStringP key)
2 7u83 346
{
6 7u83 347
    EntryP entry = table_get_entry(table, key);
2 7u83 348
 
6 7u83 349
    if ((entry) && (entry_is_rule(entry))) {
350
	return(entry);
2 7u83 351
    } else {
6 7u83 352
	return(NIL(EntryP));
2 7u83 353
    }
354
}
355
 
356
void
6 7u83 357
table_iter(TableP table, void (*proc)(EntryP, GenericP),
358
	   GenericP closure)
2 7u83 359
{
360
    unsigned i;
361
 
6 7u83 362
    for (i = 0; i < TABLE_SIZE; i++) {
2 7u83 363
	EntryP entry;
364
 
6 7u83 365
	for (entry = table->contents[i]; entry; entry = entry_next(entry)) {
366
	   (*proc)(entry, closure);
2 7u83 367
	}
368
    }
369
}
370
 
371
void
6 7u83 372
table_untrace(TableP table)
2 7u83 373
{
374
    unsigned i;
375
 
6 7u83 376
    for (i = 0; i < TABLE_SIZE; i++) {
2 7u83 377
	EntryP entry;
378
 
6 7u83 379
	for (entry = table->contents[i]; entry; entry = entry_next(entry)) {
380
	    entry_not_traced(entry);
2 7u83 381
	}
382
    }
383
}
384
 
385
void
6 7u83 386
table_unlink_untraced_rules(TableP table)
2 7u83 387
{
388
    unsigned i;
389
 
6 7u83 390
    for (i = 0; i < TABLE_SIZE; i++) {
391
	EntryP entry = (table->contents[i]);
2 7u83 392
 
393
	while (entry) {
6 7u83 394
	    if (entry_is_rule(entry) && (!entry_is_traced(entry))) {
395
		rule_deallocate(entry_get_rule(entry));
396
		entry_change_type(entry, ET_NAME);
2 7u83 397
	    }
6 7u83 398
	    entry = entry_next(entry);
2 7u83 399
	}
400
    }
401
}
402
 
403
/*
404
 * Local variables(smf):
405
 * eval: (include::add-path-entry "../os-interface" "../library")
406
 * eval: (include::add-path-entry "../generated")
407
 * end:
408
**/