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