changeset 4861:1d3dc83fb7a5

Macro for determining PTRDIFF_MAX.
author Bruno Haible <bruno@clisp.org>
date Tue, 11 Nov 2003 11:57:04 +0000
parents 4203fbdbf596
children 1f6c3678919c
files m4/ptrdiff_max.m4
diffstat 1 files changed, 67 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/m4/ptrdiff_max.m4
@@ -0,0 +1,67 @@
+# ptrdiff_max.m4 serial 1
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([gl_PTRDIFF_MAX],
+[
+  AC_CHECK_TYPE([ptrdiff_t], ,
+    [AC_DEFINE([ptrdiff_t], [long],
+       [Define as the type of the result of subtracting two pointers, if the system doesn't define it.])
+    ])
+  AC_CHECK_HEADERS_ONCE(stdint.h)
+  dnl First test whether the system already has PTRDIFF_MAX.
+  AC_MSG_CHECKING([for PTRDIFF_MAX])
+  result=
+  AC_EGREP_CPP([Found it], [
+#include <limits.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef PTRDIFF_MAX
+Found it
+#endif
+], result=yes)
+  if test -z "$result"; then
+    dnl Define it ourselves. Here we assume that the type 'ptrdiff_t' is not
+    dnl wider than the type 'long'.
+    dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr',
+    dnl which is guaranteed to work from LONG_MIN to LONG_MAX.
+    _AC_COMPUTE_INT([STYPE_MAXIMUM (ptrdiff_t)], res, [
+#include <stddef.h>
+#include <limits.h>
+#define STYPE_MINIMUM(t) (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))
+#define STYPE_MAXIMUM(t) ((t) (~ (t) 0 - STYPE_MINIMUM (t)))
+], result=?)
+    _AC_COMPUTE_INT([sizeof (ptrdiff_t) <= sizeof (int)], fits_in_int,
+      [#include <stddef.h>], result=?)
+    if test "$fits_in_int" = 1; then
+      dnl Even though PTRDIFF_MAX fits in an int, it must be of type
+      dnl 'long' if the type 'ptrdiff_t' is the same as 'long'.
+      AC_TRY_COMPILE([#include <stddef.h>
+        extern ptrdiff_t foo;
+        extern long foo;
+        ], [], fits_in_int=0)
+    fi
+    if test -z "$result"; then
+      if test "$fits_in_int" = 1; then
+        result="$res"
+      else
+        result="$res"L
+      fi
+    else
+      dnl Shouldn't happen, but who knows...
+      result='((ptrdiff_t)(~(ptrdiff_t)0-(~(ptrdiff_t)0<<(sizeof(ptrdiff_t)*CHAR_BIT-1))))'
+    fi
+  fi
+  AC_MSG_RESULT([$result])
+  if test "$result" != yes; then
+    AC_DEFINE_UNQUOTED([PTRDIFF_MAX], [$result],
+      [Define as the maximum value of type 'ptrdiff_t', if the system doesn't define it.])
+  fi
+])