Subversion Repositories tendra.SVN

Rev

Rev 5 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 104... Line 134...
104
#endif /* defined (FS_NO_ENUM) */
134
#endif /* defined (FS_NO_ENUM) */
105
 
135
 
106
/*--------------------------------------------------------------------------*/
136
/*--------------------------------------------------------------------------*/
107
 
137
 
108
static BoolT
138
static BoolT
109
error_file_skip_white_space PROTO_N ((istream, c_ref))
139
error_file_skip_white_space(IStreamP istream, char *c_ref)
110
			    PROTO_T (IStreamP istream X
-
 
111
				     char    *c_ref)
-
 
112
{
140
{
113
    BoolT comment = FALSE;
141
    BoolT comment = FALSE;
114
 
142
 
115
    for (;;) {
143
    for (;;) {
116
	char c;
144
	char c;
117
 
145
 
118
      redo:
146
      redo:
119
	switch (c = ISTREAM_READ_CHAR (istream)) {
147
	switch (c = ISTREAM_READ_CHAR(istream)) {
120
	  case '\0':
148
	  case '\0':
121
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
149
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
122
	    break;
150
	    break;
123
	  case '\n':
151
	  case '\n':
124
	    istream_inc_line (istream);
152
	    istream_inc_line(istream);
125
	    comment = FALSE;
153
	    comment = FALSE;
126
	    break;
154
	    break;
127
	  case '#':
155
	  case '#':
128
	    comment = TRUE;
156
	    comment = TRUE;
129
	    break;
157
	    break;
130
	  default:
158
	  default:
131
	    if ((!comment) && (!syntax_is_white_space (c))) {
159
	    if ((!comment) && (!syntax_is_white_space(c))) {
132
		*c_ref = c;
160
		*c_ref = c;
133
		return (TRUE);
161
		return(TRUE);
134
	    }
162
	    }
135
	}
163
	}
136
    }
164
    }
137
  eof:
165
  eof:
138
    return (FALSE);
166
    return(FALSE);
139
}
167
}
140
 
168
 
141
static void
169
static void
142
error_file_null_character PROTO_N ((istream, type))
170
error_file_null_character(IStreamP istream, ErrorFileTokenT type)
143
			  PROTO_T (IStreamP        istream X
-
 
144
				   ErrorFileTokenT type)
-
 
145
{
171
{
146
    switch (type) EXHAUSTIVE {
172
    switch (type)EXHAUSTIVE {
147
      case EFN_NAME:
173
      case EFN_NAME:
148
	E_errf_null_character_in_name (istream);
174
	E_errf_null_character_in_name(istream);
149
	UNREACHED;
175
	UNREACHED;
150
      case EFN_BUILTIN:
176
      case EFN_BUILTIN:
151
	E_errf_null_char_in_builtin (istream);
177
	E_errf_null_char_in_builtin(istream);
152
	UNREACHED;
178
	UNREACHED;
153
      case EFN_STRING:
179
      case EFN_STRING:
154
	E_errf_null_character_in_string (istream);
180
	E_errf_null_character_in_string(istream);
155
	UNREACHED;
181
	UNREACHED;
156
    }
182
    }
157
}
183
}
158
 
184
 
159
static void
185
static void
160
error_file_newline PROTO_N ((istream, type))
186
error_file_newline(IStreamP istream, ErrorFileTokenT type)
161
		   PROTO_T (IStreamP        istream X
-
 
162
			    ErrorFileTokenT type)
-
 
163
{
187
{
164
    switch (type) EXHAUSTIVE {
188
    switch (type)EXHAUSTIVE {
165
      case EFN_NAME:
189
      case EFN_NAME:
166
	E_errf_newline_in_name (istream);
190
	E_errf_newline_in_name(istream);
167
	UNREACHED;
191
	UNREACHED;
168
      case EFN_BUILTIN:
192
      case EFN_BUILTIN:
169
	E_errf_newline_in_builtin (istream);
193
	E_errf_newline_in_builtin(istream);
170
	UNREACHED;
194
	UNREACHED;
171
      case EFN_STRING:
195
      case EFN_STRING:
172
	E_errf_newline_in_string (istream);
196
	E_errf_newline_in_string(istream);
173
	UNREACHED;
197
	UNREACHED;
174
    }
198
    }
175
}
199
}
176
 
200
 
177
static void
201
static void
178
error_file_illegal_escape PROTO_N ((istream, type))
202
error_file_illegal_escape(IStreamP istream, ErrorFileTokenT type)
179
			  PROTO_T (IStreamP        istream X
-
 
180
				   ErrorFileTokenT type)
-
 
181
{
203
{
182
    switch (type) EXHAUSTIVE {
204
    switch (type)EXHAUSTIVE {
183
      case EFN_NAME:
205
      case EFN_NAME:
184
	E_errf_illegal_escape_in_name (istream);
206
	E_errf_illegal_escape_in_name(istream);
185
	UNREACHED;
207
	UNREACHED;
186
      case EFN_BUILTIN:
208
      case EFN_BUILTIN:
187
	E_errf_illegal_esc_in_builtin (istream);
209
	E_errf_illegal_esc_in_builtin(istream);
188
	UNREACHED;
210
	UNREACHED;
189
      case EFN_STRING:
211
      case EFN_STRING:
190
	E_errf_illegal_escape_in_string (istream);
212
	E_errf_illegal_escape_in_string(istream);
191
	UNREACHED;
213
	UNREACHED;
192
    }
214
    }
193
}
215
}
194
 
216
 
195
static void
217
static void
196
error_file_eof PROTO_N ((istream, type))
218
error_file_eof(IStreamP istream, ErrorFileTokenT type)
197
	       PROTO_T (IStreamP        istream X
-
 
198
			ErrorFileTokenT type)
-
 
199
{
219
{
200
    switch (type) EXHAUSTIVE {
220
    switch (type)EXHAUSTIVE {
201
      case EFN_NAME:
221
      case EFN_NAME:
202
	E_errf_eof_in_name (istream);
222
	E_errf_eof_in_name(istream);
203
	UNREACHED;
223
	UNREACHED;
204
      case EFN_BUILTIN:
224
      case EFN_BUILTIN:
205
	E_errf_eof_in_builtin (istream);
225
	E_errf_eof_in_builtin(istream);
206
	UNREACHED;
226
	UNREACHED;
207
      case EFN_STRING:
227
      case EFN_STRING:
208
	E_errf_eof_in_string (istream);
228
	E_errf_eof_in_string(istream);
209
	UNREACHED;
229
	UNREACHED;
210
    }
230
    }
211
}
231
}
212
 
232
 
213
static void
233
static void
214
error_file_read_until PROTO_N ((istream, term, type, token))
234
error_file_read_until(IStreamP istream, char term, ErrorFileTokenT type,
215
		      PROTO_T (IStreamP        istream X
-
 
216
			       char            term X
-
 
217
			       ErrorFileTokenT type X
-
 
218
			       ErrorFileLexP   token)
235
		      ErrorFileLexP token)
