Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/*** name-key.c --- External name key ADT.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 *** Commentary:
36
 *
37
 * This file implements the external name key routines used by the TDF linker.
38
 *
39
 *** Change Log:
40
 * $Log: name-key.c,v $
41
 * Revision 1.1.1.1  1998/01/17  15:57:19  release
42
 * First version to be checked into rolling release.
43
 *
44
 * Revision 1.3  1995/09/22  08:39:28  smf
45
 * Fixed problems with incomplete structures (to shut "tcc" up).
46
 * Fixed some problems in "name-key.c" (no real problems, but rewritten to
47
 * reduce the warnings that were output by "tcc" and "gcc").
48
 * Fixed bug CR95_354.tld-common-id-problem (library capsules could be loaded
49
 * more than once).
50
 *
51
 * Revision 1.2  1994/12/12  11:46:38  smf
52
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
53
 * OSSG C Coding Standards.
54
 *
55
 * Revision 1.1.1.1  1994/07/25  16:03:35  smf
56
 * Initial import of TDF linker 3.5 non shared files.
57
 *
58
**/
59
 
60
/****************************************************************************/
61
 
62
#include "name-key.h"
63
#include "syntax.h"
64
 
65
#include "solve-cycles.h"
66
 
67
/*--------------------------------------------------------------------------*/
68
 
69
static BoolT
70
name_key_parse_hex_char PROTO_N ((name, c_ref))
71
			PROTO_T (CStringP name X
72
				 char    *c_ref)
73
{
74
    char result;
75
    char c;
76
    int  value;
77
 
78
    if ((c = name [0]), ((value = syntax_value (c)) != SYNTAX_NO_VALUE)) {
79
	result = (char) ((unsigned) value << 4);
80
    } else {
81
	return (FALSE);
82
    }
83
    if ((c = name [1]), ((value = syntax_value (c)) != SYNTAX_NO_VALUE)) {
84
	result |= (char) value;
85
    } else {
86
	return (FALSE);
87
    }
88
    *c_ref = result;
89
    return (TRUE);
90
}
91
 
92
static BoolT
93
name_key_parse_escaped PROTO_N ((name_ref, c_ref))
94
		       PROTO_T (CStringP *name_ref X
95
				char     *c_ref)
96
{
97
    CStringP name = (*name_ref);
98
 
99
    switch ((*++ name)) {
100
      case 'x': case 'X':
101
	if (!name_key_parse_hex_char (name, c_ref)) {
102
	    return (FALSE);
103
	}
104
	name += 3;
105
	break;
106
      case 'n': case 'N':
107
	*c_ref = '\n';
108
	name ++;
109
	break;
110
      case 'r': case 'R':
111
	*c_ref = '\r';
112
	name ++;
113
	break;
114
      case 't': case 'T':
115
	*c_ref= '\t';
116
	name ++;
117
	break;
118
      case '0':
119
	*c_ref = '\0';
120
	name ++;
121
	break;
122
      case '\\': case '.': case '[': case ']':
123
	*c_ref = *name ++;
124
	break;
125
      default:
126
	return (FALSE);
127
    }
128
    *name_ref = name;
129
    return (TRUE);
130
}
131
 
132
static BoolT
133
name_key_parse_cstring_unique PROTO_N ((key, name))
134
			      PROTO_T (NameKeyP key X
135
				       CStringP name)
136
{
137
    unsigned length   = 1;
138
    CStringP tmp_name = name;
139
    NStringP components;
140
    unsigned i;
141
 
142
    while (*++ tmp_name) {
143
	if (*tmp_name == '.') {
144
	    length ++;
145
	}
146
    }
147
    components = ALLOCATE_VECTOR (NStringT, length);
148
    length     = 0;
149
    for (;;) {
150
	DStringT dstring;
151
 
152
	name ++;
153
	dstring_init (&dstring);
154
	while ((*name != '.') && (*name != ']')) {
155
	    if ((*name == '\0') || (*name == '[')) {
156
		dstring_destroy (&dstring);
157
		goto fail;
158
	    } else if (*name == '\\') {
159
		char c;
160
 
161
		if (name_key_parse_escaped (&name, &c)) {
162
		    dstring_append_char (&dstring, c);
163
		} else {
164
		    dstring_destroy (&dstring);
165
		    goto fail;
166
		}
167
	    } else {
168
		dstring_append_char (&dstring, *name ++);
169
	    }
170
	}
171
	dstring_to_nstring (&dstring, &(components [length ++]));
172
	if (*name == ']') {
173
	    break;
174
	}
175
    }
176
    if (*name) {
177
      fail:
178
	for (i = 0; i < length ; i ++) {
179
	    nstring_destroy (&(components [i]));
180
	}
181
	DEALLOCATE (components);
182
	return (FALSE);
183
    }
184
    name_key_init_unique (key, length);
185
    for (i = 0; i < length; i ++) {
186
	name_key_set_component (key, i, &(components [i]));
187
    }
188
    DEALLOCATE (components);
189
    return (TRUE);
190
}
191
 
