home *** CD-ROM | disk | FTP | other *** search
- /* > C.Bitset - Bitset data type */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include "bitset.h"
-
- #ifdef test
- #include <stdio.h>
- #endif
-
- /* Return values from functions */
-
- #define OK 1
- #define ERR 0
-
- #define CHAR_BIT_SHIFT 3
- #define CHAR_BIT_MASK 0x07
-
- /* General component routines */
-
- bitset bset_new (int bits)
- {
- bitset b;
- int bytes = ( bits >> CHAR_BIT_SHIFT )
- + ( ( bits & CHAR_BIT_MASK ) ? 1 : 0 );
-
- /* Create a zero-filled bitmap (all unset) */
-
- b = calloc( sizeof(struct bitset) - 1 + bytes, 1 );
-
- if ( b == NULL )
- return NULL;
-
- b->bits = bits;
- b->bytes = bytes;
-
- return b;
- }
-
- void bset_free (bitset b)
- {
- free(b);
- }
-
- void bset_clear (bitset b)
- {
- memset(b->bitmap,0,b->bytes);
- }
-
- int bset_copy (bitset b1, bitset b2)
- {
- if ( b1->bits != b2->bits )
- return ERR;
-
- memcpy(b1->bitmap,b2->bitmap,b1->bytes);
-
- return OK;
- }
-
- int bset_equal (bitset b1, bitset b2)
- {
- if ( b1->bits != b2->bits )
- return 0;
-
- return ( memcmp(b1->bitmap,b2->bitmap,b1->bytes) );
- }
-
- int bset_empty (bitset b)
- {
- int i;
-
- for ( i = 0; i < b->bytes; ++i )
- if ( b->bitmap[i] != 0 )
- return 0;
-
- return 1;
- }
-
- int bset_size (bitset b)
- {
- int i;
- unsigned char byte;
- int count = 0;
-
- for ( i = 0; i < b->bytes; ++i )
- {
- byte = b->bitmap[i];
- while ( byte != 0 )
- {
- if ( ( byte & 1 ) != 0 )
- ++count;
- byte >>= 1;
- }
- }
-
- return count;
- }
-
- int bset_iterate (bitset b, int (*process)(int))
- {
- int i;
- int ret;
- unsigned char byte;
- int current;
-
- for ( i = 0; i < b->bytes; ++i )
- {
- current = i << CHAR_BIT_SHIFT;
- byte = b->bitmap[i];
- while ( byte != 0 )
- {
- if ( ( byte & 1 ) != 0 )
- {
- ret = (*process)(current);
-
- /* Non-zero => stop processing here */
- /* Negative => Abnormal (error) termination */
-
- if ( ret != 0 )
- return ( ret >= 0 );
- }
-
- ++current;
- byte >>= 1;
- }
- }
-
- return OK;
- }
-
- /* Bitset-specific routines */
-
- int bset_set (bitset b, int bit)
- {
- if ( bit >= b->bits )
- return ERR;
-
- b->bitmap [bit >> CHAR_BIT_SHIFT ] |= 1 << (bit & CHAR_BIT_MASK);
-
- return OK;
- }
-
- int bset_clr (bitset b, int bit)
- {
- if ( bit >= b->bits )
- return ERR;
-
- b->bitmap [bit >> CHAR_BIT_SHIFT ] &= ~(1 << (bit & CHAR_BIT_MASK));
-
- return OK;
- }
-
- int bset_invert (bitset b, int bit)
- {
- if ( bit >= b->bits )
- return ERR;
-
- b->bitmap [bit >> CHAR_BIT_SHIFT ] ^= 1 << (bit & CHAR_BIT_MASK);
-
- return OK;
- }
-
- int bset_test (bitset b, int bit)
- {
- int res;
-
- if ( bit >= b->bits )
- return 0;
-
- res = b->bitmap [ bit >> CHAR_BIT_SHIFT ]
- & ( 1 << (bit & CHAR_BIT_MASK) );
-
- return res;
- }
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef test
- int print (int i)
- {
- printf("%d ",i);
- return STATUS_CONTINUE;
- }
-
- void bset_dump (bitset b)
- {
- printf("Bitset: ");
- bset_iterate(b,print);
- putchar('\n');
- }
- #endif
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef test
-
- #define BUFLEN 255
-
- int main (void)
- {
- char buf[BUFLEN];
- int i, j, num;
- bitset b[10];
-
- for ( i = 0; i < 10; ++i )
- b[i] = bset_new(255);
-
- for ( ; ; )
- {
- printf(">");
- fgets(buf,BUFLEN,stdin);
-
- if ( buf[0] == '\n' || buf[0] == '\0' )
- continue;
- else if ( sscanf(buf,"clear %1d",&i) == 1 )
- bset_clear(b[i]);
- else if ( sscanf(buf,"copy %1d %1d",&i,&j) == 2 )
- bset_copy(b[i],b[j]);
- else if ( sscanf(buf,"equal %1d %1d",&i,&j) == 2 )
- printf("%s\n",(bset_equal(b[i],b[j]) ? "yes" : "no"));
- else if ( sscanf(buf,"empty %1d",&i) == 1 )
- printf("%s\n",(bset_empty(b[i]) ? "yes" : "no"));
- else if ( sscanf(buf,"size %1d",&i) == 1 )
- printf("%d\n",bset_size(b[i]));
- else if ( sscanf(buf,"dump %1d",&i) == 1 )
- bset_dump(b[i]);
- else if ( sscanf(buf,"set %1d %d",&i,&num) == 2 )
- bset_set(b[i],num);
- else if ( sscanf(buf,"clr %1d %d",&i,&num) == 2 )
- bset_clr(b[i],num);
- else if ( sscanf(buf,"invert %1d %d",&i,&num) == 2 )
- bset_invert(b[i],num);
- else if ( sscanf(buf,"test %1d %d",&i,&num) == 2 )
- printf("%s\n",( bset_test(b[i],num) ? "yes" : "no" ));
- else if ( strncmp(buf,"quit",4) == 0 )
- break;
- else
- printf("Mistake\n");
- }
-
- printf("Deleting b[0-9]\n");
- for ( i = 0; i < 10; ++i )
- bset_free(b[i]);
-
- return 0;
- }
-
- #endif
-