/*
This eats a MUSH 2.0 flat database, and dumps a list of attribute
numbers that are actually *used*, in order.
It assumes 8 bit chars.
It chews in the entire DB, looking for lines that start with
'>', an actual attribute header line, see. It maintains (and grows as
necessary) a bitmap (I got fancy, nyah) of attribute numbers actually
used. You must have a working realloc(). When it's done,
it walks the bitmap, spitting out a list of the attribute numbers it
found, in order. It ignores the attribute numbers under A_USER_START
from filter.h.
Finally, it writes a line on stderr indicating exactly how many
attribute numbers are used, and approximately (don't ask) how many
it found unused.
Input DB in stdout, numbers file on stdout.
*/
#define SETBIT(a,n) ( (a)[n >> 3] |= (1 << ((n) & 0x07)) )
#define CLRBIT(a,n) ( (a)[n >> 3] &= ~(1 << ((n) & 0x07)) )
#define ISSET(a,n) ( (a)[n >> 3] & (1 << ((n) & 0x07)) )
#include <stdio.h>
#include "filter.h"
char *grow_map();
main(ac,av)
int ac;
char *av[];
{
int ch;
char *bitmap;
int size = 0;
int i,used,avail;
int newsize;
int attrnum;
int got_attrcount = 0;
/* Get an initial bitmap and zero it */
size = 16;
bitmap = (char *)malloc(size >> 3);
if(!bitmap){
fprintf(stderr,"Initial malloc failed. Aborting.\n");
exit(1);
}
for(i=1; i < (size >> 3); i++)
bitmap[i] = (char)0;
/* Walk across stdin looking for +N and > lines. */
while((ch = getchar()) != EOF){
if(!got_attrcount && ch == '+'){
if((ch = getchar()) == 'N'){
scanf("%d",&newsize);
got_attrcount = 1;
if(newsize > size){
bitmap = grow_map(bitmap,size,newsize+64);
size = newsize+64;
}
} else {
ungetc(ch,stdin);
}
} else if(ch == '>'){
scanf("%d",&attrnum);
#ifdef DEBUG_FILT1
fprintf(stderr,"Read attrnum %d, %x\n",attrnum,
bitmap[attrnum >> 3]);
#endif
if(attrnum <= A_USER_START)
continue;
if(attrnum > size){
bitmap = grow_map(bitmap,size,attrnum+64);
size = attrnum+64;
}
SETBIT(bitmap,attrnum);
#ifdef DEBUG_FILT1
fprintf(stderr,"%x\n",
bitmap[attrnum >> 3]);
#endif
}
/* Eat up the rest of the line. */
while(ch != '\n' && ch != EOF)
ch = getchar();
}
/* Now walk across it, writing out the numbers actually used */
used = avail = 0;
for(i = 1;i <= size;i++){
if(ISSET(bitmap,i)){
used++;
fprintf(stdout,"%d\n",i);
} else {
avail++;
}
}
/* Dump stats on stderr */
fprintf(stderr,"Used attr numbers: %d, Free attr numbers (approx): %d\n",
used,avail - A_USER_START);
}
char *
grow_map(map,old,new)
char *map;
int old;
int new;
{
char *newmap;
/* Make it bigger */
newmap = (char *)realloc(map,new >> 3);
if(!newmap){
fprintf(stderr,"realloc failed growing bitmap.\n");
exit(1);
}
/* Clear new entries */
for(old++;old < new;old++)
CLRBIT(newmap,old);
return(newmap);
}