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 <limits.h>
33
#include "version.h"
34
#include "system.h"
35
#include "c_types.h"
36
#include "hashid_ops.h"
37
#include "id_ops.h"
38
#include "off_ops.h"
39
#include "type_ops.h"
40
#include "error.h"
41
#include "catalog.h"
42
#include "tdf.h"
43
#include "basetype.h"
44
#include "capsule.h"
45
#include "char.h"
46
#include "compile.h"
47
#include "diag2.h"
48
#include "encode.h"
49
#include "file.h"
50
#include "hash.h"
51
#include "mangle.h"
52
#include "struct.h"
53
#include "throw.h"
54
#include "tok.h"
55
#include "ustring.h"
56
#include "xalloc.h"
57
 
58
 
59
/*
60
    START OF TDF OUTPUT ROUTINES
61
 
62
    The compiler can optionally be compiled with the TDF output routines
63
    disabled by defining the TDF_OUTPUT macro to be zero on the
64
    command-line.  The following routines are concerned with TDF output.
65
*/
66
 
67
#if TDF_OUTPUT
68
 
69
 
70
/*
71
    TABLE OF TDF UNIT TYPES
72
 
73
    This table gives the various TDF unit types (token definitions, tag
74
    declarations etc.).  These are called equations in the TDF linking
75
    routines.  Each entry consists of an equation name, a couple of
76
    flags indicating the unit structure, and a list of bitstreams giving
77
    the units of that type.  The entries correspond to the EQN macros
78
    defined in capsule.h.
79
*/
80
 
81
typedef struct {
82
    CONST char *name ;
83
    int labels ;
84
    int count ;
85
    LIST ( BITSTREAM_P ) pres ;
86
    LIST ( BITSTREAM_P ) units ;
87
} EQN_INFO ;
88
 
89
#define NO_EQNS		NULL_list ( BITSTREAM_P )
90
 
91
static EQN_INFO eqns [ EQN_no ] = {
92
    { LINK_tld_props, 0, 0, NO_EQNS, NO_EQNS },		/* EQN_tld */
93
    { LINK_version_props, 0, 1, NO_EQNS, NO_EQNS },	/* EQN_versions */
94
    { LINK_tokdec_props, 0, 1, NO_EQNS, NO_EQNS },	/* EQN_tokdec */
95
    { LINK_tokdef_props, 1, 1, NO_EQNS, NO_EQNS },	/* EQN_tokdef */
96
    { LINK_al_tagdef_props, 1, 1, NO_EQNS, NO_EQNS },	/* EQN_aldef */
97
    { LINK_diag_type_unit, 1, 1, NO_EQNS, NO_EQNS },	/* EQN_diagtype */
98
    { LINK_tagdec_props, 1, 1, NO_EQNS, NO_EQNS },	/* EQN_tagdec */
99
    { LINK_diag_unit, 1, 1, NO_EQNS, NO_EQNS },		/* EQN_diagdef */
100
    { LINK_dg_comp_props, 1, 1, NO_EQNS, NO_EQNS },	/* EQN_dgcomp */
101
    { LINK_tagdef_props, 1, 1, NO_EQNS, NO_EQNS },	/* EQN_tagdef */
102
    { LINK_linkinfo_props, 1, 1, NO_EQNS, NO_EQNS }	/* EQN_linkinfo */
103
} ;
104
 
105
 
106
/*
107
    TABLE OF LINKABLE TDF ENTITIES
108
 
109
    This table gives the various TDF linkable entities (tokens, tags etc.).
110
    These are called variables in the TDF linking routines.  Each entry
111
    consists of a variable name and a table of capsule level variables
112
    of that type (the label entry being a dummy).  The entries correspond
113
    to the VAR macros defined in capsule.h.
114
*/
115
 
116
typedef struct {
117
    CONST char *name ;
118
    ulong no ;
119
    ulong sz ;
120
    int present ;
121
    string *names ;
122
    unsigned char *uses ;
123
    ulong *diags ;
124
} VAR_INFO ;
125
 
126
static VAR_INFO vars [ VAR_total ] = {
127
    { LINK_tag, 0, 0, 0, NULL, NULL, NULL },		/* VAR_tag */
128
    { LINK_token, 0, 0, 0, NULL, NULL, NULL },		/* VAR_token */
129
    { LINK_al_tag, 0, 0, 0, NULL, NULL, NULL },		/* VAR_alignment */
130
    { LINK_diag_tag, 0, 0, 0, NULL, NULL, NULL },	/* VAR_diagtag */
131
    { LINK_dg_tag, 0, 0, 0, NULL, NULL, NULL },		/* VAR_dgtag */
132
    { LINK_label, 0, 0, 0, NULL, NULL, NULL }		/* VAR_label */
133
} ;
134
 
135
 
136
/*
137
    TYPE REPRESENTING A UNIT LINKAGE
138
 
139
    This type is used to represent the linkage for a unit.  It records the
140
    number of each variable type (plus labels) and the mapping of each of
141
    the external variables in this unit.  It also records a count value
142
    for the number of items in the unit when this is an explicitly
143
    created unit.
144
*/
145
 
146
typedef struct link_tag {
147
    ulong no [ VAR_total ] ;
148
    ulong no_map [ VAR_no ] ;
149
    ulong *map [ VAR_no ] ;
150
    ulong count ;
151
    int create ;
152
    struct link_tag *next ;
153
} LINKAGE ;
154
 
155
 
156
/*
157
    LIST OF ALL UNIT LINKAGES
158
 
159
    A list of all unit linkages is maintained so that extending a list of
160
    external variables also extends all the unit linkage maps.
161
*/
162
 
163
static LINKAGE *all_links = NULL ;
164
 
165
 
166
/*
167
    CREATE A NEW LINKAGE BITSTREAM
168
 
169
    This routine starts a new bitstream ps and associates a linkage unit
170
    with it.
171
*/
172
 
173
static void start_linkage
174
    PROTO_N ( ( ps, create ) )
175
    PROTO_T ( BITSTREAM **ps X int create )
