Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 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
7 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:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 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;
7 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;
7 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
/*** capsule.c --- TDF capsule ADT.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 *** Commentary:
66
 *
67
 * This file implements the TDF capsule routines used by the TDF linker.
68
 *
69
 *** Change Log:
70
 * $Log: capsule.c,v $
71
 * Revision 1.1.1.1  1998/01/17  15:57:18  release
72
 * First version to be checked into rolling release.
73
 *
74
 * Revision 1.5  1997/11/05  14:40:06  smf
75
 * capsule.c:
76
 * 	- Added "dgcompunit" for DDCI work (TDF 4.1).
77
 *
78
 * Revision 1.4  1995/09/22  08:39:10  smf
79
 * Fixed problems with incomplete structures (to shut "tcc" up).
80
 * Fixed some problems in "name-key.c" (no real problems, but rewritten to
81
 * reduce the warnings that were output by "tcc" and "gcc").
82
 * Fixed bug CR95_354.tld-common-id-problem (library capsules could be loaded
83
 * more than once).
84
 *
85
 * Revision 1.3  1995/07/07  15:32:15  smf
86
 * Updated to support TDF specification 4.0.
87
 *
88
 * Revision 1.2  1994/12/12  11:46:13  smf
89
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
90
 * OSSG C Coding Standards.
91
 *
92
 * Revision 1.1.1.1  1994/07/25  16:03:29  smf
93
 * Initial import of TDF linker 3.5 non shared files.
94
 *
95
**/
96
 
97
/****************************************************************************/
98
 
99
#include "capsule.h"
100
#include "debug.h"
101
#include "dstring.h"
102
#include "exception.h"
103
#include "gen-errors.h"
104
#include "istream.h"
105
#include "name-key.h"
106
#include "library.h"
107
#include "syntax.h"
108
#include "tdf.h"
109
#include "unit-entry.h"
110
 
111
#include "solve-cycles.h"
112
 
113
/*--------------------------------------------------------------------------*/
114
 
115
typedef struct UnitSetListEntryT {
116
    struct UnitSetListEntryT   *next;
117
    NStringT			name;
118
} UnitSetListEntryT, *UnitSetListEntryP;
119
 
120
typedef struct UnitSetT {
121
    NStringT			name;
122
    UnitEntryP			entry;
123
} UnitSetT, *UnitSetP;
124
 
125
typedef struct ShapeDataT {
126
    ShapeEntryP			entry;
127
    unsigned			num_ids;
128
    unsigned		       *id_maps;
129
} ShapeDataT, *ShapeDataP;
130
 
131
typedef struct NameDataT {
132
    NameEntryP		       *names_vec;
133
    unsigned			num_names;
134
} NameDataT, *NameDataP;
135
 
136
/*--------------------------------------------------------------------------*/
137
 
138
#define NUM_DEFAULT_UNIT_SETS	(12)
139
 
140
/*--------------------------------------------------------------------------*/
141
 
7 7u83 142
static CStringP capsule_default_unit_set_names[NUM_DEFAULT_UNIT_SETS] = {
2 7u83 143
    "tld",
144
    "tld2",
145
    "versions",
146
    "tokdec",
147
    "tokdef",
148
    "aldef",
149
    "diagtype",
150
    "tagdec",
151
    "diagdef",
152
    "dgcompunit",
153
    "tagdef",
154
    "linkinfo"
155
};
7 7u83 156
static UnitSetT   capsule_default_unit_sets[NUM_DEFAULT_UNIT_SETS];
2 7u83 157
static unsigned   capsule_num_unit_sets;
7 7u83 158
static UnitSetP   capsule_unit_sets     = NIL(UnitSetP);
2 7u83 159
static unsigned   capsule_tld_index     = 0;
160
static unsigned   capsule_tld2_index    = 1;
161
static unsigned   capsule_unit_length;
162
static unsigned   capsule_unit_offset;
7 7u83 163
static ExceptionP XX_capsule_error      = EXCEPTION("error in TDF capsule");
2 7u83 164
static unsigned   capsule_major_version = 0;
165
static unsigned   capsule_minor_version = 0;
166
 
167
/*--------------------------------------------------------------------------*/
168
 
169
static void
7 7u83 170
capsule_setup_defaults(void)
2 7u83 171
{
7 7u83 172
    if (capsule_unit_sets == NIL(UnitSetP)) {
2 7u83 173
	unsigned i;
174
 
7 7u83 175
	for (i = 0; i < NUM_DEFAULT_UNIT_SETS; i++) {
176
	    nstring_copy_cstring(& (capsule_default_unit_sets[i].name),
177
				  capsule_default_unit_set_names[i]);
2 7u83 178
	}
179
	capsule_num_unit_sets = NUM_DEFAULT_UNIT_SETS;
180
	capsule_unit_sets     = capsule_default_unit_sets;
181
    }
182
}
183
 
184
static void
7 7u83 185
capsule_setup(UnitTableP  units)
2 7u83 186
{
187
    static BoolT need_setup = TRUE;
188
 
189
    if (need_setup) {
190
	unsigned i;
191
 
7 7u83 192
	capsule_setup_defaults();
193
	for (i = 0; i < capsule_num_unit_sets; i++) {
194
	    NStringP   name = & (capsule_unit_sets[i].name);
2 7u83 195
	    UnitEntryP entry;
196
 
7 7u83 197
	    entry = unit_table_add(units, name, i);
198
	    capsule_unit_sets[i].entry = entry;
199
	    debug_info_u_name(name);
2 7u83 200
	}
201
	need_setup = FALSE;
202
    }
203
}
204
 
205
static BoolT
7 7u83 206
capsule_read_unit_set_name(IStreamP istream,				    DStringP dstring)
2 7u83 207
{
208
    char c;
209
 
210
    do {
7 7u83 211
	if (!istream_read_char(istream, &c)) {
212
	    return(FALSE);
2 7u83 213
	}
7 7u83 214
    } while (syntax_is_white_space(c));
2 7u83 215
    if (c != '"') {
7 7u83 216
	E_unit_set_expected_quote(istream);
2 7u83 217
	UNREACHED;
218
    }
7 7u83 219
    dstring_init(dstring);
220
    while (istream_read_char(istream, &c)) {
2 7u83 221
	if (c == '"') {
7 7u83 222
	    return(TRUE);
2 7u83 223
	} else if (c == '\\') {
7 7u83 224
	    switch (istream_read_escaped_char(istream, &c))EXHAUSTIVE {
2 7u83 225
	      case ISTREAM_STAT_READ_CHAR:
7 7u83 226
		dstring_append_char(dstring, c);
2 7u83 227
		break;
228
	      case ISTREAM_STAT_NO_CHAR:
229
		break;
230
	      case ISTREAM_STAT_SYNTAX_ERROR:
7 7u83 231
		E_unit_set_illegal_escape(istream);
2 7u83 232
		UNREACHED;
233
	    }
234
	} else {
7 7u83 235
	    dstring_append_char(dstring, c);
2 7u83 236
	}
237
    }
7 7u83 238
    E_unit_set_eof_in_name(istream);
2 7u83 239
    UNREACHED;
240
}
241
 
