1*4491bd90Sbluhm /* $OpenBSD: bitstring.h,v 1.7 2024/08/26 11:52:54 bluhm Exp $ */ 2501cd988Smillert /* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */ 3df930be7Sderaadt 4df930be7Sderaadt /* 5501cd988Smillert * Copyright (c) 1989, 1993 6501cd988Smillert * The Regents of the University of California. All rights reserved. 7df930be7Sderaadt * 8df930be7Sderaadt * This code is derived from software contributed to Berkeley by 9df930be7Sderaadt * Paul Vixie. 10df930be7Sderaadt * 11501cd988Smillert * Redistribution and use in source and binary forms, with or without 12501cd988Smillert * modification, are permitted provided that the following conditions 13501cd988Smillert * are met: 14501cd988Smillert * 1. Redistributions of source code must retain the above copyright 15501cd988Smillert * notice, this list of conditions and the following disclaimer. 16501cd988Smillert * 2. Redistributions in binary form must reproduce the above copyright 17501cd988Smillert * notice, this list of conditions and the following disclaimer in the 18501cd988Smillert * documentation and/or other materials provided with the distribution. 19e33d3bd3Smillert * 3. Neither the name of the University nor the names of its contributors 20501cd988Smillert * may be used to endorse or promote products derived from this software 21501cd988Smillert * without specific prior written permission. 22df930be7Sderaadt * 23501cd988Smillert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24501cd988Smillert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25501cd988Smillert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26501cd988Smillert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27501cd988Smillert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28501cd988Smillert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29501cd988Smillert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30501cd988Smillert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31501cd988Smillert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32501cd988Smillert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33501cd988Smillert * SUCH DAMAGE. 34501cd988Smillert * 35501cd988Smillert * @(#)bitstring.h 8.1 (Berkeley) 7/19/93 36df930be7Sderaadt */ 37df930be7Sderaadt 38df930be7Sderaadt #ifndef _BITSTRING_H_ 39df930be7Sderaadt #define _BITSTRING_H_ 40df930be7Sderaadt 41df930be7Sderaadt /* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91 42df930be7Sderaadt * bitstr_size changed gratuitously, but shorter 43df930be7Sderaadt * bit_alloc spelling error fixed 44df930be7Sderaadt * the following were efficient, but didn't work, they've been made to 45df930be7Sderaadt * work, but are no longer as efficient :-) 46df930be7Sderaadt * bit_nclear, bit_nset, bit_ffc, bit_ffs 47df930be7Sderaadt */ 48df930be7Sderaadt typedef unsigned char bitstr_t; 49df930be7Sderaadt 50df930be7Sderaadt /* internal macros */ 51df930be7Sderaadt /* byte of the bitstring bit is in */ 52df930be7Sderaadt #define _bit_byte(bit) \ 53df930be7Sderaadt ((bit) >> 3) 54df930be7Sderaadt 55df930be7Sderaadt /* mask for the bit within its byte */ 56df930be7Sderaadt #define _bit_mask(bit) \ 57df930be7Sderaadt (1 << ((bit)&0x7)) 58df930be7Sderaadt 59df930be7Sderaadt /* external macros */ 60df930be7Sderaadt /* bytes in a bitstring of nbits bits */ 61df930be7Sderaadt #define bitstr_size(nbits) \ 62df930be7Sderaadt (((nbits) + 7) >> 3) 63df930be7Sderaadt 64df930be7Sderaadt /* allocate a bitstring */ 65df930be7Sderaadt #define bit_alloc(nbits) \ 66df930be7Sderaadt (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t)) 67df930be7Sderaadt 68df930be7Sderaadt /* allocate a bitstring on the stack */ 69df930be7Sderaadt #define bit_decl(name, nbits) \ 70501cd988Smillert ((name)[bitstr_size(nbits)]) 71df930be7Sderaadt 72df930be7Sderaadt /* is bit N of bitstring name set? */ 73*4491bd90Sbluhm #define bit_test(name, bit) ({ \ 74*4491bd90Sbluhm register int __tbit = (bit); \ 75*4491bd90Sbluhm ((name)[_bit_byte(__tbit)] & _bit_mask(__tbit)); \ 76*4491bd90Sbluhm }) 77df930be7Sderaadt 78df930be7Sderaadt /* set bit N of bitstring name */ 79*4491bd90Sbluhm #define bit_set(name, bit) do { \ 80*4491bd90Sbluhm register int __sbit = (bit); \ 81*4491bd90Sbluhm ((name)[_bit_byte(__sbit)] |= _bit_mask(__sbit)); \ 82*4491bd90Sbluhm } while(0) 83df930be7Sderaadt 84df930be7Sderaadt /* clear bit N of bitstring name */ 85*4491bd90Sbluhm #define bit_clear(name, bit) do { \ 86*4491bd90Sbluhm register int __cbit = (bit); \ 87*4491bd90Sbluhm ((name)[_bit_byte(__cbit)] &= ~_bit_mask(__cbit)); \ 88*4491bd90Sbluhm } while(0) 89df930be7Sderaadt 90df930be7Sderaadt /* clear bits start ... stop in bitstring */ 913545baa8Sderaadt #define bit_nclear(name, start, stop) do { \ 922981a53aSguenther register bitstr_t *__name = (name); \ 932981a53aSguenther register int __start = (start), __stop = (stop); \ 942981a53aSguenther while (__start <= __stop) { \ 952981a53aSguenther bit_clear(__name, __start); \ 962981a53aSguenther __start++; \ 97df930be7Sderaadt } \ 983545baa8Sderaadt } while(0) 99df930be7Sderaadt 100df930be7Sderaadt /* set bits start ... stop in bitstring */ 1013545baa8Sderaadt #define bit_nset(name, start, stop) do { \ 1022981a53aSguenther register bitstr_t *__name = (name); \ 1032981a53aSguenther register int __start = (start), __stop = (stop); \ 1042981a53aSguenther while (__start <= __stop) { \ 1052981a53aSguenther bit_set(__name, __start); \ 1062981a53aSguenther __start++; \ 107df930be7Sderaadt } \ 1083545baa8Sderaadt } while(0) 109df930be7Sderaadt 110df930be7Sderaadt /* find first bit clear in name */ 1113545baa8Sderaadt #define bit_ffc(name, nbits, value) do { \ 1122981a53aSguenther register bitstr_t *__name = (name); \ 1132981a53aSguenther register int __bit, __nbits = (nbits), __value = -1; \ 1142981a53aSguenther for (__bit = 0; __bit < __nbits; ++__bit) \ 1152981a53aSguenther if (!bit_test(__name, __bit)) { \ 1162981a53aSguenther __value = __bit; \ 117df930be7Sderaadt break; \ 118df930be7Sderaadt } \ 1192981a53aSguenther *(value) = __value; \ 1203545baa8Sderaadt } while(0) 121df930be7Sderaadt 122df930be7Sderaadt /* find first bit set in name */ 1233545baa8Sderaadt #define bit_ffs(name, nbits, value) do { \ 1242981a53aSguenther register bitstr_t *__name = (name); \ 1252981a53aSguenther register int __bit, __nbits = (nbits), __value = -1; \ 1262981a53aSguenther for (__bit = 0; __bit < __nbits; ++__bit) \ 1272981a53aSguenther if (bit_test(__name, __bit)) { \ 1282981a53aSguenther __value = __bit; \ 129df930be7Sderaadt break; \ 130df930be7Sderaadt } \ 1312981a53aSguenther *(value) = __value; \ 1323545baa8Sderaadt } while(0) 133df930be7Sderaadt 134df930be7Sderaadt #endif /* !_BITSTRING_H_ */ 135