diff --git a/acinclude.m4 b/acinclude.m4 index 650b42d14..0a75853ad 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -340,3 +340,64 @@ AC_SUBST(XMMS_OUTPUT_PLUGIN_DIR) AC_SUBST(XMMS_GENERAL_PLUGIN_DIR) AC_SUBST(XMMS_EFFECT_PLUGIN_DIR) ]) + +dnl Checks if function/macro va_copy() is available +dnl Defines HAVE_VA_COPY on success. +AC_DEFUN(AC_FUNC_VA_COPY, +[AC_CACHE_CHECK([for va_copy], ac_cv_func_va_copy, + [AC_TRY_LINK([ +#ifdef HAVE_STDARG_H +# include +#else +# include +#endif], + [ +va_list a, b; + +va_copy(a, b);], + [ac_cv_func_va_copy=yes], + [ac_cv_func_va_copy=no])]) +if test $ac_cv_func_va_copy = yes; then + AC_DEFINE(HAVE_VA_COPY, 1, [Define if va_copy is available]) +fi]) + +dnl Checks if function/macro __va_copy() is available +dnl Defines HAVE__VA_COPY on success. +AC_DEFUN(AC_FUNC__VA_COPY, +[AC_CACHE_CHECK([for __va_copy], ac_cv_func__va_copy, + [AC_TRY_LINK([ +#ifdef HAVE_STDARG_H +# include +#else +# include +#endif], + [ +va_list a, b; + +__va_copy(a, b);], + [ac_cv_func__va_copy=yes], + [ac_cv_func__va_copy=no])]) +if test $ac_cv_func__va_copy = yes; then + AC_DEFINE(HAVE__VA_COPY, 1, [Define if __va_copy is available]) +fi]) + +dnl Checks if va_list is an array +dnl Defines VA_LIST_IS_ARRAY on success. +AC_DEFUN(AC_TYPE_VA_LIST, +[AC_CACHE_CHECK([if va_list is an array], ac_cv_type_va_list_array, + [AC_TRY_LINK([ +#ifdef HAVE_STDARG_H +# include +#else +# include +#endif +], + [ +va_list a, b; + +a = b;], + [ac_cv_type_va_list_array=no], + [ac_cv_type_va_list_array=yes])]) +if test $ac_cv_type_va_list_array = yes; then + AC_DEFINE(VA_LIST_IS_ARRAY, 1, [Define if va_list is an array]) +fi]) diff --git a/configure.ac b/configure.ac index d2642af36..b3cf5c9fd 100644 --- a/configure.ac +++ b/configure.ac @@ -172,6 +172,8 @@ AC_STRUCT_ST_BLKSIZE AC_HEADER_TIME AC_STRUCT_TM +AC_TYPE_VA_LIST + if test "x$cross_compiling" = xyes; then AC_MSG_CHECKING(whether byte ordering is bigendian) AC_ARG_WITH(endian, @@ -321,6 +323,8 @@ AC_FUNC_MEMCMP AC_FUNC_MMAP AC_TYPE_SIGNAL AC_FUNC_VPRINTF +AC_FUNC_VA_COPY +AC_FUNC__VA_COPY AC_CHECK_FUNCS( access _access \ gethostname gethostbyname connect gettimeofday getwd mkdir _mkdir \ diff --git a/libs/util/dstring.c b/libs/util/dstring.c index 31770c8a6..0593e6097 100644 --- a/libs/util/dstring.c +++ b/libs/util/dstring.c @@ -164,11 +164,24 @@ dstring_clearstr (dstring_t *dstr) dstr->str[0] = 0; } +#if defined (HAVE_VA_COPY) +# define VA_COPY(a,b) va_copy (a, b) +#elif defined (HAVE__VA_COPY) +# define VA_COPY(a,b) __va_copy (a, b) +#else +# define VA_COPY memcpy (a, b, sizeof (a)) +#endif + int dvsprintf (dstring_t *dstr, const char *fmt, va_list args) { int size; +#ifdef VA_LIST_IS_ARRAY + va_list tmp_args; + VA_COPY (tmp_args, args); +#endif + size = vsnprintf (dstr->str, dstr->truesize, fmt, args) + 1; // +1 for nul while (size <= 0 || size > dstr->truesize) { if (size > 0) @@ -176,6 +189,9 @@ dvsprintf (dstring_t *dstr, const char *fmt, va_list args) else dstr->size = dstr->truesize + 1024; dstring_adjust (dstr); +#ifdef VA_LIST_IS_ARRAY + VA_COPY (args, tmp_args); +#endif size = vsnprintf (dstr->str, dstr->truesize, fmt, args) + 1; } dstr->size = size;