Skip to content

Commit d034702

Browse files
committed
configure.ac: upgrade ancient snprintf macro to modern autoconf-archive edition
ac_func_snprintf was very old, and produced illogical results with modern compilers. Specifically, the check always failed and claimed: ``` checking for snprintf... yes checking for vsnprintf... yes checking for working snprintf... no checking for working vsnprintf... no configure: WARNING: Will use fallback (v)snprintf() implementation. ``` autoconf-archive has migrated to a dedicated AX_ namespace and released a couple decades worth of improvements, including fixing this particular bug in 2022.
1 parent a24b8da commit d034702

File tree

3 files changed

+87
-74
lines changed

3 files changed

+87
-74
lines changed

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ AC_CHECK_MEMBERS([struct stat.st_rdev])
3232

3333
# Checks for library functions.
3434
AC_CHECK_FUNCS([getopt_long getline strtof])
35-
AC_FUNC_SNPRINTF
35+
AX_FUNC_SNPRINTF
3636
AC_FUNC_SCANF_CAN_MALLOC
3737

3838
AC_MSG_CHECKING(--enable-libarchive argument)

m4/ac_func_snprintf.m4

-73
This file was deleted.

m4/ax_func_snprintf.m4

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# ===========================================================================
2+
# https://www.gnu.org/software/autoconf-archive/ax_func_snprintf.html
3+
# ===========================================================================
4+
#
5+
# SYNOPSIS
6+
#
7+
# AX_FUNC_SNPRINTF
8+
#
9+
# DESCRIPTION
10+
#
11+
# Checks for a fully C99 compliant snprintf, in particular checks whether
12+
# it does bounds checking and returns the correct string length; does the
13+
# same check for vsnprintf. If no working snprintf or vsnprintf is found,
14+
# request a replacement and warn the user about it. Note: the mentioned
15+
# replacement is freely available and may be used in any project
16+
# regardless of it's license.
17+
#
18+
# LICENSE
19+
#
20+
# Copyright (c) 2008 Ruediger Kuhlmann <[email protected]>
21+
#
22+
# Copying and distribution of this file, with or without modification, are
23+
# permitted in any medium without royalty provided the copyright notice
24+
# and this notice are preserved. This file is offered as-is, without any
25+
# warranty.
26+
27+
#serial 8
28+
29+
AU_ALIAS([AC_FUNC_SNPRINTF], [AX_FUNC_SNPRINTF])
30+
AC_DEFUN([AX_FUNC_SNPRINTF],
31+
[AC_CHECK_FUNCS(snprintf vsnprintf)
32+
AC_MSG_CHECKING(for working snprintf)
33+
AC_CACHE_VAL(ac_cv_have_working_snprintf,
34+
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
35+
#include <stdlib.h>
36+
#include <string.h>
37+
int main(void)
38+
{
39+
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
40+
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
41+
int i;
42+
i = snprintf (bufs, 2, "%s", "111");
43+
if (strcmp (bufs, "1")) exit (1);
44+
if (i != 3) exit (1);
45+
i = snprintf (bufd, 2, "%d", 111);
46+
if (strcmp (bufd, "1")) exit (1);
47+
if (i != 3) exit (1);
48+
exit(0);
49+
}]])],[ac_cv_have_working_snprintf=yes],[ac_cv_have_working_snprintf=no],[ac_cv_have_working_snprintf=cross])])
50+
AC_MSG_RESULT([$ac_cv_have_working_snprintf])
51+
AC_MSG_CHECKING(for working vsnprintf)
52+
AC_CACHE_VAL(ac_cv_have_working_vsnprintf,
53+
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
54+
#include <stdarg.h>
55+
#include <stdlib.h>
56+
#include <string.h>
57+
58+
int my_vsnprintf (char *buf, const char *tmpl, ...)
59+
{
60+
int i;
61+
va_list args;
62+
va_start (args, tmpl);
63+
i = vsnprintf (buf, 2, tmpl, args);
64+
va_end (args);
65+
return i;
66+
}
67+
68+
int main(void)
69+
{
70+
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
71+
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
72+
int i;
73+
i = my_vsnprintf (bufs, "%s", "111");
74+
if (strcmp (bufs, "1")) exit (1);
75+
if (i != 3) exit (1);
76+
i = my_vsnprintf (bufd, "%d", 111);
77+
if (strcmp (bufd, "1")) exit (1);
78+
if (i != 3) exit (1);
79+
exit(0);
80+
}]])],[ac_cv_have_working_vsnprintf=yes],[ac_cv_have_working_vsnprintf=no],[ac_cv_have_working_vsnprintf=cross])])
81+
AC_MSG_RESULT([$ac_cv_have_working_vsnprintf])
82+
if test x$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf != "xyesyes"; then
83+
AC_LIBOBJ(snprintf)
84+
AC_MSG_WARN([Replacing missing/broken (v)snprintf() with version from http://www.ijs.si/software/snprintf/.])
85+
AC_DEFINE(PREFER_PORTABLE_SNPRINTF, 1, "enable replacement (v)snprintf if system (v)snprintf is broken")
86+
fi])

0 commit comments

Comments
 (0)