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
/*** name-entry.c --- Name table entry ADT.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 *** Commentary:
66
 *
67
 * This file implements the name table entry routines used by the TDF
68
 * linker.
69
 *
70
 *** Change Log:
71
 * $Log: name-entry.c,v $
72
 * Revision 1.1.1.1  1998/01/17  15:57:19  release
73
 * First version to be checked into rolling release.
74
 *
75
 * Revision 1.3  1995/09/22  08:39:24  smf
76
 * Fixed problems with incomplete structures (to shut "tcc" up).
77
 * Fixed some problems in "name-key.c" (no real problems, but rewritten to
78
 * reduce the warnings that were output by "tcc" and "gcc").
79
 * Fixed bug CR95_354.tld-common-id-problem (library capsules could be loaded
80
 * more than once).
81
 *
82
 * Revision 1.2  1994/12/12  11:46:35  smf
83
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
84
 * OSSG C Coding Standards.
85
 *
86
 * Revision 1.1.1.1  1994/07/25  16:03:34  smf
87
 * Initial import of TDF linker 3.5 non shared files.
88
 *
89
**/
90
 
91
/****************************************************************************/
92
 
93
#include "name-entry.h"
94
#include "capsule.h"
95
#include "debug.h"
96
#include "gen-errors.h"
97
#include "library.h"
98
#include "name-table.h"
99
#include "ostream.h"
100
#include "shape-entry.h"
101
#include "shape-table.h"
102
#include "tdf.h"
103
#include "unit-table.h"
104
 
105
#include "solve-cycles.h"
106
 
107
/*--------------------------------------------------------------------------*/
108
 
109
NameEntryP
6 7u83 110
name_entry_create_direct(NameKeyP    key,				  ShapeEntryP shape_entry)
2 7u83 111
{
6 7u83 112
    NameEntryP entry = ALLOCATE(NameEntryT);
2 7u83 113
 
6 7u83 114
    entry->next                    = NIL(NameEntryP);
115
    name_key_copy(& (entry->key), key);
2 7u83 116
    entry->type                    = NT_DIRECT;
6 7u83 117
    entry->u.direct.id             = shape_entry_next_id(shape_entry);
2 7u83 118
    entry->u.direct.use            = 0;
6 7u83 119
    entry->u.direct.definition     = NIL(CapsuleP);
120
    entry->u.direct.lib_definition = NIL(LibCapsuleP);
121
    shape_entry_add_to_list(shape_entry, entry);
122
    return(entry);
2 7u83 123
}
124
 
125
NameEntryP
6 7u83 126
name_entry_create_indirect(NameKeyP   key,				    NameEntryP indirect)
2 7u83 127
{
6 7u83 128
    NameEntryP entry = ALLOCATE(NameEntryT);
2 7u83 129
 
6 7u83 130
    entry->next       = NIL(NameEntryP);
131
    name_key_copy(& (entry->key), key);
2 7u83 132
    entry->type       = NT_INDIRECT;
133
    entry->u.indirect = indirect;
6 7u83 134
    return(entry);
2 7u83 135
}
136
 
137
NameEntryP
6 7u83 138
name_entry_create_place(NameKeyP key)
2 7u83 139
{
6 7u83 140
    NameEntryP entry = ALLOCATE(NameEntryT);
2 7u83 141
 
6 7u83 142
    entry->next       = NIL(NameEntryP);
143
    name_key_copy(& (entry->key), key);
2 7u83 144
    entry->type       = NT_PLACEHOLDER;
6 7u83 145
    return(entry);
2 7u83 146
}
147
 
148
void
6 7u83 149
name_entry_make_direct(NameEntryP  entry,				ShapeEntryP shape_entry)
2 7u83 150
{
6 7u83 151
    ASSERT(name_entry_is_place(entry));
2 7u83 152
    entry->type                    = NT_DIRECT;
6 7u83 153
    entry->u.direct.id             = shape_entry_next_id(shape_entry);
2 7u83 154
    entry->u.direct.use            = 0;
6 7u83 155
    entry->u.direct.definition     = NIL(CapsuleP);
156
    entry->u.direct.lib_definition = NIL(LibCapsuleP);
157
    shape_entry_add_to_list(shape_entry, entry);
2 7u83 158
}
159
 
