Commit | Line | Data |
---|---|---|
052d3291 | 1 | /* |
b81c1bf9 KB |
2 | * Copyright (c) 1989, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
052d3291 KB |
4 | * |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Paul Vixie. | |
7 | * | |
863005e5 | 8 | * %sccs.include.redist.c% |
052d3291 | 9 | * |
b81c1bf9 | 10 | * @(#)bitstring.h 8.1 (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, \ |
44de0a78 | 35 | (unsigned int)bitstr_size(nbits) * sizeof(bitstr_t)) |
052d3291 KB |
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); \ | |
44de0a78 KB |
59 | if (_startbyte == _stopbyte) { \ |
60 | _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \ | |
61 | (0xff << ((_stop&0x7) + 1))); \ | |
62 | } else { \ | |
63 | _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \ | |
64 | while (++_startbyte < _stopbyte) \ | |
65 | _name[_startbyte] = 0; \ | |
66 | _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ | |
67 | } \ | |
052d3291 KB |
68 | } |
69 | ||
50b48a68 | 70 | /* set bits start ... stop in bitstring */ |
052d3291 | 71 | #define bit_nset(name, start, stop) { \ |
50b48a68 KB |
72 | register bitstr_t *_name = name; \ |
73 | register int _start = start, _stop = stop; \ | |
74 | register int _startbyte = _bit_byte(_start); \ | |
75 | register int _stopbyte = _bit_byte(_stop); \ | |
44de0a78 KB |
76 | if (_startbyte == _stopbyte) { \ |
77 | _name[_startbyte] |= ((0xff << (_start&0x7)) & \ | |
78 | (0xff >> (7 - (_stop&0x7)))); \ | |
79 | } else { \ | |
80 | _name[_startbyte] |= 0xff << ((_start)&0x7); \ | |
81 | while (++_startbyte < _stopbyte) \ | |
82 | _name[_startbyte] = 0xff; \ | |
83 | _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ | |
84 | } \ | |
052d3291 KB |
85 | } |
86 | ||
87 | /* find first bit clear in name */ | |
88 | #define bit_ffc(name, nbits, value) { \ | |
50b48a68 KB |
89 | register bitstr_t *_name = name; \ |
90 | register int _byte, _nbits = nbits; \ | |
91 | register int _stopbyte = _bit_byte(_nbits), _value = -1; \ | |
92 | for (_byte = 0; _byte <= _stopbyte; ++_byte) \ | |
93 | if (_name[_byte] != 0xff) { \ | |
94 | _value = _byte << 3; \ | |
95 | for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \ | |
96 | ++_value, _stopbyte >>= 1); \ | |
052d3291 KB |
97 | break; \ |
98 | } \ | |
50b48a68 | 99 | *(value) = _value; \ |
052d3291 KB |
100 | } |
101 | ||
102 | /* find first bit set in name */ | |
103 | #define bit_ffs(name, nbits, value) { \ | |
50b48a68 KB |
104 | register bitstr_t *_name = name; \ |
105 | register int _byte, _nbits = nbits; \ | |
106 | register int _stopbyte = _bit_byte(_nbits), _value = -1; \ | |
107 | for (_byte = 0; _byte <= _stopbyte; ++_byte) \ | |
108 | if (_name[_byte]) { \ | |
109 | _value = _byte << 3; \ | |
110 | for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \ | |
111 | ++_value, _stopbyte >>= 1); \ | |
052d3291 KB |
112 | break; \ |
113 | } \ | |
50b48a68 | 114 | *(value) = _value; \ |
052d3291 | 115 | } |
d2b7358e KB |
116 | |
117 | #endif /* !_BITSTRING_H_ */ |