Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 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
7 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:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 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;
7 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;
7 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 "types.h"
63
#include "help.h"
64
#include "high.h"
65
#include "table.h"
66
#include "tdf.h"
67
#include "utility.h"
68
 
69
 
70
/*
71
    HASHING FUNCTION
72
 
73
    This routine is used to construct the hash tables.  It takes a
74
    string s and returns a value in the range 0 <= n < hash_size.
75
*/
76
 
7 7u83 77
static int
78
hash(char *s)
2 7u83 79
{
7 7u83 80
    int n = 0;
81
    for (; *s; s++)n += *s;
82
    return(n % hash_size);
2 7u83 83
}
84
 
85
 
86
/*
87
    CONSTRUCT TABLES
88
 
89
    There are a number of tables of constructs.  cons_table is the
90
    table of all built-in constructs (arranged by sort and encoding),
91
    and var_table of all user defined constructs.  The tables
92
    cons_hash_tables and var_hash_tables give the corresponding
93
    hash tables (arranged by sort).  The table cons_sizes gives
94
    the number of built-in constructs of each sort.
95
*/
96
 
7 7u83 97
construct **var_table;
98
construct **cons_table;
99
static int *cons_sizes;
100
construct **cons_hash_tables;
101
static construct **var_hash_tables;
2 7u83 102
 
103
 
104
/*
105
    SORT INFORMATION TABLES
106
 
107
    These tables give information on the various sorts, namely, the
108
    number of them created, their decode letters, the number of bits
109
    in their encoding, the encoding of their "apply_token" construct,
110
    and the number of them removed from the hash tables.
111
*/
112
 
7 7u83 113
long *sort_count;
114
char *sort_letters;
115
int *sort_encoding;
116
int *sort_extension;
117
long *sort_tokens;
118
long *sort_conds;
119
long *sort_removed;
120
decode_func *sort_decode;
121
read_func *sort_read;
2 7u83 122
 
123
 
124
/*
125
    CREATE A TABLE FOR A NEW SORT
126
 
127
    A table of sz constructs of sort s is created and cleared.
128
*/
129
 
7 7u83 130
void
131
new_sort(sortname s, int sz)
2 7u83 132
{
7 7u83 133
    int i;
134
    construct *p = alloc_nof(construct, sz);
135
    for (i = 0; i < sz; i++) {
136
	(p + i) ->sortnum = s;
137
	(p + i) ->encoding = i;
138
	(p + i)->alias = null;
139
	(p + i)->ename = null;
140
	(p + i) ->name = null;
141
	(p + i) ->next = null;
142
	get_char_info(p + i) = null;
2 7u83 143
    }
7 7u83 144
    cons_table[s] = p;
145
    cons_sizes[s] = (int)sz;
146
    return;
2 7u83 147
}
148
 
149
 
150
/*
151
    PUT A NAME INTO A CONSTRUCT
152
 
153
    The nth construct of sort s is set to have name nm and argument
154
    string args.
155
*/
156
 
7 7u83 157
void
158
new_cons(char *nm, sortname s, int n, char *args)
2 7u83 159
{
7 7u83 160
    construct *p = cons_no(s, n);
161
    p->name = nm;
162
    if (add_to_cons_hash(p, s)) {
163
	fatal_error("Construct %s already defined", nm);
2 7u83 164
    }
7 7u83 165
    get_char_info(p) = args;
166
    return;
2 7u83 167
}
168
 
169
 
170
/*
171
    DUMMY DECODING FUNCTION
172
 
173
    This routine is a dummy which is used for uninitialised decode functions.
174
*/
175
 
7 7u83 176
static node *
177
de_dummy(void)
2 7u83 178
{
7 7u83 179
    fatal_error("Invalid decode function");
180
    return(null);
2 7u83 181
}
182
 
183
 
184
/*
185
    DUMMY READING FUNCTION
186
 
187
    This routine is a dummy which is used for uninitialised read functions.
188
*/
189
 
7 7u83 190
static node *
191
read_dummy(long n)
2 7u83 192
{
7 7u83 193
    fatal_error("Invalid read function");
194
    UNUSED(n);
195
    return(null);
2 7u83 196
}
197
 
198
 
199
/*
200
    INITIALIZE CONSTRUCT TABLES
201
 
202
    The various construct and sort tables are initialized.
203
*/
204
 
7 7u83 205
void
206
init_tables(void)
2 7u83 207
{
7 7u83 208
    int i;
2 7u83 209
 
210
    /* Allocate tables */
7 7u83 211
    cons_table = alloc_nof(construct *, SORT_no);
212
    cons_sizes = alloc_nof(int, SORT_no);
213
    cons_hash_tables = alloc_nof(construct *, SORT_no * hash_size);
214
    var_table = alloc_nof(construct *, SORT_no);
215
    var_hash_tables = alloc_nof(construct *, SORT_no * hash_size);
216
    sort_count = alloc_nof(long, SORT_no);
217
    sort_letters = alloc_nof(char, SORT_no + 1);
218
    sort_encoding = alloc_nof(int, SORT_no);
219
    sort_extension = alloc_nof(int, SORT_no);
220
    sort_tokens = alloc_nof(long, SORT_no);
221
    sort_conds = alloc_nof(long, SORT_no);
222
    sort_removed = alloc_nof(long, SORT_no);
223
    sort_decode = alloc_nof(decode_func, SORT_no);
224
    sort_read = alloc_nof(read_func, SORT_no);
2 7u83 225
 
226
    /* Clear out tables */
7 7u83 227
    for (i = 0; i < SORT_no; i++) {
228
	cons_table[i] = null;
229
	cons_sizes[i] = 0;
230
	var_table[i] = null;
231
	sort_count[i] = 0;
232
	sort_letters[i] = 'F';
233
	sort_encoding[i] = 0;
234
	sort_extension[i] = 0;
235
	sort_tokens[i] = -2;
236
	sort_conds[i] = -2;
237
	sort_removed[i] = 0;
238
	sort_decode[i] = de_dummy;
239
	sort_read[i] = read_dummy;
2 7u83 240
    }
7 7u83 241
    sort_letters[SORT_no] = 0;
2 7u83 242
 
243
    /* Initialize construct hash tables */
7 7u83 244
    for (i = 0; i < SORT_no * hash_size; i++) {
245
	cons_hash_tables[i] = null;
246
	var_hash_tables[i] = null;
2 7u83 247
    }
7 7u83 248
    return;
2 7u83 249
}
250
 
251
 
252
/*
253
    SPECIAL CONSTRUCTS
254
 
255
    These constructs are predefined.
256
*/
257
 
7 7u83 258
construct bytestream_cons = { SORT_bytestream, 0, null, null, null, null };
259
construct false_cons = { SORT_tdfbool, 0, null, null, null, null };
260
construct optional_cons = { SORT_option, 0, null, null, null, null };
261
construct string_cons = { SORT_tdfstring, -1, null, null, null, null };
262
construct token_cons = { SORT_token, 0, null, null, null, null };
263
construct true_cons = { SORT_tdfbool, 1, null, null, null, null };
264
construct unknown_cons = { SORT_unknown, 0, "....", null, null, null };
265
construct exp_shape = { SORT_exp, 0, "~exp_with_shape", null, null, null };
266
construct shape_of = { SORT_shape, -1, "~shape_of", null, null, null };
2 7u83 267
 
268
 
269
/*
270
    OUTPUT OPTIONS
271
 
272
    These flags give information on the form of the output.
273
*/
274
 
7 7u83 275
boolean show_tokdecs = 1;
276
boolean show_tokdefs = 1;
277
boolean show_aldecs = 1;
278
boolean show_aldefs = 1;
279
boolean show_tagdecs = 1;
280
boolean show_tagdefs = 1;
2 7u83 281
 
282
 
283
/*
284
    FIND THE NAME OF A GIVEN SORT
285
 
286
    Given the sort s, this routine returns the name of s.
287
*/
288
 
