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
/**** error.c --- Error reporting.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 **** Commentary:
66
 *
67
 * This file implements the error reporting facility specified in the file
68
 * "error.h".  See that file for more details.
69
 *
70
 **** Change Log:
71
 * $Log: error.c,v $
72
 * Revision 1.1.1.1  1998/01/17  15:57:17  release
73
 * First version to be checked into rolling release.
74
 *
75
 * Revision 1.2  1994/12/12  11:44:41  smf
76
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
77
 * OSSG C Coding Standards.
78
 *
79
 * Revision 1.1.1.1  1994/07/25  16:05:51  smf
80
 * Initial import of library shared files.
81
 *
82
**/
83
 
84
/****************************************************************************/
85
 
86
#include "error.h"
87
#include "syntax.h"
88
 
89
/*--------------------------------------------------------------------------*/
90
 
6 7u83 91
#define TAG_TABLE_SIZE		(127)
92
#define ERROR_TABLE_SIZE	(127)
93
#define STRING_TABLE_SIZE	(127)
2 7u83 94
 
95
/*--------------------------------------------------------------------------*/
96
 
6 7u83 97
static ETagP		tag_table[TAG_TABLE_SIZE];
98
static ErrorP		error_table[ERROR_TABLE_SIZE];
99
static EStringP		string_table[STRING_TABLE_SIZE];
100
static CStringP		program_name         = NIL(CStringP);
101
static ErrorInitProcP	init_proc	     = NIL(ErrorInitProcP);
102
static ETagP		etag_program	     = NIL(ETagP);
103
static ETagP		etag_severity	     = NIL(ETagP);
104
static ETagP		etag_error_name      = NIL(ETagP);
105
static ETagP		etag_dollar	     = NIL(ETagP);
106
static ETagP		etag_ocb	     = NIL(ETagP);
107
static ETagP		etag_ccb	     = NIL(ETagP);
108
static ErrorListP	error_prefix	     = NIL(ErrorListP);
2 7u83 109
static ESeverityT	min_severity	     = ERROR_SEVERITY_ERROR;
110
static ESeverityT	max_reported	     = ERROR_SEVERITY_INFORMATION;
6 7u83 111
static EStringDataT	severity_data[]    = {
2 7u83 112
    UB {"error severity information",	"Info"} UE,
113
    UB {"error severity warning",	"Warning"} UE,
114
    UB {"error severity error",		"Error"} UE,
115
    UB {"error severity fatal",		"Fatal"} UE,
116
    UB {"error severity internal",	"Internal"} UE,
117
    ERROR_END_STRING_LIST
118
};
119
 
120
/*--------------------------------------------------------------------------*/
121
 
122
static void
6 7u83 123
error_deallocate_error_list(ErrorListP error_list)
2 7u83 124
{
125
    while (error_list) {
126
	ErrorListP tmp = error_list;
127
 
128
	if (error_list->tag == ERROR_TAG_STRING) {
6 7u83 129
	    nstring_destroy(& (error_list->u.string));
2 7u83 130
	}
131
	error_list = error_list->next;
6 7u83 132
	DEALLOCATE(tmp);
2 7u83 133
    }
134
}
135
 
