mirror of
https://github.com/nginx/nginx.git
synced 2025-01-05 21:53:01 -06:00
%f format
This commit is contained in:
parent
698b8cb038
commit
74b7e5fadd
@ -8,6 +8,10 @@
|
|||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
|
static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64,
|
||||||
|
u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ngx_strlow(u_char *dst, u_char *src, size_t n)
|
ngx_strlow(u_char *dst, u_char *src, size_t n)
|
||||||
{
|
{
|
||||||
@ -67,6 +71,7 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
|
|||||||
* %[0][width][u][x|X]D int32_t/uint32_t
|
* %[0][width][u][x|X]D int32_t/uint32_t
|
||||||
* %[0][width][u][x|X]L int64_t/uint64_t
|
* %[0][width][u][x|X]L int64_t/uint64_t
|
||||||
* %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t
|
* %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t
|
||||||
|
* %[0][width][.width]f float
|
||||||
* %P ngx_pid_t
|
* %P ngx_pid_t
|
||||||
* %M ngx_msec_t
|
* %M ngx_msec_t
|
||||||
* %r rlim_t
|
* %r rlim_t
|
||||||
@ -118,22 +123,16 @@ ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
|
|||||||
u_char *
|
u_char *
|
||||||
ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
|
u_char *p, zero, *last;
|
||||||
/*
|
|
||||||
* really we need temp[NGX_INT64_LEN] only,
|
|
||||||
* but icc issues the warning
|
|
||||||
*/
|
|
||||||
int d;
|
int d;
|
||||||
|
float f, scale;
|
||||||
size_t len, slen;
|
size_t len, slen;
|
||||||
uint32_t ui32;
|
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
uint64_t ui64;
|
uint64_t ui64;
|
||||||
ngx_msec_t ms;
|
ngx_msec_t ms;
|
||||||
ngx_uint_t width, sign, hexadecimal, max_width;
|
ngx_uint_t width, sign, hex, max_width, frac_width, i;
|
||||||
ngx_str_t *v;
|
ngx_str_t *v;
|
||||||
ngx_variable_value_t *vv;
|
ngx_variable_value_t *vv;
|
||||||
static u_char hex[] = "0123456789abcdef";
|
|
||||||
static u_char HEX[] = "0123456789ABCDEF";
|
|
||||||
|
|
||||||
if (max == 0) {
|
if (max == 0) {
|
||||||
return buf;
|
return buf;
|
||||||
@ -156,12 +155,11 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||||||
zero = (u_char) ((*++fmt == '0') ? '0' : ' ');
|
zero = (u_char) ((*++fmt == '0') ? '0' : ' ');
|
||||||
width = 0;
|
width = 0;
|
||||||
sign = 1;
|
sign = 1;
|
||||||
hexadecimal = 0;
|
hex = 0;
|
||||||
max_width = 0;
|
max_width = 0;
|
||||||
|
frac_width = 0;
|
||||||
slen = (size_t) -1;
|
slen = (size_t) -1;
|
||||||
|
|
||||||
p = temp + NGX_INT64_LEN;
|
|
||||||
|
|
||||||
while (*fmt >= '0' && *fmt <= '9') {
|
while (*fmt >= '0' && *fmt <= '9') {
|
||||||
width = width * 10 + *fmt++ - '0';
|
width = width * 10 + *fmt++ - '0';
|
||||||
}
|
}
|
||||||
@ -181,17 +179,26 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
hexadecimal = 2;
|
hex = 2;
|
||||||
sign = 0;
|
sign = 0;
|
||||||
fmt++;
|
fmt++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
hexadecimal = 1;
|
hex = 1;
|
||||||
sign = 0;
|
sign = 0;
|
||||||
fmt++;
|
fmt++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
while (*fmt >= '0' && *fmt <= '9') {
|
||||||
|
frac_width = frac_width * 10 + *fmt++ - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
slen = va_arg(args, size_t);
|
slen = va_arg(args, size_t);
|
||||||
fmt++;
|
fmt++;
|
||||||
@ -339,6 +346,43 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
f = (float) va_arg(args, double);
|
||||||
|
|
||||||
|
if (f < 0) {
|
||||||
|
*buf++ = '-';
|
||||||
|
f = -f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui64 = (int64_t) f;
|
||||||
|
|
||||||
|
buf = ngx_sprintf_num(buf, last, ui64, zero, 0, width);
|
||||||
|
|
||||||
|
if (frac_width) {
|
||||||
|
|
||||||
|
if (buf < last) {
|
||||||
|
*buf++ = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
scale = 1.0;
|
||||||
|
|
||||||
|
for (i = 0; i < frac_width; i++) {
|
||||||
|
scale *= 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (int64_t) cast is required for msvc6:
|
||||||
|
* it can not convert uint64_t to double
|
||||||
|
*/
|
||||||
|
ui64 = (uint64_t) ((f - (int64_t) ui64) * scale);
|
||||||
|
|
||||||
|
buf = ngx_sprintf_num(buf, last, ui64, '0', 0, frac_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
#if !(NGX_WIN32)
|
#if !(NGX_WIN32)
|
||||||
case 'r':
|
case 'r':
|
||||||
i64 = (int64_t) va_arg(args, rlim_t);
|
i64 = (int64_t) va_arg(args, rlim_t);
|
||||||
@ -348,7 +392,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
ui64 = (uintptr_t) va_arg(args, void *);
|
ui64 = (uintptr_t) va_arg(args, void *);
|
||||||
hexadecimal = 2;
|
hex = 2;
|
||||||
sign = 0;
|
sign = 0;
|
||||||
zero = '0';
|
zero = '0';
|
||||||
width = NGX_PTR_SIZE * 2;
|
width = NGX_PTR_SIZE * 2;
|
||||||
@ -398,63 +442,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hexadecimal == 1) {
|
buf = ngx_sprintf_num(buf, last, ui64, zero, hex, width);
|
||||||
do {
|
|
||||||
|
|
||||||
/* the "(uint32_t)" cast disables the BCC's warning */
|
|
||||||
*--p = hex[(uint32_t) (ui64 & 0xf)];
|
|
||||||
|
|
||||||
} while (ui64 >>= 4);
|
|
||||||
|
|
||||||
} else if (hexadecimal == 2) {
|
|
||||||
do {
|
|
||||||
|
|
||||||
/* the "(uint32_t)" cast disables the BCC's warning */
|
|
||||||
*--p = HEX[(uint32_t) (ui64 & 0xf)];
|
|
||||||
|
|
||||||
} while (ui64 >>= 4);
|
|
||||||
|
|
||||||
} else if (ui64 <= NGX_MAX_UINT32_VALUE) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* To divide 64-bit number and to find the remainder
|
|
||||||
* on the x86 platform gcc and icc call the libc functions
|
|
||||||
* [u]divdi3() and [u]moddi3(), they call another function
|
|
||||||
* in its turn. On FreeBSD it is the qdivrem() function,
|
|
||||||
* its source code is about 170 lines of the code.
|
|
||||||
* The glibc counterpart is about 150 lines of the code.
|
|
||||||
*
|
|
||||||
* For 32-bit numbers and some divisors gcc and icc use
|
|
||||||
* the inlined multiplication and shifts. For example,
|
|
||||||
* unsigned "i32 / 10" is compiled to
|
|
||||||
*
|
|
||||||
* (i32 * 0xCCCCCCCD) >> 35
|
|
||||||
*/
|
|
||||||
|
|
||||||
ui32 = (uint32_t) ui64;
|
|
||||||
|
|
||||||
do {
|
|
||||||
*--p = (u_char) (ui32 % 10 + '0');
|
|
||||||
} while (ui32 /= 10);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
do {
|
|
||||||
*--p = (u_char) (ui64 % 10 + '0');
|
|
||||||
} while (ui64 /= 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = (temp + NGX_INT64_LEN) - p;
|
|
||||||
|
|
||||||
while (len++ < width && buf < last) {
|
|
||||||
*buf++ = zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = (temp + NGX_INT64_LEN) - p;
|
|
||||||
if (buf + len > last) {
|
|
||||||
len = last - buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = ngx_cpymem(buf, p, len);
|
|
||||||
|
|
||||||
fmt++;
|
fmt++;
|
||||||
|
|
||||||
@ -467,6 +455,92 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u_char *
|
||||||
|
ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero,
|
||||||
|
ngx_uint_t hexadecimal, ngx_uint_t width)
|
||||||
|
{
|
||||||
|
u_char *p, temp[NGX_INT64_LEN + 1];
|
||||||
|
/*
|
||||||
|
* we need temp[NGX_INT64_LEN] only,
|
||||||
|
* but icc issues the warning
|
||||||
|
*/
|
||||||
|
size_t len;
|
||||||
|
uint32_t ui32;
|
||||||
|
static u_char hex[] = "0123456789abcdef";
|
||||||
|
static u_char HEX[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
p = temp + NGX_INT64_LEN;
|
||||||
|
|
||||||
|
if (hexadecimal == 0) {
|
||||||
|
|
||||||
|
if (ui64 <= NGX_MAX_UINT32_VALUE) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To divide 64-bit numbers and to find remainders
|
||||||
|
* on the x86 platform gcc and icc call the libc functions
|
||||||
|
* [u]divdi3() and [u]moddi3(), they call another function
|
||||||
|
* in its turn. On FreeBSD it is the qdivrem() function,
|
||||||
|
* its source code is about 170 lines of the code.
|
||||||
|
* The glibc counterpart is about 150 lines of the code.
|
||||||
|
*
|
||||||
|
* For 32-bit numbers and some divisors gcc and icc use
|
||||||
|
* a inlined multiplication and shifts. For example,
|
||||||
|
* unsigned "i32 / 10" is compiled to
|
||||||
|
*
|
||||||
|
* (i32 * 0xCCCCCCCD) >> 35
|
||||||
|
*/
|
||||||
|
|
||||||
|
ui32 = (uint32_t) ui64;
|
||||||
|
|
||||||
|
do {
|
||||||
|
*--p = (u_char) (ui32 % 10 + '0');
|
||||||
|
} while (ui32 /= 10);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
*--p = (u_char) (ui64 % 10 + '0');
|
||||||
|
} while (ui64 /= 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (hexadecimal == 1) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
/* the "(uint32_t)" cast disables the BCC's warning */
|
||||||
|
*--p = hex[(uint32_t) (ui64 & 0xf)];
|
||||||
|
|
||||||
|
} while (ui64 >>= 4);
|
||||||
|
|
||||||
|
} else { /* hexadecimal == 2 */
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
/* the "(uint32_t)" cast disables the BCC's warning */
|
||||||
|
*--p = HEX[(uint32_t) (ui64 & 0xf)];
|
||||||
|
|
||||||
|
} while (ui64 >>= 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zero or space padding */
|
||||||
|
|
||||||
|
len = (temp + NGX_INT64_LEN) - p;
|
||||||
|
|
||||||
|
while (len++ < width && buf < last) {
|
||||||
|
*buf++ = zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* number safe copy */
|
||||||
|
|
||||||
|
len = (temp + NGX_INT64_LEN) - p;
|
||||||
|
|
||||||
|
if (buf + len > last) {
|
||||||
|
len = last - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ngx_cpymem(buf, p, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
|
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
|
||||||
* and implement our own ngx_strcasecmp()/ngx_strncasecmp()
|
* and implement our own ngx_strcasecmp()/ngx_strncasecmp()
|
||||||
|
Loading…
Reference in New Issue
Block a user