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-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:17  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
6 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:
6 7u83 147
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 148
	  case '\0':
6 7u83 149
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
2 7u83 150
	    break;
151
	  case '\n':
6 7u83 152
	    istream_inc_line(istream);
2 7u83 153
	    comment = FALSE;
154
	    break;
155
	  case '#':
156
	    comment = TRUE;
157
	    break;
158
	  default:
6 7u83 159
	    if ((!comment) && (!syntax_is_white_space(c))) {
2 7u83 160
		*c_ref = c;
6 7u83 161
		return(TRUE);
2 7u83 162
	    }
163
	}
164
    }
165
  eof:
6 7u83 166
    return(FALSE);
2 7u83 167
}
168
 
169
static void
6 7u83 170
error_file_null_character(IStreamP        istream,				   ErrorFileTokenT type)
2 7u83 171
{
6 7u83 172
    switch (type)EXHAUSTIVE {
2 7u83 173
      case EFN_NAME:
6 7u83 174
	E_errf_null_character_in_name(istream);
2 7u83 175
	UNREACHED;
176
      case EFN_BUILTIN:
6 7u83 177
	E_errf_null_char_in_builtin(istream);
2 7u83 178
	UNREACHED;
179
      case EFN_STRING:
6 7u83 180
	E_errf_null_character_in_string(istream);
2 7u83 181
	UNREACHED;
182
    }
183
}
184
 
185
static void
6 7u83 186
error_file_newline(IStreamP        istream,			    ErrorFileTokenT type)
2 7u83 187
{
6 7u83 188
    switch (type)EXHAUSTIVE {
2 7u83 189
      case EFN_NAME:
6 7u83 190
	E_errf_newline_in_name(istream);
2 7u83 191
	UNREACHED;
192
      case EFN_BUILTIN:
6 7u83 193
	E_errf_newline_in_builtin(istream);
2 7u83 194
	UNREACHED;
195
      case EFN_STRING:
6 7u83 196
	E_errf_newline_in_string(istream);
2 7u83 197
	UNREACHED;
198
    }
199
}
200
 
201
static void
6 7u83 202
error_file_illegal_escape(IStreamP        istream,				   ErrorFileTokenT type)
2 7u83 203
{
6 7u83 204
    switch (type)EXHAUSTIVE {
2 7u83 205
      case EFN_NAME:
6 7u83 206
	E_errf_illegal_escape_in_name(istream);
2 7u83 207
	UNREACHED;
208
      case EFN_BUILTIN:
6 7u83 209
	E_errf_illegal_esc_in_builtin(istream);
2 7u83 210
	UNREACHED;
211
      case EFN_STRING:
6 7u83 212
	E_errf_illegal_escape_in_string(istream);
2 7u83 213
	UNREACHED;
214
    }
215
}
216
 
217
static void
6 7u83 218
error_file_eof(IStreamP        istream,			ErrorFileTokenT type)
2 7u83 219
{
6 7u83 220
    switch (type)EXHAUSTIVE {
2 7u83 221
      case EFN_NAME:
6 7u83 222
	E_errf_eof_in_name(istream);
2 7u83 223
	UNREACHED;
224
      case EFN_BUILTIN:
6 7u83 225
	E_errf_eof_in_builtin(istream);
2 7u83 226
	UNREACHED;
227
      case EFN_STRING:
6 7u83 228
	E_errf_eof_in_string(istream);
2 7u83 229
	UNREACHED;
230
    }
231
}
232
 
233
static void
6 7u83 234
error_file_read_until(IStreamP        istream,			       char            term, 
235
			       ErrorFileTokenT type, 
2 7u83 236
			       ErrorFileLexP   token)
