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
/**** istream.c --- Input stream handling.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 **** Commentary:
36
 *
37
 * This file implements the input stream facility specified in the file
38
 * "istream.h".  See that file for more details.
39
 *
40
 **** Change Log:
41
 * $Log: istream.c,v $
42
 * Revision 1.1.1.1  1998/01/17  15:57:18  release
43
 * First version to be checked into rolling release.
44
 *
45
 * Revision 1.2  1994/12/12  11:45:41  smf
46
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
47
 * OSSG C Coding Standards.
48
 *
49
 * Revision 1.1.1.1  1994/07/25  16:06:10  smf
50
 * Initial import of os-interface shared files.
51
 *
52
**/
53
 
54
/****************************************************************************/
55
 
56
#include "istream.h"
57
#include "cstring.h"
58
#include "syntax.h"
59
 
60
/*--------------------------------------------------------------------------*/
61
 
62
#define ISTREAM_BUFSIZE 8193
63
 
64
/*--------------------------------------------------------------------------*/
65
 
66
ExceptionP XX_istream_read_error = EXCEPTION ("error reading from stream");
67
 
68
/*--------------------------------------------------------------------------*/
69
 
70
static char istream_input_buffer [ISTREAM_BUFSIZE];
71
 
72
static IStreamT		istream_input_1 = {
73
    NIL (FILE *),
74
    &(istream_input_buffer [0]),
75
    &(istream_input_buffer [ISTREAM_BUFSIZE - 1]),
76
    &(istream_input_buffer [ISTREAM_BUFSIZE]),
77
    &(istream_input_buffer [ISTREAM_BUFSIZE]),
78
    1,
79
    "<stdin>",
80
    FALSE
81
};
82
 
83
IStreamT	 *const istream_input = &istream_input_1;
84
 
85
/*--------------------------------------------------------------------------*/
86
 
87
static IStreamStatusT
88
istream_read_hex_char PROTO_N ((istream, c_ref))
89
		      PROTO_T (IStreamP istream X
90
			       char    *c_ref)
91
{
92
    int value;
93
    int tmp;
94
    char c;
95
 
96
  redo1:
97
    switch (c = ISTREAM_READ_CHAR (istream)) {
98
      case '\0':
99
	ISTREAM_HANDLE_NULL (istream, redo1, eof);
100
	return (ISTREAM_STAT_SYNTAX_ERROR);
101
      case '\n':
102
	istream_inc_line (istream);
103
	return (ISTREAM_STAT_SYNTAX_ERROR);
104
      default:
105
	if (((value = syntax_value (c)) == SYNTAX_NO_VALUE) || (value >= 16)) {
106
	    return (ISTREAM_STAT_SYNTAX_ERROR);
107
	}
108
	tmp = value;
109
	break;
110
    }
111
  redo2:
112
    switch (c = ISTREAM_READ_CHAR (istream)) {
113
      case '\0':
114
	ISTREAM_HANDLE_NULL (istream, redo2, eof);
115
	return (ISTREAM_STAT_SYNTAX_ERROR);
116
      case '\n':
117
	istream_inc_line (istream);
118
	return (ISTREAM_STAT_SYNTAX_ERROR);
119
      default:
120
	if (((value = syntax_value (c)) == SYNTAX_NO_VALUE) || (value >= 16)) {
121
	    return (ISTREAM_STAT_SYNTAX_ERROR);
122
	}
123
	break;
124
    }
125
    *c_ref = (char) ((tmp * 16) + value);
126
    return (ISTREAM_STAT_READ_CHAR);
127
  eof:
128
    return (ISTREAM_STAT_SYNTAX_ERROR);
129
}
130
 
131
/*--------------------------------------------------------------------------*/
132
 
133
void
134
istream_setup PROTO_Z ()
135
{
136
    istream_input_1.file = stdin;
137
}
138
 
139
#ifdef FS_FAST
140
#undef istream_init
141
#endif /* defined (FS_FAST) */
142
void
143
istream_init PROTO_N ((istream))
144
	     PROTO_T (IStreamP istream)
145
{
146
    istream->name = NIL (CStringP);
147
}
148
#ifdef FS_FAST
149
#define istream_init(is) ((is)->name = NIL (CStringP))
150
#endif /* defined (FS_FAST) */
151
 
152
BoolT
153
istream_open PROTO_N ((istream, name))
154
	     PROTO_T (IStreamP istream X
155
		      CStringP name)
156
{
157
    if ((istream->file = fopen (name, "r")) == NIL (FILE *)) {
158
	return (FALSE);
159
    }
160
    istream->buffer  = ALLOCATE_VECTOR (char, ISTREAM_BUFSIZE);
161
    istream->limit   = &(istream->buffer [ISTREAM_BUFSIZE]);
162
    istream->line    = 1;
163
    istream->name    = name;
164
    X__istream_fill_buffer (istream);
165
    return (TRUE);
166
}
167
 
168
void
169
istream_assign PROTO_N ((to, from))
170
	       PROTO_T (IStreamP to X
171
			IStreamP from)
172
{
173
    to->file      = from->file;
174
    to->buffer    = from->buffer;
175
    to->current   = from->current;
176
    to->end       = from->end;
177
    to->limit     = from->limit;
178
    to->line      = from->line;
179
    to->name      = from->name;
180
    to->read_last = from->read_last;
181
}
182
 
183
#ifdef FS_FAST
184
#undef istream_is_open
185
#endif /* defined (FS_FAST) */
186
BoolT
187
istream_is_open PROTO_N ((istream))
188
		PROTO_T (IStreamP istream)
