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