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 "enc_types.h"
34
#include "bitstream.h"
35
#include "encode.h"
36
#include "high.h"
37
#include "names.h"
38
#include "table.h"
39
#include "tdf.h"
40
#include "utility.h"
41
 
42
 
43
/*
44
    ENCODE AN EXTENDED VALUE
45
 
46
    The extended value n is encoded in b bits on the bitstream p.
47
*/
48
 
49
void enc_bits_extn
50
    PROTO_N ( ( p, b, n ) )
51
    PROTO_T ( bitstream *p X int b X long n )
52
{
53
    long m = ( ( 1 << b ) - 1 ) ;
54
    if ( n == 0 ) fatal_error ( "Can't encode 0 as an extended value" ) ;
55
    while ( n > m ) {
56
	enc_bits ( p, b, ( long ) 0 ) ;
57
	n -= m ;
58
    }
59
    enc_bits ( p, b, n ) ;
60
    return ;
61
}
62
 
63
 
64
/*
65
    AUXILIARY TDF INTEGER ENCODING ROUTINE
66
 
67
    The value n is encoded as a series of octal digits into the
68
    bitstream p.
69
*/
70
 
71
static void enc_tdf_int_aux
72
    PROTO_N ( ( p, n ) )
73
    PROTO_T ( bitstream *p X long n )
74
{
75
    unsigned long m = ( unsigned long ) n ;
76
    if ( m >= 8 ) enc_tdf_int_aux ( p, ( long ) ( m >> 3 ) ) ;
77
    enc_bits ( p, 4, ( long ) ( m & 7 ) ) ;
78
    return ;
79
}
80
 
81
 
82
/*
83
    ENCODE A TDF INTEGER
84
 
85
    The value n is encoded as a TDF integer into the bitstream p.
86
*/
87
 
88
void enc_tdf_int
89
    PROTO_N ( ( p, n ) )
90
    PROTO_T ( bitstream *p X long n )
91
{
92
    unsigned long m = ( unsigned long ) n ;
93
    if ( m >= 8 ) enc_tdf_int_aux ( p, ( long ) ( m >> 3 ) ) ;
94
    enc_bits ( p, 4, ( long ) ( ( m & 7 ) | 8 ) ) ;
95
    return ;
96
}
97
 
98
 
99
/*
100
    ENCODE AN ALIGNED STRING
101
 
102
    The string s is encoded as an aligned string into the bitstream p.
103
    n is either the length of s, or -1, indicating that strlen should
104
    be used to find the length.
105
*/
106
 
107
void enc_aligned_string
108
    PROTO_N ( ( p, s, n ) )
109
    PROTO_T ( bitstream *p X char *s X long n )
110
{
111
    long i ;
112
    if ( n == -1 ) n = ( long ) strlen ( s ) ;
113
    enc_tdf_int ( p, ( long ) 8 ) ;
114
    enc_tdf_int ( p, n ) ;
115
    align_bitstream ( p ) ;
116
    for ( i = 0 ; i < n ; i++ ) {
117
	long c = ( long ) s [i] ;
118
	enc_bits ( p, 8, c ) ;
119
    }
120
    return ;
121
}
122
 
123
 
124
/*
125
    ENCODE AN EXTERNAL NAME
126
 
127
    The external name of the construct p is encoded into the bitstream b.
128
*/
129
 
130
void enc_external
131
    PROTO_N ( ( b, p ) )
132
    PROTO_T ( bitstream *b X construct *p )
133
{
134
    node *e = p->ename ;
135
    enc_tdf_int ( b, p->encoding ) ;
136
    if ( e->cons->encoding ) {
137
	node *q = e->son ;
138
	if ( q->cons->sortnum == SORT_tdfstring ) {
139
	    node *r = q->bro ;
140
	    if ( r == null ) {
141
		enc_external_bits ( b, ENC_string_extern ) ;
142
		align_bitstream ( b ) ;
143
		enc_aligned_string ( b, q->cons->name, q->cons->encoding ) ;
144
	    } else {
145
		enc_external_bits ( b, ENC_chain_extern ) ;
146
		align_bitstream ( b ) ;
147
		enc_aligned_string ( b, q->cons->name, q->cons->encoding ) ;
148
		enc_node ( b, r ) ;
149
	    }
150
	} else {
151
	    enc_external_bits ( b, ENC_unique_extern ) ;
152
	    align_bitstream ( b ) ;
153
	    enc_tdf_int ( b, q->cons->encoding ) ;
154
	    for ( q = e->son->son ; q ; q = q->bro ) {
155
		enc_aligned_string ( b, q->cons->name, q->cons->encoding ) ;
156
	    }
157
	}
158
    } else {
159
	enc_external_bits ( b, ENC_string_extern ) ;
160
	align_bitstream ( b ) ;
161
	enc_aligned_string ( b, p->name, ( long ) -1 ) ;
162
    }
163
    return ;
164
}
165
 
166
 
167
/*
168
    FIND THE VALUE OF A STRING OF OCTAL DIGITS
169
 
170
    The value of the node p, which represents a number, is returned.
171
*/
172
 
173
static long octval
174
    PROTO_N ( ( p ) )
175
    PROTO_T ( node *p )
176
{
177
    long n = ( long ) octal_to_ulong ( p->bro->cons->name ) ;
178
    if ( p->cons->encoding ) n = -n ;
179
    return ( n ) ;
180
}
181
 
182
 
183
/*
184
    ENCODE A NODE
185
 
186
    The node p is encoded into the bitstream b.
187
*/
188
 
189
void enc_node
190
    PROTO_N ( ( b, p ) )
191
    PROTO_T ( bitstream *b X node *p )
192
{
193
    while ( p ) {
194
	construct *q = p->cons ;
195
	switch ( q->sortnum ) {
196
 
197
	    case SORT_tdfbool : {
198
		/* Encode a bit */
199
		enc_bits ( b, 1, q->encoding ) ;
200
		break ;
201
	    }
202
 
203
	    case SORT_bytestream : {
204
		/* Encode a bytestream */
205
		bitstream *c = new_bitstream () ;
206
		enc_node ( c, p->son ) ;
207
		enc_tdf_int ( b, bitstream_length ( c ) ) ;
208
		join_bitstreams ( b, c ) ;
209
		break ;
210
	    }
211
 
212
	    case SORT_completion : {
213
		/* Encode a completion */
214
		if ( p->son ) enc_node ( b, p->son ) ;
215
		break ;
216
	    }
217
 
218
	    case SORT_small_tdfint : {
219
		/* Encode a small integer */
220
		enc_tdf_int ( b, q->encoding ) ;
221
		break ;
222
	    }
223
 
224
	    case SORT_tdfint : {
225
		/* Encode a number */
226
		char *num = q->name ;
227
		while ( *num ) {
228
		    long d = ( long ) ( *num - '0' ) ;
229
		    num++ ;
230
		    if ( *num == 0 ) d |= 8 ;
231
		    enc_bits ( b, 4, d ) ;
232
		}
233
		break ;
234
	    }
235
 
236
	    case SORT_option : {
237
		/* Encode an optional argument */
238
		if ( p->son ) {
239
		    enc_bits ( b, 1, ( long ) 1 ) ;
240
		    enc_node ( b, p->son ) ;
241
		} else {
242
		    enc_bits ( b, 1, ( long ) 0 ) ;
243
		}
244
		break ;
245
	    }
246
 
247
	    case SORT_repeat : {
248
		/* Encode a repeated argument */
249
		enc_list_start ( b ) ;
250
		enc_tdf_int ( b, q->encoding ) ;
251
		if ( p->son ) enc_node ( b, p->son ) ;
252
		break ;
253
	    }
254
 
255
	    case SORT_tdfstring : {
256
		/* Encode a string */
257
		long i, n = q->encoding ;
258
		if ( n == -1 ) {
259
		    node *r = p->son ;
260
		    long m = octval ( r ) ;
261
		    if ( m < 0 ) m = -m ;
262
		    r = r->bro->bro ;
263
		    n = r->cons->encoding ;
264
		    r = r->son ;
265
		    enc_tdf_int ( b, m ) ;
266
		    enc_tdf_int ( b, n ) ;
267
		    for ( i = 0 ; i < n ; i++ ) {
268
			enc_bits ( b, ( int ) m, octval ( r ) ) ;
269
			r = r->bro->bro ;
270
		    }
271
		} else {
272
		    enc_tdf_int ( b, ( long ) 8 ) ;
273
		    enc_tdf_int ( b, n ) ;
274
		    for ( i = 0 ; i < n ; i++ ) {
275
			long c = ( long ) q->name [i] ;
276
			enc_bits ( b, 8, c ) ;
277
		    }
278
		}
279
		break ;
280
	    }
281
 
282
	    case SORT_unknown : {
283
		/* Encode an unknown bitstream */
284
		fatal_error ( "Can't encode unknown bitstream" ) ;
285
		break ;
286
	    }
287
 
288
	    case SORT_al_tag : {
289
		/* Encode an alignment tag */
290
		long e = q->encoding ;
291
		enc_al_tag_bits ( b, ( int ) e ) ;
292
		if ( e == ENC_make_al_tag ) {
293
		    enc_tdf_int ( b, p->son->cons->encoding ) ;
294
		} else {
295
		    if ( p->son ) enc_node ( b, p->son ) ;
296
		}
297
		break ;
298
	    }
299
 
300
	    case SORT_label : {
301
		/* Encode a label */
302
		long e = q->encoding ;
303
		enc_label_bits ( b, ( int ) e ) ;
304
		if ( e == ENC_make_label ) {
305
		    enc_tdf_int ( b, p->son->cons->encoding ) ;
306
		} else {
307
		    if ( p->son ) enc_node ( b, p->son ) ;
308
		}
309
		break ;
310
	    }
311
 
312
	    case SORT_tag : {
313
		/* Encode a tag */
314
		long e = q->encoding ;
315
		enc_tag_bits ( b, ( int ) e ) ;
316
		if ( e == ENC_make_tag ) {
317
		    enc_tdf_int ( b, p->son->cons->encoding ) ;
318
		} else {
319
		    if ( p->son ) enc_node ( b, p->son ) ;
320
		}
321
		break ;
322
	    }
323
 
324
	    case SORT_token : {
325
		/* Encode a token */
326
		tok_info *info = get_tok_info ( q ) ;
327
		if ( is_high ( info->res ) ) {
328
		    enc_token_bits ( b, ENC_token_apply_token ) ;
329
		    enc_token_bits ( b, ENC_make_tok ) ;
330
		    enc_tdf_int ( b, q->encoding ) ;
331
		    enc_tdf_int ( b, ( long ) 0 ) ;
332
		} else {
333
		    enc_token_bits ( b, ENC_make_tok ) ;
334
		    enc_tdf_int ( b, q->encoding ) ;
335
		}
336
		if ( p->son ) {
337
		    if ( p->son->cons != &token_cons ) {
338
			bitstream *c = new_bitstream () ;
339
			enc_node ( c, p->son ) ;
340
			enc_tdf_int ( b, bitstream_length ( c ) ) ;
341
			join_bitstreams ( b, c ) ;
342
		    }
343
		} else {
344
		    enc_tdf_int ( b, ( long ) 0 ) ;
345
		}
346
		break ;
347
	    }
348
 
349
	    default : {
350
		/* Encode a simple sort */
351
		int bits = sort_encoding [ q->sortnum ] ;
352
		int extn = sort_extension [ q->sortnum ] ;
353
		if ( extn ) {
354
		    enc_bits_extn ( b, bits, q->encoding ) ;
355
		} else {
356
		    enc_bits ( b, bits, q->encoding ) ;
357
		}
358
		if ( p->son ) enc_node ( b, p->son ) ;
359
		break ;
360
	    }
361
	}
362
	p = p->bro ;
363
    }
364
    return ;
365
}
366
 
