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