mirror of
https://github.com/zeek/zeek.git
synced 2025-10-01 22:28:20 +00:00
src/3rdparty: numeric conversion functions now return the number of characters added
This commit is contained in:
parent
3e4512bc80
commit
790e920d66
2 changed files with 60 additions and 46 deletions
76
src/3rdparty/modp_numtoa.c
vendored
76
src/3rdparty/modp_numtoa.c
vendored
|
@ -34,7 +34,8 @@ static void strreverse(char* begin, char* end)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expects 'str' to have been made using "%e" scientific notation format string
|
// Expects 'str' to have been made using "%e" scientific notation format string
|
||||||
static void sn_strip_trailing_zeros(char* str)
|
// Returns the number of characters removed
|
||||||
|
static size_t sn_strip_trailing_zeros(char* str)
|
||||||
{
|
{
|
||||||
char* frac = 0;
|
char* frac = 0;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ static void sn_strip_trailing_zeros(char* str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! frac )
|
if ( ! frac )
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
char* start_dec = frac;
|
char* start_dec = frac;
|
||||||
char* exp = 0;
|
char* exp = 0;
|
||||||
|
@ -84,22 +85,26 @@ static void sn_strip_trailing_zeros(char* str)
|
||||||
if ( trailing_zeros == start_dec )
|
if ( trailing_zeros == start_dec )
|
||||||
--trailing_zeros;
|
--trailing_zeros;
|
||||||
|
|
||||||
if ( trailing_zeros && exp )
|
if ( ! trailing_zeros || ! exp )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
char* start_exp = exp;
|
||||||
|
|
||||||
|
for ( ; ; )
|
||||||
{
|
{
|
||||||
for ( ; ; )
|
*trailing_zeros = *exp;
|
||||||
{
|
|
||||||
*trailing_zeros = *exp;
|
|
||||||
|
|
||||||
if ( *exp == 0 )
|
if ( *exp == 0 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
++trailing_zeros;
|
++trailing_zeros;
|
||||||
++exp;
|
++exp;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return exp - start_exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modp_itoa10(int32_t value, char* str)
|
size_t modp_itoa10(int32_t value, char* str)
|
||||||
{
|
{
|
||||||
char* wstr=str;
|
char* wstr=str;
|
||||||
// Take care of sign
|
// Take care of sign
|
||||||
|
@ -111,9 +116,10 @@ void modp_itoa10(int32_t value, char* str)
|
||||||
|
|
||||||
// Reverse string
|
// Reverse string
|
||||||
strreverse(str,wstr-1);
|
strreverse(str,wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modp_uitoa10(uint32_t value, char* str)
|
size_t modp_uitoa10(uint32_t value, char* str)
|
||||||
{
|
{
|
||||||
char* wstr=str;
|
char* wstr=str;
|
||||||
// Conversion. Number is reversed.
|
// Conversion. Number is reversed.
|
||||||
|
@ -121,9 +127,10 @@ void modp_uitoa10(uint32_t value, char* str)
|
||||||
*wstr='\0';
|
*wstr='\0';
|
||||||
// Reverse string
|
// Reverse string
|
||||||
strreverse(str, wstr-1);
|
strreverse(str, wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modp_litoa10(int64_t value, char* str)
|
size_t modp_litoa10(int64_t value, char* str)
|
||||||
{
|
{
|
||||||
char* wstr=str;
|
char* wstr=str;
|
||||||
uint64_t uvalue = (value < 0) ? (value == INT64_MIN ? (uint64_t)(INT64_MAX) + 1 : -value) : value;
|
uint64_t uvalue = (value < 0) ? (value == INT64_MIN ? (uint64_t)(INT64_MAX) + 1 : -value) : value;
|
||||||
|
@ -135,9 +142,10 @@ void modp_litoa10(int64_t value, char* str)
|
||||||
|
|
||||||
// Reverse string
|
// Reverse string
|
||||||
strreverse(str,wstr-1);
|
strreverse(str,wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modp_ulitoa10(uint64_t value, char* str)
|
size_t modp_ulitoa10(uint64_t value, char* str)
|
||||||
{
|
{
|
||||||
char* wstr=str;
|
char* wstr=str;
|
||||||
// Conversion. Number is reversed.
|
// Conversion. Number is reversed.
|
||||||
|
@ -145,9 +153,10 @@ void modp_ulitoa10(uint64_t value, char* str)
|
||||||
*wstr='\0';
|
*wstr='\0';
|
||||||
// Reverse string
|
// Reverse string
|
||||||
strreverse(str, wstr-1);
|
strreverse(str, wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modp_dtoa(double value, char* str, int prec)
|
size_t modp_dtoa(double value, char* str, int prec)
|
||||||
{
|
{
|
||||||
/* Hacky test for NaN
|
/* Hacky test for NaN
|
||||||
* under -fast-math this won't work, but then you also won't
|
* under -fast-math this won't work, but then you also won't
|
||||||
|
@ -156,7 +165,7 @@ void modp_dtoa(double value, char* str, int prec)
|
||||||
*/
|
*/
|
||||||
if (! (value == value)) {
|
if (! (value == value)) {
|
||||||
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
|
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
|
||||||
return;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we'll work in positive values and deal with the
|
/* we'll work in positive values and deal with the
|
||||||
|
@ -177,9 +186,9 @@ void modp_dtoa(double value, char* str, int prec)
|
||||||
which can be 100s of characters overflowing your buffers == bad
|
which can be 100s of characters overflowing your buffers == bad
|
||||||
*/
|
*/
|
||||||
if (value >= thres_max) {
|
if (value >= thres_max) {
|
||||||
sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
int n = sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
||||||
sn_strip_trailing_zeros(str);
|
n -= sn_strip_trailing_zeros(str);
|
||||||
return;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
double diff = 0.0;
|
double diff = 0.0;
|
||||||
|
@ -242,12 +251,13 @@ void modp_dtoa(double value, char* str, int prec)
|
||||||
}
|
}
|
||||||
*wstr='\0';
|
*wstr='\0';
|
||||||
strreverse(str, wstr-1);
|
strreverse(str, wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This is near identical to modp_dtoa above
|
// This is near identical to modp_dtoa above
|
||||||
// The differnce is noted below
|
// The differnce is noted below
|
||||||
void modp_dtoa2(double value, char* str, int prec)
|
size_t modp_dtoa2(double value, char* str, int prec)
|
||||||
{
|
{
|
||||||
/* Hacky test for NaN
|
/* Hacky test for NaN
|
||||||
* under -fast-math this won't work, but then you also won't
|
* under -fast-math this won't work, but then you also won't
|
||||||
|
@ -256,7 +266,7 @@ void modp_dtoa2(double value, char* str, int prec)
|
||||||
*/
|
*/
|
||||||
if (! (value == value)) {
|
if (! (value == value)) {
|
||||||
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
|
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
|
||||||
return;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we'll work in positive values and deal with the
|
/* we'll work in positive values and deal with the
|
||||||
|
@ -277,9 +287,9 @@ void modp_dtoa2(double value, char* str, int prec)
|
||||||
which can be 100s of characters overflowing your buffers == bad
|
which can be 100s of characters overflowing your buffers == bad
|
||||||
*/
|
*/
|
||||||
if (value >= thres_max) {
|
if (value >= thres_max) {
|
||||||
sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
int n = sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
||||||
sn_strip_trailing_zeros(str);
|
n -= sn_strip_trailing_zeros(str);
|
||||||
return;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
|
@ -296,9 +306,9 @@ void modp_dtoa2(double value, char* str, int prec)
|
||||||
double smallest = _pow10r[prec];
|
double smallest = _pow10r[prec];
|
||||||
|
|
||||||
if (value != 0.0 && value < smallest) {
|
if (value != 0.0 && value < smallest) {
|
||||||
sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
int n = sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
||||||
sn_strip_trailing_zeros(str);
|
n -= sn_strip_trailing_zeros(str);
|
||||||
return;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int whole = (int) value;
|
int whole = (int) value;
|
||||||
|
@ -362,11 +372,12 @@ void modp_dtoa2(double value, char* str, int prec)
|
||||||
}
|
}
|
||||||
*wstr='\0';
|
*wstr='\0';
|
||||||
strreverse(str, wstr-1);
|
strreverse(str, wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is near identical to modp_dtoa2 above, excep that it never uses
|
// This is near identical to modp_dtoa2 above, excep that it never uses
|
||||||
// exponential notation and requires a buffer length.
|
// exponential notation and requires a buffer length.
|
||||||
void modp_dtoa3(double value, char* str, int n, int prec)
|
size_t modp_dtoa3(double value, char* str, int n, int prec)
|
||||||
{
|
{
|
||||||
/* Hacky test for NaN
|
/* Hacky test for NaN
|
||||||
* under -fast-math this won't work, but then you also won't
|
* under -fast-math this won't work, but then you also won't
|
||||||
|
@ -375,7 +386,7 @@ void modp_dtoa3(double value, char* str, int n, int prec)
|
||||||
*/
|
*/
|
||||||
if (! (value == value)) {
|
if (! (value == value)) {
|
||||||
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
|
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
|
||||||
return;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we'll work in positive values and deal with the
|
/* we'll work in positive values and deal with the
|
||||||
|
@ -409,7 +420,7 @@ void modp_dtoa3(double value, char* str, int n, int prec)
|
||||||
if ( i < 0 || i >= n ) {
|
if ( i < 0 || i >= n ) {
|
||||||
// Error or truncated output.
|
// Error or truncated output.
|
||||||
snprintf(str, n, "NAN");
|
snprintf(str, n, "NAN");
|
||||||
return;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove trailing zeros. */
|
/* Remove trailing zeros. */
|
||||||
|
@ -421,7 +432,7 @@ void modp_dtoa3(double value, char* str, int n, int prec)
|
||||||
--p;
|
--p;
|
||||||
|
|
||||||
*++p = '\0';
|
*++p = '\0';
|
||||||
return;
|
return p - str - 1;
|
||||||
|
|
||||||
/* ---- End of modified part.. */
|
/* ---- End of modified part.. */
|
||||||
}
|
}
|
||||||
|
@ -491,4 +502,5 @@ void modp_dtoa3(double value, char* str, int n, int prec)
|
||||||
}
|
}
|
||||||
*wstr='\0';
|
*wstr='\0';
|
||||||
strreverse(str, wstr-1);
|
strreverse(str, wstr-1);
|
||||||
|
return wstr - str - 1;
|
||||||
}
|
}
|
||||||
|
|
30
src/3rdparty/modp_numtoa.h
vendored
30
src/3rdparty/modp_numtoa.h
vendored
|
@ -34,37 +34,38 @@
|
||||||
BEGIN_C
|
BEGIN_C
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/** \brief convert an signed integer to char buffer
|
/** \brief convert an signed integer to char buffer, return # characters added
|
||||||
*
|
*
|
||||||
* \param[in] value
|
* \param[in] value
|
||||||
* \param[out] buf the output buffer. Should be 16 chars or more.
|
* \param[out] buf the output buffer. Should be 16 chars or more.
|
||||||
*/
|
*/
|
||||||
void modp_itoa10(int32_t value, char* buf);
|
size_t modp_itoa10(int32_t value, char* buf);
|
||||||
|
|
||||||
/** \brief convert an unsigned integer to char buffer
|
/** \brief convert an unsigned integer to char buffer, return # characters added
|
||||||
*
|
*
|
||||||
* \param[in] value
|
* \param[in] value
|
||||||
* \param[out] buf The output buffer, should be 16 chars or more.
|
* \param[out] buf The output buffer, should be 16 chars or more.
|
||||||
*/
|
*/
|
||||||
void modp_uitoa10(uint32_t value, char* buf);
|
size_t modp_uitoa10(uint32_t value, char* buf);
|
||||||
|
|
||||||
/** \brief convert an signed long integer to char buffer
|
/** \brief convert an signed long integer to char buffer, return # characters added
|
||||||
*
|
*
|
||||||
* \param[in] value
|
* \param[in] value
|
||||||
* \param[out] buf the output buffer. Should be 24 chars or more.
|
* \param[out] buf the output buffer. Should be 24 chars or more.
|
||||||
*/
|
*/
|
||||||
void modp_litoa10(int64_t value, char* buf);
|
size_t modp_litoa10(int64_t value, char* buf);
|
||||||
|
|
||||||
/** \brief convert an unsigned long integer to char buffer
|
/** \brief convert an unsigned long integer to char buffer, return # characters added
|
||||||
*
|
*
|
||||||
* \param[in] value
|
* \param[in] value
|
||||||
* \param[out] buf The output buffer, should be 24 chars or more.
|
* \param[out] buf The output buffer, should be 24 chars or more.
|
||||||
*/
|
*/
|
||||||
void modp_ulitoa10(uint64_t value, char* buf);
|
size_t modp_ulitoa10(uint64_t value, char* buf);
|
||||||
|
|
||||||
/** \brief convert a floating point number to char buffer with
|
/** \brief convert a floating point number to char buffer with
|
||||||
* fixed-precision format
|
* fixed-precision format, return # characters added
|
||||||
*
|
*
|
||||||
* This is similar to "%.[0-9]f" in the printf style. It will include
|
* This is similar to "%.[0-9]f" in the printf style. It will include
|
||||||
* trailing zeros
|
* trailing zeros
|
||||||
|
@ -78,10 +79,11 @@ void modp_ulitoa10(uint64_t value, char* buf);
|
||||||
* \param[in] precision Number of digits to the right of the decimal point.
|
* \param[in] precision Number of digits to the right of the decimal point.
|
||||||
* Can only be 0-9.
|
* Can only be 0-9.
|
||||||
*/
|
*/
|
||||||
void modp_dtoa(double value, char* buf, int precision);
|
size_t modp_dtoa(double value, char* buf, int precision);
|
||||||
|
|
||||||
/** \brief convert a floating point number to char buffer with a
|
/** \brief convert a floating point number to char buffer with a
|
||||||
* variable-precision format, and no trailing zeros
|
* variable-precision format, and no trailing zero, return
|
||||||
|
* number of characters added
|
||||||
*
|
*
|
||||||
* This is similar to "%.[0-9]f" in the printf style, except it will
|
* This is similar to "%.[0-9]f" in the printf style, except it will
|
||||||
* NOT include trailing zeros after the decimal point. This type
|
* NOT include trailing zeros after the decimal point. This type
|
||||||
|
@ -100,15 +102,15 @@ void modp_dtoa(double value, char* buf, int precision);
|
||||||
* \param[in] precision Number of digits to the right of the decimal point.
|
* \param[in] precision Number of digits to the right of the decimal point.
|
||||||
* Can only be 0-9.
|
* Can only be 0-9.
|
||||||
*/
|
*/
|
||||||
void modp_dtoa2(double value, char* buf, int precision);
|
size_t modp_dtoa2(double value, char* buf, int precision);
|
||||||
|
|
||||||
/** \brief convert a floating point number to char buffer with a
|
/** \brief convert a floating point number to char buffer with a
|
||||||
* variable-precision format, no trailing zeros, and no
|
* variable-precision format, no trailing zeros, and no
|
||||||
* scientific notation.
|
* scientific notation, return number of characters added
|
||||||
*
|
*
|
||||||
* Other than avoiding scientific notation, this is the same as mop_dtoa2. It does however
|
* Other than avoiding scientific notation, this is the same as mop_dtoa2. It does however
|
||||||
* require the max buffer length. The buffer will always be null-terminated.
|
* require the max buffer length. The buffer will always be null-terminated.
|
||||||
*/
|
*/
|
||||||
void modp_dtoa3(double value, char* buf, int n, int precision);
|
size_t modp_dtoa3(double value, char* buf, int n, int precision);
|
||||||
|
|
||||||
END_C
|
END_C
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue