Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | 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 "names.h"
37
#include "node.h"
38
#include "table.h"
39
#include "tdf.h"
40
#include "utility.h"
41
 
42
 
43
/*
44
    CURRENT BITSTREAM
45
 
46
    This is the main bitstream.
47
*/
48
 
49
static bitstream *crt_bitstream ;
50
 
51
 
52
/*
53
    NUMBERS OF EQUATIONS AND VARIABLE SORTS
54
 
55
    The number of equation types and variable sorts in the output capsule.
56
*/
57
 
58
static long eqn_total, var_total ;
59
 
60
 
61
/*
62
    LINKAGE INFORMATION ENCODING VARIABLES
63
 
64
    The tld2 unit gives information on the use, declaration and
65
    definition of the externally named tags and tokens.
66
*/
67
 
68
static bitstream *tld_bs ;
69
 
70
 
71
/*
72
    ALIGNMENT TAG ENCODING VARIABLES
73
 
74
    The alignment tag definitions are formed in the bitstream al_tag_defs_bs.
75
    There are al_tag_total alignment tags, of which al_tag_external have
76
    external names and al_tag_defs are defined.
77
*/
78
 
79
static long al_tag_total = 0 ;
80
static long al_tag_external = 0 ;
81
static long al_tag_defs = 0 ;
82
static bitstream *al_tag_defs_bs ;
83
 
84
 
85
/*
86
    AUXILIARY ALIGNMENT TAG ENCODING ROUTINE
87
 
88
    The alignment tag encoding variables are modified according to the
89
    construct p.
90
*/
91
 
92
static void enc_al_tag_aux
93
    PROTO_N ( ( p ) )
94
    PROTO_T ( construct *p )
95
{
96
    al_tag_info *info = get_al_tag_info ( p ) ;
97
    al_tag_total++ ;
98
    if ( p->ename ) {
99
	al_tag_external++ ;
100
	enc_tdf_int ( tld_bs, ( long ) ( info->def ? 5 : 1 ) ) ;
101
    }
102
    if ( info->def == null ) return ;
103
    al_tag_defs++ ;
104
    enc_aldef ( al_tag_defs_bs, p ) ;
105
    return ;
106
}
107
 
108
 
109
/*
110
    AUXILIARY ROUTINE FOR ENCODING ALIGNMENT TAG NAMES
111
 
112
    The external name (if any) of the alignment tag construct p is encoded.
113
*/
114
 
115
static void enc_al_tag_names
116
    PROTO_N ( ( p ) )
117
    PROTO_T ( construct *p )
118
{
119
    if ( p->ename == null ) return ;
120
    enc_external ( crt_bitstream, p ) ;
121
    return ;
122
}
123
 
124
 
125
/*
126
    TAG ENCODING VARIABLES
127
 
128
    The tag declarations are formed in the bitstream tag_decs_bs and
129
    the definitions in tag_defs_bs.  There are tag_total tags, of
130
    which tag_external have external names, tag_decs have declarations
131
    and tag_defs have definitions.
132
*/
133
 
134
static long tag_total = 0 ;
135
static long tag_external = 0 ;
136
static long tag_decs = 0 ;
137
static long tag_defs = 0 ;
138
static bitstream *tag_decs_bs ;
139
static bitstream *tag_defs_bs ;
140
 
141
 
142
/*
143
    AUXILIARY TAG ENCODING ROUTINE
144
 
145
    The tag encoding variables are modified according to the construct p.
146
*/
147
 
148
static void enc_tag_aux
149
    PROTO_N ( ( p ) )
150
    PROTO_T ( construct *p )
