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 "check.h"
34
#include "de_types.h"
35
#include "de_capsule.h"
36
#include "decode.h"
37
#include "fetch.h"
38
#include "high.h"
39
#include "node.h"
40
#include "table.h"
41
#include "tdf.h"
42
#include "utility.h"
43
 
44
 
45
/*
46
    ARRAY OF ALL LABELS
47
 
48
    The labels in a unit are held in the table labels of size max_lab_no.
49
*/
50
 
51
static long max_lab_no = 0 ;
52
static construct *labels ;
53
 
54
 
55
/*
56
    SET UP LABELS
57
 
58
    A table of n labels is allocated and initialized.
59
*/
60
 
61
static void set_up_labels
62
    PROTO_N ( ( n ) )
63
    PROTO_T ( long n )
64
{
65
    long i ;
66
    static long lno = 0 ;
67
    max_lab_no = n ;
68
    labels = alloc_nof ( construct, n ) ;
69
    for ( i = 0 ; i < n ; i++ ) {
70
	char *nm = alloc_nof ( char, 32 ) ;
71
	IGNORE sprintf ( nm, "~~label_%ld", lno ) ;
72
	labels [i].sortnum = SORT_label ;
73
	labels [i].encoding = lno++ ;
74
	labels [i].name = nm ;
75
	labels [i].alias = null ;
76
	labels [i].next = null ;
77
	if ( add_to_var_hash ( labels + i, SORT_label ) ) {
78
	    input_error ( "Label %s already defined", nm ) ;
79
	}
80
    }
81
    return ;
82
}
83
 
84
 
85
/*
86
    FIND A LABEL
87
 
88
    The nth label in the current unit is returned.
89
*/
90
 
91
construct *find_label
92
    PROTO_N ( ( n ) )
93
    PROTO_T ( long n )
94
{
95
    if ( n < 0 || n >= max_lab_no ) {
96
	input_error ( "Label number %ld too big", n ) ;
97
	return ( null ) ;
98
    }
99
    return ( labels + n ) ;
100
}
101
 
102
 
103
/*
104
    DECODE A SORT NAME
105
 
106
    A sortname is decoded.  If expand is true the arguments of any high
107
    level sort will be stepped over.
108
*/
109
 
110
static sortname de_sortname
111
    PROTO_N ( ( expand ) )
112
    PROTO_T ( boolean expand )
113
{
114
    long n = de_sortname_bits () ;
115
    if ( n == SORT_token && expand ) {
116
	long i, m ;
117
	high_sort h, *hp ;
118
	static int made_up_sorts = 0 ;
119
	h.res = de_sortname ( 1 ) ;
120
	de_list_start () ;
121
	m = tdf_int () ;
122
	h.no_args = ( int ) m ;
123
	h.args = alloc_nof ( sortname, m ) ;
124
	h.name = alloc_nof ( char, 32 ) ;
125
	IGNORE sprintf ( h.name, "~~sort_%d", made_up_sorts++ ) ;
126
	for ( i = 0 ; i < m ; i++ ) {
127
	    h.args [i] = de_sortname ( 1 ) ;
128
	}
129
	hp = new_high_sort ( &h ) ;
130
	hp = unique_high_sort ( hp ) ;
131
	return ( hp->id ) ;
132
    }
133
    if ( n == SORT_foreign ) {
134
	warning ( "Foreign sorts not supported" ) ;
135
	IGNORE de_node ( "X" ) ;
136
	return ( SORT_unknown ) ;
137
    }
138
    return ( ( sortname ) n ) ;
139
}
140
 
141
 
142
/*
143
    DECODE AN ALIGNMENT TAG DEFINITION UNIT
144
 
145
    A number of alignment tag definitions are decoded.
146
*/
147
 
148
void de_aldef
149
    PROTO_Z ()
150
{
151
    long i, n = tdf_int () ;
152
    set_up_labels ( n ) ;
153
    n = tdf_int () ;
154
    for ( i = 0 ; i < n ; i++ ) {
155
	long t ;
156
	node *d ;
157
	construct *p ;
158
	al_tag_info *info ;
159
 
160
	/* Find the definition type */
161
	IGNORE de_al_tagdef_bits () ;
162
 
163
	/* Find the alignment tag */
164
	t = tdf_int () ;
165
	p = find_binding ( crt_binding, al_tag_var, t ) ;
166
	info = get_al_tag_info ( p ) ;
167
 
168
	/* Decode the definition (an alignment) */
169
	d = completion ( de_alignment () ) ;
170
	if ( info->def ) {
171
	    if ( !eq_node ( info->def, d ) ) {
172
		is_fatal = 0 ;
173
		input_error ( "Alignment tag %s defined inconsistently",
174
			      p->name ) ;
175
	    }
176
	    free_node ( d ) ;
177
	} else {
178
	    info->def = d ;
179
	}
180
    }
181
    return ;
182
}
183
 
