Martin Sebor wrote:
Mike Duigou wrote:
A patch to add apr_uint8_t and apr_int8_t to apr.h is attached. It
also ensures that CHAR_BIT is 8 bits (it normally is) and that
short_value and long_value are defined.
I normally just lurk here but this issue has caught my attention
as I recently implemented the same thing in C++ and gained some
insight into the gotchas behind these seemingly trivial typedefs.
I hope you'll find it helpful.
First, char may be an unsigned type so apr_int8_t should be an
alias for signed char in that case.
Very good point. I've updated my patch to correct this.
Second, if APR headers are intended to be used in C++ programs
(I don't know if that's possible or desirable), it would be a
good idea to define apr_int8_t to the same type as int8_t in
<stdint.h> and not simply to signed char unconditionally. Doing
otherwise will prevent the two from being interchangeable and
lead to compilation or linker errors in programs that mix and
match them.
I've also updated the patch to use int8_t or uint8_t from <stdint.h>
rather than "signed char" and "unsigned char" when stdint.h is available.
Thanks for the feedback! The updated patch is enclosed.
Mike
Index: include/apr.h.in
===================================================================
--- include/apr.h.in (revision 418077)
+++ include/apr.h.in (working copy)
@@ -254,8 +254,11 @@
/* Typedefs that APR needs. */
-typedef unsigned char apr_byte_t;
+typedef @unsigned_byte_value@ apr_byte_t;
+typedef @signed_byte_value@ apr_int8_t;
+typedef @unsigned_byte_value@ apr_uint8_t;
+
typedef @short_value@ apr_int16_t;
typedef unsigned @short_value@ apr_uint16_t;
Index: configure.in
===================================================================
--- configure.in (revision 418077)
+++ configure.in (working copy)
@@ -1098,6 +1098,8 @@
fi
dnl ----------------------------- Checks for standard typedefs
+echo "${nl}Checking for Standard Typedefs..."
+
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
@@ -1119,18 +1121,64 @@
fi
dnl Checks for integer size
+
+dnl Check if stdint.h typedefs are available.
+AC_DEFUN([APR_CHECK_STDINT],
+[AC_CACHE_CHECK([for stdint.h], ac_cv_define_stdint_types,
+[AC_EGREP_CPP(STDINT_AVAILABLE,
+[#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+STDINT_AVAILABLE], ac_cv_define_stdint_types=yes, ac_cv_define_stdint_types=no)
+])
+])
+
+dnl Check that CHAR_BIT is an octect (8-bits) in length.
+AC_DEFUN([AC_C_CHAR_BIT_OCTET],
+[AC_CACHE_CHECK([if CHAR_BIT is octet on this platform], ac_cv_define_char_bit_octet,
+[AC_EGREP_CPP(octet,
+[#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if CHAR_BIT == 8
+octet
+#endif], ac_cv_define_char_bit_octet=yes, ac_cv_define_char_bit_octet=no)
+])
+])
+
+APR_CHECK_STDINT
+AC_C_CHAR_BIT_OCTET
AC_CHECK_SIZEOF(char, 1)
AC_CHECK_SIZEOF(int, 4)
AC_CHECK_SIZEOF(long, 4)
AC_CHECK_SIZEOF(short, 2)
AC_CHECK_SIZEOF(long long, 8)
+if test "$ac_cv_define_stdint_types" = "yes"; then
+ signed_byte_value=int8_t
+ unsigned_byte_value=uint8_t
+elif test "$ac_cv_define_char_bit_octet" = "yes"; then
+ signed_byte_value="signed char"
+ unsigned_byte_value="unsigned char"
+else
+ # no known value for 8 bit type
+ AC_ERROR([could not detect a 8-bit integer type])
+fi
+
if test "$ac_cv_sizeof_short" = "2"; then
short_value=short
+else
+ # no known value for 16 bit type
+ AC_ERROR([could not detect a 16-bit integer type])
fi
+
if test "$ac_cv_sizeof_int" = "4"; then
int_value=int
+else
+ # no known value for 32 bit type
+ AC_ERROR([could not detect a 32-bit integer type])
fi
+
# Now we need to find what apr_int64_t (sizeof == 8) will be.
# The first match is our preference.
if test "$ac_cv_sizeof_int" = "8"; then
@@ -1360,6 +1408,8 @@
esac
AC_SUBST(voidp_size)
+AC_SUBST(signed_byte_value)
+AC_SUBST(unsigned_byte_value)
AC_SUBST(short_value)
AC_SUBST(int_value)
AC_SUBST(long_value)