From 1748289348c4c7dcc467edbf7192ade8a1b78921 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 11 Apr 2007 00:12:54 +0000 Subject: [PATCH] added our own implementation of strto[u]ll() if the system doesn't have one (patch 1696533) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45393 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 8 +++ include/wx/wxcrt.h | 12 ++-- src/common/string.cpp | 14 ---- src/common/wxcrt.cpp | 145 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 18 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index eff3612016..5920407601 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -881,6 +881,14 @@ typedef wxUint16 wxWord; typedef wxUint32 wxDword; +#ifdef LLONG_MAX + #define wxINT64_MAX LLONG_MAX + #define wxINT64_MIN LLONG_MIN +#else + #define wxINT64_MAX wxLL(9223372036854775807) + #define wxINT64_MIN wxLL(-9223372036854775807-1) +#endif + /* Define an integral type big enough to contain all of long, size_t and void *. */ diff --git a/include/wx/wxcrt.h b/include/wx/wxcrt.h index dbf8479f59..d4ebf7d492 100644 --- a/include/wx/wxcrt.h +++ b/include/wx/wxcrt.h @@ -586,10 +586,6 @@ #endif /* Unicode/ASCII */ #endif /* TCHAR-aware compilers/the others */ -#ifdef wxStrtoll - #define wxHAS_STRTOLL -#endif - /* various special cases */ @@ -806,6 +802,14 @@ WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */ #define wxUSE_WXVSNPRINTF 0 #endif +#ifndef wxStrtoll + /* supply strtoll and strtoull, if needed */ + WXDLLIMPEXP_BASE wxLongLong_t wxStrtoll(const wxChar* nptr, wxChar** endptr, int base); + WXDLLIMPEXP_BASE wxULongLong_t wxStrtoull(const wxChar* nptr, wxChar** endptr, int base); +#endif + +#define wxHAS_STRTOLL + /* In Unicode mode we need to have all standard functions such as wprintf() and so on but not all systems have them so use our own implementations in this diff --git a/src/common/string.cpp b/src/common/string.cpp index 737ae2441c..9513b69074 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1317,26 +1317,12 @@ bool wxString::ToULong(unsigned long *val, int base) const bool wxString::ToLongLong(wxLongLong_t *val, int base) const { -#ifdef wxHAS_STRTOLL return wxStringToIntType((const wxChar*)c_str(), val, base, wxStrtoll); -#else - // TODO: implement this ourselves - wxUnusedVar(val); - wxUnusedVar(base); - return false; -#endif // wxHAS_STRTOLL } bool wxString::ToULongLong(wxULongLong_t *val, int base) const { -#ifdef wxHAS_STRTOLL return wxStringToIntType((const wxChar*)c_str(), val, base, wxStrtoull); -#else - // TODO: implement this ourselves - wxUnusedVar(val); - wxUnusedVar(base); - return false; -#endif } bool wxString::ToDouble(double *val) const diff --git a/src/common/wxcrt.cpp b/src/common/wxcrt.cpp index 5f08d6d4d4..93b509bdb8 100644 --- a/src/common/wxcrt.cpp +++ b/src/common/wxcrt.cpp @@ -50,6 +50,17 @@ #include #endif +#ifndef wxStrtoll + #ifdef __WXWINCE__ + // there is no errno.h under CE apparently + #define wxSET_ERRNO(value) + #else + #include + + #define wxSET_ERRNO(value) errno = value + #endif +#endif + #if defined(__MWERKS__) && __MSL__ >= 0x6000 namespace std {} using namespace std ; @@ -1132,6 +1143,140 @@ WXDLLEXPORT wxChar *wxCtime(const time_t *timep) #endif // wxUSE_WCHAR_T +#ifndef wxStrtoll +static wxULongLong_t wxStrtoullBase(const wxChar* nptr, wxChar** endptr, int base, wxChar* sign) +{ + wxULongLong_t sum = 0; + wxString wxstr(nptr); + wxString::const_iterator i = wxstr.begin(); + wxString::const_iterator end = wxstr.end(); + + // Skip spaces + while ( i != end && wxIsspace(*i) ) i++; + + // Starts with sign? + *sign = wxT(' '); + if ( i != end ) + { + wxChar c = *i; + if ( c == wxT('+') || c == wxT('-') ) + { + *sign = c; + i++; + } + } + + // Starts with 0x? + if ( i != end && *i == wxT('0') ) + { + i++; + if ( i != end ) + { + if ( *i == wxT('x') && (base == 16 || base == 0) ) + { + base = 16; + i++; + } + else + { + if ( endptr ) + *endptr = (wxChar*) nptr; + wxSET_ERRNO(EINVAL); + return sum; + } + } + else + i--; + } + + if ( base == 0 ) + base = 10; + + for ( ; i != end; i++ ) + { + unsigned int n; + + wxChar c = *i; + if ( c >= wxT('0') ) + { + if ( c <= wxT('9') ) + n = c - wxT('0'); + else + n = wxTolower(c) - wxT('a') + 10; + } + else + break; + + if ( n >= (unsigned int)base ) + // Invalid character (for this base) + break; + + wxULongLong_t prevsum = sum; + sum = (sum * base) + n; + + if ( sum < prevsum ) + { + wxSET_ERRNO(ERANGE); + break; + } + } + + if ( endptr ) + { + const wxChar& endref = *i; + *endptr = &(wxChar&)endref; + } + + return sum; +} + +wxULongLong_t wxStrtoull(const wxChar* nptr, wxChar** endptr, int base) +{ + wxChar sign; + wxULongLong_t uval = wxStrtoullBase(nptr, endptr, base, &sign); + + if ( sign == wxT('-') ) + { + wxSET_ERRNO(ERANGE); + uval = 0; + } + + return uval; +} + +wxLongLong_t wxStrtoll(const wxChar* nptr, wxChar** endptr, int base) +{ + wxChar sign; + wxULongLong_t uval = wxStrtoullBase(nptr, endptr, base, &sign); + wxLongLong_t val = 0; + + if ( sign == wxT('-') ) + { + if ( uval <= wxULL(wxINT64_MAX+1) ) + { + if ( uval == wxULL(wxINT64_MAX+1)) + val = -((wxLongLong_t)wxINT64_MAX) - 1; + else + val = -((wxLongLong_t)uval); + } + else + { + wxSET_ERRNO(ERANGE); + } + } + else if ( uval <= wxINT64_MAX ) + { + val = uval; + } + else + { + wxSET_ERRNO(ERANGE); + } + + return val; +} +#endif // wxStrtoll + // ---------------------------------------------------------------------------- // functions which we may need even if !wxUSE_WCHAR_T // ---------------------------------------------------------------------------- -- 2.45.2