176
{
177
    /* Allocate a linkage unit */
178
    int i ;
179
    VAR_INFO *var = vars ;
180
    LINKAGE *p = xmalloc_one ( LINKAGE ) ;
181
    for ( i = 0 ; i < VAR_no ; i++ ) {
182
	ulong j, n = var->sz ;
183
	if ( n ) {
184
	    ulong *q = xmalloc_nof ( ulong, n ) ;
185
	    for ( j = 0 ; j < n ; j++ ) q [j] = LINK_NONE ;
186
	    p->map [i] = q ;
187
	} else {
188
	    p->map [i] = NULL ;
189
	}
190
	p->no [i] = 0 ;
191
	p->no_map [i] = 0 ;
192
	var++ ;
193
    }
194
    p->no [ VAR_label ] = 0 ;
195
    p->count = 0 ;
196
    p->create = create ;
197
    p->next = all_links ;
198
    all_links = p ;
199
 
200
    /* Start the bitstream */
201
    *ps = start_bitstream ( NIL ( FILE ), ( gen_ptr ) p ) ;
202
    return ;
203
}
204
 
205
 
206
/*
207
    EXTEND A VARIABLE LINKAGE TABLE
208
 
209
    This routine extends the variable linkage table for variable type v.
210
*/
211
 
212
static void extend_linkage
213
    PROTO_N ( ( v ) )
214
    PROTO_T ( int v )
215
{
216
    ulong i ;
217
    LINKAGE *q ;
218
    VAR_INFO *var = vars + v ;
219
    ulong m = var->sz ;
220
    ulong n = m + 100 ;
221
 
222
    /* Extend global linkage table */
223
    string *s = var->names ;
224
    unsigned char *u = var->uses ;
225
    ulong *d = var->diags ;
226
    s = xrealloc_nof ( s, string, n ) ;
227
    u = xrealloc_nof ( u, unsigned char, n ) ;
228
    if ( output_diag && ( v == VAR_tag || v == VAR_token ) ) {
229
	d = xrealloc_nof ( d, ulong, n ) ;
230
    }
231
    for ( i = m ; i < n ; i++ ) {
232
	s [i] = NULL ;
233
	u [i] = USAGE_NONE ;
234
	if ( d ) d [i] = LINK_NONE ;
235
    }
236
    var->sz = n ;
237
    var->names = s ;
238
    var->uses = u ;
239
    var->diags = d ;
240
 
241
    /* Extend each unit linkage table */
242
    for ( q = all_links ; q != NULL ; q = q->next ) {
243
	ulong *r = q->map [v] ;
244
	r = xrealloc_nof ( r, ulong, n ) ;
245
	for ( i = m ; i < n ; i++ ) r [i] = LINK_NONE ;
246
	q->map [v] = r ;
247
    }
248
    return ;
249
}
250
 
251
 
252
/*
253
    FIND AN EXTERNAL LINKAGE NUMBER
254
 
255
    This routine allocates an external (capsule) linkage number for a
256
    variable of type v with external name s, returning the result.
257
*/
258
 
259
ulong capsule_no
260
    PROTO_N ( ( s, v ) )
261
    PROTO_T ( string s X int v )
262
{
263
    VAR_INFO *var = vars + v ;
264
    ulong n = ( var->no )++ ;
265
    if ( n >= var->sz ) extend_linkage ( v ) ;
266
    var->uses [n] = USAGE_USE ;
267
    var->names [n] = s ;
268
    var->present = 1 ;
269
    return ( n | LINK_EXTERN ) ;
270
}
271
 
272
 
273
/*
274
    SET AN EXTERNAL LINKAGE NAME
275
 
276
    This routine sets the external name for the variable of type v with
277
    external linkage number n to be the contents of ps, allocating a new
278
    variable if n is LINK_NONE.  It returns the value of n and assigns
279
    the old variable name to ps.
280
*/
281
 
282
ulong capsule_name
283
    PROTO_N ( ( n, ps, v ) )
284
    PROTO_T ( ulong n X string *ps X int v )
285
{
286
    string s = *ps ;
287
    if ( n == LINK_NONE ) {
288
	n = capsule_no ( s, v ) ;
289
    } else {
290
	VAR_INFO *var = vars + v ;
291
	ulong m = ( n & ~LINK_EXTERN ) ;
292
	ASSERT ( n & LINK_EXTERN ) ;
293
	*ps = var->names [m] ;
294
	var->names [m] = s ;
295
    }
296
    return ( n ) ;
297
}
298
 
299
 
300
/*
301
    ASSIGN AN EXTERNAL LINKAGE NUMBER
302
 
303
    This routine allocates an external (capsule) linkage number to the
304
    identifier id of variable type v.  It returns false if this number
305
    has already been allocated.  Note that id cannot be made external
306
    after it has been made internal.
307
*/
308
 
309
int capsule_id
310
    PROTO_N ( ( id, v ) )
311
    PROTO_T ( IDENTIFIER id X int v )
312
{
313
    int r ;
314
    IDENTIFIER lid = DEREF_id ( id_alias ( id ) ) ;
315
    ulong n = DEREF_ulong ( id_no ( lid ) ) ;
316
    if ( n == LINK_NONE ) {
317
	/* Not yet given a number */
318
	string s = mangle_name ( lid, v, 0 ) ;
319
	n = capsule_no ( s, v ) ;
320
	COPY_ulong ( id_no ( lid ), n ) ;
321
	COPY_ulong ( id_no ( id ), n ) ;
322
	r = 1 ;
323
    } else {
324
	ASSERT ( n & LINK_EXTERN ) ;
325
	r = 0 ;
326
    }
327
    return ( r ) ;
328
}
329
 
330
 
331
/*
332
    FIND AN INTERNAL LINKAGE NUMBER
333
 
334
    This routine allocates an internal (unit) linkage number in the unit
335
    corresponding to bs to the external (capsule) variable number n of
336
    type v.
337
*/
338
 
339
ulong link_no
340
    PROTO_N ( ( bs, n, v ) )
341
    PROTO_T ( BITSTREAM *bs X ulong n X int v )
342
{
343
    LINKAGE *lnk = ( LINKAGE * ) bs->link ;
344
    ulong m = ( n & ~LINK_EXTERN ) ;
345
    n = lnk->map [v] [m] ;
346
    if ( n == LINK_NONE ) {
347
	/* Does not have unit number */
348
	n = ( lnk->no [v] )++ ;
349
	lnk->map [v] [m] = n ;
350
	( lnk->no_map [v] )++ ;
351
	vars [v].present = 1 ;
352
    }
353
    return ( n ) ;
354
}
355
 
