Subversion Repositories tendra.SVN

Rev

Rev 7 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 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
7 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:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 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;
7 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;
7 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
/**** ostream.c --- Output stream handling.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 **** Commentary:
66
 *
67
 * This file implements the output stream facility specified in the file
68
 * "ostream.h".  See that file for more details.
69
 *
70
 **** Change Log:
71
 * $Log: ostream.c,v $
72
 * Revision 1.1.1.1  1998/01/17  15:57:18  release
73
 * First version to be checked into rolling release.
74
 *
75
 * Revision 1.2  1994/12/12  11:45:47  smf
76
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
77
 * OSSG C Coding Standards.
78
 *
79
 * Revision 1.1.1.1  1994/07/25  16:06:11  smf
80
 * Initial import of os-interface shared files.
81
 *
82
**/
83
 
84
/****************************************************************************/
85
 
7 7u83 86
#include <stdio.h>
87
 
2 7u83 88
#include "ostream.h"
89
#include "cstring.h"
90
#include "syntax.h"
91
 
92
/*--------------------------------------------------------------------------*/
93
 
7 7u83 94
ExceptionP XX_ostream_write_error = EXCEPTION("error writing to stream");
2 7u83 95
 
96
static OStreamT			ostream_output_1 = {
7 7u83 97
    NIL(FILE *),
2 7u83 98
    "<stdout>",
99
    1
100
};
101
static OStreamT			ostream_error_1 = {
7 7u83 102
    NIL(FILE *),
2 7u83 103
    "<stderr>",
104
    1
105
};
106
 
107
OStreamT		 *const ostream_output = &ostream_output_1;
108
OStreamT		 *const ostream_error  = &ostream_error_1;
109
 
110
/*--------------------------------------------------------------------------*/
111
 
7 7u83 112
#define OSTREAM_WRITE_ERROR_CHECK(ostream)\
113
    if (ferror((ostream)->file)) { \
114
	    CStringP X___name = cstring_duplicate(ostream_name(ostream)); \
115
	    THROW_VALUE(XX_ostream_write_error, X___name); \
2 7u83 116
}
117
 
118
/*--------------------------------------------------------------------------*/
119
 
120
void
7 7u83 121
ostream_setup(void)
2 7u83 122
{
123
    ostream_output_1.file = stdout;
124
    ostream_error_1.file  = stderr;
125
}
126
 
127
#ifdef FS_FAST
128
#undef ostream_init
129
#endif /* defined (FS_FAST) */
130
void
7 7u83 131
ostream_init(OStreamP ostream)
2 7u83 132
{
7 7u83 133
    ostream->name = NIL(CStringP);
2 7u83 134
}
135
#ifdef FS_FAST
7 7u83 136
#define ostream_init(os)	((os)->name = NIL(CStringP))
2 7u83 137
#endif /* defined (FS_FAST) */
138
 
139
BoolT
7 7u83 140
ostream_open(OStreamP ostream,		      CStringP name)
2 7u83 141
{
7 7u83 142
    if ((ostream->file = fopen(name, "w")) == NIL(FILE *)) {
143
	return(FALSE);
2 7u83 144
    }
145
    ostream->name = name;
146
    ostream->line = 1;
7 7u83 147
   (void)setvbuf(ostream->file, NIL(CStringP), _IOFBF,(SizeT)BUFSIZ);
148
    return(TRUE);
2 7u83 149
}
150
 
151
#ifdef FS_FAST
152
#undef ostream_is_open
153
#endif /* defined (FS_FAST) */
154
BoolT
7 7u83 155
ostream_is_open(OStreamP ostream)
2 7u83 156
{
7 7u83 157
    return(ostream->name != NIL(CStringP));
2 7u83 158
}
159
#ifdef FS_FAST
7 7u83 160
#define ostream_is_open(os)	((os)->name != NIL(CStringP))
2 7u83 161
#endif /* defined (FS_FAST) */
162
 