7 7u83 289
char *
290
sort_name(sortname s)
2 7u83 291
{
7 7u83 292
    if (is_high(s)) {
293
	high_sort *h = high_sorts + high_no(s);
294
	return(h->name);
295
    } else if (s == SORT_unknown || s < 0) {
296
	return("....");
2 7u83 297
    } else {
7 7u83 298
	construct *p = cons_no(SORT_sortname, s);
299
	return(p->name);
2 7u83 300
    }
301
}
302
 
303
 
304
/*
305
    ADD A NAME TO A CONSTRUCT HASH TABLE
306
 
307
    The construct p of sort s is added to the built-in construct hash
308
    table.  The routine returns a pointer to any existing entry of
309
    the same name, or null otherwise.
310
*/
311
 
7 7u83 312
construct *
313
add_to_cons_hash(construct *p, sortname s)
2 7u83 314
{
7 7u83 315
    construct *q;
316
    int n = hash(p->name);
317
    construct *h = cons_hash_tables[hash_size * s + n];
318
    for (q = h; q != null; q = q->next) {
319
	if (streq(p->name, q->name)) return(q);
2 7u83 320
    }
7 7u83 321
    p->next = h;
322
    cons_hash_tables[hash_size * s + n] = p;
323
    return(null);
2 7u83 324
}
325
 
326
 
327
/*
328
    LOOK UP A NAME IN A CONSTRUCT HASH TABLE
329
 
330
    A construct with name p and sort s is looked up in the built-in
331
    construct hash table.  The routine returns a pointer to the
332
    construct if it is found, or null otherwise.
333
*/
334
 
7 7u83 335
construct *
336
search_cons_hash(char *p, sortname s)
2 7u83 337
{
7 7u83 338
    construct *q;
339
    int n = hash(p);
340
    construct *h = cons_hash_tables[hash_size * s + n];
341
    for (q = h; q != null; q = q->next) {
342
	if (streq(p, q->name)) return(q);
2 7u83 343
    }
7 7u83 344
    return(null);
2 7u83 345
}
346
 
347
 
348
/*
349
    ADD A NAME TO A VARIABLE HASH TABLE
350
 
351
    The construct p of sort s is added to the user-defined construct
352
    hash table.  The routine returns a pointer to any existing entry
353
    of the same name, or null otherwise.
354
*/
355
 
7 7u83 356
construct *
357
add_to_var_hash(construct *p, sortname s)
2 7u83 358
{
7 7u83 359
    construct *q;
360
    int n = hash(p->name);
361
    construct *h = var_hash_tables[hash_size * s + n];
362
    for (q = h; q != null; q = q->next) {
363
	if (streq(p->name, q->name)) return(q);
2 7u83 364
    }
7 7u83 365
    p->next = h;
366
    var_hash_tables[hash_size * s + n] = p;
367
    return(null);
2 7u83 368
}
369
 
370
 
371
/*
372
    LOOK UP A NAME IN A VARIABLE HASH TABLE
373
 
374
    A construct with name p and sort s is looked up in the user-defined
375
    construct hash table.  The routine returns a pointer to the construct
376
    if it is found, or null otherwise.
377
*/
378
 
7 7u83 379
construct *
380
search_var_hash(char *p, sortname s)
2 7u83 381
{
7 7u83 382
    construct *q;
383
    int n = hash(p);
384
    construct *h = var_hash_tables[hash_size * s + n];
385
    for (q = h; q != null; q = q->next) {
386
	if (streq(p, q->name)) return(q);
2 7u83 387
    }
7 7u83 388
    return(null);
2 7u83 389
}
390
 
391
 
392
/*
393
    LIST OF ALL REMOVED CONSTRUCTS
394
 
395
    All constructs removed from the user-defined construct hash table
396
    are formed into a list.  This is used in node.c to form the
397
    completion of a node.
398
*/
399
 
7 7u83 400
construct *removals = null;
2 7u83 401
 
402
 
403
/*
404
    REMOVE A NAME FROM A VARIABLE HASH TABLE
405
 
406
    The construct with name p and sort s is removed from the
407
    user-defined hash table and added to the removals list.  There
408
    is no error if the construct does not exist.
409
*/
410
 
7 7u83 411
void
412
remove_var_hash(char *p, sortname s)
2 7u83 413
{
7 7u83 414
    int n = hash(p);
415
    construct *h = var_hash_tables[hash_size * s + n];
416
    if (h == null) return;
417
    if (streq(p, h->name)) {
2 7u83 418
	/* It is the first element */
7 7u83 419
	var_hash_tables[hash_size * s + n] = h->next;
420
	h->next = removals;
421
	removals = h;
422
	(sort_removed[s]) ++;
423
	return;
2 7u83 424
    }
7 7u83 425
    while (h->next) {
426
	if (streq(p, h->next->name)) {
2 7u83 427
	    /* It is a subsequent element */
7 7u83 428
	    construct *q = h->next->next;
429
	    h->next->next = removals;
430
	    removals = h->next;
431
	    h->next = q;
432
	   (sort_removed[s]) ++;
433
	    return;
2 7u83 434
	}
7 7u83 435
	h = h->next;
2 7u83 436
    }
437
    /* Not found */
7 7u83 438
    return;
2 7u83 439
}
440
 
441
 
442
/*
443
    SORT A HASH TABLE
444
 
445
    The constructs of sort s in the hash table tab are sorted into
446
    alphabetical order.  They are formed into a list where the
447
    constructs with hash value 0 should be.  After sorting the hash
448
    table cannot be used.
449
*/
450
 
7 7u83 451
void
452
sort_table(construct **tab, sortname s)
2 7u83 453
{
7 7u83 454
    int i;
455
    construct *q = null;
456
    for (i = 0; i < hash_size; i++) {
457
	construct *p = tab[hash_size * s + i];
458
	tab[hash_size * s + i] = null;
459
	while (p) {
460
	    construct *p_next = p->next;
461
	    construct *r_last = null, *r = q;
462
	    p->next = null;
463
	    while (r && strcmp(r->name, p->name) < 0) {
464
		r_last = r;
465
		r = r->next;
2 7u83 466
	    }
7 7u83 467
	    if (r_last == null) {
468
		p->next = q;
469
		q = p;
2 7u83 470
	    } else {
7 7u83 471
		r_last->next = p;
472
		p->next = r;
2 7u83 473
	    }
7 7u83 474
	    p = p_next;
2 7u83 475
	}
476
    }
7 7u83 477
    tab[hash_size * s] = q;
478
    return;
2 7u83 479
}
480
 
481
 
482
/*
483
    FLAG
484
 
485
    This flag may be set to false to prevent sort_all sorting its
486
    tables.
487
*/
488
 
7 7u83 489
boolean order_names = 1;
2 7u83 490
 
491
 
492
/*
493
    SORTING ROUTINE
494
 
495
    The user-defined alignment tags, tags and tokens are sorted into
496
    alphabetical order.
497
*/
498
 
7 7u83 499
void
500
sort_all(void)
2 7u83 501
{
7 7u83 502
    if (order_names) {
503
	sort_table(var_hash_tables, SORT_al_tag);
504
	sort_table(var_hash_tables, SORT_tag);
505
	sort_table(var_hash_tables, SORT_token);
2 7u83 506
    }
7 7u83 507
    return;
2 7u83 508
}
509
 
510
 
511
/*
512
    APPLY A PROCEDURE TO ALL CONSTRUCTS
513
 
514
    The routine f is applied to all user-defined constructs of sort s
515
    by scanning across the hash table.
516
*/
517
 
7 7u83 518
void
519
apply_to_all(apply_func f, sortname s)
2 7u83 520
{
7 7u83 521
    int i;
522
    for (i = 0; i < hash_size; i++) {
523
	construct *p = var_hash_tables[hash_size * s + i];
524
	while (p) {
525
	    construct *q = p->next;
526
	   (*f)(p);
527
	    p = q;
2 7u83 528
	}
529
    }
7 7u83 530
    return;
2 7u83 531
}