Whether or not vsnprintf() allows NULL as pointer to destination
string to calculate length depends on the implementation.
Revert more efficient, but non-portable implementation.
This reverts commit 338a674faa96ae321560efa3f1b1e8122d61aac4.
---
src/helper/log.c | 43 +++++++++++++++++++++++++++----------------
1 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/src/helper/log.c b/src/helper/log.c
index 3067ecc..f1aa6d7 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -417,26 +417,37 @@ int log_remove_callback(log_callback_fn fn, void *priv)
/* return allocated string w/printf() result */
char *alloc_vprintf(const char *fmt, va_list ap)
{
- va_list ap_copy;
- int len;
- char *string;
+ /* no buffer at the beginning, force realloc to do the job */
+ char *string = NULL;
- /* determine the length of the buffer needed */
- va_copy(ap_copy, ap);
- len = vsnprintf(NULL, 0, fmt, ap_copy);
- va_end(ap_copy);
+ /* start with buffer size suitable for typical messages */
+ int size = 128;
- /* allocate and make room for terminating zero. */
- /* FIXME: The old version always allocated at least one byte extra and
- * other code depend on that. They should be probably be fixed, but for
- * now reserve the extra byte. */
- string = malloc(len + 2);
- if (string == NULL)
- return NULL;
+ for (;;)
+ {
+ char *t = string;
+ va_list ap_copy;
+ int ret;
+ string = realloc(string, size);
+ if (string == NULL)
+ {
+ if (t != NULL)
+ free(t);
+ return NULL;
+ }
- /* do the real work */
- vsnprintf(string, len + 1, fmt, ap);
+ va_copy(ap_copy, ap);
+
+ ret = vsnprintf(string, size, fmt, ap_copy);
+ /* NB! The result of the vsnprintf() might be an *EMPTY*
string! */
+ if ((ret >= 0) && ((ret + 1) < size))
+ break;
+
+ /* there was just enough or not enough space, allocate more in
the next round */
+ size *= 2; /* double the buffer size */
+ }
+ /* the returned buffer is by principle guaranteed to be at least one
character longer */
return string;
}
--
1.6.3.3
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development