160
void
6 7u83 161
name_entry_make_indirect(NameEntryP entry,				  NameEntryP indirect)
2 7u83 162
{
6 7u83 163
    ASSERT(name_entry_is_place(entry));
2 7u83 164
    entry->type       = NT_INDIRECT;
165
    entry->u.indirect = indirect;
166
}
167
 
168
NameEntryP
6 7u83 169
name_entry_resolve_renames(NameEntryP entry,				    NStringP   shape, 
2 7u83 170
				    BoolT      report)
171
{
6 7u83 172
    switch (entry->type)EXHAUSTIVE {
2 7u83 173
      case NT_PLACEHOLDER:
174
      case NT_DIRECT:
6 7u83 175
	return(entry);
2 7u83 176
      case NT_INDIRECT_DONE:
6 7u83 177
	return(name_entry_get_indirect(entry));
2 7u83 178
      case NT_INDIRECT_CYCLING:
179
	if (report) {
6 7u83 180
	    E_rename_cycle(shape, name_entry_key(entry));
2 7u83 181
	}
6 7u83 182
	return(NIL(NameEntryP));
2 7u83 183
      case NT_INDIRECT:
184
	entry->type = NT_INDIRECT_CYCLING;
6 7u83 185
	entry->u.indirect = name_entry_resolve_renames(entry->u.indirect,
2 7u83 186
							shape, report);
187
	entry->type = NT_INDIRECT_DONE;
6 7u83 188
	return(name_entry_get_indirect(entry));
2 7u83 189
    }
190
    UNREACHED;
191
}
192
 
193
NameKeyP
6 7u83 194
name_entry_key(NameEntryP entry)
2 7u83 195
{
6 7u83 196
    return(& (entry->key));
2 7u83 197
}
198
 
199
NameEntryP
6 7u83 200
name_entry_next(NameEntryP entry)
2 7u83 201
{
6 7u83 202
    return(entry->next);
2 7u83 203
}
204
 
205
NameEntryP *
6 7u83 206
name_entry_next_ref(NameEntryP entry)
2 7u83 207
{
6 7u83 208
    return(& (entry->next));
2 7u83 209
}
210
 
211
BoolT
6 7u83 212
name_entry_is_direct(NameEntryP entry)
2 7u83 213
{
6 7u83 214
    return(entry->type == NT_DIRECT);
2 7u83 215
}
216
 
217
BoolT
6 7u83 218
name_entry_is_indirect(NameEntryP entry)
2 7u83 219
{
6 7u83 220
    return((entry->type == NT_INDIRECT) ||
221
	   (entry->type == NT_INDIRECT_CYCLING) ||
222
	   (entry->type == NT_INDIRECT_DONE));
2 7u83 223
}
224
 
225
BoolT
6 7u83 226
name_entry_is_place(NameEntryP entry)
2 7u83 227
{
6 7u83 228
    return(entry->type == NT_PLACEHOLDER);
2 7u83 229
}
230
 
231
unsigned
6 7u83 232
name_entry_id(NameEntryP entry)
2 7u83 233
{
6 7u83 234
    ASSERT(name_entry_is_direct(entry));
235
    return(entry->u.direct.id);
2 7u83 236
}
237
 
238
void
6 7u83 239
name_entry_merge_use(NameEntryP entry,			      unsigned   use)
2 7u83 240
{
6 7u83 241
    ASSERT(name_entry_is_direct(entry));
2 7u83 242
    entry->u.direct.use |= use;
243
}
244
 
245
unsigned
6 7u83 246
name_entry_get_use(NameEntryP entry)
2 7u83 247
{
6 7u83 248
    ASSERT(name_entry_is_direct(entry));
249
    return(entry->u.direct.use & (U_DEFD | U_DECD | U_MULT | U_USED));
2 7u83 250
}
251
 
252
void
6 7u83 253
name_entry_hide(NameEntryP entry)
2 7u83 254
{
6 7u83 255
    ASSERT(name_entry_is_direct(entry));
2 7u83 256
    entry->u.direct.use |= U_HIDE;
257
}
258
 
