Converted from Software Tools RATFOR to BDS C by Leor Zolman
Sep 2, 1982
Usage: sort <infile> <outfile>
Main variables have been made external; this is pretty much in
line with the RATFOR call-by-name convention anyway.
Requires lots of disk space, up to around three times the length
of the file file being sorted. This program is intended for files
bigger than memory; simpler, faster sorts can be implemented for
really short files (like ALPH.C)
-leor
#define VERBOSE 1 /* give running account of file activity */
#define MAXLINE 200 /* longest line we want to deal with */
#define NBUFS 7 /* Max number of open buffered files */
#define MAXPTR 3000 /* Max number of lines (set for dict) */
#define MERGEORDER (NBUFS-1) /* Max # of intermediate files to merge */
#define NAMESIZE 20 /* Max Filename size */
#define LOGPTR 13 /* smallest value >= log (base 2) of MAXPTR */
#define EOS '\0' /* string termination character */
#define FILE struct _buf
#define stderr 4
#define fputc putc
char name[NAMESIZE], name2[NAMESIZE + 10];
FILE buffers[NBUFS + 1]; /* up to NBUFS general-purp. buffered files */
FILE *infil[MERGEORDER + 1]; /* tmp file ptrs for sort operation */
unsigned linptr[MAXPTR + 1], nlines;
int temp;
unsigned maxtext; /* max # of chars in main text buffer */
char *linbuf; /* text area starts after this variable */
main(argc,argv)
char **argv;
{
FILE *infile, *outfile; /* main input and output streams */
FILE *tmpfile;
int makfil(), min(), gopen(), gremov();
int gtext();
unsigned high, lim, low, t;
linbuf = endext(); /* start of text buffer area */
maxtext = topofmem() - endext() - 500;
tmpfile = buffers[0];
if (argc != 3)
exit(puts("Usage: sort <infile> <outfile>\n"));
infile = buffers[1];
if (fopen(argv[1], infile) == ERROR)
{
puts("Can't open "); puts(argv[1]); exit(-1);
}
high = 0; /* Initial formation of runs: */
do {
t = gtext(infile);
quick(nlines);
high++;
makfil(high,tmpfile);
ptext(tmpfile);
fclout(tmpfile);
} while (t != NULL);
fclose(infile); /* free up the input file buffer */
gname(high, name); /* create name of result file */
infile = buffers[0];
if (fopen(name,infile) == ERROR)
{
puts("Something's screwy; I can't open ");
puts(name);
exit(-1);
}
outfile = buffers[1];
while (fcreat(argv[2],outfile) == ERROR)
{
puts("Can't create "); puts(argv[2]);
puts("\nEnter another name to call the output: ");
gets(name2);
argv[2] = &name2;
}
while (fgets(linbuf,infile))
{
fputs(linbuf,outfile);
fputs("\r\n",outfile);
}
fclout(outfile);
fabort(infile->_fd);
unlink(name);
}
lv[1] = 1;
uv[1] = nlines;
p = 1;
while (p > 0)
if (lv[p] >= uv[p]) /* only 1 element in this subset */
p--; /* pop stack */
else
{
i = lv[p] - 1;
j = uv[p];
pivlin = linptr[j]; /* pivot line */
while (i < j)
{
for (i++; compar(linptr[i],pivlin) < 0; i++)
;
for (j--; j > i; j--)
if (compar(linptr[j], pivlin) <= 0)
break;
if (i < j) /* out of order pair */
{
temp = linptr[i];
linptr[i] = linptr[j];
linptr[j] = temp;
}
}
j = uv[p]; /* move pivot to position 1 */
merge(nfiles, outfil)
FILE *outfil;
{
char *fgets();
int i, inf, lbp, lp1, nf;
lbp = 1;
nf = 0;
for (i = 1; i <= nfiles; i++) /* get one line from each file */
if (fgets(&linbuf[lbp], infil[i]) != NULL)
{
nf++;
linptr[nf] = lbp;
lbp += MAXLINE; /* leave room for largest line */
}