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
> [email protected]
> https://lists.berlios.de/mailman/listinfo/openocd-development
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development