259
void
6 7u83 260
name_entry_unhide(NameEntryP entry)
2 7u83 261
{
6 7u83 262
    ASSERT(name_entry_is_direct(entry));
2 7u83 263
    entry->u.direct.use &= ~U_HIDE;
264
}
265
 
266
BoolT
6 7u83 267
name_entry_is_hidden(NameEntryP entry)
2 7u83 268
{
6 7u83 269
    ASSERT(name_entry_is_direct(entry));
270
    return((entry->u.direct.use & U_HIDE) == U_HIDE);
2 7u83 271
}
272
 
273
void
6 7u83 274
name_entry_set_definition(NameEntryP entry,				   CapsuleP   capsule)
2 7u83 275
{
6 7u83 276
    ASSERT(name_entry_is_direct(entry));
2 7u83 277
    entry->u.direct.definition = capsule;
278
}
279
 
280
CapsuleP
6 7u83 281
name_entry_get_definition(NameEntryP entry)
2 7u83 282
{
6 7u83 283
    ASSERT(name_entry_is_direct(entry));
284
    return(entry->u.direct.definition);
2 7u83 285
}
286
 
287
void
6 7u83 288
name_entry_set_lib_definition(NameEntryP  entry,				       LibCapsuleP capsule)
2 7u83 289
{
6 7u83 290
    ASSERT(name_entry_is_direct(entry));
2 7u83 291
    entry->u.direct.lib_definition = capsule;
292
}
293
 
294
LibCapsuleP
6 7u83 295
name_entry_get_lib_definition(NameEntryP entry)
2 7u83 296
{
6 7u83 297
    ASSERT(name_entry_is_direct(entry));
298
    return(entry->u.direct.lib_definition);
2 7u83 299
}
300
 
301
NameEntryP
6 7u83 302
name_entry_list_next(NameEntryP entry)
2 7u83 303
{
6 7u83 304
    ASSERT(name_entry_is_direct(entry));
305
    return(entry->u.direct.list_next);
2 7u83 306
}
307
 
308
NameEntryP *
6 7u83 309
name_entry_list_next_ref(NameEntryP entry)
2 7u83 310
{
6 7u83 311
    ASSERT(name_entry_is_direct(entry));
312
    return(& (entry->u.direct.list_next));
2 7u83 313
}
314
 
315
NameEntryP
6 7u83 316
name_entry_get_indirect(NameEntryP entry)
2 7u83 317
{
6 7u83 318
    ASSERT(name_entry_is_indirect(entry));
319
    return(entry->u.indirect);
2 7u83 320
}
321
 
322
NameEntryP
6 7u83 323
name_entry_deallocate(NameEntryP entry)
2 7u83 324
{
6 7u83 325
    NameEntryP next = name_entry_next(entry);
2 7u83 326
 
6 7u83 327
    name_key_destroy(name_entry_key(entry));
328
    DEALLOCATE(entry);
329
    return(next);
2 7u83 330
}
331
 
332
/*--------------------------------------------------------------------------*/
333
 
334
void
6 7u83 335
name_entry_do_count(NameEntryP entry,			     GenericP   gclosure)
2 7u83 336
{
6 7u83 337
    unsigned *count_ref = (unsigned *)gclosure;
2 7u83 338
 
6 7u83 339
    if (!(name_entry_is_hidden(entry))) {
340
	(*count_ref)++;
2 7u83 341
    }
342
}
343
 
344
void
6 7u83 345
name_entry_write_name(NameEntryP entry,			       GenericP   gclosure)
2 7u83 346
{
6 7u83 347
    if (!(name_entry_is_hidden(entry))) {
348
	TDFWriterP writer = (TDFWriterP)gclosure;
349
	NameKeyP   key    = name_entry_key(entry);
350
	unsigned   id     = name_entry_id(entry);
2 7u83 351
 
6 7u83 352
	debug_info_w_name(key, id);
353
	tdf_write_int(writer, id);
354
	tdf_write_name(writer, key);
2 7u83 355
    }
356
}
357
 
358
void
6 7u83 359
name_entry_compute_tld_size(NameEntryP entry,				     GenericP   gclosure)
2 7u83 360
{
6 7u83 361
    unsigned *size_ref = (unsigned *)gclosure;
2 7u83 362
 
6 7u83 363
    if (!name_entry_is_hidden(entry)) {
364
	unsigned use = name_entry_get_use(entry);
2 7u83 365
 
6 7u83 366
	(*size_ref) += tdf_int_size(use);
2 7u83 367
    }
368
}
369
 
