Re: Can anyone help with #112770?
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);
Reply to: