From dfb2d19fe547d6149e33a00ff35de2cd6007da3c Mon Sep 17 00:00:00 2001
From: unknown <mronstrom@mysql.com>
Date: Thu, 5 May 2005 15:22:47 +0200
Subject: [PATCH] After test on Mac OS X fixes

---
 sql/bitvector.cc | 48 +++++++++++++++++++++++++++++++++++++-----------
 sql/bitvector.h  | 24 +++++++++++++++++-------
 2 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/sql/bitvector.cc b/sql/bitvector.cc
index 219d34c5920..861cff2c9bb 100644
--- a/sql/bitvector.cc
+++ b/sql/bitvector.cc
@@ -29,7 +29,8 @@ void bitvector::create_last_word_mask()
    * bits clear. The bits within each byte is stored in big-endian order.
    */
   unsigned char const mask= (~((1 << used) - 1)) & 255;
-  last_word_ptr= (uint32*)(m_data+((bytes()-1U)>>2));
+  unsigned int byte_no= ((bytes()-1)) & ~3U;
+  last_word_ptr= (uint32*)&m_data[byte_no];
 
   /*
     The first bytes are to be set to zero since they represent real  bits
@@ -65,6 +66,7 @@ void bitvector::create_last_word_mask()
 int bitvector::init(size_t size)
 {
   DBUG_ASSERT(size < MYSQL_NO_BIT_FOUND);
+  DBUG_ASSERT(size > 0);
   m_size= size;
   m_data= (uchar*)my_malloc(byte_size_word_aligned(size), MYF(0));
   if (m_data)
@@ -289,32 +291,56 @@ bool do_test(uint bitsize)
   bv = new bitvector;
   bv->init(bitsize);
   if (test_set_get_clear_bit(bv,bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_flip_bit(bv,bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_operators(bv,bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_get_all_bits(bv, bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_compare_operators(bv,bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_count_bits_set(bv,bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_get_first_bit(bv,bitsize))
-    return TRUE;
+    goto error;
+  bv->clear_all();
   if (test_get_next_bit(bv,bitsize))
-    return TRUE;
-  printf("OK");
+    goto error;
+  delete bv;
   return FALSE;
+error:
+  delete bv;
+  printf("\n");
+  return TRUE;
 }
 
 int main()
 {
   int i;
-  for (i= 0; i < 4096; i++)
+  for (i= 1; i < 4096; i++)
     if (do_test(i))
       return -1;
+  printf("OK\n");
   return 0;
 }
+/*
+Compile by using the below on a compiled clone
 
+g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../regex -I.  -I../include
+-g -fno-omit-frame-pointer -fno-common -felide-constructors -fno-exceptions
+-fno-rtti   -fno-implicit-templates -fno-exceptions -fno-rtti
+-DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL -DHAVE_DARWIN_THREADS
+-D_P1003_1B_VISIBLE -DTEST_BITVECTOR -DSIGNAL_WITH_VIO_CLOSE
+-DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT  -o bitvector.o
+-c bitvector.cc
+g++ -o bitvector bitvector.o -L../mysys -lmysys -L../dbug -L../strings
+-lmystrings -ldbug
+*/
 #endif
diff --git a/sql/bitvector.h b/sql/bitvector.h
index bb7a1d6c3b9..2a33e1858f1 100644
--- a/sql/bitvector.h
+++ b/sql/bitvector.h
@@ -177,8 +177,8 @@ class bitvector
 
   bool get_all_bits_clear()
   {
-    uint32 *data_ptr= (uint32*)&m_data[0];
-    if (*last_word_ptr ^ last_word_mask)
+    uint32 *data_ptr= (uint32*)m_data;
+    if (*last_word_ptr != last_word_mask)
       return FALSE;
     for (; data_ptr < last_word_ptr; data_ptr++)
       if (*data_ptr)
@@ -204,7 +204,8 @@ class bitvector
   /* Set a bit to a value */
   void set_bit(size_t pos)
   {
-    *(uchar*)(m_data + (pos >> 3)) |= (uchar)(1 << (pos & 0x7U));
+    DBUG_ASSERT(pos < m_size);
+    m_data[pos>>3]|= (uchar)(1 << (pos & 0x7U));
   }
 
   /* Reset (clear) all bits in the vector */
@@ -217,18 +218,27 @@ class bitvector
   /* Reset one bit in the vector */
   void clear_bit(size_t pos)
   {
-    *(u_char*)(m_data + (pos >> 3)) &= (u_char)(~(1 << (pos & 0x7U)));
+    DBUG_ASSERT(pos < m_size);
+    m_data[pos>>3]&= ~(uchar)(1 << (pos & 0x7U));
   }
 
   void flip_bit(size_t pos)
   {
-    *(uchar*)(m_data + (pos >> 3)) ^= (uchar)(1 << (pos & 0x7U));
+    DBUG_ASSERT(pos < m_size);
+    m_data[pos>>3]^= (uchar)(1 << (pos & 0x7U));
   }
 
   bool get_bit(size_t pos) const
   {
-    return (bool)(*(uchar*)(m_data + (pos >> 3))) &
-                 (uchar)(1 << (pos & 0x7U));
+    DBUG_ASSERT(pos < m_size);
+    /*
+      !! provides the most effective implementation of conversion to
+      bool
+    */
+    uchar *byte_word= m_data + (pos >> 3);
+    uchar mask= 1 << (pos & 0x7U);
+    bool ret_value= !!(*byte_word & mask);
+    return ret_value;
   };
 
   bool operator==(bitvector const& rhs) const
-- 
2.30.9