double ScCLocale::strtod ( const char * str, char ** endptr ) { if(NULL == that()->cLocale) { // a sade workaround double result(0.0); setlocale(LC_NUMERIC, "C"); result = std::strtod(str, endptr); setlocale(LC_NUMERIC, ""); return result; } else { #if defined(Q_WS_WIN) return _strtod_l(str, endptr, that()->cLocale); #else #if defined(Q_OS_SOLARIS) or defined (Q_OS_OPENBSD) or defined (Q_OS_FREEBSD) char *oldlocale=setlocale(LC_NUMERIC, NULL); double result(0.0); setlocale(LC_NUMERIC, "C"); result = std::strtod(str, endptr); setlocale(LC_NUMERIC, oldlocale); return result; #else return strtod_l(str, endptr, that()->cLocale); #endif #endif } }
// Returns false only if parsing should be aborted. bool consume_value(value_t &val, const char** str) { assert(str); const char *c = *str; // Double / float if(*c == '+' || *c == '-') { if(!lc_neutral) { lc_neutral = _create_locale(LC_NUMERIC, "C"); } char *endptr; errno = 0; double result = _strtod_l(*str, &endptr, lc_neutral); if(errno == ERANGE && (result == HUGE_VAL || result == -HUGE_VAL)) { auto val_len = (endptr - *str); log_printf( "ERROR: Floating point constant \"%.*s\" out of range!\n", val_len, str ); return false; } else if(endptr == *str) { // Not actually a floating-point number, keep going though *str += 1; return true; } if(*endptr == 'f') { val.type = VT_FLOAT; val.f = (float)result; endptr++; } else { val.type = VT_DOUBLE; val.d = result; } if(*endptr != ' ' && *endptr != '\0') { val.type = VT_NONE; *str += 1; } else { *str = endptr; } } // Byte else if(is_valid_hex(c[0]) && is_valid_hex(c[1])) { char conv[3]; conv[2] = 0; memcpy(conv, *str, 2); val.type = VT_BYTE; val.b = (unsigned char)strtol(conv, nullptr, 16); *str += 2; } // Nothing, keep going else { *str += 1; } return true; }
double read(const char* s, size_t length) { const char *begin = s; char *end = nullptr; double val = _strtod_l(begin, &end, locale); if (begin == end) { throw std::invalid_argument("Invalid float value"); } return val; }
typename std::enable_if<std::is_same<CharT,char>::value,double>::type operator()(const CharT* s, size_t) const { CharT *end = nullptr; double val = _strtod_l(s, &end, locale_); if (s == end) { JSONCONS_THROW(json_runtime_error<std::invalid_argument>("Convert string to double failed")); } return val; }
inline double string_to_float(const std::string& s) { static _locale_t locale = _create_locale(LC_NUMERIC, "C"); const char* begin = &s[0]; char* end = const_cast<char*>(begin)+s.size(); double val = _strtod_l(begin,&end,locale); if (begin == end) { throw std::invalid_argument("Invalid float value"); } return val; }
double wstrtod(const char *nptr, char **eptr) { double d; char *leptr; #if 0 if (clocale == NULL) clocale = _create_locale(LC_ALL, "C"); #endif d = _strtod_l(nptr, &leptr, clocale); /* if 0, check if input was inf */ if (d == 0 && nptr == leptr) { int neg = 0; while (isspace(*nptr)) nptr++; if (*nptr == '+') nptr++; else if (*nptr == '-') { nptr++; neg = 1; } if (strnicmp("INF", nptr, 3) == 0) { if (eptr != NULL) { if (strnicmp("INFINITE", nptr, 8) == 0) *eptr = (char*)(nptr + 8); else *eptr = (char*)(nptr + 3); } if (neg == 1) return -HUGE_VAL; else return HUGE_VAL; } else if (strnicmp("NAN", nptr, 3) == 0) { if (eptr != NULL) *eptr = (char*)(nptr + 3); /* create a NaN : 0 * infinity*/ d = HUGE_VAL; return d * 0; } } if (eptr != NULL) *eptr = leptr; return d; }
bool GetValue(const std::string& sMessage, double& dval) { std::string svalue = ExtractValue(sMessage); printf("GetValue(\"%s\", double)\n", sMessage.c_str()); #ifdef WIN32 _locale_t loc = _create_locale(LC_ALL, "eng"); char point = '.'; #else std::locale loc(""); char point = std::use_facet<std::numpunct<char> >(loc).decimal_point(); #endif for(size_t p=0; p<svalue.length(); p++) { if (svalue[p] == '.' || svalue[p] == ',') svalue[p] = point; } char *pend; const char* szValue = svalue.c_str(); #ifdef WIN32 double dValue =_strtod_l(szValue, &pend, loc); #else double dValue = strtod(szValue, &pend); #endif // return true only if scan was stopped by spaces, linefeed or the terminating NUL and if the // string was not empty to start with if (pend != szValue) { while( *pend!='\0' && (*pend==' '||*pend=='\n')) pend++; if (*pend=='\0') { dval = dValue; return true; } } return false; }
double _wcstod_l (struct _reent *ptr, const wchar_t *nptr, wchar_t **endptr, locale_t loc) { static const mbstate_t initial; mbstate_t mbs; double val; char *buf, *end; const wchar_t *wcp; size_t len; while (iswspace_l(*nptr, loc)) nptr++; /* * Convert the supplied numeric wide char. string to multibyte. * * We could attempt to find the end of the numeric portion of the * wide char. string to avoid converting unneeded characters but * choose not to bother; optimising the uncommon case where * the input string contains a lot of text after the number * duplicates a lot of strtod()'s functionality and slows down the * most common cases. */ wcp = nptr; mbs = initial; if ((len = _wcsnrtombs_l(ptr, NULL, &wcp, (size_t) -1, 0, &mbs, loc)) == (size_t) -1) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } if ((buf = _malloc_r(ptr, len + 1)) == NULL) return (0.0); mbs = initial; _wcsnrtombs_l(ptr, buf, &wcp, (size_t) -1, len + 1, &mbs, loc); /* Let strtod() do most of the work for us. */ val = _strtod_l(ptr, buf, &end, loc); /* * We only know where the number ended in the _multibyte_ * representation of the string. If the caller wants to know * where it ended, count multibyte characters to find the * corresponding position in the wide char string. */ if (endptr != NULL) { /* The only valid multibyte char in a float converted by strtod/wcstod is the radix char. What we do here is, figure out if the radix char was in the valid leading float sequence in the incoming string. If so, the multibyte float string is strlen(radix char) - 1 bytes longer than the incoming wide char string has characters. To fix endptr, reposition end as if the radix char was just one byte long. The resulting difference (end - buf) is then equivalent to the number of valid wide characters in the input string. */ len = strlen (__localeconv_l (loc)->decimal_point); if (len > 1) { char *d = strstr (buf, __localeconv_l (loc)->decimal_point); if (d && d < end) end -= len - 1; } *endptr = (wchar_t *)nptr + (end - buf); } _free_r(ptr, buf); return (val); }
int soap_s2xsd__duration(struct soap *soap, const char *s, LONG64 *a) { LONG64 sign = 1, Y = 0, M = 0, D = 0, H = 0, N = 0, S = 0; float f = 0; *a = 0; if (s) { if (*s == '-') { sign = -1; s++; } if (*s != 'P' && *s != 'p') return soap->error = SOAP_TYPE; s++; /* date part */ while (s && *s) { char *r = NULL; LONG64 n; if (*s == 'T' || *s == 't') { s++; break; } n = soap_strtol(s, &r, 10); if (!r) return soap->error = SOAP_TYPE; s = r; switch (*s) { case 'Y': case 'y': Y = n; break; case 'M': case 'm': M = n; break; case 'D': case 'd': D = n; break; default: return soap->error = SOAP_TYPE; } s++; } /* time part */ while (s && *s) { char *r = NULL; LONG64 n; n = soap_strtol(s, &r, 10); if (!r) return soap->error = SOAP_TYPE; s = r; switch (*s) { case 'H': case 'h': H = n; break; case 'M': case 'm': N = n; break; case '.': S = n; #if defined(WITH_C_LOCALE) && defined(HAVE_STRTOD_L) # ifdef WIN32 f = (float)_strtod_l(s, NULL, SOAP_LOCALE(soap)); # else f = (float)strtod_l(s, NULL, SOAP_LOCALE(soap)); # endif #elif defined(HAVE_STRTOD) f = (float)strtod(s, NULL); #elif defined(WITH_C_LOCALE) && defined(HAVE_STRTOF_L) f = strtof_l((char*)s, NULL, SOAP_LOCALE(soap)); #elif defined(HAVE_STRTOF) f = strtof((char*)s, NULL); #endif s = NULL; continue; case 'S': case 's': S = n; break; default: return soap->error = SOAP_TYPE; } s++; } /* convert Y-M-D H:N:S.f to signed long long int milliseconds */ *a = sign * ((((((((((((Y * 12) + M) * 30) + D) * 24) + H) * 60) + N) * 60) + S) * 1000) + (LONG64)(1000.0 * f + 0.5)); } return soap->error; }
void ModelicaStrings_scanReal(_In_z_ const char* string, int startIndex, int unsignedNumber, _Out_ int* nextIndex, _Out_ double* number) { /* Grammar of real number: real ::= [sign] unsigned [fraction] [exponent] sign ::= '+' | '-' unsigned ::= digit [unsigned] fraction ::= '.' [unsigned] exponent ::= ('e' | 'E') [sign] unsigned digit ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' */ int len = 0; /* Temporary variable for the length of a matched unsigned number. */ int total_length = 0; /* Total number of characters recognized as part of a decimal number. */ int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); /* Index of first char of token, after ws. */ int exp_len = 0; /* Total number of characters recognized as part of the non-numeric parts * of exponent (the 'e' and the sign). */ /* Scan sign of decimal number */ if (string[token_start-1] == '+' || string[token_start-1] == '-') { total_length = 1; if (unsignedNumber == 1) { goto Modelica_ERROR; } } /* Scan integer part of mantissa. */ len = MatchUnsignedInteger(string, token_start + total_length); total_length += len; /* Scan decimal part of mantissa. */ if (string[token_start + total_length-1] == '.') { total_length += 1; len = MatchUnsignedInteger(string, token_start + total_length); if (len > 0) { total_length += len; } } /* Scan exponent part of mantissa. */ if (string[token_start + total_length-1] == 'e' || string[token_start + total_length-1] == 'E') { /* total_length += 1; */ exp_len = 1; if (string[token_start + total_length] == '+' || string[token_start + total_length] == '-') { exp_len += 1; } len = MatchUnsignedInteger(string, token_start + total_length + exp_len); if (len == 0) { goto Modelica_ERROR; } total_length += exp_len + len; } /* Convert accumulated characters into a number. */ if (total_length > 0 && total_length < MAX_TOKEN_SIZE) { #if defined(NO_LOCALE) const char* const dec = "."; #elif defined(_MSC_VER) && _MSC_VER >= 1400 _locale_t loc = _create_locale(LC_NUMERIC, "C"); #elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) locale_t loc = newlocale(LC_NUMERIC, "C", NULL); #else char* dec = localeconv()->decimal_point; #endif char buf[MAX_TOKEN_SIZE+1]; /* Buffer for copying the part recognized as the number for passing to strtod(). */ char* endptr; /* For error checking of strtod(). */ double x; /* For receiving the result. */ strncpy(buf, string+token_start-1, (size_t)total_length); buf[total_length] = '\0'; #if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) x = _strtod_l(buf, &endptr, loc); _free_locale(loc); #elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) x = strtod_l(buf, &endptr, loc); freelocale(loc); #else if (*dec == '.') { x = strtod(buf, &endptr); } else if (NULL == strchr(buf, '.')) { x = strtod(buf, &endptr); } else { char* p = strchr(buf, '.'); *p = *dec; x = strtod(buf, &endptr); } #endif if (*endptr == 0) { *number = x; *nextIndex = token_start + total_length; return; } } /* Token missing or cannot be converted to result type. */ Modelica_ERROR: *nextIndex = startIndex; *number = 0; return; }