356
 
357
/*
358
    ASSIGN AN INTERNAL LINKAGE NUMBER
359
 
360
    This routine allocates an internal (unit) linkage number to the
361
    identifier id of variable type v within the unit corresponding to bs.
362
    v can denote a label.  The corresponding number is returned.  Note
363
    that unless id has previously been made external then it can be
364
    internal to at most one unit.
365
*/
366
 
367
ulong unit_no
368
    PROTO_N ( ( bs, id, v, def ) )
369
    PROTO_T ( BITSTREAM *bs X IDENTIFIER id X int v X int def )
370
{
371
    ulong n ;
372
    if ( IS_NULL_id ( id ) ) {
373
	/* Allow anonymous identifiers */
374
	LINKAGE *lnk = ( LINKAGE * ) bs->link ;
375
	n = ( lnk->no [v] )++ ;
376
	vars [v].present = 1 ;
377
    } else {
378
	IDENTIFIER lid = DEREF_id ( id_alias ( id ) ) ;
379
	n = DEREF_ulong ( id_no ( lid ) ) ;
380
	if ( n == LINK_NONE ) {
381
	    /* Not yet given a number */
382
	    LINKAGE *lnk = ( LINKAGE * ) bs->link ;
383
	    n = ( lnk->no [v] )++ ;
384
	    COPY_ulong ( id_no ( lid ), n ) ;
385
	    COPY_ulong ( id_no ( id ), n ) ;
386
	    vars [v].present = 1 ;
387
	    if ( !def ) {
388
		/* Shouldn't happen */
389
		LOCATION loc ;
390
		DEREF_loc ( id_loc ( id ), loc ) ;
391
		report ( loc, ERR_token_scope ( id ) ) ;
392
	    }
393
	} else {
394
	    if ( n == LINK_TOKDEF ) {
395
		/* Recursively defined token */
396
		LOCATION loc ;
397
		DEREF_loc ( id_loc ( id ), loc ) ;
398
		report ( loc, ERR_token_recursive ( id ) ) ;
399
		n = last_params [ DUMMY_token ] ;
400
		COPY_ulong ( id_no ( id ), n ) ;
401
	    }
402
	    if ( n & LINK_EXTERN ) {
403
		/* Already has capsule number */
404
		n = link_no ( bs, n, v ) ;
405
	    }
406
	}
407
    }
408
    return ( n ) ;
409
}
410
 
411
 
412
/*
413
    CLEAR AN IDENTIFIER LINKAGE
414
 
415
    This routine clears the identifier linkage for id.
416
*/
417
 
418
void clear_no
419
    PROTO_N ( ( id ) )
420
    PROTO_T ( IDENTIFIER id )
421
{
422
    if ( !IS_NULL_id ( id ) ) {
423
	IDENTIFIER lid = DEREF_id ( id_alias ( id ) ) ;
424
	DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
425
	COPY_dspec ( id_storage ( id ), ( ds & ~dspec_done ) ) ;
426
	COPY_ulong ( id_no ( id ), LINK_NONE ) ;
427
	if ( !EQ_id ( lid, id ) ) {
428
	    ds = DEREF_dspec ( id_storage ( lid ) ) ;
429
	    COPY_dspec ( id_storage ( lid ), ( ds & ~dspec_done ) ) ;
430
	    COPY_ulong ( id_no ( lid ), LINK_NONE ) ;
431
	}
432
    }
433
    return ;
434
}
435
 
436
 
437
/*
438
    SET A DIAGNOSTIC TAG NUMBER
439
 
440
    This routine sets the diagnostic tag associated with external identifier
441
    id of type v to be m.
442
*/
443
 
444
void set_diag_tag
445
    PROTO_N ( ( id, v, m ) )
446
    PROTO_T ( IDENTIFIER id X int v X ulong m )
447
{
448
    ulong n = DEREF_ulong ( id_no ( id ) ) ;
449
    if ( n == LINK_NONE ) {
450
	IGNORE capsule_id ( id, v ) ;
451
	CONS_id ( id, pending_funcs, pending_funcs ) ;
452
	n = DEREF_ulong ( id_no ( id ) ) ;
453
    }
454
    n &= ~LINK_EXTERN ;
455
    ASSERT ( vars [v].diags ) ;
456
    vars [v].diags [n] = m ;
457
    return ;
458
}
459
 
460
 
461
/*
462
    GET A DIAGNOSTIC TAG NUMBER
463
 
464
    This routine gets the diagnostic tag associated with external identifier
465
    id of type v.
466
*/
467
 
468
ulong get_diag_tag
469
    PROTO_N ( ( id, v ) )
470
    PROTO_T ( IDENTIFIER id X int v )
471
{
472
    ulong n = DEREF_ulong ( id_no ( id ) ) ;
473
    if ( n == LINK_NONE ) return ( LINK_NONE ) ;
474
    n &= ~LINK_EXTERN ;
475
    ASSERT ( vars [v].diags ) ;
476
    return ( vars [v].diags [n] ) ;
477
}
478
 
479
 
480
/*
481
    FIND THE NUMBER OF LABELS IN A UNIT
482
 
483
    This routine returns the number of labels in the unit corresponding
484
    to the bitstream bs.
485
*/
486
 
487
ulong no_labels
488
    PROTO_N ( ( bs ) )
489
    PROTO_T ( BITSTREAM *bs )
490
{
491
    LINKAGE *lnk = ( LINKAGE * ) bs->link ;
492
    return ( lnk->no [ VAR_label ] ) ;
493
}
494
 
495
 
496
/*
497
    RECORD USAGE INFORMATION
498
 
499
    This routine records the usage information u for the external variable
500
    of type v with number n.
501
*/
502
 
503
void record_usage
504
    PROTO_N ( ( n, v, u ) )
505
    PROTO_T ( ulong n X int v X unsigned u )
506
{
507
    ulong m = ( n & ~LINK_EXTERN ) ;
508
    unsigned char *pw = vars [v].uses + m ;
509
    unsigned w = ( unsigned ) *pw ;
510
    *pw = ( unsigned char ) ( w | u ) ;
511
    return ;
512
}
513
 