136
static ErrorListP
6 7u83 137
error_parse_message(CStringP message)
2 7u83 138
{
139
    ErrorListP  error_list;
140
    ErrorListP *error_list_next = &error_list;
6 7u83 141
    CStringP    message_copy    = cstring_duplicate(message);
2 7u83 142
    CStringP    scan            = message = message_copy;
143
 
144
    while (*scan) {
6 7u83 145
	if ((*scan++ == '$') && (*scan == '{')) {
2 7u83 146
	    if (scan > (message + 1)) {
6 7u83 147
		ErrorListP tmp = ALLOCATE(ErrorListT);
2 7u83 148
 
149
		tmp->tag  = ERROR_TAG_STRING;
6 7u83 150
		scan[-1] = '\0';
151
		nstring_copy_cstring(& (tmp->u.string), message);
2 7u83 152
		*error_list_next = tmp;
6 7u83 153
		error_list_next  = & (tmp->next);
2 7u83 154
	    }
6 7u83 155
	    scan++;
2 7u83 156
	    message = scan;
157
	    while (*scan != '}') {
158
		if ((*scan == '\0') || (*scan == '$') || (*scan == '{') ||
6 7u83 159
		   ((!syntax_is_printable(*scan)) && (*scan != ' '))) {
160
		    *error_list_next = NIL(ErrorListP);
161
		    error_deallocate_error_list(error_list);
162
		    return(NIL(ErrorListP));
2 7u83 163
		}
6 7u83 164
		scan++;
2 7u83 165
	    }
6 7u83 166
	    if (scan++ > message) {
167
		ErrorListP tmp = ALLOCATE(ErrorListT);
2 7u83 168
		CStringP   tag;
169
 
170
		tmp->tag   = ERROR_TAG_TAG;
6 7u83 171
		scan[-1] = '\0';
172
		tag        = cstring_duplicate(message);
173
		tmp->u.tag = error_define_tag(tag);
2 7u83 174
		if (tmp->u.tag->name != tag) {
6 7u83 175
		    DEALLOCATE(tag);
2 7u83 176
		}
177
		*error_list_next = tmp;
6 7u83 178
		error_list_next  = & (tmp->next);
2 7u83 179
	    }
180
	    message = scan;
181
	}
182
    }
183
    if (scan > message) {
6 7u83 184
	ErrorListP tmp = ALLOCATE(ErrorListT);
2 7u83 185
 
186
	tmp->tag = ERROR_TAG_STRING;
6 7u83 187
	nstring_copy_cstring(& (tmp->u.string), message);
2 7u83 188
	*error_list_next = tmp;
6 7u83 189
	error_list_next  = & (tmp->next);
2 7u83 190
    }
6 7u83 191
    *error_list_next = NIL(ErrorListP);
192
    DEALLOCATE(message_copy);
193
    return(error_list);
2 7u83 194
}
195
 
196
static void
6 7u83 197
write_error_list(OStreamP   ostream,			  ErrorListP error_list, 
198
			  ErrorP     error, 
199
			  ErrorProcP proc, 
2 7u83 200
			  GenericP   closure)
201
{
202
    while (error_list) {
6 7u83 203
	switch (error_list->tag)EXHAUSTIVE {
2 7u83 204
	  case ERROR_TAG_STRING:
6 7u83 205
	    write_nstring(ostream, & (error_list->u.string));
2 7u83 206
	    break;
207
	  case ERROR_TAG_TAG:
208
	    if (error_list->u.tag == etag_program) {
6 7u83 209
		write_cstring(ostream, program_name);
2 7u83 210
	    } else if (error_list->u.tag == etag_severity) {
211
		EStringP estring =
6 7u83 212
		    severity_data[(error->severity)].estring;
2 7u83 213
 
6 7u83 214
		write_cstring(ostream, error_string_contents(estring));
2 7u83 215
	    } else if (error_list->u.tag == etag_error_name) {
6 7u83 216
		write_cstring(ostream, error->name);
2 7u83 217
	    } else if (error_list->u.tag == etag_dollar) {
6 7u83 218
		write_char(ostream, '$');
2 7u83 219
	    } else if (error_list->u.tag == etag_ocb) {
6 7u83 220
		write_char(ostream, '{');
2 7u83 221
	    } else if (error_list->u.tag == etag_ccb) {
6 7u83 222
		write_char(ostream, '}');
2 7u83 223
	    } else if (proc) {
6 7u83 224
		((*proc)(ostream, error_list->u.tag, closure));
2 7u83 225
	    }
226
	    break;
227
	}
228
	error_list = error_list->next;
229
    }
230
}
231
 
