1# Copyright (c) 2008 Holger Weiss <holger@jhweiss.de>.
2#
3# This code may freely be used, modified and/or redistributed for any purpose.
4# It would be nice if additions and fixes to this file (including trivial code
5# cleanups) would be sent back in order to let me include them in the version
6# available at <http://www.jhweiss.de/software/snprintf.html>.  However, this is
7# not a requirement for using or redistributing (possibly modified) versions of
8# this file, nor is leaving this notice intact mandatory.
9
10# HW_HEADER_STDARG_H
11# ------------------
12# Define HAVE_STDARG_H to 1 if <stdarg.h> is available.
13AC_DEFUN([HW_HEADER_STDARG_H],
14[
15  AC_PREREQ([2.60])dnl Older releases should work if AC_CHECK_HEADERS is used.
16  AC_CHECK_HEADERS_ONCE([stdarg.h])
17])# HW_HEADER_STDARG_H
18
19# HW_HEADER_VARARGS_H
20# -------------------
21# Define HAVE_VARARGS_H to 1 if <varargs.h> is available.
22AC_DEFUN([HW_HEADER_VARARGS_H],
23[
24  AC_PREREQ([2.60])dnl Older releases should work if AC_CHECK_HEADERS is used.
25  AC_CHECK_HEADERS_ONCE([varargs.h])
26])# HW_HEADER_VARARGS_H
27
28# HW_FUNC_VA_COPY
29# ---------------
30# Set $hw_cv_func_va_copy to "yes" or "no".  Define HAVE_VA_COPY to 1 if
31# $hw_cv_func_va_copy is set to "yes".  Note that it's "unspecified whether
32# va_copy and va_end are macros or identifiers declared with external linkage."
33# (C99: 7.15.1, 1)  Therefore, the presence of va_copy(3) cannot simply "be
34# tested with #ifdef", as suggested by the Autoconf manual (5.5.1).
35AC_DEFUN([HW_FUNC_VA_COPY],
36[
37  AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H.
38  AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H.
39  AC_CACHE_CHECK([for va_copy],
40    [hw_cv_func_va_copy],
41    [AC_RUN_IFELSE(
42      [AC_LANG_PROGRAM(
43        [[#if HAVE_STDARG_H
44        #include <stdarg.h>
45        #elif HAVE_VARARGS_H
46        #include <varargs.h>
47        #endif]],
48        [[va_list ap, aq; va_copy(aq, ap);]])],
49      [hw_cv_func_va_copy=yes],
50      [hw_cv_func_va_copy=no],
51      [hw_cv_func_va_copy=no])])
52  AS_IF([test "$hw_cv_func_va_copy" = yes],
53    [AC_DEFINE([HAVE_VA_COPY], [1],
54      [Define to 1 if you have the `va_copy' function or macro.])])
55])# HW_FUNC_VA_COPY
56
57# HW_FUNC___VA_COPY
58# -----------------
59# Set $hw_cv_func___va_copy to "yes" or "no".  Define HAVE___VA_COPY to 1 if
60# $hw_cv_func___va_copy is set to "yes".
61AC_DEFUN([HW_FUNC___VA_COPY],
62[
63  AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H.
64  AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H.
65  AC_CACHE_CHECK([for __va_copy],
66    [hw_cv_func___va_copy],
67    [AC_RUN_IFELSE(
68      [AC_LANG_PROGRAM(
69        [[#if HAVE_STDARG_H
70        #include <stdarg.h>
71        #elif HAVE_VARARGS_H
72        #include <varargs.h>
73        #endif]],
74        [[va_list ap, aq; __va_copy(aq, ap);]])],
75      [hw_cv_func___va_copy=yes],
76      [hw_cv_func___va_copy=no],
77      [hw_cv_func___va_copy=no])])
78  AS_IF([test "$hw_cv_func___va_copy" = yes],
79    [AC_DEFINE([HAVE___VA_COPY], [1],
80      [Define to 1 if you have the `__va_copy' function or macro.])])
81])# HW_FUNC___VA_COPY
82
83# HW_FUNC_VSNPRINTF
84# -----------------
85# Set $hw_cv_func_vsnprintf and $hw_cv_func_vsnprintf_c99 to "yes" or "no",
86# respectively.  Define HAVE_VSNPRINTF to 1 only if $hw_cv_func_vsnprintf_c99
87# is set to "yes".  Otherwise, define vsnprintf to rpl_vsnprintf and make sure
88# the replacement function will be built.
89AC_DEFUN([HW_FUNC_VSNPRINTF],
90[
91  AC_PREREQ([2.60])dnl 2.59 should work if some AC_TYPE_* macros are replaced.
92  AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H.
93  AC_CHECK_FUNC([vsnprintf],
94    [hw_cv_func_vsnprintf=yes],
95    [hw_cv_func_vsnprintf=no])
96  AS_IF([test "$hw_cv_func_vsnprintf" = yes],
97    [AC_CACHE_CHECK([whether vsnprintf is C99 compliant],
98      [hw_cv_func_vsnprintf_c99],
99      [AC_RUN_IFELSE(
100        [AC_LANG_PROGRAM(
101          [[#if HAVE_STDARG_H
102          #include <stdarg.h>
103          #endif
104          #include <stdio.h>
105          static int testprintf(char *buf, size_t size, const char *format, ...)
106          {
107            int result;
108            va_list ap;
109            va_start(ap, format);
110            result = vsnprintf(buf, size, format, ap);
111            va_end(ap);
112            return result;
113          }]],
114          [[char buf[43];
115          if (testprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 ||
116              testprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 ||
117              buf[0] != 'T' || buf[3] != '\0')
118            return 1;]])],
119        [hw_cv_func_vsnprintf_c99=yes],
120        [hw_cv_func_vsnprintf_c99=no],
121        [hw_cv_func_vsnprintf_c99=no])])],
122    [hw_cv_func_snprintf_c99=no])
123  AS_IF([test "$hw_cv_func_vsnprintf_c99" = yes],
124    [AC_DEFINE([HAVE_VSNPRINTF], [1],
125      [Define to 1 if you have a C99 compliant `vsnprintf' function.])],
126    [AC_DEFINE([vsnprintf], [rpl_vsnprintf],
127      [Define to rpl_vsnprintf if the replacement function should be used.])
128    AC_CHECK_HEADERS([inttypes.h locale.h stddef.h stdint.h])
129    AC_CHECK_MEMBERS([struct lconv.decimal_point, struct lconv.thousands_sep],
130      [], [], [#include <locale.h>])
131    AC_TYPE_LONG_DOUBLE
132    AC_TYPE_LONG_LONG_INT
133    AC_TYPE_UNSIGNED_LONG_LONG_INT
134    AC_TYPE_SIZE_T
135    AC_TYPE_INTMAX_T
136    AC_TYPE_UINTMAX_T
137    AC_TYPE_UINTPTR_T
138    AC_CHECK_TYPES([ptrdiff_t])
139    AC_CHECK_FUNCS([localeconv])
140    _HW_FUNC_XPRINTF_REPLACE])
141])# HW_FUNC_VSNPRINTF
142
143# HW_FUNC_SNPRINTF
144# ----------------
145# Set $hw_cv_func_snprintf and $hw_cv_func_snprintf_c99 to "yes" or "no",
146# respectively.  Define HAVE_SNPRINTF to 1 only if $hw_cv_func_snprintf_c99
147# is set to "yes".  Otherwise, define snprintf to rpl_snprintf and make sure
148# the replacement function will be built.
149AC_DEFUN([HW_FUNC_SNPRINTF],
150[
151  AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our snprintf(3) calls vsnprintf(3).
152  AC_CHECK_FUNC([snprintf],
153    [hw_cv_func_snprintf=yes],
154    [hw_cv_func_snprintf=no])
155  AS_IF([test "$hw_cv_func_snprintf" = yes],
156    [AC_CACHE_CHECK([whether snprintf is C99 compliant],
157      [hw_cv_func_snprintf_c99],
158      [AC_RUN_IFELSE(
159        [AC_LANG_PROGRAM([[#include <stdio.h>]],
160          [[char buf[43];
161          if (snprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 ||
162              snprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 ||
163              buf[0] != 'T' || buf[3] != '\0')
164            return 1;]])],
165        [hw_cv_func_snprintf_c99=yes],
166        [hw_cv_func_snprintf_c99=no],
167        [hw_cv_func_snprintf_c99=no])])],
168    [hw_cv_func_snprintf_c99=no])
169  AS_IF([test "$hw_cv_func_snprintf_c99" = yes],
170    [AC_DEFINE([HAVE_SNPRINTF], [1],
171      [Define to 1 if you have a C99 compliant `snprintf' function.])],
172    [AC_DEFINE([snprintf], [rpl_snprintf],
173      [Define to rpl_snprintf if the replacement function should be used.])
174    _HW_FUNC_XPRINTF_REPLACE])
175])# HW_FUNC_SNPRINTF
176
177# HW_FUNC_VASPRINTF
178# -----------------
179# Set $hw_cv_func_vasprintf to "yes" or "no".  Define HAVE_VASPRINTF to 1 if
180# $hw_cv_func_vasprintf is set to "yes".  Otherwise, define vasprintf to
181# rpl_vasprintf and make sure the replacement function will be built.
182AC_DEFUN([HW_FUNC_VASPRINTF],
183[
184  AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our vasprintf(3) calls vsnprintf(3).
185  AC_CHECK_FUNCS([vasprintf],
186    [hw_cv_func_vasprintf=yes],
187    [hw_cv_func_vasprintf=no])
188  AS_IF([test "$hw_cv_func_vasprintf" = no],
189    [AC_DEFINE([vasprintf], [rpl_vasprintf],
190      [Define to rpl_vasprintf if the replacement function should be used.])
191    AC_CHECK_HEADERS([stdlib.h])
192    HW_FUNC_VA_COPY
193    AS_IF([test "$hw_cv_func_va_copy" = no],
194      [HW_FUNC___VA_COPY])
195    _HW_FUNC_XPRINTF_REPLACE])
196])# HW_FUNC_VASPRINTF
197
198# HW_FUNC_ASPRINTF
199# ----------------
200# Set $hw_cv_func_asprintf to "yes" or "no".  Define HAVE_ASPRINTF to 1 if
201# $hw_cv_func_asprintf is set to "yes".  Otherwise, define asprintf to
202# rpl_asprintf and make sure the replacement function will be built.
203AC_DEFUN([HW_FUNC_ASPRINTF],
204[
205  AC_REQUIRE([HW_FUNC_VASPRINTF])dnl Our asprintf(3) calls vasprintf(3).
206  AC_CHECK_FUNCS([asprintf],
207    [hw_cv_func_asprintf=yes],
208    [hw_cv_func_asprintf=no])
209  AS_IF([test "$hw_cv_func_asprintf" = no],
210    [AC_DEFINE([asprintf], [rpl_asprintf],
211      [Define to rpl_asprintf if the replacement function should be used.])
212    _HW_FUNC_XPRINTF_REPLACE])
213])# HW_FUNC_ASPRINTF
214
215# _HW_FUNC_XPRINTF_REPLACE
216# ------------------------
217# Arrange for building snprintf.c.  Must be called if one or more of the
218# functions provided by snprintf.c are needed.
219AC_DEFUN([_HW_FUNC_XPRINTF_REPLACE],
220[
221  AS_IF([test "x$_hw_cv_func_xprintf_replace_done" != xyes],
222    [AC_C_CONST
223    HW_HEADER_STDARG_H
224    AC_LIBOBJ([snprintf])
225    _hw_cv_func_xprintf_replace_done=yes])
226])# _HW_FUNC_XPRINTF_REPLACE
227
228dnl vim: set joinspaces textwidth=80:
229