514
 
515
/*
516
    FIND USAGE INFORMATION
517
 
518
    This routine finds the usage information for the external variable of
519
    type v with number n.
520
*/
521
 
522
unsigned find_usage
523
    PROTO_N ( ( n, v ) )
524
    PROTO_T ( ulong n X int v )
525
{
526
    ulong m = ( n & ~LINK_EXTERN ) ;
527
    unsigned u = ( unsigned ) vars [v].uses [m] ;
528
    return ( u ) ;
529
}
530
 
531
 
532
/*
533
    CLEAR USAGE INFORMATION
534
 
535
    This routine clears the usage information for the external variable
536
    of type v with number n.
537
*/
538
 
539
void clear_usage
540
    PROTO_N ( ( n, v ) )
541
    PROTO_T ( ulong n X int v )
542
{
543
    ulong m = ( n & ~LINK_EXTERN ) ;
544
    vars [v].uses [m] = USAGE_NONE ;
545
    return ;
546
}
547
 
548
 
549
/*
550
    INCREMENT A LINKAGE COUNTER
551
 
552
    This routine increments the linkage counter associated with the
553
    bitstream bs.  This is used to keep track of the number of tag
554
    declarations, or similar, within a unit.
555
*/
556
 
557
void count_item
558
    PROTO_N ( ( bs ) )
559
    PROTO_T ( BITSTREAM *bs )
560
{
561
    LINKAGE *lnk = ( LINKAGE * ) bs->link ;
562
    ( lnk->count )++ ;
563
    return ;
564
}
565
 
566
 
567
/*
568
    ADD A UNIT TO A CAPSULE
569
 
570
    This routine adds the unit given by the bitstream bs to the list of
571
    units of type u.  If the associate unit count is zero then the unit
572
    is not added.
573
*/
574
 
575
static void add_unit
576
    PROTO_N ( ( u, bs, ps ) )
577
    PROTO_T ( int u X BITSTREAM *bs X BITSTREAM *ps )
578
{
579
    if ( bs ) {
580
	LINKAGE *lnk = ( LINKAGE * ) bs->link ;
581
	if ( lnk == NULL || lnk->count || ps ) {
582
	    EQN_INFO *eqn = eqns + u ;
583
	    LIST ( BITSTREAM_P ) us = eqn->units ;
584
	    LIST ( BITSTREAM_P ) vs = eqn->pres ;
585
	    CONS_bits ( bs, us, us ) ;
586
	    CONS_bits ( ps, vs, vs ) ;
587
	    eqn->units = us ;
588
	    eqn->pres = vs ;
589
	}
590
    }
591
    return ;
592
}
593
 
594
 
595
/*
596
    STANDARD BITSTREAMS
597
 
598
    These bitstreams represent standard units within the TDF capsule.
599
*/
600
 
601
BITSTREAM *tokdec_unit = NULL ;
602
BITSTREAM *tokdef_unit = NULL ;
603
BITSTREAM *aldef_unit = NULL ;
604
BITSTREAM *tagdec_unit = NULL ;
605
BITSTREAM *tagdef_unit = NULL ;
606
BITSTREAM *linkinfo_unit = NULL ;
607
BITSTREAM *diagdef_unit = NULL ;
608
BITSTREAM *diagtype_unit = NULL ;
609
BITSTREAM *diagcomp_unit = NULL ;
610
static BITSTREAM *diagcomp_pre = NULL ;
611
static int written_capsule = 0 ;
612
 
613
 
614
/*
615
    DYNAMIC INITIALISATION AND TERMINATION FUNCTIONS
616
 
617
    These bitstreams are used to build up the bodies of the dynamic
618
    initialisation and termination functions.  A count of the number
619
    of statements in each is maintained.
620
*/
621
 
622
BITSTREAM *init_func = NULL ;
623
BITSTREAM *term_func = NULL ;
624
BITSTREAM *term_static_func = NULL ;
625
ulong init_no = 0 ;
626
ulong term_no = 0 ;
627
 
628
 
629
/*
630
    CREATE A LINKER INFORMATION UNIT
631
 
632
    This routine creates a linker information unit containing just a tld
633
    version number.  The usage information for the external variables is
634
    added at a subsequent stage.
635
*/
636
 
637
static BITSTREAM *make_tld_unit
638
    PROTO_Z ()
639
{
640
    BITSTREAM *bs = start_bitstream ( NIL ( FILE ), NULL_gen_ptr ) ;
641
    ENC_INT ( bs, 1 ) ;
642
    return ( bs ) ;
643
}
644
 
645
 
646
/*
647
    CREATE A VERSIONS UNIT
648
 
649
    This routine creates a versions unit containing a single version
650
    which gives the TDF version number.
651
*/
652
 
653
static BITSTREAM *make_version_unit
654
    PROTO_Z ()
655
{
656
    BITSTREAM *bs ;
657
    start_linkage ( &bs, 1 ) ;
658
    ENC_make_version ( bs ) ;
659
    bs = enc_version ( bs ) ;
660
    count_item ( bs ) ;
661
    if ( output_all ) {
662
	/* Output compiler version number */
663
	string vers = report_version ( 0 ) ;
664
	ENC_user_info ( bs ) ;
665
	ENC_make_string ( bs ) ;
666
	bs = enc_ustring ( bs, vers ) ;
667
	count_item ( bs ) ;
668
    }
669
    return ( bs ) ;
670
}
671
 
672
 
673
/*
674
    CREATE ALL CAPSULE UNITS
675
 
676
    This routine creates or completes all the units comprising the TDF
677
    capsule.
678
*/
679
 
680
static void make_capsule_units
681
    PROTO_Z ()