192
static BoolT
193
name_key_parse_cstring_string PROTO_N ((key, name))
194
			      PROTO_T (NameKeyP key X
195
				       CStringP name)
196
{
197
    DStringT dstring;
198
    NStringT nstring;
199
 
200
    dstring_init (&dstring);
201
    while (*name) {
202
	if ((*name == '[') || (*name == ']') || (*name == '.')) {
203
	    dstring_destroy (&dstring);
204
	    return (FALSE);
205
	} else if (*name == '\\') {
206
	    char c;
207
 
208
	    if (name_key_parse_escaped (&name, &c)) {
209
		dstring_append_char (&dstring, c);
210
	    } else {
211
		dstring_destroy (&dstring);
212
		return (FALSE);
213
	    }
214
	} else {
215
	    dstring_append_char (&dstring, *name ++);
216
	}
217
    }
218
    dstring_to_nstring (&dstring, &nstring);
219
    name_key_init_string (key, &nstring);
220
    return (TRUE);
221
}
222
 
223
static void
224
write_name_key_1 PROTO_N ((ostream, nstring))
225
		 PROTO_T (OStreamP ostream X
226
			  NStringP nstring)
227
{
228
    unsigned length = nstring_length (nstring);
229
    CStringP bytes  = nstring_contents (nstring);
230
 
231
    while (length --) {
232
	switch (*bytes) {
233
	  case '[': case ']': case '.': case '\\':
234
	    write_char (ostream, '\\');
235
	    FALL_THROUGH;
236
	  default:
237
	    write_char (ostream, *bytes);
238
	}
239
	bytes ++;
240
    }
241
}
242
 
243
/*--------------------------------------------------------------------------*/
244
 
245
void
246
name_key_init_string PROTO_N ((key, string))
247
		     PROTO_T (NameKeyP key X
248
			      NStringP string)
249
{
250
    key->type = KT_STRING;
251
    nstring_assign (&(key->u.string), string);
252
}
253
 
254
void
255
name_key_init_unique PROTO_N ((key, components))
256
		     PROTO_T (NameKeyP key X
257
			      unsigned components)
258
{
259
    key->type                = KT_UNIQUE;
260
    key->u.unique.length     = components;
261
    key->u.unique.components = ALLOCATE_VECTOR (NStringT, components);
262
}
263
 
264
BoolT
265
name_key_parse_cstring PROTO_N ((key, name))
266
		       PROTO_T (NameKeyP key X
267
				CStringP name)
268
{
269
    if (*name == '[') {
270
	return (name_key_parse_cstring_unique (key, name));
271
    } else {
272
	return (name_key_parse_cstring_string (key, name));
273
    }
274
}
275
 
276
void
277
name_key_set_component PROTO_N ((key, component, string))
278
		       PROTO_T (NameKeyP key X
279
				unsigned component X
280
				NStringP string)
281
{
282
    ASSERT ((key->type == KT_UNIQUE) && (component < key->u.unique.length));
283
    nstring_assign (&(key->u.unique.components [component]), string);
284
}
285
 
286
NameKeyTypeT
287
name_key_type PROTO_N ((key))
288
	      PROTO_T (NameKeyP key)
289
{
290
    return (key->type);
291
}
292
 
293
NStringP
294
name_key_string PROTO_N ((key))
295
		PROTO_T (NameKeyP key)
296
{
297
    ASSERT (key->type == KT_STRING);
298
    return (&(key->u.string));
299
}
300
 
301
unsigned
302
name_key_components PROTO_N ((key))
303
		    PROTO_T (NameKeyP key)
304
{
305
    ASSERT (key->type == KT_UNIQUE);
306
    return (key->u.unique.length);
307
}
308
 
