vxWorks: type cast fixes

This commit is contained in:
Matej Sekoranja
2014-11-06 12:38:01 +01:00
parent 554dc06eda
commit c86e31ad99
3 changed files with 92 additions and 6 deletions

View File

@@ -308,6 +308,71 @@ noconvert:
return 0;
}
#if defined(__vxworks)
/* vxworks version of std::istringstream >>uint64_t is buggy, we use out own implementation */
static
unsigned long long strtoull(const char *nptr, char **endptr, int base)
{
const char *s = nptr;
unsigned long long acc;
int c;
unsigned long long cutoff;
int neg = 0, any, cutlim;
do
c = *s++;
while (isspace(c));
if (c == '-')
{
neg = 1;
c = *s++;
}
else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X'))
{
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = (unsigned long long) UINT64_MAX / (unsigned long long) base;
cutlim = (unsigned long long) UINT64_MAX % (unsigned long long) base;
for (acc = 0, any = 0;; c = *s++)
{
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else
{
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0)
{
acc = UINT64_MAX;
errno = ERANGE;
}
else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = any ? (char *) s - 1 : (char *) nptr;
return (acc);
}
#else
static
unsigned long long strtoull(const char *ptr, char ** endp, int base)
{
@@ -350,7 +415,7 @@ noconvert:
*endp = (char*)ptr;
return 0;
}
#endif
#endif
/* do we need long long? */
@@ -486,6 +551,26 @@ void parseToPOD(const string& in, float *out) {
void parseToPOD(const string& in, double *out) {
int err = epicsParseDouble(in.c_str(), out, NULL);
if(err) handleParseError(err);
#if defined(__vxworks)
/* vxWorks strtod returns [-]epicsINF when it should return ERANGE error
* if [-]epicsINF is returned and first char is a digit then translate this into ERANGE error
*/
else if (*out == epicsINF || *out == -epicsINF) {
const char* s = in.c_str();
int c;
/* skip spaces and the sign */
do {
c = *s++;
} while (isspace(c));
if (c == '-' || c == '+')
c = *s++;
if (isdigit(c))
handleParseError(S_stdlib_overflow);
}
#endif
}
}}}

View File

@@ -29,7 +29,7 @@ typedef int intptr_t;
typedef unsigned int uintptr_t;
#ifndef INT64_MAX
#define INT64_MAX (0x7fffffffffffffffLL)
#define UINT64_MAX (0xffffffffffffffffLL)
#define UINT64_MAX (0xffffffffffffffffULL)
#endif
#else
#include <stdint.h>

View File

@@ -37,11 +37,11 @@ namespace {
};
template<>
struct testequal<double> {
static bool op(double A, double B) {return fabs(A-B)<1e-300; }
static bool op(double A, double B) {return fabs(A-B)<1e-15; }
};
template<>
struct testequal<float> {
static bool op(float A, float B) {return fabs(A-B)<1e-30; }
static bool op(float A, float B) {return fabs(A-B)<1e-7; }
};
template<typename TO, typename FROM>
@@ -117,7 +117,7 @@ namespace {
MAIN(testTypeCast)
{
testPlan(122);
testPlan(123);
try {
@@ -387,7 +387,8 @@ try {
FAIL(int8_t, string, "1000");
FAIL(int8_t, string, "-1000");
FAIL(double, string, "1e+10000000");
FAIL(double, string, "1e+1000");
FAIL(double, string, "-1e+1000");
FAIL(epics::pvData::boolean, string, "hello");
FAIL(epics::pvData::boolean, string, "1");