summaryrefslogtreecommitdiff
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
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.
-rw-r--r--ChangeLog7
-rw-r--r--configure.in7
-rw-r--r--src/main.c47
3 files changed, 40 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 083c3d8..b847444 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2002-01-26 shawn <sabetts@vcn.bc.ca>
+ * 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.
+
* src/list.c (format_window_name): If res_class or res_name are
NULL use "None" instead.
diff --git a/configure.in b/configure.in
index 6e3d8f6..c2f9629 100644
--- a/configure.in
+++ b/configure.in
@@ -17,7 +17,7 @@ dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dnl
-dnl $Id: configure.in,v 1.24 2002/01/08 19:13:06 algernon Exp $
+dnl $Id: configure.in,v 1.25 2002/01/27 00:57:19 sabetts Exp $
AC_INIT(src/main.c)
AM_INIT_AUTOMAKE(ratpoison, 1.0.1-cvs)
@@ -69,12 +69,13 @@ AC_CHECK_LIB(X11, XOpenDisplay,,
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(unistd.h stdarg.h)
dnl Checks for typedefs, structures, and compiler characteristics.
dnl Checks for library functions.
-AC_CHECK_FUNCS(getopt getopt_long setsid setpgid setpgrp setenv unsetenv)
+AC_CHECK_FUNCS(getopt getopt_long setsid setpgid setpgrp setenv unsetenv vsnprintf )
+
AC_TYPE_SIGNAL
AC_OUTPUT(Makefile doc/Makefile src/Makefile contrib/Makefile)
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. */