must have directory vnode as first op
[unix-history] / usr / src / include / bitstring.h
CommitLineData
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 *
863005e5 8 * %sccs.include.redist.c%
052d3291 9 *
d2b7358e 10 * @(#)bitstring.h 5.5 (Berkeley) %G%
052d3291
KB
11 */
12
d2b7358e
KB
13#ifndef _BITSTRING_H_
14#define _BITSTRING_H_
15
052d3291
KB
16typedef 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) \
1b1df875 34 (bitstr_t *)calloc(1, \
052d3291
KB
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
50b48a68 53 /* clear bits start ... stop in bitstring */
052d3291 54#define bit_nclear(name, start, stop) { \
50b48a68
KB
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); \
052d3291
KB
63}
64
50b48a68 65 /* set bits start ... stop in bitstring */
052d3291 66#define bit_nset(name, start, stop) { \
50b48a68
KB
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)); \
052d3291
KB
75}
76
77 /* find first bit clear in name */
78#define bit_ffc(name, nbits, value) { \
50b48a68
KB
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); \
052d3291
KB
87 break; \
88 } \
50b48a68 89 *(value) = _value; \
052d3291
KB
90}
91
92 /* find first bit set in name */
93#define bit_ffs(name, nbits, value) { \
50b48a68
KB
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); \
052d3291
KB
102 break; \
103 } \
50b48a68 104 *(value) = _value; \
052d3291 105}
d2b7358e
KB
106
107#endif /* !_BITSTRING_H_ */