151
{
152
    tag_info *info = get_tag_info ( p ) ;
153
    tag_total++ ;
154
    if ( info->var == 3 ) return ;
155
    if ( p->ename ) {
156
	tag_external++ ;
157
	enc_tdf_int ( tld_bs, ( long ) ( info->def ? 7 : 3 ) ) ;
158
    }
159
    tag_decs++ ;
160
    enc_tagdec ( tag_decs_bs, p ) ;
161
    if ( info->def == null ) return ;
162
    tag_defs += enc_tagdef ( tag_defs_bs, p ) ;
163
    return ;
164
}
165
 
166
 
167
/*
168
    AUXILIARY ROUTINE FOR ENCODING TAG NAMES
169
 
170
    The external name (if any) of the tag construct p is encoded.
171
*/
172
 
173
static void enc_tag_names
174
    PROTO_N ( ( p ) )
175
    PROTO_T ( construct *p )
176
{
177
    tag_info *info = get_tag_info ( p ) ;
178
    if ( info->var == 3 ) return ;
179
    if ( p->ename == null ) return ;
180
    enc_external ( crt_bitstream, p ) ;
181
    return ;
182
}
183
 
184
 
185
/*
186
    TOKEN ENCODING VARIABLES
187
 
188
    The token declarations are formed in the bitstream tok_decs_bs and
189
    the definitions in tok_defs_bs.  There are tok_total tokens, of
190
    which tok_external have external names, tok_decs have declarations
191
    and tok_defs have definitions.
192
*/
193
 
194
static long tok_total = 0 ;
195
static long tok_external = 0 ;
196
static long tok_decs = 0 ;
197
static long tok_defs = 0 ;
198
static bitstream *tok_decs_bs ;
199
static bitstream *tok_defs_bs ;
200
 
201
 
202
/*
203
    AUXILIARY TOKEN ENCODING ROUTINE
204
 
205
    The token encoding variables are modified according to the construct p.
206
*/
207
 
208
static void enc_token_aux
209
    PROTO_N ( ( p ) )
210
    PROTO_T ( construct *p )
211
{
212
    tok_info *info = get_tok_info ( p ) ;
213
    if ( p->encoding == -1 ) return ;
214
    tok_total++ ;
215
    if ( info->dec == 0 ) return ;
216
    if ( p->ename ) {
217
	tok_external++ ;
218
	if ( info->def ) {
219
	    enc_tdf_int ( tld_bs, ( long ) 5 ) ;
220
	} else {
221
	    enc_tdf_int ( tld_bs, ( long ) 3 ) ;
222
	}
223
    }
224
    if ( info->def == null || !show_tokdefs ) {
225
	if ( info->args ) {
226
	    tok_decs++ ;
227
	    enc_tokdec ( tok_decs_bs, p ) ;
228
	}
229
    } else {
230
	tok_defs++ ;
231
	enc_tokdef ( tok_defs_bs, p ) ;
232
    }
233
    return ;
234
}
235
 
236
 
237
/*
238
    AUXILIARY ROUTINE FOR ENCODING TOKEN NAMES
239
 
240
    The external name (if any) of the token construct p is encoded.
241
*/
242
 
243
static void enc_token_names
244
    PROTO_N ( ( p ) )
245
    PROTO_T ( construct *p )
246
{
247
    tok_info *info = get_tok_info ( p ) ;
248
    if ( p->encoding == -1 ) return ;
249
    if ( info->dec == 0 ) return ;
250
    if ( p->ename == null ) return ;
251
    enc_external ( crt_bitstream, p ) ;
252
    return ;
253
}
254
 
255
 
256
/*
257
    LABEL ENCODING VARIABLES
258
 
259
    There are lab_total labels.
260
*/
261
 
262
static long lab_total = 0 ;
263
 
264
 
265
/*
266
    AUXILIARY LABEL ENCODING ROUTINE
267
 
268
    The label encoding variables are modified according to the construct p.
269
*/
270
 
271
/*ARGSUSED*/ static void enc_label_aux
272
    PROTO_N ( ( p ) )
273
    PROTO_T ( construct *p )
274
{
275
    UNUSED ( p ) ;
276
    lab_total++ ;
277
    return ;
278
}
279
 
