Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/algol60/src/tools/tld/name-key.c – Rev 7

Subversion Repositories tendra.SVN

Rev

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