189
{
190
    return (istream->name != NIL (CStringP));
191
}
192
#ifdef FS_FAST
193
#define istream_is_open(is) ((is)->name != NIL (CStringP))
194
#endif /* defined (FS_FAST) */
195
 
196
BoolT
197
istream_read_char PROTO_N ((istream, c_ref))
198
		  PROTO_T (IStreamP istream X
199
			   char    *c_ref)
200
{
201
    char c;
202
 
203
  redo:
204
    switch (c = ISTREAM_READ_CHAR (istream)) {
205
      case '\n':
206
	istream_inc_line (istream);
207
	break;
208
      case '\0':
209
	ISTREAM_HANDLE_NULL (istream, redo, eof);
210
	break;
211
      default:
212
	break;
213
    }
214
    *c_ref = c;
215
    return (TRUE);
216
  eof:
217
    return (FALSE);
218
}
219
 
220
BoolT
221
istream_peek_char PROTO_N ((istream, c_ref))
222
		  PROTO_T (IStreamP istream X
223
			   char    *c_ref)
224
{
225
    char c;
226
 
227
  redo:
228
    switch (c = ISTREAM_PEEK_CHAR (istream)) {
229
      case '\0':
230
	ISTREAM_HANDLE_NULL (istream, redo, eof);
231
	break;
232
      default:
233
	break;
234
    }
235
    *c_ref = c;
236
    return (TRUE);
237
  eof:
238
    return (FALSE);
239
}
240
 
241
IStreamStatusT
242
istream_read_escaped_char PROTO_N ((istream, c_ref))
243
			  PROTO_T (IStreamP istream X
244
				   char    *c_ref)
245
{
246
    char c;
247
 
248
  redo:
249
    switch (c = ISTREAM_READ_CHAR (istream)) {
250
      case '\0':
251
	ISTREAM_HANDLE_NULL (istream, redo, eof);
252
	*c_ref = c;
253
	return (ISTREAM_STAT_READ_CHAR);
254
      case '\n':
255
	istream_inc_line (istream);
256
	return (ISTREAM_STAT_NO_CHAR);
257
      case '0':
258
	*c_ref = '\0';
259
	return (ISTREAM_STAT_READ_CHAR);
260
      case 'f': case 'F':
261
	*c_ref = '\f';
262
	return (ISTREAM_STAT_READ_CHAR);
263
      case 'n': case 'N':
264
	*c_ref = '\n';
265
	return (ISTREAM_STAT_READ_CHAR);
266
      case 'r': case 'R':
267
	*c_ref = '\r';
268
	return (ISTREAM_STAT_READ_CHAR);
269
      case 't': case 'T':
270
	*c_ref = '\t';
271
	return (ISTREAM_STAT_READ_CHAR);
272
      case 'x': case 'X':
273
	return (istream_read_hex_char (istream, c_ref));
274
      default:
275
	*c_ref = c;
276
	return (ISTREAM_STAT_READ_CHAR);
277
    }
278
  eof:
279
    return (ISTREAM_STAT_SYNTAX_ERROR);
280
}
281
 
282
#ifdef FS_FAST
283
#undef istream_inc_line
284
#endif /* defined (FS_FAST) */
285
void
286
istream_inc_line PROTO_N ((istream))
287
		 PROTO_T (IStreamP istream)
288
{
289
    istream->line ++;
290
}
291
#ifdef FS_FAST
292
#define istream_inc_line(is) ((is)->line ++)
293
#endif /* defined (FS_FAST) */
294
 
295
#ifdef FS_FAST
296
#undef istream_line
297
#endif /* defined (FS_FAST) */
298
unsigned
299
istream_line PROTO_N ((istream))
300
	     PROTO_T (IStreamP istream)
301
{
302
    return (istream->line);
303
}
304
#ifdef FS_FAST
305
#define istream_line(is) ((is)->line)
306
#endif /* defined (FS_FAST) */
307
 
308
#ifdef FS_FAST
309
#undef istream_name
310
#endif /* defined (FS_FAST) */
311
CStringP
312
istream_name PROTO_N ((istream))
313
	     PROTO_T (IStreamP istream)
314
{
315
    return (istream->name);
316
}
317
#ifdef FS_FAST
318
#define istream_name(is) ((is)->name)
319
#endif /* defined (FS_FAST) */
320
 
321
void
322
istream_close PROTO_N ((istream))
323
	      PROTO_T (IStreamP istream)
324
{
325
    (void) fclose (istream->file);
326
    if (istream != istream_input) {
327
	DEALLOCATE (istream->buffer);
328
    }
329
    istream_init (istream);
330
}
331
 
332
/*--------------------------------------------------------------------------*/
333
 
334
void
335
X__istream_fill_buffer PROTO_N ((istream))
336
		       PROTO_T (IStreamP istream)
337
{
338
    SizeT bytes = fread ((GenericP) (istream->buffer), sizeof (char),
339
			 (SizeT) (ISTREAM_BUFSIZE - 1), istream->file);
340
 
341
    if ((bytes == (SizeT) 0) && (ferror (istream->file))) {
342
	CStringP name = cstring_duplicate (istream->name);
343
 
344
	THROW_VALUE (XX_istream_read_error, name);
345
	UNREACHED;
346
    }
347
    istream->current   = istream->buffer;
348
    istream->end       = (istream->current + bytes);
349
    istream->read_last = FALSE;
350
    *(istream->end) ++ = '\0';
351
}