Changes in / [2583407:3ad5c50]


Ignore:
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/stdlib.cfa

    r2583407 r3ad5c50  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 14 18:22:36 2023
    13 // Update Count     : 642
     12// Last Modified On : Fri Mar 15 18:47:28 2024
     13// Update Count     : 685
    1414//
    1515
     
    2424#include <complex.h>                                                                    // _Complex_I
    2525#include <assert.h>
     26#include <ctype.h>
    2627
    2728#pragma GCC visibility push(default)
     
    6566//---------------------------------------
    6667
     68// Cannot overload with singular (isspace) counterparts because they are macros.
     69
     70bool isalnums( const char s[] ) {
     71        for () {
     72                if ( *s == '\0' ) return true;
     73                if ( ! isalnum( *s ) ) return false;
     74                s += 1;
     75        } // for
     76} // isalnums
     77
     78bool isalphas( const char s[] ) {
     79        for () {
     80                if ( *s == '\0' ) return true;
     81                if ( ! isalpha( *s ) ) return false;
     82                s += 1;
     83        } // for
     84} // isblanks
     85
     86bool iscntrls( const char s[] ) {
     87        for () {
     88                if ( *s == '\0' ) return true;
     89                if ( ! iscntrl( *s ) ) return false;
     90                s += 1;
     91        } // for
     92} // iscntrls
     93
     94bool isdigits( const char s[] ) {
     95        for () {
     96                if ( *s == '\0' ) return true;
     97                if ( ! isdigit( *s ) ) return false;
     98                s += 1;
     99        } // for
     100} // isdigits
     101
     102bool isgraphs( const char s[] ) {
     103        for () {
     104                if ( *s == '\0' ) return true;
     105                if ( ! isgraph( *s ) ) return false;
     106                s += 1;
     107        } // for
     108} // isgraphs
     109
     110bool islowers( const char s[] ) {
     111        for () {
     112                if ( *s == '\0' ) return true;
     113                if ( ! islower( *s ) ) return false;
     114                s += 1;
     115        } // for
     116} // islowers
     117
     118bool isprints( const char s[] ) {
     119        for () {
     120                if ( *s == '\0' ) return true;
     121                if ( ! isprint( *s ) ) return false;
     122                s += 1;
     123        } // for
     124} // isprints
     125
     126bool ispuncts( const char s[] ) {
     127        for () {
     128                if ( *s == '\0' ) return true;
     129                if ( ! ispunct( *s ) ) return false;
     130                s += 1;
     131        } // for
     132} // ispuncts
     133
     134bool isspaces( const char s[] ) {
     135        for () {
     136                if ( *s == '\0' ) return true;
     137                if ( ! isspace( *s ) ) return false;
     138                s += 1;
     139        } // for
     140} // isspaces
     141
     142bool isblanks( const char s[] ) {
     143        for () {
     144                if ( *s == '\0' ) return true;
     145                if ( ! isblank( *s ) ) return false;
     146                s += 1;
     147        } // for
     148} // isblanks
     149
     150bool isuppers( const char s[] ) {
     151        for () {
     152                if ( *s == '\0' ) return true;
     153                if ( ! isupper( *s ) ) return false;
     154                s += 1;
     155        } // for
     156} // isuppers
     157
     158bool isxdigits( const char s[] ) {
     159        for () {
     160                if ( *s == '\0' ) return true;
     161                if ( ! isxdigit( *s ) ) return false;
     162                s += 1;
     163        } // for
     164} // isxdigits
     165
     166//---------------------------------------
     167
     168float _Complex strto( const char sptr[], char * eptr[] ) {
     169        float re, im;
     170        char * eeptr;
     171        errno = 0;                                                                                      // reset
     172        re = strtof( sptr, &eeptr );
     173        if ( sptr != eeptr ) {
     174                im = strtof( eeptr, &eeptr );
     175                if ( sptr != eeptr ) {
     176                        if ( *eeptr == 'i' ) {
     177                                if ( eptr != 0p ) *eptr = eeptr + 1;
     178                                return re + im * _Complex_I;
     179                        } // if
     180                } // if
     181        } // if
     182        if ( eptr != 0p ) *eptr = eeptr;                                        // error case
     183        return 0.0f + 0.0f * _Complex_I;
     184} // strto
     185
     186double _Complex strto( const char sptr[], char * eptr[] ) {
     187        double re, im;
     188        char * eeptr;
     189        re = strtod( sptr, &eeptr );
     190        if ( sptr != eeptr ) {
     191                im = strtod( eeptr, &eeptr );
     192                if ( sptr != eeptr ) {
     193                        if ( *eeptr == 'i' ) {
     194                                if ( eptr != 0p ) *eptr = eeptr + 1;
     195                                return re + im * _Complex_I;
     196                        } // if
     197                } // if
     198        } // if
     199        if ( eptr != 0p ) *eptr = eeptr;                                        // error case
     200        return 0.0 + 0.0 * _Complex_I;
     201} // strto
     202
     203long double _Complex strto( const char sptr[], char * eptr[] ) {
     204        long double re, im;
     205        char * eeptr;
     206        re = strtold( sptr, &eeptr );
     207        if ( sptr != eeptr ) {
     208                im = strtold( eeptr, &eeptr );
     209                if ( sptr != eeptr ) {
     210                        if ( *eeptr == 'i' ) {
     211                                if ( eptr != 0p ) *eptr = eeptr + 1;
     212                                return re + im * _Complex_I;
     213                        } // if
     214                } // if
     215        } // if
     216        if ( eptr != 0p ) *eptr = eeptr;                                        // error case
     217        return 0.0L + 0.0L * _Complex_I;
     218} // strto
     219
    67220forall( T | { T strto( const char sptr[], char * eptr[], int ); } )
    68 T convert( const char sptr[] ) {
     221T convert( const char sptr[] ) {                                                // integral
    69222        char * eptr;
    70223        errno = 0;                                                                                      // reset
     
    72225        if ( errno == ERANGE ) throw ExceptionInst( out_of_range );
    73226        if ( eptr == sptr ||                                                            // conversion failed, no characters generated
    74                  *eptr != '\0' ) throw ExceptionInst( invalid_argument ); // not at end of str ?
     227                 eptr[0] != '\0' && ! isspaces( eptr ) ) throw ExceptionInst( invalid_argument ); // not at end of blank str ?
    75228        return val;
    76229} // convert
    77230
    78 float _Complex strto( const char sptr[], char * eptr[] ) {
    79         float re, im;
    80         char * eeptr;
    81         re = strtof( sptr, &eeptr );
    82         if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }
    83         im = strtof( eeptr, &eeptr );
    84         if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }
    85         if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }
    86         return re + im * _Complex_I;
    87 } // strto
    88 
    89 double _Complex strto( const char sptr[], char * eptr[] ) {
    90         double re, im;
    91         char * eeptr;
    92         re = strtod( sptr, &eeptr );
    93         if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }
    94         im = strtod( eeptr, &eeptr );
    95         if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }
    96         if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }
    97         return re + im * _Complex_I;
    98 } // strto
    99 
    100 long double _Complex strto( const char sptr[], char * eptr[] ) {
    101         long double re, im;
    102         char * eeptr;
    103         re = strtold( sptr, &eeptr );
    104         if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }
    105         im = strtold( eeptr, &eeptr );
    106         if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }
    107         if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }
    108         return re + im * _Complex_I;
    109 } // strto
     231forall( T | { T strto( const char sptr[], char * eptr[] ); } )
     232T convert( const char sptr[] ) {                                                // floating-point
     233        char * eptr;
     234        errno = 0;                                                                                      // reset
     235        T val = strto( sptr, &eptr );                                           // attempt conversion
     236        if ( errno == ERANGE ) throw ExceptionInst( out_of_range );
     237        if ( eptr == sptr ||                                                            // conversion failed, no characters generated
     238                 eptr[0] != '\0' && ! isspaces( eptr ) ) throw ExceptionInst( invalid_argument ); // not at end of blank str ?
     239        return val;
     240} // convert
    110241
    111242//---------------------------------------
  • libcfa/src/stdlib.hfa

    r2583407 r3ad5c50  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Oct  8 09:18:28 2023
    13 // Update Count     : 789
     12// Last Modified On : Fri Mar 15 18:47:26 2024
     13// Update Count     : 792
    1414//
    1515
     
    291291forall( T & | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] );
    292292forall( T & | sized(T) | { void ^?{}( T & ); }, TT... | { void adelete( TT ); } ) void adelete( T arr[], TT rest );
     293//---------------------------------------
     294
     295// Cannot overload with singular (isspace) counterparts because they are macros.
     296
     297bool isalnums( const char s[] );
     298bool isalphas( const char s[] );
     299bool iscntrls( const char s[] );
     300bool isdigits( const char s[] );
     301bool isgraphs( const char s[] );
     302bool islowers( const char s[] );
     303bool isprints( const char s[] );
     304bool ispuncts( const char s[] );
     305bool isspaces( const char s[] );
     306bool isblanks( const char s[] );
     307bool isuppers( const char s[] );
     308bool isxdigits( const char s[] );
    293309
    294310//---------------------------------------
     
    315331
    316332forall( T | { T strto( const char sptr[], char * eptr[], int ); } )
    317 T convert( const char sptr[] );
     333T convert( const char sptr[] );                                                 // integrals
     334forall( T | { T strto( const char sptr[], char * eptr[] ); } )
     335T convert( const char sptr[] );                                                 // floating-point (no base)
    318336
    319337static inline {
  • tests/.expect/ato.x64.txt

    r2583407 r3ad5c50  
    33-123 -123
    44123 123
     5-123 -123
     6123 123
     7-123.456 -123.456
     8-123.456789012346 -123.4567890123456
     9-123.456789012345679 -123.45678901234567890123456789
     10-123.456-123.456i -123.456-123.456i
     11-123.456789012346+123.456789012346i -123.4567890123456+123.4567890123456i
     12123.456789012345679-123.456789012345679i 123.45678901234567890123456789-123.45678901234567890123456789i
     13123.45678901234-123.456789i 123.45678901234 -123.4567890i
    514-123 -123
    615123 123
     16-123 -123
     17123 123
     18-123 -123
     19123 123
    720-123.456 -123.456
    821-123.456789012346 -123.4567890123456
    9 -123.456789012345679 -123.45678901234567890123456789
     22-123.456789012345679 -123.45678901234567890123456789
     23-123.456-123.456i -123.456-123.456i
     24-123.456789012346+123.456789012346i -123.4567890123456+123.4567890123456i
     25123.456789012345679-123.456789012345679i 123.45678901234567890123456789-123.45678901234567890123456789i
     26123.45678901234-123.456789i 123.45678901234 -123.4567890i
     27invalid argument 2.0fred
     28invalid argument 2  3x
     29-123 -123
     30123 123
     31-123 -123
     32123 123
     33-123 -123
     34123 123
     35-123.456 -123.456
     36-123.456789012346 -123.4567890123456
     37-123.456789012345679 -123.45678901234567890123456789
    1038-123.456-123.456i -123.456-123.456i
    1139-123.456789012346+123.456789012346i -123.4567890123456+123.4567890123456i
    1240123.456789012345679-123.456789012345679i 123.45678901234567890123456789-123.45678901234567890123456789i
    1341123.45678901234-123.456789i 123.45678901234-123.4567890i
    14 -123 -123
    15 123 123
    16 -123 -123
    17 123 123
    18 -123 -123
    19 123 123
    20 -123.456 -123.456
    21 -123.456789012346 -123.4567890123456
    22 -123.456789012345679 -123.45678901234567890123456789
    23 -123.456-123.456i -123.456-123.456i
    24 0.+0.i 2  3
    25 -123.456789012346+123.456789012346i -123.4567890123456+123.4567890123456i
    26 123.456789012345679-123.456789012345679i 123.45678901234567890123456789-123.45678901234567890123456789i
    27 123.45678901234-123.456789i 123.45678901234-123.4567890i
     42invalid argument 2.0fred
     43invalid argument 2  3x
  • tests/ato.cfa

    r2583407 r3ad5c50  
    1010// Created On       : Thu Feb  4 08:10:57 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  4 21:33:53 2018
    13 // Update Count     : 92
     12// Last Modified On : Fri Mar 15 17:58:35 2024
     13// Update Count     : 145
    1414//
    1515
     
    1818
    1919int main( void ) {
     20        // ato
     21
    2022        const char * sptr = "-123";
    2123        int i = ato( sptr );
     
    3234        sout | uli | sptr;
    3335
    34         sptr = "-123";
     36        sptr = " -123 ";                                                                        // spaces allowed
    3537        long long int lli = ato( sptr );
    3638        sout | lli | sptr;
    37         sptr = "123";
     39        sptr = " 123 ";                                                                         // spaces allowed
    3840        unsigned long long int ulli = ato( sptr );
    3941        sout | ulli | sptr;
     
    4547        double d = ato( sptr );
    4648        sout | d | sptr;
    47         sptr = "-123.45678901234567890123456789";
     49        sptr = " -123.45678901234567890123456789 ";                     // spaces allowed
    4850        long double ld = ato( sptr );
    4951        sout | ld | sptr;
     
    5860        long double _Complex ldc = ato( sptr );
    5961        sout | ldc | sptr;
    60         sptr = "123.45678901234-123.4567890i";
     62        sptr = " 123.45678901234 -123.4567890i ";                       // spaces allowed
    6163        long double _Complex ldc2 = ato( sptr );
    6264        sout | ldc2 | sptr;
    6365
     66        // strto
    6467
    6568        sptr = "-123";
    66         i = strto( sptr, 0, 10 );
     69        i = strto( sptr, 0p, 10 );
    6770        sout | i | sptr;
    6871        sptr = "123";
    69         ui = strto( sptr, 0, 10 );
     72        ui = strto( sptr, 0p, 10 );
    7073        sout | ui | sptr;
    7174
    7275        sptr = "-123";
    73         li = strto( sptr, 0, 10 );
     76        li = strto( sptr, 0p, 10 );
    7477        sout | li | sptr;
    7578        sptr = "123";
    76         uli = strto( sptr, 0, 10 );
     79        uli = strto( sptr, 0p, 10 );
    7780        sout | uli | sptr;
    7881
    79         sptr = "-123";
    80         lli = strto( sptr, 0, 10 );
     82        sptr = " -123 ";                                                                        // spaces allowed
     83        lli = strto( sptr, 0p, 10 );
    8184        sout | lli | sptr;
    82         sptr = "123";
    83         ulli = strto( sptr, 0, 10 );
     85        sptr = " 123 ";                                                                         // spaces allowed
     86        ulli = strto( sptr, 0p, 10 );
    8487        sout | ulli | sptr;
    8588
    8689        sptr = "-123.456";
    87         f = strto( sptr, 0 );
     90        f = strto( sptr, 0p );
    8891        sout | f | sptr;
    8992        sptr = "-123.4567890123456";
    90         d = strto( sptr, 0 );
     93        d = strto( sptr, 0p );
    9194        sout | d | sptr;
    92         sptr = "-123.45678901234567890123456789";
    93         ld = strto( sptr, 0 );
     95        sptr = " -123.45678901234567890123456789 ";                     // spaces allowed
     96        ld = strto( sptr, 0p );
    9497        sout | ld | sptr;
    9598
    9699        sptr = "-123.456-123.456i";
    97         fc = strto( sptr, 0 );
     100        fc = strto( sptr, 0p );
    98101        sout | fc | sptr;
    99 
    100         char * eptr = 0;
    101         // sptr = "2fred";
    102         // fc = strto( sptr, &eptr );
    103         // sout | fc | sptr | eptr;
    104 
    105         sptr = "2  3";
    106         fc = strto( sptr, &eptr );
    107         sout | fc | sptr | eptr;
    108 
    109102        sptr = "-123.4567890123456+123.4567890123456i";
    110         dc = strto( sptr, 0 );
     103        dc = strto( sptr, 0p );
    111104        sout | dc | sptr;
    112105        sptr = "123.45678901234567890123456789-123.45678901234567890123456789i";
    113         ldc = strto( sptr, 0 );
     106        ldc = strto( sptr, 0p );
     107        sout | ldc | sptr;
     108        sptr = " 123.45678901234 -123.4567890i ";                       // spaces allowed
     109        ldc2 = strto( sptr, 0p );
     110        sout | ldc2 | sptr;
     111
     112        sptr = "2.0fred";
     113        char * eptr = 0p;
     114        errno = 0;                                                                                      // reset
     115        f = strto( sptr, &eptr );
     116        if ( errno == ERANGE ) sout | "out of range";
     117        if ( eptr == sptr ||                                                            // conversion failed, no characters generated
     118                 *eptr != '\0' ) sout | "invalid argument" | sptr; // not at end of str ?
     119        else assert( false );
     120
     121        sptr = "2  3x";
     122        eptr = 0p;
     123        errno = 0;                                                                                      // reset
     124        fc = strto( sptr, &eptr );
     125        if ( errno == ERANGE ) sout | "out of range";
     126        if ( eptr == sptr ||                                                            // conversion failed, no characters generated
     127                 *eptr != '\0' ) sout | "invalid argument" | sptr; // not at end of str ?
     128        else assert( false );
     129
     130        // convert
     131
     132        sptr = "-123";
     133        i = convert( sptr );
     134        sout | i | sptr;
     135        sptr = "123";
     136        ui = convert( sptr );
     137        sout | ui | sptr;
     138
     139        sptr = "-123";
     140        li = convert( sptr );
     141        sout | li | sptr;
     142        sptr = "123";
     143        uli = convert( sptr );
     144        sout | uli | sptr;
     145
     146        sptr = " -123 ";                                                                        // spaces allowed
     147        lli = convert( sptr );
     148        sout | lli | sptr;
     149        sptr = " 123 ";                                                                         // spaces allowed
     150        ulli = convert( sptr );
     151        sout | ulli | sptr;
     152
     153        sptr = "-123.456";
     154        f = convert( sptr );
     155        sout | f | sptr;
     156        sptr = "-123.4567890123456";
     157        d = convert( sptr );
     158        sout | d | sptr;
     159        sptr = " -123.45678901234567890123456789 ";                     // spaces allowed
     160        ld = convert( sptr );
     161        sout | ld | sptr;
     162
     163        sptr = "-123.456-123.456i";
     164        fc = convert( sptr );
     165        sout | fc | sptr;
     166        sptr = "-123.4567890123456+123.4567890123456i";
     167        dc = convert( sptr );
     168        sout | dc | sptr;
     169        sptr = "123.45678901234567890123456789-123.45678901234567890123456789i";
     170        ldc = convert( sptr );
    114171        sout | ldc | sptr;
    115172        sptr = "123.45678901234-123.4567890i";
    116         ldc2 = strto( sptr, 0 );
     173        ldc2 = convert( sptr );
    117174        sout | ldc2 | sptr;
     175
     176        sptr = "2.0fred";
     177        try {
     178                f = convert( sptr );
     179                assert( false );
     180        } catch( invalid_argument * ) {
     181                sout | "invalid argument" | sptr;
     182        } // try
     183
     184        sptr = "2  3x";
     185        try {
     186                fc = convert( sptr );
     187                assert( false );
     188        } catch( invalid_argument * ) {
     189                sout | "invalid argument" | sptr;
     190        } // try
    118191} // main
    119192
Note: See TracChangeset for help on using the changeset viewer.