Do not apply.  The old implementation was total crap, and your vsnprintf
implementation must be too.  That's not our problem, and it can be
worked around without destroying the improvements for others.

Use a single 'char' on the stack.  One character should be enough.

--Z

On Mon, 2009-11-30 at 10:16 +0100, Øyvind Harboe wrote:
> 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;
>  }
>  


_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to