242
static void
7 7u83 243
capsule_check_unit_sets(IStreamP istream)
2 7u83 244
{
245
    static BoolT    inited    = FALSE;
246
    static NStringT tld;
247
    static NStringT tld2;
248
    BoolT           tld_found = FALSE;
249
    unsigned        i;
250
 
251
    if (!inited) {
7 7u83 252
	nstring_copy_cstring(&tld, "tld");
253
	nstring_copy_cstring(&tld2, "tld2");
2 7u83 254
	inited = TRUE;
255
    }
256
    capsule_tld_index  = UINT_MAX;
257
    capsule_tld2_index = UINT_MAX;
7 7u83 258
    for (i = 0; i < capsule_num_unit_sets; i++) {
259
	NStringP name = & (capsule_unit_sets[i].name);
2 7u83 260
	unsigned j;
261
 
7 7u83 262
	for (j = 0; j < i; j++) {
263
	    if (nstring_equal(name, & (capsule_unit_sets[j].name))) {
264
		E_unit_set_duplicate_name(istream_name(istream), name);
2 7u83 265
		UNREACHED;
266
	    }
267
	}
7 7u83 268
	if (nstring_equal(name, &tld)) {
2 7u83 269
	    capsule_tld_index = i;
270
	    tld_found         = TRUE;
7 7u83 271
	} else if (nstring_equal(name, &tld2)) {
2 7u83 272
	    capsule_tld2_index = i;
273
	}
274
    }
275
    if (!tld_found) {
7 7u83 276
	E_unit_set_no_tld_name(istream_name(istream));
2 7u83 277
	UNREACHED;
278
    }
279
}
280
 
281
static void
7 7u83 282
capsule_read_unit_set_file_1(IStreamP istream)
2 7u83 283
{
7 7u83 284
    UnitSetListEntryP  head          = NIL(UnitSetListEntryP);
2 7u83 285
    UnitSetListEntryP *tail          = &head;
286
    unsigned           num_unit_sets = 0;
287
    UnitSetListEntryP  entry;
288
    UnitSetP           unit_sets;
289
    unsigned           i;
290
 
291
    for (;;) {
292
	DStringT dstring;
293
 
7 7u83 294
	if (!capsule_read_unit_set_name(istream, &dstring)) {
2 7u83 295
	    goto done;
296
	}
7 7u83 297
	entry       = ALLOCATE(UnitSetListEntryT);
298
	entry->next = NIL(UnitSetListEntryP);
299
	dstring_to_nstring(&dstring, & (entry->name));
2 7u83 300
	*tail       = entry;
7 7u83 301
	tail        = & (entry->next);
302
	dstring_destroy(&dstring);
303
	num_unit_sets++;
2 7u83 304
    }
305
  done:
7 7u83 306
    unit_sets = ALLOCATE_VECTOR(UnitSetT, num_unit_sets);
2 7u83 307
    i         = 0;
308
    entry     = head;
309
    while (entry) {
310
	UnitSetListEntryP tmp = entry->next;
311
 
7 7u83 312
	nstring_assign(& (unit_sets[i].name), & (entry->name));
313
	DEALLOCATE(entry);
2 7u83 314
	entry = tmp;
7 7u83 315
	i++;
2 7u83 316
    }
317
    capsule_num_unit_sets = num_unit_sets;
318
    capsule_unit_sets     = unit_sets;
7 7u83 319
    capsule_check_unit_sets(istream);
2 7u83 320
}
321
 
322
/*--------------------------------------------------------------------------*/
323
 
324
static TDFReaderP
7 7u83 325
capsule_reader(CapsuleP capsule)
2 7u83 326
{
7 7u83 327
    ASSERT(capsule->type == CT_INPUT);
328
    return(& (capsule->u.reader));
2 7u83 329
}
330
 
331
static TDFWriterP
7 7u83 332
capsule_writer(CapsuleP capsule)
2 7u83 333
{
7 7u83 334
    ASSERT(capsule->type == CT_OUTPUT);
335
    return(& (capsule->u.writer));
2 7u83 336
}
337
 
338
static NStringP
7 7u83 339
capsule_magic(void)
2 7u83 340
{
341
    static NStringT const_magic;
342
    static BoolT    inited = FALSE;
343
 
344
    if (!inited) {
7 7u83 345
	nstring_copy_cstring(&const_magic, "TDFC");
2 7u83 346
	inited = TRUE;
347
    }
7 7u83 348
    return(&const_magic);
2 7u83 349
}
7 7u83 350
 
2 7u83 351
/*--------------------------------------------------------------------------*/
352
 
353
static void
7 7u83 354
capsule_read_header(CapsuleP capsule)
2 7u83 355
{
7 7u83 356
    TDFReaderP reader      = capsule_reader(capsule);
357
    NStringP   const_magic = capsule_magic();
2 7u83 358
    NStringT   magic;
359
    unsigned   major;
360
    unsigned   minor;
361
 
7 7u83 362
    nstring_init_length(&magic,(unsigned)4);
363
    tdf_read_bytes(reader, &magic);
364
    if (!nstring_equal(&magic, const_magic)) {
365
	E_capsule_bad_magic(capsule, &magic, const_magic);
366
	THROW(XX_capsule_error);
2 7u83 367
	UNREACHED;
368
    }
7 7u83 369
    nstring_destroy(&magic);
370
    major = tdf_read_int(reader);
371
    minor = tdf_read_int(reader);
372
    debug_info_r_versions(major, minor);
2 7u83 373
    if (major < 4) {
7 7u83 374
	E_capsule_bad_version(capsule, major);
375
	THROW(XX_capsule_error);
2 7u83 376
	UNREACHED;
377
    } else if (capsule_major_version == 0) {
378
	capsule_major_version = major;
379
	capsule_minor_version = minor;
380
    } else if (capsule_major_version != major) {
7 7u83 381
	E_capsule_version_mismatch(capsule, capsule_major_version, major);
382
	THROW(XX_capsule_error);
2 7u83 383
	UNREACHED;
384
    } else if (capsule_minor_version < minor) {
385
	capsule_minor_version = minor;
386
    }
7 7u83 387
    tdf_read_align(reader);
2 7u83 388
}
389
 
390
static UnitEntryP *
7 7u83 391
capsule_read_unit_set_names(CapsuleP   capsule,				     UnitTableP units, 
2 7u83 392
				     unsigned  *num_unit_sets_ref)
393
{
7 7u83 394
    TDFReaderP  reader        = capsule_reader(capsule);
395
    unsigned    num_unit_sets = tdf_read_int(reader);
396
    UnitEntryP *units_vec     = ALLOCATE_VECTOR(UnitEntryP, num_unit_sets);
397
    UnitEntryP  tld_entry     = capsule_unit_sets[capsule_tld_index].entry;
398
    UnitEntryP  tld2_entry    = ((capsule_tld2_index == UINT_MAX)?
399
				 NIL(UnitEntryP):
400
				 capsule_unit_sets[capsule_tld2_index].entry);
2 7u83 401
    BoolT       has_tld_unit  = FALSE;
402
    unsigned    i;
403
 
7 7u83 404
    debug_info_r_start_unit_decs(num_unit_sets);
405
    for (i = 0; i < num_unit_sets; i++) {
2 7u83 406
	NStringT   nstring;
407
	UnitEntryP entry;
408
 
7 7u83 409
	tdf_read_string(reader, &nstring);
410
	if ((entry = unit_table_get(units, &nstring)) != NIL(UnitEntryP)) {
411
	    unsigned order = unit_entry_order(entry);
2 7u83 412
	    unsigned j;
413
 
7 7u83 414
	    for (j = 0; j < i; j++) {
415
		if (entry == units_vec[j]) {
416
		    E_duplicate_unit_set_name(capsule, &nstring);
417
		    THROW(XX_capsule_error);
2 7u83 418
		    UNREACHED;
7 7u83 419
		} else if (order < unit_entry_order(units_vec[j])) {
420
		    E_out_of_order_unit_set_name(capsule, &nstring);
421
		    THROW(XX_capsule_error);
2 7u83 422
		    UNREACHED;
423
		}
424
	    }
425
	    if (entry == tld2_entry) {
7 7u83 426
		E_tld2_unit_set_type_obsolete(capsule);
2 7u83 427
	    }
428
	    if ((entry == tld_entry) || (entry == tld2_entry)) {
429
		if (has_tld_unit) {
7 7u83 430
		    E_extra_tld_unit_set(capsule);
431
		    THROW(XX_capsule_error);
2 7u83 432
		    UNREACHED;
433
		}
434
		has_tld_unit = TRUE;
435
	    }
7 7u83 436
	    units_vec[i] = entry;
2 7u83 437
	} else {
7 7u83 438
	    E_unknown_unit_set_name(capsule, &nstring);
439
	    THROW(XX_capsule_error);
2 7u83 440
	    UNREACHED;
441
	}
7 7u83 442
	debug_info_r_unit_dec(&nstring);
443
	nstring_destroy(&nstring);
2 7u83 444
    }
445
    if (!has_tld_unit) {
7 7u83 446
	E_missing_tld_unit_set(tdf_reader_name(reader));
2 7u83 447
    }
448
    *num_unit_sets_ref = num_unit_sets;
7 7u83 449
    return(units_vec);
2 7u83 450
}
451
 
452
static ShapeDataP
7 7u83 453
capsule_read_shapes(CapsuleP    capsule,			     ShapeTableP shapes, 
2 7u83 454
			     unsigned   *num_shapes_ref)
455
{
7 7u83 456
    TDFReaderP reader     = capsule_reader(capsule);
457
    unsigned   num_shapes = tdf_read_int(reader);
458
    ShapeDataP shapes_vec = ALLOCATE_VECTOR(ShapeDataT, num_shapes);
2 7u83 459
    unsigned   i;
460
 
7 7u83 461
    debug_info_r_start_shapes(num_shapes);
462
    for (i = 0; i < num_shapes; i++) {
2 7u83 463
	NStringT    nstring;
464
	unsigned    num_ids;
465
	ShapeEntryP entry;
466
	unsigned    j;
467
 
7 7u83 468
	tdf_read_string(reader, &nstring);
469
	num_ids = tdf_read_int(reader);
470
	entry   = shape_table_add(shapes, &nstring);
471
	for (j = 0; j < i; j++) {
472
	    if (entry == shapes_vec[j].entry) {
473
		E_duplicate_shape_name(capsule, &nstring);
474
		THROW(XX_capsule_error);
2 7u83 475
		UNREACHED;
476
	    }
477
	}
7 7u83 478
	debug_info_r_shape(&nstring, num_ids);
479
	nstring_destroy(&nstring);
480
	shapes_vec[i].entry   = entry;
481
	shapes_vec[i].num_ids = num_ids;
482
	shapes_vec[i].id_maps = ALLOCATE_VECTOR(unsigned, num_ids);
483
	for (j = 0; j < num_ids; j++) {
484
	    shapes_vec[i].id_maps[j] = UINT_MAX;
2 7u83 485
	}
486
    }
487
    *num_shapes_ref = num_shapes;
7 7u83 488
    return(shapes_vec);
2 7u83 489
}
490
 
491
static NameEntryP *
7 7u83 492
capsule_read_external_names_1(CapsuleP   capsule,				       ShapeDataP shape, 
2 7u83 493
				       unsigned  *num_ref)
494
{
7 7u83 495
    TDFReaderP  reader         = capsule_reader(capsule);
496
    unsigned    num_this_shape = tdf_read_int(reader);
2 7u83 497
    ShapeEntryP entry          = shape->entry;
7 7u83 498
    NStringP    key            = shape_entry_key(entry);
499
    NameTableP  table          = shape_entry_name_table(entry);
2 7u83 500
    unsigned    num_ids        = shape->num_ids;
501
    unsigned   *id_maps        = shape->id_maps;
7 7u83 502
    NameEntryP *names_vec      = ALLOCATE_VECTOR(NameEntryP, num_this_shape);
2 7u83 503
    unsigned    i;
504
 
7 7u83 505
    debug_info_r_start_shape_names(key, num_this_shape);
506
    for (i = 0; i < num_this_shape; i++) {
507
	unsigned   id = tdf_read_int(reader);
2 7u83 508
	NameKeyT   name;
509
	NameEntryP name_entry;
510
 
7 7u83 511
	tdf_read_name(reader, &name);
2 7u83 512
	if (id >= num_ids) {
7 7u83 513
	    E_name_id_out_of_range(capsule, key, &name, id, num_ids);
514
	    THROW(XX_capsule_error);
2 7u83 515
	    UNREACHED;
516
	}
7 7u83 517
	name_entry = name_table_add(table, &name, entry);
518
	if (id_maps[id]!= UINT_MAX) {
519
	    E_name_id_used_multiple_times(capsule, key, &name, id);
520
	    THROW(XX_capsule_error);
2 7u83 521
	    UNREACHED;
522
	}
7 7u83 523
	names_vec[i] = name_entry;
524
	id_maps[id] = name_entry_id(name_entry);
525
	debug_info_r_name(&name, id, id_maps[id],
526
			   name_entry_key(name_entry));
527
	name_key_destroy(&name);
2 7u83 528
    }
529
    *num_ref = num_this_shape;
7 7u83 530
    return(names_vec);
2 7u83 531
}
532
 
