1 /* bit.c -- Implementation File (module.c template V1.0) 2 Copyright (C) 1995 Free Software Foundation, Inc. 3 Contributed by James Craig Burley. 4 5 This file is part of GNU Fortran. 6 7 GNU Fortran is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GNU Fortran is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GNU Fortran; see the file COPYING. If not, write to 19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. 21 22 Related Modules: 23 None 24 25 Description: 26 Tracks arrays of booleans in useful ways. 27 28 Modifications: 29 */ 30 31 /* Include files. */ 32 33 #include "proj.h" 34 #include "bit.h" 35 #include "malloc.h" 36 37 /* Externals defined here. */ 38 39 40 /* Simple definitions and enumerations. */ 41 42 43 /* Internal typedefs. */ 44 45 46 /* Private include files. */ 47 48 49 /* Internal structure definitions. */ 50 51 52 /* Static objects accessed by functions in this module. */ 53 54 55 /* Static functions (internal). */ 56 57 58 /* Internal macros. */ 59 60 61 /* ffebit_count -- Count # of bits set a particular way 62 63 ffebit b; // the ffebit object 64 ffebitCount offset; // 0..size-1 65 bool value; // FALSE (0), TRUE (1) 66 ffebitCount range; // # bits to test 67 ffebitCount number; // # bits equal to value 68 ffebit_count(b,offset,value,range,&number); 69 70 Sets <number> to # bits at <offset> through <offset + range - 1> set to 71 <value>. If <range> is 0, <number> is set to 0. */ 72 73 void 74 ffebit_count (ffebit b, ffebitCount offset, bool value, ffebitCount range, 75 ffebitCount *number) 76 { 77 ffebitCount element; 78 ffebitCount bitno; 79 80 assert (offset + range <= b->size); 81 82 for (*number = 0; range != 0; --range, ++offset) 83 { 84 element = offset / CHAR_BIT; 85 bitno = offset % CHAR_BIT; 86 if (value 87 == ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE)) 88 ++ * number; 89 } 90 } 91 92 /* ffebit_new -- Create a new ffebit object 93 94 ffebit b; 95 ffebit_kill(b); 96 97 Destroys an ffebit object obtained via ffebit_new. */ 98 99 void 100 ffebit_kill (ffebit b) 101 { 102 malloc_kill_ks (b->pool, b, 103 offsetof (struct _ffebit_, bits) 104 + (b->size + CHAR_BIT - 1) / CHAR_BIT); 105 } 106 107 /* ffebit_new -- Create a new ffebit object 108 109 ffebit b; 110 mallocPool pool; 111 ffebitCount size; 112 b = ffebit_new(pool,size); 113 114 Allocates an ffebit object that holds the values of <size> bits in pool 115 <pool>. */ 116 117 ffebit 118 ffebit_new (mallocPool pool, ffebitCount size) 119 { 120 ffebit b; 121 122 b = malloc_new_zks (pool, "ffebit", 123 offsetof (struct _ffebit_, bits) 124 + (size + CHAR_BIT - 1) / CHAR_BIT, 125 0); 126 b->pool = pool; 127 b->size = size; 128 129 return b; 130 } 131 132 /* ffebit_set -- Set value of # of bits 133 134 ffebit b; // the ffebit object 135 ffebitCount offset; // 0..size-1 136 bool value; // FALSE (0), TRUE (1) 137 ffebitCount length; // # bits to set starting at offset (usually 1) 138 ffebit_set(b,offset,value,length); 139 140 Sets bit #s <offset> through <offset + length - 1> to <value>. */ 141 142 void 143 ffebit_set (ffebit b, ffebitCount offset, bool value, ffebitCount length) 144 { 145 ffebitCount i; 146 ffebitCount element; 147 ffebitCount bitno; 148 149 assert (offset + length <= b->size); 150 151 for (i = 0; i < length; ++i, ++offset) 152 { 153 element = offset / CHAR_BIT; 154 bitno = offset % CHAR_BIT; 155 b->bits[element] = (((unsigned char) (value ? 1 : 0)) << bitno) 156 | (b->bits[element] & ~((unsigned char) 1 << bitno)); 157 } 158 } 159 160 /* ffebit_test -- Test value of # of bits 161 162 ffebit b; // the ffebit object 163 ffebitCount offset; // 0..size-1 164 bool value; // FALSE (0), TRUE (1) 165 ffebitCount length; // # bits with same value 166 ffebit_test(b,offset,&value,&length); 167 168 Returns value of bits at <offset> through <offset + length - 1> in 169 <value>. If <offset> is already at the end of the bit array (if 170 offset == ffebit_size(b)), <length> is set to 0 and <value> is 171 undefined. */ 172 173 void 174 ffebit_test (ffebit b, ffebitCount offset, bool *value, ffebitCount *length) 175 { 176 ffebitCount i; 177 ffebitCount element; 178 ffebitCount bitno; 179 180 if (offset >= b->size) 181 { 182 assert (offset == b->size); 183 *length = 0; 184 return; 185 } 186 187 element = offset / CHAR_BIT; 188 bitno = offset % CHAR_BIT; 189 *value = (b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE; 190 *length = 1; 191 192 for (i = b->size - offset - 1, ++offset; i != 0; --i, ++offset, ++*length) 193 { 194 element = offset / CHAR_BIT; 195 bitno = offset % CHAR_BIT; 196 if (*value 197 != ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE)) 198 break; 199 } 200 } 201