Looks great, but one minor comment below....

On Tue, 2009-11-24 at 00:37 +0100, Andreas Fritiofson wrote:
> The previous implementation was unnecessarily complex. Get rid of the loops,
> let vsnprintf() tell us directly how much storage we need and allocate that. A
> second pass writes the actual string. Also add a va_end() that was missing.
> This should be much faster for large strings and less wasteful for small ones.
> 
> A quirk that has been retained is that some callers patch in a newline at the
> end of the returned string and depend on alloc_vprintf to allocate at least
> one byte extra.
> 
> Signed-off-by: Andreas Fritiofson <andreas.fritiof...@gmail.com>
> ---
>  src/helper/log.c |   43 ++++++++++++++++---------------------------
>  1 files changed, 16 insertions(+), 27 deletions(-)
> 
> diff --git a/src/helper/log.c b/src/helper/log.c
> index caaed42..6869d2e 100644
> --- a/src/helper/log.c
> +++ b/src/helper/log.c
> @@ -395,37 +395,26 @@ 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)
>  {
> -     /* no buffer at the beginning, force realloc to do the job */
> -     char *string = NULL;
> -
> -     /* start with buffer size suitable for typical messages */
> -     int size = 128;
> -
> -     for (;;)
> -     {
> -             char *t = string;
> -             va_list ap_copy;
> -             int ret;
> -             string = realloc(string, size);
> -             if (string == NULL)
> -             {
> -                     if (t != NULL)
> -                             free(t);
> -                     return NULL;
> -             }
> +     va_list ap_copy;
> +     int len;
> +     char *string;
>  
> -             va_copy(ap_copy, ap);
> +     /* determine the length of the buffer needed */
> +     va_copy(ap_copy, ap);
> +     len = vsnprintf(NULL, 0, fmt, ap_copy);
> +     va_end(ap_copy);
>  
> -             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;
> +     /* 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;
>  
> -             /* there was just enough or not enough space, allocate more in 
> the next round */
> -             size *= 2; /* double the buffer size */
> -     }
> +     /* do the real work */
> +     vsnprintf(string, len + 1, fmt, ap_copy);

I think you meant for this to be ap, not ap_copy.

> -     /* the returned buffer is by principle guaranteed to be at least one 
> character longer */
>       return string;
>  }
>  

Fix this minor detail, and I'll commit both of your patches.

--Z

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

Reply via email to