From c21c3b0befeb46a51b6bf3758ffa30813bea0ff0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 9 Mar 2024 14:19:22 +0100 Subject: Adding upstream version 1.44.3. Signed-off-by: Daniel Baumann --- fluent-bit/lib/jansson-e23f558/src/strconv.c | 132 +++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 fluent-bit/lib/jansson-e23f558/src/strconv.c (limited to 'fluent-bit/lib/jansson-e23f558/src/strconv.c') diff --git a/fluent-bit/lib/jansson-e23f558/src/strconv.c b/fluent-bit/lib/jansson-e23f558/src/strconv.c new file mode 100644 index 000000000..c6f4fd16b --- /dev/null +++ b/fluent-bit/lib/jansson-e23f558/src/strconv.c @@ -0,0 +1,132 @@ +#include "jansson_private.h" +#include "strbuffer.h" +#include +#include +#include +#include +#include + +/* need jansson_private_config.h to get the correct snprintf */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#if JSON_HAVE_LOCALECONV +#include + +/* + - This code assumes that the decimal separator is exactly one + character. + + - If setlocale() is called by another thread between the call to + localeconv() and the call to sprintf() or strtod(), the result may + be wrong. setlocale() is not thread-safe and should not be used + this way. Multi-threaded programs should use uselocale() instead. +*/ + +static void to_locale(strbuffer_t *strbuffer) { + const char *point; + char *pos; + + point = localeconv()->decimal_point; + if (*point == '.') { + /* No conversion needed */ + return; + } + + pos = strchr(strbuffer->value, '.'); + if (pos) + *pos = *point; +} + +static void from_locale(char *buffer) { + const char *point; + char *pos; + + point = localeconv()->decimal_point; + if (*point == '.') { + /* No conversion needed */ + return; + } + + pos = strchr(buffer, *point); + if (pos) + *pos = '.'; +} +#endif + +int jsonp_strtod(strbuffer_t *strbuffer, double *out) { + double value; + char *end; + +#if JSON_HAVE_LOCALECONV + to_locale(strbuffer); +#endif + + errno = 0; + value = strtod(strbuffer->value, &end); + assert(end == strbuffer->value + strbuffer->length); + + if ((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) { + /* Overflow */ + return -1; + } + + *out = value; + return 0; +} + +int jsonp_dtostr(char *buffer, size_t size, double value, int precision) { + int ret; + char *start, *end; + size_t length; + + if (precision == 0) + precision = 17; + + ret = snprintf(buffer, size, "%.*g", precision, value); + if (ret < 0) + return -1; + + length = (size_t)ret; + if (length >= size) + return -1; + +#if JSON_HAVE_LOCALECONV + from_locale(buffer); +#endif + + /* Make sure there's a dot or 'e' in the output. Otherwise + a real is converted to an integer when decoding */ + if (strchr(buffer, '.') == NULL && strchr(buffer, 'e') == NULL) { + if (length + 3 >= size) { + /* No space to append ".0" */ + return -1; + } + buffer[length] = '.'; + buffer[length + 1] = '0'; + buffer[length + 2] = '\0'; + length += 2; + } + + /* Remove leading '+' from positive exponent. Also remove leading + zeros from exponents (added by some printf() implementations) */ + start = strchr(buffer, 'e'); + if (start) { + start++; + end = start + 1; + + if (*start == '-') + start++; + + while (*end == '0') + end++; + + if (end != start) { + memmove(start, end, length - (size_t)(end - buffer)); + length -= (size_t)(end - start); + } + } + + return (int)length; +} -- cgit v1.2.3