source: libcfa/src/fstream.cfa@ 7ee8153

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 7ee8153 was 8d321f9, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

adjust / comments, change exception name from IO_OPEN_FAILURE to Open_Failure, add temporary Open_Failure tag in lieu of polymorphic exceptions

  • Property mode set to 100644
File size: 8.2 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// fstream.c --
8//
9// Author : Peter A. Buhr
10// Created On : Wed May 27 17:56:53 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Jun 19 16:24:54 2020
13// Update Count : 384
14//
15
16#include "fstream.hfa"
17
18#include <stdio.h> // vfprintf, vfscanf
19#include <stdlib.h> // exit
20#include <stdarg.h> // varargs
21#include <string.h> // strlen
22#include <float.h> // DBL_DIG, LDBL_DIG
23#include <complex.h> // creal, cimag
24#include <assert.h>
25#include <errno.h> // errno
26
27
28// *********************************** ofstream ***********************************
29
30
31#define IO_MSG "I/O error: "
32
33void ?{}( ofstream & os, void * file ) {
34 os.$file = file;
35 os.$sepDefault = true;
36 os.$sepOnOff = false;
37 os.$nlOnOff = true;
38 os.$prt = false;
39 os.$sawNL = false;
40 $sepSetCur( os, sepGet( os ) );
41 sepSet( os, " " );
42 sepSetTuple( os, ", " );
43} // ?{}
44
45// private
46bool $sepPrt( ofstream & os ) { $setNL( os, false ); return os.$sepOnOff; }
47void $sepReset( ofstream & os ) { os.$sepOnOff = os.$sepDefault; }
48void $sepReset( ofstream & os, bool reset ) { os.$sepDefault = reset; os.$sepOnOff = os.$sepDefault; }
49const char * $sepGetCur( ofstream & os ) { return os.$sepCur; }
50void $sepSetCur( ofstream & os, const char sepCur[] ) { os.$sepCur = sepCur; }
51bool $getNL( ofstream & os ) { return os.$sawNL; }
52void $setNL( ofstream & os, bool state ) { os.$sawNL = state; }
53bool $getANL( ofstream & os ) { return os.$nlOnOff; }
54bool $getPrt( ofstream & os ) { return os.$prt; }
55void $setPrt( ofstream & os, bool state ) { os.$prt = state; }
56
57// public
58void ?{}( ofstream & os ) { os.$file = 0p; }
59
60void ?{}( ofstream & os, const char name[], const char mode[] ) {
61 open( os, name, mode );
62} // ?{}
63
64void ?{}( ofstream & os, const char name[] ) {
65 open( os, name, "w" );
66} // ?{}
67
68void ^?{}( ofstream & os ) {
69 close( os );
70} // ^?{}
71
72void sepOn( ofstream & os ) { os.$sepOnOff = ! $getNL( os ); }
73void sepOff( ofstream & os ) { os.$sepOnOff = false; }
74
75bool sepDisable( ofstream & os ) {
76 bool temp = os.$sepDefault;
77 os.$sepDefault = false;
78 $sepReset( os );
79 return temp;
80} // sepDisable
81
82bool sepEnable( ofstream & os ) {
83 bool temp = os.$sepDefault;
84 os.$sepDefault = true;
85 if ( os.$sepOnOff ) $sepReset( os ); // start of line ?
86 return temp;
87} // sepEnable
88
89void nlOn( ofstream & os ) { os.$nlOnOff = true; }
90void nlOff( ofstream & os ) { os.$nlOnOff = false; }
91
92const char * sepGet( ofstream & os ) { return os.$separator; }
93void sepSet( ofstream & os, const char s[] ) {
94 assert( s );
95 strncpy( os.$separator, s, sepSize - 1 );
96 os.$separator[sepSize - 1] = '\0';
97} // sepSet
98
99const char * sepGetTuple( ofstream & os ) { return os.$tupleSeparator; }
100void sepSetTuple( ofstream & os, const char s[] ) {
101 assert( s );
102 strncpy( os.$tupleSeparator, s, sepSize - 1 );
103 os.$tupleSeparator[sepSize - 1] = '\0';
104} // sepSet
105
106void ends( ofstream & os ) {
107 if ( $getANL( os ) ) nl( os );
108 else $setPrt( os, false ); // turn off
109 if ( &os == &exit ) exit( EXIT_FAILURE );
110 if ( &os == &abort ) abort();
111} // ends
112
113int fail( ofstream & os ) {
114 return os.$file == 0 || ferror( (FILE *)(os.$file) );
115} // fail
116
117int flush( ofstream & os ) {
118 return fflush( (FILE *)(os.$file) );
119} // flush
120
121void open( ofstream & os, const char name[], const char mode[] ) {
122 FILE * file = fopen( name, mode );
123 #ifdef __CFA_DEBUG__
124 if ( file == 0p ) {
125 throw (Open_Failure){ os };
126 // abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
127 } // if
128 #endif // __CFA_DEBUG__
129 (os){ file };
130} // open
131
132void open( ofstream & os, const char name[] ) {
133 open( os, name, "w" );
134} // open
135
136void close( ofstream & os ) {
137 if ( (FILE *)(os.$file) == 0p ) return;
138 if ( (FILE *)(os.$file) == (FILE *)stdout || (FILE *)(os.$file) == (FILE *)stderr ) return;
139
140 if ( fclose( (FILE *)(os.$file) ) == EOF ) {
141 abort | IO_MSG "close output" | nl | strerror( errno );
142 } // if
143 os.$file = 0p;
144} // close
145
146ofstream & write( ofstream & os, const char data[], size_t size ) {
147 if ( fail( os ) ) {
148 abort | IO_MSG "attempt write I/O on failed stream";
149 } // if
150
151 if ( fwrite( data, 1, size, (FILE *)(os.$file) ) != size ) {
152 abort | IO_MSG "write" | nl | strerror( errno );
153 } // if
154 return os;
155} // write
156
157int fmt( ofstream & os, const char format[], ... ) {
158 va_list args;
159 va_start( args, format );
160 int len = vfprintf( (FILE *)(os.$file), format, args );
161 if ( len == EOF ) {
162 if ( ferror( (FILE *)(os.$file) ) ) {
163 abort | IO_MSG "invalid write";
164 } // if
165 } // if
166 va_end( args );
167
168 $setPrt( os, true ); // called in output cascade
169 $sepReset( os ); // reset separator
170 return len;
171} // fmt
172
173static ofstream soutFile = { (FILE *)stdout };
174ofstream & sout = soutFile, & stdout = soutFile;
175static ofstream serrFile = { (FILE *)stderr };
176ofstream & serr = serrFile, & stderr = serrFile;
177
178static ofstream exitFile = { (FILE *)stdout };
179ofstream & exit = exitFile;
180static ofstream abortFile = { (FILE *)stderr };
181ofstream & abort = abortFile;
182
183
184// *********************************** ifstream ***********************************
185
186
187// private
188void ?{}( ifstream & is, void * file ) {
189 is.$file = file;
190 is.$nlOnOff = false;
191} // ?{}
192
193// public
194void ?{}( ifstream & is ) { is.$file = 0p; }
195
196void ?{}( ifstream & is, const char name[], const char mode[] ) {
197 open( is, name, mode );
198} // ?{}
199
200void ?{}( ifstream & is, const char name[] ) {
201 open( is, name, "r" );
202} // ?{}
203
204void ^?{}( ifstream & is ) {
205 close( is );
206} // ^?{}
207
208void nlOn( ifstream & os ) { os.$nlOnOff = true; }
209void nlOff( ifstream & os ) { os.$nlOnOff = false; }
210bool getANL( ifstream & os ) { return os.$nlOnOff; }
211
212int fail( ifstream & is ) {
213 return is.$file == 0p || ferror( (FILE *)(is.$file) );
214} // fail
215
216int eof( ifstream & is ) {
217 return feof( (FILE *)(is.$file) );
218} // eof
219
220void open( ifstream & is, const char name[], const char mode[] ) {
221 FILE * file = fopen( name, mode );
222 #ifdef __CFA_DEBUG__
223 if ( file == 0p ) {
224 throw (Open_Failure){ is };
225 // abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
226 } // if
227 #endif // __CFA_DEBUG__
228 is.$file = file;
229} // open
230
231void open( ifstream & is, const char name[] ) {
232 open( is, name, "r" );
233} // open
234
235void close( ifstream & is ) {
236 if ( (FILE *)(is.$file) == 0p ) return;
237 if ( (FILE *)(is.$file) == (FILE *)stdin ) return;
238
239 if ( fclose( (FILE *)(is.$file) ) == EOF ) {
240 abort | IO_MSG "close input" | nl | strerror( errno );
241 } // if
242 is.$file = 0p;
243} // close
244
245ifstream & read( ifstream & is, char * data, size_t size ) {
246 if ( fail( is ) ) {
247 abort | IO_MSG "attempt read I/O on failed stream";
248 } // if
249
250 if ( fread( data, size, 1, (FILE *)(is.$file) ) == 0 ) {
251 abort | IO_MSG "read" | nl | strerror( errno );
252 } // if
253 return is;
254} // read
255
256ifstream &ungetc( ifstream & is, char c ) {
257 if ( fail( is ) ) {
258 abort | IO_MSG "attempt ungetc I/O on failed stream";
259 } // if
260
261 if ( ungetc( c, (FILE *)(is.$file) ) == EOF ) {
262 abort | IO_MSG "ungetc" | nl | strerror( errno );
263 } // if
264 return is;
265} // ungetc
266
267int fmt( ifstream & is, const char format[], ... ) {
268 va_list args;
269
270 va_start( args, format );
271 int len = vfscanf( (FILE *)(is.$file), format, args );
272 if ( len == EOF ) {
273 if ( ferror( (FILE *)(is.$file) ) ) {
274 abort | IO_MSG "invalid read";
275 } // if
276 } // if
277 va_end( args );
278 return len;
279} // fmt
280
281static ifstream sinFile = { (FILE *)stdin };
282ifstream & sin = sinFile, & stdin = sinFile;
283
284
285// *********************************** exceptions ***********************************
286
287
288void ?{}( Open_Failure & this, ofstream & ostream ) {
289 VTABLE_INIT(this, Open_Failure);
290 this.ostream = &ostream;
291 this.tag = 1;
292}
293void ?{}( Open_Failure & this, ifstream & istream ) {
294 VTABLE_INIT(this, Open_Failure);
295 this.istream = &istream;
296 this.tag = 0;
297}
298const char * Open_Failure_msg(Open_Failure * this) {
299 return "Open_Failure";
300}
301VTABLE_INSTANCE(Open_Failure)(Open_Failure_msg);
302void throwOpen_Failure( ofstream & ostream ) {
303 Open_Failure exc = { ostream };
304}
305void throwOpen_Failure( ifstream & istream ) {
306 Open_Failure exc = { istream };
307}
308
309// Local Variables: //
310// tab-width: 4 //
311// End: //
Note: See TracBrowser for help on using the repository browser.