219
{
236
{
220
    DStringT dstring;
237
    DStringT dstring;
221
 
238
 
222
    dstring_init (&dstring);
239
    dstring_init(&dstring);
223
    for (;;) {
240
    for (;;) {
224
	char c;
241
	char c;
225
 
242
 
226
      redo:
243
      redo:
227
	switch (c = ISTREAM_READ_CHAR (istream)) {
244
	switch (c = ISTREAM_READ_CHAR(istream)) {
228
	  case '\0':
245
	  case '\0':
229
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
246
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
230
	    error_file_null_character (istream, type);
247
	    error_file_null_character(istream, type);
231
	    UNREACHED;
248
	    UNREACHED;
232
	  case '\n':
249
	  case '\n':
233
	    istream_inc_line (istream);
250
	    istream_inc_line(istream);
234
	    error_file_newline (istream, type);
251
	    error_file_newline(istream, type);
235
	    UNREACHED;
252
	    UNREACHED;
236
	  default:
253
	  default:
237
	    if (c == term) {
254
	    if (c == term) {
238
		CStringP tmp;
255
		CStringP tmp;
239
 
256
 
240
		tmp = dstring_to_cstring (&dstring);
257
		tmp = dstring_to_cstring(&dstring);
241
		dstring_destroy (&dstring);
258
		dstring_destroy(&dstring);
242
		token->u.string = tmp;
259
		token->u.string = tmp;
243
		return;
260
		return;
244
	    } else if (c == '\\') {
261
	    } else if (c == '\\') {
245
		switch (istream_read_escaped_char (istream, &c)) EXHAUSTIVE {
262
		switch (istream_read_escaped_char(istream, &c))EXHAUSTIVE {
246
		  case ISTREAM_STAT_READ_CHAR:
263
		  case ISTREAM_STAT_READ_CHAR:
247
		    if (c == '\0') {
264
		    if (c == '\0') {
248
			error_file_null_character (istream, type);
265
			error_file_null_character(istream, type);
249
			UNREACHED;
266
			UNREACHED;
250
		    }
267
		    }
251
		    dstring_append_char (&dstring, c);
268
		    dstring_append_char(&dstring, c);
252
		    break;
269
		    break;
253
		  case ISTREAM_STAT_SYNTAX_ERROR:
270
		  case ISTREAM_STAT_SYNTAX_ERROR:
254
		    error_file_illegal_escape (istream, type);
271
		    error_file_illegal_escape(istream, type);
255
		    UNREACHED;
272
		    UNREACHED;
256
		  case ISTREAM_STAT_NO_CHAR:
273
		  case ISTREAM_STAT_NO_CHAR:
257
		    /*NOTHING*/
274
		    /*NOTHING*/
258
		    break;
275
		    break;
259
		}
276
		}
260
	    } else {
277
	    } else {
261
		dstring_append_char (&dstring, c);
278
		dstring_append_char(&dstring, c);
262
	    }
279
	    }
263
	    break;
280
	    break;
264
	}
281
	}
265
    }
282
    }
266
  eof:
283
  eof:
267
    error_file_eof (istream, type);
284
    error_file_eof(istream, type);
268
    UNREACHED;
285
    UNREACHED;
269
}
286
}
270
 
287
 
271
static void
288
static void
272
error_file_check_builtin PROTO_N ((istream, token))
289
error_file_check_builtin(IStreamP istream, ErrorFileLexP token)
273
			 PROTO_T (IStreamP      istream X
-
 
274
				  ErrorFileLexP token)
-
 
275
{
290
{
276
    if (cstring_ci_equal (token->u.string, "strings")) {
291
    if (cstring_ci_equal(token->u.string, "strings")) {
277
	token->tag = EFTOKEN_BLT_STRINGS;
292
	token->tag = EFTOKEN_BLT_STRINGS;
278
    } else if (cstring_ci_equal (token->u.string, "prefix")) {
293
    } else if (cstring_ci_equal(token->u.string, "prefix")) {
279
	token->tag = EFTOKEN_BLT_PREFIX;
294
	token->tag = EFTOKEN_BLT_PREFIX;
280
    } else if (cstring_ci_equal (token->u.string, "errors")) {
295
    } else if (cstring_ci_equal(token->u.string, "errors")) {
281
	token->tag = EFTOKEN_BLT_ERRORS;
296
	token->tag = EFTOKEN_BLT_ERRORS;
282
    } else {
297
    } else {
283
	E_errf_unknown_builtin (istream, token->u.string);
298
	E_errf_unknown_builtin(istream, token->u.string);
284
	UNREACHED;
299
	UNREACHED;
285
    }
300
    }
286
    DEALLOCATE (token->u.string);
301
    DEALLOCATE(token->u.string);
287
}
302
}
288
 
303
 
289
static void
304
static void
290
error_file_next_token PROTO_N ((istream, token))
305
error_file_next_token(IStreamP istream, ErrorFileLexP token)
291
		      PROTO_T (IStreamP      istream X
-
 
292
			       ErrorFileLexP token)
-
 