533
static NameDataP
7 7u83 534
capsule_read_external_names(CapsuleP   capsule,				     unsigned   num_shapes, 
2 7u83 535
				     ShapeDataP shapes_vec)
536
{
7 7u83 537
    TDFReaderP reader = capsule_reader(capsule);
2 7u83 538
    NameDataT *names_vec_vec;
539
    unsigned   num_names;
540
    unsigned   i;
541
 
7 7u83 542
    if ((num_names = tdf_read_int(reader)) != num_shapes) {
543
	E_shape_and_name_count_mismatch(capsule, num_shapes, num_names);
544
	THROW(XX_capsule_error);
2 7u83 545
	UNREACHED;
546
    }
7 7u83 547
    debug_info_r_start_names(num_names);
548
    names_vec_vec = ALLOCATE_VECTOR(NameDataT, num_names);
549
    for (i = 0; i < num_names; i++) {
550
	ShapeDataP  shape = & (shapes_vec[i]);
2 7u83 551
	NameEntryP *names_vec;
552
	unsigned    num_this_shape;
553
 
7 7u83 554
	names_vec = capsule_read_external_names_1(capsule, shape,
2 7u83 555
						   &num_this_shape);
7 7u83 556
	names_vec_vec[i].names_vec = names_vec;
557
	names_vec_vec[i].num_names = num_this_shape;
2 7u83 558
    }
7 7u83 559
    return(names_vec_vec);
2 7u83 560
}
561
 
562
/*--------------------------------------------------------------------------*/
563
 
564
static unsigned
7 7u83 565
capsule_get_token_index(ShapeTableP shapes,				 unsigned    num_shapes, 
2 7u83 566
				 ShapeDataP  shapes_vec)
567
{
7 7u83 568
    ShapeEntryP token_entry = shape_table_get_token_entry(shapes);
2 7u83 569
    unsigned    i;
570
 
7 7u83 571
    for (i = 0; i < num_shapes; i++) {
572
	if (shapes_vec[i].entry == token_entry) {
573
	    return(i);
2 7u83 574
	}
575
    }
7 7u83 576
    return(UINT_MAX);
2 7u83 577
}
578
 
579
static unsigned
7 7u83 580
capsule_get_tag_index(ShapeTableP shapes,			       unsigned    num_shapes, 
2 7u83 581
			       ShapeDataP  shapes_vec)
582
{
7 7u83 583
    ShapeEntryP tag_entry = shape_table_get_tag_entry(shapes);
2 7u83 584
    unsigned    i;
585
 
7 7u83 586
    for (i = 0; i < num_shapes; i++) {
587
	if (shapes_vec[i].entry == tag_entry) {
588
	    return(i);
2 7u83 589
	}
590
    }
7 7u83 591
    return(UINT_MAX);
2 7u83 592
}
593
 
594
static void
7 7u83 595
capsule_read_usage(CapsuleP  capsule,			    NameDataP entry, 
596
			    BoolT     need_dec, 
597
			    BoolT     no_mult, 
2 7u83 598
			    NStringP  shape_key)
599
{
7 7u83 600
    TDFReaderP  reader    = capsule_reader(capsule);
2 7u83 601
    unsigned    num_names = entry->num_names;
602
    NameEntryP *names_vec = entry->names_vec;
603
    unsigned    i;
604
 
7 7u83 605
    debug_info_r_start_usages(shape_key, num_names);
606
    for (i = 0; i < num_names; i++) {
607
	unsigned   use        = tdf_read_int(reader);
608
	NameEntryP name_entry = names_vec[i];
609
	unsigned   name_use   = name_entry_get_use(name_entry);
610
	NameKeyP   key        = name_entry_key(name_entry);
2 7u83 611
 
612
	if (use & ~(U_USED | U_DECD | U_DEFD | U_MULT)) {
7 7u83 613
	    E_bad_usage(capsule, shape_key, key, use);
614
	    THROW(XX_capsule_error);
2 7u83 615
	    UNREACHED;
616
	} else if (no_mult && (use & U_MULT)) {
7 7u83 617
	    E_illegally_multiply_defined(capsule, shape_key, key);
618
	    THROW(XX_capsule_error);
2 7u83 619
	    UNREACHED;
620
	} else if (need_dec &&
7 7u83 621
		  (((use & (U_DEFD | U_DECD)) == U_DEFD) ||
622
		   ((use & (U_MULT | U_DECD)) == U_MULT))) {
623
	    E_defined_but_not_declared(capsule, shape_key, key);
624
	    THROW(XX_capsule_error);
2 7u83 625
	    UNREACHED;
626
	}
627
	if ((use & U_DEFD) && (name_use & U_DEFD)) {
7 7u83 628
	    CapsuleP definition = name_entry_get_definition(name_entry);
629
	    CStringP prev_name  = capsule_name(definition);
2 7u83 630
 
7 7u83 631
	    E_multiply_defined(capsule, shape_key, key, prev_name);
2 7u83 632
	} else if ((use & U_MULT) && (name_use & U_MULT) &&
7 7u83 633
		  (!(use & U_DEFD)) && (!(name_use & U_DEFD))) {
634
	    name_entry_set_definition(name_entry, NIL(CapsuleP));
2 7u83 635
	} else if ((use & U_DEFD) ||
7 7u83 636
		  ((use & U_MULT) && (!(name_use & (U_MULT | U_DEFD))))) {
637
	    name_entry_set_definition(name_entry, capsule);
2 7u83 638
	}
7 7u83 639
	debug_info_r_usage(use, name_use, key);
640
	name_entry_merge_use(name_entry, use);
2 7u83 641
    }
642
}
643
 
