Subversion Repositories tendra.SVN

Rev

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

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