682
{
683
    BITSTREAM *bs ;
684
    init_diag () ;
685
    bs = make_version_unit () ;
686
    add_unit ( EQN_versions, bs, NIL ( BITSTREAM ) ) ;
687
    enc_dynamic_init () ;
688
    add_unit ( EQN_tokdec, tokdec_unit, NIL ( BITSTREAM ) ) ;
689
    add_unit ( EQN_tokdef, tokdef_unit, NIL ( BITSTREAM ) ) ;
690
    add_unit ( EQN_aldef, aldef_unit, NIL ( BITSTREAM ) ) ;
691
    add_unit ( EQN_diagtype, diagtype_unit, NIL ( BITSTREAM ) ) ;
692
    add_unit ( EQN_tagdec, tagdec_unit, NIL ( BITSTREAM ) ) ;
693
    add_unit ( EQN_diagdef, diagdef_unit, NIL ( BITSTREAM ) ) ;
694
    add_unit ( EQN_dgcomp, diagcomp_unit, diagcomp_pre ) ;
695
    add_unit ( EQN_tagdef, tagdef_unit, NIL ( BITSTREAM ) ) ;
696
    add_unit ( EQN_linkinfo, linkinfo_unit, NIL ( BITSTREAM ) ) ;
697
    return ;
698
}
699
 
700
 
701
/*
702
    WRITE AN EXTERNAL NAME
703
 
704
    This routine writes the external name s to the bitstream bs.  Spaces
705
    are used to designate the components of unique identifiers.
706
*/
707
 
708
static BITSTREAM *enc_name
709
    PROTO_N ( ( bs, s, v ) )
710
    PROTO_T ( BITSTREAM *bs X string s X int v )
711
{
712
    string t = s ;
713
    unsigned u = 0 ;
714
    unsigned long n ;
715
    for ( ; ; ) {
716
	t = ustrchr ( t, ' ' ) ;
717
	u++ ;
718
	if ( t == NULL ) break ;
719
	t++ ;
720
    }
721
    if ( u == 1 ) {
722
	/* Simple identifiers */
723
	n = ( unsigned long ) ustrlen ( s ) ;
724
	if ( v == VAR_tag && n > mangle_length ) {
725
	    n = mangle_length ;
726
	}
727
	ENC_string_extern ( bs ) ;
728
	ENC_ALIGN ( bs ) ;
729
	ENC_IDENT ( bs, s, n ) ;
730
    } else {
731
	/* Unique identifiers */
732
	ENC_unique_extern ( bs ) ;
733
	ENC_ALIGN ( bs ) ;
734
	ENC_SLIST ( bs, u ) ;
735
	for ( ; ; ) {
736
	    t = ustrchr ( s, ' ' ) ;
737
	    if ( t == NULL ) {
738
		n = ( unsigned long ) ustrlen ( s ) ;
739
		ENC_IDENT ( bs, s, n ) ;
740
		break ;
741
	    }
742
	    n = ( unsigned long ) ( t - s ) ;
743
	    ENC_IDENT ( bs, s, n ) ;
744
	    s = t + 1 ;
745
	}
746
    }
747
    return ( bs ) ;
748
}
749
 
750
 
751
/*
752
    WRITE MAIN CAPSULE BODY
753
 
754
    This routine writes the main body of the output TDF capsule to the
755
    bitstream bs.
756
*/
757
 
758
static BITSTREAM *write_capsule_body
759
    PROTO_N ( ( bs ) )
760
    PROTO_T ( BITSTREAM *bs )
