The proper solution: tell the maintainers of your vsnprintf to improve
their implementation! ;) --Z

On Mon, 2009-11-30 at 02:20 -0800, Zach Welch wrote:
> 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


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

Reply via email to