237
{
238
    DStringT dstring;
239
 
6 7u83 240
    dstring_init(&dstring);
2 7u83 241
    for (;;) {
242
	char c;
243
 
244
      redo:
6 7u83 245
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 246
	  case '\0':
6 7u83 247
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
248
	    error_file_null_character(istream, type);
2 7u83 249
	    UNREACHED;
250
	  case '\n':
6 7u83 251
	    istream_inc_line(istream);
252
	    error_file_newline(istream, type);
2 7u83 253
	    UNREACHED;
254
	  default:
255
	    if (c == term) {
256
		CStringP tmp;
257
 
6 7u83 258
		tmp = dstring_to_cstring(&dstring);
259
		dstring_destroy(&dstring);
2 7u83 260
		token->u.string = tmp;
261
		return;
262
	    } else if (c == '\\') {
6 7u83 263
		switch (istream_read_escaped_char(istream, &c))EXHAUSTIVE {
2 7u83 264
		  case ISTREAM_STAT_READ_CHAR:
265
		    if (c == '\0') {
6 7u83 266
			error_file_null_character(istream, type);
2 7u83 267
			UNREACHED;
268
		    }
6 7u83 269
		    dstring_append_char(&dstring, c);
2 7u83 270
		    break;
271
		  case ISTREAM_STAT_SYNTAX_ERROR:
6 7u83 272
		    error_file_illegal_escape(istream, type);
2 7u83 273
		    UNREACHED;
274
		  case ISTREAM_STAT_NO_CHAR:
275
		    /*NOTHING*/
276
		    break;
277
		}
278
	    } else {
6 7u83 279
		dstring_append_char(&dstring, c);
2 7u83 280
	    }
281
	    break;
282
	}
283
    }
284
  eof:
6 7u83 285
    error_file_eof(istream, type);
2 7u83 286
    UNREACHED;
287
}
288
 
289
static void
6 7u83 290
error_file_check_builtin(IStreamP      istream,				  ErrorFileLexP token)
2 7u83 291
{
6 7u83 292
    if (cstring_ci_equal(token->u.string, "strings")) {
2 7u83 293
	token->tag = EFTOKEN_BLT_STRINGS;
6 7u83 294
    } else if (cstring_ci_equal(token->u.string, "prefix")) {
2 7u83 295
	token->tag = EFTOKEN_BLT_PREFIX;
6 7u83 296
    } else if (cstring_ci_equal(token->u.string, "errors")) {
2 7u83 297
	token->tag = EFTOKEN_BLT_ERRORS;
298
    } else {
6 7u83 299
	E_errf_unknown_builtin(istream, token->u.string);
2 7u83 300
	UNREACHED;
301
    }
6 7u83 302
    DEALLOCATE(token->u.string);
2 7u83 303
}
304
 
305
static void
6 7u83 306
error_file_next_token(IStreamP      istream,			       ErrorFileLexP token)
2 7u83 307
{
308
    char c;
309
 
6 7u83 310
    if (error_file_skip_white_space(istream, &c)) {
2 7u83 311
	switch (c) {
312
	  case '%':
6 7u83 313
	    error_file_read_until(istream, '%', EFN_BUILTIN, token);
314
	    error_file_check_builtin(istream, token);
2 7u83 315
	    break;
316
	  case '\'':
6 7u83 317
	    error_file_read_until(istream, '\'', EFN_NAME, token);
2 7u83 318
	    token->tag = EFTOKEN_NAME;
319
	    break;
320
	  case '"':
6 7u83 321
	    error_file_read_until(istream, '"', EFN_STRING, token);
2 7u83 322
	    token->tag = EFTOKEN_STRING;
323
	    break;
324
	  default:
6 7u83 325
	    E_errf_illegal_character(istream, c);
2 7u83 326
	    UNREACHED;
327
	}
328
    } else {
329
	token->tag = EFTOKEN_EOF;
330
    }
331
}
332
 
