Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**** rename-file.c --- Routines for parsing rename file.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 **** Commentary:
36
 *
37
 * This file provides the routines that parse the rename file.  The rename
38
 * file has the following format.
39
 *
40
 *	'shape'
41
 *		"name1" "name2";
42
 *		"name3" [unique.4];
43
 *
44
 * Where shape names are enclosed in single quotes, string names are enclosed
45
 * in double quotes, and uniques are written using the normal unique syntax.
46
 * A single shape name may be followed by any number of name pairs, each of
47
 * which is terminated by a semi-colon.
48
 *
49
 **** Change Log:
50
 * $Log: rename-file.c,v $
51
 * Revision 1.1.1.1  1998/01/17  15:57:16  release
52
 * First version to be checked into rolling release.
53
 *
54
 * Revision 1.3  1995/09/22  08:37:15  smf
55
 * Fixed problems with incomplete structures (to shut "tcc" up).
56
 *
57
 * Revision 1.2  1994/12/12  11:44:10  smf
58
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
59
 * OSSG C Coding Standards.
60
 *
61
 * Revision 1.1.1.1  1994/07/25  16:03:28  smf
62
 * Initial import of TDF linker 3.5 non shared files.
63
 *
64
**/
65
 
66
/****************************************************************************/
67
 
68
#include "rename-file.h"
69
#include "dstring.h"
70
#include "gen-errors.h"
71
#include "istream.h"
72
#include "nstring-list.h"
73
#include "syntax.h"
74
 
75
#include "solve-cycles.h"
76
 
77
/*--------------------------------------------------------------------------*/
78
 
79
#ifdef FS_NO_ENUM
80
typedef int RenameTagT, *RenameTagP;
81
#define RTOK_SHAPE		(0)
82
#define RTOK_NAME		(1)
83
#define RTOK_SEMI		(2)
84
#define RTOK_EOF		(3)
85
#else
86
typedef enum {
87
    RTOK_SHAPE,
88
    RTOK_NAME,
89
    RTOK_SEMI,
90
    RTOK_EOF
91
} RenameTagT, *RenameTagP;
92
#endif /* defined (FS_NO_ENUM) */
93
 
94
typedef struct RenameTokenT {
95
    RenameTagT			tag;
96
    union {
97
	NStringT		shape;
98
	NameKeyT		name;
99
    } u;
100
} RenameTokenT, *RenameTokenP;
101
 
102
/*--------------------------------------------------------------------------*/
103
 
104
static BoolT
105
rename_file_skip_white_space PROTO_N ((istream, c_ref))
106
			     PROTO_T (IStreamP istream X
107
				      char    *c_ref)
108
{
109
    BoolT comment = FALSE;
110
 
111
    for (;;) {
112
	char c;
113
 
114
      redo:
115
	switch (c = ISTREAM_READ_CHAR (istream)) {
116
	  case '\0':
117
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
118
	    break;
119
	  case '\n':
120
	    istream_inc_line (istream);
121
	    comment = FALSE;
122
	    break;
123
	  case '#':
124
	    comment = TRUE;
125
	    break;
126
	  default:
127
	    if ((!comment) && (!syntax_is_white_space (c))) {
128
		*c_ref = c;
129
		return (TRUE);
130
	    }
131
	    break;
132
	}
133
    }
134
  eof:
135
    return (FALSE);
136
}
137
 
138
static void
139
rename_file_read_unique PROTO_N ((istream, token))
140
			PROTO_T (IStreamP     istream X
141
				 RenameTokenP token)
