Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/fstream.cfa

    rba0d2ea r52e311a  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 29 22:34:10 2021
    13 // Update Count     : 454
     12// Last Modified On : Sun Oct 10 11:23:05 2021
     13// Update Count     : 512
    1414//
    1515
     
    2828#define IO_MSG "I/O error: "
    2929
    30 void ?{}( ofstream & os, void * file ) {
    31         os.file$ = file;
    32         os.sepDefault$ = true;
    33         os.sepOnOff$ = false;
    34         os.nlOnOff$ = true;
    35         os.prt$ = false;
    36         os.sawNL$ = false;
    37         os.acquired$ = false;
     30// private
     31void ?{}( ofstream & os, void * file ) with( os ) {
     32        file$ = file;
     33        sepDefault$ = true;
     34        sepOnOff$ = false;
     35        nlOnOff$ = true;
     36        prt$ = false;
     37        sawNL$ = false;
    3838        sepSetCur$( os, sepGet( os ) );
    3939        sepSet( os, " " );
     
    4141} // ?{}
    4242
    43 // private
    44 bool sepPrt$( ofstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
    45 void sepReset$( ofstream & os ) { os.sepOnOff$ = os.sepDefault$; }
    46 void sepReset$( ofstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
    47 const char * sepGetCur$( ofstream & os ) { return os.sepCur$; }
    48 void sepSetCur$( ofstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
    49 bool getNL$( ofstream & os ) { return os.sawNL$; }
    50 void setNL$( ofstream & os, bool state ) { os.sawNL$ = state; }
    51 bool getANL$( ofstream & os ) { return os.nlOnOff$; }
    52 bool getPrt$( ofstream & os ) { return os.prt$; }
    53 void setPrt$( ofstream & os, bool state ) { os.prt$ = state; }
     43inline bool sepPrt$( ofstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
     44inline void sepReset$( ofstream & os ) { os.sepOnOff$ = os.sepDefault$; }
     45inline void sepReset$( ofstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
     46inline const char * sepGetCur$( ofstream & os ) { return os.sepCur$; }
     47inline void sepSetCur$( ofstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
     48inline bool getNL$( ofstream & os ) { return os.sawNL$; }
     49inline void setNL$( ofstream & os, bool state ) { os.sawNL$ = state; }
     50inline bool getANL$( ofstream & os ) { return os.nlOnOff$; }
     51inline bool getPrt$( ofstream & os ) { return os.prt$; }
     52inline void setPrt$( ofstream & os, bool state ) { os.prt$ = state; }
     53
     54inline void lock( ofstream & os ) with( os ) {  lock( os.lock$ ); }
     55inline void unlock( ofstream & os ) { unlock( os.lock$ ); }
    5456
    5557// public
    5658void ?{}( ofstream & os ) { os.file$ = 0p; }
    57 
    58 void ?{}( ofstream & os, const char name[], const char mode[] ) {
    59         open( os, name, mode );
    60 } // ?{}
    61 
    62 void ?{}( ofstream & os, const char name[] ) {
    63         open( os, name, "w" );
    64 } // ?{}
    65 
    66 void ^?{}( ofstream & os ) {
    67         close( os );
    68 } // ^?{}
     59void ?{}( ofstream & os, const char name[], const char mode[] ) { open( os, name, mode ); }
     60void ?{}( ofstream & os, const char name[] ) { open( os, name, "w" ); }
     61void ^?{}( ofstream & os ) { close( os ); }
    6962
    7063void sepOn( ofstream & os ) { os.sepOnOff$ = ! getNL$( os ); }
     
    107100        if ( &os == &exit ) exit( EXIT_FAILURE );
    108101        if ( &os == &abort ) abort();
    109         if ( os.acquired$ ) { os.acquired$ = false; release( os ); }
    110102} // ends
    111103
    112 bool fail( ofstream & os ) {
    113         return os.file$ == 0 || ferror( (FILE *)(os.file$) );
    114 } // fail
    115 
    116 void clear( ofstream & os ) {
    117         clearerr( (FILE *)(os.file$) );
    118 } // clear
    119 
    120 int flush( ofstream & os ) {
    121         return fflush( (FILE *)(os.file$) );
    122 } // flush
     104bool fail( ofstream & os ) { return os.file$ == 0 || ferror( (FILE *)(os.file$) ); }
     105void clear( ofstream & os ) { clearerr( (FILE *)(os.file$) ); }
     106int flush( ofstream & os ) { return fflush( (FILE *)(os.file$) ); }
    123107
    124108void open( ofstream & os, const char name[], const char mode[] ) {
    125         FILE * file = fopen( name, mode );
    126         #ifdef __CFA_DEBUG__
     109        FILE * file;
     110    for ( cnt; 10 ) {
     111                errno = 0;
     112                file = fopen( name, mode );
     113          if ( file != 0p || errno != EINTR ) break;            // timer interrupt ?
     114          if ( cnt == 9 ) abort( "ofstream open EINTR spinning exceeded" );
     115    } // for
    127116        if ( file == 0p ) {
    128117                throw (Open_Failure){ os };
    129118                // abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
    130119        } // if
    131         #endif // __CFA_DEBUG__
    132         (os){ file };
     120        (os){ file };                                                                           // initialize
    133121} // open
    134122
    135 void open( ofstream & os, const char name[] ) {
    136         open( os, name, "w" );
    137 } // open
    138 
    139 void close( ofstream & os ) {
    140   if ( (FILE *)(os.file$) == 0p ) return;
    141   if ( (FILE *)(os.file$) == (FILE *)stdout || (FILE *)(os.file$) == (FILE *)stderr ) return;
    142 
    143         if ( fclose( (FILE *)(os.file$) ) == EOF ) {
     123void open( ofstream & os, const char name[] ) { open( os, name, "w" ); }
     124
     125void close( ofstream & os ) with( os ) {
     126  if ( (FILE *)(file$) == 0p ) return;
     127  if ( (FILE *)(file$) == (FILE *)stdout || (FILE *)(file$) == (FILE *)stderr ) return;
     128
     129        int ret;
     130    for ( cnt; 10 ) {
     131                errno = 0;
     132                ret = fclose( (FILE *)(file$) );
     133          if ( ret != EOF || errno != EINTR ) break;            // timer interrupt ?
     134          if ( cnt == 9 ) abort( "ofstream open EINTR spinning exceeded" );
     135    } // for
     136        if ( ret == EOF ) {
    144137                throw (Close_Failure){ os };
    145138                // abort | IO_MSG "close output" | nl | strerror( errno );
    146139        } // if
    147         os.file$ = 0p;
     140        file$ = 0p;                                                                                     // safety after close
    148141} // close
    149142
     
    164157        va_list args;
    165158        va_start( args, format );
    166         int len = vfprintf( (FILE *)(os.file$), format, args );
     159               
     160        int len;
     161    for ( cnt; 10 ) {
     162                errno = 0;
     163                len = vfprintf( (FILE *)(os.file$), format, args );
     164          if ( len != EOF || errno != EINTR ) break;            // timer interrupt ?
     165          if ( cnt == 9 ) abort( "ofstream fmt EINTR spinning exceeded" );
     166    } // for
    167167        if ( len == EOF ) {
    168168                if ( ferror( (FILE *)(os.file$) ) ) {
     
    177177} // fmt
    178178
    179 inline void acquire( ofstream & os ) {
    180         lock( os.lock$ );
    181         if ( ! os.acquired$ ) os.acquired$ = true;
    182         else unlock( os.lock$ );
    183 } // acquire
    184 
    185 inline void release( ofstream & os ) {
    186         unlock( os.lock$ );
    187 } // release
    188 
    189 void ?{}( osacquire & acq, ofstream & os ) { &acq.os = &os; lock( os.lock$ ); }
    190 void ^?{}( osacquire & acq ) { release( acq.os ); }
    191 
    192179static ofstream soutFile = { (FILE *)stdout };
    193180ofstream & sout = soutFile, & stdout = soutFile;
     
    207194        flush( os );
    208195        return os;
    209         // (ofstream &)(os | '\n');
    210         // setPrt$( os, false );                                                        // turn off
    211         // setNL$( os, true );
    212         // flush( os );
    213         // return sepOff( os );                                                 // prepare for next line
    214196} // nl
    215197
     
    219201
    220202// private
    221 void ?{}( ifstream & is, void * file ) {
    222         is.file$ = file;
    223         is.nlOnOff$ = false;
    224         is.acquired$ = false;
    225 } // ?{}
     203void ?{}( ifstream & is, void * file ) with( is ) {
     204        file$ = file;
     205        nlOnOff$ = false;
     206} // ?{}
     207
     208bool getANL$( ifstream & os ) { return os.nlOnOff$; }
     209
     210inline void lock( ifstream & os ) with( os ) { lock( os.lock$ ); }
     211inline void unlock( ifstream & os ) { unlock( os.lock$ ); }
    226212
    227213// public
    228214void ?{}( ifstream & is ) { is.file$ = 0p; }
    229 
    230 void ?{}( ifstream & is, const char name[], const char mode[] ) {
    231         open( is, name, mode );
    232 } // ?{}
    233 
    234 void ?{}( ifstream & is, const char name[] ) {
    235         open( is, name, "r" );
    236 } // ?{}
    237 
    238 void ^?{}( ifstream & is ) {
    239         close( is );
    240 } // ^?{}
     215void ?{}( ifstream & is, const char name[], const char mode[] ) { open( is, name, mode ); }
     216void ?{}( ifstream & is, const char name[] ) { open( is, name, "r" ); }
     217void ^?{}( ifstream & is ) { close( is ); }
     218
     219bool fail( ifstream & is ) { return is.file$ == 0p || ferror( (FILE *)(is.file$) ); }
     220void clear( ifstream & is ) { clearerr( (FILE *)(is.file$) ); }
    241221
    242222void nlOn( ifstream & os ) { os.nlOnOff$ = true; }
    243223void nlOff( ifstream & os ) { os.nlOnOff$ = false; }
    244 bool getANL( ifstream & os ) { return os.nlOnOff$; }
    245 
    246 bool fail( ifstream & is ) {
    247         return is.file$ == 0p || ferror( (FILE *)(is.file$) );
    248 } // fail
    249 
    250 void clear( ifstream & is ) {
    251         clearerr( (FILE *)(is.file$) );
    252 } // clear
    253 
    254 void ends( ifstream & is ) {
    255         if ( is.acquired$ ) { is.acquired$ = false; release( is ); }
    256 } // ends
    257 
    258 bool eof( ifstream & is ) {
    259         return feof( (FILE *)(is.file$) );
    260 } // eof
     224
     225void ends( ifstream & is ) {}
     226
     227bool eof( ifstream & is ) { return feof( (FILE *)(is.file$) ) != 0; }
    261228
    262229void open( ifstream & is, const char name[], const char mode[] ) {
    263         FILE * file = fopen( name, mode );
    264         #ifdef __CFA_DEBUG__
     230        FILE * file;
     231    for ( cnt; 10 ) {
     232                errno = 0;
     233                file = fopen( name, mode );
     234          if ( file != 0p || errno != EINTR ) break;            // timer interrupt ?
     235          if ( cnt == 9 ) abort( "ifstream open EINTR spinning exceeded" );
     236    } // for
    265237        if ( file == 0p ) {
    266238                throw (Open_Failure){ is };
    267239                // abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
    268240        } // if
    269         #endif // __CFA_DEBUG__
    270         is.file$ = file;
     241        (is){ file };                                                                           // initialize
    271242} // open
    272243
    273 void open( ifstream & is, const char name[] ) {
    274         open( is, name, "r" );
    275 } // open
    276 
    277 void close( ifstream & is ) {
    278   if ( (FILE *)(is.file$) == 0p ) return;
    279   if ( (FILE *)(is.file$) == (FILE *)stdin ) return;
    280 
    281         if ( fclose( (FILE *)(is.file$) ) == EOF ) {
     244void open( ifstream & is, const char name[] ) { open( is, name, "r" ); }
     245
     246void close( ifstream & is ) with( is ) {
     247  if ( (FILE *)(file$) == 0p ) return;
     248  if ( (FILE *)(file$) == (FILE *)stdin ) return;
     249
     250        int ret;
     251    for ( cnt; 10 ) {
     252                errno = 0;
     253                ret = fclose( (FILE *)(file$) );
     254          if ( ret != EOF || errno != EINTR ) break;            // timer interrupt ?
     255          if ( cnt == 9 ) abort( "ifstream close EINTR spinning exceeded" );
     256    } // for
     257        if ( ret == EOF ) {
    282258                throw (Close_Failure){ is };
    283259                // abort | IO_MSG "close input" | nl | strerror( errno );
    284260        } // if
    285         is.file$ = 0p;
     261        file$ = 0p;                                                                                     // safety after close
    286262} // close
    287263
     
    312288int fmt( ifstream & is, const char format[], ... ) {
    313289        va_list args;
    314 
    315290        va_start( args, format );
    316         int len = vfscanf( (FILE *)(is.file$), format, args );
     291
     292        int len;
     293    for () {                                                                                    // no check for EINTR limit waiting for keyboard input
     294                errno = 0;
     295                len = vfscanf( (FILE *)(is.file$), format, args );
     296          if ( len != EOF || errno != EINTR ) break;            // timer interrupt ?
     297    } // for
    317298        if ( len == EOF ) {
    318299                if ( ferror( (FILE *)(is.file$) ) ) {
     
    324305} // fmt
    325306
    326 inline void acquire( ifstream & is ) {
    327         lock( is.lock$ );
    328         if ( ! is.acquired$ ) is.acquired$ = true;
    329         else unlock( is.lock$ );
    330 } // acquire
    331 
    332 inline void release( ifstream & is ) {
    333         unlock( is.lock$ );
    334 } // release
    335 
    336 void ?{}( isacquire & acq, ifstream & is ) { &acq.is = &is; lock( is.lock$ ); }
    337 void ^?{}( isacquire & acq ) { release( acq.is ); }
    338 
    339307static ifstream sinFile = { (FILE *)stdin };
    340308ifstream & sin = sinFile, & stdin = sinFile;
     
    347315
    348316// exception I/O constructors
    349 void ?{}( Open_Failure & this, ofstream & ostream ) {
    350         this.virtual_table = &Open_Failure_vt;
    351         this.ostream = &ostream;
    352         this.tag = 1;
    353 } // ?{}
    354 
    355 void ?{}( Open_Failure & this, ifstream & istream ) {
    356         this.virtual_table = &Open_Failure_vt;
    357         this.istream = &istream;
    358         this.tag = 0;
     317void ?{}( Open_Failure & ex, ofstream & ostream ) with(ex) {
     318        virtual_table = &Open_Failure_vt;
     319        ostream = &ostream;
     320        tag = 1;
     321} // ?{}
     322
     323void ?{}( Open_Failure & ex, ifstream & istream ) with(ex) {
     324        virtual_table = &Open_Failure_vt;
     325        istream = &istream;
     326        tag = 0;
    359327} // ?{}
    360328
     
    363331
    364332// exception I/O constructors
    365 void ?{}( Close_Failure & this, ofstream & ostream ) {
    366         this.virtual_table = &Close_Failure_vt;
    367         this.ostream = &ostream;
    368         this.tag = 1;
    369 } // ?{}
    370 
    371 void ?{}( Close_Failure & this, ifstream & istream ) {
    372         this.virtual_table = &Close_Failure_vt;
    373         this.istream = &istream;
    374         this.tag = 0;
     333void ?{}( Close_Failure & ex, ofstream & ostream ) with(ex) {
     334        virtual_table = &Close_Failure_vt;
     335        ostream = &ostream;
     336        tag = 1;
     337} // ?{}
     338
     339void ?{}( Close_Failure & ex, ifstream & istream ) with(ex) {
     340        virtual_table = &Close_Failure_vt;
     341        istream = &istream;
     342        tag = 0;
    375343} // ?{}
    376344
     
    379347
    380348// exception I/O constructors
    381 void ?{}( Write_Failure & this, ofstream & ostream ) {
    382         this.virtual_table = &Write_Failure_vt;
    383         this.ostream = &ostream;
    384         this.tag = 1;
    385 } // ?{}
    386 
    387 void ?{}( Write_Failure & this, ifstream & istream ) {
    388         this.virtual_table = &Write_Failure_vt;
    389         this.istream = &istream;
    390         this.tag = 0;
     349void ?{}( Write_Failure & ex, ofstream & ostream ) with(ex) {
     350        virtual_table = &Write_Failure_vt;
     351        ostream = &ostream;
     352        tag = 1;
     353} // ?{}
     354
     355void ?{}( Write_Failure & ex, ifstream & istream ) with(ex) {
     356        virtual_table = &Write_Failure_vt;
     357        istream = &istream;
     358        tag = 0;
    391359} // ?{}
    392360
     
    395363
    396364// exception I/O constructors
    397 void ?{}( Read_Failure & this, ofstream & ostream ) {
    398         this.virtual_table = &Read_Failure_vt;
    399         this.ostream = &ostream;
    400         this.tag = 1;
    401 } // ?{}
    402 
    403 void ?{}( Read_Failure & this, ifstream & istream ) {
    404         this.virtual_table = &Read_Failure_vt;
    405         this.istream = &istream;
    406         this.tag = 0;
     365void ?{}( Read_Failure & ex, ofstream & ostream ) with(ex) {
     366        virtual_table = &Read_Failure_vt;
     367        ostream = &ostream;
     368        tag = 1;
     369} // ?{}
     370
     371void ?{}( Read_Failure & ex, ifstream & istream ) with(ex) {
     372        virtual_table = &Read_Failure_vt;
     373        istream = &istream;
     374        tag = 0;
    407375} // ?{}
    408376
Note: See TracChangeset for help on using the changeset viewer.