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-file.c --- Error file parsing routines.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 **** Commentary:
66
 *
67
 * This file implements the error file parsing facility specified in the file
68
 * "error-file.h".  See that file for more details.
69
 *
70
 **** Change Log:
71
 * $Log: error-file.c,v $
72
 * Revision 1.1.1.1  1998/01/17  15:57:45  release
73
 * First version to be checked into rolling release.
74
 *
75
 * Revision 1.3  1994/12/12  11:44:37  smf
76
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
77
 * OSSG C Coding Standards.
78
 *
79
 * Revision 1.2  1994/08/22  09:36:44  smf
80
 * Fixed bug DR114:ids-too-long.
81
 *
82
 * Revision 1.1.1.1  1994/07/25  16:05:49  smf
83
 * Initial import of library shared files.
84
 *
85
**/
86
 
87
/****************************************************************************/
88
 
89
#include "error-file.h"
90
#include "dstring.h"
91
#include "error.h"
92
#include "gen-errors.h"
93
#include "syntax.h"
94
 
95
/*--------------------------------------------------------------------------*/
96
 
97
#ifdef FS_NO_ENUM
98
typedef int ErrorFileTagT, *ErrorFileTagP;
99
#define EFTOKEN_NAME		(0)
100
#define EFTOKEN_STRING		(1)
101
#define EFTOKEN_BLT_STRINGS	(2)
102
#define EFTOKEN_BLT_PREFIX	(3)
103
#define EFTOKEN_BLT_ERRORS	(4)
104
#define EFTOKEN_EOF		(5)
105
#else
106
typedef enum {
107
    EFTOKEN_NAME,
108
    EFTOKEN_STRING,
109
    EFTOKEN_BLT_STRINGS,
110
    EFTOKEN_BLT_PREFIX,
111
    EFTOKEN_BLT_ERRORS,
112
    EFTOKEN_EOF
113
} ErrorFileTagT, *ErrorFileTagP;
114
#endif /* defined (FS_NO_ENUM) */
115
 
116
typedef struct ErrorFileLexT {
117
    ErrorFileTagT		tag;
118
    union {
119
	CStringP		string;
120
    } u;
121
} ErrorFileLexT, *ErrorFileLexP;
122
 
123
#ifdef FS_NO_ENUM
124
typedef int ErrorFileTokenT, *ErrorFileTokenP;
125
#define EFN_BUILTIN	(0)
126
#define EFN_NAME	(1)
127
#define EFN_STRING	(2)
128
#else
129
typedef enum {
130
    EFN_BUILTIN,
131
    EFN_NAME,
132
    EFN_STRING
133
} ErrorFileTokenT, *ErrorFileTokenP;
134
#endif /* defined (FS_NO_ENUM) */
135
 
136
/*--------------------------------------------------------------------------*/
137
 
138
static BoolT
7 7u83 139
error_file_skip_white_space(IStreamP istream, char *c_ref)
2 7u83 140
{
141
    BoolT comment = FALSE;
142
 
143
    for (;;) {
144
	char c;
145
 
146
      redo:
7 7u83 147
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 148
	  case '\0':
7 7u83 149
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
2 7u83 150
	    break;
151
	  case '\n':
7 7u83 152
	    istream_inc_line(istream);
2 7u83 153
	    comment = FALSE;
154
	    break;
155
	  case '#':
156
	    comment = TRUE;
157
	    break;
158
	  default:
7 7u83 159
	    if ((!comment) && (!syntax_is_white_space(c))) {
2 7u83 160
		*c_ref = c;
7 7u83 161
		return(TRUE);
2 7u83 162
	    }
163
	}
164
    }
165
  eof:
7 7u83 166
    return(FALSE);
2 7u83 167
}
168
 
169
static void
7 7u83 170
error_file_null_character(IStreamP istream, ErrorFileTokenT type)
2 7u83 171
{
7 7u83 172
    switch (type)EXHAUSTIVE {
2 7u83 173
      case EFN_NAME:
7 7u83 174
	E_errf_null_character_in_name(istream);
2 7u83 175
	UNREACHED;
176
      case EFN_BUILTIN:
7 7u83 177
	E_errf_null_char_in_builtin(istream);
2 7u83 178
	UNREACHED;
179
      case EFN_STRING:
7 7u83 180
	E_errf_null_character_in_string(istream);
2 7u83 181
	UNREACHED;
182
    }
183
}
184
 
185
static void
7 7u83 186
error_file_newline(IStreamP istream, ErrorFileTokenT type)
2 7u83 187
{
7 7u83 188
    switch (type)EXHAUSTIVE {
2 7u83 189
      case EFN_NAME:
7 7u83 190
	E_errf_newline_in_name(istream);
2 7u83 191
	UNREACHED;
192
      case EFN_BUILTIN:
7 7u83 193
	E_errf_newline_in_builtin(istream);
2 7u83 194
	UNREACHED;
195
      case EFN_STRING:
7 7u83 196
	E_errf_newline_in_string(istream);
2 7u83 197
	UNREACHED;
198
    }
199
}
200
 
