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