Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    rfd4c009 re474cf09  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 13 13:05:24 2021
    13 // Update Count     : 1324
     12// Last Modified On : Tue Mar  2 14:51:30 2021
     13// Update Count     : 1151
    1414//
    1515
     
    195195                        int len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
    196196                        fmt( os, "%s", buf ); \
    197                         if ( isfinite( val ) ) { /* if number, print decimal point when no fraction or exponent */ \
     197                        if ( isfinite( val ) ) {                                        /* if number, always print decimal point */ \
    198198                                for ( int i = 0;; i += 1 ) { \
    199199                                        if ( i == len ) { fmt( os, "." ); break; } \
    200                                         if ( buf[i] == '.' || buf[i] == 'e' || buf[i] == 'E' ) break; /* decimal point or scientific ? */ \
     200                                        if ( buf[i] == '.' ) break; \
    201201                                } /* for */ \
    202202                        } /* if */ \
     
    525525} // distribution
    526526
    527 IntegralFMTImpl( signed char, "     *hh ", "     *.*hh " )
    528 IntegralFMTImpl( unsigned char, "     *hh ", "     *.*hh " )
    529 IntegralFMTImpl( signed short int, "     *h ", "     *.*h " )
    530 IntegralFMTImpl( unsigned short int, "     *h ", "     *.*h " )
    531 IntegralFMTImpl( signed int, "     * ", "     *.* " )
    532 IntegralFMTImpl( unsigned int, "     * ", "     *.* " )
    533 IntegralFMTImpl( signed long int, "     *l ", "     *.*l " )
    534 IntegralFMTImpl( unsigned long int, "     *l ", "     *.*l " )
    535 IntegralFMTImpl( signed long long int, "     *ll ", "     *.*ll " )
    536 IntegralFMTImpl( unsigned long long int, "     *ll ", "     *.*ll " )
    537 
    538 
     527IntegralFMTImpl( signed char, "%    *hh ", "%    *.*hh " )
     528IntegralFMTImpl( unsigned char, "%    *hh ", "%    *.*hh " )
     529IntegralFMTImpl( signed short int, "%    *h ", "%    *.*h " )
     530IntegralFMTImpl( unsigned short int, "%    *h ", "%    *.*h " )
     531IntegralFMTImpl( signed int, "%    * ", "%    *.* " )
     532IntegralFMTImpl( unsigned int, "%    * ", "%    *.* " )
     533IntegralFMTImpl( signed long int, "%    *l ", "%    *.*l " )
     534IntegralFMTImpl( unsigned long int, "%    *l ", "%    *.*l " )
     535IntegralFMTImpl( signed long long int, "%    *ll ", "%    *.*ll " )
     536IntegralFMTImpl( unsigned long long int, "%    *ll ", "%    *.*ll " )
     537
     538#if 0
     539#if defined( __SIZEOF_INT128__ )
     540// Default prefix for non-decimal prints is 0b, 0, 0x.
     541#define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
     542forall( ostype & | ostream( ostype ) ) \
     543static void base10_128( ostype & os, _Ostream_Manip(T) f ) { \
     544        if ( f.val > UINT64_MAX ) { \
     545                unsigned long long int lsig = f.val % P10_UINT64; \
     546                f.val /= P10_UINT64; /* msig */ \
     547                base10_128( os, f ); /* recursion */ \
     548                _Ostream_Manip(unsigned long long int) fmt @= { lsig, 0, 19, 'u', { .all : 0 } }; \
     549                fmt.flags.nobsdp = true; \
     550                /* printf( "fmt1 %c %lld %d\n", fmt.base, fmt.val, fmt.all ); */ \
     551                sepOff( os ); \
     552                (ostype &)(os | fmt); \
     553        } else { \
     554                /* printf( "fmt2 %c %lld %d\n", f.base, (unsigned long long int)f.val, f.all ); */ \
     555                _Ostream_Manip(SIGNED long long int) fmt @= { (SIGNED long long int)f.val, f.wd, f.pc, f.base, { .all : f.all } }; \
     556                (ostype &)(os | fmt); \
     557        } /* if */ \
     558} /* base10_128 */ \
     559forall( ostype & | ostream( ostype ) ) { \
     560        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     561                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     562\
     563                if ( f.base == 'b' | f.base == 'B' | f.base == 'o' | f.base == 'x' | f.base == 'X' ) { \
     564                        unsigned long long int msig = (unsigned long long int)(f.val >> 64); \
     565                        unsigned long long int lsig = (unsigned long long int)(f.val); \
     566                        _Ostream_Manip(SIGNED long long int) fmt @= { msig, f.wd, f.pc, f.base, { .all : f.all } }; \
     567                        _Ostream_Manip(unsigned long long int) fmt2 @= { lsig, 0, 0, f.base, { .all : 0 } }; \
     568                        if ( msig == 0 ) { \
     569                                fmt.val = lsig; \
     570                                (ostype &)(os | fmt); \
     571                        } else { \
     572                                fmt2.flags.pad0 = fmt2.flags.nobsdp = true;     \
     573                                if ( f.base == 'b' | f.base == 'B' ) { \
     574                                        if ( fmt.flags.pc && fmt.pc > 64 ) fmt.pc -= 64; else { fmt.flags.pc = false; fmt.pc = 0; } \
     575                                        if ( fmt.flags.left ) { \
     576                                                fmt.flags.left = false; \
     577                                                fmt.wd = 0; \
     578                                                /* printf( "L %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
     579                                                fmt2.flags.left = true; \
     580                                                int msigd = high1( msig ); \
     581                                                fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
     582                                                if ( ! fmt.flags.nobsdp ) fmt2.wd -= 2; /* compensate for 0b base specifier */ \
     583                                                if ( (int)fmt2.wd < 64 ) fmt2.wd = 64; /* cast deals with negative value */ \
     584                                                fmt2.flags.pc = true; fmt2.pc = 64; \
     585                                        } else { \
     586                                                if ( fmt.wd > 64 ) fmt.wd -= 64; \
     587                                                else fmt.wd = 1; \
     588                                                /* printf( "R %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
     589                                                fmt2.wd = 64; \
     590                                        } /* if */ \
     591                                        /* printf( "C %llo %d %d '%c' %x\n", fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
     592                                        (ostype &)(os | fmt | "" | fmt2); \
     593                                } else if ( f.base == 'o' ) { \
     594                                        if ( fmt.flags.pc && fmt.pc > 22 ) fmt.pc -= 22; else { fmt.flags.pc = false; fmt.pc = 0; } \
     595                                        fmt.val = (unsigned long long int)fmt.val >> 2; \
     596                                        fmt2.val = ((msig & 0x3) << 1) + ((lsig & 0x8000000000000000U) != 0); \
     597                                        if ( fmt.flags.left ) { \
     598                                                fmt.flags.left = false; \
     599                                                fmt.wd = 0; \
     600                                                /* printf( "L %llo %llo %llo %d %d '%c' %x %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all, fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
     601                                                (ostype &)(os | fmt | "" | fmt2); \
     602                                                sepOff( os ); \
     603                                                fmt2.flags.left = true; \
     604                                                int msigd = ceiling_div( high1( fmt.val ), 3 ); \
     605                                                fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
     606                                                if ( ! fmt.flags.nobsdp ) fmt2.wd -= 1; /* compensate for 0 base specifier */ \
     607                                                if ( (int)fmt2.wd < 21 ) fmt2.wd = 21; /* cast deals with negative value */ \
     608                                                fmt2.flags.pc = true; fmt2.pc = 21; \
     609                                        } else { \
     610                                                if ( fmt.wd > 22 ) fmt.wd -= 22; \
     611                                                else fmt.wd = 1; \
     612                                                /* printf( "R %llo %llo %llo %d %d '%c' %x %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all, fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
     613                                                (ostype &)(os | fmt | "" | fmt2); \
     614                                                sepOff( os ); \
     615                                                fmt2.wd = 21; \
     616                                        } /* if */ \
     617                                        fmt2.val = lsig & 0x7fffffffffffffffU; \
     618                                        /* printf( "\nC %llo %d %d '%c' %x\n", fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
     619                                        (ostype &)(os | fmt2); \
     620                                } else { /* f.base == 'x'  | f.base == 'X' */ \
     621                                        if ( fmt.flags.pc && fmt.pc > 16 ) fmt.pc -= 16; else { fmt.flags.pc = false; fmt.pc = 0; } \
     622                                        if ( fmt.flags.left ) { \
     623                                                fmt.flags.left = false; \
     624                                                fmt.wd = 0; \
     625                                                /* printf( "L %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
     626                                                fmt2.flags.left = true; \
     627                                                int msigd = high1( msig ); \
     628                                                fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
     629                                                if ( ! fmt.flags.nobsdp ) fmt2.wd -= 2; /* compensate for 0x base specifier */ \
     630                                                if ( (int)fmt2.wd < 16 ) fmt2.wd = 16; /* cast deals with negative value */ \
     631                                                fmt2.flags.pc = true; fmt2.pc = 16; \
     632                                        } else { \
     633                                                if ( fmt.wd > 16 ) fmt.wd -= 16; \
     634                                                else fmt.wd = 1; \
     635                                                /* printf( "R %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
     636                                                fmt2.wd = 16; \
     637                                        } /* if */ \
     638                                        /* printf( "C %llo %d %d '%c' %x\n", fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
     639                                        (ostype &)(os | fmt | "" | fmt2); \
     640                                } /* if */ \
     641                        } /* if */ \
     642                } else { \
     643                        if ( CODE == 'd' ) { \
     644                                if ( f.val < 0 )  { fmt( os, "-" ); sepOff( os ); f.val = -f.val; f.flags.sign = false; } \
     645                        } /* if */ \
     646                        base10_128( os, f ); \
     647                } /* if */ \
     648                return os; \
     649        } /* ?|? */ \
     650        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     651} // distribution
     652
     653IntegralFMTImpl128( int128, signed, 'd', "%    *ll ", "%    *.*ll " )
     654IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
     655#endif // __SIZEOF_INT128__
     656#endif // 0
     657
     658#if 1
    539659#if defined( __SIZEOF_INT128__ )
    540660// Default prefix for non-decimal prints is 0b, 0, 0x.
     
    626746IntegralFMTImpl128( unsigned int128 )
    627747#endif // __SIZEOF_INT128__
     748#endif // 0
    628749
    629750// *********************************** floating point ***********************************
    630751
    631 static const char *suffixes[] = {
    632         "y", "z", "a", "f", "p", "n", "u", "m", "",
    633         "K", "M", "G", "T", "P", "E", "Z", "Y"
    634 };
    635 #define SUFFIXES_START (-24) /* Smallest power for which there is a suffix defined. */
    636 #define SUFFIXES_END (SUFFIXES_START + (int)((sizeof(suffixes) / sizeof(char *) - 1) * 3))
    637 
    638 #define PrintWithDP2( os, format, ... ) \
     752#define PrintWithDP2( os, format, val, ... ) \
    639753        { \
    640                 if ( ! f.flags.eng ) { \
    641                         len = snprintf( buf, size, format, ##__VA_ARGS__ ); \
    642                         if ( isfinite( f.val ) && ( f.pc != 0 || ! f.flags.nobsdp ) ) { /* if number, print decimal point when no fraction or exponent */ \
    643                                 for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
    644                                 if ( i == len ) { \
    645                                         if ( ! f.flags.left ) { \
    646                                                 buf[i] = '.'; buf[i + 1] = '\0'; \
    647                                                 if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
    648                                         } else { \
    649                                                 for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
    650                                                 buf[i] = '.'; \
    651                                                 if ( i == len ) buf[i + 1] = '\0'; \
    652                                         } /* if */ \
     754                enum { size = 48 }; \
     755                char buf[size]; \
     756                int bufbeg = 0, i, len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
     757                if ( isfinite( val ) && (f.base != 'g' || f.pc != 0) ) { /* if number, print decimal point */ \
     758                        for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
     759                        if ( i == len && ! f.flags.nobsdp ) { \
     760                                if ( ! f.flags.left ) { \
     761                                        buf[i] = '.'; buf[i + 1] = '\0'; \
     762                                        if ( buf[0] == ' ' ) bufbeg = 1;        /* decimal point within width */ \
     763                                } else { \
     764                                        for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
     765                                        buf[i] = '.'; \
     766                                        if ( i == len ) buf[i + 1] = '\0'; \
    653767                                } /* if */ \
    654768                        } /* if */ \
    655                 } else { \
    656                         int exp10, len2; \
    657                         eng( f.val, f.pc, exp10 );                                      /* changes arguments */ \
    658                         if ( ! f.flags.left && f.wd > 1 ) { \
    659                                 /* Exponent size (number of digits, 'e', optional minus sign) */ \
    660                                 f.wd -= lrint( floor( log10( abs( exp10 ) ) ) ) + 1 + 1 + (exp10 < 0 ? 1 : 0); \
    661                                 if ( f.wd < 1 ) f.wd = 1; \
    662                         } /* if */ \
    663                         len = snprintf( buf, size, format, ##__VA_ARGS__ ); \
    664                         if ( f.flags.left ) { \
    665                                 for ( len -= 1; len > 0 && buf[len] == ' '; len -= 1 ); \
    666                                 len += 1; \
    667                         } /* if */ \
    668                         if ( ! f.flags.nobsdp || (exp10 < SUFFIXES_START) || (exp10 > SUFFIXES_END) ) { \
    669                                 len2 = snprintf( &buf[len], size - len, "e%d", exp10 ); \
    670                         } else { \
    671                                 len2 = snprintf( &buf[len], size - len, "%s", suffixes[(exp10 - SUFFIXES_START) / 3] ); \
    672                         } /* if */ \
    673                         if ( f.flags.left && len + len2 < f.wd ) buf[len + len2] = ' '; \
    674769                } /* if */ \
    675770                fmt( os, "%s", &buf[bufbeg] ); \
     
    678773#define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \
    679774forall( ostype & | ostream( ostype ) ) { \
    680         static void eng( T &value, int & pc, int & exp10 ) { \
    681                 exp10 = lrint( floor( log10( abs( value ) ) ) ); /* round to desired precision */ \
    682                 if ( exp10 < 0 ) exp10 -= 2; \
    683                 exp10 = floor( exp10, 3 ); \
    684                 value *= pow( 10.0, -exp10 ); \
    685                 if ( pc <= 3 ) pc = 3; \
    686         } /* eng */ \
    687 \
    688775        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    689                 enum { size = 48 }; \
    690                 char buf[size]; \
    691                 int bufbeg = 0, i, len; \
    692 \
    693776                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    694                 char fmtstr[sizeof(DFMTP) + 8];                                 /* sizeof includes '\0' */ \
     777                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
    695778                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
    696779                else memcpy( &fmtstr, DFMTP, sizeof(DFMTP) ); \
     
    706789                        fmtstr[sizeof(DFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    707790                        /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
    708                         PrintWithDP2( os, &fmtstr[star], f.wd, f.val ) \
     791                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd ) \
    709792                } else {                                                                                /* precision */ \
    710793                        fmtstr[sizeof(DFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    711794                        /* printf( "%g %d %d %s\n", f.val, f.wd, f.pc, &fmtstr[star] ); */ \
    712                         PrintWithDP2( os, &fmtstr[star], f.wd, f.pc, f.val ) \
     795                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd, f.pc ) \
    713796                } /* if */ \
    714797                return os; \
     
    718801} // distribution
    719802
    720 FloatingPointFMTImpl( double, "     * ", "     *.* " )
    721 FloatingPointFMTImpl( long double, "     *L ", "     *.*L " )
     803FloatingPointFMTImpl( double, "%    * ", "%    *.* " )
     804FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
    722805
    723806// *********************************** character ***********************************
Note: See TracChangeset for help on using the changeset viewer.