Index: ossp-pkg/var/ChangeLog RCS File: /v/ossp/cvs/ossp-pkg/var/ChangeLog,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/var/ChangeLog,v' 2>/dev/null --- ChangeLog 2003/10/24 18:24:35 1.2 +++ ChangeLog 2004/04/04 08:04:34 1.3 @@ -11,9 +11,15 @@ This is a list of all source changes to OSSP var. For less details please have a look at the NEWS file. - Changes between 1.0.0 and 1.0.1 (14-Feb-2002 to xx-Oct-2003) + Changes between 1.0.0 and 1.1.0 (14-Feb-2002 to 04-Apr-2004) - o Upgraded build environment to GNU libtool 1.5 + o Provide Autoconf check (AC_CHECK_VA_COPY) for va_copy(d,s) macro + and fallback implementations and now that we can be sure that + va_copy() exists for us, use it in var_formatv() and ts.c instead + of the direct assignments (which are not sufficiently portable). + [Ralf S. Engelschall ] + + o Upgraded build environment to GNU libtool 1.5.4 and GNU autoconf 2.59 [Ralf S. Engelschall ] Changes between 0.9.0 and 1.0.0 (08-Mar-2002 to 14-Feb-2003) Index: ossp-pkg/var/aclocal.m4 RCS File: /v/ossp/cvs/ossp-pkg/var/aclocal.m4,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/var/aclocal.m4,v' 2>/dev/null --- aclocal.m4 2003/02/14 21:17:07 1.8 +++ aclocal.m4 2004/04/04 08:04:34 1.9 @@ -234,4 +234,108 @@ AC_MSG_RESULT([$with_$2]) ])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 +#include +#include +#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 $2]) + if test ".$ac_cv_va_copy" = .; then + AC_TRY_RUN(__va_copy_test($2), [ac_cv_va_copy="$1"]) + fi +]) + +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(STD, [va_copy((d), (s))]) + dnl # 2. check for alternative/deprecated GCC macro + __va_copy_check(MAC, [VA_COPY((d), (s))]) + dnl # 3. check for assignment approach (assuming va_list is a struct) + __va_copy_check(AS1, [do { (d) = (s); } while (0)]) + dnl # 4. check for assignment approach (assuming va_list is a pointer) + __va_copy_check(AS2, [do { *(d) = *(s); } while (0)]) + dnl # 5. check for memory copying approach (assuming va_list is a struct) + __va_copy_check(CP1, [memcpy((void *)&(d), (void *)&(s)), sizeof((s))]) + dnl # 6. check for memory copying approach (assuming va_list is a pointer) + __va_copy_check(CP2, [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" = ".STD"; 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 +]) + dnl # provide Autoconf display result message + if test ".$ac_cv_va_copy" = ".STD"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no (using fallback implementation)]) + fi +]) Index: ossp-pkg/var/configure.ac RCS File: /v/ossp/cvs/ossp-pkg/var/configure.ac,v rcsdiff -q -kk '-r1.13' '-r1.14' -u '/v/ossp/cvs/ossp-pkg/var/configure.ac,v' 2>/dev/null --- configure.ac 2003/02/14 21:17:07 1.13 +++ configure.ac 2004/04/04 08:04:34 1.14 @@ -45,6 +45,9 @@ dnl # checks for platform environment AC_CHECK_FUNCS(snprintf) +dnl # check for va_copy() +AC_CHECK_VA_COPY + dnl # checks for external libraries AC_CHECK_EXTLIB([OSSP ex], ex, __ex_ctx, ex.h, [AC_DEFINE(WITH_EX, 1, [Define to 1 if building with OSSP ex])]) Index: ossp-pkg/var/ts.c RCS File: /v/ossp/cvs/ossp-pkg/var/ts.c,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/var/ts.c,v' 2>/dev/null --- ts.c 2003/02/14 21:17:07 1.4 +++ ts.c 2004/04/04 08:04:34 1.5 @@ -206,7 +206,7 @@ if (format == NULL) return NULL; - ap2 = ap; + va_copy(ap2, ap); if ((n = ts_suite_mvxprintf(NULL, 0, format, ap)) == -1) return NULL; if ((buffer = (char *)malloc(n+1)) == NULL) Index: ossp-pkg/var/var.c RCS File: /v/ossp/cvs/ossp-pkg/var/var.c,v rcsdiff -q -kk '-r1.101' '-r1.102' -u '/v/ossp/cvs/ossp-pkg/var/var.c,v' 2>/dev/null --- var.c 2004/02/17 09:21:06 1.101 +++ var.c 2004/04/04 08:04:34 1.102 @@ -2621,9 +2621,9 @@ return VAR_RC(VAR_ERR_INVALID_ARGUMENT); /* determine formatting buffer length */ - apbak = ap; + va_copy(apbak, ap); nBuf = var_mvsnprintf(NULL, 0, fmt, ap); - ap = apbak; + va_copy(ap, apbak); if (nBuf == -1) return VAR_RC(VAR_ERR_FORMATTING_FAILURE);