370
void
6 7u83 371
name_entry_write_tld(NameEntryP entry,			      GenericP   gclosure)
2 7u83 372
{
6 7u83 373
    TDFWriterP writer = (TDFWriterP)gclosure;
2 7u83 374
 
6 7u83 375
    if (!(name_entry_is_hidden(entry))) {
376
	unsigned use = name_entry_get_use(entry);
2 7u83 377
 
6 7u83 378
	debug_info_w_usage(use, name_entry_key(entry));
379
	tdf_write_int(writer, use);
2 7u83 380
    }
381
}
382
 
383
void
6 7u83 384
name_entry_check_multi_defs(NameEntryP entry,				     GenericP   gclosure)
2 7u83 385
{
6 7u83 386
    NStringP shape_name = (NStringP)gclosure;
2 7u83 387
 
6 7u83 388
    if ((name_entry_get_use(entry) & U_MULT) &&
389
	(name_entry_get_definition(entry) == NIL(CapsuleP))) {
390
	E_no_single_definition(shape_name, name_entry_key(entry));
2 7u83 391
    }
392
}
393
 
394
void
6 7u83 395
name_entry_do_lib_count(NameEntryP entry,				 GenericP   gclosure)
2 7u83 396
{
6 7u83 397
    if (name_entry_get_definition(entry)) {
398
	unsigned *num_names_ref = (unsigned *)gclosure;
2 7u83 399
 
6 7u83 400
	(*num_names_ref)++;
2 7u83 401
    }
402
}
403
 
404
void
6 7u83 405
name_entry_do_lib_write(NameEntryP entry,				 GenericP   gclosure)
2 7u83 406
{
6 7u83 407
    CapsuleP definition = name_entry_get_definition(entry);
2 7u83 408
 
409
    if (definition) {
6 7u83 410
	TDFWriterP writer        = (TDFWriterP)gclosure;
411
	NameKeyP   key           = name_entry_key(entry);
412
	unsigned   use           = name_entry_get_use(entry);
413
	unsigned   capsule_index = capsule_get_index(definition);
2 7u83 414
 
6 7u83 415
	debug_info_w_index_entry(key, use, capsule_name(definition),
2 7u83 416
				  capsule_index);
6 7u83 417
	tdf_write_name(writer, key);
418
	tdf_write_int(writer, use);
419
	tdf_write_int(writer, capsule_index);
2 7u83 420
    }
421
}
422
 
423
void
6 7u83 424
name_entry_suppress(NameEntryP entry,			     GenericP   gclosure)
2 7u83 425
{
6 7u83 426
    NStringP shape = (NStringP)gclosure;
2 7u83 427
 
6 7u83 428
    debug_info_l_suppress(shape, name_entry_key(entry));
429
    name_entry_set_lib_definition(entry, NIL(LibCapsuleP));
2 7u83 430
}
431
 
432
void
6 7u83 433
name_entry_builder_suppress(NameEntryP entry,				     GenericP   gclosure)
2 7u83 434
{
6 7u83 435
    NStringP shape = (NStringP)gclosure;
2 7u83 436
 
6 7u83 437
    debug_info_l_suppress(shape, name_entry_key(entry));
438
    name_entry_set_definition(entry, NIL(CapsuleP));
2 7u83 439
}
440
 
441
BoolT
6 7u83 442
name_entry_resolve_undefined(NameEntryP  entry,				      NameTableP  table, 
443
				      UnitTableP  units, 
444
				      ShapeTableP shapes, 
2 7u83 445
				      NStringP    shape_key)