293
{
306
{
294
    char c;
307
    char c;
295
 
308
 
296
    if (error_file_skip_white_space (istream, &c)) {
309
    if (error_file_skip_white_space(istream, &c)) {
297
	switch (c) {
310
	switch (c) {
298
	  case '%':
311
	  case '%':
299
	    error_file_read_until (istream, '%', EFN_BUILTIN, token);
312
	    error_file_read_until(istream, '%', EFN_BUILTIN, token);
300
	    error_file_check_builtin (istream, token);
313
	    error_file_check_builtin(istream, token);
301
	    break;
314
	    break;
302
	  case '\'':
315
	  case '\'':
303
	    error_file_read_until (istream, '\'', EFN_NAME, token);
316
	    error_file_read_until(istream, '\'', EFN_NAME, token);
304
	    token->tag = EFTOKEN_NAME;
317
	    token->tag = EFTOKEN_NAME;
305
	    break;
318
	    break;
306
	  case '"':
319
	  case '"':
307
	    error_file_read_until (istream, '"', EFN_STRING, token);
320
	    error_file_read_until(istream, '"', EFN_STRING, token);
308
	    token->tag = EFTOKEN_STRING;
321
	    token->tag = EFTOKEN_STRING;
309
	    break;
322
	    break;
310
	  default:
323
	  default:
311
	    E_errf_illegal_character (istream, c);
324
	    E_errf_illegal_character(istream, c);
312
	    UNREACHED;
325
	    UNREACHED;
313
	}
326
	}
314
    } else {
327
    } else {
315
	token->tag = EFTOKEN_EOF;
328
	token->tag = EFTOKEN_EOF;
316
    }
329
    }
317
}
330
}
318
 
331
 
319
static void
332
static void
320
error_file_parse_strings PROTO_N ((istream, token))
333
error_file_parse_strings(IStreamP istream, ErrorFileLexP token)
321
			 PROTO_T (IStreamP      istream X
-
 
322
				  ErrorFileLexP token)
-
 
323
{
334
{
324
    while (error_file_next_token (istream, token),
335
    while (error_file_next_token(istream, token),
325
	   (token->tag == EFTOKEN_NAME)) {
336
	  (token->tag == EFTOKEN_NAME)) {
326
	CStringP name = token->u.string;
337
	CStringP name = token->u.string;
327
 
338
 
328
	if (error_file_next_token (istream, token),
339
	if (error_file_next_token(istream, token),
329
	    (token->tag != EFTOKEN_STRING)) {
340
	   (token->tag != EFTOKEN_STRING)) {
330
	    E_errf_expected_string (istream);
341
	    E_errf_expected_string(istream);
331
	    UNREACHED;
342
	    UNREACHED;
332
	} else if (!error_redefine_string (name, token->u.string)) {
343
	} else if (!error_redefine_string(name, token->u.string)) {
333
	    E_errf_unknown_string (istream, name);
344
	    E_errf_unknown_string(istream, name);
334
	    UNREACHED;
345
	    UNREACHED;
335
	}
346
	}
336
	DEALLOCATE (name);
347
	DEALLOCATE(name);
337
    }
348
    }
338
}
349
}
339
 
350
 
340
static void
351
static void
341
error_file_parse_prefix PROTO_N ((istream, token))
352
error_file_parse_prefix(IStreamP istream, ErrorFileLexP token)
342
			PROTO_T (IStreamP      istream X
-
 
343
				 ErrorFileLexP token)
-
 
344
{
353
{
345
    error_file_next_token (istream, token);
354
    error_file_next_token(istream, token);
346
    if (token->tag != EFTOKEN_STRING) {
355
    if (token->tag != EFTOKEN_STRING) {
347
	E_errf_expected_string (istream);
356
	E_errf_expected_string(istream);
348
	UNREACHED;
357
	UNREACHED;
349
    } else if (!error_set_prefix_message (token->u.string)) {
358
    } else if (!error_set_prefix_message(token->u.string)) {
350
	E_errf_illegal_message (istream, token->u.string);
359
	E_errf_illegal_message(istream, token->u.string);
351
	UNREACHED;
360
	UNREACHED;
352
    }
361
    }
353
    DEALLOCATE (token->u.string);
362
    DEALLOCATE(token->u.string);
354
    error_file_next_token (istream, token);
363
    error_file_next_token(istream, token);
355
}
364
}
356
 
365
 
357
static void
366
static void
358
error_file_parse_errors PROTO_N ((istream, token))
367
error_file_parse_errors(IStreamP istream, ErrorFileLexP token)
359
			PROTO_T (IStreamP      istream X
-
 
360
				 ErrorFileLexP token)
-
 
