/*	BITMAP.C	makebitmap, setbit, testbit: bit map manipulation
 *			routines.
 *
 *	Copyright (c) 1985, Allen I. Holub, all rights reserved.
 *	This program may be copied for personal, non-profit use only.
 */

extern char *calloc(unsigned, unsigned);



#ifdef DEBUG
    #include <stdio.h>
#endif 

typedef char BITMAP;

/*----------------------------------------------------------------------*/

BITMAP *makebitmap(size)unsigned size;
{
    /*	Make a bit map with "size" bits. The first entry in
     *	the map is an  unsigned int representing the maximum
     *	bit. The map itself is concatenated to this integer.
     *	Return a pointer to the map on success, 0 if there's
     *	not enough memory.
     */

    unsigned *map, numbytes;

    numbytes = (size >> 3) + ((size &0x07) ? 1 : 0);

    #ifdef DEBUG
        printf("Making a %d bit map (%d bytes required)\n", size, numbytes);
    #endif 

    if (map = (unsigned*)calloc(numbytes + sizeof(unsigned), 1))
        *map = size;

    return (BITMAP*)map;
}

//-------------------------------------------------------------------------

setbit(c, map, val)unsigned c, val;
char *map;
{
    /*   Set bit c in the map to val.
     *   If c > map size, 0 is returned, else 1 is returned.
     */

    if (c >= *(unsigned*)map)
     /* if c >= map size */
        return 0;

    map += sizeof(unsigned); /* Skip past size   */

    if (val)
        map[c >> 3] |= 1 << (c &0x07);
    else
        map[c >> 3] &= ~(1 << (c &0x07));

    return (1);
}


/* ------------------------------------------------------------------- */


testbit(c, map)unsigned c;
char *map;
{
    /*   Return 1 if the bit corresponding to c in map is set.
     *   0 if it is not.
     */

    if (c >= *(unsigned*)map)
        return 0;

    map += sizeof(unsigned);

    return (map[c >> 3] &(1 << (c &0x07)));
}

//-------------------------------------------------------------------------

#ifdef DEBUG

    main()
    {
        int bitnum, set, i,  *map;

        printf("Making a 32 bit wide bit map\n");

        if (!(map = makebitmap(32)))
            printf("Can't make map\n");

        while (1)
        {
            /* Print the bit map. Try to print past the end of the
             * map to make sure overflow detection works (bit 32 should
             * come back as a 0).
             */

            for (i = 0; i <= 32; i++)
                putchar(testbit(i, map) ? 'X' : '.');

            printf("\n\nBit number :");
            scanf("%d", &bitnum);
            printf("\n1 to set, 0 to clear: ");
            scanf("%d", &set);

            if (!setbit(bitnum, map, set))
                printf("Bit out of range\n");
        }
    }

#endif