mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 06:51:04 +08:00
Move mg_*printf* decls in fmt.h
This commit is contained in:
parent
0dabc45780
commit
f2009ebd62
2
Makefile
2
Makefile
@ -156,7 +156,7 @@ mongoose.c: Makefile $(wildcard src/*) $(wildcard mip/*.c)
|
||||
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c mip/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
||||
|
||||
mongoose.h: $(HDRS) Makefile
|
||||
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/config.h src/str.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h mip/mip.h | sed -e 's,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
|
||||
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/config.h src/str.h src/fmt.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h mip/mip.h | sed -e 's,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
|
||||
|
||||
clean:
|
||||
rm -rf $(PROG) *.exe *.o *.dSYM unit_test* valgrind_unit_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack unpacked
|
||||
|
297
mongoose.c
297
mongoose.c
@ -107,145 +107,6 @@ int mg_base64_decode(const char *src, int n, char *dst) {
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/dbl.c"
|
||||
#endif
|
||||
|
||||
|
||||
double mg_atod(const char *p, int len, int *numlen) {
|
||||
double d = 0.0;
|
||||
int i = 0, sign = 1;
|
||||
|
||||
// Sign
|
||||
if (i < len && *p == '-') {
|
||||
sign = -1, i++;
|
||||
} else if (i < len && *p == '+') {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Decimal
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
d *= 10.0;
|
||||
d += p[i] - '0';
|
||||
}
|
||||
d *= sign;
|
||||
|
||||
// Fractional
|
||||
if (i < len && p[i] == '.') {
|
||||
double frac = 0.0, base = 0.1;
|
||||
i++;
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
frac += base * (p[i] - '0');
|
||||
base /= 10.0;
|
||||
}
|
||||
d += frac * sign;
|
||||
}
|
||||
|
||||
// Exponential
|
||||
if (i < len && (p[i] == 'e' || p[i] == 'E')) {
|
||||
int j, exp = 0, minus = 0;
|
||||
i++;
|
||||
if (i < len && p[i] == '-') minus = 1, i++;
|
||||
if (i < len && p[i] == '+') i++;
|
||||
while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
|
||||
exp = exp * 10 + (p[i++] - '0');
|
||||
if (minus) exp = -exp;
|
||||
for (j = 0; j < exp; j++) d *= 10.0;
|
||||
for (j = 0; j < -exp; j++) d /= 10.0;
|
||||
}
|
||||
|
||||
if (numlen != NULL) *numlen = i;
|
||||
return d;
|
||||
}
|
||||
|
||||
static int addexp(char *buf, int e, int sign) {
|
||||
int n = 0;
|
||||
buf[n++] = 'e';
|
||||
buf[n++] = (char) sign;
|
||||
if (e > 400) return 0;
|
||||
if (e < 10) buf[n++] = '0';
|
||||
if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
|
||||
if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
|
||||
buf[n++] = (char) (e + '0');
|
||||
return n;
|
||||
}
|
||||
|
||||
static int xisinf(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
|
||||
((unsigned) ieee754.u == 0);
|
||||
}
|
||||
|
||||
static int xisnan(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
|
||||
((unsigned) ieee754.u != 0) >
|
||||
0x7ff00000;
|
||||
}
|
||||
|
||||
size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
char buf[40];
|
||||
int i, s = 0, n = 0, e = 0;
|
||||
double t, mul, saved;
|
||||
if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
|
||||
if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
|
||||
if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
|
||||
if (d < 0.0) d = -d, buf[s++] = '-';
|
||||
|
||||
// Round
|
||||
saved = d;
|
||||
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;
|
||||
d += t;
|
||||
// Calculate exponent, and 'mul' for scientific representation
|
||||
mul = 1.0;
|
||||
while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
} else {
|
||||
for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
|
||||
int ch = (int) (d / t);
|
||||
if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
t /= 10.0;
|
||||
}
|
||||
// printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
|
||||
if (n == 0) buf[s++] = '0';
|
||||
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++) {
|
||||
int ch = (int) (d / t);
|
||||
buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
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
|
||||
buf[s + n] = '\0';
|
||||
return mg_snprintf(dst, dstlen, "%s", buf);
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/dns.c"
|
||||
#endif
|
||||
@ -583,6 +444,15 @@ size_t mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
size_t n;
|
||||
va_start(ap, fmt);
|
||||
n = mg_vsnprintf(buf, len, fmt, &ap);
|
||||
va_end(ap);
|
||||
return n;
|
||||
}
|
||||
|
||||
char *mg_vmprintf(const char *fmt, va_list ap) {
|
||||
char *s = NULL;
|
||||
mg_vasprintf(&s, 0, fmt, ap);
|
||||
@ -649,6 +519,140 @@ static bool is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
double mg_atod(const char *p, int len, int *numlen) {
|
||||
double d = 0.0;
|
||||
int i = 0, sign = 1;
|
||||
|
||||
// Sign
|
||||
if (i < len && *p == '-') {
|
||||
sign = -1, i++;
|
||||
} else if (i < len && *p == '+') {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Decimal
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
d *= 10.0;
|
||||
d += p[i] - '0';
|
||||
}
|
||||
d *= sign;
|
||||
|
||||
// Fractional
|
||||
if (i < len && p[i] == '.') {
|
||||
double frac = 0.0, base = 0.1;
|
||||
i++;
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
frac += base * (p[i] - '0');
|
||||
base /= 10.0;
|
||||
}
|
||||
d += frac * sign;
|
||||
}
|
||||
|
||||
// Exponential
|
||||
if (i < len && (p[i] == 'e' || p[i] == 'E')) {
|
||||
int j, exp = 0, minus = 0;
|
||||
i++;
|
||||
if (i < len && p[i] == '-') minus = 1, i++;
|
||||
if (i < len && p[i] == '+') i++;
|
||||
while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
|
||||
exp = exp * 10 + (p[i++] - '0');
|
||||
if (minus) exp = -exp;
|
||||
for (j = 0; j < exp; j++) d *= 10.0;
|
||||
for (j = 0; j < -exp; j++) d /= 10.0;
|
||||
}
|
||||
|
||||
if (numlen != NULL) *numlen = i;
|
||||
return d;
|
||||
}
|
||||
|
||||
static int addexp(char *buf, int e, int sign) {
|
||||
int n = 0;
|
||||
buf[n++] = 'e';
|
||||
buf[n++] = (char) sign;
|
||||
if (e > 400) return 0;
|
||||
if (e < 10) buf[n++] = '0';
|
||||
if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
|
||||
if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
|
||||
buf[n++] = (char) (e + '0');
|
||||
return n;
|
||||
}
|
||||
|
||||
static int xisinf(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
|
||||
((unsigned) ieee754.u == 0);
|
||||
}
|
||||
|
||||
static int xisnan(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
|
||||
((unsigned) ieee754.u != 0) >
|
||||
0x7ff00000;
|
||||
}
|
||||
|
||||
size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
char buf[40];
|
||||
int i, s = 0, n = 0, e = 0;
|
||||
double t, mul, saved;
|
||||
if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
|
||||
if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
|
||||
if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
|
||||
if (d < 0.0) d = -d, buf[s++] = '-';
|
||||
|
||||
// Round
|
||||
saved = d;
|
||||
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;
|
||||
d += t;
|
||||
// Calculate exponent, and 'mul' for scientific representation
|
||||
mul = 1.0;
|
||||
while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
} else {
|
||||
for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
|
||||
int ch = (int) (d / t);
|
||||
if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
t /= 10.0;
|
||||
}
|
||||
// printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
|
||||
if (n == 0) buf[s++] = '0';
|
||||
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++) {
|
||||
int ch = (int) (d / t);
|
||||
buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
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
|
||||
buf[s + n] = '\0';
|
||||
return mg_snprintf(dst, dstlen, "%s", buf);
|
||||
}
|
||||
|
||||
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
|
||||
const char *letters = "0123456789abcdef";
|
||||
uint64_t v = (uint64_t) val;
|
||||
@ -1044,6 +1048,7 @@ struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read,
|
||||
|
||||
|
||||
|
||||
|
||||
struct packed_file {
|
||||
const char *data;
|
||||
size_t size;
|
||||
@ -1424,6 +1429,7 @@ struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close, p_read,
|
||||
|
||||
|
||||
|
||||
|
||||
// Multipart POST example:
|
||||
// --xyz
|
||||
// Content-Disposition: form-data; name="val"
|
||||
@ -2437,6 +2443,7 @@ void mg_iobuf_free(struct mg_iobuf *io) {
|
||||
|
||||
|
||||
|
||||
|
||||
static const char *escapeseq(int esc) {
|
||||
return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
|
||||
}
|
||||
@ -2696,6 +2703,8 @@ long mg_json_get_long(struct mg_str json, const char *path, long dflt) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void default_logger(unsigned char c) {
|
||||
putchar(c);
|
||||
(void) c;
|
||||
@ -4845,15 +4854,6 @@ bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||
return mg_split(s, k, v, ',');
|
||||
}
|
||||
|
||||
size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
size_t n;
|
||||
va_start(ap, fmt);
|
||||
n = mg_vsnprintf(buf, len, fmt, &ap);
|
||||
va_end(ap);
|
||||
return n;
|
||||
}
|
||||
|
||||
char *mg_hex(const void *buf, size_t len, char *to) {
|
||||
const unsigned char *p = (const unsigned char *) buf;
|
||||
const char *hex = "0123456789abcdef";
|
||||
@ -5618,6 +5618,7 @@ uint64_t mg_millis(void) {
|
||||
|
||||
|
||||
|
||||
|
||||
struct ws_msg {
|
||||
uint8_t flags;
|
||||
size_t header_len;
|
||||
|
12
mongoose.h
12
mongoose.h
@ -744,16 +744,21 @@ unsigned long mg_unhexn(const char *s, size_t len);
|
||||
int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
|
||||
int64_t mg_to64(struct mg_str str);
|
||||
uint64_t mg_tou64(struct mg_str str);
|
||||
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
||||
double mg_atod(const char *buf, int len, int *numlen);
|
||||
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
||||
char *mg_remove_double_dots(char *s);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef void (*mg_pfn_t)(char, void *); // Custom putchar
|
||||
typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
|
||||
void mg_pfn_realloc(char ch, void *param); // Print to malloced str
|
||||
void mg_pfn_iobuf(char ch, void *param); // Print to iobuf
|
||||
|
||||
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
||||
double mg_atod(const char *buf, int len, int *numlen);
|
||||
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
||||
|
||||
size_t mg_vrprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_rprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
|
||||
@ -1356,6 +1361,7 @@ char *mg_json_get_b64(struct mg_str json, const char *path, int *len);
|
||||
|
||||
|
||||
|
||||
|
||||
// JSON-RPC request descriptor
|
||||
struct mg_rpc_req {
|
||||
struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]}
|
||||
|
135
src/dbl.c
135
src/dbl.c
@ -1,135 +0,0 @@
|
||||
#include "str.h"
|
||||
|
||||
double mg_atod(const char *p, int len, int *numlen) {
|
||||
double d = 0.0;
|
||||
int i = 0, sign = 1;
|
||||
|
||||
// Sign
|
||||
if (i < len && *p == '-') {
|
||||
sign = -1, i++;
|
||||
} else if (i < len && *p == '+') {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Decimal
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
d *= 10.0;
|
||||
d += p[i] - '0';
|
||||
}
|
||||
d *= sign;
|
||||
|
||||
// Fractional
|
||||
if (i < len && p[i] == '.') {
|
||||
double frac = 0.0, base = 0.1;
|
||||
i++;
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
frac += base * (p[i] - '0');
|
||||
base /= 10.0;
|
||||
}
|
||||
d += frac * sign;
|
||||
}
|
||||
|
||||
// Exponential
|
||||
if (i < len && (p[i] == 'e' || p[i] == 'E')) {
|
||||
int j, exp = 0, minus = 0;
|
||||
i++;
|
||||
if (i < len && p[i] == '-') minus = 1, i++;
|
||||
if (i < len && p[i] == '+') i++;
|
||||
while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
|
||||
exp = exp * 10 + (p[i++] - '0');
|
||||
if (minus) exp = -exp;
|
||||
for (j = 0; j < exp; j++) d *= 10.0;
|
||||
for (j = 0; j < -exp; j++) d /= 10.0;
|
||||
}
|
||||
|
||||
if (numlen != NULL) *numlen = i;
|
||||
return d;
|
||||
}
|
||||
|
||||
static int addexp(char *buf, int e, int sign) {
|
||||
int n = 0;
|
||||
buf[n++] = 'e';
|
||||
buf[n++] = (char) sign;
|
||||
if (e > 400) return 0;
|
||||
if (e < 10) buf[n++] = '0';
|
||||
if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
|
||||
if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
|
||||
buf[n++] = (char) (e + '0');
|
||||
return n;
|
||||
}
|
||||
|
||||
static int xisinf(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
|
||||
((unsigned) ieee754.u == 0);
|
||||
}
|
||||
|
||||
static int xisnan(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
|
||||
((unsigned) ieee754.u != 0) >
|
||||
0x7ff00000;
|
||||
}
|
||||
|
||||
size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
char buf[40];
|
||||
int i, s = 0, n = 0, e = 0;
|
||||
double t, mul, saved;
|
||||
if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
|
||||
if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
|
||||
if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
|
||||
if (d < 0.0) d = -d, buf[s++] = '-';
|
||||
|
||||
// Round
|
||||
saved = d;
|
||||
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;
|
||||
d += t;
|
||||
// Calculate exponent, and 'mul' for scientific representation
|
||||
mul = 1.0;
|
||||
while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
} else {
|
||||
for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
|
||||
int ch = (int) (d / t);
|
||||
if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
t /= 10.0;
|
||||
}
|
||||
// printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
|
||||
if (n == 0) buf[s++] = '0';
|
||||
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++) {
|
||||
int ch = (int) (d / t);
|
||||
buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
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
|
||||
buf[s + n] = '\0';
|
||||
return mg_snprintf(dst, dstlen, "%s", buf);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#include "event.h"
|
||||
#include "fmt.h"
|
||||
#include "log.h"
|
||||
#include "net.h"
|
||||
#include "util.h"
|
||||
|
||||
void mg_call(struct mg_connection *c, int ev, void *ev_data) {
|
||||
// Run user-defined handler first, in order to give it an ability
|
||||
|
145
src/fmt.c
145
src/fmt.c
@ -1,5 +1,5 @@
|
||||
#include "fmt.h"
|
||||
#include "iobuf.h"
|
||||
#include "str.h"
|
||||
|
||||
size_t mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) {
|
||||
va_list ap_copy;
|
||||
@ -32,6 +32,15 @@ size_t mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
size_t n;
|
||||
va_start(ap, fmt);
|
||||
n = mg_vsnprintf(buf, len, fmt, &ap);
|
||||
va_end(ap);
|
||||
return n;
|
||||
}
|
||||
|
||||
char *mg_vmprintf(const char *fmt, va_list ap) {
|
||||
char *s = NULL;
|
||||
mg_vasprintf(&s, 0, fmt, ap);
|
||||
@ -98,6 +107,140 @@ static bool is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
double mg_atod(const char *p, int len, int *numlen) {
|
||||
double d = 0.0;
|
||||
int i = 0, sign = 1;
|
||||
|
||||
// Sign
|
||||
if (i < len && *p == '-') {
|
||||
sign = -1, i++;
|
||||
} else if (i < len && *p == '+') {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Decimal
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
d *= 10.0;
|
||||
d += p[i] - '0';
|
||||
}
|
||||
d *= sign;
|
||||
|
||||
// Fractional
|
||||
if (i < len && p[i] == '.') {
|
||||
double frac = 0.0, base = 0.1;
|
||||
i++;
|
||||
for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
|
||||
frac += base * (p[i] - '0');
|
||||
base /= 10.0;
|
||||
}
|
||||
d += frac * sign;
|
||||
}
|
||||
|
||||
// Exponential
|
||||
if (i < len && (p[i] == 'e' || p[i] == 'E')) {
|
||||
int j, exp = 0, minus = 0;
|
||||
i++;
|
||||
if (i < len && p[i] == '-') minus = 1, i++;
|
||||
if (i < len && p[i] == '+') i++;
|
||||
while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
|
||||
exp = exp * 10 + (p[i++] - '0');
|
||||
if (minus) exp = -exp;
|
||||
for (j = 0; j < exp; j++) d *= 10.0;
|
||||
for (j = 0; j < -exp; j++) d /= 10.0;
|
||||
}
|
||||
|
||||
if (numlen != NULL) *numlen = i;
|
||||
return d;
|
||||
}
|
||||
|
||||
static int addexp(char *buf, int e, int sign) {
|
||||
int n = 0;
|
||||
buf[n++] = 'e';
|
||||
buf[n++] = (char) sign;
|
||||
if (e > 400) return 0;
|
||||
if (e < 10) buf[n++] = '0';
|
||||
if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
|
||||
if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
|
||||
buf[n++] = (char) (e + '0');
|
||||
return n;
|
||||
}
|
||||
|
||||
static int xisinf(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
|
||||
((unsigned) ieee754.u == 0);
|
||||
}
|
||||
|
||||
static int xisnan(double x) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} ieee754 = {x};
|
||||
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
|
||||
((unsigned) ieee754.u != 0) >
|
||||
0x7ff00000;
|
||||
}
|
||||
|
||||
size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
|
||||
char buf[40];
|
||||
int i, s = 0, n = 0, e = 0;
|
||||
double t, mul, saved;
|
||||
if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
|
||||
if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
|
||||
if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
|
||||
if (d < 0.0) d = -d, buf[s++] = '-';
|
||||
|
||||
// Round
|
||||
saved = d;
|
||||
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;
|
||||
d += t;
|
||||
// Calculate exponent, and 'mul' for scientific representation
|
||||
mul = 1.0;
|
||||
while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
} else {
|
||||
for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
|
||||
int ch = (int) (d / t);
|
||||
if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
t /= 10.0;
|
||||
}
|
||||
// printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
|
||||
if (n == 0) buf[s++] = '0';
|
||||
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++) {
|
||||
int ch = (int) (d / t);
|
||||
buf[s + n++] = (char) (ch + '0');
|
||||
d -= ch * t;
|
||||
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
|
||||
buf[s + n] = '\0';
|
||||
return mg_snprintf(dst, dstlen, "%s", buf);
|
||||
}
|
||||
|
||||
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
|
||||
const char *letters = "0123456789abcdef";
|
||||
uint64_t v = (uint64_t) val;
|
||||
|
22
src/fmt.h
Normal file
22
src/fmt.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch.h"
|
||||
#include "iobuf.h"
|
||||
|
||||
typedef void (*mg_pfn_t)(char, void *); // Custom putchar
|
||||
typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
|
||||
void mg_pfn_realloc(char ch, void *param); // Print to malloced str
|
||||
void mg_pfn_iobuf(char ch, void *param); // Print to iobuf
|
||||
|
||||
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
||||
double mg_atod(const char *buf, int len, int *numlen);
|
||||
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
||||
|
||||
size_t mg_vrprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_rprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
|
||||
size_t mg_snprintf(char *, size_t, const char *fmt, ...);
|
||||
size_t mg_asprintf(char **, size_t, const char *fmt, ...);
|
||||
size_t mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
||||
char *mg_mprintf(const char *fmt, ...);
|
||||
char *mg_vmprintf(const char *fmt, va_list ap);
|
2
src/fs.c
2
src/fs.c
@ -1,5 +1,5 @@
|
||||
#include "fs.h"
|
||||
#include "util.h"
|
||||
#include "fmt.h"
|
||||
|
||||
struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
|
||||
struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd));
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "fmt.h"
|
||||
#include "fs.h"
|
||||
#include "str.h"
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "http.h"
|
||||
#include "arch.h"
|
||||
#include "base64.h"
|
||||
#include "fmt.h"
|
||||
#include "log.h"
|
||||
#include "net.h"
|
||||
#include "ssi.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "json.h"
|
||||
#include "base64.h"
|
||||
#include "fmt.h"
|
||||
|
||||
static const char *escapeseq(int esc) {
|
||||
return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "log.h"
|
||||
#include "fmt.h"
|
||||
#include "str.h"
|
||||
#include "util.h"
|
||||
|
||||
static void default_logger(unsigned char c) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "net.h"
|
||||
#include "dns.h"
|
||||
#include "fmt.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "tls.h"
|
||||
#include "util.h"
|
||||
|
||||
size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
|
||||
size_t old = c->send.len;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "fmt.h"
|
||||
#include "json.h"
|
||||
|
||||
// JSON-RPC request descriptor
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "ssi.h"
|
||||
#include "fmt.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef MG_MAX_SSI_DEPTH
|
||||
#define MG_MAX_SSI_DEPTH 5
|
||||
|
@ -155,15 +155,6 @@ bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||
return mg_split(s, k, v, ',');
|
||||
}
|
||||
|
||||
size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
size_t n;
|
||||
va_start(ap, fmt);
|
||||
n = mg_vsnprintf(buf, len, fmt, &ap);
|
||||
va_end(ap);
|
||||
return n;
|
||||
}
|
||||
|
||||
char *mg_hex(const void *buf, size_t len, char *to) {
|
||||
const unsigned char *p = (const unsigned char *) buf;
|
||||
const char *hex = "0123456789abcdef";
|
||||
|
17
src/str.h
17
src/str.h
@ -37,21 +37,4 @@ unsigned long mg_unhexn(const char *s, size_t len);
|
||||
int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
|
||||
int64_t mg_to64(struct mg_str str);
|
||||
uint64_t mg_tou64(struct mg_str str);
|
||||
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
||||
double mg_atod(const char *buf, int len, int *numlen);
|
||||
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
||||
char *mg_remove_double_dots(char *s);
|
||||
|
||||
typedef void (*mg_pfn_t)(char, void *); // Custom putchar
|
||||
typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
|
||||
void mg_pfn_realloc(char ch, void *param); // Print to malloced str
|
||||
void mg_pfn_iobuf(char ch, void *param); // Print to iobuf
|
||||
|
||||
size_t mg_vrprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_rprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
|
||||
size_t mg_snprintf(char *, size_t, const char *fmt, ...);
|
||||
size_t mg_asprintf(char **, size_t, const char *fmt, ...);
|
||||
size_t mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
||||
char *mg_mprintf(const char *fmt, ...);
|
||||
char *mg_vmprintf(const char *fmt, va_list ap);
|
||||
|
Loading…
x
Reference in New Issue
Block a user