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 | * | |
8 | * Redistribution and use in source and binary forms are permitted | |
9 | * provided that the above copyright notice and this paragraph are | |
10 | * duplicated in all such forms and that any documentation, | |
11 | * advertising materials, and other materials related to such | |
12 | * distribution and use acknowledge that the software was developed | |
13 | * by the University of California, Berkeley. The name of the | |
14 | * University may not be used to endorse or promote products derived | |
15 | * from this software without specific prior written permission. | |
16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
19 | * | |
20 | * @(#)bitstring.h 5.1 (Berkeley) %G% | |
21 | */ | |
22 | ||
23 | typedef unsigned char bitstr_t; | |
24 | ||
25 | /* internal macros */ | |
26 | /* byte of the bitstring bit is in */ | |
27 | #define _bit_byte(bit) \ | |
28 | ((bit) >> 3) | |
29 | ||
30 | /* mask for the bit within its byte */ | |
31 | #define _bit_mask(bit) \ | |
32 | (1 << ((bit)&0x7)) | |
33 | ||
34 | /* external macros */ | |
35 | /* bytes in a bitstring of nbits bits */ | |
36 | #define bitstr_size(nbits) \ | |
37 | ((((nbits) - 1) >> 3) + 1) | |
38 | ||
39 | /* allocate a bitstring */ | |
40 | #define bit_alloc(nbits) \ | |
41 | (bitstr_t *)malloc(1, \ | |
42 | (unsigned int)_bitstr_size(nbits) * sizeof(bitstr_t)) | |
43 | ||
44 | /* allocate a bitstring on the stack */ | |
45 | #define bit_decl(name, nbits) \ | |
46 | (name)[bitstr_size(nbits)] | |
47 | ||
48 | /* is bit N of bitstring name set? */ | |
49 | #define bit_test(name, bit) \ | |
50 | ((name)[_bit_byte(bit)] & _bit_mask(bit)) | |
51 | ||
52 | /* set bit N of bitstring name */ | |
53 | #define bit_set(name, bit) \ | |
54 | (name)[_bit_byte(bit)] |= _bit_mask(bit) | |
55 | ||
56 | /* clear bit N of bitstring name */ | |
57 | #define bit_clear(name, bit) \ | |
58 | (name)[_bit_byte(bit)] &= ~_bit_mask(bit) | |
59 | ||
60 | /* clear bits 0 ... N in bitstring name */ | |
61 | #define bit_nclear(name, start, stop) { \ | |
62 | register int _startbyte, _stopbyte; \ | |
63 | _startbyte = _bit_byte(start); \ | |
64 | (name)[_startbyte] &= 0xff >> (8 - ((start)&0x7)); \ | |
65 | for (_stopbyte = _bit_byte(stop); ++_startbyte < _stopbyte; \ | |
66 | (name)[_startbyte] = 0); \ | |
67 | (name)[_stopbyte] &= 0xff << (((stop)&0x7) + 1); \ | |
68 | } | |
69 | ||
70 | /* set bits 0 ... N in string name */ | |
71 | #define bit_nset(name, start, stop) { \ | |
72 | register int _startbyte, _stopbyte; \ | |
73 | _startbyte = _bit_byte(start); \ | |
74 | (name)[_startbyte] |= 0xff << ((start)&0x7); \ | |
75 | for (_stopbyte = _bit_byte(stop); ++_startbyte < _stopbyte; \ | |
76 | (name)[_startbyte] = 0xff); \ | |
77 | (name)[_stopbyte] |= 0xff >> (7 - ((stop)&0x7)); \ | |
78 | } | |
79 | ||
80 | /* find first bit clear in name */ | |
81 | #define bit_ffc(name, nbits, value) { \ | |
82 | register int _byte, _stopbyte; \ | |
83 | for ((value) = -1, _byte = 0, _stopbyte = _bit_byte(nbits); \ | |
84 | _byte <= _stopbyte; _byte++) \ | |
85 | if ((name)[_byte] != 0xff) { \ | |
86 | (value) = _byte << 3; \ | |
87 | for (_stopbyte = (name)[_byte]; (_stopbyte&0x1); \ | |
88 | ++(value), _stopbyte >>= 1); \ | |
89 | break; \ | |
90 | } \ | |
91 | } | |
92 | ||
93 | /* find first bit set in name */ | |
94 | #define bit_ffs(name, nbits, value) { \ | |
95 | register int _byte, _stopbyte; \ | |
96 | for ((value) = -1, _byte = 0, _stopbyte = _bit_byte(nbits); \ | |
97 | _byte <= _stopbyte; _byte++) \ | |
98 | if ((name)[_byte]) { \ | |
99 | (value) = _byte << 3; \ | |
100 | for (_stopbyte = (name)[_byte]; !(_stopbyte&0x1); \ | |
101 | ++(value), _stopbyte >>= 1); \ | |
102 | break; \ | |
103 | } \ | |
104 | } |