163
void
7 7u83 164
ostream_buffer(OStreamP ostream)
2 7u83 165
{
7 7u83 166
   (void)setvbuf(ostream->file, NIL(CStringP), _IOFBF,(SizeT)BUFSIZ);
2 7u83 167
}
168
 
169
void
7 7u83 170
ostream_unbuffer(OStreamP ostream)
2 7u83 171
{
7 7u83 172
   (void)setvbuf(ostream->file, NIL(CStringP), _IONBF,(SizeT)0);
2 7u83 173
}
174
 
175
void
7 7u83 176
ostream_close(OStreamP ostream)
2 7u83 177
{
7 7u83 178
    if (fclose(ostream->file)) {
179
	CStringP name = cstring_duplicate(ostream_name(ostream));
2 7u83 180
 
7 7u83 181
	THROW_VALUE(XX_ostream_write_error, name);
2 7u83 182
    }
7 7u83 183
    ostream_init(ostream);
2 7u83 184
}
185
 
186
void
7 7u83 187
ostream_flush(OStreamP ostream)
2 7u83 188
{
7 7u83 189
    if (fflush(ostream->file)) {
190
	CStringP name = cstring_duplicate(ostream_name(ostream));
2 7u83 191
 
7 7u83 192
	THROW_VALUE(XX_ostream_write_error, name);
2 7u83 193
    }
194
}
195
 
196
#ifdef FS_FAST
197
#undef ostream_name
198
#endif /* defined (FS_FAST) */
199
CStringP
7 7u83 200
ostream_name(OStreamP ostream)
2 7u83 201
{
7 7u83 202
    return(ostream->name);
2 7u83 203
}
204
#ifdef FS_FAST
7 7u83 205
#define ostream_name(os)	((os)->name)
2 7u83 206
#endif /* defined (FS_FAST) */
207
 
208
#ifdef FS_FAST
209
#undef ostream_line
210
#endif /* defined (FS_FAST) */
211
unsigned
7 7u83 212
ostream_line(OStreamP ostream)
2 7u83 213
{
7 7u83 214
    return(ostream->line);
2 7u83 215
}
216
#ifdef FS_FAST
7 7u83 217
#define ostream_line(os)	((os)->line)
2 7u83 218
#endif /* defined (FS_FAST) */
219
 
220
void
7 7u83 221
write_newline(OStreamP ostream)
2 7u83 222
{
7 7u83 223
    ostream->line++;
224
   (void)putc('\n', ostream->file);
225
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 226
}
227
 
228
void
7 7u83 229
write_tab(OStreamP ostream)
2 7u83 230
{
7 7u83 231
   (void)putc('\t', ostream->file);
232
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 233
}
234
 
235
void
7 7u83 236
write_byte(OStreamP ostream,		    ByteT    c)
2 7u83 237
{
238
    if (c == '\n') {
7 7u83 239
	ostream->line++;
2 7u83 240
    }
7 7u83 241
   (void)putc((int)c, ostream->file);
242
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 243
}
244
 
245
void
7 7u83 246
write_char(OStreamP ostream,		    char     c)
2 7u83 247
{
248
    if (c == '\n') {
7 7u83 249
	ostream->line++;
2 7u83 250
    }
7 7u83 251
   (void)putc((int)c, ostream->file);
252
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 253
}
254
 
255
void
7 7u83 256
write_escaped_char(OStreamP ostream,			    char     c)
2 7u83 257
{
258
    switch (c) {
259
      case '\0':
7 7u83 260
	(void)fputs("\\0", ostream->file);
2 7u83 261
	break;
262
      case '\f':
7 7u83 263
	(void)fputs("\\f", ostream->file);
2 7u83 264
	break;
265
      case '\n':
7 7u83 266
	ostream->line++;
267
	(void)fputc('\n', ostream->file);
2 7u83 268
	break;
269
      case '\r':
7 7u83 270
	(void)fputs("\\r", ostream->file);
2 7u83 271
	break;
272
      case '\t':
7 7u83 273
	(void)fputc('\t', ostream->file);
2 7u83 274
	break;
275
      case '\\':
7 7u83 276
	(void)fputs("\\\\", ostream->file);
2 7u83 277
	break;
278
      default:
7 7u83 279
	if (syntax_is_printable(c)) {
280
	   (void)fputc((int)c, ostream->file);
2 7u83 281
	} else {
7 7u83 282
	   (void)fprintf(ostream->file, "\\x%02x",
283
			   (unsigned)(unsigned char)c);
2 7u83 284
	}
285
    }
7 7u83 286
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 287
}
288
 
