Remove Base 3.14 compatibility
This commit is contained in:
@@ -25,406 +25,6 @@ using std::string;
|
||||
#define NEED_LONGLONG
|
||||
#endif
|
||||
|
||||
#ifndef EPICS_VERSION_INT
|
||||
#define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
|
||||
#define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
|
||||
#endif
|
||||
|
||||
#if EPICS_VERSION_INT < VERSION_INT(3,15,0,1)
|
||||
/* These integer conversion primitives added to epicsStdlib.c in 3.15.0.1 */
|
||||
|
||||
#define S_stdlib_noConversion 1 /* No digits to convert */
|
||||
#define S_stdlib_extraneous 2 /* Extraneous characters */
|
||||
#define S_stdlib_underflow 3 /* Too small to represent */
|
||||
#define S_stdlib_overflow 4 /* Too large to represent */
|
||||
#define S_stdlib_badBase 5 /* Number base not supported */
|
||||
|
||||
static int
|
||||
epicsParseLong(const char *str, long *to, int base, char **units)
|
||||
{
|
||||
int c;
|
||||
char *endp;
|
||||
long value;
|
||||
|
||||
while ((c = *str) && isspace(c))
|
||||
++str;
|
||||
|
||||
errno = 0;
|
||||
value = strtol(str, &endp, base);
|
||||
|
||||
if (endp == str)
|
||||
return S_stdlib_noConversion;
|
||||
if (errno == EINVAL) /* Not universally supported */
|
||||
return S_stdlib_badBase;
|
||||
if (errno == ERANGE)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
while ((c = *endp) && isspace(c))
|
||||
++endp;
|
||||
if (c && !units)
|
||||
return S_stdlib_extraneous;
|
||||
|
||||
*to = value;
|
||||
if (units)
|
||||
*units = endp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseULong(const char *str, unsigned long *to, int base, char **units)
|
||||
{
|
||||
int c;
|
||||
char *endp;
|
||||
unsigned long value;
|
||||
|
||||
while ((c = *str) && isspace(c))
|
||||
++str;
|
||||
|
||||
errno = 0;
|
||||
value = strtoul(str, &endp, base);
|
||||
|
||||
if (endp == str)
|
||||
return S_stdlib_noConversion;
|
||||
if (errno == EINVAL) /* Not universally supported */
|
||||
return S_stdlib_badBase;
|
||||
if (errno == ERANGE)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
while ((c = *endp) && isspace(c))
|
||||
++endp;
|
||||
if (c && !units)
|
||||
return S_stdlib_extraneous;
|
||||
|
||||
*to = value;
|
||||
if (units)
|
||||
*units = endp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseDouble(const char *str, double *to, char **units)
|
||||
{
|
||||
int c;
|
||||
char *endp;
|
||||
double value;
|
||||
|
||||
while ((c = *str) && isspace(c))
|
||||
++str;
|
||||
|
||||
errno = 0;
|
||||
value = epicsStrtod(str, &endp);
|
||||
|
||||
if (endp == str)
|
||||
return S_stdlib_noConversion;
|
||||
if (errno == ERANGE)
|
||||
return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow;
|
||||
|
||||
while ((c = *endp) && isspace(c))
|
||||
++endp;
|
||||
if (c && !units)
|
||||
return S_stdlib_extraneous;
|
||||
|
||||
*to = value;
|
||||
if (units)
|
||||
*units = endp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* These call the primitives */
|
||||
|
||||
static int
|
||||
epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units)
|
||||
{
|
||||
long value;
|
||||
int status = epicsParseLong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value < -0x80 || value > 0x7f)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsInt8)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units)
|
||||
{
|
||||
unsigned long value;
|
||||
int status = epicsParseULong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value > 0xff && value <= ~0xffUL)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsUInt8)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units)
|
||||
{
|
||||
long value;
|
||||
int status = epicsParseLong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value < -0x8000 || value > 0x7fff)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsInt16)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units)
|
||||
{
|
||||
unsigned long value;
|
||||
int status = epicsParseULong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value > 0xffff && value <= ~0xffffUL)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsUInt16)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units)
|
||||
{
|
||||
long value;
|
||||
int status = epicsParseLong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
#if (LONG_MAX > 0x7fffffff)
|
||||
if (value < -0x80000000L || value > 0x7fffffffL)
|
||||
return S_stdlib_overflow;
|
||||
#endif
|
||||
|
||||
*to = (epicsInt32)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units)
|
||||
{
|
||||
unsigned long value;
|
||||
int status = epicsParseULong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
#if (ULONG_MAX > 0xffffffff)
|
||||
if (value > 0xffffffffUL && value <= ~0xffffffffUL)
|
||||
return S_stdlib_overflow;
|
||||
#endif
|
||||
|
||||
*to = (epicsUInt32)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseFloat(const char *str, float *to, char **units)
|
||||
{
|
||||
double value, abs;
|
||||
int status = epicsParseDouble(str, &value, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
abs = fabs(value);
|
||||
if (value > 0 && abs <= FLT_MIN)
|
||||
return S_stdlib_underflow;
|
||||
if (finite(value) && abs >= FLT_MAX)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (float)value;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sometimes we have to provide our own copy of strtoll()
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
// On Windows with MSVC, Base-3.15 provides strtoll()
|
||||
# define NEED_OLL_FUNCS (EPICS_VERSION_INT < VERSION_INT(3,15,0,1))
|
||||
#elif defined(vxWorks)
|
||||
// On VxWorks, Base-3.15 provides strtoll()
|
||||
# define NEED_OLL_FUNCS (EPICS_VERSION_INT < VERSION_INT(3,15,0,1))
|
||||
#else
|
||||
// Other architectures all provide strtoll()
|
||||
# define NEED_OLL_FUNCS 0
|
||||
#endif
|
||||
|
||||
#if defined(NEED_LONGLONG) && NEED_OLL_FUNCS
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined(vxWorks)
|
||||
/* The VxWorks version of std::istringstream >> uint64_t is buggy,
|
||||
* provide our 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)
|
||||
{
|
||||
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
|
||||
#endif
|
||||
|
||||
/* do we need long long? */
|
||||
#ifdef NEED_LONGLONG
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user