]> git.saurik.com Git - bison.git/blame - lib/bitset.c
Fix BeOS, FreeBSD, MacOS porting problems reported by Bruno Haible.
[bison.git] / lib / bitset.c
CommitLineData
7086e707 1/* General bitsets.
4d1801f1 2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
7086e707
AD
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
ef017502
AD
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
7086e707 9
ef017502
AD
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
7086e707 14
ef017502
AD
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
0fb669f9 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
7086e707
AD
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdlib.h>
eaef5507 24#include <string.h>
7086e707 25#include "bitset.h"
613f5e1a 26#include "abitset.h"
ef017502
AD
27#include "lbitset.h"
28#include "ebitset.h"
eaef5507 29#include "vbitset.h"
613f5e1a 30#include "bitset_stats.h"
7086e707
AD
31#include "obstack.h"
32
6aa452a6
AD
33const char * const bitset_type_names[] = BITSET_TYPE_NAMES;
34
7086e707 35
7086e707
AD
36/* Return number of bytes required to create a N_BIT bitset
37 of TYPE. The bitset may grow to require more bytes than this. */
d32fe6f6 38size_t
447e90bc 39bitset_bytes (enum bitset_type type, bitset_bindex n_bits)
7086e707 40{
d32fe6f6 41 size_t bytes;
7086e707 42
613f5e1a
AD
43 if (bitset_stats_enabled)
44 return bitset_stats_bytes ();
45
7086e707
AD
46 switch (type)
47 {
48 case BITSET_ARRAY:
613f5e1a 49 bytes = abitset_bytes (n_bits);
7086e707
AD
50 break;
51
52 case BITSET_LIST:
53 bytes = lbitset_bytes (n_bits);
54 break;
55
56 case BITSET_TABLE:
57 bytes = ebitset_bytes (n_bits);
58 break;
59
eaef5507
PE
60 case BITSET_VARRAY:
61 bytes = vbitset_bytes (n_bits);
62 break;
63
7086e707
AD
64 default:
65 abort ();
66 }
67
68 return bytes;
69}
70
71
72/* Initialise bitset BSET of TYPE for N_BITS. */
73bitset
447e90bc 74bitset_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
7086e707 75{
613f5e1a
AD
76 if (bitset_stats_enabled)
77 return bitset_stats_init (bset, n_bits, type);
447e90bc 78
7086e707
AD
79 switch (type)
80 {
81 case BITSET_ARRAY:
613f5e1a 82 return abitset_init (bset, n_bits);
7086e707
AD
83
84 case BITSET_LIST:
85 return lbitset_init (bset, n_bits);
86
87 case BITSET_TABLE:
88 return ebitset_init (bset, n_bits);
89
eaef5507
PE
90 case BITSET_VARRAY:
91 return vbitset_init (bset, n_bits);
92
7086e707
AD
93 default:
94 abort ();
95 }
96}
97
98
99/* Select a bitset type for a set of N_BITS and with attribute hints
100 specified by ATTR. For variable size bitsets, N_BITS is only a
101 hint and may be zero. */
102enum bitset_type
447e90bc 103bitset_type_choose (bitset_bindex n_bits ATTRIBUTE_UNUSED, unsigned int attr)
7086e707 104{
7086e707
AD
105 /* Check attributes. */
106 if (attr & BITSET_FIXED && attr & BITSET_VARIABLE)
107 abort ();
108 if (attr & BITSET_SPARSE && attr & BITSET_DENSE)
109 abort ();
110
eaef5507 111 /* Choose the type of bitset. Note that sometimes we will be asked
6aa452a6 112 for a zero length fixed size bitset. */
7086e707 113
4d1801f1 114
eaef5507
PE
115 /* If no attributes selected, choose a good compromise. */
116 if (!attr)
117 return BITSET_VARRAY;
118
119 if (attr & BITSET_SPARSE)
120 return BITSET_LIST;
121
122 if (attr & BITSET_FIXED)
123 return BITSET_ARRAY;
7086e707 124
eaef5507
PE
125 if (attr & BITSET_GREEDY)
126 return BITSET_TABLE;
127
128 return BITSET_VARRAY;
7086e707
AD
129}
130
131
132/* Create a bitset of N_BITS of type TYPE. */
133bitset
447e90bc 134bitset_alloc (bitset_bindex n_bits, enum bitset_type type)
7086e707 135{
d32fe6f6 136 size_t bytes;
7086e707
AD
137 bitset bset;
138
7086e707
AD
139 bytes = bitset_bytes (type, n_bits);
140
ef017502
AD
141 bset = (bitset) xcalloc (1, bytes);
142
143 /* The cache is disabled until some elements are allocated. If we
613f5e1a 144 have variable length arrays, then we may need to allocate a dummy
ef017502 145 element. */
7086e707
AD
146
147 return bitset_init (bset, n_bits, type);
148}
149
150
151/* Create a bitset of N_BITS of type TYPE. */
152bitset
447e90bc
PE
153bitset_obstack_alloc (struct obstack *bobstack,
154 bitset_bindex n_bits, enum bitset_type type)
7086e707 155{
d32fe6f6 156 size_t bytes;
ef017502 157 bitset bset;
7086e707 158
7086e707
AD
159 bytes = bitset_bytes (type, n_bits);
160
ef017502
AD
161 bset = obstack_alloc (bobstack, bytes);
162 memset (bset, 0, bytes);
163
164 return bitset_init (bset, n_bits, type);
7086e707
AD
165}
166
167
168/* Create a bitset of N_BITS and with attribute hints specified by
169 ATTR. */
170bitset
447e90bc 171bitset_create (bitset_bindex n_bits, unsigned int attr)
7086e707
AD
172{
173 enum bitset_type type;
174
175 type = bitset_type_choose (n_bits, attr);
176
177 return bitset_alloc (n_bits, type);
178}
179
180
181/* Free bitset BSET. */
182void
447e90bc 183bitset_free (bitset bset)
7086e707 184{
ef017502 185 BITSET_FREE_ (bset);
7086e707
AD
186 free (bset);
187}
188
189
190/* Free bitset BSET allocated on obstack. */
191void
447e90bc 192bitset_obstack_free (bitset bset)
7086e707 193{
ef017502 194 BITSET_FREE_ (bset);
7086e707
AD
195}
196
197
613f5e1a
AD
198/* Return bitset type. */
199enum bitset_type
447e90bc 200bitset_type_get (bitset bset)
613f5e1a
AD
201{
202 enum bitset_type type;
203
204 type = BITSET_TYPE_ (bset);
205 if (type != BITSET_STATS)
206 return type;
447e90bc 207
613f5e1a
AD
208 return bitset_stats_type_get (bset);
209}
210
211
6aa452a6
AD
212/* Return name of bitset type. */
213const char *
447e90bc 214bitset_type_name_get (bitset bset)
6aa452a6
AD
215{
216 enum bitset_type type;
217
218 type = bitset_type_get (bset);
219
220 return bitset_type_names[type];
221}
222
223
7086e707 224/* Find next bit set in SRC starting from and including BITNO.
d32fe6f6
PE
225 Return BITSET_BINDEX_MAX if SRC empty. */
226bitset_bindex
447e90bc 227bitset_next (bitset src, bitset_bindex bitno)
7086e707
AD
228{
229 bitset_bindex val;
230 bitset_bindex next = bitno;
231
232 if (!bitset_list (src, &val, 1, &next))
d32fe6f6 233 return BITSET_BINDEX_MAX;
7086e707
AD
234 return val;
235}
236
237
eaef5507
PE
238/* Return true if both bitsets are of the same type and size. */
239extern bool
240bitset_compatible_p (bitset bset1, bitset bset2)
241{
242 return BITSET_COMPATIBLE_ (bset1, bset2);
243}
244
245
7086e707 246/* Find previous bit set in SRC starting from and including BITNO.
d32fe6f6
PE
247 Return BITSET_BINDEX_MAX if SRC empty. */
248bitset_bindex
447e90bc 249bitset_prev (bitset src, bitset_bindex bitno)
7086e707
AD
250{
251 bitset_bindex val;
252 bitset_bindex next = bitno;
253
6aa452a6 254 if (!bitset_list_reverse (src, &val, 1, &next))
d32fe6f6 255 return BITSET_BINDEX_MAX;
7086e707
AD
256 return val;
257}
258
259
260/* Find first set bit. */
d32fe6f6 261bitset_bindex
447e90bc 262bitset_first (bitset src)
7086e707
AD
263{
264 return bitset_next (src, 0);
265}
266
267
268/* Find last set bit. */
d32fe6f6 269bitset_bindex
447e90bc 270bitset_last (bitset src)
7086e707
AD
271{
272 return bitset_prev (src, 0);
273}
274
275
d0829076
PE
276/* Is BITNO in SRC the only set bit? */
277bool
447e90bc 278bitset_only_set_p (bitset src, bitset_bindex bitno)
345cea78
AD
279{
280 bitset_bindex val[2];
281 bitset_bindex next = 0;
282
283 if (bitset_list (src, val, 2, &next) != 1)
d0829076 284 return false;
345cea78
AD
285 return val[0] == bitno;
286}
287
288
ef017502 289/* Print contents of bitset BSET to FILE. */
7086e707 290static void
d0829076 291bitset_print (FILE *file, bitset bset, bool verbose)
7086e707 292{
6aa452a6
AD
293 unsigned int pos;
294 bitset_bindex i;
613f5e1a 295 bitset_iterator iter;
7086e707
AD
296
297 if (verbose)
d32fe6f6 298 fprintf (file, "n_bits = %lu, set = {",
779e7ceb 299 (unsigned long int) bitset_size (bset));
7086e707
AD
300
301 pos = 30;
613f5e1a 302 BITSET_FOR_EACH (iter, bset, i, 0)
7086e707
AD
303 {
304 if (pos > 70)
305 {
306 fprintf (file, "\n");
307 pos = 0;
308 }
309
4d1801f1 310 fprintf (file, "%lu ", (unsigned long int) i);
7086e707 311 pos += 1 + (i >= 10) + (i >= 100);
613f5e1a 312 };
7086e707
AD
313
314 if (verbose)
315 fprintf (file, "}\n");
316}
317
318
6aa452a6
AD
319/* Dump bitset BSET to FILE. */
320void
447e90bc 321bitset_dump (FILE *file, bitset bset)
7086e707 322{
d0829076 323 bitset_print (file, bset, false);
6aa452a6 324}
7086e707 325
7086e707 326
6aa452a6
AD
327/* Release memory associated with bitsets. */
328void
447e90bc 329bitset_release_memory (void)
6aa452a6
AD
330{
331 lbitset_release_memory ();
332 ebitset_release_memory ();
7086e707
AD
333}
334
335
d0829076
PE
336/* Toggle bit BITNO in bitset BSET and the new value of the bit. */
337bool
447e90bc 338bitset_toggle_ (bitset bset, bitset_bindex bitno)
ef017502 339{
6aa452a6
AD
340 /* This routine is for completeness. It could be optimized if
341 required. */
342 if (bitset_test (bset, bitno))
343 {
344 bitset_reset (bset, bitno);
d0829076 345 return false;
6aa452a6
AD
346 }
347 else
348 {
349 bitset_set (bset, bitno);
d0829076 350 return true;
6aa452a6 351 }
ef017502
AD
352}
353
354
eaef5507
PE
355/* Return number of bits in bitset SRC. */
356bitset_bindex
357bitset_size_ (bitset src)
358{
359 return BITSET_NBITS_ (src);
360}
361
362
ef017502 363/* Return number of bits set in bitset SRC. */
d32fe6f6 364bitset_bindex
447e90bc 365bitset_count_ (bitset src)
7086e707 366{
ef017502
AD
367 bitset_bindex list[BITSET_LIST_SIZE];
368 bitset_bindex next;
d32fe6f6
PE
369 bitset_bindex num;
370 bitset_bindex count;
447e90bc 371
613f5e1a
AD
372 /* This could be greatly sped up by adding a count method for each
373 bitset implementation that uses a direct technique (based on
374 masks) for counting the number of bits set in a word. */
375
ef017502
AD
376 next = 0;
377 for (count = 0; (num = bitset_list (src, list, BITSET_LIST_SIZE, &next));
378 count += num)
379 continue;
447e90bc 380
ef017502 381 return count;
7086e707
AD
382}
383
384
d0829076 385/* DST = SRC. Return true if DST != SRC.
6aa452a6
AD
386 This is a fallback for the case where SRC and DST are different
387 bitset types. */
d0829076 388bool
447e90bc 389bitset_copy_ (bitset dst, bitset src)
ef017502 390{
6aa452a6
AD
391 bitset_bindex i;
392 bitset_iterator iter;
7086e707 393
6aa452a6
AD
394 /* Convert bitset types. We assume that the DST bitset
395 is large enough to hold the SRC bitset. */
396 bitset_zero (dst);
397 BITSET_FOR_EACH (iter, src, i, 0)
398 {
399 bitset_set (dst, i);
400 };
7086e707 401
d0829076 402 return true;
7086e707
AD
403}
404
405
613f5e1a
AD
406/* This is a fallback for implementations that do not support
407 four operand operations. */
d0829076 408static inline bool
447e90bc
PE
409bitset_op4_cmp (bitset dst, bitset src1, bitset src2, bitset src3,
410 enum bitset_ops op)
ef017502 411{
d0829076
PE
412 bool changed = false;
413 bool stats_enabled_save;
ef017502
AD
414 bitset tmp;
415
416 /* Create temporary bitset. */
6aa452a6 417 stats_enabled_save = bitset_stats_enabled;
d0829076 418 bitset_stats_enabled = false;
613f5e1a 419 tmp = bitset_alloc (0, bitset_type_get (dst));
6aa452a6 420 bitset_stats_enabled = stats_enabled_save;
ef017502
AD
421
422 switch (op)
423 {
424 case BITSET_OP_OR_AND:
6aa452a6
AD
425 bitset_or (tmp, src1, src2);
426 changed = bitset_and_cmp (dst, src3, tmp);
ef017502
AD
427 break;
428
429 case BITSET_OP_AND_OR:
6aa452a6
AD
430 bitset_and (tmp, src1, src2);
431 changed = bitset_or_cmp (dst, src3, tmp);
ef017502
AD
432 break;
433
434 case BITSET_OP_ANDN_OR:
6aa452a6
AD
435 bitset_andn (tmp, src1, src2);
436 changed = bitset_or_cmp (dst, src3, tmp);
ef017502
AD
437 break;
438
439 default:
440 abort ();
441 }
442
443 bitset_free (tmp);
444 return changed;
7086e707
AD
445}
446
447
d5c559cd
PE
448/* DST = (SRC1 & SRC2) | SRC3. */
449void
447e90bc 450bitset_and_or_ (bitset dst, bitset src1, bitset src2, bitset src3)
d5c559cd
PE
451{
452 bitset_and_or_cmp_ (dst, src1, src2, src3);
453}
454
455
6aa452a6
AD
456/* DST = (SRC1 & SRC2) | SRC3. Return non-zero if
457 DST != (SRC1 & SRC2) | SRC3. */
d0829076 458bool
447e90bc 459bitset_and_or_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
7086e707 460{
6aa452a6 461 return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_AND_OR);
7086e707
AD
462}
463
464
d5c559cd
PE
465/* DST = (SRC1 & ~SRC2) | SRC3. */
466void
447e90bc 467bitset_andn_or_ (bitset dst, bitset src1, bitset src2, bitset src3)
d5c559cd
PE
468{
469 bitset_andn_or_cmp_ (dst, src1, src2, src3);
470}
471
472
6aa452a6
AD
473/* DST = (SRC1 & ~SRC2) | SRC3. Return non-zero if
474 DST != (SRC1 & ~SRC2) | SRC3. */
d0829076 475bool
447e90bc 476bitset_andn_or_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
ef017502 477{
6aa452a6 478 return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_ANDN_OR);
ef017502
AD
479}
480
481
d5c559cd
PE
482/* DST = (SRC1 | SRC2) & SRC3. */
483void
447e90bc 484bitset_or_and_ (bitset dst, bitset src1, bitset src2, bitset src3)
d5c559cd
PE
485{
486 bitset_or_and_cmp_ (dst, src1, src2, src3);
487}
488
489
6aa452a6
AD
490/* DST = (SRC1 | SRC2) & SRC3. Return non-zero if
491 DST != (SRC1 | SRC2) & SRC3. */
d0829076 492bool
447e90bc 493bitset_or_and_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
7086e707 494{
6aa452a6 495 return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_OR_AND);
7086e707
AD
496}
497
498
499/* Function to be called from debugger to print bitset. */
500void
447e90bc 501debug_bitset (bitset bset)
7086e707 502{
ef017502 503 if (bset)
d0829076 504 bitset_print (stderr, bset, true);
7086e707 505}