mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-05 21:18:32 +08:00
Fix #2104 - %.*f formatting
This commit is contained in:
parent
f79edeb053
commit
6b29a2a724
24
mongoose.c
24
mongoose.c
@ -411,9 +411,7 @@ void mg_error(struct mg_connection *c, const char *fmt, ...) {
|
||||
|
||||
|
||||
|
||||
static bool is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
static bool is_digit(int c) { return c >= '0' && c <= '9'; }
|
||||
|
||||
static int addexp(char *buf, int e, int sign) {
|
||||
int n = 0;
|
||||
@ -446,7 +444,7 @@ static int xisnan(double x) {
|
||||
0x7ff00000;
|
||||
}
|
||||
|
||||
static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
|
||||
char buf[40];
|
||||
int i, s = 0, n = 0, e = 0;
|
||||
double t, mul, saved;
|
||||
@ -468,13 +466,13 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
|
||||
// printf(" --> %g %d %g %g\n", saved, e, t, mul);
|
||||
|
||||
if (e >= width) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
|
||||
if (e >= width && width > 1) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
|
||||
// printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
|
||||
n += addexp(buf + s + n, e, '+');
|
||||
return mg_snprintf(dst, dstlen, "%.*s", n, buf);
|
||||
} else if (e <= -width) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
|
||||
} else if (e <= -width && width > 1) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
|
||||
// printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf);
|
||||
n += addexp(buf + s + n, -e, '-');
|
||||
return mg_snprintf(dst, dstlen, "%.*s", n, buf);
|
||||
@ -497,8 +495,8 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
t /= 10.0;
|
||||
}
|
||||
}
|
||||
while (n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeros
|
||||
if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
|
||||
while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
|
||||
if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
|
||||
n += s;
|
||||
if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
|
||||
buf[n] = '\0';
|
||||
@ -542,9 +540,7 @@ static char mg_esc(int c, bool esc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char mg_escape(int c) {
|
||||
return mg_esc(c, true);
|
||||
}
|
||||
static char mg_escape(int c) { return mg_esc(c, true); }
|
||||
|
||||
static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
|
||||
size_t len) {
|
||||
@ -631,7 +627,7 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
if (c == 'g' || c == 'f') {
|
||||
double v = va_arg(*ap, double);
|
||||
if (pr == ~0U) pr = 6;
|
||||
k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr);
|
||||
k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
|
||||
} else if (is_long == 2) {
|
||||
int64_t v = va_arg(*ap, int64_t);
|
||||
k = mg_lld(tmp, v, s, h);
|
||||
|
24
src/fmt.c
24
src/fmt.c
@ -2,9 +2,7 @@
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
|
||||
static bool is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
static bool is_digit(int c) { return c >= '0' && c <= '9'; }
|
||||
|
||||
static int addexp(char *buf, int e, int sign) {
|
||||
int n = 0;
|
||||
@ -37,7 +35,7 @@ static int xisnan(double x) {
|
||||
0x7ff00000;
|
||||
}
|
||||
|
||||
static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
|
||||
char buf[40];
|
||||
int i, s = 0, n = 0, e = 0;
|
||||
double t, mul, saved;
|
||||
@ -59,13 +57,13 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
|
||||
// printf(" --> %g %d %g %g\n", saved, e, t, mul);
|
||||
|
||||
if (e >= width) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
|
||||
if (e >= width && width > 1) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
|
||||
// printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
|
||||
n += addexp(buf + s + n, e, '+');
|
||||
return mg_snprintf(dst, dstlen, "%.*s", n, buf);
|
||||
} else if (e <= -width) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
|
||||
} else if (e <= -width && width > 1) {
|
||||
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
|
||||
// printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf);
|
||||
n += addexp(buf + s + n, -e, '-');
|
||||
return mg_snprintf(dst, dstlen, "%.*s", n, buf);
|
||||
@ -88,8 +86,8 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
t /= 10.0;
|
||||
}
|
||||
}
|
||||
while (n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeros
|
||||
if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
|
||||
while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
|
||||
if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
|
||||
n += s;
|
||||
if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
|
||||
buf[n] = '\0';
|
||||
@ -133,9 +131,7 @@ static char mg_esc(int c, bool esc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char mg_escape(int c) {
|
||||
return mg_esc(c, true);
|
||||
}
|
||||
static char mg_escape(int c) { return mg_esc(c, true); }
|
||||
|
||||
static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
|
||||
size_t len) {
|
||||
@ -222,7 +218,7 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
if (c == 'g' || c == 'f') {
|
||||
double v = va_arg(*ap, double);
|
||||
if (pr == ~0U) pr = 6;
|
||||
k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr);
|
||||
k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
|
||||
} else if (is_long == 2) {
|
||||
int64_t v = va_arg(*ap, int64_t);
|
||||
k = mg_lld(tmp, v, s, h);
|
||||
|
@ -1601,15 +1601,22 @@ static void test_str(void) {
|
||||
}
|
||||
|
||||
{
|
||||
char tmp[40];
|
||||
#if MG_ARCH == MG_ARCH_WIN32
|
||||
bool is_windows = true;
|
||||
#else
|
||||
bool is_windows = false;
|
||||
#endif
|
||||
|
||||
#define DBLWIDTH(a, b) a, b
|
||||
#define TESTDOUBLE(fmt_, num_, res_) \
|
||||
do { \
|
||||
const char *N = #num_; \
|
||||
size_t n = mg_snprintf(tmp, sizeof(tmp), fmt_, num_); \
|
||||
if (0) printf("[%s] [%s] -> [%s] [%.*s]\n", fmt_, N, res_, (int) n, tmp); \
|
||||
ASSERT(n == strlen(res_)); \
|
||||
ASSERT(strcmp(tmp, res_) == 0); \
|
||||
#define TESTDOUBLE(fmt_, num_, res_) \
|
||||
do { \
|
||||
char t1[40] = "", t2[40] = ""; \
|
||||
const char *N = #num_; \
|
||||
mg_snprintf(t1, sizeof(t1), fmt_, num_); \
|
||||
snprintf(t2, sizeof(t2), fmt_, num_); \
|
||||
printf("[%s,%s] : [%s] [%s] [%s]\n", fmt_, N, res_, t2, t1); \
|
||||
ASSERT(strcmp(t1, res_) == 0); \
|
||||
if (!is_windows) ASSERT(strcmp(t1, t2) == 0); \
|
||||
} while (0)
|
||||
|
||||
TESTDOUBLE("%g", 0.0, "0");
|
||||
@ -1649,6 +1656,15 @@ static void test_str(void) {
|
||||
TESTDOUBLE("%g", -600.1234, "-600.123");
|
||||
TESTDOUBLE("%g", 599.1234, "599.123");
|
||||
TESTDOUBLE("%g", -599.1234, "-599.123");
|
||||
TESTDOUBLE("%g", 0.14, "0.14");
|
||||
TESTDOUBLE("%f", 0.14, "0.140000");
|
||||
TESTDOUBLE("%.*f", DBLWIDTH(4, 0.14), "0.1400");
|
||||
TESTDOUBLE("%.*f", DBLWIDTH(3, 0.14), "0.140");
|
||||
TESTDOUBLE("%.*f", DBLWIDTH(2, 0.14), "0.14");
|
||||
TESTDOUBLE("%.*f", DBLWIDTH(1, 0.14), "0.1");
|
||||
TESTDOUBLE("%.*f", DBLWIDTH(1, 0.19), "0.2");
|
||||
TESTDOUBLE("%.*f", DBLWIDTH(1, 0.16), "0.2");
|
||||
// TESTDOUBLE("%.*f", DBLWIDTH(1, 0.15), "0.1");
|
||||
|
||||
#ifndef _WIN32
|
||||
TESTDOUBLE("%g", (double) INFINITY, "inf");
|
||||
|
Loading…
Reference in New Issue
Block a user