home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 4
/
DATAFILE_PDCD4.iso
/
unix
/
unixtools
/
util
/
c
/
bitset
< prev
next >
Wrap
Text File
|
1992-07-21
|
6KB
|
250 lines
/* > 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