1*c87b03e5Sespie /* bit.c -- Implementation File (module.c template V1.0)
2*c87b03e5Sespie Copyright (C) 1995 Free Software Foundation, Inc.
3*c87b03e5Sespie Contributed by James Craig Burley.
4*c87b03e5Sespie
5*c87b03e5Sespie This file is part of GNU Fortran.
6*c87b03e5Sespie
7*c87b03e5Sespie GNU Fortran is free software; you can redistribute it and/or modify
8*c87b03e5Sespie it under the terms of the GNU General Public License as published by
9*c87b03e5Sespie the Free Software Foundation; either version 2, or (at your option)
10*c87b03e5Sespie any later version.
11*c87b03e5Sespie
12*c87b03e5Sespie GNU Fortran is distributed in the hope that it will be useful,
13*c87b03e5Sespie but WITHOUT ANY WARRANTY; without even the implied warranty of
14*c87b03e5Sespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*c87b03e5Sespie GNU General Public License for more details.
16*c87b03e5Sespie
17*c87b03e5Sespie You should have received a copy of the GNU General Public License
18*c87b03e5Sespie along with GNU Fortran; see the file COPYING. If not, write to
19*c87b03e5Sespie the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20*c87b03e5Sespie 02111-1307, USA.
21*c87b03e5Sespie
22*c87b03e5Sespie Related Modules:
23*c87b03e5Sespie None
24*c87b03e5Sespie
25*c87b03e5Sespie Description:
26*c87b03e5Sespie Tracks arrays of booleans in useful ways.
27*c87b03e5Sespie
28*c87b03e5Sespie Modifications:
29*c87b03e5Sespie */
30*c87b03e5Sespie
31*c87b03e5Sespie /* Include files. */
32*c87b03e5Sespie
33*c87b03e5Sespie #include "proj.h"
34*c87b03e5Sespie #include "bit.h"
35*c87b03e5Sespie #include "malloc.h"
36*c87b03e5Sespie
37*c87b03e5Sespie /* Externals defined here. */
38*c87b03e5Sespie
39*c87b03e5Sespie
40*c87b03e5Sespie /* Simple definitions and enumerations. */
41*c87b03e5Sespie
42*c87b03e5Sespie
43*c87b03e5Sespie /* Internal typedefs. */
44*c87b03e5Sespie
45*c87b03e5Sespie
46*c87b03e5Sespie /* Private include files. */
47*c87b03e5Sespie
48*c87b03e5Sespie
49*c87b03e5Sespie /* Internal structure definitions. */
50*c87b03e5Sespie
51*c87b03e5Sespie
52*c87b03e5Sespie /* Static objects accessed by functions in this module. */
53*c87b03e5Sespie
54*c87b03e5Sespie
55*c87b03e5Sespie /* Static functions (internal). */
56*c87b03e5Sespie
57*c87b03e5Sespie
58*c87b03e5Sespie /* Internal macros. */
59*c87b03e5Sespie
60*c87b03e5Sespie
61*c87b03e5Sespie /* ffebit_count -- Count # of bits set a particular way
62*c87b03e5Sespie
63*c87b03e5Sespie ffebit b; // the ffebit object
64*c87b03e5Sespie ffebitCount offset; // 0..size-1
65*c87b03e5Sespie bool value; // FALSE (0), TRUE (1)
66*c87b03e5Sespie ffebitCount range; // # bits to test
67*c87b03e5Sespie ffebitCount number; // # bits equal to value
68*c87b03e5Sespie ffebit_count(b,offset,value,range,&number);
69*c87b03e5Sespie
70*c87b03e5Sespie Sets <number> to # bits at <offset> through <offset + range - 1> set to
71*c87b03e5Sespie <value>. If <range> is 0, <number> is set to 0. */
72*c87b03e5Sespie
73*c87b03e5Sespie void
ffebit_count(ffebit b,ffebitCount offset,bool value,ffebitCount range,ffebitCount * number)74*c87b03e5Sespie ffebit_count (ffebit b, ffebitCount offset, bool value, ffebitCount range,
75*c87b03e5Sespie ffebitCount *number)
76*c87b03e5Sespie {
77*c87b03e5Sespie ffebitCount element;
78*c87b03e5Sespie ffebitCount bitno;
79*c87b03e5Sespie
80*c87b03e5Sespie assert (offset + range <= b->size);
81*c87b03e5Sespie
82*c87b03e5Sespie for (*number = 0; range != 0; --range, ++offset)
83*c87b03e5Sespie {
84*c87b03e5Sespie element = offset / CHAR_BIT;
85*c87b03e5Sespie bitno = offset % CHAR_BIT;
86*c87b03e5Sespie if (value
87*c87b03e5Sespie == ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE))
88*c87b03e5Sespie ++ * number;
89*c87b03e5Sespie }
90*c87b03e5Sespie }
91*c87b03e5Sespie
92*c87b03e5Sespie /* ffebit_new -- Create a new ffebit object
93*c87b03e5Sespie
94*c87b03e5Sespie ffebit b;
95*c87b03e5Sespie ffebit_kill(b);
96*c87b03e5Sespie
97*c87b03e5Sespie Destroys an ffebit object obtained via ffebit_new. */
98*c87b03e5Sespie
99*c87b03e5Sespie void
ffebit_kill(ffebit b)100*c87b03e5Sespie ffebit_kill (ffebit b)
101*c87b03e5Sespie {
102*c87b03e5Sespie malloc_kill_ks (b->pool, b,
103*c87b03e5Sespie offsetof (struct _ffebit_, bits)
104*c87b03e5Sespie + (b->size + CHAR_BIT - 1) / CHAR_BIT);
105*c87b03e5Sespie }
106*c87b03e5Sespie
107*c87b03e5Sespie /* ffebit_new -- Create a new ffebit object
108*c87b03e5Sespie
109*c87b03e5Sespie ffebit b;
110*c87b03e5Sespie mallocPool pool;
111*c87b03e5Sespie ffebitCount size;
112*c87b03e5Sespie b = ffebit_new(pool,size);
113*c87b03e5Sespie
114*c87b03e5Sespie Allocates an ffebit object that holds the values of <size> bits in pool
115*c87b03e5Sespie <pool>. */
116*c87b03e5Sespie
117*c87b03e5Sespie ffebit
ffebit_new(mallocPool pool,ffebitCount size)118*c87b03e5Sespie ffebit_new (mallocPool pool, ffebitCount size)
119*c87b03e5Sespie {
120*c87b03e5Sespie ffebit b;
121*c87b03e5Sespie
122*c87b03e5Sespie b = malloc_new_zks (pool, "ffebit",
123*c87b03e5Sespie offsetof (struct _ffebit_, bits)
124*c87b03e5Sespie + (size + CHAR_BIT - 1) / CHAR_BIT,
125*c87b03e5Sespie 0);
126*c87b03e5Sespie b->pool = pool;
127*c87b03e5Sespie b->size = size;
128*c87b03e5Sespie
129*c87b03e5Sespie return b;
130*c87b03e5Sespie }
131*c87b03e5Sespie
132*c87b03e5Sespie /* ffebit_set -- Set value of # of bits
133*c87b03e5Sespie
134*c87b03e5Sespie ffebit b; // the ffebit object
135*c87b03e5Sespie ffebitCount offset; // 0..size-1
136*c87b03e5Sespie bool value; // FALSE (0), TRUE (1)
137*c87b03e5Sespie ffebitCount length; // # bits to set starting at offset (usually 1)
138*c87b03e5Sespie ffebit_set(b,offset,value,length);
139*c87b03e5Sespie
140*c87b03e5Sespie Sets bit #s <offset> through <offset + length - 1> to <value>. */
141*c87b03e5Sespie
142*c87b03e5Sespie void
ffebit_set(ffebit b,ffebitCount offset,bool value,ffebitCount length)143*c87b03e5Sespie ffebit_set (ffebit b, ffebitCount offset, bool value, ffebitCount length)
144*c87b03e5Sespie {
145*c87b03e5Sespie ffebitCount i;
146*c87b03e5Sespie ffebitCount element;
147*c87b03e5Sespie ffebitCount bitno;
148*c87b03e5Sespie
149*c87b03e5Sespie assert (offset + length <= b->size);
150*c87b03e5Sespie
151*c87b03e5Sespie for (i = 0; i < length; ++i, ++offset)
152*c87b03e5Sespie {
153*c87b03e5Sespie element = offset / CHAR_BIT;
154*c87b03e5Sespie bitno = offset % CHAR_BIT;
155*c87b03e5Sespie b->bits[element] = (((unsigned char) (value ? 1 : 0)) << bitno)
156*c87b03e5Sespie | (b->bits[element] & ~((unsigned char) 1 << bitno));
157*c87b03e5Sespie }
158*c87b03e5Sespie }
159*c87b03e5Sespie
160*c87b03e5Sespie /* ffebit_test -- Test value of # of bits
161*c87b03e5Sespie
162*c87b03e5Sespie ffebit b; // the ffebit object
163*c87b03e5Sespie ffebitCount offset; // 0..size-1
164*c87b03e5Sespie bool value; // FALSE (0), TRUE (1)
165*c87b03e5Sespie ffebitCount length; // # bits with same value
166*c87b03e5Sespie ffebit_test(b,offset,&value,&length);
167*c87b03e5Sespie
168*c87b03e5Sespie Returns value of bits at <offset> through <offset + length - 1> in
169*c87b03e5Sespie <value>. If <offset> is already at the end of the bit array (if
170*c87b03e5Sespie offset == ffebit_size(b)), <length> is set to 0 and <value> is
171*c87b03e5Sespie undefined. */
172*c87b03e5Sespie
173*c87b03e5Sespie void
ffebit_test(ffebit b,ffebitCount offset,bool * value,ffebitCount * length)174*c87b03e5Sespie ffebit_test (ffebit b, ffebitCount offset, bool *value, ffebitCount *length)
175*c87b03e5Sespie {
176*c87b03e5Sespie ffebitCount i;
177*c87b03e5Sespie ffebitCount element;
178*c87b03e5Sespie ffebitCount bitno;
179*c87b03e5Sespie
180*c87b03e5Sespie if (offset >= b->size)
181*c87b03e5Sespie {
182*c87b03e5Sespie assert (offset == b->size);
183*c87b03e5Sespie *length = 0;
184*c87b03e5Sespie return;
185*c87b03e5Sespie }
186*c87b03e5Sespie
187*c87b03e5Sespie element = offset / CHAR_BIT;
188*c87b03e5Sespie bitno = offset % CHAR_BIT;
189*c87b03e5Sespie *value = (b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE;
190*c87b03e5Sespie *length = 1;
191*c87b03e5Sespie
192*c87b03e5Sespie for (i = b->size - offset - 1, ++offset; i != 0; --i, ++offset, ++*length)
193*c87b03e5Sespie {
194*c87b03e5Sespie element = offset / CHAR_BIT;
195*c87b03e5Sespie bitno = offset % CHAR_BIT;
196*c87b03e5Sespie if (*value
197*c87b03e5Sespie != ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE))
198*c87b03e5Sespie break;
199*c87b03e5Sespie }
200*c87b03e5Sespie }
201