201
static void
7 7u83 202
error_file_illegal_escape(IStreamP istream, ErrorFileTokenT type)
2 7u83 203
{
7 7u83 204
    switch (type)EXHAUSTIVE {
2 7u83 205
      case EFN_NAME:
7 7u83 206
	E_errf_illegal_escape_in_name(istream);
2 7u83 207
	UNREACHED;
208
      case EFN_BUILTIN:
7 7u83 209
	E_errf_illegal_esc_in_builtin(istream);
2 7u83 210
	UNREACHED;
211
      case EFN_STRING:
7 7u83 212
	E_errf_illegal_escape_in_string(istream);
2 7u83 213
	UNREACHED;
214
    }
215
}
216
 
217
static void
7 7u83 218
error_file_eof(IStreamP istream, ErrorFileTokenT type)
2 7u83 219
{
7 7u83 220
    switch (type)EXHAUSTIVE {
2 7u83 221
      case EFN_NAME:
7 7u83 222
	E_errf_eof_in_name(istream);
2 7u83 223
	UNREACHED;
224
      case EFN_BUILTIN:
7 7u83 225
	E_errf_eof_in_builtin(istream);
2 7u83 226
	UNREACHED;
227
      case EFN_STRING:
7 7u83 228
	E_errf_eof_in_string(istream);
2 7u83 229
	UNREACHED;
230
    }
231
}
232
 
233
static void
7 7u83 234
error_file_read_until(IStreamP istream, char term, ErrorFileTokenT type,
235
		      ErrorFileLexP token)
2 7u83 236
{
237
    DStringT dstring;
238
 
7 7u83 239
    dstring_init(&dstring);
2 7u83 240
    for (;;) {
241
	char c;
242
 
243
      redo:
7 7u83 244
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 245
	  case '\0':
7 7u83 246
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
247
	    error_file_null_character(istream, type);
2 7u83 248
	    UNREACHED;
249
	  case '\n':
7 7u83 250
	    istream_inc_line(istream);
251
	    error_file_newline(istream, type);
2 7u83 252
	    UNREACHED;
253
	  default:
254
	    if (c == term) {
255
		CStringP tmp;
256
 
7 7u83 257
		tmp = dstring_to_cstring(&dstring);
258
		dstring_destroy(&dstring);
2 7u83 259
		token->u.string = tmp;
260
		return;
261
	    } else if (c == '\\') {
7 7u83 262
		switch (istream_read_escaped_char(istream, &c))EXHAUSTIVE {
2 7u83 263
		  case ISTREAM_STAT_READ_CHAR:
264
		    if (c == '\0') {
7 7u83 265
			error_file_null_character(istream, type);
2 7u83 266
			UNREACHED;
267
		    }
7 7u83 268
		    dstring_append_char(&dstring, c);
2 7u83 269
		    break;
270
		  case ISTREAM_STAT_SYNTAX_ERROR:
7 7u83 271
		    error_file_illegal_escape(istream, type);
2 7u83 272
		    UNREACHED;
273
		  case ISTREAM_STAT_NO_CHAR:
274
		    /*NOTHING*/
275
		    break;
276
		}
277
	    } else {
7 7u83 278
		dstring_append_char(&dstring, c);
2 7u83 279
	    }
280
	    break;
281
	}
282
    }
283
  eof:
7 7u83 284
    error_file_eof(istream, type);
2 7u83 285
    UNREACHED;
286
}
287
 
288
static void
7 7u83 289
error_file_check_builtin(IStreamP istream, ErrorFileLexP token)
2 7u83 290
{
7 7u83 291
    if (cstring_ci_equal(token->u.string, "strings")) {
2 7u83 292
	token->tag = EFTOKEN_BLT_STRINGS;
7 7u83 293
    } else if (cstring_ci_equal(token->u.string, "prefix")) {
2 7u83 294
	token->tag = EFTOKEN_BLT_PREFIX;
7 7u83 295
    } else if (cstring_ci_equal(token->u.string, "errors")) {
2 7u83 296
	token->tag = EFTOKEN_BLT_ERRORS;
297
    } else {
7 7u83 298
	E_errf_unknown_builtin(istream, token->u.string);
2 7u83 299
	UNREACHED;
300
    }
7 7u83 301
    DEALLOCATE(token->u.string);
2 7u83 302
}
303
 