280
 
281
/*
282
    ENCODE A SET OF LINKS
283
 
284
    A set of ntok token link, nalign alignment tag links and ntag tag
285
    nlinks are encoded into the bitstream p.  Since the same numbers
286
    are used for variable sorts in all the encoded units these links
287
    are identities.
288
*/
289
 
290
static void enc_links
291
    PROTO_N ( ( p, ntok, nalign, ntag ) )
292
    PROTO_T ( bitstream *p X long ntok X long nalign X long ntag )
293
{
294
    long i ;
295
    enc_tdf_int ( p, var_total ) ;
296
    if ( tok_total ) enc_tdf_int ( p, ntok ) ;
297
    if ( al_tag_total ) enc_tdf_int ( p, nalign ) ;
298
    if ( tag_total ) enc_tdf_int ( p, ntag ) ;
299
    enc_tdf_int ( p, var_total ) ;
300
 
301
    /* Token links */
302
    if ( tok_total ) {
303
	enc_tdf_int ( p, ntok ) ;
304
	for ( i = 0 ; i < ntok ; i++ ) {
305
	    enc_tdf_int ( p, i ) ;
306
	    enc_tdf_int ( p, i ) ;
307
	}
308
    }
309
 
310
    /* Alignment tag links */
311
    if ( al_tag_total ) {
312
	enc_tdf_int ( p, nalign ) ;
313
	for ( i = 0 ; i < nalign ; i++ ) {
314
	    enc_tdf_int ( p, i ) ;
315
	    enc_tdf_int ( p, i ) ;
316
	}
317
    }
318
 
319
    /* Tag links */
320
    if ( tag_total ) {
321
	enc_tdf_int ( p, ntag ) ;
322
	for ( i = 0 ; i < ntag ; i++ ) {
323
	    enc_tdf_int ( p, i ) ;
324
	    enc_tdf_int ( p, i ) ;
325
	}
326
    }
327
    return ;
328
}
329
 
330
 
331
/*
332
    EQUATION TYPES
333
*/
334
 
335
#define EQN_VERS	0
336
#define EQN_TLD		1
337
#define EQN_TOKDEC	2
338
#define EQN_TOKDEF	3
339
#define EQN_ALDEF	4
340
#define EQN_TAGDEC	5
341
#define EQN_TAGDEF	6
342
 
343
 
344
/*
345
    ENCODE AN EQUATION
346
 
347
    The ne equations of type t (see above) given in the bitstream q are
348
    encoded into the bitstream p.
349
*/
350
 
351
static void enc_equation
352
    PROTO_N ( ( p, ne, q, t ) )
353
    PROTO_T ( bitstream *p X long ne X bitstream *q X int t )
354
{
355
    long n ;
356
    bitstream *u ;
357
 
358
    if ( ne == 0 ) {
359
	/* There are no sets of equations */
360
	enc_tdf_int ( p, ( long ) 0 ) ;
361
	return ;
362
    }
363
 
364
    /* There is one set of equations */
365
    enc_tdf_int ( p, ( long ) 1 ) ;
366
    u = new_bitstream () ;
367
 
368
    /* Encode the links */
369
    switch ( t ) {
370
	case EQN_VERS : {
371
	    enc_links ( p, ( long ) 0, ( long ) 0, ( long ) 0 ) ;
372
	    enc_tdf_int ( u, ne ) ;
373
	    break ;
374
	}
375
	case EQN_TLD : {
376
	    enc_tdf_int ( p, ( long ) 0 ) ;
377
	    enc_tdf_int ( p, ( long ) 0 ) ;
378
	    break ;
379
	}
380
	case EQN_TOKDEC : {
381
	    enc_links ( p, tok_total, ( long ) 0, ( long ) 0 ) ;
382
	    enc_tdf_int ( u, ne ) ;
383
	    break ;
384
	}
385
	default : {
386
	    enc_links ( p, tok_total, al_tag_total, tag_total ) ;
387
	    enc_tdf_int ( u, lab_total ) ;
388
	    enc_tdf_int ( u, ne ) ;
389
	    break ;
390
	}
391
    }
392
 
393
    /* Append the body to the links */
394
    join_bitstreams ( u, q ) ;
395
    align_bitstream ( u ) ;
396
 
397
    /* Precede links and body by their length in bytes */
398
    n = bitstream_length ( u ) ;
399
    enc_tdf_int ( p, ( long ) ( n / BYTESIZE ) ) ;
400
    align_bitstream ( p ) ;
401
    join_bitstreams ( p, u ) ;
402
    return ;
403
}
404
 