644
static void
7 7u83 645
capsule_read_tld_type_0_unit(CapsuleP capsule, ShapeTableP shapes,
646
			     unsigned num_shapes, ShapeDataP shapes_vec,
647
			     NameDataP names_vec_vec)
2 7u83 648
{
649
    unsigned i;
650
 
7 7u83 651
    i = capsule_get_token_index(shapes, num_shapes, shapes_vec);
2 7u83 652
    if (i != UINT_MAX) {
7 7u83 653
	NStringP key = shape_entry_key(shapes_vec[i].entry);
2 7u83 654
 
7 7u83 655
	capsule_read_usage(capsule, & (names_vec_vec[i]), FALSE, TRUE, key);
2 7u83 656
    }
7 7u83 657
    i = capsule_get_tag_index(shapes, num_shapes, shapes_vec);
2 7u83 658
    if (i != UINT_MAX) {
7 7u83 659
	NStringP key = shape_entry_key(shapes_vec[i].entry);
2 7u83 660
 
7 7u83 661
	capsule_read_usage(capsule, & (names_vec_vec[i]), TRUE, FALSE, key);
2 7u83 662
    }
663
}
664
 
665
static void
7 7u83 666
capsule_read_tld_type_1_unit(CapsuleP capsule, ShapeTableP shapes,
667
			     unsigned num_shapes, ShapeDataP shapes_vec,
668
			     NameDataP names_vec_vec)
2 7u83 669
{
670
    unsigned i;
7 7u83 671
    unsigned token = capsule_get_token_index(shapes, num_shapes, shapes_vec);
672
    unsigned tag   = capsule_get_tag_index(shapes, num_shapes, shapes_vec);
2 7u83 673
 
7 7u83 674
    for (i = 0; i < num_shapes; i++) {
675
	NStringP key = shape_entry_key(shapes_vec[i].entry);
2 7u83 676
 
7 7u83 677
	capsule_read_usage(capsule, & (names_vec_vec[i]), i == tag,
2 7u83 678
			    i == token, key);
679
    }
680
}
681
 
682
/*--------------------------------------------------------------------------*/
683
 
7 7u83 684
typedef void(*UnitTypeProcP)
685
(CapsuleP, ShapeTableP, unsigned, ShapeDataP, NameDataP);
2 7u83 686
 
7 7u83 687
static UnitTypeProcP capsule_type_jump_table[] = {
2 7u83 688
    capsule_read_tld_type_0_unit,
689
    capsule_read_tld_type_1_unit
690
};
691
 
692
#define CAPSULE_TYPE_JUMP_TABLE_SIZE \
7 7u83 693
	((unsigned)(sizeof(capsule_type_jump_table) / \
694
		     sizeof(UnitTypeProcP)))
2 7u83 695
 
696
/*--------------------------------------------------------------------------*/
697
 
698
static void
7 7u83 699
capsule_read_tld_unit_header(CapsuleP capsule,				      NStringP unit_set)
2 7u83 700
{
7 7u83 701
    TDFReaderP reader = capsule_reader(capsule);
2 7u83 702
 
7 7u83 703
    if (tdf_read_int(reader) != 1) {
704
	E_too_many_tld_units(capsule);
705
	THROW(XX_capsule_error);
2 7u83 706
	UNREACHED;
707
    }
7 7u83 708
    debug_info_r_start_units(unit_set,(unsigned)1);
709
    debug_info_r_start_unit(unit_set,(unsigned)1,(unsigned)1);
710
    if (tdf_read_int(reader) != 0) {
711
	E_too_many_tld_unit_counts(capsule);
712
	THROW(XX_capsule_error);
2 7u83 713
	UNREACHED;
714
    }
7 7u83 715
    debug_info_r_start_counts((unsigned)0);
716
    if (tdf_read_int(reader) != 0) {
717
	E_too_many_tld_unit_mappings(capsule);
718
	THROW(XX_capsule_error);
2 7u83 719
	UNREACHED;
720
    }
7 7u83 721
    debug_info_r_start_maps((unsigned)0);
722
    capsule_unit_length = tdf_read_int(reader);
723
    debug_info_r_unit_body(capsule_unit_length);
724
    tdf_read_align(reader);
725
    capsule_unit_offset = tdf_reader_byte(reader);
2 7u83 726
}
727
 
728
static void
7 7u83 729
capsule_read_tld_unit_trailer(CapsuleP capsule)
2 7u83 730
{
7 7u83 731
    TDFReaderP reader  = capsule_reader(capsule);
732
    unsigned   offset  = tdf_reader_byte(reader);
2 7u83 733
    unsigned   correct = (capsule_unit_offset + capsule_unit_length);
734
 
7 7u83 735
    tdf_read_align(reader);
2 7u83 736
    if (correct != offset) {
7 7u83 737
	E_tld_unit_wrong_size(capsule, correct, offset);
738
	THROW(XX_capsule_error);
2 7u83 739
	UNREACHED;
740
    }
741
}
742
 
743
static void
7 7u83 744
capsule_read_tld2_units(CapsuleP capsule, ShapeTableP shapes,
745
			unsigned num_shapes, ShapeDataP shapes_vec,
746
			NameDataP names_vec_vec)
2 7u83 747
{
7 7u83 748
    UnitEntryP tld2_entry = capsule_unit_sets[capsule_tld2_index].entry;
749
    NStringP   key        = unit_entry_key(tld2_entry);
2 7u83 750
 
7 7u83 751
    ASSERT(capsule_tld2_index != UINT_MAX);
752
    capsule_read_tld_unit_header(capsule, key);
753
    debug_info_r_tld_version((unsigned)0);
754
    capsule_read_tld_type_0_unit(capsule, shapes, num_shapes, shapes_vec,
2 7u83 755
				  names_vec_vec);
7 7u83 756
    capsule_read_tld_unit_trailer(capsule);
2 7u83 757
}
758
 
759
static void
7 7u83 760
capsule_read_tld_units(CapsuleP capsule, ShapeTableP shapes,
761
		       unsigned num_shapes, ShapeDataP shapes_vec,
762
		       NameDataP names_vec_vec)
