source: libcfa/src/iostream.cfa@ c671112

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since c671112 was 3c5dee4, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

change istype nl to ignore characters to newline, change ostype to print a decimal point for floating points

  • Property mode set to 100644
File size: 16.4 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// iostream.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 : Mon May 13 12:46:45 2019
13// Update Count : 650
14//
15
16#include "iostream.hfa"
17
18extern "C" {
19#include <stdio.h>
20#include <stdbool.h> // true/false
21//#include <string.h> // strlen, strcmp
22extern int strcmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
23extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
24#include <float.h> // DBL_DIG, LDBL_DIG
25#include <math.h> // modff, modf, modlf
26#include <complex.h> // creal, cimag
27}
28
29forall( dtype ostype | ostream( ostype ) ) {
30 ostype & ?|?( ostype & os, zero_t ) {
31 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
32 fmt( os, "%d", 0n );
33 return os;
34 } // ?|?
35 void ?|?( ostype & os, zero_t z ) {
36 (ostype &)(os | z); nl( os );
37 } // ?|?
38
39 ostype & ?|?( ostype & os, one_t ) {
40 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
41 fmt( os, "%d", 1n );
42 return os;
43 } // ?|?
44 void ?|?( ostype & os, one_t o ) {
45 (ostype &)(os | o); nl( os );
46 } // ?|?
47
48 ostype & ?|?( ostype & os, bool b ) {
49 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
50 fmt( os, "%s", b ? "true" : "false" );
51 return os;
52 } // ?|?
53 void ?|?( ostype & os, bool b ) {
54 (ostype &)(os | b); nl( os );
55 } // ?|?
56
57 ostype & ?|?( ostype & os, char c ) {
58 fmt( os, "%c", c );
59 if ( c == '\n' ) setNL( os, true );
60 return sepOff( os );
61 } // ?|?
62 void ?|?( ostype & os, char c ) {
63 (ostype &)(os | c); nl( os );
64 } // ?|?
65
66 ostype & ?|?( ostype & os, signed char sc ) {
67 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
68 fmt( os, "%hhd", sc );
69 return os;
70 } // ?|?
71 void ?|?( ostype & os, signed char sc ) {
72 (ostype &)(os | sc); nl( os );
73 } // ?|?
74
75 ostype & ?|?( ostype & os, unsigned char usc ) {
76 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
77 fmt( os, "%hhu", usc );
78 return os;
79 } // ?|?
80 void ?|?( ostype & os, unsigned char usc ) {
81 (ostype &)(os | usc); nl( os );
82 } // ?|?
83
84 ostype & ?|?( ostype & os, short int si ) {
85 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
86 fmt( os, "%hd", si );
87 return os;
88 } // ?|?
89 void & ?|?( ostype & os, short int si ) {
90 (ostype &)(os | si); nl( os );
91 } // ?|?
92
93 ostype & ?|?( ostype & os, unsigned short int usi ) {
94 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
95 fmt( os, "%hu", usi );
96 return os;
97 } // ?|?
98 void & ?|?( ostype & os, unsigned short int usi ) {
99 (ostype &)(os | usi); nl( os );
100 } // ?|?
101
102 ostype & ?|?( ostype & os, int i ) {
103 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
104 fmt( os, "%d", i );
105 return os;
106 } // ?|?
107 void & ?|?( ostype & os, int i ) {
108 (ostype &)(os | i); nl( os );
109 } // ?|?
110
111 ostype & ?|?( ostype & os, unsigned int ui ) {
112 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
113 fmt( os, "%u", ui );
114 return os;
115 } // ?|?
116 void & ?|?( ostype & os, unsigned int ui ) {
117 (ostype &)(os | ui); nl( os );
118 } // ?|?
119
120 ostype & ?|?( ostype & os, long int li ) {
121 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
122 fmt( os, "%ld", li );
123 return os;
124 } // ?|?
125 void & ?|?( ostype & os, long int li ) {
126 (ostype &)(os | li); nl( os );
127 } // ?|?
128
129 ostype & ?|?( ostype & os, unsigned long int uli ) {
130 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
131 fmt( os, "%lu", uli );
132 return os;
133 } // ?|?
134 void & ?|?( ostype & os, unsigned long int uli ) {
135 (ostype &)(os | uli); nl( os );
136 } // ?|?
137
138 ostype & ?|?( ostype & os, long long int lli ) {
139 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
140 fmt( os, "%lld", lli );
141 return os;
142 } // ?|?
143 void & ?|?( ostype & os, long long int lli ) {
144 (ostype &)(os | lli); nl( os );
145 } // ?|?
146
147 ostype & ?|?( ostype & os, unsigned long long int ulli ) {
148 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
149 fmt( os, "%llu", ulli );
150 return os;
151 } // ?|?
152 void & ?|?( ostype & os, unsigned long long int ulli ) {
153 (ostype &)(os | ulli); nl( os );
154 } // ?|?
155
156 ostype & ?|?( ostype & os, float f ) {
157 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
158 fmt( os, "%g", f );
159 float tempi;
160 if ( isfinite( f ) && modff( f, &tempi ) == 0.0F ) fmt( os, "." ); // always print decimal point
161 return os;
162 } // ?|?
163 void & ?|?( ostype & os, float f ) {
164 (ostype &)(os | f); nl( os );
165 } // ?|?
166
167 ostype & ?|?( ostype & os, double d ) {
168 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
169 fmt( os, "%.*lg", DBL_DIG, d );
170 // fmt( os, "%lg", d );
171 double tempi;
172 if ( isfinite( d ) && modf( d, &tempi ) == 0.0D ) fmt( os, "." ); // always print decimal point
173 return os;
174 } // ?|?
175 void & ?|?( ostype & os, double d ) {
176 (ostype &)(os | d); nl( os );
177 } // ?|?
178
179 ostype & ?|?( ostype & os, long double ld ) {
180 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
181 fmt( os, "%.*Lg", LDBL_DIG, ld );
182 // fmt( os, "%Lg", ld );
183 long double tempi;
184 if ( isfinite( ld ) && modfl( ld, &tempi ) == 0.0L ) fmt( os, "." ); // always print decimal point
185 return os;
186 } // ?|?
187 void & ?|?( ostype & os, long double ld ) {
188 (ostype &)(os | ld); nl( os );
189 } // ?|?
190
191 ostype & ?|?( ostype & os, float _Complex fc ) {
192 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
193 float temp = crealf( fc ), tempi;
194 fmt( os, "%g", temp );
195 if ( isfinite( temp ) && modff( temp, &tempi ) == 0.0F ) fmt( os, "." ); // always print decimal point
196 temp = cimagf( fc );
197 fmt( os, "%+g", temp );
198 if ( isfinite( temp ) && modff( temp, &tempi ) == 0.0F ) fmt( os, "." ); // always print decimal point
199 fmt( os, "i" );
200 return os;
201 } // ?|?
202 void & ?|?( ostype & os, float _Complex fc ) {
203 (ostype &)(os | fc); nl( os );
204 } // ?|?
205
206 ostype & ?|?( ostype & os, double _Complex dc ) {
207 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
208 double temp = creal( dc ), tempi;
209 fmt( os, "%.*lg", DBL_DIG, temp );
210 if ( isfinite( temp ) && modf( temp, &tempi ) == 0.0D ) fmt( os, "." ); // always print decimal point
211 temp = cimag( dc );
212 fmt( os, "%+.*lg", DBL_DIG, temp );
213 if ( isfinite( temp ) && modf( temp, &tempi ) == 0.0D ) fmt( os, "." ); // always print decimal point
214 fmt( os, "i" );
215 // fmt( os, "%lg%+lgi", creal( dc ), cimag( dc ) );
216 return os;
217 } // ?|?
218 void & ?|?( ostype & os, double _Complex dc ) {
219 (ostype &)(os | dc); nl( os );
220 } // ?|?
221
222 ostype & ?|?( ostype & os, long double _Complex ldc ) {
223 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
224 long double temp = creall( ldc ), tempi;
225 fmt( os, "%.*Lg", LDBL_DIG, temp );
226 if ( isfinite( temp ) && modfl( temp, &tempi ) == 0.0L ) fmt( os, "." ); // always print decimal point
227 temp = cimagl( ldc );
228 fmt( os, "%+.*Lg", LDBL_DIG, cimagl( ldc ) );
229 if ( isfinite( temp ) && modfl( temp, &tempi ) == 0.0L ) fmt( os, "." ); // always print decimal point
230 fmt( os, "i" );
231 // fmt( os, "%Lg%+Lgi", creall( ldc ), cimagl( ldc ) );
232 return os;
233 } // ?|?
234 void & ?|?( ostype & os, long double _Complex ldc ) {
235 (ostype &)(os | ldc); nl( os );
236 } // ?|?
237
238 ostype & ?|?( ostype & os, const char * str ) {
239 enum { Open = 1, Close, OpenClose };
240 static const unsigned char mask[256] @= {
241 // opening delimiters, no space after
242 ['('] : Open, ['['] : Open, ['{'] : Open,
243 ['='] : Open, ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open,
244 [(unsigned char)'¡'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
245 // closing delimiters, no space before
246 [','] : Close, ['.'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
247 ['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
248 [')'] : Close, [']'] : Close, ['}'] : Close,
249 // opening-closing delimiters, no space before or after
250 ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, [':'] : OpenClose,
251 [' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
252 }; // mask
253
254 if ( str[0] == '\0' ) { sepOff( os ); return os; } // null string => no separator
255
256 // first character IS NOT spacing or closing punctuation => add left separator
257 unsigned char ch = str[0]; // must make unsigned
258 if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
259 fmt( os, "%s", sepGetCur( os ) );
260 } // if
261
262 // if string starts line, must reset to determine open state because separator is off
263 sepReset( os ); // reset separator
264
265 // last character IS spacing or opening punctuation => turn off separator for next item
266 size_t len = strlen( str );
267 ch = str[len - 1]; // must make unsigned
268 if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
269 sepOn( os );
270 } else {
271 sepOff( os );
272 } // if
273 if ( ch == '\n' ) setNL( os, true ); // check *AFTER* sepPrt call above as it resets NL flag
274 return write( os, str, len );
275 } // ?|?
276 void ?|?( ostype & os, const char * str ) {
277 (ostype &)(os | str); nl( os );
278 } // ?|?
279
280// ostype & ?|?( ostype & os, const char16_t * str ) {
281// if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
282// fmt( os, "%ls", str );
283// return os;
284// } // ?|?
285
286// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
287// ostype & ?|?( ostype & os, const char32_t * str ) {
288// if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
289// fmt( os, "%ls", str );
290// return os;
291// } // ?|?
292// #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
293
294// ostype & ?|?( ostype & os, const wchar_t * str ) {
295// if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
296// fmt( os, "%ls", str );
297// return os;
298// } // ?|?
299
300 ostype & ?|?( ostype & os, const void * p ) {
301 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
302 fmt( os, "%p", p );
303 return os;
304 } // ?|?
305 void ?|?( ostype & os, const void * p ) {
306 (ostype &)(os | p); nl( os );
307 } // ?|?
308
309 // manipulators
310 ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
311 (ostype &)(manip( os ));
312 return os;
313 } // ?|?
314 void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
315 (ostype &)(manip( os ));
316 if ( getPrt( os ) ) nl( os ); // something printed ?
317 setPrt( os, false ); // turn off
318 } // ?|?
319
320 ostype & sep( ostype & os ) {
321 return (ostype &)(os | sepGet( os ));
322 } // sep
323
324 ostype & sepTuple( ostype & os ) {
325 return os | sepGetTuple( os );
326 } // sepTuple
327
328 ostype & nl( ostype & os ) {
329 (ostype &)(os | '\n');
330 setPrt( os, false ); // turn off
331 setNL( os, true );
332 flush( os );
333 return sepOff( os ); // prepare for next line
334 } // nl
335
336 void nl( ostype & os ) {
337 if ( getANL( os ) ) (ostype &)(nl( os )); // implementation only
338 else setPrt( os, false ); // turn off
339 } // nl
340
341 ostype & nonl( ostype & os ) {
342 setPrt( os, false ); // turn off
343 return os;
344 } // nonl
345
346 ostype & sepOn( ostype & os ) {
347 sepOn( os ); // call void returning
348 return os;
349 } // sepOn
350
351 ostype & sepOff( ostype & os ) {
352 sepOff( os ); // call void returning
353 return os;
354 } // sepOff
355
356 ostype & sepEnable( ostype & os ) {
357 sepEnable( os ); // call void returning
358 return os;
359 } // sepEnable
360
361 ostype & sepDisable( ostype & os ) {
362 sepDisable( os ); // call void returning
363 return os;
364 } // sepDisable
365
366 ostype & nlOn( ostype & os ) {
367 nlOn( os ); // call void returning
368 return os;
369 } // nlOn
370
371 ostype & nlOff( ostype & os ) {
372 nlOff( os ); // call void returning
373 return os;
374 } // nlOff
375} // distribution
376
377// tuples
378forall( dtype ostype, otype T, ttype Params | writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } ) {
379 ostype & ?|?( ostype & os, T arg, Params rest ) {
380 (ostype &)(os | arg); // print first argument
381 sepSetCur( os, sepGetTuple( os ) ); // switch to tuple separator
382 (ostype &)(os | rest); // print remaining arguments
383 sepSetCur( os, sepGet( os ) ); // switch to regular separator
384 return os;
385 } // ?|?
386 void ?|?( ostype & os, T arg, Params rest ) {
387 // (ostype &)(?|?( os, arg, rest )); nl( os );
388 (ostype &)(os | arg); // print first argument
389 sepSetCur( os, sepGetTuple( os ) ); // switch to tuple separator
390 (ostype &)(os | rest); // print remaining arguments
391 sepSetCur( os, sepGet( os ) ); // switch to regular separator
392 nl( os );
393 } // ?|?
394} // distribution
395
396//---------------------------------------
397
398// writes the range [begin, end) to the given stream
399forall( dtype ostype, otype elt_type | writeable( elt_type, ostype ), otype iterator_type | iterator( iterator_type, elt_type ) ) {
400 void write( iterator_type begin, iterator_type end, ostype & os ) {
401 void print( elt_type i ) { os | i; }
402 for_each( begin, end, print );
403 } // ?|?
404
405 void write_reverse( iterator_type begin, iterator_type end, ostype & os ) {
406 void print( elt_type i ) { os | i; }
407 for_each_reverse( begin, end, print );
408 } // ?|?
409} // distribution
410
411//---------------------------------------
412
413forall( dtype istype | istream( istype ) ) {
414 istype & ?|?( istype & is, bool & b ) {
415 char val[6];
416 fmt( is, "%5s", val );
417 if ( strcmp( val, "true" ) == 0 ) b = true;
418 else if ( strcmp( val, "false" ) == 0 ) b = false;
419 else {
420 fprintf( stderr, "invalid Boolean constant\n" );
421 abort();
422 } // if
423 return is;
424 } // ?|?
425
426 istype & ?|?( istype & is, char & c ) {
427 char temp;
428 for () {
429 fmt( is, "%c", &temp ); // must pass pointer through varg to fmt
430 // do not overwrite parameter with newline unless appropriate
431 if ( temp != '\n' || getANL( is ) ) { c = temp; break; }
432 if ( eof( is ) ) break;
433 } // for
434 return is;
435 } // ?|?
436
437 istype & ?|?( istype & is, signed char & sc ) {
438 fmt( is, "%hhd", &sc );
439 return is;
440 } // ?|?
441
442 istype & ?|?( istype & is, unsigned char & usc ) {
443 fmt( is, "%hhu", &usc );
444 return is;
445 } // ?|?
446
447 istype & ?|?( istype & is, short int & si ) {
448 fmt( is, "%hd", &si );
449 return is;
450 } // ?|?
451
452 istype & ?|?( istype & is, unsigned short int & usi ) {
453 fmt( is, "%hu", &usi );
454 return is;
455 } // ?|?
456
457 istype & ?|?( istype & is, int & i ) {
458 fmt( is, "%d", &i );
459 return is;
460 } // ?|?
461
462 istype & ?|?( istype & is, unsigned int & ui ) {
463 fmt( is, "%u", &ui );
464 return is;
465 } // ?|?
466
467 istype & ?|?( istype & is, long int & li ) {
468 fmt( is, "%ld", &li );
469 return is;
470 } // ?|?
471
472 istype & ?|?( istype & is, unsigned long int & ulli ) {
473 fmt( is, "%lu", &ulli );
474 return is;
475 } // ?|?
476
477 istype & ?|?( istype & is, long long int & lli ) {
478 fmt( is, "%lld", &lli );
479 return is;
480 } // ?|?
481
482 istype & ?|?( istype & is, unsigned long long int & ulli ) {
483 fmt( is, "%llu", &ulli );
484 return is;
485 } // ?|?
486
487
488 istype & ?|?( istype & is, float & f ) {
489 fmt( is, "%f", &f );
490 return is;
491 } // ?|?
492
493 istype & ?|?( istype & is, double & d ) {
494 fmt( is, "%lf", &d );
495 return is;
496 } // ?|?
497
498 istype & ?|?( istype & is, long double & ld ) {
499 fmt( is, "%Lf", &ld );
500 return is;
501 } // ?|?
502
503
504 istype & ?|?( istype & is, float _Complex & fc ) {
505 float re, im;
506 fmt( is, "%g%gi", &re, &im );
507 fc = re + im * _Complex_I;
508 return is;
509 } // ?|?
510
511 istype & ?|?( istype & is, double _Complex & dc ) {
512 double re, im;
513 fmt( is, "%lf%lfi", &re, &im );
514 dc = re + im * _Complex_I;
515 return is;
516 } // ?|?
517
518 istype & ?|?( istype & is, long double _Complex & ldc ) {
519 long double re, im;
520 fmt( is, "%Lf%Lfi", &re, &im );
521 ldc = re + im * _Complex_I;
522 return is;
523 } // ?|?
524
525 // manipulators
526 istype & ?|?( istype & is, istype & (* manip)( istype & ) ) {
527 return manip( is );
528 } // ?|?
529
530 istype & nl( istype & is ) {
531 fmt( is, "%*[^\n]" ); // ignore characters to newline
532 return is;
533 } // nl
534
535 istype & nlOn( istype & is ) {
536 nlOn( is ); // call void returning
537 return is;
538 } // nlOn
539
540 istype & nlOff( istype & is ) {
541 nlOff( is ); // call void returning
542 return is;
543 } // nlOff
544} // distribution
545
546_Istream_cstrUC cstr( char * str ) { return (_Istream_cstrUC){ str }; }
547forall( dtype istype | istream( istype ) )
548istype & ?|?( istype & is, _Istream_cstrUC cstr ) {
549 fmt( is, "%s", cstr.s );
550 return is;
551} // cstr
552
553_Istream_cstrC cstr( char * str, int size ) { return (_Istream_cstrC){ str, size }; }
554forall( dtype istype | istream( istype ) )
555istype & ?|?( istype & is, _Istream_cstrC cstr ) {
556 char buf[16];
557 sprintf( buf, "%%%ds", cstr.size );
558 fmt( is, buf, cstr.s );
559 return is;
560} // cstr
561
562// Local Variables: //
563// tab-width: 4 //
564// compile-command: "cfa iostream.cfa" //
565// End: //
Note: See TracBrowser for help on using the repository browser.