184
 
185
/*
186
    DECODE A TAG DECLARATION UNIT
187
 
188
    A number of tag declarations are decoded.
189
*/
190
 
191
void de_tagdec
192
    PROTO_Z ()
193
{
194
    long i, n = tdf_int () ;
195
    set_up_labels ( n ) ;
196
    n = tdf_int () ;
197
    for ( i = 0 ; i < n ; i++ ) {
198
	long t ;
199
	node *d ;
200
	boolean is_var ;
201
	construct *p ;
202
	tag_info *info ;
203
 
204
	/* Find the declaration type */
205
	long m = de_tagdec_bits () ;
206
	if ( m == ENC_make_id_tagdec ) {
207
	    is_var = 0 ;
208
	} else if ( m == ENC_make_var_tagdec ) {
209
	    is_var = 1 ;
210
	} else {
211
	    is_var = 2 ;
212
	}
213
 
214
	/* Find the tag */
215
	t = tdf_int () ;
216
	p = find_binding ( crt_binding, tag_var, t ) ;
217
	set_tag_type ( p, is_var ) ;
218
	info = get_tag_info ( p ) ;
219
 
220
	/* Declaration = optional access + optional string + shape from 4.0 */
221
	d = completion ( de_node ( "?[u]?[X]S" ) ) ;
222
	info->var = is_var ;
223
	if ( info->dec ) {
224
	    if ( !eq_node ( info->dec, d ) ) {
225
		is_fatal = 0 ;
226
		input_error ( "Tag %s declared inconsistently", p->name ) ;
227
	    }
228
	    free_node ( d ) ;
229
	} else {
230
	    info->dec = d ;
231
	}
232
    }
233
    return ;
234
}
235
 
236
 
237
/*
238
    DECODE A TAG DEFINITION UNIT
239
 
240
    A number of tag definitions are decoded.
241
*/
242
 
243
void de_tagdef
244
    PROTO_Z ()
245
{
246
    long i, n = tdf_int () ;
247
    set_up_labels ( n ) ;
248
    n = tdf_int () ;
249
    for ( i = 0 ; i < n ; i++ ) {
250
	long t ;
251
	node *d ;
252
	construct *p ;
253
	tag_info *info ;
254
	boolean is_var ;
255
 
256
	/* Find the definition type */
257
	long m = de_tagdef_bits () ;
258
	if ( m == ENC_make_id_tagdef ) {
259
	    is_var = 0 ;
260
	} else if ( m == ENC_make_var_tagdef ) {
261
	    is_var = 1 ;
262
	} else {
263
	    is_var = 2 ;
264
	}
265
 
266
	/* Find the tag */
267
	t = tdf_int () ;
268
	p = find_binding ( crt_binding, tag_var, t ) ;
269
	info = get_tag_info ( p ) ;
270
	if ( info->dec == null ) {
271
	    input_error ( "Tag %s defined but not declared", p->name ) ;
272
	}
273
	set_tag_type ( p, is_var ) ;
274
 
275
	/* Added signature in 4.0 */
276
	d = completion ( de_node ( is_var ? "?[u]?[X]x" : "?[X]x" ) ) ;
277
	info->var = is_var ;
278
	if ( info->def ) {
279
	    if ( is_var == 2 ) {
280
		node *dp = info->def ;
281
		while ( dp->bro ) dp = dp->bro ;
282
		dp->bro = d ;
283
	    } else {
284
		if ( !eq_node ( info->def, d ) ) {
285
		    is_fatal = 0 ;
286
		    input_error ( "Tag %s defined inconsistently", p->name ) ;
287
		}
288
		free_node ( d ) ;
289
	    }
290
	} else {
291
	    info->def = d ;
292
	    if ( do_check ) check_tagdef ( p ) ;
293
	}
294
    }
295
    return ;
296
}
297
 
298
 
