Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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.h --- Input stream handling.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 **** Commentary:
36
 *
37
 ***=== INTRODUCTION =========================================================
38
 *
39
 * This file specifies the interface to the input stream facility.
40
 *
41
 ***=== TYPES ================================================================
42
 *
43
 ** Type:	IStreamT
44
 ** Type:	IStreamP
45
 ** Repr:	<private>
46
 *
47
 * This is the input stream type.
48
 *
49
 ** Type:	IStreamStatusT
50
 ** Type:	IStreamStatusP
51
 ** Repr:	enum {ISTREAM_STAT_READ_CHAR, ISTREAM_STAT_NO_CHAR,
52
 *		      ISTREAM_STAT_SYNTAX_ERROR}
53
 *
54
 * This is the return type of the ``istream_read_escaped_char'' function.  The
55
 * constants represent the results: a character was read, no character was
56
 * read, and a syntax error occured respectively.
57
 *
58
 ***=== CONSTANTS ============================================================
59
 *
60
 ** Constant:	istream_input
61
 *
62
 * This value is a pointer to an input stream object that will read from the
63
 * standard input.  The ``istream_setup'' function must be called before this
64
 * constant is used.
65
 *
66
 ***=== FUNCTIONS ============================================================
67
 *
68
 ** Function:	void			istream_setup
69
 *			PROTO_S ((void))
70
 ** Exceptions:
71
 *
72
 * This function initialises the input stream facility.  It should be called
73
 * before any other istream manipulation function.
74
 *
75
 ** Function:	void			istream_init
76
 *			PROTO_S ((IStreamP istream))
77
 ** Exceptions:
78
 *
79
 * This function initialises the specified istream not to read from any file.
80
 *
81
 ** Function:	BoolT			istream_open
82
 *			PROTO_S ((IStreamP istream, CStringP name))
83
 ** Exceptions: XX_dalloc_no_memory, XX_istream_read_error
84
 *
85
 * This function initialises the specified istream to read from the file with
86
 * the specified name.  The name should not be modified or deallocated until
87
 * the istream has been closed.  If the file cannot be opened, the function
88
 * returns false. If the file is opened successfully, the function returns
89
 * true.
90
 *
91
 ** Function:	void			istream_assign
92
 *			PROTO_S ((IStreamP to, IStreamP from))
93
 ** Exceptions:
94
 *
95
 * This function assigns the from istream to the to istream.  The from istream
96
 * should not be used again.
97
 *
98
 ** Function:	BoolT			istream_is_open
99
 *			PROTO_S ((IStreamP istream))
100
 *
101
 * This function returns true if the specified istream is reading from a file,
102
 * and false otherwise.
103
 *
104
 ** Function:	BoolT			istream_read_char
105
 *			PROTO_S ((IStreamP istream, char *c_ref))
106
 ** Exceptions:	XX_dalloc_no_memory, XX_istream_read_error
107
 *
108
 * This function reads the next character from the specified istream (and
109
 * advances the character pointer).  If a character is read then the character
110
 * is assigned to the reference argument, and the function returns true.  If
111
 * the end of file is reached, the function returns false.  If the character
112
 * read is a newline, then the istream's line count is incremented.
113
 *
114
 ** Function:	BoolT			istream_peek_char
115
 *			PROTO_S ((IStreamP istream, char *c_ref))
116
 ** Exceptions:	XX_dalloc_no_memory, XX_istream_read_error
117
 *
118
 * This function reads the next character from the specified istream (but does
119
 * not advance the character pointer).  If a character is read then the
120
 * character is assigned to the reference argument, and the function returns
121
 * true.  If the end of file is reached, the function returns false.
122
 *
123
 ** Function:	IStreamStatusT		istream_read_escaped_char
124
 *			PROTO_S ((IStreamP istream, char *c_ref))
125
 ** Exceptions:	XX_dalloc_no_memory, XX_istream_read_error
126
 *
127
 * This function reads a character sequence from the specified istream, and
128
 * parses it as an escaped character sequence.  Normally, the character to
129
 * which the sequence evaluates is assigned to the reference argument and
130
 * ``ISTREAM_STAT_READ_CHAR'' is returned.  If if it evaluates to no
131
 * character, then ``ISTREAM_STAT_NO_CHAR'' is returned (this is not an
132
 * error).  If there is an error in the syntax of the character sequence, then
133
 * ``ISTREAM_STAT_SYNTAX_ERROR'' is returned.  If any of the characters read
134
 * are newline characters, then the istream's line counter will be incremented
135
 * for each newline.
136
 *
137
 ** Function:	void			istream_inc_line
138
 *			PROTO_S ((IStreamP istream))
139
 ** Exceptions:
140
 *
141
 * This function increments the specified istream's line counter.  It should
142
 * only really be called as specified in the documentation for the
143
 * ``ISTREAM_READ_CHAR'' macro.
144
 *
145
 ** Function:	unsigned		istream_line
146
 *			PROTO_S ((IStreamP istream))
147
 ** Exceptions:
148
 *
149
 * This function returns the line number of the specified istream (one more
150
 * than the number of newlines that have been read).
151
 *
152
 ** Function:	CStringP		istream_name
153
 *			PROTO_S ((IStreamP istream))
154
 ** Exceptions:
155
 *
156
 * This function returns the name of the file from which the specified istream
157
 * is reading. The return value should not be modified or deallocated.
158
 *
159
 ** Function:	void			istream_close
160
 *			PROTO_S ((IStreamP istream))
161
 ** Exceptions:
162
 *
163
 * This function closes the specified istream.
164
 *
165
 ***=== MACROS ===============================================================
166
 *
167
 ** Macro:	ISTREAM_READ_CHAR (istream)
168
 ** Exceptions:
169
 *
170
 * This macro returns the next character from the specified istream.  It is a
171
 * slightly faster alternative to the ``istream_read_char'' function.  In
172
 * order to get the speed improvement, the program needs to do some extra
173
 * work: if the character returned is a newline, then the program must call
174
 * the ``istream_inc_line'' function to increment the line count; if the
175
 * character returned is a null character, then the program must call the
176
 * ``ISTREAM_HANDLE_NULL'' macro on the istream that was read.  It is not
177
 * obvious that the speed increase is worth the extra effort in coding.
178
 *
179
 ** Macro:	ISTREAM_PEEK_CHAR (istream)
180
 ** Exceptions:
181
 *
182
 * This macro returns the next character from the specified istream, without
183
 * reading it.  It is a slightly faster alternative to the
184
 * ``istream_peek_char'' function.  In order to get the speed improvement, the
185
 * program needs to do some extra work: if the character returned is the null
186
 * character, then the program must call the ``ISTREAM_HANDLE_NULL'' macro on
187
 * the istream that was read.  Unlike the ``ISTREAM_READ_CHAR'' macro, it is
188
 * not necessary to increment the istream's line count.  It is not obvious
189
 * that the speed increase is worth the extra effort in coding.
190
 *
191
 ** Macro:	ISTREAM_HANDLE_NULL (istream, redo, eof)
192
 ** Exceptions:	XX_dalloc_no_memory, XX_istream_read_error
193
 *
194
 * This macro should be called when either of the previous two macros returns
195
 * the null character.  It checks to see if the null character is really a
196
 * null character, a refill buffer instruction, or an end of file.  If it is a
197
 * real null character, then the program continues normally.  If it is a
198
 * refill buffer instruction, the istream's buffer is refilled, and the
199
 * program goes to the label ``redo''.  If it is an end of file, then the
200
 * program goes to the label ``eof''.
201
 *
202
 ***=== EXCEPTIONS ===========================================================
203
 *
204
 ** Exception:	XX_istream_read_error (CStringP name)
205
 *
206
 * This exception is raised if a read attempt fails.  The data thrown is a
207
 * copy of the name of the file that the read error occured on.  The copy
208
 * should be deallocated when finished with.
209
 *
210
 **** Change Log:
211
 * $Log: istream.h,v $
212
 * Revision 1.1.1.1  1998/01/17  15:57:18  release
213
 * First version to be checked into rolling release.
214
 *
215
 * Revision 1.2  1994/12/12  11:45:43  smf
216
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
217
 * OSSG C Coding Standards.
218
 *
219
 * Revision 1.1.1.1  1994/07/25  16:06:10  smf
220
 * Initial import of os-interface shared files.
221
 *
222
**/
223
 
224
/****************************************************************************/
225
 
226
#ifndef H_ISTREAM
227
#define H_ISTREAM
228
 
