Mercurial > gnulib
changeset 39535:7178af96238a
limits-h: Provide numerical limits macros.
* lib/limits.in.h (LLONG_MIN, LLONG_MAX, ULLONG_MAX): Define also for
IRIX and for GCC.
(WORD_BIT, LONG_BIT): Define.
* m4/limits-h.m4 (gl_LIMITS_H): Set LIMITS_H to non-empty also when
<limits.h> does not define LLONG_MAX or WORD_BIT.
* tests/test-limits-h.c (TYPE_SIGNED, TYPE_WIDTH, TYPE_MINIMUM,
TYPE_MAXIMUM): New macros, from intprops.h.
Add tests for CHAR_BIT, WORD_BIT, LONG_BIT, <type>_MIN, and <type>_MAX.
* doc/posix-headers/limits.texi: Document what the 'limits-h' module
provides.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Thu, 06 Sep 2018 14:28:38 +0200 |
parents | 6f769e5e2a29 |
children | 1a32372de943 |
files | ChangeLog doc/posix-headers/limits.texi lib/limits.in.h m4/limits-h.m4 tests/test-limits-h.c |
diffstat | 5 files changed, 146 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Sep 06 11:23:53 2018 +0200 +++ b/ChangeLog Thu Sep 06 14:28:38 2018 +0200 @@ -1,3 +1,17 @@ +2018-09-06 Bruno Haible <bruno@clisp.org> + + limits-h: Provide numerical limits macros. + * lib/limits.in.h (LLONG_MIN, LLONG_MAX, ULLONG_MAX): Define also for + IRIX and for GCC. + (WORD_BIT, LONG_BIT): Define. + * m4/limits-h.m4 (gl_LIMITS_H): Set LIMITS_H to non-empty also when + <limits.h> does not define LLONG_MAX or WORD_BIT. + * tests/test-limits-h.c (TYPE_SIGNED, TYPE_WIDTH, TYPE_MINIMUM, + TYPE_MAXIMUM): New macros, from intprops.h. + Add tests for CHAR_BIT, WORD_BIT, LONG_BIT, <type>_MIN, and <type>_MAX. + * doc/posix-headers/limits.texi: Document what the 'limits-h' module + provides. + 2018-09-05 Bruno Haible <bruno@clisp.org> fcntl: Don't access nonexistent optional argument.
--- a/doc/posix-headers/limits.texi Thu Sep 06 11:23:53 2018 +0200 +++ b/doc/posix-headers/limits.texi Thu Sep 06 14:28:38 2018 +0200 @@ -3,29 +3,33 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html} -Gnulib module: gethostname +Gnulib module: limits-h or gethostname -Portability problems fixed by Gnulib: +Portability problems fixed by Gnulib module @code{limits-h}: +@itemize +@item +The macros @code{LLONG_MIN}, @code{LLONG_MAX}, @code{ULLONG_MAX} are not +defined on some platforms: +older glibc systems (e.g. Fedora 1), AIX 5.1, HP-UX 11, IRIX 6.5, OpenVMS, OSF/1 5.1 with gcc. +@item +The macros @code{WORD_BIT}, @code{LONG_BIT} are not defined on some platforms: +glibc 2.11 without @code{-D_GNU_SOURCE}, Cygwin, mingw, MSVC 14. +@item +Macros like @code{CHAR_WIDTH} are not defined on some platforms: +glibc 2.24, many others. +@end itemize + +Portability problems fixed by Gnulib module @code{gethostname}: @itemize @item The @code{HOST_NAME_MAX} macro is not defined on some platforms: Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin 1.5.x, mingw, MSVC 14, Interix 3.5, BeOS. -@item -Macros like @code{CHAR_WIDTH} are not defined on some platforms: -glibc 2.24, many others. @end itemize Portability problems not fixed by Gnulib: @itemize @item -The macros @code{LLONG_MIN}, @code{LLONG_MAX}, @code{ULLONG_MAX} are not -defined on some platforms: -AIX 5.1, HP-UX 11, IRIX 6.5, OpenVMS, OSF/1 5.1 with gcc. -@item -The macros @code{WORD_BIT}, @code{LONG_BIT} are not defined on some platforms: -glibc 2.11 without @code{-D_GNU_SOURCE}, Cygwin, mingw, MSVC 14. -@item The macro @code{SSIZE_MAX} has the wrong type, albeit with the correct value: 32-bit glibc 2.24 (on some architectures), Cygwin 2.5.2.
--- a/lib/limits.in.h Thu Sep 06 11:23:53 2018 +0200 +++ b/lib/limits.in.h Thu Sep 06 14:28:38 2018 +0200 @@ -28,15 +28,32 @@ #ifndef _@GUARD_PREFIX@_LIMITS_H #define _@GUARD_PREFIX@_LIMITS_H -/* For HP-UX 11.31. */ -#if defined LONG_LONG_MIN && !defined LLONG_MIN -# define LLONG_MIN LONG_LONG_MIN +#ifndef LLONG_MIN +# if defined LONG_LONG_MIN /* HP-UX 11.31 */ +# define LLONG_MIN LONG_LONG_MIN +# elif defined LONGLONG_MIN /* IRIX 6.5 */ +# define LLONG_MIN LONGLONG_MIN +# elif defined __GNUC__ +# define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL) +# endif #endif -#if defined LONG_LONG_MAX && !defined LLONG_MAX -# define LLONG_MAX LONG_LONG_MAX +#ifndef LLONG_MAX +# if defined LONG_LONG_MAX /* HP-UX 11.31 */ +# define LLONG_MAX LONG_LONG_MAX +# elif defined LONGLONG_MAX /* IRIX 6.5 */ +# define LLONG_MAX LONGLONG_MAX +# elif defined __GNUC__ +# define LLONG_MAX __LONG_LONG_MAX__ +# endif #endif -#if defined ULONG_LONG_MAX && !defined ULLONG_MAX -# define ULLONG_MAX ULONG_LONG_MAX +#ifndef ULLONG_MAX +# if defined ULONG_LONG_MAX /* HP-UX 11.31 */ +# define ULLONG_MAX ULONG_LONG_MAX +# elif defined ULONGLONG_MAX /* IRIX 6.5 */ +# define ULLONG_MAX ULONGLONG_MAX +# elif defined __GNUC__ +# define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL) +# endif #endif /* The number of usable bits in an unsigned or signed integer type @@ -53,6 +70,19 @@ #define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n)) #define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1)) +#ifndef WORD_BIT +/* Assume 'int' is 32 bits wide. */ +# define WORD_BIT 32 +#endif +#ifndef LONG_BIT +/* Assume 'long' is 32 or 64 bits wide. */ +# if LONG_MAX == INT_MAX +# define LONG_BIT 32 +# else +# define LONG_BIT 64 +# endif +#endif + /* Macros specified by ISO/IEC TS 18661-1:2014. */ #if (! defined ULLONG_WIDTH \
--- a/m4/limits-h.m4 Thu Sep 06 11:23:53 2018 +0200 +++ b/m4/limits-h.m4 Thu Sep 06 14:28:38 2018 +0200 @@ -11,14 +11,18 @@ [ gl_CHECK_NEXT_HEADERS([limits.h]) - AC_CACHE_CHECK([whether limits.h has ULLONG_WIDTH etc.], + AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.], [gl_cv_header_limits_width], [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ - #define __STDC_WANT_IEC_60559_BFP_EXT__ 1 - #endif - #include <limits.h> - int ullw = ULLONG_WIDTH;]])], + [AC_LANG_PROGRAM( + [[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ + #define __STDC_WANT_IEC_60559_BFP_EXT__ 1 + #endif + #include <limits.h> + long long llm = LLONG_MAX; + int wb = WORD_BIT; + int ullw = ULLONG_WIDTH; + ]])], [gl_cv_header_limits_width=yes], [gl_cv_header_limits_width=no])]) if test "$gl_cv_header_limits_width" = yes; then
--- a/tests/test-limits-h.c Thu Sep 06 11:23:53 2018 +0200 +++ b/tests/test-limits-h.c Thu Sep 06 14:28:38 2018 +0200 @@ -26,11 +26,78 @@ # pragma GCC diagnostic ignored "-Woverlength-strings" #endif -/* Macros specified by ISO/IEC TS 18661-1:2014. */ - #define verify_width(width, min, max) \ verify ((max) >> ((width) - 1 - ((min) < 0)) == 1) +/* Macros borrowed from intprops.h. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) +#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) + +/* Type width macros. */ + +int type_bits[] = + { + CHAR_BIT, + WORD_BIT, + LONG_BIT + }; +verify_width (CHAR_BIT, CHAR_MIN, CHAR_MAX); +verify_width (WORD_BIT, INT_MIN, INT_MAX); +verify_width (LONG_BIT, LONG_MIN, LONG_MAX); + +/* Numerical limit macros. */ + +char limits1[] = { CHAR_MIN, CHAR_MAX }; +verify (TYPE_MINIMUM (char) == CHAR_MIN); +verify (TYPE_MAXIMUM (char) == CHAR_MAX); + +signed char limits2[] = { SCHAR_MIN, SCHAR_MAX }; +verify (TYPE_MINIMUM (signed char) == SCHAR_MIN); +verify (TYPE_MAXIMUM (signed char) == SCHAR_MAX); + +unsigned char limits3[] = { UCHAR_MAX }; +verify (TYPE_MINIMUM (unsigned char) == 0); +verify (TYPE_MAXIMUM (unsigned char) == UCHAR_MAX); + +short limits4[] = { SHRT_MIN, SHRT_MAX }; +verify (TYPE_MINIMUM (short int) == SHRT_MIN); +verify (TYPE_MAXIMUM (short int) == SHRT_MAX); + +unsigned short limits5[] = { USHRT_MAX }; +verify (TYPE_MINIMUM (unsigned short int) == 0); +verify (TYPE_MAXIMUM (unsigned short int) == USHRT_MAX); + +int limits6[] = { INT_MIN, INT_MAX }; +verify (TYPE_MINIMUM (int) == INT_MIN); +verify (TYPE_MAXIMUM (int) == INT_MAX); + +unsigned int limits7[] = { UINT_MAX }; +verify (TYPE_MINIMUM (unsigned int) == 0); +verify (TYPE_MAXIMUM (unsigned int) == UINT_MAX); + +long limits8[] = { LONG_MIN, LONG_MAX }; +verify (TYPE_MINIMUM (long int) == LONG_MIN); +verify (TYPE_MAXIMUM (long int) == LONG_MAX); + +unsigned long limits9[] = { ULONG_MAX }; +verify (TYPE_MINIMUM (unsigned long int) == 0); +verify (TYPE_MAXIMUM (unsigned long int) == ULONG_MAX); + +long long limits10[] = { LLONG_MIN, LLONG_MAX }; +verify (TYPE_MINIMUM (long long int) == LLONG_MIN); +verify (TYPE_MAXIMUM (long long int) == LLONG_MAX); + +unsigned long long limits11[] = { ULLONG_MAX }; +verify (TYPE_MINIMUM (unsigned long long int) == 0); +verify (TYPE_MAXIMUM (unsigned long long int) == ULLONG_MAX); + +/* Macros specified by ISO/IEC TS 18661-1:2014. */ + verify_width (CHAR_WIDTH, CHAR_MIN, CHAR_MAX); verify_width (SCHAR_WIDTH, SCHAR_MIN, SCHAR_MAX); verify_width (UCHAR_WIDTH, 0, UCHAR_MAX);