299
/*
300
    DECODE A TOKEN DECLARATION UNIT
301
 
302
    A number of token declarations are decoded.
303
*/
304
 
305
void de_tokdec
306
    PROTO_Z ()
307
{
308
    long i, n = tdf_int () ;
309
    for ( i = 0 ; i < n ; i++ ) {
310
	long t ;
311
	node *sig ;
312
	char *args ;
313
	sortname rs ;
314
	construct *p ;
315
	tok_info *info ;
316
 
317
	/* Find the declaration type */
318
	IGNORE de_tokdec_bits () ;
319
 
320
	/* Find the token */
321
	t = tdf_int () ;
322
	p = find_binding ( crt_binding, tok_var, t ) ;
323
	info = get_tok_info ( p ) ;
324
 
325
	/* Deal with signature */
326
	sig = de_node ( "?[X]" ) ;
327
 
328
	/* Decode token sort */
329
	rs = de_sortname ( 0 ) ;
330
	if ( rs == SORT_token ) {
331
	    long m ;
332
	    rs = de_sortname ( 1 ) ;
333
	    de_list_start () ;
334
	    m = tdf_int () ;
335
	    if ( m == 0 ) {
336
		args = null ;
337
	    } else {
338
		long j ;
339
		char abuff [100], *a = abuff ;
340
		for ( j = 0 ; j < m ; j++ ) {
341
		    sortname ps = de_sortname ( 1 ) ;
342
		    if ( is_high ( ps ) ) {
343
			sprint_high_sort ( a, ps ) ;
344
			while ( *a ) a++ ;
345
		    } else {
346
			*( a++ ) = sort_letters [ps] ;
347
		    }
348
		}
349
		*a = 0 ;
350
		args = string_copy_aux ( abuff ) ;
351
	    }
352
	} else {
353
	    args = null ;
354
	}
355
	if ( is_high ( rs ) ) {
356
	    input_error ( "Token %s has high-level result sort", p->name ) ;
357
	}
358
	set_token_sort ( p, rs, args, sig ) ;
359
	info->dec = 1 ;
360
    }
361
    return ;
362
}
363
 
364
 
365
/*
366
    DECODE A TOKEN DEFINITION BODY
367
 
368
    The actual body of a token definition is decoded.
369
*/
370
 
371
void de_token_defn
372
    PROTO_N ( ( p, sig ) )
373
    PROTO_T ( construct *p X node *sig )
374
{
375
    long m ;
376
    node *d ;
377
    char *args ;
378
    sortname rs ;
379
    tok_info *info = get_tok_info ( p ) ;
380
    construct **old_pars = info->pars ;
381
 
382
    /* Find the end of the definition */
383
    long end_posn = tdf_int () ;
384
    end_posn += input_posn () ;
385
 
386
    /* Find the definition type */
387
    IGNORE de_token_defn_bits () ;
388
 
389
    /* Decode the token sort */
390
    rs = de_sortname ( 1 ) ;
391
    de_list_start () ;
392
    m = tdf_int () ;
393
    if ( m == 0 ) {
394
	args = null ;
395
    } else {
396
	long j ;
397
	char abuff [100], *a = abuff ;
398
	if ( !in_skip_pass ) {
399
	    info->pars = alloc_nof ( construct *, m + 1 ) ;
400
	}
401
	for ( j = 0 ; j < m ; j++ ) {
402
	    /* Decode the token arguments */
403
	    sortname ps = de_sortname ( 1 ) ;
404
	    long pn = tdf_int () ;
405
	    construct *q = find_binding ( crt_binding, tok_var, pn ) ;
406
	    set_token_sort ( q, ps, ( char * ) null, ( node * ) null ) ;
407
	    if ( is_high ( ps ) ) {
408
		sprint_high_sort ( a, ps ) ;
409
		while ( *a ) a++ ;
410
	    } else {
411
		*( a++ ) = sort_letters [ps] ;
412
	    }
413
	    if ( !in_skip_pass ) info->pars [j] = q ;
414
	}
415
	*a = 0 ;
416
	args = string_copy_aux ( abuff ) ;
417
	if ( !in_skip_pass ) info->pars [j] = null ;
418
    }
419
    if ( is_high ( rs ) ) {
420
	input_error ( "Token %s has high-level result sort", p->name ) ;
421
    }
422
    set_token_sort ( p, rs, args, sig ) ;
423
    info->dec = 1 ;
424
 
425
    /* Decode the actual definition */
426
    if ( in_skip_pass ) {
427
	long bits = end_posn - input_posn () ;
428
	input_skip ( bits ) ;
429
    } else {
430
	char buff [2] ;
431
	buff [0] = sort_letters [rs] ;
432
	buff [1] = 0 ;
433
	d = completion ( de_node ( buff ) ) ;
434
	if ( info->def ) {
435
	    if ( !eq_node ( info->def, d ) ) {
436
		is_fatal = 0 ;
437
		input_error ( "Token %s defined inconsistently",
438
			      p->name ) ;
439
	    }
440
	    free_node ( d ) ;
441
	    info->pars = old_pars ;
442
	} else {
443
	    info->def = d ;
444
	}
445
	if ( rs == SORT_unknown ) {
446
	    long bits = end_posn - input_posn () ;
447
	    input_skip ( bits ) ;
448
	}
449
	if ( input_posn () != end_posn ) {
450
	    input_error ( "Token %s definition length wrong", p->name ) ;
451
	}
452
	if ( info->pars ) {
453
	    /* Mark the formal arguments as unused */
454
	    construct **ps ;
455
	    for ( ps = info->pars ; *ps ; ps++ ) {
456
		info = get_tok_info ( *ps ) ;
457
		info->dec = 0 ;
458
	    }
459
	}
460
    }
461
    return ;
462
}
463
 