761
{
762
    int i, j ;
763
    EQN_INFO *eqn ;
764
    VAR_INFO *var ;
765
    ulong no_eqns = 0 ;
766
    ulong no_vars = 0 ;
767
    BITSTREAM *ts, *to ;
768
 
769
    /* Call capsule construction routines */
770
    make_capsule_units () ;
771
 
772
    /* Count the number of variables */
773
    var = vars ;
774
    for ( i = 0 ; i < VAR_no ; i++ ) {
775
	if ( var->present ) no_vars++ ;
776
	var++ ;
777
    }
778
 
779
    /* Construct linker information unit */
780
    if ( no_vars ) {
781
	ts = make_tld_unit () ;
782
	add_unit ( EQN_tld, ts, NIL ( BITSTREAM ) ) ;
783
    } else {
784
	ts = NULL ;
785
    }
786
    to = ts ;
787
 
788
    /* Count the number of equations */
789
    eqn = eqns ;
790
    for ( i = 0 ; i < EQN_no ; i++ ) {
791
	if ( !IS_NULL_list ( eqn->units ) ) no_eqns++ ;
792
	eqn++ ;
793
    }
794
 
795
    /* Output the equation names */
796
    eqn = eqns ;
797
    ENC_SLIST ( bs, no_eqns ) ;
798
    for ( i = 0 ; i < EQN_no ; i++ ) {
799
	if ( !IS_NULL_list ( eqn->units ) ) {
800
	    string s = ustrlit ( eqn->name ) ;
801
	    ENC_IDENT ( bs, s, ustrlen ( s ) ) ;
802
	}
803
	eqn++ ;
804
    }
805
 
806
    /* Output the variable names and numbers */
807
    var = vars ;
808
    ENC_SLIST ( bs, no_vars ) ;
809
    for ( i = 0 ; i < VAR_no ; i++ ) {
810
	if ( var->present ) {
811
	    string s = ustrlit ( var->name ) ;
812
	    ENC_IDENT ( bs, s, ustrlen ( s ) ) ;
813
	    ENC_INT ( bs, var->no ) ;
814
	}
815
	var++ ;
816
    }
817
 
818
    /* Output the external variable identifiers */
819
    var = vars ;
820
    ENC_SLIST ( bs, no_vars ) ;
821
    for ( i = 0 ; i < VAR_no ; i++ ) {
822
	if ( var->present ) {
823
	    ulong no_ext = 0 ;
824
	    ulong k, n = var->no ;
825
	    string *names = var->names ;
826
	    unsigned char *uses = var->uses ;
827
	    for ( k = 0 ; k < n ; k++ ) {
828
		string s = names [k] ;
829
		unsigned use = ( unsigned ) uses [k] ;
830
		if ( use != USAGE_NONE ) {
831
		    CONST char *msg ;
832
		    if ( s ) {
833
			/* Count number of external names */
834
			no_ext++ ;
835
		    } else {
836
			if ( !( use & USAGE_DEFN ) ) {
837
			    /* Undefined internal object */
838
			    if ( ( use & USAGE_DECL ) && i == VAR_dgtag ) {
839
				/* Diagnostic tags can just be declared */
840
				use |= USAGE_DEFN ;
841
			    } else {
842
				msg = "'%s %lu' used but not defined" ;
843
				error ( ERROR_INTERNAL, msg, var->name, k ) ;
844
				use |= USAGE_DECL ;
845
				names [k] = mangle_anon () ;
846
				no_ext++ ;
847
			    }
848
			    uses [k] = ( unsigned char ) use ;
849
			}
850
		    }
851
		    if ( i == VAR_tag && !( use & USAGE_DECL ) ) {
852
			/* Undeclared tag */
853
			if ( s ) {
854
			    msg = "'%s' used but not declared" ;
855
			    error ( ERROR_INTERNAL, msg, strlit ( s ) ) ;
856
			} else {
857
			    msg = "'%s %lu' used but not declared" ;
858
			    error ( ERROR_INTERNAL, msg, var->name, k ) ;
859
			}
860
		    }
861
		} else {
862
		    names [k] = NULL ;
863
		}
864
	    }
865
	    ENC_SLIST ( bs, no_ext ) ;
866
	    for ( k = 0 ; k < n ; k++ ) {
867
		string s = names [k] ;
868
		if ( s ) {
869
		    unsigned use = ( unsigned ) uses [k] ;
870
		    if ( use & USAGE_COMMON ) {
871
			/* Common subsumes defined */
872
			if ( use & USAGE_DEFN ) {
873
			    use &= ~USAGE_DEFN ;
874
			} else {
875
			    use &= ~USAGE_COMMON ;
876
			}
877
		    }
878
		    ENC_INT ( ts, use ) ;
879
		    ENC_INT ( bs, k ) ;
880
		    bs = enc_name ( bs, s, i ) ;
881
		}
882
	    }
883
	}
884
	var++ ;
885
    }
886
 
887
    /* Update linker information unit */
888
    if ( ts != to ) {
889
	LIST ( BITSTREAM_P ) u = eqns [ EQN_tld ].units ;
890
	u = END_list ( u ) ;
891
	COPY_bits ( HEAD_list ( u ), ts ) ;
892
    }
893
 
894
    /* Output the equation units */
895
    eqn = eqns ;
896
    ENC_SLIST ( bs, no_eqns ) ;
897
    for ( i = 0 ; i < EQN_no ; i++ ) {
898
	int labels = eqn->labels ;
899
	int count = eqn->count ;
900
	LIST ( BITSTREAM_P ) u = eqn->units ;
901
	if ( !IS_NULL_list ( u ) ) {
902
	    /* Output list of units */
903
	    LIST ( BITSTREAM_P ) v = eqn->pres ;
904
	    unsigned no_units = LENGTH_list ( u ) ;
905
	    if ( no_units > 1 ) {
906
		u = REVERSE_list ( u ) ;
907
		eqn->units = u ;
908
	    }
909
	    ENC_SLIST ( bs, no_units ) ;
910
	    while ( !IS_NULL_list ( u ) ) {
911
		unsigned ub ;
912
		BITSTREAM *us = DEREF_bits ( HEAD_list ( u ) ) ;
913
		BITSTREAM *vs = DEREF_bits ( HEAD_list ( v ) ) ;
914
		gen_ptr plnk = us->link ;
915
 
916
		/* Output linkage information */
917
		if ( plnk ) {
918
		    /* Output numbers of local variables */
919
		    LINKAGE *lnk = ( LINKAGE * ) plnk ;
920
		    var = vars ;
921
		    ENC_SLIST ( bs, no_vars ) ;
922
		    for ( j = 0 ; j < VAR_no ; j++ ) {
923
			if ( var->present ) {
924
			    ulong nj = lnk->no [j] ;
925
			    ENC_INT ( bs, nj ) ;
926
			}
927
			var++ ;
928
		    }
929
 
930
		    /* Output links for local variables */
931
		    ENC_SLIST ( bs, no_vars ) ;
932
		    var = vars ;
933
		    for ( j = 0 ; j < VAR_no ; j++ ) {
934
			if ( var->present ) {
935
			    ulong k, n = vars [j].no ;
936
			    ulong *map = lnk->map [j] ;
937
			    ulong no_map = lnk->no_map [j] ;
938
			    ENC_SLIST ( bs, no_map ) ;
939
			    for ( k = 0 ; k < n ; k++ ) {
940
				ulong nk = map [k] ;
941
				if ( nk != LINK_NONE ) {
942
				    ENC_INT ( bs, nk ) ;
943
				    ENC_INT ( bs, k ) ;
944
				}
945
			    }
946
			}
947
			var++ ;
948
		    }
949
 
950
		    /* Add extra information to unit */
951
		    if ( lnk->create && ( labels || count || vs ) ) {
952
			BITSTREAM *ws ;
953
			ws = start_bitstream ( NIL ( FILE ), plnk ) ;
954
			if ( labels ) {
955
			    /* Number of labels */
956
			    ulong no_labs = lnk->no [ VAR_label ] ;
957
			    ENC_INT ( ws, no_labs ) ;
958
			}
959
			ws = join_bitstreams ( ws, vs ) ;
960
			if ( count ) {
961
			    /* Number of items */
962
			    ulong no_item = lnk->count ;
963
			    ENC_SLIST ( ws, no_item ) ;
964
			}
965
			us = join_bitstreams ( ws, us ) ;
966
		    }
967
 
968
		} else {
969
		    /* No linkage information */
970
		    ENC_SLIST_SMALL ( bs, 0 ) ;
971
		    ENC_SLIST_SMALL ( bs, 0 ) ;
972
		}
973
 
974
		/* Add unit bitstream to capsule */
975
		ENC_ALIGN ( us ) ;
976
		ub = length_bitstream ( us ) ;
977
		ENC_LENGTH ( bs, ( ub / BYTE_SIZE ) ) ;
978
		ENC_ALIGN ( bs ) ;
979
		bs = join_bitstreams ( bs, us ) ;
980
		v = TAIL_list ( v ) ;
981
		u = TAIL_list ( u ) ;
982
	    }
983
	}
984
	eqn++ ;
985
    }
986
    return ( bs ) ;
987
}
988
 
989
 
990
/*
991
    CURRENT FUNCTION INFORMATION
992
 
993
    At the start of each function definition the associated class type
994
    and the identifier corresponding to the this parameter are recorded
995
    in these variables.
996
*/
997
 
998
CLASS_TYPE last_class = NULL_ctype ;
999
ulong last_params [ DUMMY_max ] ;
1000
int last_conts [ DUMMY_max ] ;
1001
 
1002
 
1003
/*
1004
    CLEAR FUNCTION INFORMATION
1005
 
1006
    This routine clears the function information above.
1007
*/
1008
 
1009
void clear_params
1010
    PROTO_Z ()
1011
{
1012
    int n ;
1013
    for ( n = 0 ; n < DUMMY_max ; n++ ) {
1014
	last_params [n] = LINK_NONE ;
1015
	last_conts [n] = 0 ;
1016
    }
1017
    return ;
1018
}
1019
 
1020
 
1021
/*
1022
    INITIALISE OUTPUT ROUTINES
1023
 
1024
    This routine initialises the TDF capsule output routines.
1025
*/
1026
 
1027
void init_capsule
1028
    PROTO_Z ()
1029
{
1030
    if ( output_capsule ) {
1031
	/* Initialise capsule units */
1032
	HASHID nm ;
1033
	gen_ptr lnk ;
1034
	if ( output_tokdec || output_all ) {
1035
	    start_linkage ( &tokdec_unit, 1 ) ;
1036
	    output_tokdec = 1 ;
1037
	}
1038
	start_linkage ( &tokdef_unit, 1 ) ;
1039
	start_linkage ( &aldef_unit, 1 ) ;
1040
	start_linkage ( &tagdec_unit, 1 ) ;
1041
	start_linkage ( &tagdef_unit, 1 ) ;
1042
	start_linkage ( &linkinfo_unit, 1 ) ;
1043
	if ( output_diag ) {
1044
	    start_linkage ( &diagdef_unit, 1 ) ;
1045
	    start_linkage ( &diagtype_unit, 1 ) ;
1046
	    start_linkage ( &diagcomp_unit, 1 ) ;
1047
	    output_inline = 0 ;
1048
	    output_unused = 1 ;
1049
	}
1050
	written_capsule = 0 ;
1051
 
1052
	/* Initialise special functions */
1053
	clear_params () ;
1054
	lnk = tagdef_unit->link ;
1055
	init_func = start_bitstream ( NIL ( FILE ), lnk ) ;
1056
	term_func = start_bitstream ( NIL ( FILE ), lnk ) ;
1057
	term_static_func = start_bitstream ( NIL ( FILE ), lnk ) ;
1058
	init_no = 0 ;
1059
	term_no = 0 ;
1060
 
1061
	/* Initialise dummy types */
1062
	MAKE_type_compound ( cv_none, NULL_ctype, dummy_class ) ;
1063
	MAKE_type_ptr ( cv_none, dummy_class, ptr_dummy_class ) ;
1064
	MAKE_type_dummy ( cv_none, TOK_destr_type, dummy_count ) ;
1065
	MAKE_type_dummy ( cv_none, TOK_vtab_type, dummy_vtab ) ;
1066
	MAKE_type_ptr ( cv_none, dummy_vtab, ptr_dummy_vtab ) ;
1067
	MAKE_type_func ( cv_none, type_sint, NULL_list ( TYPE ), 0,
1068
			 cv_lang, NULL_list ( TYPE ), NULL_nspace,
1069
			 NULL_list ( IDENTIFIER ), NULL_list ( TYPE ),
1070
			 dummy_func ) ;
1071
	MAKE_off_type ( type_size_t, off_size_t ) ;
1072
	nm = lookup_anon () ;
1073
	dummy_type_name = DEREF_id ( hashid_id ( nm ) ) ;
1074
    }
1075
    return ;
1076
}
1077
 
1078
 
1079
/*
1080
    INITIALISE DIAGNOSTIC ROUTINES
1081
 
1082
    This routine is called at the start of each input file to initialise
1083
    the diagnostic routines.
1084
*/
1085
 
1086
void init_diag
1087
    PROTO_Z ()
1088
{
1089
#if TDF_NEW_DIAG
1090
    if ( output_capsule && output_diag >= 2 ) {
1091
	BITSTREAM *bs = diagcomp_pre ;
1092
	if ( bs == NULL ) {
1093
	    bs = start_bitstream ( NIL ( FILE ), diagcomp_unit->link ) ;
1094
	    bs = enc_dg_compilation ( bs ) ;
1095
	    diagcomp_pre = bs ;
1096
	    output_new_diag = output_diag ;
1097
	}
1098
    }
1099
#endif
1100
    return ;
1101
}
1102
 
1103
 
1104
/*
1105
    START OF DUMMY TDF OUTPUT ROUTINES
1106
 
1107
    The following routines are dummies which are used if TDF output is
1108
    disabled.  The output is still a valid TDF capsule, it just contains
1109
    no information.
1110
*/
1111
 
1112
#else /* TDF_OUTPUT */
1113
 
1114
 
1115
/*
1116
    WRITE MAIN CAPSULE BODY (DUMMY VERSION)
1117
 
1118
    This routine writes the main body of a dummy TDF capsule to the
1119
    bitstream bs.
1120
*/
1121
 
1122
static BITSTREAM *write_capsule_body
1123
    PROTO_N ( ( bs ) )
1124
    PROTO_T ( BITSTREAM *bs )
1125
{
1126
    return ( bs ) ;
1127
}
1128
 
1129
 
1130
/*
1131
    INITIALISE OUTPUT ROUTINES (DUMMY VERSION)
1132
 
1133
    This is the dummy initialisation routine for when the TDF output
1134
    routines are disabled.
1135
*/
1136
 
1137
void init_capsule
1138
    PROTO_Z ()
1139
{
1140
    output_capsule = 0 ;
1141
    return ;
1142
}
1143
 
1144
 
1145
/*
1146
    INITIALISEE DIAGNOSTIC ROUTINES (DUMMY VERSION)
1147
 
1148
    This is the dummy diagnostic initialisation routine for when the TDF
1149
    output routines are disabled.
1150
*/
1151
 
1152
void init_diag
1153
    PROTO_Z ()
1154
{
1155
    return ;
1156
}
1157
 
1158
 
1159
/*
1160
    END OF TDF OUTPUT ROUTINES
1161
 
1162
    The remaining routines in this module are common whether TDF output
1163
    is disabled or not.
1164
*/
1165
 
