xref: /netbsd-src/include/bitstring.h (revision cda4f8f6ee55684e8d311b86c99ea59191e6b74f)
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.2 (Berkeley) 4/4/90
21  */
22 
23 #ifndef _BITSTRING_H_
24 #define _BITSTRING_H_
25 
26 /* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91
27  * bitstr_size changed gratuitously, but shorter
28  * bit_alloc   spelling error fixed
29  * the following were efficient, but didn't work, they've been made to
30  * work, but are no longer as efficient :-)
31  * bit_nclear, bit_nset, bit_ffc, bit_ffs
32  */
33 typedef	unsigned char bitstr_t;
34 
35 /* internal macros */
36 				/* byte of the bitstring bit is in */
37 #define	_bit_byte(bit) \
38 	((bit) >> 3)
39 
40 				/* mask for the bit within its byte */
41 #define	_bit_mask(bit) \
42 	(1 << ((bit)&0x7))
43 
44 /* external macros */
45 				/* bytes in a bitstring of nbits bits */
46 #define	bitstr_size(nbits) \
47 	(((nbits) + 7) >> 3)
48 
49 				/* allocate a bitstring */
50 #define	bit_alloc(nbits) \
51 	(bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
52 
53 				/* allocate a bitstring on the stack */
54 #define	bit_decl(name, nbits) \
55 	(name)[bitstr_size(nbits)]
56 
57 				/* is bit N of bitstring name set? */
58 #define	bit_test(name, bit) \
59 	((name)[_bit_byte(bit)] & _bit_mask(bit))
60 
61 				/* set bit N of bitstring name */
62 #define	bit_set(name, bit) \
63 	(name)[_bit_byte(bit)] |= _bit_mask(bit)
64 
65 				/* clear bit N of bitstring name */
66 #define	bit_clear(name, bit) \
67 	(name)[_bit_byte(bit)] &= ~_bit_mask(bit)
68 
69 				/* clear bits start ... stop in bitstring */
70 #define	bit_nclear(name, start, stop) { \
71 	register bitstr_t *_name = name; \
72 	register int _start = start, _stop = stop; \
73 	while (_start <= _stop) { \
74 		bit_clear(_name, _start); \
75 		_start++; \
76 		} \
77 }
78 
79 				/* set bits start ... stop in bitstring */
80 #define	bit_nset(name, start, stop) { \
81 	register bitstr_t *_name = name; \
82 	register int _start = start, _stop = stop; \
83 	while (_start <= _stop) { \
84 		bit_set(_name, _start); \
85 		_start++; \
86 		} \
87 }
88 
89 				/* find first bit clear in name */
90 #define	bit_ffc(name, nbits, value) { \
91 	register bitstr_t *_name = name; \
92 	register int _bit, _nbits = nbits, _value = -1; \
93 	for (_bit = 0; _bit < _nbits; ++_bit) \
94 		if (!bit_test(_name, _bit)) { \
95 			_value = _bit; \
96 			break; \
97 		} \
98 	*(value) = _value; \
99 }
100 
101 				/* find first bit set in name */
102 #define	bit_ffs(name, nbits, value) { \
103 	register bitstr_t *_name = name; \
104 	register int _bit, _nbits = nbits, _value = -1; \
105 	for (_bit = 0; _bit < _nbits; ++_bit) \
106 		if (bit_test(_name, _bit)) { \
107 			_value = _bit; \
108 			break; \
109 		} \
110 	*(value) = _value; \
111 }
112 
113 #endif /* !_BITSTRING_H_ */
114