464
 
465
/*
466
    DECODE A TOKEN DEFINITION UNIT
467
 
468
    A number of token definitions are decoded.
469
*/
470
 
471
void de_tokdef
472
    PROTO_Z ()
473
{
474
    long i, n = tdf_int () ;
475
    set_up_labels ( n ) ;
476
    n = tdf_int () ;
477
    for ( i = 0 ; i < n ; i++ ) {
478
	long t ;
479
	node *sig ;
480
	construct *p ;
481
 
482
	/* Find the definition type */
483
	IGNORE de_tokdef_bits () ;
484
 
485
	/* Find the token */
486
	t = tdf_int () ;
487
	p = find_binding ( crt_binding, tok_var, t ) ;
488
 
489
	/* Deal with signature */
490
	sig = de_node ( "?[X]" ) ;
491
 
492
	/* Decode token definition */
493
	de_token_defn ( p, sig ) ;
494
    }
495
    return ;
496
}
497
 
498
 
499
/*
500
    FLAG
501
 
502
    Has a version number been read?
503
*/
504
 
505
int have_version = 0 ;
506
 
507
 
508
/*
509
    CHECK A VERSION NUMBER
510
 
511
    This routine reads and checks a version number.
512
*/
513
 
514
static void de_version_number
515
    PROTO_Z ()
516
{
517
    long v1 = tdf_int () ;
518
    long v2 = tdf_int () ;
519
    if ( v1 != VERSION_major || v2 > VERSION_minor ) {
520
	input_error ( "Illegal version number, %ld.%ld", v1, v2 ) ;
521
    }
522
    have_version = 1 ;
523
    return ;
524
}
525
 
526
 
527
/*
528
    DECODE A VERSION UNIT
529
 
530
    A number of TDF version numbers are decoded.  These were only
531
    introduced for version 2.1 of the TDF specification.
532
*/
533
 
534
void de_version
535
    PROTO_Z ()
536
{
537
    long i, n = tdf_int () ;
538
    for ( i = 0 ; i < n ; i++ ) {
539
	long m = de_version_bits () ;
540
	if ( m == ENC_make_version ) {
541
	    de_version_number () ;
542
	} else if ( m == ENC_user_info ) {
543
	    IGNORE de_node ( "X" ) ;
544
	}
545
    }
546
    return ;
547
}
548
 
549
 
550
/*
551
    DECODE A MAGIC NUMBER
552
*/
553
 
554
void de_magic
555
    PROTO_N ( ( m ) )
556
    PROTO_T ( char *m )
557
{
558
    int i, n = ( int ) strlen ( m ) ;
559
    for ( i = 0 ; i < n ; i++ ) {
560
	long c = fetch ( 8 ) ;
561
	if ( c != ( long ) m [i] ) {
562
	    input_error ( "Bad magic number" ) ;
563
	    return ;
564
	}
565
    }
566
    de_version_number () ;
567
    byte_align () ;
568
    return ;
569
}