361
{
368
{
362
    while (error_file_next_token (istream, token),
369
    while (error_file_next_token(istream, token),
363
	   (token->tag == EFTOKEN_NAME)) {
370
	  (token->tag == EFTOKEN_NAME)) {
364
	CStringP name = token->u.string;
371
	CStringP name = token->u.string;
365
 
372
 
366
	error_file_next_token (istream, token);
373
	error_file_next_token(istream, token);
367
	if (token->tag != EFTOKEN_STRING) {
374
	if (token->tag != EFTOKEN_STRING) {
368
	    E_errf_expected_string (istream);
375
	    E_errf_expected_string(istream);
369
	    UNREACHED;
376
	    UNREACHED;
370
	} else {
377
	} else {
371
	    switch (error_redefine_error (name, token->u.string)) EXHAUSTIVE {
378
	    switch (error_redefine_error(name, token->u.string))EXHAUSTIVE {
372
	      case ERROR_STATUS_BAD_ERROR:
379
	      case ERROR_STATUS_BAD_ERROR:
373
		E_errf_unknown_error (istream, name);
380
		E_errf_unknown_error(istream, name);
374
		UNREACHED;
381
		UNREACHED;
375
	      case ERROR_STATUS_BAD_MESSAGE:
382
	      case ERROR_STATUS_BAD_MESSAGE:
376
		E_errf_illegal_message (istream, token->u.string);
383
		E_errf_illegal_message(istream, token->u.string);
377
		UNREACHED;
384
		UNREACHED;
378
	      case ERROR_STATUS_SUCCESS:
385
	      case ERROR_STATUS_SUCCESS:
379
		/*NOTHING*/
386
		/*NOTHING*/
380
		break;
387
		break;
381
	    }
388
	    }
382
	}
389
	}
383
	DEALLOCATE (name);
390
	DEALLOCATE(name);
384
	DEALLOCATE (token->u.string);
391
	DEALLOCATE(token->u.string);
385
    }
392
    }
386
}
393
}
387
 
394
 
388
/*--------------------------------------------------------------------------*/
395
/*--------------------------------------------------------------------------*/
389
 
396
 
390
void
397
void
391
error_file_parse PROTO_N ((name, must_open))
398
error_file_parse(CStringP name, BoolT must_open)
392
		 PROTO_T (CStringP name X
-
 
393
			  BoolT    must_open)
-
 
394
{
399
{
395
    IStreamT      istream;
400
    IStreamT      istream;
396
    ErrorFileLexT token;
401
    ErrorFileLexT token;
397
 
402
 
398
    if (istream_open (&istream, name)) {
403
    if (istream_open(&istream, name)) {
399
	error_file_next_token (&istream, &token);
404
	error_file_next_token(&istream, &token);
400
	while (token.tag != EFTOKEN_EOF) {
405
	while (token.tag != EFTOKEN_EOF) {
401
	    switch (token.tag) {
406
	    switch (token.tag) {
402
	      case EFTOKEN_BLT_STRINGS:
407
	      case EFTOKEN_BLT_STRINGS:
403
		error_file_parse_strings (&istream, &token);
408
		error_file_parse_strings(&istream, &token);
404
		break;
409
		break;
405
	      case EFTOKEN_BLT_PREFIX:
410
	      case EFTOKEN_BLT_PREFIX:
406
		error_file_parse_prefix (&istream, &token);
411
		error_file_parse_prefix(&istream, &token);
407
		break;
412
		break;
408
	      case EFTOKEN_BLT_ERRORS:
413
	      case EFTOKEN_BLT_ERRORS:
409
		error_file_parse_errors (&istream, &token);
414
		error_file_parse_errors(&istream, &token);
410
		break;
415
		break;
411
	      default:
416
	      default:
412
		E_errf_expected_section (&istream);
417
		E_errf_expected_section(&istream);
413
		UNREACHED;
418
		UNREACHED;
414
	    }
419
	    }
415
	}
420
	}
416
	istream_close (&istream);
421
	istream_close(&istream);
417
    } else if (must_open) {
422
    } else if (must_open) {
418
	E_errf_cannot_open (name);
423
	E_errf_cannot_open(name);
419
	UNREACHED;
424
	UNREACHED;
420
    }
425
    }
421
}
426
}
422

427

423
/*
428
/*