232
static void
6 7u83 233
write_error_list_text(OStreamP   ostream,			       ErrorListP error_list)
2 7u83 234
{
235
    NStringP nstring;
236
    CStringP contents;
237
    unsigned length;
238
 
6 7u83 239
    write_char(ostream, '"');
2 7u83 240
    while (error_list) {
6 7u83 241
	switch (error_list->tag)EXHAUSTIVE {
2 7u83 242
	  case ERROR_TAG_STRING:
6 7u83 243
	    nstring  = & (error_list->u.string);
244
	    contents = nstring_contents(nstring);
245
	    length   = nstring_length(nstring);
2 7u83 246
 
6 7u83 247
	    while (length--) {
2 7u83 248
		switch (*contents) {
249
		  case '\n':
6 7u83 250
		    write_cstring(ostream, "\\n\\");
251
		    write_newline(ostream);
2 7u83 252
		    break;
253
		  case '"':
6 7u83 254
		    write_cstring(ostream, "\\\"");
2 7u83 255
		    break;
256
		  default:
6 7u83 257
		    ASSERT(*contents != '\0');
258
		    write_char(ostream, *contents);
2 7u83 259
		    break;
260
		}
6 7u83 261
		contents++;
2 7u83 262
	    }
263
	    break;
264
	  case ERROR_TAG_TAG:
6 7u83 265
	    write_cstring(ostream, "${");
266
	    write_cstring(ostream, error_list->u.tag->name);
267
	    write_char(ostream, '}');
2 7u83 268
	    break;
269
	}
270
	error_list = error_list->next;
271
    }
6 7u83 272
    write_char(ostream, '"');
2 7u83 273
}
274
 
275
static void
6 7u83 276
write_error_table(OStreamP ostream)
2 7u83 277
{
278
    unsigned i;
279
 
6 7u83 280
    for (i = 0; i < ERROR_TABLE_SIZE; i++) {
281
	ErrorP error = error_table[i];
2 7u83 282
 
283
	while (error) {
6 7u83 284
	    write_char(ostream, '\'');
285
	    write_cstring(ostream, error->name);
286
	    write_char(ostream, '\'');
287
	    write_newline(ostream);
288
	    write_cstring(ostream, "    ");
289
	    write_error_list_text(ostream, error->error_list);
290
	    write_newline(ostream);
2 7u83 291
	    error = error->next;
292
	}
293
    }
294
}
295
 
296
static void
6 7u83 297
write_string_table(OStreamP ostream)
2 7u83 298
{
299
    unsigned i;
300
 
6 7u83 301
    for (i = 0; i < STRING_TABLE_SIZE; i++) {
302
	EStringP string = string_table[i];
2 7u83 303
 
304
	while (string) {
305
	    CStringP contents = string->contents;
306
 
6 7u83 307
	    write_char(ostream, '\'');
308
	    write_cstring(ostream, string->name);
309
	    write_char(ostream, '\'');
310
	    write_newline(ostream);
311
	    write_cstring(ostream, "    ");
312
	    write_char(ostream, '"');
2 7u83 313
	    while (*contents) {
314
		switch (*contents) {
315
		  case '\n':
6 7u83 316
		    write_cstring(ostream, "\\n\\");
317
		    write_newline(ostream);
2 7u83 318
		    break;
319
		  case '"':
6 7u83 320
		    write_cstring(ostream, "\\\"");
2 7u83 321
		    break;
322
		  default:
6 7u83 323
		    write_char(ostream, *contents);
2 7u83 324
		    break;
325
		}
6 7u83 326
		contents++;
2 7u83 327
	    }
6 7u83 328
	    write_char(ostream, '"');
329
	    write_newline(ostream);
2 7u83 330
	    string = string->next;
331
	}
332
    }
333
}
334
 
335
/*--------------------------------------------------------------------------*/
336
 