405
 
406
/*
407
    VERSION NUMBERS
408
 
409
    These variables give the major and minor version numbers.
410
*/
411
 
412
static char *magic_number = VERSION_capsule ;
413
long version_major = VERSION_major ;
414
long version_minor = VERSION_minor ;
415
 
416
 
417
/*
418
    ENCODE A CAPSULE
419
 
420
    A complete capsule is encoded.
421
*/
422
 
423
void enc_capsule
424
    PROTO_Z ()
425
{
426
    long n ;
427
    bitstream *vers_bs ;
428
    char *m = magic_number ;
429
    bitstream *p = new_bitstream () ;
430
 
431
    /* Map to lowest applicable version number */
432
    if ( version_major == 4 ) {
433
	if ( version_minor == 1 ) version_minor = 0 ;
434
    }
435
 
436
    /* Initialize the equation bitstreams */
437
    tld_bs = new_bitstream () ;
438
    tok_decs_bs = new_bitstream () ;
439
    tok_defs_bs = new_bitstream () ;
440
    al_tag_defs_bs = new_bitstream () ;
441
    tag_decs_bs = new_bitstream () ;
442
    tag_defs_bs = new_bitstream () ;
443
 
444
    /* Analyse all the tags, tokens etc */
445
    enc_tdf_int ( tld_bs, ( long ) 1 ) ;
446
    apply_to_all ( enc_label_aux, SORT_label ) ;
447
    apply_to_all ( enc_token_aux, SORT_token ) ;
448
    apply_to_all ( enc_al_tag_aux, SORT_al_tag ) ;
449
    apply_to_all ( enc_tag_aux, SORT_tag ) ;
450
 
451
    /* Check on output options */
452
    if ( !show_tokdecs ) tok_decs = 0 ;
453
    if ( !show_tokdefs ) tok_defs = 0 ;
454
    if ( !show_aldefs ) al_tag_defs = 0 ;
455
    if ( !show_tagdecs ) tag_decs = 0 ;
456
    if ( !show_tagdefs ) tag_defs = 0 ;
457
 
458
    /* Output equation types */
459
    eqn_total = 2 ;
460
    if ( tok_decs ) eqn_total++ ;
461
    if ( tok_defs ) eqn_total++ ;
462
    if ( al_tag_defs ) eqn_total++ ;
463
    if ( tag_decs ) eqn_total++ ;
464
    if ( tag_defs ) eqn_total++ ;
465
    while ( n = ( long ) *( m++ ), n != 0 ) {
466
	enc_bits ( p, 8, n ) ;
467
    }
468
    enc_tdf_int ( p, version_major ) ;
469
    enc_tdf_int ( p, version_minor ) ;
470
    align_bitstream ( p ) ;
471
    enc_tdf_int ( p, eqn_total ) ;
472
    enc_aligned_string ( p, LINK_tld_props, ( long ) -1 ) ;
473
    enc_aligned_string ( p, LINK_version_props, ( long ) -1 ) ;
474
    if ( tok_decs ) {
475
	enc_aligned_string ( p, LINK_tokdec_props, ( long ) -1 ) ;
476
    }
477
    if ( tok_defs ) {
478
	enc_aligned_string ( p, LINK_tokdef_props, ( long ) -1 ) ;
479
    }
480
    if ( al_tag_defs ) {
481
	enc_aligned_string ( p, LINK_al_tagdef_props, ( long ) -1 ) ;
482
    }
483
    if ( tag_decs ) {
484
	enc_aligned_string ( p, LINK_tagdec_props, ( long ) -1 ) ;
485
    }
486
    if ( tag_defs ) {
487
	enc_aligned_string ( p, LINK_tagdef_props, ( long ) -1 ) ;
488
    }
489
 
490
    /* Adjust totals for removed variables */
491
    tok_total += sort_removed [ SORT_token ] ;
492
    tag_total += sort_removed [ SORT_tag ] ;
493
    al_tag_total += sort_removed [ SORT_al_tag ] ;
494
    lab_total += sort_removed [ SORT_label ] ;
495
 
496
    /* Output variable sorts */
497
    var_total = 0 ;
498
    if ( tok_total ) var_total++ ;
499
    if ( al_tag_total ) var_total++ ;
500
    if ( tag_total ) var_total++ ;
501
    enc_tdf_int ( p, var_total ) ;
502
    if ( tok_total ) {
503
	enc_aligned_string ( p, LINK_token, ( long ) -1 ) ;
504
	enc_tdf_int ( p, tok_total ) ;
505
    }
506
    if ( al_tag_total ) {
507
	enc_aligned_string ( p, LINK_al_tag, ( long ) -1 ) ;
508
	enc_tdf_int ( p, al_tag_total ) ;
509
    }
510
    if ( tag_total ) {
511
	enc_aligned_string ( p, LINK_tag, ( long ) -1 ) ;
512
	enc_tdf_int ( p, tag_total ) ;
513
    }
514
 
515
    /* Output external names */
516
    enc_tdf_int ( p, var_total ) ;
517
    crt_bitstream = p ;
518
    if ( tok_total ) {
519
	enc_tdf_int ( p, tok_external ) ;
520
	apply_to_all ( enc_token_names, SORT_token ) ;
521
    }
522
    if ( al_tag_total ) {
523
	enc_tdf_int ( p, al_tag_external ) ;
524
	apply_to_all ( enc_al_tag_names, SORT_al_tag ) ;
525
    }
526
    if ( tag_total ) {
527
	enc_tdf_int ( p, tag_external ) ;
528
	apply_to_all ( enc_tag_names, SORT_tag ) ;
529
    }
530
 
531
    /* Output equations */
532
    enc_tdf_int ( p, eqn_total ) ;
533
    enc_equation ( p, ( long ) 1, tld_bs, EQN_TLD ) ;
534
    vers_bs = new_bitstream () ;
535
    enc_version_bits ( vers_bs, ENC_make_version ) ;
536
    enc_tdf_int ( vers_bs, version_major ) ;
537
    enc_tdf_int ( vers_bs, version_minor ) ;
538
    enc_equation ( p, ( long ) 1, vers_bs, EQN_VERS ) ;
539
    if ( tok_decs ) enc_equation ( p, tok_decs, tok_decs_bs, EQN_TOKDEC ) ;
540
    if ( tok_defs ) enc_equation ( p, tok_defs, tok_defs_bs, EQN_TOKDEF ) ;
541
    if ( al_tag_defs ) {
542
	enc_equation ( p, al_tag_defs, al_tag_defs_bs, EQN_ALDEF ) ;
543
    }
544
    if ( tag_decs ) enc_equation ( p, tag_decs, tag_decs_bs, EQN_TAGDEC ) ;
545
    if ( tag_defs ) enc_equation ( p, tag_defs, tag_defs_bs, EQN_TAGDEF ) ;
546
 
547
    /* Send bitstream to output file */
548
    print_bitstream ( p ) ;
549
    return ;
550
}