367
 
368
/*
369
    ENCODE A SORT
370
*/
371
 
372
static void enc_sort
373
    PROTO_N ( ( b, s ) )
374
    PROTO_T ( bitstream *b X sortname s )
375
{
376
    if ( is_high ( s ) ) {
377
	int i ;
378
	high_sort *h = high_sorts + high_no ( s ) ;
379
	enc_sort ( b, SORT_token ) ;
380
	enc_sort ( b, h->res ) ;
381
	enc_list_start ( b ) ;
382
	enc_tdf_int ( b, ( long ) h->no_args ) ;
383
	for ( i = 0 ; i < h->no_args ; i++ ) {
384
	    enc_sort ( b, h->args [i] ) ;
385
	}
386
    } else {
387
	enc_sortname_bits ( b, s ) ;
388
    }
389
    return ;
390
}
391
 
392
 
393
/*
394
    ALIGNMENT TAG DEFINITION AUXILIARY ENCODING ROUTINE
395
 
396
    The definition of the alignment tag p is encoded into the bitstream p.
397
*/
398
 
399
void enc_aldef
400
    PROTO_N ( ( b, p ) )
401
    PROTO_T ( bitstream *b X construct *p )
402
{
403
    al_tag_info *info = get_al_tag_info ( p ) ;
404
    enc_al_tagdef_bits ( b, ENC_make_al_tagdef ) ;
405
    enc_tdf_int ( b, p->encoding ) ;
406
    enc_node ( b, info->def ) ;
407
    return ;
408
}
409
 
410
 
411
/*
412
    TAG DECLARATION AUXILIARY ENCODING ROUTINE
413
 
414
    The declaration of the tag p is encoded into the bitstream p.
415
*/
416
 
417
void enc_tagdec
418
    PROTO_N ( ( b, p ) )
419
    PROTO_T ( bitstream *b X construct *p )
420
{
421
    int m = 0 ;
422
    tag_info *info = get_tag_info ( p ) ;
423
    switch ( info->var ) {
424
	case 0 : m = ENC_make_id_tagdec ; break ;
425
	case 1 : m = ENC_make_var_tagdec ; break ;
426
	case 2 : m = ENC_common_tagdec ; break ;
427
    }
428
    enc_tagdec_bits ( b, m ) ;
429
    enc_tdf_int ( b, p->encoding ) ;
430
    enc_node ( b, info->dec ) ;
431
    return ;
432
}
433
 
434
 
435
/*
436
    TAG DEFINITION AUXILIARY ENCODING ROUTINE
437
 
438
    The definition of the tag p is encoded into the bitstream p.  Because
439
    of common_tagdef, there may actually be more than one definition.
440
    The number of definitions is returned.
441
*/
442
 
443
int enc_tagdef
444
    PROTO_N ( ( b, p ) )
445
    PROTO_T ( bitstream *b X construct *p )
446
{
447
    int n = 0 ;
448
    int m = 0 ;
449
    tag_info *info = get_tag_info ( p ) ;
450
    node *d = info->def ;
451
    switch ( info->var ) {
452
	case 0 : m = ENC_make_id_tagdef ; break ;
453
	case 1 : m = ENC_make_var_tagdef ; break ;
454
	case 2 : m = ENC_common_tagdef ; break ;
455
    }
456
    while ( d ) {
457
	/* Can have multiple definitions */
458
	enc_tagdef_bits ( b, m ) ;
459
	enc_tdf_int ( b, p->encoding ) ;
460
	enc_node ( b, d->son ) ;
461
	d = d->bro ;
462
	n++ ;
463
    }
464
    return ( n ) ;
465
}
466
 
467
 
