On Sat, 19 Jan 2002, Chris Tillman wrote: > The upshot is that powerpc compilers enforce the correct usage of > varargs, where most i386 compilers do not. It's not really a powerpc > specific problem.
Yep, and here is a patch, against the current sid source, untested, maybe someone should test this or rather redesign the interface relating to xvsprintf() and stuff. The manpage to vsnprintf() explicitly says that the va_list contains something undefined afterwards, so one cannot call it twice in a row without va_end(), va_start() in between. Lukas The patch: diff -purN ratpoison-1.0.0.cvs.20020117/src/bar.c ratpoison-1.0.0.cvs.20020117.mod/src/bar.c --- ratpoison-1.0.0.cvs.20020117/src/bar.c Fri Dec 21 12:58:56 2001 +++ ratpoison-1.0.0.cvs.20020117.mod/src/bar.c Sun Jan 20 17:21:28 2002 @@ -124,7 +124,7 @@ marked_message_printf (int mark_start, i va_list ap; va_start (ap, fmt); - buffer = xvsprintf (fmt, ap); + xvsprintf (buffer, fmt, ap); va_end (ap); marked_message (buffer, mark_start, mark_end); diff -purN ratpoison-1.0.0.cvs.20020117/src/main.c ratpoison-1.0.0.cvs.20020117.mod/src/main.c --- ratpoison-1.0.0.cvs.20020117/src/main.c Wed Jan 16 21:55:17 2002 +++ ratpoison-1.0.0.cvs.20020117.mod/src/main.c Sun Jan 20 17:02:22 2002 @@ -126,47 +126,13 @@ xstrdup (char *s) /* Return a new string based on fmt. */ char * -xvsprintf (char *fmt, va_list ap) -{ - int size, nchars; - char *buffer; - - /* A resonable starting value. */ - size = strlen (fmt) + 1; - buffer = (char *)xmalloc (size); - - nchars = vsnprintf (buffer, size, fmt, ap); - - /* From the GNU Libc manual: In versions of the GNU C library prior - to 2.1 the return value is the number of characters stored, not - including the terminating null; unless there was not enough space - in S to store the result in which case `-1' is returned. */ - if (nchars == -1) - { - do - { - size *= 2; - buffer = (char *)xrealloc (buffer, size); - } while (vsnprintf (buffer, size, fmt, ap) == -1); - } - else if (nchars >= size) - { - buffer = (char *)xrealloc (buffer, nchars + 1); - vsnprintf (buffer, nchars + 1, fmt, ap); - } - - return buffer; -} - -/* Return a new string based on fmt. */ -char * xsprintf (char *fmt, ...) { char *buffer; va_list ap; va_start (ap, fmt); - buffer = xvsprintf (fmt, ap); + xvsprintf (buffer, fmt, ap); va_end (ap); return buffer; diff -purN ratpoison-1.0.0.cvs.20020117/src/ratpoison.h ratpoison-1.0.0.cvs.20020117.mod/src/ratpoison.h --- ratpoison-1.0.0.cvs.20020117/src/ratpoison.h Fri Dec 21 12:58:56 2001 +++ ratpoison-1.0.0.cvs.20020117.mod/src/ratpoison.h Sun Jan 20 17:05:22 2002 @@ -70,6 +70,43 @@ void *xmalloc (size_t size); void *xrealloc (void *ptr, size_t size); char *xstrdup (char *s); char *xsprintf (char *fmt, ...); -char *xvsprintf (char *fmt, va_list ap); + +/* Return a new string based on fmt. */ + +/* + * This should be replaced by something cleaner. Maybe the authors + * should (re)read the manpages of vsnprintf and stdarg and redesign + * this interface. + */ +#define xvsprintf(buf,fmt,ap) \ +{ \ + int size = strlen(fmt) + 1; \ + int nchars; \ + \ + buf = xmalloc(size); \ + nchars = vsnprintf (buf, size, fmt, ap); \ + \ + /* From the GNU Libc manual: In versions of the GNU C library prior \ + to 2.1 the return value is the number of characters stored, not \ + including the terminating null; unless there was not enough space \ + in S to store the result in which case `-1' is returned. */ \ + if (nchars == -1) \ + { \ + do \ + { \ + size *= 2; \ + buf = xrealloc (buf, size); \ + va_end(ap); \ + va_start(ap, fmt); \ + } while (vsnprintf (buf, size, fmt, ap) == -1); \ + } \ + else if (nchars >= size) \ + { \ + buf = xrealloc (buf, nchars + 1); \ + va_end(ap); \ + va_start(ap, fmt); \ + vsnprintf (buf, nchars + 1, fmt, ap); \ + } \ +} #endif /* ! _RATPOISON_H */ diff -purN ratpoison-1.0.0.cvs.20020117/src/sbuf.c ratpoison-1.0.0.cvs.20020117.mod/src/sbuf.c --- ratpoison-1.0.0.cvs.20020117/src/sbuf.c Fri Dec 21 12:58:56 2001 +++ ratpoison-1.0.0.cvs.20020117.mod/src/sbuf.c Sun Jan 20 17:00:58 2002 @@ -98,7 +98,7 @@ sbuf_printf (struct sbuf *b, char *fmt, free (b->data); va_start (ap, fmt); - b->data = xvsprintf (fmt, ap); + xvsprintf (b->data, fmt, ap); va_end (ap); return b->data; @@ -111,7 +111,7 @@ sbuf_printf_concat (struct sbuf *b, char va_list ap; va_start (ap, fmt); - buffer = xvsprintf (fmt, ap); + xvsprintf (buffer, fmt, ap); va_end (ap); sbuf_concat (b, buffer);