Ignore:
Timestamp:
Jan 31, 2024, 6:40:25 PM (20 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
496ffc17
Parents:
c75b30a (diff), e71b09a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    rc75b30a r32490deb  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan  3 10:53:13 2024
    13 // Update Count     : 1898
     12// Last Modified On : Sun Jan 28 11:58:54 2024
     13// Update Count     : 1917
    1414//
    1515
     
    944944        istype & nl( istype & is ) {
    945945                fmt( is, "%*[^\n]" );                                                   // ignore characters to newline
    946                 if ( ! eof( is ) && getANL$( is ) ) fmt( is, "%*c" ); // read newline
     946                if ( ! eof( is ) ) fmt( is, "%*c" );                    // read newline
    947947                return is;
    948948        } // nl
     
    984984        }
    985985
    986         istype & ?|?( istype & is, _Istream_Cquoted f ) with( f ) {
    987                 char fmtstr[32];                                                                // storage scanset and format codes
     986        istype & ?|?( istype & is, _Istream_Cquoted f ) with( f.cstr ) {
     987                int args;
     988          fini: {
     989                        args = fmt( is, "%*[ \f\n\r\t\v]" );            // remove leading whitespace
     990                        if ( eof( is ) ) break fini;
     991                        char rfmt[4] = { delimiters[0], '%', 'n', '\0' };
     992                        int len = 0;                                                            // may not be set in fmt
     993                        args = fmt( is, rfmt, &len );                           // remove leading quote
     994                        if ( len == 0 || eof( is ) ) break fini;
     995
     996                        // Change the remainder of the read into a getline by reseting the closing delimiter.
     997                        if ( delimiters[1] != '\0' ) {
     998                                delimiters[0] = delimiters[1];
     999                                delimiters[1] = '\0';
     1000                        } // if
     1001                        flags.delimiter = true;
     1002                        return is | *(_Istream_Cstr *)&f;
     1003                } // fini
     1004                // read failed => no pattern match => set string to null
     1005                if ( ! flags.ignore && s != 0p && args == 0 ) s[0] = '\0';
     1006                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
     1007                        clear( is );                                                            // => reset EOF => detect again on next read
     1008                } // if
     1009                return is;
     1010        }
     1011
     1012        istype & ?|?( istype & is, _Istream_Cstr f ) with( f.cstr ) {
     1013                const char * scanset;
     1014                size_t nscanset = 0;
     1015                if ( flags.delimiter ) scanset = delimiters;    // getline ?
     1016                else scanset = f.cstr.scanset;
     1017                if ( scanset ) nscanset = strlen( scanset );
     1018
     1019                char fmtstr[nscanset + 32];                                             // storage for scanset and format codes
    9881020                fmtstr[0] = '%';
    989 
    9901021                int pos = 1;
    9911022                int args;
    9921023                bool check = true;
    9931024
    994                 if ( cstr.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
    995                 int rwd = cstr.wd;
    996                 if ( cstr.wd != -1 ) {                                          // => just ignore versus ignore with width
     1025                if ( flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
     1026                int rwd = wd;
     1027                if ( wd != -1 ) {                                                               // => just ignore versus ignore with width
    9971028                        // wd is buffer bytes available (for input chars + null terminator)
    9981029                        // rwd is count of input chars
    9991030                        // no maximum width necessary because text ignored => width is read width
    1000                         if ( cstr.flags.rwd ) check = false;
    1001                         else rwd = cstr.wd - 1;
     1031                        if ( flags.rwd ) check = false;
     1032                        else rwd = wd - 1;
     1033                        assert( rwd > 0 );
    10021034                        pos += sprintf( &fmtstr[pos], "%d", rwd );
    10031035                } // if
    10041036
    1005                 int len = 0;                                                                    // may not be set in fmt
    1006                 char enddelim;
    1007                 if ( ! cstr.flags.inex ) {                                              // => quoted getline
    1008                         args = fmt( is, "%*[ \f\n\r\t\v]" );            // remove leading whitespace
    1009                         if ( eof( is ) ) goto Eof;
    1010                         char rfmt[4] = { cstr.delimiters[0], '%', 'n', '\0' };
    1011                         args = fmt( is, rfmt, &len );                           // remove leading quote
    1012                         if ( len == 0 || eof( is ) ) goto Eof;
    1013                 } // if
    1014                 enddelim = cstr.delimiters[1] == '\0' ? cstr.delimiters[0] : cstr.delimiters[1];
    1015                 sprintf( &fmtstr[pos], "[^%c]%%n", enddelim );
    1016                 if ( cstr.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    1017                 else args = fmt( is, fmtstr, cstr.s, &len );
    1018                 if ( check && len == rwd && ! eof( is ) ) {             // might not fit
    1019                         char peek;
    1020                         fmt( is, "%c", &peek );                                         // check for delimiter
    1021                         if ( ! eof( is ) ) {
    1022                                 if ( peek != enddelim ) {
    1023                                         ungetc( is, peek );
    1024                                         throwResume ExceptionInst( cstring_length );
    1025                                 } // if
    1026                         } // if
    1027                 } else fmt( is, "%*c" );                                                // remove delimiter
    1028           Eof: ;
    1029                 if ( rwd > 0 && args == 0 ) cstr.s[0] = '\0';   // read failed => no pattern match => set string to null
    1030                 if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
    1031                         clear( is );                                                            // => reset EOF => detect again on next read
    1032                 } // if
    1033                 return is;
    1034         }
    1035 
    1036         istype & ?|?( istype & is, _Istream_Cstr f ) with( f ) {
    1037                 const char * scanset;
    1038                 size_t nscanset = 0;
    1039                 if ( flags.delimiter ) scanset = delimiters;    // getline ?
    1040                 else scanset = f.scanset;
    1041                 if ( scanset ) nscanset = strlen( scanset );
    1042 
    1043                 char fmtstr[nscanset + 32];                                             // storage for scanset and format codes
    1044                 fmtstr[0] = '%';
    1045 
    1046                 int pos = 1;
    1047                 int args;
    1048                 bool check = true;
    1049 
    1050                 if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
    1051                 int rwd = f.wd;
    1052                 if ( f.wd != -1 ) {                                                             // => just ignore versus ignore with width
    1053                         // wd is buffer bytes available (for input chars + null terminator)
    1054                         // rwd is count of input chars
    1055                         // no maximum width necessary because text ignored => width is read width
    1056                         if ( f.flags.rwd ) check = false;
    1057                         else rwd = f.wd - 1;
    1058                         pos += sprintf( &fmtstr[pos], "%d", rwd );
    1059                 } // if
    1060 
    10611037                if ( ! scanset ) {                                                              // %s, %*s, %ws, %*ws
    1062                         // fprintf( stderr, "cstr %s\n", f.s );
     1038                        // fprintf( stderr, "cstr %s\n", s );
    10631039                        strcpy( &fmtstr[pos], "s%n" );
    10641040                        int len = 0;                                                            // may not be set in fmt
    1065                         if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    1066                         else args = fmt( is, fmtstr, f.s, &len );
    1067                         // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s );
     1041                        if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1042                        else args = fmt( is, fmtstr, s, &len );
     1043                        // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, wd, s );
    10681044                        if ( check && len >= rwd && ! eof( is ) ) {     // might not fit
    10691045                                char peek;
     
    10761052                        } // if
    10771053                        // FIX ME: CFA strings need to be modified to NOT change the argument for this case, then this can be removed.
    1078                         if ( rwd > 0 && args == 0 ) f.s[0]= '\0';       // read failed => no pattern match => set string to null
     1054                        if ( ! flags.ignore && args == 0 ) s[0]= '\0'; // read failed => no pattern match => set string to null
    10791055                } else {
    1080                         if ( f.flags.delimiter ) {                                      // getline
     1056                        if ( flags.delimiter ) {                                        // getline
    10811057                                int len = 0;                                                    // may not be set in fmt
    1082                                 sprintf( &fmtstr[pos], "[^%c]%%n", f.delimiters[0] );
    1083                                 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    1084                                 else args = fmt( is, fmtstr, f.s, &len );
     1058                                if ( delimiters[2] != '\0' ) {                  // read single character ?
     1059                                        sprintf( &fmtstr[pos], "c%%n" );
     1060                                } else {
     1061                                        sprintf( &fmtstr[pos], "[^%c]%%n", delimiters[0] );
     1062                                } // if
     1063                                if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1064                                else args = fmt( is, fmtstr, s, &len );
    10851065                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
    1086                                         fmtstr[0] = f.delimiters[0]; fmtstr[1] = '%'; fmtstr[2] = 'n'; fmtstr[3] = '\0';
    1087                                         fmt( is, fmtstr, &len );                        // remove delimiter
     1066                                        char peek;
     1067                                        fmt( is, "%c", &peek );                         // check for delimiter
    10881068                                        if ( ! eof( is ) ) {
    1089 //                                              if ( peek != f.delimiter[0] ) {
    1090                                                 if ( len != 1 ) {
    1091 //                                                      ungetc( is, peek );
     1069                                                if ( peek != delimiters[0] ) {
     1070                                                        ungetc( is, peek );
    10921071                                                        throwResume ExceptionInst( cstring_length );
    10931072                                                } // if
     
    10971076                                // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
    10981077                                // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
    1099                                 sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
    1100                                 // fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd );
     1078                                sprintf( &fmtstr[pos], "[%s%s]%%n", flags.inex ? "^" : "", scanset );
     1079                                // fprintf( stderr, "incl/excl %s %d\n", fmtstr, wd );
    11011080                                int len = 0;                                                    // may not be set in fmt
    1102                                 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    1103                                 else args = fmt( is, fmtstr, f.s, &len );
    1104                                 // 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] );
     1081                                if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1082                                else args = fmt( is, fmtstr, s, &len );
     1083                                // fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, s, args, wd, len, eof( is ), check, s[wd] );
    11051084                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
    11061085                                        // fprintf( stderr, "overflow\n" );
     
    11101089                                        if ( ! eof( is ) ) {
    11111090                                                ungetc( is, peek );
    1112                                                 if ( f.flags.inex ^ strchr( f.scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length );
     1091                                                if ( flags.inex ^ strchr( scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length );
    11131092                                        } // if
    11141093                                } // if
    11151094                        } // if
    1116                         if ( rwd > 0 && args == 0 ) f.s[0]= '\0';       // read failed => no pattern match => set string to null
     1095                        if ( ! flags.ignore && args == 0 ) s[0]= '\0'; // read failed => no pattern match => set string to null
    11171096                } // if
    11181097                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
     
    11201099                        clear( is );                                                            // => reset EOF => detect again on next read
    11211100                } // if
    1122                 return is;
    1123         } // ?|?
    1124 
    1125         istype & ?|?( istype & is, _Istream_Char f ) {
    1126                 fmt( is, "%*c" );                                                               // argument variable unused
    11271101                return is;
    11281102        } // ?|?
     
    11451119} // distribution
    11461120
     1121INPUT_FMT_IMPL( char, "c" )
    11471122INPUT_FMT_IMPL( signed char, "hhi" )
    11481123INPUT_FMT_IMPL( unsigned char, "hhi" )
Note: See TracChangeset for help on using the changeset viewer.