333
static void
6 7u83 334
error_file_parse_strings(IStreamP      istream,				  ErrorFileLexP token)
2 7u83 335
{
6 7u83 336
    while (error_file_next_token(istream, token),
337
	  (token->tag == EFTOKEN_NAME)) {
2 7u83 338
	CStringP name = token->u.string;
339
 
6 7u83 340
	if (error_file_next_token(istream, token),
341
	   (token->tag != EFTOKEN_STRING)) {
342
	    E_errf_expected_string(istream);
2 7u83 343
	    UNREACHED;
6 7u83 344
	} else if (!error_redefine_string(name, token->u.string)) {
345
	    E_errf_unknown_string(istream, name);
2 7u83 346
	    UNREACHED;
347
	}
6 7u83 348
	DEALLOCATE(name);
2 7u83 349
    }
350
}
351
 
352
static void
6 7u83 353
error_file_parse_prefix(IStreamP      istream,				 ErrorFileLexP token)
2 7u83 354
{
6 7u83 355
    error_file_next_token(istream, token);
2 7u83 356
    if (token->tag != EFTOKEN_STRING) {
6 7u83 357
	E_errf_expected_string(istream);
2 7u83 358
	UNREACHED;
6 7u83 359
    } else if (!error_set_prefix_message(token->u.string)) {
360
	E_errf_illegal_message(istream, token->u.string);
2 7u83 361
	UNREACHED;
362
    }
6 7u83 363
    DEALLOCATE(token->u.string);
364
    error_file_next_token(istream, token);
2 7u83 365
}
366
 
367
static void
6 7u83 368
error_file_parse_errors(IStreamP      istream,				 ErrorFileLexP token)
2 7u83 369
{
6 7u83 370
    while (error_file_next_token(istream, token),
371
	  (token->tag == EFTOKEN_NAME)) {
2 7u83 372
	CStringP name = token->u.string;
373
 
6 7u83 374
	error_file_next_token(istream, token);
2 7u83 375
	if (token->tag != EFTOKEN_STRING) {
6 7u83 376
	    E_errf_expected_string(istream);
2 7u83 377
	    UNREACHED;
378
	} else {
6 7u83 379
	    switch (error_redefine_error(name, token->u.string))EXHAUSTIVE {
2 7u83 380
	      case ERROR_STATUS_BAD_ERROR:
6 7u83 381
		E_errf_unknown_error(istream, name);
2 7u83 382
		UNREACHED;
383
	      case ERROR_STATUS_BAD_MESSAGE:
6 7u83 384
		E_errf_illegal_message(istream, token->u.string);
2 7u83 385
		UNREACHED;
386
	      case ERROR_STATUS_SUCCESS:
387
		/*NOTHING*/
388
		break;
389
	    }
390
	}
6 7u83 391
	DEALLOCATE(name);
392
	DEALLOCATE(token->u.string);
2 7u83 393
    }
394
}
395
 
396
/*--------------------------------------------------------------------------*/
397
 
398
void
6 7u83 399
error_file_parse(CStringP name,			  BoolT    must_open)
2 7u83 400
{
401
    IStreamT      istream;
402
    ErrorFileLexT token;
403
 
6 7u83 404
    if (istream_open(&istream, name)) {
405
	error_file_next_token(&istream, &token);
2 7u83 406
	while (token.tag != EFTOKEN_EOF) {
407
	    switch (token.tag) {
408
	      case EFTOKEN_BLT_STRINGS:
6 7u83 409
		error_file_parse_strings(&istream, &token);
2 7u83 410
		break;
411
	      case EFTOKEN_BLT_PREFIX:
6 7u83 412
		error_file_parse_prefix(&istream, &token);
2 7u83 413
		break;
414
	      case EFTOKEN_BLT_ERRORS:
6 7u83 415
		error_file_parse_errors(&istream, &token);
2 7u83 416
		break;
417
	      default:
6 7u83 418
		E_errf_expected_section(&istream);
2 7u83 419
		UNREACHED;
420
	    }
421
	}
6 7u83 422
	istream_close(&istream);
2 7u83 423
    } else if (must_open) {
6 7u83 424
	E_errf_cannot_open(name);
2 7u83 425
	UNREACHED;
426
    }
427
}
428
 
429
/*
430
 * Local variables(smf):
431
 * eval: (include::add-path-entry "../os-interface" "../generated")
432
 * end:
433
**/