142
{
143
    NameKeyP          name   = &(token->u.name);
144
    unsigned          length = 1;
145
    DStringT          dstring;
146
    NStringT          nstring;
147
    NStringListT      list;
148
    NStringListEntryP entry;
149
    unsigned          i;
150
 
151
    dstring_init (&dstring);
152
    nstring_list_init (&list);
153
    for (;;) {
154
	char c;
155
 
156
      redo:
157
	switch (c = ISTREAM_READ_CHAR (istream)) {
158
	  case '\0':
159
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
160
	    dstring_append_char (&dstring, '\0');
161
	    break;
162
	  case '\n':
163
	    istream_inc_line (istream);
164
	    E_rename_unexpected_newline (istream);
165
	    break;
166
	  case ']':
167
	    dstring_to_nstring (&dstring, &nstring);
168
	    nstring_list_append (&list, &nstring);
169
	    dstring_destroy (&dstring);
170
	    name_key_init_unique (name, length);
171
 	    for (i = 0, entry = nstring_list_head (&list); entry;
172
		 i ++, entry = nstring_list_entry_deallocate (entry)) {
173
		NStringP component = nstring_list_entry_string (entry);
174
 
175
		name_key_set_component (name, i, component);
176
	    }
177
	    token->tag = RTOK_NAME;
178
	    return;
179
	  case '[':
180
	    E_rename_illegal_char (istream, c);
181
	    break;
182
	  case '.':
183
	    dstring_to_nstring (&dstring, &nstring);
184
	    nstring_list_append (&list, &nstring);
185
	    dstring_destroy (&dstring);
186
	    dstring_init (&dstring);
187
	    length ++;
188
	    break;
189
	  case '\\':
190
	    switch (istream_read_escaped_char (istream, &c)) EXHAUSTIVE {
191
	      case ISTREAM_STAT_READ_CHAR:
192
		dstring_append_char (&dstring, c);
193
		break;
194
	      case ISTREAM_STAT_SYNTAX_ERROR:
195
		E_rename_illegal_escape (istream);
196
		break;
197
	      case ISTREAM_STAT_NO_CHAR:
198
		/*NOTHING*/
199
		break;
200
	    }
201
	    break;
202
	  default:
203
	    dstring_append_char (&dstring, c);
204
	    break;
205
	}
206
    }
207
  eof:
208
    E_rename_unexpected_eof (istream);
209
    dstring_destroy (&dstring);
210
    for (entry = nstring_list_head (&list); entry;
211
	 entry = nstring_list_entry_deallocate (entry)) {
212
	nstring_destroy (nstring_list_entry_string (entry));
213
    }
214
    token->tag = RTOK_EOF;
215
}
216
 
217
static void
218
rename_file_read_shape PROTO_N ((istream, token))
219
		       PROTO_T (IStreamP     istream X
220
				RenameTokenP token)
221
{
222
    DStringT dstring;
223
 
224
    dstring_init (&dstring);
225
    for (;;) {
226
	char c;
227
 
228
      redo:
229
	switch (c = ISTREAM_READ_CHAR (istream)) {
230
	  case '\0':
231
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
232
	    dstring_append_char (&dstring, '\0');
233
	    break;
234
	  case '\n':
235
	    istream_inc_line (istream);
236
	    E_rename_unexpected_newline (istream);
237
	    break;
238
	  case '\'':
239
	    dstring_to_nstring (&dstring, &(token->u.shape));
240
	    dstring_destroy (&dstring);
241
	    token->tag = RTOK_SHAPE;
242
	    return;
243
	  case '\\':
244
	    switch (istream_read_escaped_char (istream, &c)) EXHAUSTIVE {
245
	      case ISTREAM_STAT_READ_CHAR:
246
		dstring_append_char (&dstring, c);
247
		break;
248
	      case ISTREAM_STAT_SYNTAX_ERROR:
249
		E_rename_illegal_escape (istream);
250
		break;
251
	      case ISTREAM_STAT_NO_CHAR:
252
		/*NOTHING*/
253
		break;
254
	    }
255
	    break;
256
	  default:
257
	    dstring_append_char (&dstring, c);
258
	    break;
259
	}
260
    }
261
  eof:
262
    E_rename_unexpected_eof (istream);
263
    dstring_destroy (&dstring);
264
    token->tag = RTOK_EOF;
265
}
266
 
267
static void
268
rename_file_read_string PROTO_N ((istream, token))
269
			PROTO_T (IStreamP     istream X
270
				 RenameTokenP token)
271
{
272
    DStringT dstring;
273
    NStringT nstring;
274
 
275
    dstring_init (&dstring);
276
    for (;;) {
277
	char c;
278
 
279
      redo:
280
	switch (c = ISTREAM_READ_CHAR (istream)) {
281
	  case '\0':
282
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
283
	    dstring_append_char (&dstring, '\0');
284
	    break;
285
	  case '\n':
286
	    istream_inc_line (istream);
287
	    E_rename_unexpected_newline (istream);
288
	    break;
289
	  case '"':
290
	    dstring_to_nstring (&dstring, &nstring);
291
	    dstring_destroy (&dstring);
292
	    name_key_init_string (&(token->u.name), &nstring);
293
	    token->tag = RTOK_NAME;
294
	    return;
295
	  case '[': case ']': case '.':
296
	    E_rename_illegal_char (istream, c);
297
	    break;
298
	  case '\\':
299
	    switch (istream_read_escaped_char (istream, &c)) EXHAUSTIVE {
300
	      case ISTREAM_STAT_READ_CHAR:
301
		dstring_append_char (&dstring, c);
302
		break;
303
	      case ISTREAM_STAT_SYNTAX_ERROR:
304
		E_rename_illegal_escape (istream);
305
		break;
306
	      case ISTREAM_STAT_NO_CHAR:
307
		/*NOTHING*/
308
		break;
309
	    }
310
	    break;
311
	  default:
312
	    dstring_append_char (&dstring, c);
313
	    break;
314
	}
315
    }
316
  eof:
317
    E_rename_unexpected_eof (istream);
318
    dstring_destroy (&dstring);
319
    token->tag = RTOK_EOF;
320
}
321
 
