Changeset 8c13ca8


Ignore:
Timestamp:
Nov 18, 2023, 7:44:49 AM (13 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
66d92e3
Parents:
decd4a6
Message:

raise exception missing_data when read fails to find value, initial code for quoted manipulator

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    rdecd4a6 r8c13ca8  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Nov 11 07:06:27 2023
    13 // Update Count     : 1803
     12// Last Modified On : Fri Nov 17 13:33:12 2023
     13// Update Count     : 1853
    1414//
    1515
     
    775775        istype & ?|?( istype & is, bool & b ) {
    776776                char val[6];
    777                 fmt( is, "%5s", val );
     777                int args = fmt( is, "%5s", val );
     778                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    778779                if ( strcmp( val, "true" ) == 0 ) b = true;
    779780                else if ( strcmp( val, "false" ) == 0 ) b = false;
     
    788789                char temp;
    789790                for () {
    790                         fmt( is, "%c", &temp );                                         // must pass pointer through varg to fmt
     791                        int args = fmt( is, "%c", &temp );
     792                        if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    791793                        // do not overwrite parameter with newline unless appropriate
    792794                        if ( temp != '\n' || getANL$( is ) ) { c = temp; break; }
     
    797799
    798800        istype & ?|?( istype & is, signed char & sc ) {
    799                 fmt( is, "%hhi", &sc );
     801                int args = fmt( is, "%hhi", &sc );
     802                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    800803                return is;
    801804        } // ?|?
    802805
    803806        istype & ?|?( istype & is, unsigned char & usc ) {
    804                 fmt( is, "%hhi", &usc );
     807                int args = fmt( is, "%hhi", &usc );
     808                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    805809                return is;
    806810        } // ?|?
    807811
    808812        istype & ?|?( istype & is, short int & si ) {
    809                 fmt( is, "%hi", &si );
     813                int args = fmt( is, "%hi", &si );
     814                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    810815                return is;
    811816        } // ?|?
    812817
    813818        istype & ?|?( istype & is, unsigned short int & usi ) {
    814                 fmt( is, "%hi", &usi );
     819                int args = fmt( is, "%hi", &usi );
     820                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    815821                return is;
    816822        } // ?|?
    817823
    818824        istype & ?|?( istype & is, int & i ) {
    819                 fmt( is, "%i", &i );
     825                int args = fmt( is, "%i", &i );
     826                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    820827                return is;
    821828        } // ?|?
    822829
    823830        istype & ?|?( istype & is, unsigned int & ui ) {
    824                 fmt( is, "%i", &ui );
     831                int args = fmt( is, "%i", &ui );
     832                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    825833                return is;
    826834        } // ?|?
    827835
    828836        istype & ?|?( istype & is, long int & li ) {
    829                 fmt( is, "%li", &li );
     837                int args = fmt( is, "%li", &li );
     838                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    830839                return is;
    831840        } // ?|?
    832841
    833842        istype & ?|?( istype & is, unsigned long int & ulli ) {
    834                 fmt( is, "%li", &ulli );
     843                int args = fmt( is, "%li", &ulli );
     844                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    835845                return is;
    836846        } // ?|?
    837847
    838848        istype & ?|?( istype & is, long long int & lli ) {
    839                 fmt( is, "%lli", &lli );
     849                int args = fmt( is, "%lli", &lli );
     850                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    840851                return is;
    841852        } // ?|?
    842853
    843854        istype & ?|?( istype & is, unsigned long long int & ulli ) {
    844                 fmt( is, "%lli", &ulli );
     855                int args = fmt( is, "%lli", &ulli );
     856                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    845857                return is;
    846858        } // ?|?
     
    869881
    870882        istype & ?|?( istype & is, float & f ) {
    871                 fmt( is, "%f", &f );
     883                int args = fmt( is, "%f", &f );
     884                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    872885                return is;
    873886        } // ?|?
    874887
    875888        istype & ?|?( istype & is, double & d ) {
    876                 fmt( is, "%lf", &d );
     889                int args = fmt( is, "%lf", &d );
     890                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    877891                return is;
    878892        } // ?|?
    879893
    880894        istype & ?|?( istype & is, long double & ld ) {
    881                 fmt( is, "%Lf", &ld );
     895                int args = fmt( is, "%Lf", &ld );
     896                if ( args != -1 && args != 1 ) throwResume ExceptionInst( missing_data );
    882897                return is;
    883898        } // ?|?
     
    885900        istype & ?|?( istype & is, float _Complex & fc ) {
    886901                float re, im;
    887                 fmt( is, "%f%fi", &re, &im );
     902                int args = fmt( is, "%f%fi", &re, &im );
     903                if ( args != -1 && args != 2 ) throwResume ExceptionInst( missing_data );
    888904                fc = re + im * _Complex_I;
    889905                return is;
     
    892908        istype & ?|?( istype & is, double _Complex & dc ) {
    893909                double re, im;
    894                 fmt( is, "%lf%lfi", &re, &im );
     910                int args = fmt( is, "%lf%lfi", &re, &im );
     911                if ( args != -1 && args != 2 ) throwResume ExceptionInst( missing_data );
    895912                dc = re + im * _Complex_I;
    896913                return is;
     
    899916        istype & ?|?( istype & is, long double _Complex & ldc ) {
    900917                long double re, im;
    901                 fmt( is, "%Lf%Lfi", &re, &im );
     918                int args = fmt( is, "%Lf%Lfi", &re, &im );
     919                if ( args != -1 && args != 2 ) throwResume ExceptionInst( missing_data );
    902920                ldc = re + im * _Complex_I;
    903921                return is;
     
    905923
    906924        istype & ?|?( istype & is, const char fmt[] ) {
    907                 fmt( is, fmt, "" );
     925                size_t len = strlen( fmt );
     926                char fmt2[len + 16];
     927                strcpy( fmt2, fmt );                                                    // copy format and add %n
     928                strcpy( &fmt2[len], "%n" );
     929                int len2 = -1;
     930                int args = fmt( is, fmt2, &len2 );
     931                if ( args != -1 && len2 == -1 ) throwResume ExceptionInst( missing_data );
    908932                return is;
    909933        } // ?|?
     
    950974                } else {
    951975                        char ch;
    952 //                      fprintf( stderr, "skip " );
     976                        // fprintf( stderr, "skip " );
    953977                        for ( f.wd ) {                                                          // skip N characters
    954978                          if ( eof( is ) ) break;
    955979                                fmt( is, "%c", &ch );
    956 //                              fprintf( stderr, "`%c' ", ch );
     980                                // fprintf( stderr, "`%c' ", ch );
    957981                        } // for
    958982                } // if
     
    960984        }
    961985
    962         istype & ?|?( istype & is, _Istream_Cstr f ) {
    963                 const char * scanset;
    964                 size_t nscanset = 0;
    965                 if ( f.flags.delimiter ) scanset = f.delimiter; // getline ?
    966                 else scanset = f.scanset;
    967                 if ( scanset ) nscanset = strlen( scanset );
    968 
    969                 char fmtstr[nscanset + 32];                                             // storage for scanset and format codes
     986        istype & ?|?( istype & is, _Istream_Cquoted f ) {
     987                char fmtstr[32];                                                                // storage scanset and format codes
    970988                fmtstr[0] = '%';
    971989
     
    9851003                } // if
    9861004
     1005                int len = 0;                                                                    // may not be set in fmt
     1006                if ( ! f.flags.inex ) {                                                 // => quoted getline
     1007                        // fprintf( stderr, "quoted\n" );
     1008                        args = fmt( is, "%*[ \f\n\r\t\v]" );            // remove leading whitespace
     1009                        if ( eof( is ) ) goto Eof;
     1010//                      args = fmt( is, (const char *)f.delimiter ); // remove leading quote
     1011                        args = fmt( is, "'%n", &len ); // remove leading quote
     1012                        fprintf( stderr, "quoted %d %d\n", args, len );
     1013                        if ( len == 0 || eof( is ) ) goto Eof;
     1014                } // if
     1015                sprintf( &fmtstr[pos], "[^%c]%%n", f.delimiter[0] );
     1016                // fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
     1017                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1018                else args = fmt( is, fmtstr, f.s, &len );
     1019                // fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
     1020                if ( check && len == rwd && ! eof( is ) ) {             // might not fit
     1021                        char peek;
     1022                        fmt( is, "%c", &peek );                                         // check for delimiter
     1023                        // fprintf( stderr, "peek %d '%c'\n", args, peek );
     1024                        if ( ! eof( is ) ) {
     1025                                if ( peek != f.delimiter[0] ) {
     1026                                        ungetc( is, peek );
     1027                                        throwResume ExceptionInst( cstring_length );
     1028                                } // if
     1029                        } // if
     1030                } else fmt( is, "%*c" );                                                // remove delimiter
     1031          Eof: ;
     1032                if ( rwd > 0 && args == 0 ) f.s[0] = '\0';              // read failed => no pattern match => set string to null
     1033                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
     1034                        // fprintf( stderr, "clear\n" );
     1035                        clear( is );                                                            // => reset EOF => detect again on next read
     1036                } // if
     1037                return is;
     1038        }
     1039
     1040        istype & ?|?( istype & is, _Istream_Cstr f ) {
     1041                const char * scanset;
     1042                size_t nscanset = 0;
     1043                if ( f.flags.delimiter ) scanset = f.delimiter; // getline ?
     1044                else scanset = f.scanset;
     1045                if ( scanset ) nscanset = strlen( scanset );
     1046
     1047                char fmtstr[nscanset + 32];                                             // storage for scanset and format codes
     1048                fmtstr[0] = '%';
     1049
     1050                int pos = 1;
     1051                int args;
     1052                bool check = true;
     1053
     1054                if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
     1055                int rwd = f.wd;
     1056                if ( f.wd != -1 ) {                                                             // => just ignore versus ignore with width
     1057                        // wd is buffer bytes available (for input chars + null terminator)
     1058                        // rwd is count of input chars
     1059                        // no maximum width necessary because text ignored => width is read width
     1060                        if ( f.flags.rwd ) check = false;
     1061                        else rwd = f.wd - 1;
     1062                        pos += sprintf( &fmtstr[pos], "%d", rwd );
     1063                } // if
     1064
    9871065                if ( ! scanset ) {                                                              // %s, %*s, %ws, %*ws
    988 //                      fprintf( stderr, "cstr %s\n", f.s );
     1066                        // fprintf( stderr, "cstr %s\n", f.s );
    9891067                        strcpy( &fmtstr[pos], "s%n" );
    9901068                        int len = 0;                                                            // may not be set in fmt
    9911069                        if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    9921070                        else args = fmt( is, fmtstr, f.s, &len );
    993 //                      fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s );
     1071                        // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s );
    9941072                        if ( check && len >= rwd && ! eof( is ) ) {     // might not fit
    9951073                                char peek;
    9961074                                fmt( is, "%c", &peek );                                 // check for whitespace terminator
    997 //                              fprintf( stderr, "peek %d '%c'\n", args, peek );
     1075                                // fprintf( stderr, "peek %d '%c'\n", args, peek );
    9981076                                if ( ! eof( is ) ) {
    9991077                                        ungetc( is, peek );
    1000                                         if ( ! isspace( peek ) ) throw ExceptionInst( cstring_length );
     1078                                        if ( ! isspace( peek ) ) throwResume ExceptionInst( cstring_length );
    10011079                                } // if
    10021080                        } // if
     
    10051083                } else {
    10061084                        if ( f.flags.delimiter ) {                                      // getline
    1007 //                              fprintf( stderr, "getline\n" );
    1008                                 sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
    1009 //                              fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
    10101085                                int len = 0;                                                    // may not be set in fmt
     1086                                if ( ! f.flags.inex ) {                                 // => quoted getline
     1087                                        // fprintf( stderr, "quoted\n" );
     1088                                        args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace
     1089                                        if ( eof( is ) ) goto X;
     1090                                        args = fmt( is, "\"" );                         // remove leading quote
     1091                                        if ( eof( is ) ) goto X;
     1092                                } // if
     1093                                // fprintf( stderr, "getline\n" );
     1094                                // sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
     1095                                sprintf( &fmtstr[pos], "[^%s]%%n", scanset );
     1096                                // fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
    10111097                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    10121098                                else args = fmt( is, fmtstr, f.s, &len );
    1013 //                              fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
     1099                                // fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
    10141100                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
    10151101                                        char peek;
    10161102                                        fmt( is, "%c", &peek );                         // check for delimiter
    1017 //                                      fprintf( stderr, "peek %d '%c'\n", args, peek );
     1103                                        // fprintf( stderr, "peek %d '%c'\n", args, peek );
    10181104                                        if ( ! eof( is ) ) {
    10191105                                                if ( peek != f.delimiter[0] ) {
    10201106                                                        ungetc( is, peek );
    1021                                                         throw ExceptionInst( cstring_length );
     1107                                                        throwResume ExceptionInst( cstring_length );
    10221108                                                } // if
    10231109                                        } // if
    1024                                 } else fmt( is, "%*c" );                                //  remove delimiter
     1110                                } else fmt( is, "%*c" );                        // remove delimiter
     1111                          X: ;
    10251112                        } else {
    10261113                                // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
    10271114                                // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
    10281115                                sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
    1029 //                              fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd );
     1116                                // fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd );
    10301117                                int len = 0;                                                    // may not be set in fmt
    10311118                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    10321119                                else args = fmt( is, fmtstr, f.s, &len );
    1033 //                              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] );
     1120                                // 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] );
    10341121                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
    1035 //                                      fprintf( stderr, "overflow\n" );
     1122                                        // fprintf( stderr, "overflow\n" );
    10361123                                        char peek;
    10371124                                        fmt( is, "%c", &peek );                         // check for whitespace terminator
    1038 //                                      fprintf( stderr, "peek %d '%c'\n", args, peek );
     1125                                        // fprintf( stderr, "peek %d '%c'\n", args, peek );
    10391126                                        if ( ! eof( is ) ) {
    10401127                                                ungetc( is, peek );
    1041                                                 if ( f.flags.inex ^ strchr( f.scanset, peek ) != 0p ) throw ExceptionInst( cstring_length );
     1128                                                if ( f.flags.inex ^ strchr( f.scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length );
    10421129                                        } // if
    10431130                                } // if
     
    10461133                } // if
    10471134                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
    1048 //                      fprintf( stderr, "clear\n" );
     1135                        // fprintf( stderr, "clear\n" );
    10491136                        clear( is );                                                            // => reset EOF => detect again on next read
    10501137                } // if
  • libcfa/src/iostream.hfa

    rdecd4a6 r8c13ca8  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Oct 18 21:21:20 2023
    13 // Update Count     : 583
     12// Last Modified On : Wed Nov 15 17:55:31 2023
     13// Update Count     : 596
    1414//
    1515
     
    388388        _Istream_Cskip skip( unsigned int wd ) { return (_Istream_Cskip)@{ 0p, wd }; }
    389389} // distribution
    390 forall( istype & | basic_istream( istype ) ) {
    391         istype & ?|?( istype & is, _Istream_Cskip f );
    392 }
    393390
    394391struct _Istream_str_base {
     
    414411}; // _Istream_Cstr
    415412
     413struct _Istream_Cquoted {
     414        char * s;
     415        inline _Istream_str_base;
     416}; // _Istream_Cquoted
     417
    416418static inline {
    417419        // width must include room for null terminator
     
    422424                return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } };
    423425        }
     426        _Istream_Cquoted & quoted( _Istream_Cstr & fmt, const char delimiter = '"' ) {
     427                fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0';
     428                return (_Istream_Cquoted &)fmt;
     429        }
    424430        _Istream_Cstr & getline( _Istream_Cstr & fmt, const char delimiter = '\n' ) {
    425431                fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt; }
     
    429435        _Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
    430436} // distribution
     437
    431438forall( istype & | basic_istream( istype ) ) {
    432439        istype & ?|?( istype & is, _Istream_Cstr f );
    433 }
     440        istype & ?|?( istype & is, _Istream_Cskip f );
     441        istype & ?|?( istype & is, _Istream_Cquoted f );
     442} // distribution
    434443
    435444struct _Istream_Char {
Note: See TracChangeset for help on using the changeset viewer.