289
void
7 7u83 290
write_int(OStreamP ostream,		   int      i)
2 7u83 291
{
7 7u83 292
   (void)fprintf(ostream->file, "%d", i);
293
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 294
}
295
 
296
void
7 7u83 297
write_unsigned(OStreamP ostream,			unsigned i)
2 7u83 298
{
7 7u83 299
   (void)fprintf(ostream->file, "%u", i);
300
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 301
}
302
 
303
void
7 7u83 304
write_cstring(OStreamP ostream,		       CStringP cstring)
2 7u83 305
{
306
    CStringP tmp = cstring;
307
 
308
    while (*tmp) {
7 7u83 309
	if (*tmp++ == '\n') {
310
	    ostream->line++;
2 7u83 311
	}
312
    }
7 7u83 313
   (void)fputs(cstring, ostream->file);
314
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 315
}
316
 
317
void
7 7u83 318
write_bytes(OStreamP ostream,		     ByteP    bytes ,
2 7u83 319
		     unsigned length)
320
{
321
    unsigned tmp_length = length;
322
    ByteP    tmp_bytes  = bytes;
323
 
7 7u83 324
    while (tmp_length--) {
325
	if (*tmp_bytes++ == '\n') {
326
	    ostream->line++;
2 7u83 327
	}
328
    }
7 7u83 329
   (void)fwrite((GenericP)bytes, sizeof(ByteT), (SizeT)length,
2 7u83 330
		   ostream->file);
7 7u83 331
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 332
}
333
 
334
void
7 7u83 335
write_chars(OStreamP ostream,		     CStringP chars ,
2 7u83 336
		     unsigned length)
337
{
7 7u83 338
    while (length--) {
339
	write_char(ostream, *chars++);
2 7u83 340
    }
341
}
342
 
343
void
7 7u83 344
write_escaped_chars(OStreamP ostream,			     CStringP chars ,
2 7u83 345
			     unsigned length)
346
{
7 7u83 347
    while (length--) {
348
	write_escaped_char(ostream, *chars++);
2 7u83 349
    }
350
}
351
 
352
void
7 7u83 353
write_system_error(OStreamP ostream)
2 7u83 354
{
7 7u83 355
#if (defined(FS_STRERROR) || defined(FS_SYS_ERRLIST))
2 7u83 356
# ifdef FS_STRERROR
7 7u83 357
    CStringP message = strerror(errno);
2 7u83 358
# else
359
    CStringP message;
360
 
361
    if ((errno >= 0) && (errno < sys_nerr)) {
7 7u83 362
	message = sys_errlist[errno];
2 7u83 363
    } else {
364
	message = "unknown error";
365
    }
366
# endif /* defined (FS_STRERROR) */
7 7u83 367
    write_cstring(ostream, message);
2 7u83 368
#else
7 7u83 369
    write_cstring(ostream, "error ");
370
    write_int(ostream, errno);
2 7u83 371
#endif /* (defined (FS_STRERROR) || defined (FS_SYS_ERRLIST)) */
372
}
373
 
374
void
7 7u83 375
write_pointer(OStreamP ostream,		       GenericP pointer)
2 7u83 376
{
7 7u83 377
   (void)fprintf(ostream->file, "%p", pointer);
378
    OSTREAM_WRITE_ERROR_CHECK(ostream);
2 7u83 379
}