| 1 |
|
|---|
| 2 |
dnl @synopsis AC_FUNC_SNPRINTF |
|---|
| 3 |
dnl |
|---|
| 4 |
dnl Checks for a fully C99 compliant snprintf, in particular checks |
|---|
| 5 |
dnl whether it does bounds checking and returns the correct string length; |
|---|
| 6 |
dnl does the same check for vsnprintf. If no working snprintf or vsnprintf |
|---|
| 7 |
dnl is found, request a replacement and warn the user about it. |
|---|
| 8 |
dnl Note: the mentioned replacement is freely available and may be used in |
|---|
| 9 |
dnl any project regardless of it's licence (just like the autoconf special |
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
AC_DEFUN([AC_FUNC_SNPRINTF], |
|---|
| 17 |
[AC_CHECK_FUNCS(snprintf vsnprintf) |
|---|
| 18 |
AC_MSG_CHECKING(for working snprintf) |
|---|
| 19 |
AC_CACHE_VAL(ac_cv_have_working_snprintf, |
|---|
| 20 |
[AC_TRY_RUN( |
|---|
| 21 |
[ |
|---|
| 22 |
|
|---|
| 23 |
int main(void) |
|---|
| 24 |
{ |
|---|
| 25 |
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' }; |
|---|
| 26 |
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' }; |
|---|
| 27 |
int i; |
|---|
| 28 |
i = snprintf (bufs, 2, "%s", "111"); |
|---|
| 29 |
if (strcmp (bufs, "1")) exit (1); |
|---|
| 30 |
if (i != 3) exit (1); |
|---|
| 31 |
i = snprintf (bufd, 2, "%d", 111); |
|---|
| 32 |
if (strcmp (bufd, "1")) exit (1); |
|---|
| 33 |
if (i != 3) exit (1); |
|---|
| 34 |
exit(0); |
|---|
| 35 |
}], ac_cv_have_working_snprintf=yes, ac_cv_have_working_snprintf=no, ac_cv_have_working_snprintf=cross)]) |
|---|
| 36 |
AC_MSG_RESULT([$ac_cv_have_working_snprintf]) |
|---|
| 37 |
AC_MSG_CHECKING(for working vsnprintf) |
|---|
| 38 |
AC_CACHE_VAL(ac_cv_have_working_vsnprintf, |
|---|
| 39 |
[AC_TRY_RUN( |
|---|
| 40 |
[ |
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
int my_vsnprintf (char *buf, const char *tmpl, ...) |
|---|
| 44 |
{ |
|---|
| 45 |
int i; |
|---|
| 46 |
va_list args; |
|---|
| 47 |
va_start (args, tmpl); |
|---|
| 48 |
i = vsnprintf (buf, 2, tmpl, args); |
|---|
| 49 |
va_end (args); |
|---|
| 50 |
return i; |
|---|
| 51 |
} |
|---|
| 52 |
|
|---|
| 53 |
int main(void) |
|---|
| 54 |
{ |
|---|
| 55 |
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' }; |
|---|
| 56 |
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' }; |
|---|
| 57 |
int i; |
|---|
| 58 |
i = my_vsnprintf (bufs, "%s", "111"); |
|---|
| 59 |
if (strcmp (bufs, "1")) exit (1); |
|---|
| 60 |
if (i != 3) exit (1); |
|---|
| 61 |
i = my_vsnprintf (bufd, "%d", 111); |
|---|
| 62 |
if (strcmp (bufd, "1")) exit (1); |
|---|
| 63 |
if (i != 3) exit (1); |
|---|
| 64 |
exit(0); |
|---|
| 65 |
}], ac_cv_have_working_vsnprintf=yes, ac_cv_have_working_vsnprintf=no, ac_cv_have_working_vsnprintf=cross)]) |
|---|
| 66 |
AC_MSG_RESULT([$ac_cv_have_working_vsnprintf]) |
|---|
| 67 |
if test x$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf != "xyesyes"; then |
|---|
| 68 |
AC_LIBOBJ(snprintf) |
|---|
| 69 |
AC_MSG_WARN([Replacing missing/broken (v)snprintf() with version from http://www.ijs.si/software/snprintf/.]) |
|---|
| 70 |
AC_DEFINE(PREFER_PORTABLE_SNPRINTF, 1, "enable replacement (v)snprintf if system (v)snprintf is broken") |
|---|
| 71 |
fi]) |
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 |
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
AC_DEFUN([AC_FUNC_MEMMOVE], |
|---|
| 83 |
[AC_CHECK_FUNCS(memmove) |
|---|
| 84 |
AC_MSG_CHECKING(for working memmove) |
|---|
| 85 |
AC_CACHE_VAL(ac_cv_have_working_memmove, |
|---|
| 86 |
[AC_TRY_RUN( |
|---|
| 87 |
[ |
|---|
| 88 |
|
|---|
| 89 |
int main(void) |
|---|
| 90 |
{ |
|---|
| 91 |
char buf[10]; |
|---|
| 92 |
strcpy (buf, "01234567"); |
|---|
| 93 |
memmove (buf, buf + 2, 3); |
|---|
| 94 |
if (strcmp (buf, "23434567")) |
|---|
| 95 |
exit (1); |
|---|
| 96 |
strcpy (buf, "01234567"); |
|---|
| 97 |
memmove (buf + 2, buf, 3); |
|---|
| 98 |
if (strcmp (buf, "01012567")) |
|---|
| 99 |
exit (1); |
|---|
| 100 |
exit (0); |
|---|
| 101 |
}], ac_cv_have_working_memmove=yes, ac_cv_have_working_memmove=no, ac_cv_have_working_memmove=cross)]) |
|---|
| 102 |
AC_MSG_RESULT([$ac_cv_have_working_memmove]) |
|---|
| 103 |
if test x$ac_cv_have_working_memmove != "xyes"; then |
|---|
| 104 |
AC_LIBOBJ(memmove) |
|---|
| 105 |
AC_MSG_WARN([Replacing missing/broken memmove.]) |
|---|
| 106 |
AC_DEFINE(PREFER_PORTABLE_MEMMOVE, 1, "enable replacement memmove if system memmove is broken or missing") |
|---|
| 107 |
fi]) |
|---|
| 108 |
|
|---|
| 109 |
m4_define([AC_LANG_FUNC_LINK_TRY(C)], |
|---|
| 110 |
[AC_LANG_PROGRAM( |
|---|
| 111 |
[/* Define $1 to an innocuous variant, in case <limits.h> declares $1. |
|---|
| 112 |
For example, HP-UX 11i <limits.h> declares gettimeofday. */ |
|---|
| 113 |
|
|---|
| 114 |
|
|---|
| 115 |
/* System header to define __stub macros and hopefully few prototypes, |
|---|
| 116 |
which can conflict with char $1 (); below. |
|---|
| 117 |
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since |
|---|
| 118 |
<limits.h> exists even on freestanding compilers. */ |
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 |
|
|---|
| 126 |
|
|---|
| 127 |
/* Override any gcc2 internal prototype to avoid an error. */ |
|---|
| 128 |
|
|---|
| 129 |
extern "C" |
|---|
| 130 |
{ |
|---|
| 131 |
|
|---|
| 132 |
/* We use char because int might match the return type of a gcc2 |
|---|
| 133 |
builtin and then its argument prototype would still apply. */ |
|---|
| 134 |
char $1 (); |
|---|
| 135 |
/* The GNU C library defines this for functions which it implements |
|---|
| 136 |
to always fail with ENOSYS. Some functions are actually named |
|---|
| 137 |
something starting with __ and the normal name is an alias. */ |
|---|
| 138 |
|
|---|
| 139 |
choke me |
|---|
| 140 |
|
|---|
| 141 |
char (*f) () = $1; |
|---|
| 142 |
|
|---|
| 143 |
|
|---|
| 144 |
} |
|---|
| 145 |
|
|---|
| 146 |
], [return f != $1;])]) |
|---|