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