xref: /original-bsd/include/bitstring.h (revision 35d77a20)
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  * %sccs.include.redist.c%
9  *
10  *	@(#)bitstring.h	5.5 (Berkeley) 04/03/91
11  */
12 
13 #ifndef _BITSTRING_H_
14 #define	_BITSTRING_H_
15 
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) \
34 	(bitstr_t *)calloc(1, \
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 
53 				/* clear bits start ... stop in bitstring */
54 #define	bit_nclear(name, start, stop) { \
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); \
63 }
64 
65 				/* set bits start ... stop in bitstring */
66 #define	bit_nset(name, start, stop) { \
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)); \
75 }
76 
77 				/* find first bit clear in name */
78 #define	bit_ffc(name, nbits, value) { \
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); \
87 			break; \
88 		} \
89 	*(value) = _value; \
90 }
91 
92 				/* find first bit set in name */
93 #define	bit_ffs(name, nbits, value) { \
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); \
102 			break; \
103 		} \
104 	*(value) = _value; \
105 }
106 
107 #endif /* !_BITSTRING_H_ */
108