Changeset e0dc038


Ignore:
Timestamp:
Oct 17, 2023, 9:32:34 PM (14 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
2d7cb19, f842032
Parents:
ca995e3
Message:

first attempt at new C string input

Location:
libcfa/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/fstream.cfa

    rca995e3 re0dc038  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 18 10:41:17 2023
    13 // Update Count     : 541
     12// Last Modified On : Tue Oct 17 08:38:49 2023
     13// Update Count     : 544
    1414//
    1515
     
    311311        } // if
    312312        va_end( args );
     313//      if ( len == 0 ) throw ExceptionInst( missing_data );
    313314        return len;
    314315} // fmt
  • libcfa/src/fstream.hfa

    rca995e3 re0dc038  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 18 10:41:15 2023
    13 // Update Count     : 258
     12// Last Modified On : Fri Oct 13 13:55:21 2023
     13// Update Count     : 260
    1414//
    1515
     
    119119void ends( ifstream & );
    120120int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     121ifstream & ungetc( ifstream & is, char c );
     122bool eof( ifstream & is );
    121123
    122124bool fail( ifstream & is );
    123125void clear( ifstream & );
    124 bool eof( ifstream & is );
    125126void open( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r"
    126127void open( ifstream & is, const char name[] );
    127128void close( ifstream & is );
    128 
    129129ifstream & read( ifstream & is, char data[], size_t size );
    130 ifstream & ungetc( ifstream & is, char c );
    131130
    132131void ?{}( ifstream & is );
  • libcfa/src/iostream.cfa

    rca995e3 re0dc038  
    1 
    21//
    32// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     
    1110// Created On       : Wed May 27 17:56:53 2015
    1211// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sun Oct  8 12:10:21 2023
    14 // Update Count     : 1564
     12// Last Modified On : Tue Oct 17 20:57:05 2023
     13// Update Count     : 1795
    1514//
    1615
     
    966965                        char fmtstr[ sizeof("%*[]") + nscanset ];
    967966                        int pos = 0;
    968                         fmtstr[pos] = '%';                  pos += 1;
    969                         fmtstr[pos] = '*';                  pos += 1;
    970                         fmtstr[pos] = '[';                  pos += 1;
     967                        strcpy( &fmtstr[pos], "%*[" );  pos += 3;
    971968                        strcpy( &fmtstr[pos], f.scanset );  pos += nscanset;
    972                         fmtstr[pos] = ']';                  pos += 1;
    973                         fmtstr[pos] = '\0';
    974                         fmt( is, fmtstr, (void*)0 );  // last arg is dummy: suppress gcc warning
    975                 }
    976                 else for ( f.wd ) fmt( is, "%*c" );
     969                        strcpy( &fmtstr[pos], "]" );
     970                        fmt( is, fmtstr, "" );                                          // skip scanset
     971                } else {
     972                        char ch;
     973//                      fprintf( stderr, "skip " );
     974                        for ( f.wd ) {                                                          // skip N characters
     975                          if ( eof( is ) ) break;
     976                                fmt( is, "%c", &ch );
     977//                              fprintf( stderr, "`%c' ", ch );
     978                        } // for
     979                } // if
    977980                return is;
    978981        }
     
    980983
    981984        istype & ?|?( istype & is, _Istream_Cstr f ) {
    982                 const char * scanset = f.scanset;
     985                const char * scanset;
     986                size_t nscanset = 0;
    983987                if ( f.flags.delimiter ) scanset = f.delimiter; // getline ?
    984 
    985                 size_t len = 0;
    986                 if ( scanset ) len = strlen( scanset );
    987                 char fmtstr[len + 16];
    988                 int start = 1;
     988                else scanset = f.scanset;
     989                if ( scanset ) nscanset = strlen( scanset );
     990
     991                char fmtstr[nscanset + 32];                                             // storage for scanset and format codes
    989992                fmtstr[0] = '%';
    990                 if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
    991                 // no maximum width necessary because text ignored => width is read width
    992                 if ( f.wd != -1 ) {
     993
     994                int pos = 1;
     995                int args;
     996                bool check = true;
     997
     998                if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
     999                int rwd = f.wd;
     1000                if ( f.wd != -1 ) {                                                             // => just ignore versus ignore with width
    9931001                        // wd is buffer bytes available (for input chars + null terminator)
    9941002                        // rwd is count of input chars
    995                         int rwd;
    996                         if (f.flags.rwd) {
    997                                 verify (f.wd >= 0);
    998                                 rwd = f.wd;
     1003                        // no maximum width necessary because text ignored => width is read width
     1004                        if ( f.flags.rwd ) check = false;
     1005                        else rwd = f.wd - 1;
     1006                        pos += sprintf( &fmtstr[pos], "%d", rwd );
     1007                } // if
     1008
     1009                if ( ! scanset ) {                                                              // %s, %*s, %ws, %*ws
     1010//                      fprintf( stderr, "cstr %s\n", f.s );
     1011                        strcpy( &fmtstr[pos], "s%n" );
     1012                        int len = 0;                                                            // may not be set in fmt
     1013                        if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1014                        else args = fmt( is, fmtstr, f.s, &len );
     1015//                      fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s );
     1016                        if ( check && len >= rwd && ! eof( is ) ) {     // might not fit
     1017                                char peek;
     1018                                fmt( is, "%c", &peek );                                 // check for whitespace terminator
     1019//                              fprintf( stderr, "peek %d '%c'\n", args, peek );
     1020                                if ( ! eof( is ) ) {
     1021                                        ungetc( is, peek );
     1022                                        if ( ! isspace( peek ) ) throw ExceptionInst( cstring_length );
     1023                                } // if
     1024                        } // if
     1025                } else {
     1026                        if ( f.flags.delimiter ) {                                      // getline
     1027//                              fprintf( stderr, "getline\n" );
     1028                                sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
     1029//                              fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
     1030                                int len = 0;                                                    // may not be set in fmt
     1031                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1032                                else args = fmt( is, fmtstr, f.s, &len );
     1033//                              fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
     1034                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
     1035                                        char peek;
     1036                                        fmt( is, "%c", &peek );                         // check for delimiter
     1037//                                      fprintf( stderr, "peek %d '%c'\n", args, peek );
     1038                                        if ( ! eof( is ) ) {
     1039                                                if ( peek != f.delimiter[0] ) {
     1040                                                        ungetc( is, peek );
     1041                                                        throw ExceptionInst( cstring_length );
     1042                                                } // if
     1043                                        } // if
     1044                                } else fmt( is, "%*c" );                                //  remove delimiter
    9991045                        } else {
    1000                                 verify (f.wd >= 1);
    1001                                 rwd = f.wd - 1;
     1046                                // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
     1047                                // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
     1048                                sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
     1049//                              fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd );
     1050                                int len = 0;                                                    // may not be set in fmt
     1051                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1052                                else args = fmt( is, fmtstr, f.s, &len );
     1053//                              fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, f.s, args, f.wd, len, eof( is ), check, f.s[f.wd] );
     1054                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
     1055//                                      fprintf( stderr, "overflow\n" );
     1056                                        char peek;
     1057                                        fmt( is, "%c", &peek );                         // check for whitespace terminator
     1058//                                      fprintf( stderr, "peek %d '%c'\n", args, peek );
     1059                                        if ( ! eof( is ) ) {
     1060                                                ungetc( is, peek );
     1061                                                if ( f.flags.inex ^ strchr( f.scanset, peek ) != 0p ) throw ExceptionInst( cstring_length );
     1062                                        } // if
     1063                                } // if
    10021064                        } // if
    1003                         start += sprintf( &fmtstr[start], "%d", rwd );
    1004                 }
    1005 
    1006                 if ( ! scanset ) {
    1007                         // %s, %*s, %ws, %*ws
    1008                         fmtstr[start] = 's'; fmtstr[start + 1] = '\0';
    1009                         // printf( "cstr %s\n", fmtstr );
    1010                 } else {
    1011                         // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
    1012                         // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
    1013                         fmtstr[start] = '['; start += 1;
    1014                         if ( f.flags.inex ) { fmtstr[start] = '^'; start += 1; }
    1015                         strcpy( &fmtstr[start], scanset );                      // copy includes '\0'
    1016                         len += start;
    1017                         fmtstr[len] = ']'; fmtstr[len + 1] = '\0';
    1018                         // printf( "incl/excl %s\n", fmtstr );
    1019                 } // if
    1020 
    1021                 int check = f.wd - 2;
    1022                 if (! f.flags.ignore ) {
    1023                         if ( ! f.flags.rwd ) f.s[check] = '\0';         // insert sentinel
    1024                 }
    1025                 len = fmt( is, fmtstr, f.s );
    1026                 //fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, f.s[check], f.s );
    1027 
    1028                 if ( ! f.flags.ignore && ! f.flags.rwd && f.s[check] != '\0' ) { // sentinel overwritten ?
    1029                         // buffer filled, but would we have kept going?
    1030                         if ( ! eof( is ) ) {
    1031                                 char peek;
    1032                                 fmt( is, "%c", &peek );
    1033                                 ungetc( is, peek );
    1034                                 bool hasMore;
    1035                                 if (f.flags.delimiter) { // getline
    1036                                         hasMore = (peek != f.delimiter[0]);
    1037                                 } else if (f.scanset) { // incl/excl
    1038                                         bool peekMatch = strchr(f.scanset, peek) != 0p;
    1039                                         hasMore = f.flags.inex ? (!peekMatch) : (peekMatch);
    1040                                 } else { // %s
    1041                                         hasMore = !isspace(peek);
    1042                                 }
    1043                                 if (hasMore) throw (cstring_length){ &cstring_length_vt };
    1044                         } // if
    1045                 } // if
    1046 
    1047                 if ( f.flags.delimiter ) {                                              // getline ?
    1048                         if ( len == 0 ) f.s[0] = '\0';                          // empty read => argument unchanged => set empty
    1049                         if ( ! eof( is ) ) {                                            // ignore delimiter, may not be present because of width
    1050                                 char delimiter;
    1051                                 fmt( is, "%c", &delimiter );
    1052                                 if ( delimiter != f.delimiter[0] ) ungetc( is, delimiter );
    1053                         } // if
    1054                 } //if
     1065                } // if
     1066                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
     1067//                      fprintf( stderr, "clear\n" );
     1068                        clear( is );                                                            // => reset EOF => detect again on next read
     1069                } // if
    10551070                return is;
    10561071        } // ?|?
  • libcfa/src/iostream.hfa

    rca995e3 re0dc038  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Oct  8 12:02:55 2023
    13 // Update Count     : 568
     12// Last Modified On : Mon Oct 16 21:12:01 2023
     13// Update Count     : 573
    1414//
    1515
     
    324324        istype & ungetc( istype &, char );
    325325        bool eof( istype & );
     326        void clear( istype & );
    326327}; // basic_istream
    327328
     
    329330trait istream {
    330331        bool fail( istype & );
    331         void clear( istype & );
     332        void open( istype & is, const char name[], const char mode[] );
    332333        void open( istype & is, const char name[] );
    333334        void close( istype & is );
     
    402403
    403404ExceptionDecl( cstring_length );
     405ExceptionDecl( missing_data );
    404406
    405407// *********************************** manipulators ***********************************
    406408
     409// skip does not compose with other C string manipulators.
    407410struct _Istream_Cskip {
    408411        const char * scanset;
Note: See TracChangeset for help on using the changeset viewer.