337
void
6 7u83 338
error_init(CStringP       name,		    ErrorInitProcP proc)
2 7u83 339
{
340
    static CStringP prefix = "${program name}: ${severity}: ";
341
 
342
    program_name = name;
343
    while (*name) {
6 7u83 344
	if (*name++ == '/') {
2 7u83 345
	    program_name = name;
346
	}
347
    }
348
    init_proc       = proc;
6 7u83 349
    etag_program    = error_define_tag("program name");
350
    etag_severity   = error_define_tag("severity");
351
    etag_error_name = error_define_tag("this error name");
352
    etag_dollar     = error_define_tag("dollar");
353
    etag_ocb        = error_define_tag("open brace");
354
    etag_ccb        = error_define_tag("close brace");
355
    error_prefix    = error_parse_message(prefix);
356
    error_intern_strings(severity_data);
357
    ostream_buffer(ostream_error);
2 7u83 358
}
359
 
360
void
6 7u83 361
error_call_init_proc(void)
2 7u83 362
{
363
    if (init_proc) {
6 7u83 364
	(*init_proc)();
365
	init_proc = NIL(ErrorInitProcP);
2 7u83 366
    }
367
}
368
 
369
ETagP
6 7u83 370
error_define_tag(CStringP name)
2 7u83 371
{
6 7u83 372
    unsigned hash   = (cstring_hash_value(name)% TAG_TABLE_SIZE);
373
    ETagP   *entryp = & (tag_table[hash]);
2 7u83 374
    ETagP    entry;
375
 
6 7u83 376
    while ((entry = *entryp) != NIL(ETagP)) {
377
	if (cstring_equal(entry->name, name)) {
378
	    return(entry);
2 7u83 379
	}
6 7u83 380
	entryp = & (entry->next);
2 7u83 381
    }
6 7u83 382
    entry       = ALLOCATE(ETagT);
383
    entry->next = NIL(ETagP);
2 7u83 384
    entry->name = name;
385
    *entryp     = entry;
6 7u83 386
    return(entry);
2 7u83 387
}
388
 
389
ErrorP
6 7u83 390
error_define_error(CStringP   name,			    ESeverityT severity, 
391
			    CStringP   message, 
2 7u83 392
			    GenericP   data)
393
{
6 7u83 394
    ErrorListP error_list = error_parse_message(message);
395
    unsigned   hash       = (cstring_hash_value(name)% ERROR_TABLE_SIZE);
396
    ErrorP    *entryp     = & (error_table[hash]);
2 7u83 397
    ErrorP     entry;
398
 
6 7u83 399
    while ((entry = *entryp) != NIL(ErrorP)) {
400
	ASSERT(!cstring_equal(entry->name, name));
401
	entryp = & (entry->next);
2 7u83 402
    }
6 7u83 403
    ASSERT(error_list);
404
    entry             = ALLOCATE(ErrorT);
405
    entry->next       = NIL(ErrorP);
2 7u83 406
    entry->name       = name;
407
    entry->severity   = severity;
408
    entry->error_list = error_list;
409
    entry->data       = data;
410
    *entryp           = entry;
6 7u83 411
    return(entry);
2 7u83 412
}
413
 
414
void
6 7u83 415
error_intern_tags(ETagDataP vector)
2 7u83 416
{
417
    while (vector->name) {
6 7u83 418
	ETagP tag = error_define_tag(vector->name);
2 7u83 419
 
420
	vector->tag = tag;
6 7u83 421
	vector++;
2 7u83 422
    }
423
}
424
 
425
void
6 7u83 426
error_intern_errors(ErrorDataP vector)
2 7u83 427
{
428
    while (vector->s.name) {
6 7u83 429
	ErrorP error = error_define_error(vector->s.name, vector->s.severity,
2 7u83 430
					   vector->s.message, vector->s.data);
431
 
432
	vector->error = error;
6 7u83 433
	vector++;
2 7u83 434
    }
435
}
436
 
