summaryrefslogtreecommitdiff
path: root/infrastructure/m4/ax_check_llong_minmax.m4
blob: f3f99c5316ea7394f818dedaf457a425e8e1618d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
dnl @synopsis AX_CHECK_LLONG_MINMAX
dnl
dnl This macro will fix up LLONG_MIN and LLONG_MAX as appropriate. I'm finding
dnl it quite difficult to believe that so many hoops are necessary. The world
dnl seems to have gone quite mad.
dnl
dnl This gem is adapted from the OpenSSH configure script so here's
dnl the original copyright notice:
dnl
dnl Copyright (c) 1999-2004 Damien Miller
dnl
dnl Permission to use, copy, modify, and distribute this software for any
dnl purpose with or without fee is hereby granted, provided that the above
dnl copyright notice and this permission notice appear in all copies.
dnl
dnl @category C
dnl @author Martin Ebourne and Damien Miller
dnl @version 2005/07/07

AC_DEFUN([AX_CHECK_LLONG_MINMAX], [
  AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [[#include <limits.h>]])
  if test -z "$have_llong_max"; then
    AC_MSG_CHECKING([[for max value of long long]])
    AC_RUN_IFELSE([AC_LANG_SOURCE([[
      #include <stdio.h>
      /* Why is this so damn hard? */
      #undef __GNUC__
      #undef __USE_ISOC99
      #define __USE_ISOC99
      #include <limits.h>
      #define DATA "conftest.llminmax"
      int main(void) {
        FILE *f;
        long long i, llmin, llmax = 0;

        if((f = fopen(DATA,"w")) == NULL)
          exit(1);

        #if defined(LLONG_MIN) && defined(LLONG_MAX)
        fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n");
        llmin = LLONG_MIN;
        llmax = LLONG_MAX;
        #else
        fprintf(stderr, "Calculating LLONG_MIN and LLONG_MAX\n");
        /* This will work on one's complement and two's complement */
        for (i = 1; i > llmax; i <<= 1, i++)
          llmax = i;
        llmin = llmax + 1LL;    /* wrap */
        #endif

        /* Sanity check */
        if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax || llmax - 1 > llmax) {
          fprintf(f, "unknown unknown\n");
          exit(2);
        }

        if (fprintf(f ,"%lld %lld", llmin, llmax) < 0)
          exit(3);

        exit(0);
      }
      ]])], [
      read llong_min llong_max < conftest.llminmax
      AC_MSG_RESULT([$llong_max])
      AC_DEFINE_UNQUOTED([LLONG_MAX], [${llong_max}LL],
                         [max value of long long calculated by configure])
      AC_MSG_CHECKING([[for min value of long long]])
      AC_MSG_RESULT([$llong_min])
      AC_DEFINE_UNQUOTED([LLONG_MIN], [${llong_min}LL],
                         [min value of long long calculated by configure])
      ],
      [AC_MSG_RESULT(not found)],
      [AC_MSG_WARN([[cross compiling: not checking]])]
      )
    fi
  ])dnl