Commit a23daa15 authored by Marko Mikulicic's avatar Marko Mikulicic Committed by Cesanta Bot

Move mg_a*printf to common

PUBLISHED_FROM=cccd28ef43ec4e08fa52340ce78bda10db5ac27a
parent 9dba6c80
......@@ -3,8 +3,6 @@ title: "Utility API"
symbol_kind: "intro"
decl_name: "util.h"
items:
- { name: mg_asprintf.md }
- { name: mg_avprintf.md }
- { name: mg_base64_decode.md }
- { name: mg_base64_encode.md }
- { name: mg_basic_auth_header.md }
......
---
title: "mg_asprintf()"
decl_name: "mg_asprintf"
symbol_kind: "func"
signature: |
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
---
Prints message to the buffer. If the buffer is large enough to hold the
message, it returns buffer. If buffer is to small, it allocates a large
enough buffer on heap and returns allocated buffer.
This is a supposed use case:
char buf[5], *p = buf;
mg_avprintf(&p, sizeof(buf), "%s", "hi there");
use_p_somehow(p);
if (p != buf) {
free(p);
}
The purpose of this is to avoid malloc-ing if generated strings are small.
---
title: "mg_avprintf()"
decl_name: "mg_avprintf"
symbol_kind: "func"
signature: |
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
---
Same as mg_asprintf, but takes varargs list.
......@@ -1480,6 +1480,14 @@ void cs_hmac_sha1(const unsigned char *key, size_t keylen,
#define C_DISABLE_BUILTIN_SNPRINTF 0
#endif
#ifndef MG_MALLOC
#define MG_MALLOC malloc
#endif
#ifndef MG_FREE
#define MG_FREE free
#endif
size_t c_strnlen(const char *s, size_t maxlen) {
size_t l = 0;
for (; l < maxlen && s[l] != '\0'; l++) {
......@@ -1812,6 +1820,51 @@ int mg_casecmp(const char *s1, const char *s2) {
return mg_ncasecmp(s1, s2, (size_t) ~0);
}
int mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
int ret;
va_list ap;
va_start(ap, fmt);
ret = mg_avprintf(buf, size, fmt, ap);
va_end(ap);
return ret;
}
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
va_list ap_copy;
int len;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
va_end(ap_copy);
if (len < 0) {
/* eCos and Windows are not standard-compliant and return -1 when
* the buffer is too small. Keep allocating larger buffers until we
* succeed or out of memory. */
*buf = NULL; /* LCOV_EXCL_START */
while (len < 0) {
MG_FREE(*buf);
size *= 2;
if ((*buf = (char *) MG_MALLOC(size)) == NULL) break;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
va_end(ap_copy);
}
/* LCOV_EXCL_STOP */
} else if (len >= (int) size) {
/* Standard-compliant code path. Allocate a buffer that is large enough. */
if ((*buf = (char *) MG_MALLOC(len + 1)) == NULL) {
len = -1; /* LCOV_EXCL_LINE */
} else { /* LCOV_EXCL_LINE */
va_copy(ap_copy, ap);
len = vsnprintf(*buf, len + 1, fmt, ap_copy);
va_end(ap_copy);
}
}
return len;
}
#endif /* EXCLUDE_COMMON */
#ifdef MG_MODULE_LINES
#line 1 "mongoose/src/tun.h"
......@@ -9123,51 +9176,6 @@ void mg_hexdump_connection(struct mg_connection *nc, const char *path,
}
#endif
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
va_list ap_copy;
int len;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
va_end(ap_copy);
if (len < 0) {
/* eCos and Windows are not standard-compliant and return -1 when
* the buffer is too small. Keep allocating larger buffers until we
* succeed or out of memory. */
*buf = NULL; /* LCOV_EXCL_START */
while (len < 0) {
MG_FREE(*buf);
size *= 2;
if ((*buf = (char *) MG_MALLOC(size)) == NULL) break;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
va_end(ap_copy);
}
/* LCOV_EXCL_STOP */
} else if (len >= (int) size) {
/* Standard-compliant code path. Allocate a buffer that is large enough. */
if ((*buf = (char *) MG_MALLOC(len + 1)) == NULL) {
len = -1; /* LCOV_EXCL_LINE */
} else { /* LCOV_EXCL_LINE */
va_copy(ap_copy, ap);
len = vsnprintf(*buf, len + 1, fmt, ap_copy);
va_end(ap_copy);
}
}
return len;
}
int mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
int ret;
va_list ap;
va_start(ap, fmt);
ret = mg_avprintf(buf, size, fmt, ap);
va_end(ap);
return ret;
}
int mg_is_big_endian(void) {
static const int n = 1;
/* TODO(mkm) use compiletime check with 4-byte char literal */
......
......@@ -1869,6 +1869,26 @@ int mg_ncasecmp(const char *s1, const char *s2, size_t len);
*/
int mg_casecmp(const char *s1, const char *s2);
/*
* Prints message to the buffer. If the buffer is large enough to hold the
* message, it returns buffer. If buffer is to small, it allocates a large
* enough buffer on heap and returns allocated buffer.
* This is a supposed use case:
*
* char buf[5], *p = buf;
* mg_avprintf(&p, sizeof(buf), "%s", "hi there");
* use_p_somehow(p);
* if (p != buf) {
* free(p);
* }
*
* The purpose of this is to avoid malloc-ing if generated strings are small.
*/
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
/* Same as mg_asprintf, but takes varargs list. */
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
#ifdef __cplusplus
}
#endif
......@@ -3763,26 +3783,6 @@ void mg_hexdump_connection(struct mg_connection *nc, const char *path,
const void *buf, int num_bytes, int ev);
#endif
/*
* Prints message to the buffer. If the buffer is large enough to hold the
* message, it returns buffer. If buffer is to small, it allocates a large
* enough buffer on heap and returns allocated buffer.
* This is a supposed use case:
*
* char buf[5], *p = buf;
* mg_avprintf(&p, sizeof(buf), "%s", "hi there");
* use_p_somehow(p);
* if (p != buf) {
* free(p);
* }
*
* The purpose of this is to avoid malloc-ing if generated strings are small.
*/
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
/* Same as mg_asprintf, but takes varargs list. */
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
/*
* Returns true if target platform is big endian.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment