#include<stdlib.h>
#include<stdio.h>
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);
}
}