Commit | Line | Data |
---|---|---|
052d3291 KB |
1 | /* |
2 | * Copyright (c) 1989 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Paul Vixie. | |
7 | * | |
863005e5 | 8 | * %sccs.include.redist.c% |
052d3291 | 9 | * |
d2b7358e | 10 | * @(#)bitstring.h 5.5 (Berkeley) %G% |
052d3291 KB |
11 | */ |
12 | ||
d2b7358e KB |
13 | #ifndef _BITSTRING_H_ |
14 | #define _BITSTRING_H_ | |
15 | ||
052d3291 KB |
16 | typedef unsigned char bitstr_t; |
17 | ||
18 | /* internal macros */ | |
19 | /* byte of the bitstring bit is in */ | |
20 | #define _bit_byte(bit) \ | |
21 | ((bit) >> 3) | |
22 | ||
23 | /* mask for the bit within its byte */ | |
24 | #define _bit_mask(bit) \ | |
25 | (1 << ((bit)&0x7)) | |
26 | ||
27 | /* external macros */ | |
28 | /* bytes in a bitstring of nbits bits */ | |
29 | #define bitstr_size(nbits) \ | |
30 | ((((nbits) - 1) >> 3) + 1) | |
31 | ||
32 | /* allocate a bitstring */ | |
33 | #define bit_alloc(nbits) \ | |
1b1df875 | 34 | (bitstr_t *)calloc(1, \ |
052d3291 KB |
35 | (unsigned int)_bitstr_size(nbits) * sizeof(bitstr_t)) |
36 | ||
37 | /* allocate a bitstring on the stack */ | |
38 | #define bit_decl(name, nbits) \ | |
39 | (name)[bitstr_size(nbits)] | |
40 | ||
41 | /* is bit N of bitstring name set? */ | |
42 | #define bit_test(name, bit) \ | |
43 | ((name)[_bit_byte(bit)] & _bit_mask(bit)) | |
44 | ||
45 | /* set bit N of bitstring name */ | |
46 | #define bit_set(name, bit) \ | |
47 | (name)[_bit_byte(bit)] |= _bit_mask(bit) | |
48 | ||
49 | /* clear bit N of bitstring name */ | |
50 | #define bit_clear(name, bit) \ | |
51 | (name)[_bit_byte(bit)] &= ~_bit_mask(bit) | |
52 | ||
50b48a68 | 53 | /* clear bits start ... stop in bitstring */ |
052d3291 | 54 | #define bit_nclear(name, start, stop) { \ |
50b48a68 KB |
55 | register bitstr_t *_name = name; \ |
56 | register int _start = start, _stop = stop; \ | |
57 | register int _startbyte = _bit_byte(_start); \ | |
58 | register int _stopbyte = _bit_byte(_stop); \ | |
59 | _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \ | |
60 | while (++_startbyte < _stopbyte) \ | |
61 | _name[_startbyte] = 0; \ | |
62 | _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ | |
052d3291 KB |
63 | } |
64 | ||
50b48a68 | 65 | /* set bits start ... stop in bitstring */ |
052d3291 | 66 | #define bit_nset(name, start, stop) { \ |
50b48a68 KB |
67 | register bitstr_t *_name = name; \ |
68 | register int _start = start, _stop = stop; \ | |
69 | register int _startbyte = _bit_byte(_start); \ | |
70 | register int _stopbyte = _bit_byte(_stop); \ | |
71 | _name[_startbyte] |= 0xff << ((start)&0x7); \ | |
72 | while (++_startbyte < _stopbyte) \ | |
73 | _name[_startbyte] = 0xff; \ | |
74 | _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ | |
052d3291 KB |
75 | } |
76 | ||
77 | /* find first bit clear in name */ | |
78 | #define bit_ffc(name, nbits, value) { \ | |
50b48a68 KB |
79 | register bitstr_t *_name = name; \ |
80 | register int _byte, _nbits = nbits; \ | |
81 | register int _stopbyte = _bit_byte(_nbits), _value = -1; \ | |
82 | for (_byte = 0; _byte <= _stopbyte; ++_byte) \ | |
83 | if (_name[_byte] != 0xff) { \ | |
84 | _value = _byte << 3; \ | |
85 | for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \ | |
86 | ++_value, _stopbyte >>= 1); \ | |
052d3291 KB |
87 | break; \ |
88 | } \ | |
50b48a68 | 89 | *(value) = _value; \ |
052d3291 KB |
90 | } |
91 | ||
92 | /* find first bit set in name */ | |
93 | #define bit_ffs(name, nbits, value) { \ | |
50b48a68 KB |
94 | register bitstr_t *_name = name; \ |
95 | register int _byte, _nbits = nbits; \ | |
96 | register int _stopbyte = _bit_byte(_nbits), _value = -1; \ | |
97 | for (_byte = 0; _byte <= _stopbyte; ++_byte) \ | |
98 | if (_name[_byte]) { \ | |
99 | _value = _byte << 3; \ | |
100 | for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \ | |
101 | ++_value, _stopbyte >>= 1); \ | |
052d3291 KB |
102 | break; \ |
103 | } \ | |
50b48a68 | 104 | *(value) = _value; \ |
052d3291 | 105 | } |
d2b7358e KB |
106 | |
107 | #endif /* !_BITSTRING_H_ */ |