2 7u83 763
{
7 7u83 764
    TDFReaderP reader    = capsule_reader(capsule);
765
    UnitEntryP tld_entry = capsule_unit_sets[capsule_tld_index].entry;
766
    NStringP   key       = unit_entry_key(tld_entry);
2 7u83 767
    unsigned   unit_type;
768
 
7 7u83 769
    capsule_read_tld_unit_header(capsule, key);
770
    unit_type = tdf_read_int(reader);
2 7u83 771
    if (unit_type >= CAPSULE_TYPE_JUMP_TABLE_SIZE) {
7 7u83 772
	E_unknown_tld_unit_type(capsule, unit_type);
773
	THROW(XX_capsule_error);
2 7u83 774
	UNREACHED;
775
    }
7 7u83 776
    debug_info_r_tld_version(unit_type);
777
   (*(capsule_type_jump_table[unit_type]))(capsule, shapes, num_shapes,
2 7u83 778
					      shapes_vec, names_vec_vec);
7 7u83 779
    capsule_read_tld_unit_trailer(capsule);
2 7u83 780
}
781
 
782
static MapEntryP *
7 7u83 783
capsule_read_unit_counts(CapsuleP capsule, unsigned num_shapes,
784
			 ShapeDataP shapes_vec, unsigned num_counts,
785
			 UnitEntryP unit_entry, UnitP unit, unsigned unit_num)
2 7u83 786
{
787
    if ((num_counts != 0) && (num_counts != num_shapes)) {
7 7u83 788
	E_unit_count_num_mismatch(capsule, num_counts, num_shapes, unit_num,
789
				   unit_entry_key(unit_entry));
790
	THROW(XX_capsule_error);
2 7u83 791
	UNREACHED;
792
    }
7 7u83 793
    debug_info_r_start_counts(num_counts);
2 7u83 794
    if (num_counts != 0) {
7 7u83 795
	TDFReaderP reader  = capsule_reader(capsule);
796
	MapTableP  table   = unit_map_table(unit);
797
	MapEntryP *entries = ALLOCATE_VECTOR(MapEntryP, num_counts);
2 7u83 798
	unsigned   i;
799
 
7 7u83 800
	for (i = 0; i < num_counts; i++) {
801
	    unsigned  count = tdf_read_int(reader);
802
	    NStringP  key   = shape_entry_key(shapes_vec[i].entry);
803
	    MapEntryP entry = map_table_add(table, key, count);
2 7u83 804
 
7 7u83 805
	    debug_info_r_count(count, key);
806
	    entries[i] = entry;
2 7u83 807
	}
7 7u83 808
	return(entries);
2 7u83 809
    } else {
7 7u83 810
	return(NIL(MapEntryP *));
2 7u83 811
    }
812
}
813
 
814
static void
7 7u83 815
capsule_read_unit_maps(CapsuleP capsule, unsigned num_counts,
816
		       ShapeDataP shapes_vec, UnitEntryP unit_entry,
817
		       unsigned unit_num, MapEntryP *entries)
2 7u83 818
{
7 7u83 819
    TDFReaderP reader          = capsule_reader(capsule);
820
    unsigned   num_link_shapes = tdf_read_int(reader);
2 7u83 821
    unsigned   i;
822
 
823
    if (num_link_shapes != num_counts) {
7 7u83 824
	E_unit_mapping_num_mismatch(capsule, num_link_shapes, num_counts,
825
				     unit_num, unit_entry_key(unit_entry));
826
	THROW(XX_capsule_error);
2 7u83 827
	UNREACHED;
828
    }
7 7u83 829
    debug_info_r_start_maps(num_link_shapes);
830
    for (i = 0; i < num_link_shapes; i++) {
831
	unsigned    num_links   = tdf_read_int(reader);
832
	ShapeEntryP shape_entry = (shapes_vec[i].entry);
833
	NStringP    key         = shape_entry_key(shape_entry);
2 7u83 834
	unsigned    j;
835
 
7 7u83 836
	map_entry_set_num_links(entries[i], num_links);
837
	debug_info_r_start_shape_maps(key, num_links);
838
	for (j = 0; j < num_links; j++) {
839
	    unsigned  internal = tdf_read_int(reader);
840
	    unsigned  external = tdf_read_int(reader);
841
	    unsigned  num_ids  = shapes_vec[i].num_ids;
842
	    unsigned *id_maps  = shapes_vec[i].id_maps;
2 7u83 843
 
844
	    if (external >= num_ids) {
7 7u83 845
		E_id_out_of_range(capsule, external, num_ids, key, unit_num,
846
				   unit_entry_key(unit_entry));
847
		THROW(XX_capsule_error);
2 7u83 848
		UNREACHED;
849
	    }
7 7u83 850
	    if (id_maps[external] == UINT_MAX) {
851
		unsigned id = shape_entry_next_id(shape_entry);
2 7u83 852
 
7 7u83 853
		id_maps[external] = id;
2 7u83 854
	    }
7 7u83 855
	    debug_info_r_map(internal, external, id_maps[external]);
856
	    external = id_maps[external];
857
	    map_entry_set_link(entries[i], j, internal, external);
2 7u83 858
	}
859
    }
860
}
861
 
862
static void
7 7u83 863
capsule_read_unit(CapsuleP capsule, unsigned num_shapes, ShapeDataP shapes_vec,
864
		  UnitEntryP unit_entry, unsigned unit_num)
2 7u83 865
{
7 7u83 866
    TDFReaderP reader     = capsule_reader(capsule);
867
    unsigned   num_counts = tdf_read_int(reader);
868
    UnitP      unit       = unit_entry_add_unit(unit_entry, num_counts);
2 7u83 869
    MapEntryP *entries;
870
    unsigned   size;
871
    NStringT   nstring;
872
 
7 7u83 873
    entries = capsule_read_unit_counts(capsule, num_shapes, shapes_vec,
2 7u83 874
					num_counts, unit_entry, unit,
875
					unit_num);
7 7u83 876
    capsule_read_unit_maps(capsule, num_counts, shapes_vec, unit_entry,
2 7u83 877
			    unit_num, entries);
7 7u83 878
    size = tdf_read_int(reader);
879
    debug_info_r_unit_body(size);
880
    nstring_init_length(&nstring, size);
881
    tdf_read_bytes(reader, &nstring);
882
    unit_set_contents(unit, &nstring);
883
    DEALLOCATE(entries);
2 7u83 884
}
885
 
886
static void
7 7u83 887
capsule_read_units(CapsuleP   capsule,			    unsigned   num_shapes, 
888
			    ShapeDataP shapes_vec, 
2 7u83 889
			    UnitEntryP unit_entry)
890
{
7 7u83 891
    TDFReaderP reader    = capsule_reader(capsule);
892
    unsigned   num_units = tdf_read_int(reader);
2 7u83 893
    unsigned   i;
894
 
7 7u83 895
    debug_info_r_start_units(unit_entry_key(unit_entry), num_units);
896
    for (i = 0; i < num_units; i++) {
897
	debug_info_r_start_unit(unit_entry_key(unit_entry), i + 1,
2 7u83 898
				 num_units);
7 7u83 899
	capsule_read_unit(capsule, num_shapes, shapes_vec, unit_entry, i);
2 7u83 900
    }
901
}
902
 
903
static void
7 7u83 904
capsule_read_unit_sets(CapsuleP capsule, unsigned num_unit_sets,
905
		       UnitEntryP *units_vec, ShapeTableP shapes,
906
		       unsigned num_shapes, ShapeDataP shapes_vec,
907
		       NameDataP names_vec_vec)
2 7u83 908
{
7 7u83 909
    TDFReaderP reader       = capsule_reader(capsule);
910
    UnitEntryP tld_entry    = capsule_unit_sets[capsule_tld_index].entry;
911
    UnitEntryP tld2_entry   = ((capsule_tld2_index == UINT_MAX)?
912
			       NIL(UnitEntryP):
913
			       capsule_unit_sets[capsule_tld2_index].entry);
2 7u83 914
    unsigned   num_units;
915
    unsigned   i;
916
 
7 7u83 917
    if ((num_units = tdf_read_int(reader)) != num_unit_sets) {
918
	E_unit_set_count_mismatch(capsule, num_unit_sets, num_units);
919
	THROW(XX_capsule_error);
2 7u83 920
	UNREACHED;
921
    }
7 7u83 922
    debug_info_r_start_unit_sets(num_units);
923
    for (i = 0; i < num_units; i++) {
924
	if (units_vec[i] == tld_entry) {
925
	    capsule_read_tld_units(capsule, shapes, num_shapes, shapes_vec,
2 7u83 926
				    names_vec_vec);
7 7u83 927
	} else if (units_vec[i] == tld2_entry) {
928
	    capsule_read_tld2_units(capsule, shapes, num_shapes, shapes_vec,
2 7u83 929
				     names_vec_vec);
930
	} else {
7 7u83 931
	    capsule_read_units(capsule, num_shapes, shapes_vec,
932
				units_vec[i]);
2 7u83 933
	}
934
    }
935
}
936
 
937
/*--------------------------------------------------------------------------*/
938
 
939
static void
7 7u83 940
capsule_write_header(CapsuleP capsule)
2 7u83 941
{
7 7u83 942
    TDFWriterP writer      = capsule_writer(capsule);
943
    NStringP   const_magic = capsule_magic();
2 7u83 944
 
7 7u83 945
    tdf_write_bytes(writer, const_magic);
946
    ASSERT(capsule_major_version >= 4);
947
    tdf_write_int(writer, capsule_major_version);
948
    tdf_write_int(writer, capsule_minor_version);
949
    debug_info_w_versions(capsule_major_version, capsule_minor_version);
950
    tdf_write_align(writer);
2 7u83 951
}
952
 
953
/*--------------------------------------------------------------------------*/
954
 
955
void
7 7u83 956
capsule_read_unit_set_file(CStringP name)
2 7u83 957
{
958
    IStreamT istream;
959
 
7 7u83 960
    ASSERT(capsule_unit_sets == NIL(UnitSetP));
961
    if (!istream_open(&istream, name)) {
962
	E_cannot_open_unit_set_file(name);
2 7u83 963
	UNREACHED;
964
    }
7 7u83 965
    capsule_read_unit_set_file_1(&istream);
966
    istream_close(&istream);
2 7u83 967
}
968
 
969
CapsuleP
7 7u83 970
capsule_create_stream_input(CStringP name)
2 7u83 971
{
7 7u83 972
    CapsuleP capsule = ALLOCATE(CapsuleT);
2 7u83 973
 
974
    capsule->type = CT_INPUT;
7 7u83 975
    if (!tdf_reader_open(capsule_reader(capsule), name)) {
976
	DEALLOCATE(capsule);
977
	return(NIL(CapsuleP));
2 7u83 978
    }
979
    capsule->name     = name;
980
    capsule->complete = FALSE;
7 7u83 981
    return(capsule);
2 7u83 982
}
983
 
984
CapsuleP
7 7u83 985
capsule_create_string_input(CStringP name,				     NStringP contents)
2 7u83 986
{
7 7u83 987
    CapsuleP capsule = ALLOCATE(CapsuleT);
2 7u83 988
 
989
    capsule->type     = CT_INPUT;
7 7u83 990
    tdf_reader_open_string(capsule_reader(capsule), name, contents);
2 7u83 991
    capsule->name     = name;
992
    capsule->complete = FALSE;
7 7u83 993
    return(capsule);
2 7u83 994
}
995
 
996
CapsuleP
7 7u83 997
capsule_create_stream_output(CStringP name)
2 7u83 998
{
7 7u83 999
    CapsuleP capsule = ALLOCATE(CapsuleT);
2 7u83 1000
 
1001
    capsule->type = CT_OUTPUT;
7 7u83 1002
    if (!tdf_writer_open(capsule_writer(capsule), name)) {
1003
	DEALLOCATE(capsule);
1004
	return(NIL(CapsuleP));
2 7u83 1005
    }
1006
    capsule->name = name;
7 7u83 1007
    return(capsule);
2 7u83 1008
}
1009
 
1010
CStringP
7 7u83 1011
capsule_name(CapsuleP capsule)
2 7u83 1012
{
7 7u83 1013
    return(capsule->name);
2 7u83 1014
}
1015
 
1016
unsigned
7 7u83 1017
capsule_byte(CapsuleP capsule)
2 7u83 1018
{
7 7u83 1019
    return(tdf_reader_byte(capsule_reader(capsule)));
2 7u83 1020
}
1021
 
1022
void
7 7u83 1023
capsule_read(CapsuleP    capsule,		      UnitTableP  units, 
2 7u83 1024
		      ShapeTableP shapes)
1025
{
7 7u83 1026
    ASSERT(capsule->type == CT_INPUT);
1027
    capsule_setup(units);
2 7u83 1028
    HANDLE {
1029
	UnitEntryP *units_vec;
1030
	unsigned    num_unit_sets;
1031
	ShapeDataP  shapes_vec;
1032
	unsigned    num_shapes;
1033
	NameDataP   names_vec_vec;
1034
	unsigned    i;
1035
 
7 7u83 1036
	debug_info_r_start_capsule(capsule_name(capsule));
1037
	capsule_read_header(capsule);
1038
	units_vec     = capsule_read_unit_set_names(capsule, units,
2 7u83 1039
						     &num_unit_sets);
7 7u83 1040
	shapes_vec    = capsule_read_shapes(capsule, shapes, &num_shapes);
1041
	names_vec_vec = capsule_read_external_names(capsule, num_shapes,
2 7u83 1042
						     shapes_vec);
7 7u83 1043
	capsule_read_unit_sets(capsule, num_unit_sets, units_vec, shapes,
2 7u83 1044
				num_shapes, shapes_vec, names_vec_vec);
7 7u83 1045
	tdf_read_eof(capsule_reader(capsule));
1046
	debug_info_r_end_capsule();
1047
	DEALLOCATE(units_vec);
1048
	for (i = 0; i < num_shapes; i++) {
1049
	    DEALLOCATE(shapes_vec[i].id_maps);
1050
	    DEALLOCATE(names_vec_vec[i].names_vec);
2 7u83 1051
	}
7 7u83 1052
	DEALLOCATE(shapes_vec);
1053
	DEALLOCATE(names_vec_vec);
2 7u83 1054
	capsule->complete = TRUE;
1055
    } WITH {
7 7u83 1056
	ExceptionP exception = EXCEPTION_EXCEPTION();
2 7u83 1057
 
7 7u83 1058
	debug_info_r_abort_capsule();
2 7u83 1059
	if ((exception != XX_capsule_error) &&
7 7u83 1060
	   (exception != XX_tdf_read_error)) {
1061
	    RETHROW();
2 7u83 1062
	}
1063
    } END_HANDLE
1064
}
1065
 
1066
void
7 7u83 1067
capsule_store_contents(CapsuleP capsule)
2 7u83 1068
{
1069
    if (capsule->complete) {
7 7u83 1070
	TDFReaderP reader = capsule_reader(capsule);
1071
	unsigned   length = tdf_reader_byte(reader);
2 7u83 1072
 
7 7u83 1073
	nstring_init_length(& (capsule->contents), length);
1074
	tdf_reader_rewind(reader);
1075
	tdf_read_bytes(reader, & (capsule->contents));
1076
	tdf_read_eof(reader);
2 7u83 1077
    }
1078
}
1079
 
1080
NStringP
7 7u83 1081
capsule_contents(CapsuleP capsule)
2 7u83 1082
{
7 7u83 1083
    return(& (capsule->contents));
2 7u83 1084
}
1085
 
1086
void
7 7u83 1087
capsule_set_index(CapsuleP capsule,			   unsigned i)
2 7u83 1088
{
1089
    capsule->capsule_index = i;
1090
}
1091
 
1092
unsigned
7 7u83 1093
capsule_get_index(CapsuleP capsule)
2 7u83 1094
{
7 7u83 1095
    return(capsule->capsule_index);
2 7u83 1096
}
1097
 
1098
void
7 7u83 1099
capsule_write(CapsuleP    capsule,		       UnitTableP  units, 
2 7u83 1100
		       ShapeTableP shapes)
1101
{
7 7u83 1102
    TDFWriterP      writer     = capsule_writer(capsule);
1103
    UnitEntryP      tld_entry  = capsule_unit_sets[capsule_tld_index].entry;
2 7u83 1104
    unsigned        num_shapes = 0;
1105
    UnitSetClosureT unit_set_closure;
1106
    unsigned        i;
1107
 
7 7u83 1108
    debug_info_w_start_capsule(capsule_name(capsule));
1109
    capsule_write_header(capsule);
2 7u83 1110
    unit_set_closure.num_unit_sets = 1;
1111
    unit_set_closure.shapes        = shapes;
7 7u83 1112
    unit_table_iter(units, unit_entry_do_count,(GenericP) &unit_set_closure);
1113
    debug_info_w_start_unit_decs(unit_set_closure.num_unit_sets);
1114
    tdf_write_int(writer, unit_set_closure.num_unit_sets);
1115
    for (i = 0; i < capsule_num_unit_sets; i++) {
1116
	UnitEntryP entry = capsule_unit_sets[i].entry;
2 7u83 1117
 
7 7u83 1118
	unit_entry_write_unit_set(entry, tld_entry, writer);
2 7u83 1119
    }
7 7u83 1120
    shape_table_iter(shapes, shape_entry_do_count,(GenericP) &num_shapes);
1121
    debug_info_w_start_shapes(num_shapes);
1122
    tdf_write_int(writer, num_shapes);
1123
    shape_table_iter(shapes, shape_entry_write_shape,(GenericP)writer);
1124
    debug_info_w_start_names(num_shapes);
1125
    tdf_write_int(writer, num_shapes);
1126
    shape_table_iter(shapes, shape_entry_write_externs,(GenericP)writer);
1127
    debug_info_w_start_unit_sets(unit_set_closure.num_unit_sets);
1128
    tdf_write_int(writer, unit_set_closure.num_unit_sets);
1129
    for (i = 0; i < capsule_num_unit_sets; i++) {
1130
	UnitEntryP entry = capsule_unit_sets[i].entry;
2 7u83 1131
 
1132
	if (entry == tld_entry) {
7 7u83 1133
	    unit_entry_write_tld_unit(entry, shapes, writer);
2 7u83 1134
	} else {
7 7u83 1135
	    unit_entry_write_units(entry, shapes, num_shapes, writer);
2 7u83 1136
	}
1137
    }
7 7u83 1138
    debug_info_w_end_capsule();
2 7u83 1139
}
1140
 
1141
void
7 7u83 1142
capsule_close(CapsuleP capsule)
2 7u83 1143
{
7 7u83 1144
    switch (capsule->type)EXHAUSTIVE {
2 7u83 1145
      case CT_INPUT:
7 7u83 1146
	tdf_reader_close(capsule_reader(capsule));
2 7u83 1147
	break;
1148
      case CT_OUTPUT:
7 7u83 1149
	tdf_writer_close(capsule_writer(capsule));
2 7u83 1150
	break;
1151
    }
1152
}
1153
 
1154
unsigned
7 7u83 1155
capsule_get_major_version(void)
2 7u83 1156
{
7 7u83 1157
    return(capsule_major_version);
2 7u83 1158
}
1159
 
1160
void
7 7u83 1161
capsule_set_major_version(unsigned major)
2 7u83 1162
{
1163
    capsule_major_version = major;
1164
}
1165
 
1166
unsigned
7 7u83 1167
capsule_get_minor_version(void)
2 7u83 1168
{
7 7u83 1169
    return(capsule_minor_version);
2 7u83 1170
}
1171
 
1172
/*
1173
 * Local variables(smf):
1174
 * eval: (include::add-path-entry "../os-interface" "../library")
1175
 * eval: (include::add-path-entry "../generated")
1176
 * end:
1177
**/