229
#include "os-interface.h"
230
#include "dalloc.h"
231
#include "exception.h"
232
 
233
/*--------------------------------------------------------------------------*/
234
 
235
typedef struct IStreamT {
236
    FILE		       *file;
237
    CStringP			buffer;
238
    CStringP			current;
239
    CStringP			end;
240
    CStringP			limit;
241
    unsigned			line;
242
    CStringP			name;
243
    BoolT			read_last;
244
} IStreamT, *IStreamP;
245
 
246
#ifdef FS_NO_ENUM
247
typedef int IStreamStatusT, *IStreamStatusP;
248
#define ISTREAM_STAT_READ_CHAR		(0)
249
#define ISTREAM_STAT_NO_CHAR		(1)
250
#define ISTREAM_STAT_SYNTAX_ERROR	(2)
251
#else
252
typedef enum {
253
    ISTREAM_STAT_READ_CHAR,
254
    ISTREAM_STAT_NO_CHAR,
255
    ISTREAM_STAT_SYNTAX_ERROR
256
} IStreamStatusT, *IStreamStatusP;
257
#endif /* defined (FS_NO_ENUM) */
258
 
259
/*--------------------------------------------------------------------------*/
260
 
261
extern ExceptionP		XX_istream_read_error;
262
extern IStreamT		 *const istream_input;
263
 
264
/*--------------------------------------------------------------------------*/
265
 
266
extern void			istream_setup
267
	PROTO_S ((void));
268
extern void			istream_init
269
	PROTO_S ((IStreamP));
270
extern BoolT			istream_open
271
	PROTO_S ((IStreamP, CStringP));
272
extern void			istream_assign
273
	PROTO_S ((IStreamP, IStreamP));
274
extern BoolT			istream_is_open
275
	PROTO_S ((IStreamP));
276
extern BoolT			istream_read_char
277
	PROTO_S ((IStreamP, char *));
278
extern BoolT			istream_peek_char
279
	PROTO_S ((IStreamP, char *));
280
extern IStreamStatusT		istream_read_escaped_char
281
	PROTO_S ((IStreamP, char *));
282
extern void			istream_inc_line
283
	PROTO_S ((IStreamP));
284
extern unsigned			istream_line
285
	PROTO_S ((IStreamP));
286
extern CStringP			istream_name
287
	PROTO_S ((IStreamP));
288
extern void			istream_close
289
	PROTO_S ((IStreamP));
290
 
291
/*--------------------------------------------------------------------------*/
292
 
293
extern void			X__istream_fill_buffer
294
	PROTO_S ((IStreamP));
295
 
296
/*--------------------------------------------------------------------------*/
297
 
298
#define ISTREAM_READ_CHAR(istream) \
299
(((istream)->read_last = TRUE), (*((istream)->current) ++))
300
 
301
#define ISTREAM_PEEK_CHAR(istream) \
302
(((istream)->read_last = FALSE), (*((istream)->current)))
303
 
304
#define ISTREAM_HANDLE_NULL(istream,redo,eof) \
305
{ \
306
    IStreamP X___is = (istream); \
307
    if (X___is->read_last) { \
308
	if (X___is->current == X___is->end) { \
309
	    if (X___is->end == X___is->limit) { \
310
		X__istream_fill_buffer (X___is); \
311
		goto redo; \
312
	    } else { \
313
		X___is->current --; \
314
		goto eof; \
315
	    } \
316
	} \
317
    } else { \
318
	if (X___is->current == (X___is->end - 1)) { \
319
	    if (X___is->end == X___is->limit) { \
320
		X__istream_fill_buffer (X___is); \
321
		goto redo; \
322
	    } else { \
323
		goto eof; \
324
	    } \
325
	} \
326
    } \
327
}
328
 
329
/*--------------------------------------------------------------------------*/
330
 
331
#ifdef FS_FAST
332
#define istream_init(is) ((is)->name = NIL (CStringP))
333
#define istream_is_open(is) ((is)->name != NIL (CStringP))
334
#define istream_inc_line(is) ((is)->line ++)
335
#define istream_line(is) ((is)->line)
336
#define istream_name(is) ((is)->name)
337
#endif /* defined (FS_FAST) */
338
 
339
#endif /* !defined (H_ISTREAM) */