322
static void
323
rename_file_next_token PROTO_N ((istream, token))
324
		       PROTO_T (IStreamP     istream X
325
				RenameTokenP token)
326
{
327
    char c;
328
 
329
  again:
330
    if (rename_file_skip_white_space (istream, &c)) {
331
	switch (c) {
332
	  case '[':
333
	    rename_file_read_unique (istream, token);
334
	    break;
335
	  case '\'':
336
	     rename_file_read_shape (istream, token);
337
	    break;
338
	  case '"':
339
	    rename_file_read_string (istream, token);
340
	    break;
341
	  case ';':
342
	    token->tag = RTOK_SEMI;
343
	    break;
344
	  default:
345
	    E_rename_illegal_char (istream, c);
346
	    goto again;
347
	}
348
    } else {
349
	token->tag = RTOK_EOF;
350
    }
351
}
352
 
353
static void
354
rename_file_parse_names PROTO_N ((istream, shape, arg_data, token))
355
			PROTO_T (IStreamP     istream X
356
				 NStringP     shape X
357
				 ArgDataP     arg_data X
358
				 RenameTokenP token)
359
{
360
    rename_file_next_token (istream, token);
361
    while (token->tag == RTOK_NAME) {
362
	NameKeyT name;
363
 
364
	name_key_assign (&name, &(token->u.name));
365
	rename_file_next_token (istream, token);
366
	if (token->tag != RTOK_NAME) {
367
	    E_rename_expected_name (istream);
368
	    name_key_destroy (&name);
369
	    if (token->tag != RTOK_SEMI) {
370
		return;
371
	    }
372
	    rename_file_next_token (istream, token);
373
	} else {
374
	    NameKeyT to_name;
375
 
376
	    name_key_assign (&to_name, &(token->u.name));
377
	    arg_data_add_rename (arg_data, shape, &name, &to_name);
378
	    rename_file_next_token (istream, token);
379
	    if (token->tag != RTOK_SEMI) {
380
		E_rename_expected_semi (istream);
381
	    } else {
382
		rename_file_next_token (istream, token);
383
	    }
384
	}
385
    }
386
}
387
 
388
static void
389
rename_file_parse_1 PROTO_N ((istream, arg_data))
390
		    PROTO_T (IStreamP istream X
391
			     ArgDataP arg_data)
392
{
393
    BoolT        need_error = TRUE;
394
    RenameTokenT token;
395
    NStringT     shape;
396
 
397
    rename_file_next_token (istream, &token);
398
    while (token.tag != RTOK_EOF) {
399
	switch (token.tag) {
400
	  case RTOK_SHAPE:
401
	    nstring_assign (&shape, &(token.u.shape));
402
	    rename_file_parse_names (istream, &shape, arg_data, &token);
403
	    nstring_destroy (&shape);
404
	    need_error = TRUE;
405
	    break;
406
	  case RTOK_NAME:
407
	    name_key_destroy (&(token.u.name));
408
	    FALL_THROUGH;
409
	  default:
410
	    if (need_error) {
411
		E_rename_expected_shape (istream);
412
		need_error = FALSE;
413
	    }
414
	    rename_file_next_token (istream, &token);
415
	    break;
416
	}
417
    }
418
}
419
 
420
/*--------------------------------------------------------------------------*/
421
 
422
void
423
rename_file_parse PROTO_N ((name, arg_data))
424
		  PROTO_T (CStringP name X
425
			   ArgDataP arg_data)
426
{
427
    IStreamT istream;
428
 
429
    if (istream_open (&istream, name)) {
430
	rename_file_parse_1 (&istream, arg_data);
431
	istream_close (&istream);
432
    } else {
433
	E_cannot_open_rename_file (name);
434
    }
435
    if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
436
	exit (EXIT_FAILURE);
437
	UNREACHED;
438
    }
439
}
440
 
441
/*
442
 * Local variables(smf):
443
 * eval: (include::add-path-entry "../os-interface" "../library" "../tdf")
444
 * eval: (include::add-path-entry "../generated")
445
 * End:
446
**/