Changeset 32490deb for libcfa/src/iostream.cfa
- Timestamp:
- Jan 31, 2024, 6:40:25 PM (20 months ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/iostream.cfa
rc75b30a r32490deb 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jan 3 10:53:13202413 // Update Count : 1 89812 // Last Modified On : Sun Jan 28 11:58:54 2024 13 // Update Count : 1917 14 14 // 15 15 … … 944 944 istype & nl( istype & is ) { 945 945 fmt( is, "%*[^\n]" ); // ignore characters to newline 946 if ( ! eof( is ) && getANL$( is ) ) fmt( is, "%*c" );// read newline946 if ( ! eof( is ) ) fmt( is, "%*c" ); // read newline 947 947 return is; 948 948 } // nl … … 984 984 } 985 985 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 988 1020 fmtstr[0] = '%'; 989 990 1021 int pos = 1; 991 1022 int args; 992 1023 bool check = true; 993 1024 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 width1025 if ( flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; } 1026 int rwd = wd; 1027 if ( wd != -1 ) { // => just ignore versus ignore with width 997 1028 // wd is buffer bytes available (for input chars + null terminator) 998 1029 // rwd is count of input chars 999 1030 // 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 ); 1002 1034 pos += sprintf( &fmtstr[pos], "%d", rwd ); 1003 1035 } // if 1004 1036 1005 int len = 0; // may not be set in fmt1006 char enddelim;1007 if ( ! cstr.flags.inex ) { // => quoted getline1008 args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace1009 if ( eof( is ) ) goto Eof;1010 char rfmt[4] = { cstr.delimiters[0], '%', 'n', '\0' };1011 args = fmt( is, rfmt, &len ); // remove leading quote1012 if ( len == 0 || eof( is ) ) goto Eof;1013 } // if1014 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 fit1019 char peek;1020 fmt( is, "%c", &peek ); // check for delimiter1021 if ( ! eof( is ) ) {1022 if ( peek != enddelim ) {1023 ungetc( is, peek );1024 throwResume ExceptionInst( cstring_length );1025 } // if1026 } // if1027 } else fmt( is, "%*c" ); // remove delimiter1028 Eof: ;1029 if ( rwd > 0 && args == 0 ) cstr.s[0] = '\0'; // read failed => no pattern match => set string to null1030 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF1031 clear( is ); // => reset EOF => detect again on next read1032 } // if1033 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 codes1044 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 width1053 // wd is buffer bytes available (for input chars + null terminator)1054 // rwd is count of input chars1055 // no maximum width necessary because text ignored => width is read width1056 if ( f.flags.rwd ) check = false;1057 else rwd = f.wd - 1;1058 pos += sprintf( &fmtstr[pos], "%d", rwd );1059 } // if1060 1061 1037 if ( ! scanset ) { // %s, %*s, %ws, %*ws 1062 // fprintf( stderr, "cstr %s\n", f.s );1038 // fprintf( stderr, "cstr %s\n", s ); 1063 1039 strcpy( &fmtstr[pos], "s%n" ); 1064 1040 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 ); 1068 1044 if ( check && len >= rwd && ! eof( is ) ) { // might not fit 1069 1045 char peek; … … 1076 1052 } // if 1077 1053 // 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 null1054 if ( ! flags.ignore && args == 0 ) s[0]= '\0'; // read failed => no pattern match => set string to null 1079 1055 } else { 1080 if ( f .flags.delimiter ) { // getline1056 if ( flags.delimiter ) { // getline 1081 1057 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 ); 1085 1065 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 ); // removedelimiter1066 char peek; 1067 fmt( is, "%c", &peek ); // check for delimiter 1088 1068 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 ); 1092 1071 throwResume ExceptionInst( cstring_length ); 1093 1072 } // if … … 1097 1076 // incl %[xxx], %*[xxx], %w[xxx], %*w[xxx] 1098 1077 // 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 ); 1101 1080 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] ); 1105 1084 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1106 1085 // fprintf( stderr, "overflow\n" ); … … 1110 1089 if ( ! eof( is ) ) { 1111 1090 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 ); 1113 1092 } // if 1114 1093 } // if 1115 1094 } // if 1116 if ( rwd > 0 && args == 0 ) f.s[0]= '\0';// read failed => no pattern match => set string to null1095 if ( ! flags.ignore && args == 0 ) s[0]= '\0'; // read failed => no pattern match => set string to null 1117 1096 } // if 1118 1097 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF … … 1120 1099 clear( is ); // => reset EOF => detect again on next read 1121 1100 } // if 1122 return is;1123 } // ?|?1124 1125 istype & ?|?( istype & is, _Istream_Char f ) {1126 fmt( is, "%*c" ); // argument variable unused1127 1101 return is; 1128 1102 } // ?|? … … 1145 1119 } // distribution 1146 1120 1121 INPUT_FMT_IMPL( char, "c" ) 1147 1122 INPUT_FMT_IMPL( signed char, "hhi" ) 1148 1123 INPUT_FMT_IMPL( unsigned char, "hhi" )
Note:
See TracChangeset
for help on using the changeset viewer.