437
ErrorStatusT
6 7u83 438
error_redefine_error(CStringP name,			      CStringP message)
2 7u83 439
{
6 7u83 440
    error_call_init_proc();
2 7u83 441
    {
6 7u83 442
	unsigned hash  = (cstring_hash_value(name)% ERROR_TABLE_SIZE);
443
	ErrorP   entry = (error_table[hash]);
2 7u83 444
 
445
	while (entry) {
6 7u83 446
	    if (cstring_equal(entry->name, name)) {
447
		ErrorListP error_list = error_parse_message(message);
2 7u83 448
 
6 7u83 449
		if (error_list == NIL(ErrorListP)) {
450
		    return(ERROR_STATUS_BAD_MESSAGE);
2 7u83 451
		}
6 7u83 452
		error_deallocate_error_list(entry->error_list);
2 7u83 453
		entry->error_list = error_list;
6 7u83 454
		return(ERROR_STATUS_SUCCESS);
2 7u83 455
	    }
456
	    entry = entry->next;
457
	}
6 7u83 458
	return(ERROR_STATUS_BAD_ERROR);
2 7u83 459
    }
460
}
461
 
462
ErrorP
6 7u83 463
error_lookup_error(CStringP name)
2 7u83 464
{
6 7u83 465
    error_call_init_proc();
2 7u83 466
    {
6 7u83 467
	unsigned hash  = (cstring_hash_value(name)% ERROR_TABLE_SIZE);
468
	ErrorP   entry = (error_table[hash]);
2 7u83 469
 
470
	while (entry) {
6 7u83 471
	    if (cstring_equal(entry->name, name)) {
472
		return(entry);
2 7u83 473
	    }
474
	    entry = entry->next;
475
	}
6 7u83 476
	return(NIL(ErrorP));
2 7u83 477
    }
478
}
479
 
480
GenericP
6 7u83 481
error_data(ErrorP error)
2 7u83 482
{
6 7u83 483
    return(error->data);
2 7u83 484
}
485
 
486
void
6 7u83 487
error_report(ErrorP     error,		      ErrorProcP proc, 
2 7u83 488
		      GenericP   closure)
489
{
490
    if ((error->severity) >= min_severity) {
6 7u83 491
	write_error_list(ostream_error, error_prefix, error, NIL(ErrorProcP),
492
			  NIL(GenericP));
493
	write_error_list(ostream_error, error->error_list, error, proc,
2 7u83 494
			  closure);
6 7u83 495
	write_newline(ostream_error);
496
	ostream_flush(ostream_error);
2 7u83 497
    }
498
    if ((error->severity) > max_reported) {
499
	max_reported = error->severity;
500
    }
501
    if ((error->severity) >= ERROR_SEVERITY_FATAL) {
502
	if (error->severity == ERROR_SEVERITY_INTERNAL) {
6 7u83 503
	    abort();
2 7u83 504
	    UNREACHED;
505
	}
6 7u83 506
	exit(EXIT_FAILURE);
2 7u83 507
	UNREACHED;
508
    }
509
}
510
 
511
void
6 7u83 512
error_set_min_report_severity(ESeverityT severity)
2 7u83 513
{
514
    min_severity = severity;
515
}
516
 
517
ESeverityT
6 7u83 518
error_get_min_report_severity(void)
2 7u83 519
{
6 7u83 520
    return(min_severity);
2 7u83 521
}
522
 
523
ESeverityT
6 7u83 524
error_max_reported_severity(void)
2 7u83 525
{
6 7u83 526
    return(max_reported);
2 7u83 527
}
528
 
529
void
6 7u83 530
error_set_severity_message(ESeverityT severity,				    CStringP   message)
2 7u83 531
{
6 7u83 532
    severity_data[severity].estring->contents = message;
2 7u83 533
}
534
 
