Changeset 0528d79 for libcfa/src


Ignore:
Timestamp:
May 18, 2025, 8:26:51 AM (4 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
1e28e05
Parents:
bd72f517
Message:

fix bugs reading enumerators

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    rbd72f517 r0528d79  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 14 20:43:14 2025
    13 // Update Count     : 2081
     12// Last Modified On : Sun May 18 08:23:40 2025
     13// Update Count     : 2175
    1414//
    1515
     
    944944        } // ?|?
    945945
    946         istype & ?|?( istype & is, const char fmt[] ) with ( basic_istream_table ) {            // match text
     946        istype & ?|?( istype & is, const char fmt[] ) with ( basic_istream_table ) { // match text
    947947                size_t len = strlen( fmt );
    948948                char fmtstr[len + 16];
     
    12021202} // distribution
    12031203
     1204// *********************************** enumerations ***********************************
    12041205
    12051206forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial( E ) )
    12061207istype & ?|?( istype & is, E & e ) with ( basic_istream_table ) {
    1207 //      if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
    1208 
    12091208        // Match longest input enumerator string to enumerator labels, where enumerator names are unique.
    1210 
    1211         int N = countof( E ), lnths[N], fred = 0;
    1212         int r = 0;
    1213         for ( s; E ) {                                                                          // scan string rows gathering lengths
    1214                 lnths[r] = strlen( label( s ) );
    1215                 if ( lnths[r] > fred ) fred = lnths[r];
    1216                 r += 1;
     1209        size_t N = countof( E ), lnths[N], maxlen = 0;          // N must be > 0, maxlen must be > 0
     1210
     1211        size_t ec = 0;
     1212        for ( s; E ) {                                                                          // gather label lengths
     1213                lnths[ec] = strlen( label( s ) );
     1214                if ( lnths[ec] > maxlen ) maxlen = lnths[ec];   // gather longest length
     1215                // printf( "%s %zd\n", label( s ), lnths[e] );
     1216                ec += 1;
    12171217        } // for
    1218 
    1219         int mcol = -1;                                                                          // last match column
    1220         char ch, curr = '\0', prev = '\0';
     1218        // printf( "maxlen %d\n", maxlen );
    12211219
    12221220        fmt( is, " " );                                                                         // remove leading whitespace
    1223         if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
    1224 
    1225         for ( c; fred ) {                                                                       // scan columns of the label matix (some columns missing)
    1226                 int args = fmt( is, "%c", &ch );                                // read character
    1227           if ( eof( is ) ) {
    1228                         if ( c == 0 ) return is;                                        // no characters read ?
     1221  if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
     1222        // printf( "after whitespace\n" );
     1223
     1224        char ch;
     1225        ssize_t exact = -1;                                                                     // -1 => no exact match seen so far
     1226
     1227        for ( c; maxlen ) {                                                                     // scan columns of the label matrix (some columns missing)
     1228                fmt( is, "%c", &ch );                                                   // read character => get a character or EOF
     1229                // printf( "after fmt %d %d '%c'\n", c, args, ch );
     1230                if ( eof( is ) || isspace( ch ) != 0 ) {                // enumerator delimiter ? => end of enumerator
     1231                        // printf( "match eof %zd %s\n", exact, label( fromInt( exact ) ) );
     1232                        if ( exact != -1 ) {                                            // exact match available ?
     1233                                e = fromInt( exact );
     1234                                return is;
     1235                        } // if
     1236                        // printf( "no match\n" );
     1237                        // consume input character(s) as garbage
    12291238                        clearerr( is );                                                         // => read something => reset EOF => detect again on next read
    1230                         break;
    1231                 } // if
    1232           if ( args != 1 ) throwResume ExceptionInst( missing_data ); // may be unnecessary since reading single character
    1233 
    1234                 for ( r; N ) {                                                                  // scan enumeration strings for matching character in current column
    1235                         if ( c < lnths[r] ) {                                           // string long enough for this column check ?
    1236                                 char match = label( fromInt( r ) )[c];  // optimization
    1237                                 // Stop on first match, could be other matches.
    1238                                 if ( (match == ch) && (c == 0 || curr == label( fromInt( r ) )[c - 1]) ) {
    1239                                         mcol = c;                                                       // matching column
    1240                                         prev = curr;                                            // last matching character
    1241                                         curr = ch;                                                      // current matching character
    1242                                         break;
    1243                                 } // if
     1239                        throwResume ExceptionInst( missing_data );      // no matching enumerator
     1240                } // if
     1241
     1242                bool match = false;
     1243                for ( r; N ) {                                                                  // scan all enumeration labels for matching character
     1244                        // if ( lnths[r] > c ) printf( "%d %d %d %c %s %c\n", c, r, lnths[r], ch, label( fromInt( r ) ), label( fromInt( r ) )[c] );
     1245                        if ( lnths[r] > c && label( fromInt( r ) )[c] == ch ) { // label long enough and matching character ?
     1246                                // printf( "match char\n" );
     1247                                match = true;
     1248                                if ( lnths[r] - 1 == c ) exact = r;             // exact match ?
     1249                                else if ( exact != -1 && lnths[exact] <= c ) exact = -1; // previous exact match too short ?
     1250                        } else {
     1251                                lnths[r] = 0;                                                   // mark enumerator ineligible
    12441252                        } // if
    1245                 } else {
    1246                         ungetc( ch, is );                                                       // push back last unmatching character
    1247                         if ( mcol == -1 ) throwResume ExceptionInst( missing_data ); // no matching character in first column
    1248                         break;
    12491253                } // for
     1254                // printf( "match %d\n", match );
     1255                if ( ! match ) {                                                                // no matching character in column
     1256                        if ( exact != -1 ) {                                            // exact match available ?
     1257                                // printf( "match %zd unget %c\n", exact, ch );
     1258                                ungetc( ch, is );                                               // push back last unmatching character
     1259                                e = fromInt( exact );
     1260                                return is;
     1261                        } //  if
     1262                        // consume input character(s) as garbage
     1263                        throwResume ExceptionInst( missing_data );      // no match found
     1264                } // if
     1265                //printf( "loop match %d\n", match );
    12501266        } // for
    1251 
    1252         for ( c; N ) {                                                                          // scan enumeration strings of length "mcol" for match
    1253                 if ( mcol == lnths[c] - 1 ) {
    1254                         char match = label( fromInt( c ) )[mcol];       // optimization
    1255                         if ( (match == curr) && (mcol == 0 || prev == label( fromInt( c ) )[mcol - 1]) ) {
    1256                                 e = fromInt( c );
    1257                                 break;
    1258                         } // if
    1259                 } // if
    1260         } else {
    1261                 throwResume ExceptionInst( missing_data );              // no match in this column
    1262         } // for
     1267        // printf( "loop end\n" );
     1268        e = fromInt( exact );
    12631269        return is;
    12641270}
    1265 
     1271 
    12661272forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
    12671273        ostype & ?|?( ostype & os, E e ) {
  • libcfa/src/iostream.hfa

    rbd72f517 r0528d79  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 14 20:42:53 2025
    13 // Update Count     : 767
     12// Last Modified On : Mon May 12 17:29:29 2025
     13// Update Count     : 769
    1414//
    1515
     
    317317} // ?|?
    318318
     319
    319320// *********************************** istream ***********************************
     321
    320322
    321323forall( istype & )
     
    528530INPUT_FMT_DECL( long double _Complex )
    529531
     532// *********************************** enumerations ***********************************
     533
     534forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial(E) )
     535istype & ?|?( istype &, E & );
     536
     537forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
     538        ostype & ?|?( ostype &, E );
     539        OSTYPE_VOID( E );
     540}
     541
    530542// *********************************** time ***********************************
    531543
     
    539551} // distribution
    540552
    541 forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial(E) )
    542 istype & ?|?( istype &, E & );
    543 
    544 forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
    545         ostype & ?|?( ostype &, E );
    546         OSTYPE_VOID( E );
    547 }
    548 
    549553// Local Variables: //
    550554// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.