/* 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); }