535
BoolT
6 7u83 536
error_set_prefix_message(CStringP message)
2 7u83 537
{
6 7u83 538
    ErrorListP error_list = error_parse_message(message);
2 7u83 539
 
6 7u83 540
    if (error_list == NIL(ErrorListP)) {
541
	return(FALSE);
2 7u83 542
    }
6 7u83 543
    error_deallocate_error_list(error_prefix);
2 7u83 544
    error_prefix = error_list;
6 7u83 545
    return(TRUE);
2 7u83 546
}
547
 
548
EStringP
6 7u83 549
error_define_string(CStringP name,			     CStringP contents)
2 7u83 550
{
6 7u83 551
    unsigned  hash   = (cstring_hash_value(name)% STRING_TABLE_SIZE);
552
    EStringP *entryp = & (string_table[hash]);
2 7u83 553
    EStringP  entry;
554
 
6 7u83 555
    while ((entry = *entryp) != NIL(EStringP)) {
556
	ASSERT(!cstring_equal(entry->name, name));
557
	entryp = & (entry->next);
2 7u83 558
    }
6 7u83 559
    entry           = ALLOCATE(EStringT);
560
    entry->next     = NIL(EStringP);
2 7u83 561
    entry->name     = name;
562
    entry->contents = contents;
563
    *entryp         = entry;
6 7u83 564
    return(entry);
2 7u83 565
}
566
 
567
void
6 7u83 568
error_intern_strings(EStringDataP vector)
2 7u83 569
{
570
    while (vector->s.name) {
6 7u83 571
	EStringP estring = error_define_string(vector->s.name,
2 7u83 572
						vector->s.contents);
573
 
574
	vector->estring = estring;
6 7u83 575
	vector++;
2 7u83 576
    }
577
}
578
 
579
BoolT
6 7u83 580
error_redefine_string(CStringP name,			       CStringP contents)
2 7u83 581
{
6 7u83 582
    unsigned hash  = (cstring_hash_value(name)% STRING_TABLE_SIZE);
583
    EStringP entry = (string_table[hash]);
2 7u83 584
 
585
    while (entry) {
6 7u83 586
	if (cstring_equal(entry->name, name)) {
2 7u83 587
	    entry->contents = contents;
6 7u83 588
	    return(TRUE);
2 7u83 589
	}
590
	entry = entry->next;
591
    }
6 7u83 592
    return(FALSE);
2 7u83 593
}
594
 
595
EStringP
6 7u83 596
error_lookup_string(CStringP name)
2 7u83 597
{
6 7u83 598
    unsigned hash  = (cstring_hash_value(name)% STRING_TABLE_SIZE);
599
    EStringP entry = (string_table[hash]);
2 7u83 600
 
601
    while (entry) {
6 7u83 602
	if (cstring_equal(entry->name, name)) {
603
	    return(entry);
2 7u83 604
	}
605
	entry = entry->next;
606
    }
6 7u83 607
    return(NIL(EStringP));
2 7u83 608
}
609
 
610
CStringP
6 7u83 611
error_string_contents(EStringP estring)
2 7u83 612
{
6 7u83 613
    return(estring->contents);
2 7u83 614
}
615
 
616
void
6 7u83 617
write_error_file(OStreamP ostream)
2 7u83 618
{
6 7u83 619
    error_call_init_proc();
620
    write_cstring(ostream, "%prefix%");
621
    write_newline(ostream);
622
    write_cstring(ostream, "    ");
623
    write_error_list_text(ostream, error_prefix);
624
    write_newline(ostream);
625
    write_newline(ostream);
626
    write_cstring(ostream, "%errors%");
627
    write_newline(ostream);
628
    write_error_table(ostream);
629
    write_newline(ostream);
630
    write_cstring(ostream, "%strings%");
631
    write_newline(ostream);
632
    write_string_table(ostream);
2 7u83 633
}
634
 
635
/*
636
 * Local variables(smf):
637
 * eval: (include::add-path-entry "../os-interface" "../generated")
638
 * end:
639
**/