Index: /trunk/acconfig.h
===================================================================
--- /trunk/acconfig.h	(revision 475)
+++ /trunk/acconfig.h	(revision 476)
@@ -375,10 +375,4 @@
 /* Define if your vsnprintf is broken.        */
 #undef HAVE_BROKEN_VSNPRINTF
-
-/* Define if you have va_copy.                */
-#undef VA_COPY
-
-/* Define if va_list may be copied as array.  */
-#undef VA_COPY_AS_ARRAY
 
 /* Define if you need unix entropy gatherer.  */
Index: /trunk/aclocal.m4
===================================================================
--- /trunk/aclocal.m4	(revision 475)
+++ /trunk/aclocal.m4	(revision 476)
@@ -276,89 +276,116 @@
 dnl *** va_copy checks ***
 dnl **********************
-AC_DEFUN([SL_CHECK_VA_COPY],
-[AC_MSG_CHECKING(for va_copy())
-AC_CACHE_VAL(sh_cv_va_copy,[
-        AC_TRY_RUN([
-        #include <stdarg.h>
-        void f (int i, ...) {
-        va_list args1, args2;
-        va_start (args1, i);
-        va_copy (args2, args1);
-        if (va_arg (args2, int) != 42)
-	  exit (1);
-	if (va_arg (args1, int) != 42)
-          exit (1);
-        va_end (args1); va_end (args2);
-        }
-        int main() {
-          f (0, 42);
-          return 0;
-        }],
-        sh_cv_va_copy=yes
-        ,
-        sh_cv_va_copy=no
-        ,
-	sh_cv_va_copy=no)
+# va_copy.m4 serial 1 (js-1.6.20070208)
+
+dnl ## From the OpenWrt Project (http://openwrt.org)
+dnl ## Project is GPL v2
+dnl ##
+dnl ##
+dnl ##  Check for C99 va_copy() implementation
+dnl ##  (and provide fallback implementation if neccessary)
+dnl ##
+dnl ##  configure.in:
+dnl ##    AC_CHECK_VA_COPY
+dnl ##  foo.c:
+dnl ##    #include "config.h"
+dnl ##    [...]
+dnl ##    va_copy(d,s)
+dnl ##
+dnl ##  This check is rather complex: first because we really have to
+dnl ##  try various possible implementations in sequence and second, we
+dnl ##  cannot define a macro in config.h with parameters directly.
+dnl ##
+
+dnl #   test program for va_copy() implementation
+changequote(<<,>>)
+m4_define(__va_copy_test, <<[
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) $1
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+]>>)
+changequote([,])
+
+dnl #   test driver for va_copy() implementation
+m4_define(__va_copy_check, [
+    AH_VERBATIM($1,
+[/* Predefined possible va_copy() implementation (id: $1) */
+#define __VA_COPY_USE_$1(d, s) $2])
+    if test ".$ac_cv_va_copy" = .; then
+        AC_TRY_RUN(__va_copy_test($2), [ac_cv_va_copy="$1"])
+    fi
 ])
-AC_MSG_RESULT($sh_cv_va_copy)
-AC_MSG_CHECKING(for __va_copy())
-AC_CACHE_VAL(sh_cv___va_copy,[
-        AC_TRY_RUN([
-        #include <stdarg.h>
-        void f (int i, ...) {
-        va_list args1, args2;
-        va_start (args1, i);
-        __va_copy (args2, args1);
-        if (va_arg (args2, int) != 42)
-	  exit (1);
-	if (va_arg (args1, int) != 42)
-          exit (1);
-        va_end (args1); va_end (args2);
-        }
-        int main() {
-          f (0, 42);
-          return 0;
-        }],
-        sh_cv___va_copy=yes
-        ,
-        sh_cv___va_copy=no
-        ,
-	sh_cv___va_copy=no)
+
+dnl #   Autoconf check for va_copy() implementation checking
+AC_DEFUN([AC_CHECK_VA_COPY],[
+  dnl #   provide Autoconf display check message
+  AC_MSG_CHECKING(for va_copy() function)
+  dnl #   check for various implementations in priorized sequence   
+  AC_CACHE_VAL(ac_cv_va_copy, [
+    ac_cv_va_copy=""
+    dnl #   1. check for standardized C99 macro
+    __va_copy_check(C99, [va_copy((d), (s))])
+    dnl #   2. check for alternative/deprecated GCC macro
+    __va_copy_check(GCM, [VA_COPY((d), (s))])
+    dnl #   3. check for internal GCC macro (high-level define)
+    __va_copy_check(GCH, [__va_copy((d), (s))])
+    dnl #   4. check for internal GCC macro (built-in function)
+    __va_copy_check(GCB, [__builtin_va_copy((d), (s))])
+    dnl #   5. check for assignment approach (assuming va_list is a struct)
+    __va_copy_check(ASS, [do { (d) = (s); } while (0)])
+    dnl #   6. check for assignment approach (assuming va_list is a pointer)
+    __va_copy_check(ASP, [do { *(d) = *(s); } while (0)])
+    dnl #   7. check for memory copying approach (assuming va_list is a struct)
+    __va_copy_check(CPS, [memcpy((void *)&(d), (void *)&(s)), sizeof((s))])
+    dnl #   8. check for memory copying approach (assuming va_list is a pointer)
+    __va_copy_check(CPP, [memcpy((void *)(d), (void *)(s)), sizeof(*(s))])
+    if test ".$ac_cv_va_copy" = .; then
+        AC_ERROR([no working implementation found])
+    fi
+  ])
+  dnl #   optionally activate the fallback implementation
+  if test ".$ac_cv_va_copy" = ".C99"; then
+      AC_DEFINE(HAVE_VA_COPY, 1, [Define if va_copy() macro exists (and no fallback implementation is required)])
+  fi
+  dnl #   declare which fallback implementation to actually use
+  AC_DEFINE_UNQUOTED([__VA_COPY_USE], [__VA_COPY_USE_$ac_cv_va_copy],
+      [Define to id of used va_copy() implementation])
+  dnl #   provide activation hook for fallback implementation
+  AH_VERBATIM([__VA_COPY_ACTIVATION],
+[/* Optional va_copy() implementation activation */
+#ifndef HAVE_VA_COPY
+#define va_copy(d, s) __VA_COPY_USE(d, s)
+#endif
 ])
-AC_MSG_RESULT($sh_cv___va_copy)
-AC_MSG_CHECKING(whether va_lists can be copied by value)
-AC_CACHE_VAL(sh_cv_va_val_copy,[
-        AC_TRY_RUN([
-        #include <stdarg.h>
-        void f (int i, ...) {
-        va_list args1, args2;
-        va_start (args1, i);
-        args2 = args1;
-        if (va_arg (args2, int) != 42)
-	  exit (1);
-	if (va_arg (args1, int) != 42)
-          exit (1);
-        va_end (args1); va_end (args2);
-        }
-        int main() {
-          f (0, 42);
-          return 0;
-        }],
-        sh_cv_va_val_copy=yes
-        ,
-        sh_cv_va_val_copy=no
-        ,
-	sh_cv_va_val_copy=no)
-])
-if test "x$sh_cv_va_copy" = "xyes"; then
-  AC_DEFINE(VA_COPY, va_copy)
-else if test "x$sh_cv___va_copy" = "xyes"; then
-  AC_DEFINE(VA_COPY, __va_copy)
-fi
-fi
-if test "x$sh_cv_va_val_copy" = "xno"; then
-  AC_DEFINE(VA_COPY_AS_ARRAY)
-fi
-AC_MSG_RESULT($sh_cv_va_val_copy)
+  dnl #   provide Autoconf display result message
+  if test ".$ac_cv_va_copy" = ".C99"; then
+      AC_MSG_RESULT([yes])
+  else
+      AC_MSG_RESULT([no (using fallback implementation)])
+  fi
 ])
 
Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 475)
+++ /trunk/configure.ac	(revision 476)
@@ -395,5 +395,5 @@
 )
 AC_CHECK_FUNC(statfs, AC_DEFINE(HAVE_STATFS) statfs="yes",  statfs="no")
-SL_CHECK_VA_COPY
+AC_CHECK_VA_COPY
 AC_CHECK_FUNCS(vsnprintf, [SL_CHECK_VSNPRINTF])
 AC_CHECK_MLOCK
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 475)
+++ /trunk/docs/Changelog	(revision 476)
@@ -1,3 +1,5 @@
 3.1.6:
+	* More modern and more complete VA_COPY autoconf macro
+	  (from the openwrt project)
 	* Modify testcompile.sh to remove 'smatch' and use 'clang'
 	  instead.
Index: /trunk/src/sh_error.c
===================================================================
--- /trunk/src/sh_error.c	(revision 475)
+++ /trunk/src/sh_error.c	(revision 476)
@@ -1574,14 +1574,4 @@
 }
 
-#if !defined(VA_COPY)
-#if defined(__GNUC__) && defined(__PPC__) && (defined(_CALL_SYSV) || defined(_WIN32))
-#define VA_COPY(ap1, ap2)     (*(ap1) = *(ap2))
-#elif defined(VA_COPY_AS_ARRAY)
-#define VA_COPY(ap1, ap2)     memmove ((ap1), (ap2), sizeof (va_list))
-#else /* va_list is a pointer */
-#define VA_COPY(ap1, ap2)     ((ap1) = (ap2))
-#endif
-#endif 
-
 
 /* print an error  into string
@@ -1717,6 +1707,6 @@
   else 
     {
-      /* use VA_COPY */
-      /*@i@*/VA_COPY(vl2, vl);
+      /* use va_copy */
+      /*@i@*/va_copy(vl2, vl);
       len      = sl_strlen(lmsg->msg);
       /*@i@*/required = sl_vsnprintf(&(lmsg->msg[len]), 
Index: /trunk/src/slib.c
===================================================================
--- /trunk/src/slib.c	(revision 475)
+++ /trunk/src/slib.c	(revision 476)
@@ -587,14 +587,4 @@
 
 
-#if !defined (VA_COPY)
-#if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
-#define VA_COPY(ap1, ap2)     (*(ap1) = *(ap2))
-#elif defined (VA_COPY_AS_ARRAY)
-#define VA_COPY(ap1, ap2)     memmove ((ap1), (ap2), sizeof (va_list))
-#else /* va_list is a pointer */
-#define VA_COPY(ap1, ap2)     ((ap1) = (ap2))
-#endif
-#endif 
-
 #if !defined(HAVE_VSNPRINTF) || defined(HAVE_BROKEN_VSNPRINTF)
 static
@@ -784,5 +774,5 @@
   str[n-1] = '\0';
 #else
-  VA_COPY (vl2, vl);                     /* save the argument list           */
+  va_copy(vl2, vl);                      /* save the argument list           */
   total = sl_printf_count (format, vl);
   len = (int) total;
@@ -830,5 +820,5 @@
   str[n-1] = '\0';
 #else
-  VA_COPY (vl2, vl);                   /* save the argument list           */
+  va_copy(vl2, vl);                    /* save the argument list           */
   total = sl_printf_count (format, vl);
   if (total < n) 
