xref: /openbsd-src/include/bitstring.h (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: bitstring.h,v 1.3 1997/09/21 10:45:26 niklas Exp $	*/
2 /*	$NetBSD: bitstring.h,v 1.4 1994/10/26 00:55:45 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1989 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Paul Vixie.
10  *
11  * Redistribution and use in source and binary forms are permitted
12  * provided that the above copyright notice and this paragraph are
13  * duplicated in all such forms and that any documentation,
14  * advertising materials, and other materials related to such
15  * distribution and use acknowledge that the software was developed
16  * by the University of California, Berkeley.  The name of the
17  * University may not be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  *
23  *	@(#)bitstring.h	5.2 (Berkeley) 4/4/90
24  */
25 
26 #ifndef _BITSTRING_H_
27 #define _BITSTRING_H_
28 
29 /* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91
30  * bitstr_size changed gratuitously, but shorter
31  * bit_alloc   spelling error fixed
32  * the following were efficient, but didn't work, they've been made to
33  * work, but are no longer as efficient :-)
34  * bit_nclear, bit_nset, bit_ffc, bit_ffs
35  */
36 typedef	unsigned char bitstr_t;
37 
38 /* internal macros */
39 				/* byte of the bitstring bit is in */
40 #define	_bit_byte(bit) \
41 	((bit) >> 3)
42 
43 				/* mask for the bit within its byte */
44 #define	_bit_mask(bit) \
45 	(1 << ((bit)&0x7))
46 
47 /* external macros */
48 				/* bytes in a bitstring of nbits bits */
49 #define	bitstr_size(nbits) \
50 	(((nbits) + 7) >> 3)
51 
52 				/* allocate a bitstring */
53 #define	bit_alloc(nbits) \
54 	(bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
55 
56 				/* allocate a bitstring on the stack */
57 #define	bit_decl(name, nbits) \
58 	(name)[bitstr_size(nbits)]
59 
60 				/* is bit N of bitstring name set? */
61 #define	bit_test(name, bit) \
62 	((name)[_bit_byte(bit)] & _bit_mask(bit))
63 
64 				/* set bit N of bitstring name */
65 #define	bit_set(name, bit) \
66 	(name)[_bit_byte(bit)] |= _bit_mask(bit)
67 
68 				/* clear bit N of bitstring name */
69 #define	bit_clear(name, bit) \
70 	(name)[_bit_byte(bit)] &= ~_bit_mask(bit)
71 
72 				/* clear bits start ... stop in bitstring */
73 #define	bit_nclear(name, start, stop) do { \
74 	register bitstr_t *_name = name; \
75 	register int _start = start, _stop = stop; \
76 	while (_start <= _stop) { \
77 		bit_clear(_name, _start); \
78 		_start++; \
79 		} \
80 } while (0)
81 
82 				/* set bits start ... stop in bitstring */
83 #define	bit_nset(name, start, stop) do { \
84 	register bitstr_t *_name = name; \
85 	register int _start = start, _stop = stop; \
86 	while (_start <= _stop) { \
87 		bit_set(_name, _start); \
88 		_start++; \
89 		} \
90 } while (0)
91 
92 				/* find first bit clear in name */
93 #define	bit_ffc(name, nbits, value) do { \
94 	register bitstr_t *_name = name; \
95 	register int _bit, _nbits = nbits, _value = -1; \
96 	for (_bit = 0; _bit < _nbits; ++_bit) \
97 		if (!bit_test(_name, _bit)) { \
98 			_value = _bit; \
99 			break; \
100 		} \
101 	*(value) = _value; \
102 } while (0)
103 
104 				/* find first bit set in name */
105 #define	bit_ffs(name, nbits, value) do { \
106 	register bitstr_t *_name = name; \
107 	register int _bit, _nbits = nbits, _value = -1; \
108 	for (_bit = 0; _bit < _nbits; ++_bit) \
109 		if (bit_test(_name, _bit)) { \
110 			_value = _bit; \
111 			break; \
112 		} \
113 	*(value) = _value; \
114 } while (0)
115 
116 #endif /* !_BITSTRING_H_ */
117