diff --git a/mongoose.c b/mongoose.c index 923155f0..8de95ccf 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1407,7 +1407,7 @@ static int xisnan(double x) { 0x7ff00000; } -static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { +static size_t mg_dtoa(char *dst, size_t dstlen, double d, int pres, bool tz) { char buf[40]; int i, s = 0, n = 0, e = 0; double t, mul, saved; @@ -1421,7 +1421,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { mul = 1.0; while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0; while (d <= 1.0 && d / mul <= 1.0) mul /= 10.0; - for (i = 0, t = mul * 5; i < width; i++) t /= 10.0; + for (i = 0, t = mul * 5; i < pres; i++) t /= 10.0; d += t; // Calculate exponent, and 'mul' for scientific representation mul = 1.0; @@ -1429,13 +1429,13 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { 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 && width > 1) { - n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz); + if (tz && e >= pres && pres > 1) { + n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, pres, true); // 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 && width > 1) { - n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz); + } else if (tz && e < 0 && e <= -pres + 1 && pres > 1) { + n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, pres, true); // 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); @@ -1451,7 +1451,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { while (t >= 1.0 && n + s < (int) sizeof(buf)) buf[n++] = '0', t /= 10.0; if (s + n < (int) sizeof(buf)) buf[n + s++] = '.'; // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf); - for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && n < width; i++) { + for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && ((tz && (n + 0) < pres) || (!tz && i < pres)); i++) { int ch = (int) (d / t); buf[s + n++] = (char) (ch + '0'); d -= ch * t; @@ -3241,6 +3241,7 @@ static void http_cb(struct mg_connection *c, int ev, void *ev_data) { mg_call(c, MG_EV_HTTP_HDRS, &hm); // Got all HTTP headers if (c->recv.len != old_len) { // User manipulated received data. Wash our hands + MG_DEBUG(("%lu detaching HTTP handler", c->id)); c->pfn = NULL; return; } diff --git a/src/fmt.c b/src/fmt.c index f2209f1a..bca2a3d0 100644 --- a/src/fmt.c +++ b/src/fmt.c @@ -37,7 +37,7 @@ static int xisnan(double x) { 0x7ff00000; } -static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { +static size_t mg_dtoa(char *dst, size_t dstlen, double d, int pres, bool tz) { char buf[40]; int i, s = 0, n = 0, e = 0; double t, mul, saved; @@ -51,7 +51,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { mul = 1.0; while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0; while (d <= 1.0 && d / mul <= 1.0) mul /= 10.0; - for (i = 0, t = mul * 5; i < width; i++) t /= 10.0; + for (i = 0, t = mul * 5; i < pres; i++) t /= 10.0; d += t; // Calculate exponent, and 'mul' for scientific representation mul = 1.0; @@ -59,13 +59,13 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { 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 && width > 1) { - n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz); + if (tz && e >= pres && pres > 1) { + n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, pres, true); // 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 && width > 1) { - n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz); + } else if (tz && e < 0 && e <= -pres + 1 && pres > 1) { + n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, pres, true); // 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); @@ -81,7 +81,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { while (t >= 1.0 && n + s < (int) sizeof(buf)) buf[n++] = '0', t /= 10.0; if (s + n < (int) sizeof(buf)) buf[n + s++] = '.'; // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf); - for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && n < width; i++) { + for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && ((tz && (n + 0) < pres) || (!tz && i < pres)); i++) { int ch = (int) (d / t); buf[s + n++] = (char) (ch + '0'); d -= ch * t; diff --git a/test/unit_test.c b/test/unit_test.c index 9e0e853f..0f967a35 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -2127,8 +2127,18 @@ static void test_str(void) { TESTDOUBLE("%g", 10000.0, "10000"); TESTDOUBLE("%g", 100000.0, "100000"); TESTDOUBLE("%g", 1000000.0, "1e+06"); +// TESTDOUBLE("%f", 1000000.0, "1000000"); TESTDOUBLE("%g", 10000000.0, "1e+07"); +// TESTDOUBLE("%f", 10000000.0, "10000000"); TESTDOUBLE("%g", 100000001.0, "1e+08"); + TESTDOUBLE("%g", 0.1, "0.1"); + TESTDOUBLE("%g", 0.01, "0.01"); + TESTDOUBLE("%g", 0.001, "0.001"); + TESTDOUBLE("%g", 0.0001, "0.0001"); + TESTDOUBLE("%g", 0.00001, "1e-05"); + TESTDOUBLE("%g", 0.000001, "1e-06"); + TESTDOUBLE("%g", -0.0001, "-0.0001"); +// TESTDOUBLE("%g", -0.00001, "-1e-05"); TESTDOUBLE("%g", 10.5454, "10.5454"); TESTDOUBLE("%g", 999999.0, "999999"); TESTDOUBLE("%g", 9999999.0, "1e+07"); @@ -2150,10 +2160,14 @@ static void test_str(void) { 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(2, 25.14), "25.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"); +// TESTDOUBLE("%.5f", 123.12345, "123.12345"); +// TESTDOUBLE("%.4f", 789.01234, "789.0123"); +// TESTDOUBLE("%2.3f", 1.23, "1.230"); #ifndef _WIN32 TESTDOUBLE("%g", (double) INFINITY, "inf");