309
NStringP
310
name_key_get_component PROTO_N ((key, component))
311
		       PROTO_T (NameKeyP key X
312
				unsigned component)
313
{
314
    ASSERT ((key->type == KT_UNIQUE) && (component < key->u.unique.length));
315
    return (&(key->u.unique.components [component]));
316
}
317
 
318
unsigned
319
name_key_hash_value PROTO_N ((key))
320
		    PROTO_T (NameKeyP key)
321
{
322
#ifdef __TenDRA__
323
    unsigned hash_value; /* "tcc" complains if this is initialised */
324
#else
325
    unsigned hash_value = 0; /* "gcc" complains if this is not initialised */
326
#endif /* defined (__TenDRA__) */
327
    unsigned components;
328
    unsigned i;
329
 
330
    switch (key->type) EXHAUSTIVE {
331
      case KT_STRING:
332
	hash_value = nstring_hash_value (&(key->u.string));
333
	break;
334
      case KT_UNIQUE:
335
	components = key->u.unique.length;
336
	hash_value = components;
337
	for (i = 0; i < components; i ++) {
338
	    hash_value += nstring_hash_value (&(key->u.unique.components [i]));
339
	}
340
	break;
341
    }
342
    return (hash_value);
343
}
344
 
345
BoolT
346
name_key_equal PROTO_N ((key1, key2))
347
	       PROTO_T (NameKeyP key1 X
348
			NameKeyP key2)
349
{
350
    unsigned components;
351
    unsigned i;
352
 
353
    if (key1->type != key2->type) {
354
	return (FALSE);
355
    }
356
    switch (key1->type) EXHAUSTIVE {
357
      case KT_STRING:
358
	return (nstring_equal (&(key1->u.string), &(key2->u.string)));
359
      case KT_UNIQUE:
360
	if ((components = key1->u.unique.length) != key2->u.unique.length) {
361
	    return (FALSE);
362
	}
363
	for (i = 0; i < components; i ++) {
364
	    if (!nstring_equal (&(key1->u.unique.components [i]),
365
				&(key2->u.unique.components [i]))) {
366
		return (FALSE);
367
	    }
368
	}
369
	break;
370
    }
371
    return (TRUE);
372
}
373
 
374
void
375
name_key_assign PROTO_N ((to, from))
376
		PROTO_T (NameKeyP to X
377
			 NameKeyP from)
378
{
379
    switch (to->type = from->type) EXHAUSTIVE {
380
      case KT_STRING:
381
	nstring_assign (&(to->u.string), &(from->u.string));
382
	break;
383
      case KT_UNIQUE:
384
	to->u.unique.length     = from->u.unique.length;
385
	to->u.unique.components = from->u.unique.components;
386
	break;
387
    }
388
}
389
 
390
void
391
name_key_copy PROTO_N ((to, from))
392
	      PROTO_T (NameKeyP to X
393
		       NameKeyP from)
394
{
395
    unsigned components;
396
    unsigned i;
397
 
398
    switch (to->type = from->type) EXHAUSTIVE {
399
      case KT_STRING:
400
	nstring_copy (&(to->u.string), &(from->u.string));
401
	break;
402
      case KT_UNIQUE:
403
	components = to->u.unique.length = from->u.unique.length;
404
	to->u.unique.components = ALLOCATE_VECTOR (NStringT, components);
405
	for (i = 0; i < components; i ++) {
406
	    nstring_copy (&(to->u.unique.components [i]),
407
			  &(from->u.unique.components [i]));
408
	}
409
	break;
410
    }
411
}
412
 
413
void
414
name_key_destroy PROTO_N ((key))
415
		 PROTO_T (NameKeyP key)
416
{
417
    unsigned components;
418
    unsigned i;
419
 
420
    switch (key->type) EXHAUSTIVE {
421
      case KT_STRING:
422
	nstring_destroy (&(key->u.string));
423
	break;
424
      case KT_UNIQUE:
425
	components = key->u.unique.length;
426
	for (i = 0; i < components; i ++) {
427
	    nstring_destroy (&(key->u.unique.components [i]));
428
	}
429
	DEALLOCATE (key->u.unique.components);
430
	break;
431
    }
432
}
433
 
434
void
435
write_name_key PROTO_N ((ostream, key))
436
	       PROTO_T (OStreamP ostream X
437
			NameKeyP key)
438
{
439
    char     sep = '[';
440
    unsigned components;
441
    unsigned i;
442
 
443
    switch (key->type) EXHAUSTIVE {
444
      case KT_STRING:
445
	write_name_key_1 (ostream, &(key->u.string));
446
	break;
447
      case KT_UNIQUE:
448
	components = key->u.unique.length;
449
	for (i = 0; i < components; i ++) {
450
	    NStringP nstring = &(key->u.unique.components [i]);
451
 
452
	    write_char (ostream, sep);
453
	    write_name_key_1 (ostream, nstring);
454
	    sep = '.';
455
	}
456
	write_char (ostream, ']');
457
	break;
458
    }
459
}
460
 
461
/*--------------------------------------------------------------------------*/
462
 
463
void
464
name_key_list_init PROTO_N ((list))
465
		   PROTO_T (NameKeyListP list)
466
{
467
    list->head = NIL (NameKeyListEntryP);
468
}
469
 
470
void
471
name_key_list_add PROTO_N ((list, key))
472
		  PROTO_T (NameKeyListP list X
473
			   NameKeyP     key)
474
{
475
    NameKeyListEntryP entry;
476
 
477
    for (entry = name_key_list_head (list); entry;
478
	 entry = name_key_list_entry_next (entry)) {
479
	if (name_key_equal (key, &(entry->key))) {
480
	    name_key_destroy (key);
481
	    return;
482
	}
483
    }
484
    entry       = ALLOCATE (NameKeyListEntryT);
485
    entry->next = list->head;
486
    name_key_assign (&(entry->key), key);
487
    list->head  = entry;
488
}
489
 
490
NameKeyListEntryP
491
name_key_list_head PROTO_N ((list))
492
		   PROTO_T (NameKeyListP list)
493
{
494
    return (list->head);
495
}
496
 
497
NameKeyP
498
name_key_list_entry_key PROTO_N ((entry))
499
			PROTO_T (NameKeyListEntryP entry)
500
{
501
    return (&(entry->key));
502
}
503
 
504
NameKeyListEntryP
505
name_key_list_entry_next PROTO_N ((entry))
506
			 PROTO_T (NameKeyListEntryP entry)
507
{
508
    return (entry->next);
509
}
510
 
511
/*--------------------------------------------------------------------------*/
512
 
513
void
514
name_key_pair_list_init PROTO_N ((list))
515
			PROTO_T (NameKeyPairListP list)
516
{
517
    list->head = NIL (NameKeyPairListEntryP);
518
}
519
 
520
BoolT
521
name_key_pair_list_add PROTO_N ((list, from, to))
522
		       PROTO_T (NameKeyPairListP list X
523
				NameKeyP         from X
524
				NameKeyP         to)
525
{
526
    NameKeyPairListEntryP entry;
527
 
528
    for (entry = name_key_pair_list_head (list); entry;
529
	 entry = name_key_pair_list_entry_next (entry)) {
530
	if (name_key_equal (from, &(entry->from))) {
531
	    return (FALSE);
532
	}
533
    }
534
    entry       = ALLOCATE (NameKeyPairListEntryT);
535
    entry->next = list->head;
536
    name_key_assign (&(entry->from), from);
537
    name_key_assign (&(entry->to), to);
538
    list->head  = entry;
539
    return (TRUE);
540
}
541
 
542
NameKeyPairListEntryP
543
name_key_pair_list_head PROTO_N ((list))
544
			PROTO_T (NameKeyPairListP list)
545
{
546
    return (list->head);
547
}
548
 
549
NameKeyP
550
name_key_pair_list_entry_from PROTO_N ((entry))
551
			      PROTO_T (NameKeyPairListEntryP entry)
552
{
553
    return (&(entry->from));
554
}
555
 
556
NameKeyP
557
name_key_pair_list_entry_to PROTO_N ((entry))
558
			    PROTO_T (NameKeyPairListEntryP entry)
559
{
560
    return (&(entry->to));
561
}
562
 
563
NameKeyPairListEntryP
564
name_key_pair_list_entry_next PROTO_N ((entry))
565
			      PROTO_T (NameKeyPairListEntryP entry)
566
{
567
    return (entry->next);
568
}
569
 
570
/*
571
 * Local variables(smf):
572
 * eval: (include::add-path-entry "../os-interface" "../library")
573
 * eval: (include::add-path-entry "../generated")
574
 * end:
575
**/