#include #include static unsigned long itemsize = 0; //size of each element in bytes static unsigned long nitems = 0; //items in our array static unsigned long totalsize = 0; //total number of bytes of stuff we've got static unsigned long rawbufsize = 0; //size of our input buffer static void* rawbuf = NULL; //our raw input buffer void memcheck(void* ptr); int bincmp(void* a, void* b); int main(int argc, char** argv) { if(argc != 2) { fprintf(stderr, "Usage: binsort N\n\tWhere N is the number of bytes per entry\n"); exit(1); } itemsize = strtoul(argv[1], NULL, 10); if(itemsize <= 0) { fprintf(stderr, "binsort: Invalid element size given. Aborting."); exit(1); } //let's start with, oh 1KB of input space. //the size of each record doesn't matter yet. we'll chop it up properly later. rawbuf = calloc(1024, 1); memcheck(rawbuf); rawbufsize = 1024; totalsize = fread(rawbuf, 1, (size_t)rawbufsize, stdin); //read more if we need to while(totalsize == rawbufsize) { //we're out of buffer space. let's allocate some more. rawbuf = realloc(rawbuf, rawbufsize * 2); memcheck(rawbuf); rawbufsize *= 2; totalsize += fread(rawbuf + totalsize, 1, (size_t)(rawbufsize - totalsize), stdin); } //OK, everything's in. Make sure there's something there. if(totalsize <= 0) { fprintf(stderr, "binsort: No data given. Aborting."); exit(1); } //make sure our data is "square"; i.e. the last record is complete if(totalsize % itemsize != 0) { unsigned long newtotalsize = itemsize * ((totalsize / itemsize) + 1); if(rawbufsize < newtotalsize) { //ugh. the buffer isn't large enough to square up our data. fix it. rawbuf = realloc(rawbuf, newtotalsize); memcheck(rawbuf); rawbufsize = newtotalsize; } //fill in zeros to pad the last item while(totalsize < newtotalsize) { //FIXME: Write one 0 byte at a time (how?) ++totalsize; } } nitems = totalsize / itemsize; //sort it! qsort(rawbuf, (size_t)nitems, (size_t)itemsize, bincmp); //spit out the result unsigned long nout = fwrite(rawbuf, (size_t)itemsize, (size_t)nitems, stdout); if(nout < nitems) { fprintf(stderr, "binsort: Write error. Aborting."); exit(1); } exit(0); return 0; } int bincmp(void* a, void* b) { return memcmp(a, b, (size_t)itemsize); } void memcheck(void* ptr) { if(ptr == NULL) { fprintf(stderr, "binsort: Memory error. Aborting."); exit(1); } }