Hi Francesco, hi Sylvestre,
this bug has been fixed upstream.
Please find attached a patch tho backport the fix to HDF5 1.8.11.

I should have commit access to the repo of the debian package [2] so
please let me know if you want me to update the package to include the
patch.


[1]
http://mail.lists.hdfgroup.org/pipermail/hdf-forum_lists.hdfgroup.org/2013-September/007137.html
[2] git://git.debian.org/git/pkg-grass/hdf5.git


best regards

-- 
Antonio Valentino
>From 4707d38bd9994de69dded7e3599b4efd20b13aec Mon Sep 17 00:00:00 2001
From: Antonio Valentino <antonio.valent...@tiscali.it>
Date: Fri, 27 Sep 2013 19:23:52 +0000
Subject: [PATCH] Fix long double detection

---
 src/H5detect.c | 67 ++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 20 deletions(-)

diff --git a/src/H5detect.c b/src/H5detect.c
index d6f6a3b..eedf175 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -118,10 +118,12 @@ static volatile int	nd_g = 0, na_g = 0;
 
 static void print_results(int nd, detected_t *d, int na, malign_t *m);
 static void iprint(detected_t *);
-static int byte_cmp(int, const void *, const void *);
-static int bit_cmp(int, int *, volatile void *, volatile void *);
+static int byte_cmp(int, const void *, const void *, const unsigned char *);
+static int bit_cmp(int, int *, volatile void *, volatile void *,
+    const unsigned char *);
 static void fix_order(int, int, int *, const char **);
-static int imp_bit(int, int *, volatile void *, volatile void *);
+static int imp_bit(int, int *, volatile void *, volatile void *,
+    const unsigned char *);
 static unsigned long find_bias(int, int, int *, void *);
 static void precision (detected_t*);
 static void print_header(void);
@@ -293,6 +295,8 @@ precision (detected_t *d)
 #define DETECT_F(TYPE,VAR,INFO) {					      \
    volatile TYPE _v1, _v2, _v3;						      \
    unsigned char _buf1[sizeof(TYPE)], _buf3[sizeof(TYPE)];		      \
+    unsigned char _pad_mask[sizeof(TYPE)];                                    \
+    unsigned char _byte_mask;                                                 \
    int _i, _j, _last = (-1);						      \
    char *_mesg;								      \
 									      \
@@ -300,11 +304,26 @@ precision (detected_t *d)
    INFO.varname = #VAR;							      \
    INFO.size = sizeof(TYPE);						      \
 									      \
-   /* Completely initialize temporary variables, in case the bits used in */  \
-   /* the type take less space than the number of bits used to store the type */  \
-   memset(&_v3, 0, sizeof(TYPE));                                             \
-   memset(&_v2, 0, sizeof(TYPE));                                             \
-   memset(&_v1, 0, sizeof(TYPE));                                             \
+    /* Initialize padding mask */                                             \
+    HDmemset(_pad_mask, 0, sizeof(_pad_mask));                                \
+                                                                              \
+    /* Padding bits.  Set a variable to 4.0, then flip each bit and see if    \
+     * the modified variable is equal ("==") to the original.  Build a        \
+     * padding bitmask to indicate which bits in the type are padding (i.e.   \
+     * have no effect on the value and should be ignored by subsequent        \
+     * steps).  This is necessary because padding bits can change arbitrarily \
+     * and interfere with detection of the various properties below unless we \
+     * know to ignore them. */                                                \
+    _v1 = 4.0;                                                                \
+    HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE));                        \
+    for(_i = 0; _i < (int)sizeof(TYPE); _i++)                                 \
+        for(_byte_mask = (unsigned char)1; _byte_mask; _byte_mask <<= 1) {    \
+            _buf1[_i] ^= _byte_mask;                                          \
+            HDmemcpy((void *)&_v2, (const void *)_buf1, sizeof(TYPE));        \
+            if(_v1 != _v2)                                                    \
+                _pad_mask[_i] |= _byte_mask;                                  \
+            _buf1[_i] ^= _byte_mask;                                          \
+        } /* enf for */                                                       \
 									      \
    /* Byte Order */							      \
    for(_i = 0, _v1 = 0.0, _v2 = 1.0; _i < (int)sizeof(TYPE); _i++) {	      \
@@ -313,7 +332,7 @@ precision (detected_t *d)
       _v2 /= 256.0;							      \
       memcpy(_buf1, (const void *)&_v1, sizeof(TYPE));			      \
       memcpy(_buf3, (const void *)&_v3, sizeof(TYPE));			      \
-      _j = byte_cmp(sizeof(TYPE), &_buf3, &_buf1);			      \
+      _j = byte_cmp(sizeof(TYPE), _buf3, _buf1, _pad_mask);			      \
       if(_j >= 0) {							      \
           INFO.perm[_i] = _j;						      \
           _last = _i;							      \
@@ -327,19 +346,19 @@ precision (detected_t *d)
    /* Implicit mantissa bit */						      \
    _v1 = 0.5;								      \
    _v2 = 1.0;								      \
-   INFO.imp = imp_bit (sizeof(TYPE), INFO.perm, &_v1, &_v2);		      \
+    INFO.imp = imp_bit (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask);      \
 									      \
    /* Sign bit */							      \
    _v1 = 1.0;								      \
    _v2 = -1.0;								      \
-   INFO.sign = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2);		      \
+    INFO.sign = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask);     \
 									      \
    /* Mantissa */							      \
    INFO.mpos = 0;							      \
 									      \
    _v1 = 1.0;								      \
    _v2 = 1.5;								      \
