-
-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
110 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
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 | ||
]) | ||
|
||
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 | ||
]) | ||
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 | ||
]) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters