diff --git a/pvDataApp/misc/parseToPOD.cpp b/pvDataApp/misc/parseToPOD.cpp index 4a3efcc..6fad99f 100644 --- a/pvDataApp/misc/parseToPOD.cpp +++ b/pvDataApp/misc/parseToPOD.cpp @@ -245,6 +245,99 @@ epicsParseFloat(const char *str, float *to, char **units) } #endif +#if defined(NEED_LONGLONG) && defined(__vxworks) +static +long long strtoll(const char *ptr, char ** endp, int base) +{ + size_t inlen = strlen(ptr); + long long result; + unsigned char offset=0; + + assert(base==0); + + if(ptr[0]=='-') + offset=1; + + try { + std::istringstream strm(ptr); + + assert(strm.rdbuf()->in_avail()>=0 + && inlen==(size_t)strm.rdbuf()->in_avail()); + + if(ptr[offset]=='0') { + if(ptr[offset+1]=='x') + strm >> std::hex; + else + strm >> std::oct; + } + + strm >> result; + if(strm.fail()) + goto noconvert; + + assert(strm.rdbuf()->in_avail()>=0 + && inlen>=(size_t)strm.rdbuf()->in_avail()); + + size_t consumed = inlen - strm.rdbuf()->in_avail(); + *endp = (char*)ptr + consumed; + + return result; + + } catch(...) { + goto noconvert; + } + + return result; +noconvert: + *endp = (char*)ptr; + return 0; +} + +static +unsigned long long strtoull(const char *ptr, char ** endp, int base) +{ + size_t inlen = strlen(ptr); + unsigned long long result; + + assert(base==0); + + try { + std::istringstream strm(ptr); + + assert(strm.rdbuf()->in_avail()>=0 + && inlen==(size_t)strm.rdbuf()->in_avail()); + + if(ptr[0]=='0') { + if(ptr[1]=='x') + strm >> std::hex; + else + strm >> std::oct; + } + + strm >> result; + if(strm.fail()) + goto noconvert; + + assert(strm.rdbuf()->in_avail()>=0 + && inlen>=(size_t)strm.rdbuf()->in_avail()); + + size_t consumed = inlen - strm.rdbuf()->in_avail(); + *endp = (char*)ptr + consumed; + + return result; + + } catch(...) { + goto noconvert; + } + + return result; +noconvert: + *endp = (char*)ptr; + return 0; +} + +#endif + /* do we need long long? */ #ifdef NEED_LONGLONG static int diff --git a/pvDataApp/misc/typeCast.h b/pvDataApp/misc/typeCast.h index dbf8b1a..b49fcb8 100644 --- a/pvDataApp/misc/typeCast.h +++ b/pvDataApp/misc/typeCast.h @@ -15,7 +15,7 @@ #include // gently nudge the compiler to inline our wrappers -#if defined(__GNUC__) +#if defined(__GNUC__) && __GNUC__>=3 # define FORCE_INLINE __attribute__((always_inline)) inline #elif defined(_MSC_VER) # define FORCE_INLINE __forceinline diff --git a/pvDataApp/pv/pvType.h b/pvDataApp/pv/pvType.h index 93eb1f2..b9ffce7 100644 --- a/pvDataApp/pv/pvType.h +++ b/pvDataApp/pv/pvType.h @@ -20,8 +20,10 @@ #ifdef __vxworks typedef int intptr_t; typedef unsigned int uintptr_t; +#ifndef INT64_MAX #define INT64_MAX (0x7fffffffffffffffLL) #define UINT64_MAX (0xffffffffffffffffLL) +#endif #else #include #endif diff --git a/testApp/misc/testTypeCast.cpp b/testApp/misc/testTypeCast.cpp index 239bf70..a7ca746 100644 --- a/testApp/misc/testTypeCast.cpp +++ b/testApp/misc/testTypeCast.cpp @@ -350,10 +350,23 @@ int main(int argc,char *argv[]) TEST(int32_t, -7, String, "-07"); TEST(int32_t, -8, String, "-010"); + TEST(int64_t, 15, String, "0xf"); + TEST(int64_t, 15, String, "0xF"); + TEST(int64_t, -15, String, "-0xF"); + TEST(int64_t, 16, String, "0x10"); + TEST(int64_t, -16, String, "-0x10"); + + TEST(int64_t, 7, String, "07"); + TEST(int64_t, 8, String, "010"); + TEST(int64_t, -7, String, "-07"); + TEST(int64_t, -8, String, "-010"); + *out << "String parsing errors\n"; FAIL(int32_t, String, "hello!"); FAIL(int32_t, String, "42 is the answer"); + FAIL(int64_t, String, "hello!"); + FAIL(int64_t, String, "42 is the answer"); FAIL(double, String, "hello!"); FAIL(double, String, "42 is the answer");