304
static void
7 7u83 305
error_file_next_token(IStreamP istream, ErrorFileLexP token)
2 7u83 306
{
307
    char c;
308
 
7 7u83 309
    if (error_file_skip_white_space(istream, &c)) {
2 7u83 310
	switch (c) {
311
	  case '%':
7 7u83 312
	    error_file_read_until(istream, '%', EFN_BUILTIN, token);
313
	    error_file_check_builtin(istream, token);
2 7u83 314
	    break;
315
	  case '\'':
7 7u83 316
	    error_file_read_until(istream, '\'', EFN_NAME, token);
2 7u83 317
	    token->tag = EFTOKEN_NAME;
318
	    break;
319
	  case '"':
7 7u83 320
	    error_file_read_until(istream, '"', EFN_STRING, token);
2 7u83 321
	    token->tag = EFTOKEN_STRING;
322
	    break;
323
	  default:
7 7u83 324
	    E_errf_illegal_character(istream, c);
2 7u83 325
	    UNREACHED;
326
	}
327
    } else {
328
	token->tag = EFTOKEN_EOF;
329
    }
330
}
331
 
332
static void
7 7u83 333
error_file_parse_strings(IStreamP istream, ErrorFileLexP token)
2 7u83 334
{
7 7u83 335
    while (error_file_next_token(istream, token),
336
	  (token->tag == EFTOKEN_NAME)) {
2 7u83 337
	CStringP name = token->u.string;
338
 
7 7u83 339
	if (error_file_next_token(istream, token),
340
	   (token->tag != EFTOKEN_STRING)) {
341
	    E_errf_expected_string(istream);
2 7u83 342
	    UNREACHED;
7 7u83 343
	} else if (!error_redefine_string(name, token->u.string)) {
344
	    E_errf_unknown_string(istream, name);
2 7u83 345
	    UNREACHED;
346
	}
7 7u83 347
	DEALLOCATE(name);
2 7u83 348
    }
349
}
350
 
351
static void
7 7u83 352
error_file_parse_prefix(IStreamP istream, ErrorFileLexP token)
2 7u83 353
{
7 7u83 354
    error_file_next_token(istream, token);
2 7u83 355
    if (token->tag != EFTOKEN_STRING) {
7 7u83 356
	E_errf_expected_string(istream);
2 7u83 357
	UNREACHED;
7 7u83 358
    } else if (!error_set_prefix_message(token->u.string)) {
359
	E_errf_illegal_message(istream, token->u.string);
2 7u83 360
	UNREACHED;
361
    }
7 7u83 362
    DEALLOCATE(token->u.string);
363
    error_file_next_token(istream, token);
2 7u83 364
}
365
 
366
static void
7 7u83 367
error_file_parse_errors(IStreamP istream, ErrorFileLexP token)
2 7u83 368
{
7 7u83 369
    while (error_file_next_token(istream, token),
370
	  (token->tag == EFTOKEN_NAME)) {
2 7u83 371
	CStringP name = token->u.string;
372
 
7 7u83 373
	error_file_next_token(istream, token);
2 7u83 374
	if (token->tag != EFTOKEN_STRING) {
7 7u83 375
	    E_errf_expected_string(istream);
2 7u83 376
	    UNREACHED;
377
	} else {
7 7u83 378
	    switch (error_redefine_error(name, token->u.string))EXHAUSTIVE {
2 7u83 379
	      case ERROR_STATUS_BAD_ERROR:
7 7u83 380
		E_errf_unknown_error(istream, name);
2 7u83 381
		UNREACHED;
382
	      case ERROR_STATUS_BAD_MESSAGE:
7 7u83 383
		E_errf_illegal_message(istream, token->u.string);
2 7u83 384
		UNREACHED;
385
	      case ERROR_STATUS_SUCCESS:
386
		/*NOTHING*/
387
		break;
388
	    }
389
	}
7 7u83 390
	DEALLOCATE(name);
391
	DEALLOCATE(token->u.string);
2 7u83 392
    }
393
}
394
 
395
/*--------------------------------------------------------------------------*/
396
 
397
void
7 7u83 398
error_file_parse(CStringP name, BoolT must_open)
2 7u83 399
{
400
    IStreamT      istream;
401
    ErrorFileLexT token;
402
 
7 7u83 403
    if (istream_open(&istream, name)) {
404
	error_file_next_token(&istream, &token);
2 7u83 405
	while (token.tag != EFTOKEN_EOF) {
406
	    switch (token.tag) {
407
	      case EFTOKEN_BLT_STRINGS:
7 7u83 408
		error_file_parse_strings(&istream, &token);
2 7u83 409
		break;
410
	      case EFTOKEN_BLT_PREFIX:
7 7u83 411
		error_file_parse_prefix(&istream, &token);
2 7u83 412
		break;
413
	      case EFTOKEN_BLT_ERRORS:
7 7u83 414
		error_file_parse_errors(&istream, &token);
2 7u83 415
		break;
416
	      default:
7 7u83 417
		E_errf_expected_section(&istream);
2 7u83 418
		UNREACHED;
419
	    }
420
	}
7 7u83 421
	istream_close(&istream);
2 7u83 422
    } else if (must_open) {
7 7u83 423
	E_errf_cannot_open(name);
2 7u83 424
	UNREACHED;
425
    }
426
}
427
 
428
/*
429
 * Local variables(smf):
430
 * eval: (include::add-path-entry "../os-interface" "../generated")
431
 * end:
432
**/