#include #define IDX signed long #define byte unsigned char char *inname = NULL, *outname = NULL; FILE *in, *out; IDX fields = 0; int fieldlen = 0; byte *(*readptr)(IDX); void (*interchange)(IDX, IDX); byte *buf; /* for in-memory sorting */ byte *bufa, *bufb; /* Error routines */ void error(char *msg) { fputs(msg, stderr); fputs("\n", stderr); exit(1); } void fileerr(char *fname) { perror(fname); exit(1); } void readerr() { if (ferror(in)) fileerr(inname); fputs("Error reading from ", stderr); fputs(inname, stderr); fputs("\n", stderr); exit(1); } void writeerr() { if (ferror(out)) fileerr(outname); fputs("Error writing to ", stderr); fputs(outname, stderr); fputs("\n", stderr); exit(1); } void usage() { error("Usage: sort fieldlength input-file [output-file] [options]\n" "where 'options' are:\n" " -f sort in file\n" " -i ignore excess bytes\n" " -m sort in memory [default]\n" " -r replace input file\n" ); } /* Converts a field index to a pointer into the buffer. */ byte *memptr(IDX i) { return buf + (fieldlen * i); } byte *currentbuf = NULL; /* Reads a field from disk into a buffer. Alternates between two static buffers, so you can deal with two fields at once. */ byte *fileptr(IDX i) { if (currentbuf == bufa) currentbuf = bufb; else currentbuf = bufa; if (fseek(in, fieldlen*i, SEEK_SET)) fileerr(inname); if (!fread(currentbuf, fieldlen, 1, in)) readerr(); return currentbuf; } /* Swaps fields a and b in the buffer. */ void mem_interchange(IDX a, IDX b) { register byte *ap = memptr(a); register byte *bp = memptr(b); register byte temp; register int c; for (c=0; c= field b), 0 otherwise */ int compare(IDX a, IDX b) { if (a >= fields) return 1; else if (b >= fields) return 0; else { register byte *ap = (*readptr)(a); register byte *bp = (*readptr)(b); register int c; for (c=0; c *bp) return 1; ap++; bp++; } } return 1; } int partition(IDX m, IDX p) { IDX i = m; while (1) { do i++; while (!compare(i, m)); do p--; while (!compare(m, p)); if (i < p) (*interchange)(i, p); else break; } (*interchange)(m, p); return p; } void quicksort(IDX p, IDX q) { if (p < q) { IDX j = q+1; j = partition(p, j); quicksort(p, j-1); quicksort(j+1, q); } } #define INPLACE 1 #define IGNORE 2 #define REPLACE 4 void main(int argc, char **argv) { int i; char *p; int flags = 0; long flen, done; /* read the command-line arguments */ for (i=1; i