468
/*
469
    WORK OUT THE NUMBER OF FORMAL ARGUMENTS GIVEN A STRING
470
*/
471
 
472
static long no_formals
473
    PROTO_N ( ( args ) )
474
    PROTO_T ( char *args )
475
{
476
    long n = 0 ;
477
    while ( *args ) {
478
	args = find_sortname ( args, ( sortname * ) null ) ;
479
	args++ ;
480
	n = n + 1 ;
481
    }
482
    return ( n ) ;
483
}
484
 
485
 
486
/*
487
    TOKEN DECLARATION AUXILIARY ENCODING ROUTINE
488
 
489
    The declaration of the token p is encoded into the bitstream p.
490
*/
491
 
492
void enc_tokdec
493
    PROTO_N ( ( b, p ) )
494
    PROTO_T ( bitstream *b X construct *p )
495
{
496
    tok_info *info = get_tok_info ( p ) ;
497
    enc_tokdec_bits ( b, ENC_make_tokdec ) ;
498
    enc_tdf_int ( b, p->encoding ) ;
499
 
500
    /* Deal with signature */
501
    if ( info->sig == null ) {
502
	enc_bits ( b, 1, ( long ) 0 ) ;
503
    } else {
504
	enc_node ( b, info->sig ) ;
505
    }
506
 
507
    /* Encode token sort */
508
    enc_sort ( b, SORT_token ) ;
509
 
510
    /* Encode the token result sort */
511
    enc_sort ( b, info->res ) ;
512
 
513
    /* Encode the token argument sorts */
514
    enc_list_start ( b ) ;
515
    if ( info->args ) {
516
	char *q = info->args ;
517
	enc_tdf_int ( b, no_formals ( q ) ) ;
518
	while ( *q ) {
519
	    sortname s ;
520
	    q = find_sortname ( q, &s ) ;
521
	    q++ ;
522
	    enc_sort ( b, s ) ;
523
	}
524
    } else {
525
	enc_tdf_int ( b, ( long ) 0 ) ;
526
    }
527
    return ;
528
}
529
 
530
 
531
/*
532
    TOKEN DEFINITION AUXILIARY ENCODING ROUTINE
533
 
534
    The definition of the token p is encoded into the bitstream p.
535
*/
536
 
537
void enc_tokdef
538
    PROTO_N ( ( b, p ) )
539
    PROTO_T ( bitstream *b X construct *p )
540
{
541
    bitstream *c = new_bitstream () ;
542
    tok_info *info = get_tok_info ( p ) ;
543
    enc_tokdef_bits ( b, ENC_make_tokdef ) ;
544
    enc_tdf_int ( b, p->encoding ) ;
545
 
546
    /* Deal with signature */
547
    if ( info->sig == null ) {
548
	enc_bits ( b, 1, ( long ) 0 ) ;
549
    } else {
550
	enc_node ( b, info->sig ) ;
551
    }
552
 
553
    /* Encode token definition type */
554
    enc_token_defn_bits ( c, ENC_token_definition ) ;
555
 
556
    /* Encode the token result sort */
557
    enc_sort ( c, info->res ) ;
558
 
559
    /* Encode the token arguments */
560
    enc_list_start ( c ) ;
561
    if ( info->args ) {
562
	construct **q = info->pars ;
563
	enc_tdf_int ( c, no_formals ( info->args ) ) ;
564
	while ( *q ) {
565
	    tok_info *qinfo = get_tok_info ( *q ) ;
566
	    enc_sort ( c, qinfo->res ) ;
567
	    enc_tdf_int ( c, ( *q )->encoding ) ;
568
	    q++ ;
569
	}
570
    } else {
571
	enc_tdf_int ( c, ( long ) 0 ) ;
572
    }
573
 
574
    /* Encode the token definition */
575
    enc_node ( c, info->def ) ;
576
    enc_tdf_int ( b, bitstream_length ( c ) ) ;
577
    join_bitstreams ( b, c ) ;
578
    return ;
579
}