summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorsabetts <sabetts>2002-01-27 00:57:19 +0000
committersabetts <sabetts>2002-01-27 00:57:19 +0000
commit4c4d1845ab1425b9a92ebc86288106a8610d2f69 (patch)
tree894a85497e4a953c82d060b2d8c10c3c897f22ed /src/main.c
parent0a53640a044b85a537d49d9ae71a1c69ad08940b (diff)
downloadratpoison-4c4d1845ab1425b9a92ebc86288106a8610d2f69.zip
* configure.in: check for the vsnprintf function and stdarg.h
header. * src/main.c (xvsprintf): Cleaned up to call vsnprintf only in one place. wrap the vsnprintf call with va_copy (or __va_copy) and va_end.
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/src/main.c b/src/main.c
index 2ba8ecf..ae698c5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -130,32 +130,43 @@ xvsprintf (char *fmt, va_list ap)
{
int size, nchars;
char *buffer;
+ va_list ap_copy;
/* 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)
+ while (1)
{
- buffer = (char *)xrealloc (buffer, nchars + 1);
- vsnprintf (buffer, nchars + 1, fmt, ap);
+#if defined(va_copy)
+ va_copy (ap_copy, ap);
+#elif defined(__va_copy)
+ __va_copy (ap_copy, ap);
+#else
+ /* If there is no copy macro then this MAY work. On some systems
+ this could fail because va_list is a pointer so assigning one
+ to the other as below wouldn't make a copy of the data, but
+ just the pointer to the data. */
+ ap_copy = ap;
+#endif
+ nchars = vsnprintf (buffer, size, fmt, ap_copy);
+#if defined(va_copy) || defined(__va_copy)
+ va_end (ap_copy);
+#endif
+
+ if (nchars > -1 && nchars < size)
+ return buffer;
+ else if (nchars > -1)
+ size = nchars + 1;
+ else
+ size *= 2;
+
+ /* Resize the buffer and try again. */
+ buffer = (char *)xrealloc (buffer, size);
}
- return buffer;
+ /* Never gets here. */
+ return NULL;
}
/* Return a new string based on fmt. */