1275970Scy# Modified by Dave Hart for integration into NTP 4.2.7 <hart@ntp.org>
2275970Scy#
3275970Scy# Changed in a backwards-incompatible way to separate HAVE_SNPRINTF from
4275970Scy# HW_WANT_RPL_SNPRINTF, etc. for each of the four replaced functions.
5275970Scy# HAVE_* will always be set if the corresponding HW_FUNC_* macro is
6275970Scy# invoked, directly or indirectly.  This allows 3rd-party modules like
7275970Scy# libopts to avoid their own replacement of snprintf.
8275970Scy#
9275970Scy# Changed to honor hw_nodef_snprintf, etc. which prevent config.h from
10275970Scy# aliasing snprintf to rpl_snprintf, etc.
11275970Scy#
12275970Scy# Changed to honor hw_force_rpl_snprintf=yes, etc.  This is used by NTP
13275970Scy# to test rpl_snprintf() and rpl_vsnprintf() on platforms which provide
14275970Scy# C99-compliant implementations.
15275970Scy#
16275970Scy
17275970Scy# $Id: snprintf.m4,v 1.1.1.1 2008/01/06 03:24:00 holger Exp $
18275970Scy
19275970Scy# Copyright (c) 2008 Holger Weiss <holger@jhweiss.de>.
20275970Scy#
21275970Scy# This code may freely be used, modified and/or redistributed for any purpose.
22275970Scy# It would be nice if additions and fixes to this file (including trivial code
23275970Scy# cleanups) would be sent back in order to let me include them in the version
24275970Scy# available at <http://www.jhweiss.de/software/snprintf.html>.  However, this is
25275970Scy# not a requirement for using or redistributing (possibly modified) versions of
26275970Scy# this file, nor is leaving this notice intact mandatory.
27275970Scy
28275970Scy# HW_HEADER_STDARG_H
29275970Scy# ------------------
30275970Scy# Define HAVE_STDARG_H to 1 if <stdarg.h> is available.
31275970ScyAC_DEFUN([HW_HEADER_STDARG_H],
32275970Scy[
33275970Scy  AC_PREREQ([2.60])dnl Older releases should work if AC_CHECK_HEADERS is used.
34275970Scy  AC_CHECK_HEADERS_ONCE([stdarg.h])
35275970Scy])# HW_HEADER_STDARG_H
36275970Scy
37275970Scy# HW_HEADER_VARARGS_H
38275970Scy# -------------------
39275970Scy# Define HAVE_VARARGS_H to 1 if <varargs.h> is available.
40275970ScyAC_DEFUN([HW_HEADER_VARARGS_H],
41275970Scy[
42275970Scy  AC_PREREQ([2.60])dnl Older releases should work if AC_CHECK_HEADERS is used.
43275970Scy  AC_CHECK_HEADERS_ONCE([varargs.h])
44275970Scy])# HW_HEADER_VARARGS_H
45275970Scy
46275970Scy# HW_FUNC_VA_COPY
47275970Scy# ---------------
48275970Scy# Set $hw_cv_func_va_copy to "yes" or "no".  Define HAVE_VA_COPY to 1 if
49275970Scy# $hw_cv_func_va_copy is set to "yes".  Note that it's "unspecified whether
50275970Scy# va_copy and va_end are macros or identifiers declared with external linkage."
51275970Scy# (C99: 7.15.1, 1)  Therefore, the presence of va_copy(3) cannot simply "be
52275970Scy# tested with #ifdef", as suggested by the Autoconf manual (5.5.1).
53275970ScyAC_DEFUN([HW_FUNC_VA_COPY],
54275970Scy[
55275970Scy  AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H.
56275970Scy  AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H.
57275970Scy  AC_CACHE_CHECK([for va_copy],
58275970Scy    [hw_cv_func_va_copy],
59275970Scy    [AC_RUN_IFELSE(
60275970Scy      [AC_LANG_PROGRAM(
61275970Scy        [[#if HAVE_STDARG_H
62275970Scy        #include <stdarg.h>
63275970Scy        #elif HAVE_VARARGS_H
64275970Scy        #include <varargs.h>
65275970Scy        #endif]],
66275970Scy        [[va_list ap, aq; va_copy(aq, ap);]])],
67275970Scy      [hw_cv_func_va_copy=yes],
68275970Scy      [hw_cv_func_va_copy=no],
69275970Scy      [hw_cv_func_va_copy=no])])
70275970Scy  AS_IF([test "$hw_cv_func_va_copy" = yes],
71275970Scy    [AC_DEFINE([HAVE_VA_COPY], [1],
72275970Scy      [Define to 1 if you have the `va_copy' function or macro.])])
73275970Scy])# HW_FUNC_VA_COPY
74275970Scy
75275970Scy# HW_FUNC___VA_COPY
76275970Scy# -----------------
77275970Scy# Set $hw_cv_func___va_copy to "yes" or "no".  Define HAVE___VA_COPY to 1 if
78275970Scy# $hw_cv_func___va_copy is set to "yes".
79275970ScyAC_DEFUN([HW_FUNC___VA_COPY],
80275970Scy[
81275970Scy  AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H.
82275970Scy  AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H.
83275970Scy  AC_CACHE_CHECK([for __va_copy],
84275970Scy    [hw_cv_func___va_copy],
85275970Scy    [AC_RUN_IFELSE(
86275970Scy      [AC_LANG_PROGRAM(
87275970Scy        [[#if HAVE_STDARG_H
88275970Scy        #include <stdarg.h>
89275970Scy        #elif HAVE_VARARGS_H
90275970Scy        #include <varargs.h>
91275970Scy        #endif]],
92275970Scy        [[va_list ap, aq; __va_copy(aq, ap);]])],
93275970Scy      [hw_cv_func___va_copy=yes],
94275970Scy      [hw_cv_func___va_copy=no],
95275970Scy      [hw_cv_func___va_copy=no])])
96275970Scy  AS_IF([test "$hw_cv_func___va_copy" = yes],
97275970Scy    [AC_DEFINE([HAVE___VA_COPY], [1],
98275970Scy      [Define to 1 if you have the `__va_copy' function or macro.])])
99275970Scy])# HW_FUNC___VA_COPY
100275970Scy
101275970Scy# HW_FUNC_VSNPRINTF
102275970Scy# -----------------
103275970Scy# Set $hw_cv_func_vsnprintf and $hw_cv_func_vsnprintf_c99 to "yes" or
104275970Scy# "no", respectively.  If either $hw_force_rpl_vsnprintf is "yes" or
105275970Scy# $hw_cv_func_vsnprintf_c99 is "no", define HW_WANT_RPL_VSNPRINTF and
106275970Scy# define vsnprintf to rpl_vsnprintf.
107275970ScyAC_DEFUN([HW_FUNC_VSNPRINTF],
108275970Scy[
109275970Scy  AC_PREREQ([2.60])dnl 2.59 should work if some AC_TYPE_* macros are replaced.
110275970Scy  AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H.
111275970Scy  AC_CHECK_FUNC([vsnprintf],
112275970Scy    [hw_cv_func_vsnprintf=yes],
113275970Scy    [hw_cv_func_vsnprintf=no])
114275970Scy  AS_IF([test "$hw_cv_func_vsnprintf" = yes],
115275970Scy    [AC_CACHE_CHECK([whether vsnprintf is C99 compliant],
116275970Scy      [hw_cv_func_vsnprintf_c99],
117275970Scy      [AC_RUN_IFELSE(
118275970Scy        [AC_LANG_PROGRAM(
119275970Scy          [[#if HAVE_STDARG_H
120275970Scy          #include <stdarg.h>
121275970Scy          #endif
122275970Scy          #include <stdio.h>
123275970Scy          static int testprintf(char *buf, size_t size, const char *format, ...)
124275970Scy          {
125275970Scy            int result;
126275970Scy            va_list ap;
127275970Scy            va_start(ap, format);
128275970Scy            result = vsnprintf(buf, size, format, ap);
129275970Scy            va_end(ap);
130275970Scy            return result;
131275970Scy          }]],
132275970Scy          [[char buf[43];
133275970Scy          if (testprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 ||
134275970Scy              testprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 ||
135275970Scy              buf[0] != 'T' || buf[3] != '\0')
136275970Scy            return 1;]])],
137275970Scy        [hw_cv_func_vsnprintf_c99=yes],
138275970Scy        [hw_cv_func_vsnprintf_c99=no],
139275970Scy        [hw_cv_func_vsnprintf_c99=no])])],
140275970Scy    [hw_cv_func_vsnprintf_c99=no])
141275970Scy  AC_DEFINE([HAVE_VSNPRINTF], [1],
142275970Scy      [Define if C99-compliant `vsnprintf' is available.])
143275970Scy  AC_MSG_CHECKING([if C99-snprintf replacement vsnprintf will be used])
144275970Scy  AS_IF([test "${hw_force_rpl_vsnprintf=no}" = yes -o "$hw_cv_func_vsnprintf_c99" = no],
145275970Scy    [hw_use_rpl_vsnprintf=yes],
146275970Scy    [hw_use_rpl_vsnprintf=no])
147275970Scy  AC_MSG_RESULT([$hw_use_rpl_vsnprintf])
148275970Scy  AS_IF([test "$hw_use_rpl_vsnprintf" = yes],
149275970Scy    [AC_DEFINE([HW_WANT_RPL_VSNPRINTF], [1],
150275970Scy      [Define to provide `rpl_vsnprintf' function.])
151275970Scy    AS_IF([test ${hw_nodef_vsnprintf=no} = no],
152275970Scy      [AC_DEFINE([vsnprintf], [rpl_vsnprintf],
153275970Scy        [Define to rpl_vsnprintf if the replacement function should be used.])])
154275970Scy    AC_CHECK_HEADERS([inttypes.h locale.h stddef.h stdint.h])
155275970Scy    AC_CHECK_MEMBERS([struct lconv.decimal_point, struct lconv.thousands_sep],
156275970Scy      [], [], [#include <locale.h>])
157275970Scy    AC_TYPE_LONG_DOUBLE
158275970Scy    AC_TYPE_LONG_LONG_INT
159275970Scy    AC_TYPE_UNSIGNED_LONG_LONG_INT
160275970Scy    AC_TYPE_SIZE_T
161275970Scy    AC_TYPE_INTMAX_T
162275970Scy    AC_TYPE_UINTMAX_T
163275970Scy    AC_TYPE_UINTPTR_T
164275970Scy    AC_CHECK_TYPES([ptrdiff_t])
165275970Scy    AC_CHECK_FUNCS([localeconv])
166275970Scy    _HW_FUNC_XPRINTF_REPLACE])
167275970Scy])# HW_FUNC_VSNPRINTF
168275970Scy
169275970Scy# HW_FUNC_SNPRINTF
170275970Scy# ----------------
171275970Scy# Set $hw_cv_func_snprintf and $hw_cv_func_snprintf_c99 to "yes" or
172275970Scy# "no", respectively.  If either $hw_force_rpl_snprintf is "yes" or
173275970Scy# $hw_cv_func_snprintf_c99 is "no", define HW_WANT_RPL_SNPRINTF and
174275970Scy# define snprintf to rpl_snprintf.
175275970Scy# The same will be done for vsnprintf, as if HW_FUNC_VSNPRINTF were
176275970Scy# used.
177275970ScyAC_DEFUN([HW_FUNC_SNPRINTF],
178275970Scy[
179275970Scy  AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our snprintf(3) calls vsnprintf(3).
180275970Scy  AC_CHECK_FUNC([snprintf],
181275970Scy    [hw_cv_func_snprintf=yes],
182275970Scy    [hw_cv_func_snprintf=no])
183275970Scy  AS_IF([test "$hw_cv_func_snprintf" = yes],
184275970Scy    [AC_CACHE_CHECK([whether snprintf is C99 compliant],
185275970Scy      [hw_cv_func_snprintf_c99],
186275970Scy      [AC_RUN_IFELSE(
187275970Scy        [AC_LANG_PROGRAM([[#include <stdio.h>]],
188275970Scy          [[char buf[43];
189275970Scy          if (snprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 ||
190275970Scy              snprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 ||
191275970Scy              buf[0] != 'T' || buf[3] != '\0')
192275970Scy            return 1;]])],
193275970Scy        [hw_cv_func_snprintf_c99=yes],
194275970Scy        [hw_cv_func_snprintf_c99=no],
195275970Scy        [hw_cv_func_snprintf_c99=no])])],
196275970Scy    [hw_cv_func_snprintf_c99=no])
197275970Scy  AC_DEFINE([HAVE_SNPRINTF], [1],
198275970Scy      [Define if C99-compliant `snprintf' is available.])
199275970Scy  AC_MSG_CHECKING([if C99-snprintf replacement snprintf will be used])
200275970Scy  AS_IF([test "${hw_force_rpl_snprintf=no}" = yes -o "$hw_cv_func_snprintf_c99" = no],
201275970Scy    [hw_use_rpl_snprintf=yes],
202275970Scy    [hw_use_rpl_snprintf=no])
203275970Scy  AC_MSG_RESULT([$hw_use_rpl_snprintf])
204275970Scy  AS_IF([test "$hw_use_rpl_snprintf" = yes],
205275970Scy    [AC_DEFINE([HW_WANT_RPL_SNPRINTF], [1],
206275970Scy      [Define to provide `rpl_snprintf' function.])
207275970Scy    AS_IF([test ${hw_nodef_snprintf=no} = no],
208275970Scy      [AC_DEFINE([snprintf], [rpl_snprintf],
209275970Scy        [Define to rpl_snprintf if the replacement function should be used.])])
210275970Scy    _HW_FUNC_XPRINTF_REPLACE])
211275970Scy])# HW_FUNC_SNPRINTF
212275970Scy
213275970Scy# HW_FUNC_VASPRINTF
214275970Scy# -----------------
215275970Scy# Set $hw_cv_func_vasprintf to "yes" or "no".  If either
216275970Scy# $hw_force_rpl_vasprintf is "yes" or $hw_cv_func_vasprintf is "no",
217275970Scy# define HW_WANT_RPL_VASPRINTF and define vasprintf to rpl_vasprintf.
218275970Scy# The same will be done for vsnprintf, as if HW_FUNC_VSNPRINTF were
219275970Scy# used.
220275970ScyAC_DEFUN([HW_FUNC_VASPRINTF],
221275970Scy[
222275970Scy  AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our vasprintf(3) calls vsnprintf(3).
223275970Scy  AC_CHECK_FUNCS([vasprintf],
224275970Scy    [hw_cv_func_vasprintf=yes],
225275970Scy    [hw_cv_func_vasprintf=no])
226275970Scy  AC_DEFINE([HAVE_VASPRINTF], [1],
227275970Scy      [Define if `vasprintf' is available.])
228275970Scy  AC_MSG_CHECKING([if C99-snprintf replacement vasprintf will be used])
229275970Scy  AS_IF([test "${hw_force_rpl_vasprintf=no}" = yes -o "$hw_cv_func_vasprintf" = no],
230275970Scy    [hw_use_rpl_vasprintf=yes],
231275970Scy    [hw_use_rpl_vasprintf=no])
232275970Scy  AC_MSG_RESULT([$hw_use_rpl_vasprintf])
233275970Scy  AS_IF([test "$hw_use_rpl_vasprintf" = yes],
234275970Scy    [AC_DEFINE([HW_WANT_RPL_VASPRINTF], [1],
235275970Scy      [Define to provide `rpl_vasprintf' function.])
236275970Scy    AS_IF([test ${hw_nodef_vasprintf=no} = no],
237275970Scy      [AC_DEFINE([vasprintf], [rpl_vasprintf],
238275970Scy      [Define to rpl_vasprintf if the replacement function should be used.])])
239275970Scy    AC_CHECK_HEADERS([stdlib.h])
240275970Scy    HW_FUNC_VA_COPY
241275970Scy    AS_IF([test "$hw_cv_func_va_copy" = no],
242275970Scy      [HW_FUNC___VA_COPY])
243275970Scy    _HW_FUNC_XPRINTF_REPLACE])
244275970Scy])# HW_FUNC_VASPRINTF
245275970Scy
246275970Scy# HW_FUNC_ASPRINTF
247275970Scy# ----------------
248275970Scy# Set $hw_cv_func_asprintf to "yes" or "no".  If either
249275970Scy# $hw_force_rpl_asprintf is "yes" or $hw_cv_func_asprintf is "no",
250275970Scy# define HW_WANT_RPL_ASPRINTF and define asprintf to rpl_asprintf.
251275970Scy# The same will be done for vasprintf, as if HW_FUNC_VASPRINTF were
252275970Scy# used.
253275970ScyAC_DEFUN([HW_FUNC_ASPRINTF],
254275970Scy[
255275970Scy  AC_REQUIRE([HW_FUNC_VASPRINTF])dnl Our asprintf(3) calls vasprintf(3).
256275970Scy  AC_CHECK_FUNCS([asprintf],
257275970Scy    [hw_cv_func_asprintf=yes],
258275970Scy    [hw_cv_func_asprintf=no])
259275970Scy  AC_DEFINE([HAVE_ASPRINTF], [1],
260275970Scy      [Define if `asprintf' is available.])
261275970Scy  AC_MSG_CHECKING([if C99-snprintf replacement asprintf will be used])
262275970Scy  AS_IF([test "${hw_force_rpl_asprintf=no}" = yes -o "$hw_cv_func_asprintf" = no],
263275970Scy    [hw_use_rpl_asprintf=yes],
264275970Scy    [hw_use_rpl_asprintf=no])
265275970Scy  AC_MSG_RESULT([$hw_use_rpl_asprintf])
266275970Scy  AS_IF([test "$hw_use_rpl_asprintf" = yes],
267275970Scy    [AC_DEFINE([HW_WANT_RPL_ASPRINTF], [1],
268275970Scy      [Define to provide `rpl_asprintf' function.])
269275970Scy    AS_IF([test ${hw_nodef_asprintf=no} = no],
270275970Scy      [AC_DEFINE([asprintf], [rpl_asprintf],
271275970Scy      [Define to rpl_asprintf if the replacement function should be used.])])
272275970Scy    _HW_FUNC_XPRINTF_REPLACE])
273275970Scy])# HW_FUNC_ASPRINTF
274275970Scy
275275970Scy# _HW_FUNC_XPRINTF_REPLACE
276275970Scy# ------------------------
277275970Scy# Arrange for building snprintf.c.  Must be called if one or more of the
278275970Scy# functions provided by snprintf.c are needed.
279275970ScyAC_DEFUN([_HW_FUNC_XPRINTF_REPLACE],
280275970Scy[
281275970Scy  AS_IF([test "x$_hw_cv_func_xprintf_replace_done" != xyes],
282275970Scy    [AC_C_CONST
283275970Scy    HW_HEADER_STDARG_H
284275970Scy    AC_LIBOBJ([snprintf])
285275970Scy    _hw_cv_func_xprintf_replace_done=yes])
286275970Scy])# _HW_FUNC_XPRINTF_REPLACE
287275970Scy
288275970Scydnl vim: set joinspaces textwidth=80:
289