-   INFO.msize = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2);		      \
+    INFO.msize = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask);    \
    INFO.msize += 1 + (INFO.imp?0:1) - INFO.mpos;			      \
 									      \
    /* Exponent */							      \
@@ -879,7 +898,8 @@ iprint(detected_t *d)
  *
  * Purpose:	Compares two chunks of memory A and B and returns the
  *		byte index into those arrays of the first byte that
- *		differs between A and B.
+ *		differs between A and B.  Ignores differences where the
+ *              corresponding bit in pad_mask is set to 0.
  *
  * Return:	Success:	Index of differing byte.
  *
@@ -894,13 +914,16 @@ iprint(detected_t *d)
  *-------------------------------------------------------------------------
  */
 static int
-byte_cmp(int n, const void *_a, const void *_b)
+byte_cmp(int n, const void *_a, const void *_b, const unsigned char *pad_mask)
 {
     int	i;
     const unsigned char	*a = (const unsigned char *) _a;
     const unsigned char	*b = (const unsigned char *) _b;
 
-    for (i = 0; i < n; i++) if (a[i] != b[i]) return i;
+    for(i = 0; i < n; i++)
+        if((a[i] & pad_mask[i]) != (b[i] & pad_mask[i]))
+            return i;
+
     return -1;
 }
 
@@ -911,7 +934,8 @@ byte_cmp(int n, const void *_a, const void *_b)
  * Purpose:	Compares two bit vectors and returns the index for the
  *		first bit that differs between the two vectors.	 The
  *		size of the vector is NBYTES.  PERM is a mapping from
- *		actual order to little endian.
+ *		actual order to little endian.  Ignores differences where
+ *              the corresponding bit in pad_mask is set to 0.
  *
  * Return:	Success:	Index of first differing bit.
  *
@@ -926,7 +950,8 @@ byte_cmp(int n, const void *_a, const void *_b)
  *-------------------------------------------------------------------------
  */
 static int
-bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b)
+bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b,
+    const unsigned char *pad_mask)
 {
     int			i, j;
     volatile unsigned char	*a = (volatile unsigned char *) _a;
@@ -935,7 +960,8 @@ bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b)
 
     for (i = 0; i < nbytes; i++) {
 	assert(perm[i] < nbytes);
-	if ((aa = a[perm[i]]) != (bb = b[perm[i]])) {
+        if ((aa = a[perm[i]] & pad_mask[perm[i]])
+                != (bb = b[perm[i]] & pad_mask[perm[i]])) {
 	    for (j = 0; j < 8; j++, aa >>= 1, bb >>= 1) {
 		if ((aa & 1) != (bb & 1)) return i * 8 + j;
 	    }
@@ -1050,7 +1076,8 @@ fix_order(int n, int last, int *perm, const char **mesg)
  *-------------------------------------------------------------------------
  */
 static int
-imp_bit(int n, int *perm, volatile void *_a, volatile void *_b)
+imp_bit(int n, int *perm, volatile void *_a, volatile void *_b,
+    const unsigned char *pad_mask)
 {
     volatile unsigned char	*a = (volatile unsigned char *) _a;
     volatile unsigned char	*b = (volatile unsigned char *) _b;
@@ -1061,7 +1088,7 @@ imp_bit(int n, int *perm, volatile void *_a, volatile void *_b)
      * Look for the least significant bit that has changed between
      * A and B.	 This is the least significant bit of the exponent.
      */
-    changed = bit_cmp(n, perm, a, b);
+    changed = bit_cmp(n, perm, a, b, pad_mask);
     assert(changed >= 0);
 
     /*
-- 
1.8.4.rc3

_______________________________________________
Pkg-grass-devel mailing list
Pkg-grass-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

Reply via email to