1166
#endif /* TDF_OUTPUT */
1167
 
1168
 
1169
/*
1170
    TDF OUTPUT FLAGS
1171
 
1172
    The flag output_capsule can be set to false to suppress TDF output.
1173
    The other flags inhibit the output of other optional features.
1174
*/
1175
 
1176
int output_tdf = 1 ;
1177
int output_capsule = 1 ;
1178
int output_all = 0 ;
1179
int output_bugs = 0 ;
1180
int output_builtin = 0 ;
1181
int output_date = 1 ;
1182
int output_diag = 0 ;
1183
int output_except = 1 ;
1184
int output_init = 0 ;
1185
int output_inline = 0 ;
1186
int output_new_diag = 0 ;
1187
int output_order = 0 ;
1188
int output_partial = 1 ;
1189
int output_rtti = 1 ;
1190
int output_shared = 1 ;
1191
int output_std = 0 ;
1192
int output_term = 0 ;
1193
int output_tokdec = 0 ;
1194
int output_unused = 1 ;
1195
int output_virtual = 0 ;
1196
 
1197
 
1198
/*
1199
    PROCESS A TDF OUTPUT OPTION
1200
 
1201
    This routine processes the TDF output options given by opt.  This
1202
    corresponds to the command-line option '-jopt'.
1203
*/
1204
 
1205
void output_option
1206
    PROTO_N ( ( opt ) )
1207
    PROTO_T ( string opt )
1208
{
1209
    int out = 1 ;
1210
    character c ;
1211
    while ( c = *( opt++ ), c != 0 ) {
1212
	switch ( c ) {
1213
	    case 'a' : output_all = out ; break ;
1214
	    case 'b' : output_bugs = out ; break ;
1215
	    case 'c' : output_capsule = out ; break ;
1216
	    case 'd' : output_term = out ; break ;
1217
	    case 'e' : output_except = out ; break ;
1218
	    case 'f' : mangle_signature = out ; break ;
1219
	    case 'g' : output_diag = ( DIAG_VERSION * out ) ; break ;
1220
	    case 'h' : output_builtin = out ; break ;
1221
	    case 'i' : output_init = out ; break ;
1222
	    case 'j' : output_inline = out ; break ;
1223
	    case 'l' : output_std = out ; break ;
1224
	    case 'm' : output_date = out ; break ;
1225
	    case 'n' : mangle_objects = out ; break ;
1226
	    case 'o' : output_order = out ; break ;
1227
	    case 'p' : output_partial = out ; break ;
1228
	    case 'r' : output_rtti = out ; break ;
1229
	    case 's' : output_shared = out ; break ;
1230
	    case 't' : output_tokdec = out ; break ;
1231
	    case 'u' : output_unused = out ; break ;
1232
	    case 'v' : output_virtual = out ; break ;
1233
	    case '+' : out = 1 ; break ;
1234
	    case '-' : out = 0 ; break ;
1235
	    default : {
1236
		/* Unknown output options */
1237
		CONST char *err = "Unknown output option, '%c'" ;
1238
		error ( ERROR_WARNING, err, ( int ) c ) ;
1239
		break ;
1240
	    }
1241
	}
1242
    }
1243
    return ;
1244
}
1245
 
1246
 
1247
/*
1248
    ENCODE A VERSION NUMBER
1249
 
1250
    This routine adds the TDF version number to the bitstream bs, making
1251
    adjustments to the minor version number if the extensions they
1252
    represent are not used.
1253
*/
1254
 
1255
BITSTREAM *enc_version
1256
    PROTO_N ( ( bs ) )
1257
    PROTO_T ( BITSTREAM *bs )
1258
{
1259
    int v = TDF_minor ;
1260
#if ( TDF_major == 4 && TDF_minor == 1 )
1261
    if ( !output_new_diag ) v = 0 ;
1262
#endif
1263
    ENC_INT ( bs, TDF_major ) ;
1264
    ENC_INT ( bs, v ) ;
1265
    return ( bs ) ;
1266
}
1267
 
1268
 
1269
/*
1270
    MAIN TDF OUTPUT ROUTINE
1271
 
1272
    This routine outputs the TDF capsule built up by the parsing and
1273
    construction routines.
1274
*/
1275
 
1276
void write_capsule
1277
    PROTO_Z ()
1278
{
1279
    if ( output_tdf && !written_capsule ) {
1280
	/* Open the output file */
1281
	FILE *f ;
1282
	BITSTREAM *bs ;
1283
	written_capsule = 1 ;
1284
	if ( !open_output ( OUTPUT_TDF, binary_mode ) ) {
1285
	    string nm = output_name [ OUTPUT_TDF ] ;
1286
	    fail ( ERR_fail_output ( nm ) ) ;
1287
	    term_error ( 0 ) ;
1288
	    return ;
1289
	}
1290
	f = output_file [ OUTPUT_TDF ] ;
1291
	bs = start_bitstream ( f, NULL_gen_ptr ) ;
1292
 
1293
	/* Encode the magic number (4.0 and later) */
1294
	ASSERT ( TDF_VERSION == 100 * TDF_major + TDF_minor ) ;
1295
#if ( TDF_major >= 4 )
1296
	ENC_BITS ( bs, 8, ascii_T ) ;
1297
	ENC_BITS ( bs, 8, ascii_D ) ;
1298
	ENC_BITS ( bs, 8, ascii_F ) ;
1299
	ENC_BITS ( bs, 8, ascii_C ) ;
1300
	bs = enc_version ( bs ) ;
1301
	ENC_ALIGN ( bs ) ;
1302
#endif
1303
 
1304
	/* Encode the main capsule body */
1305
	if ( output_capsule ) {
1306
	    bs = write_capsule_body ( bs ) ;
1307
	} else {
1308
	    ENC_SLIST_SMALL ( bs, 0 ) ;
1309
	    ENC_SLIST_SMALL ( bs, 0 ) ;
1310
	    ENC_SLIST_SMALL ( bs, 0 ) ;
1311
	    ENC_SLIST_SMALL ( bs, 0 ) ;
1312
	}
1313
	end_bitstream ( bs, 1 ) ;
1314
	close_output ( OUTPUT_TDF ) ;
1315
    }
1316
    return ;
1317
}