1dnl AC_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] -*- sh -*-
2dnl
3dnl the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
4dnl existence of an include file <stdint.h> that defines a set of
5dnl typedefs, especially uint8_t,int32_t,uintptr_t.
6dnl Many older installations will not provide this file, but some will
7dnl have the very same definitions in <inttypes.h>. In other enviroments
8dnl we can use the inet-types in <sys/types.h> which would define the
9dnl typedefs int8_t and u_int8_t respectivly.
10dnl
11dnl This macros will create a local "_stdint.h" or the headerfile given as
12dnl an argument. In many cases that file will just have a singular
13dnl "#include <stdint.h>" or "#include <inttypes.h>" statement, while
14dnl in other environments it will provide the set of basic 'stdint's defined:
15dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
16dnl int_least32_t.. int_fast32_t.. intmax_t
17dnl which may or may not rely on the definitions of other files,
18dnl or using the AC_COMPILE_CHECK_SIZEOF macro to determine the actual
19dnl sizeof each type.
20dnl
21dnl if your header files require the stdint-types you will want to create an
22dnl installable file mylib-int.h that all your other installable header
23dnl may include. So if you have a library package named "mylib", just use
24dnl      AC_CREATE_STDINT_H(mylib-int.h)
25dnl in configure.in and go to install that very header file in Makefile.am
26dnl along with the other headers (mylib.h) - and the mylib-specific headers
27dnl can simply use "#include <mylib-int.h>" to obtain the stdint-types.
28dnl
29dnl Remember, if the system already had a valid <stdint.h>, the generated
30dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things...
31dnl
32dnl (this file is part of the http://ac-archive.sf.net/gstdint project)
33dnl @version $Id: ac_create_stdint_h.m4,v 1.2 2002/02/17 00:08:45 s_a_white Exp $
34dnl @author  Guido Draheim <guidod@gmx.de>       STATUS: used on new platforms
35
36AC_DEFUN([AC_CREATE_STDINT_H],
37[# ------ AC CREATE STDINT H -------------------------------------
38AC_MSG_CHECKING([for stdint-types....])
39ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
40if test "$ac_stdint_h" = "stdint.h" ; then
41 AC_MSG_RESULT("(are you sure you want them in ./stdint.h?)")
42elif test "$ac_stdint_h" = "inttypes.h" ; then
43 AC_MSG_RESULT("(are you sure you want them in ./inttypes.h?)")
44else
45 AC_MSG_RESULT("(putting them into $ac_stdint_h)")
46fi
47
48inttype_headers=`echo inttypes.h sys/inttypes.h sys/inttypes.h $2 \
49| sed -e 's/,/ /g'`
50
51 ac_cv_header_stdint_x="no-file"
52 ac_cv_header_stdint_o="no-file"
53 ac_cv_header_stdint_u="no-file"
54 for i in stdint.h $inttype_headers ; do
55   unset ac_cv_type_uintptr_t
56   unset ac_cv_type_uint64_t
57   _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl
58     continue,[#include <$i>])
59   AC_CHECK_TYPE(uint64_t,[and64="(uint64_t too)"],[and64=""],[#include<$i>])
60   AC_MSG_RESULT(... seen our uintptr_t in $i $and64)
61   break;
62 done
63 if test "$ac_cv_header_stdint_x" = "no-file" ; then
64 for i in stdint.h $inttype_headers ; do
65   unset ac_cv_type_uint32_t
66   unset ac_cv_type_uint64_t
67   AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl
68     continue,[#include <$i>])
69   AC_CHECK_TYPE(uint64_t,[and64="(uint64_t too)"],[and64=""],[#include<$i>])
70   AC_MSG_RESULT(... seen our uint32_t in $i $and64)
71   break;
72 done
73 if test "$ac_cv_header_stdint_o" = "no-file" ; then
74 for i in sys/types.h $inttype_headers ; do
75   unset ac_cv_type_u_int32_t
76   unset ac_cv_type_u_int64_t
77   AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl
78     continue,[#include <$i>])
79   AC_CHECK_TYPE(uint64_t,[and64="(u_int64_t too)"],[and64=""],[#include<$i>])
80   AC_MSG_RESULT(... seen our u_int32_t in $i $and64)
81   break;
82 done
83 fi
84 fi
85
86# ----------------- DONE inttypes.h checks MAYBE C basic types --------
87
88if test "$ac_cv_header_stdint_x" = "no-file" ; then
89   AC_COMPILE_CHECK_SIZEOF(char)
90   AC_COMPILE_CHECK_SIZEOF(short)
91   AC_COMPILE_CHECK_SIZEOF(int)
92   AC_COMPILE_CHECK_SIZEOF(long)
93   AC_COMPILE_CHECK_SIZEOF(void*)
94   ac_cv_header_stdint_test="yes"
95else
96   ac_cv_header_stdint_test="no"
97fi
98
99# ----------------- DONE inttypes.h checks START header -------------
100_ac_stdint_h=AS_TR_CPP(_$ac_stdint_h)
101AC_MSG_RESULT(creating $ac_stdint_h : $_ac_stdint_h)
102echo "#ifndef" $_ac_stdint_h >$ac_stdint_h
103echo "#define" $_ac_stdint_h "1" >>$ac_stdint_h
104echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint_h
105echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint_h
106if test "$GCC" = "yes" ; then
107  echo "/* generated using a gnu compiler version" `$CC --version` "*/" \
108  >>$ac_stdint_h
109else
110  echo "/* generated using $CC */" >>$ac_stdint_h
111fi
112echo "" >>$ac_stdint_h
113
114if test "$ac_cv_header_stdint_x" != "no-file" ; then
115   ac_cv_header_stdint="$ac_cv_header_stdint_x"
116elif  test "$ac_cv_header_stdint_o" != "no-file" ; then
117   ac_cv_header_stdint="$ac_cv_header_stdint_o"
118elif  test "$ac_cv_header_stdint_u" != "no-file" ; then
119   ac_cv_header_stdint="$ac_cv_header_stdint_u"
120else
121   ac_cv_header_stdint="stddef.h"
122fi
123
124# ----------------- See if int_least and int_fast types are present
125unset ac_cv_type_int_least32_t
126unset ac_cv_type_int_fast32_t
127AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
128AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
129
130if test "$ac_cv_header_stdint" != "stddef.h" ; then
131if test "$ac_cv_header_stdint" != "stdint.h" ; then
132AC_MSG_RESULT(..adding include stddef.h)
133   echo "#include <stddef.h>" >>$ac_stdint_h
134fi ; fi
135AC_MSG_RESULT(..adding include $ac_cv_header_stdint)
136   echo "#include <$ac_cv_header_stdint>" >>$ac_stdint_h
137echo "" >>$ac_stdint_h
138
139# ----------------- DONE header START basic int types -------------
140if test "$ac_cv_header_stdint_x" = "no-file" ; then
141   AC_MSG_RESULT(... need to look at C basic types)
142dnl ac_cv_header_stdint_test="yes" # moved up before creating the file
143else
144   AC_MSG_RESULT(... seen good stdint.h inttypes)
145dnl ac_cv_header_stdint_test="no"  # moved up before creating the file
146fi
147
148if test "$ac_cv_header_stdint_u" != "no-file" ; then
149   AC_MSG_RESULT(... seen bsd/sysv typedefs)
150   cat >>$ac_stdint_h <<EOF
151
152/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
153typedef u_int8_t uint8_t;
154typedef u_int16_t uint16_t;
155typedef u_int32_t uint32_t;
156EOF
157    cat >>$ac_stdint_h <<EOF
158
159/* glibc compatibility */
160#ifndef __int8_t_defined
161#define __int8_t_defined
162#endif
163EOF
164fi
165
166ac_cv_sizeof_x="$ac_cv_sizeof_char:$ac_cv_sizeof_short"
167ac_cv_sizeof_X="$ac_cv_sizeof_x:$ac_cv_sizeof_int"
168ac_cv_sizeof_X="$ac_cv_sizeof_X:$ac_cv_sizeof_voidp:$ac_cv_sizeof_long"
169if test "$ac_cv_header_stdint" = "stddef.h" ; then
170#   we must guess all the basic types. Apart from byte-adressable system,
171# there a few 32-bit-only dsp-systems. nibble-addressable systems are way off.
172    cat >>$ac_stdint_h <<EOF
173/* ------------ BITSPECIFIC INTTYPES SECTION --------------- */
174EOF
175    t="typedefs for a"
176    case "$ac_cv_sizeof_X" in
177     1:2:2:2:4) AC_MSG_RESULT(..adding $t normal 16-bit system)
178                cat >>$ac_stdint_h <<EOF
179/*              a normal 16-bit system                       */
180typedef unsigned char   uint8_t;
181typedef unsigned short  uint16_t;
182typedef unsigned long   uint32_t;
183#ifndef __int8_t_defined
184#define __int8_t_defined
185typedef          char    int8_t;
186typedef          short   int16_t;
187typedef          long    int32_t;
188#endif
189EOF
190;;
191     1:2:2:4:4) AC_MSG_RESULT(..adding $t 32-bit system derived from a 16-bit)
192                cat >>$ac_stdint_h <<EOF
193/*              a 32-bit system derived from a 16-bit        */
194typedef unsigned char   uint8_t;
195typedef unsigned short  uint16_t;
196typedef unsigned int    uint32_t;
197#ifndef __int8_t_defined
198#define __int8_t_defined
199typedef          char    int8_t;
200typedef          short   int16_t;
201typedef          int     int32_t;
202#endif
203EOF
204;;
205     1:2:4:4:4) AC_MSG_RESULT(..adding $t normal 32-bit system)
206                cat >>$ac_stdint_h <<EOF
207/*              a normal 32-bit system                       */
208typedef unsigned char   uint8_t;
209typedef unsigned short  uint16_t;
210typedef unsigned int    uint32_t;
211#ifndef __int8_t_defined
212#define __int8_t_defined
213typedef          char    int8_t;
214typedef          short   int16_t;
215typedef          int     int32_t;
216#endif
217EOF
218;;
219     1:2:4:4:8) AC_MSG_RESULT(..adding $t 32-bit system prepared for 64-bit)
220                cat >>$ac_stdint_h <<EOF
221
222/*              a 32-bit system prepared for 64-bit          */
223typedef unsigned char   uint8_t;
224typedef unsigned short  uint16_t;
225typedef unsigned int    uint32_t;
226#ifndef __int8_t_defined
227#define __int8_t_defined
228typedef          char    int8_t;
229typedef          short   int16_t;
230typedef          int     int32_t;
231#endif
232EOF
233;;
234     1:2:4:8:8) AC_MSG_RESULT(..adding $t normal 64-bit system)
235                cat >>$ac_stdint_h <<EOF
236
237/*              a normal 64-bit system                       */
238typedef unsigned char   uint8_t;
239typedef unsigned short  uint16_t;
240typedef unsigned int    uint32_t;
241#ifndef __int8_t_defined
242#define __int8_t_defined
243typedef          char    int8_t;
244typedef          short   int16_t;
245typedef          int     int32_t;
246#endif
247EOF
248;;
249     1:2:4:8:4) AC_MSG_RESULT(..adding $t 64-bit system derived from a 32-bit)
250                cat >>$ac_stdint_h <<EOF
251
252/*              a 64-bit system derived from a 32-bit system */
253typedef unsigned char   uint8_t;
254typedef unsigned short  uint16_t;
255typedef unsigned int    uint32_t;
256#ifndef __int8_t_defined
257#define __int8_t_defined
258typedef          char    int8_t;
259typedef          short   int16_t;
260typedef          int     int32_t;
261#endif
262EOF
263;;
264  *)
265    AC_MSG_ERROR([ $ac_cv_sizeof_X dnl
266 what is that a system? contact the author, quick! http://ac-archive.sf.net])
267    exit 1
268;;
269   esac
270fi
271
272# ------------- DONE basic int types START int64_t types ------------
273if test "$ac_cv_type_uint64_t" = "yes"
274then AC_MSG_RESULT(... seen good uint64_t)
275     cat >>$ac_stdint_h <<EOF
276
277/* system headers have good uint64_t */
278#ifndef _HAVE_UINT64_T
279#define _HAVE_UINT64_T
280#endif
281EOF
282
283elif test "$ac_cv_type_u_int64_t" = "yes"
284then AC_MSG_RESULT(..adding typedef u_int64_t uint64_t)
285     cat >>$ac_stdint_h <<EOF
286
287/* system headers have an u_int64_t */
288#ifndef _HAVE_UINT64_T
289#define _HAVE_UINT64_T
290typedef u_int64_t uint64_t;
291#endif
292EOF
293else AC_MSG_RESULT(..adding generic uint64_t runtime checks)
294     cat >>$ac_stdint_h <<EOF
295
296/* -------------------- 64 BIT GENERIC SECTION -------------------- */
297/* here are some common heuristics using compiler runtime specifics */
298#if defined __STDC_VERSION__ && defined __STDC_VERSION__ > 199901L
299
300#ifndef _HAVE_UINT64_T
301#define _HAVE_UINT64_T
302typedef long long int64_t;
303typedef unsigned long long uint64_t;
304#endif
305
306#elif !defined __STRICT_ANSI__
307#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
308
309#ifndef _HAVE_UINT64_T
310#define _HAVE_UINT64_T
311typedef __int64 int64_t;
312typedef unsigned __int64 uint64_t;
313#endif
314
315#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
316dnl /* note: all ELF-systems seem to have loff-support which needs 64-bit */
317
318#if !defined _NO_LONGLONG
319#ifndef _HAVE_UINT64_T
320#define _HAVE_UINT64_T
321typedef long long int64_t;
322typedef unsigned long long uint64_t;
323#endif
324#endif
325
326#elif defined __alpha || (defined __mips && defined _ABIN32)
327
328#if !defined _NO_LONGLONG
329#ifndef _HAVE_UINT64_T
330#define _HAVE_UINT64_T
331typedef long int64_t;
332typedef unsigned long uint64_t;
333#endif
334#endif
335  /* compiler/cpu type ... or just ISO C99 */
336#endif
337#endif
338EOF
339
340# plus a default 64-bit for systems that are likely to be 64-bit ready
341  case "$ac_cv_sizeof_x:$ac_cv_sizeof_voidp:$ac_cv_sizeof_long" in
342    1:2:8:8) AC_MSG_RESULT(..adding uint64_t default, normal 64-bit system)
343cat >>$ac_stdint_h <<EOF
344/* DEFAULT: */
345/* seen normal 64-bit system, CC has sizeof(long and void*) == 8 bytes */
346#ifndef _HAVE_UINT64_T
347#define _HAVE_UINT64_T
348typedef long int64_t;
349typedef unsigned long uint64_t;
350#endif
351EOF
352;;
353    1:2:4:8) AC_MSG_RESULT(..adding uint64_t default, typedef to long)
354cat >>$ac_stdint_h <<EOF
355/* DEFAULT: */
356/* seen 32-bit system prepared for 64-bit, CC has sizeof(long) == 8 bytes */
357#ifndef _HAVE_UINT64_T
358#define _HAVE_UINT64_T
359typedef long int64_t;
360typedef unsigned long uint64_t;
361#endif
362EOF
363;;
364    1:2:8:4) AC_MSG_RESULT(..adding uint64_t default, typedef long long)
365cat >>$ac_stdint_h <<EOF
366/* DEFAULT: */
367/* seen 64-bit derived from a 32-bit, CC has sizeof(long) == 4 bytes */
368#ifndef _HAVE_UINT64_T
369#define _HAVE_UINT64_T
370typedef long long int64_t;
371typedef unsigned long long uint64_t;
372#endif
373EOF
374;;
375   *)
376cat >>$ac_stdint_h <<EOF
377/* NOTE: */
378/* the configure-checks for the basic types did not make us believe */
379/* that we could add a fallback to a 'long long' typedef to int64_t */
380EOF
381  esac
382fi
383
384# ------------- DONE int64_t types START intptr types ------------
385if test "$ac_cv_header_stdint_x" = "no-file" ; then
386  cat >>$ac_stdint_h <<EOF
387
388/* -------------------------- INPTR SECTION --------------------------- */
389EOF
390  case "$ac_cv_sizeof_x:$ac_cv_sizeof_voidp" in
391  1:2:2)
392    a="int16_t" ; cat >>$ac_stdint_h <<EOF
393/* we tested sizeof(void*) to be of 2 chars, hence we declare it 16-bit */
394
395typedef uint16_t uintptr_t;
396typedef  int16_t  intptr_t;
397EOF
398;;
399  1:2:4)
400    a="int32_t" ; cat >>$ac_stdint_h <<EOF
401/* we tested sizeof(void*) to be of 4 chars, hence we declare it 32-bit */
402
403typedef uint32_t uintptr_t;
404typedef  int32_t  intptr_t;
405EOF
406;;
407  1:2:8)
408    a="int64_t" ; cat >>$ac_stdint_h <<EOF
409/* we tested sizeof(void*) to be of 8 chars, hence we declare it 64-bit */
410
411typedef uint64_t uintptr_t;
412typedef  int64_t  intptr_t;
413EOF
414;;
415  *)
416    a="long" ; cat >>$ac_stdint_h <<EOF
417/* we tested sizeof(void*) but got no guess, hence we declare it as if long */
418
419typedef unsigned long uintptr_t;
420typedef          long  intptr_t;
421EOF
422;;
423  esac
424AC_MSG_RESULT(..adding typedef $a intptr_t)
425fi
426
427# ------------- DONE intptr types START int_least types ------------
428if test "$ac_cv_type_int_least32_t" = "no"; then
429AC_MSG_RESULT(..adding generic int_least-types)
430     cat >>$ac_stdint_h <<EOF
431
432/* --------------GENERIC INT_LEAST ------------------ */
433
434typedef  int8_t    int_least8_t;
435typedef  int16_t   int_least16_t;
436typedef  int32_t   int_least32_t;
437#ifdef _HAVE_INT64_T
438typedef  int64_t   int_least64_t;
439#endif
440
441typedef uint8_t   uint_least8_t;
442typedef uint16_t  uint_least16_t;
443typedef uint32_t  uint_least32_t;
444#ifdef _HAVE_INT64_T
445typedef uint64_t  uint_least64_t;
446#endif
447EOF
448fi
449
450# ------------- DONE intptr types START int_least types ------------
451if test "$ac_cv_type_int_fast32_t" = "no"; then
452AC_MSG_RESULT(..adding generic int_fast-types)
453     cat >>$ac_stdint_h <<EOF
454
455/* --------------GENERIC INT_FAST ------------------ */
456
457typedef  int8_t    int_fast8_t;
458typedef  int32_t   int_fast16_t;
459typedef  int32_t   int_fast32_t;
460#ifdef _HAVE_INT64_T
461typedef  int64_t   int_fast64_t;
462#endif
463
464typedef uint8_t   uint_fast8_t;
465typedef uint32_t  uint_fast16_t;
466typedef uint32_t  uint_fast32_t;
467#ifdef _HAVE_INT64_T
468typedef uint64_t  uint_fast64_t;
469#endif
470EOF
471fi
472
473if test "$ac_cv_header_stdint_x" = "no-file" ; then
474     cat >>$ac_stdint_h <<EOF
475
476#ifdef _HAVE_INT64_T
477typedef int64_t        intmax_t;
478typedef uint64_t      uintmax_t;
479#else
480typedef long int       intmax_t;
481typedef unsigned long uintmax_t;
482#endif
483EOF
484fi
485
486AC_MSG_RESULT(... DONE $ac_stdint_h)
487   cat >>$ac_stdint_h <<EOF
488
489  /* once */
490#endif
491#endif
492EOF
493])
494
495dnl quote from SunOS-5.8 sys/inttypes.h:
496dnl Use at your own risk.  As of February 1996, the committee is squarely
497dnl behind the fixed sized types; the "least" and "fast" types are still being
498dnl discussed.  The probability that the "fast" types may be removed before
499dnl the standard is finalized is high enough that they are not currently
500dnl implemented.
501
502