Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

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