446
{
6 7u83 447
    unsigned use = name_entry_get_use(entry);
448
    NameKeyP key = name_entry_key(entry);
2 7u83 449
 
450
    if ((use & U_DEFD) || (!(use & U_USED))) {
6 7u83 451
	debug_info_l_not_needed(key, shape_key, use);
452
	return(FALSE);
2 7u83 453
    } else if (table) {
6 7u83 454
	NameEntryP lib_entry = name_table_get(table, key);
2 7u83 455
 
456
	if (lib_entry) {
6 7u83 457
	    LibCapsuleP lib_def = name_entry_get_lib_definition(lib_entry);
458
	    unsigned    lib_use = name_entry_get_use(lib_entry);
2 7u83 459
 
6 7u83 460
	    if (lib_def && (!lib_capsule_is_loaded(lib_def)) &&
2 7u83 461
		((!(use & U_MULT)) || (lib_use & U_DEFD))) {
6 7u83 462
		CStringP name     = lib_capsule_full_name(lib_def);
463
		NStringP contents = lib_capsule_contents(lib_def);
2 7u83 464
		CapsuleP capsule;
465
 
6 7u83 466
		debug_info_l_found(key, shape_key, use, name);
467
		capsule = capsule_create_string_input(name, contents);
468
		capsule_read(capsule, units, shapes);
469
		capsule_close(capsule);
470
		lib_capsule_loaded(lib_def);
471
		return(TRUE);
2 7u83 472
	    }
473
	}
474
    }
6 7u83 475
    E_no_definition_found(shape_key, key);
476
    debug_info_l_not_found(key, shape_key, use);
477
    return(FALSE);
2 7u83 478
}
479
 
480
void
6 7u83 481
name_entry_hide_defd(NameEntryP entry,			      GenericP   gclosure)
2 7u83 482
{
6 7u83 483
    if (name_entry_get_use(entry) & U_DEFD) {
484
	NStringP shape = (NStringP)gclosure;
2 7u83 485
 
6 7u83 486
	debug_info_l_hide(shape, name_entry_key(entry));
487
	name_entry_hide(entry);
2 7u83 488
    }
489
}
490
 
491
void
6 7u83 492
name_entry_keep(NameEntryP entry,			 GenericP   gclosure)
2 7u83 493
{
6 7u83 494
    NStringP shape = (NStringP)gclosure;
2 7u83 495
 
6 7u83 496
    debug_info_l_keep(shape, name_entry_key(entry));
497
    name_entry_unhide(entry);
2 7u83 498
}
499
 
500
void
6 7u83 501
name_entry_suppress_mult(NameEntryP entry,				  GenericP   gclosure)
2 7u83 502
{
6 7u83 503
    if ((name_entry_get_use(entry) & (U_DEFD | U_MULT)) == U_MULT) {
504
	NStringP shape = (NStringP)gclosure;
2 7u83 505
 
6 7u83 506
	debug_info_l_suppress(shape, name_entry_key(entry));
507
	name_entry_set_definition(entry, NIL(CapsuleP));
2 7u83 508
    }
509
}
510
 
511
void
6 7u83 512
name_entry_lib_suppress_mult(NameEntryP entry,				      GenericP   gclosure)
2 7u83 513
{
6 7u83 514
    if ((name_entry_get_use(entry) & (U_DEFD | U_MULT)) == U_MULT) {
515
	NStringP shape = (NStringP)gclosure;
2 7u83 516
 
6 7u83 517
	debug_info_l_suppress(shape, name_entry_key(entry));
518
	name_entry_set_lib_definition(entry, NIL(LibCapsuleP));
2 7u83 519
    }
520
}
521
 
522
void
6 7u83 523
name_entry_show_content(NameEntryP entry,				 GenericP   gclosure)
2 7u83 524
{
6 7u83 525
    LibCapsuleP capsule = name_entry_get_lib_definition(entry);
2 7u83 526
 
6 7u83 527
    UNUSED(gclosure);
528
    write_cstring(ostream_output, "  ");
529
    write_name_key(ostream_output, name_entry_key(entry));
530
    write_char(ostream_output, ' ');
531
    write_usage(ostream_output, name_entry_get_use(entry));
532
    write_cstring(ostream_output, " '");
533
    write_cstring(ostream_output, lib_capsule_name(capsule));
534
    write_char(ostream_output, '\'');
535
    write_newline(ostream_output);
2 7u83 536
}
537
 
538
/*
539
 * Local variables(smf):
540
 * eval: (include::add-path-entry "../os-interface" "../library")
541
 * eval: (include::add-path-entry "../generated")
542
 * end:
543
**/