home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource3
/
195_01
/
sort.c
< prev
next >
Wrap
Text File
|
1987-10-05
|
8KB
|
412 lines
/* [SORT.C of JUGPDS Vol.18]
*****************************************************************
* *
* Written by Hakuo Katayose (JUG-CP/M No.179) *
* 49-114 Kawauchi-Sanjuunin-machi *
* Sendai, Miyagi 980 *
* Phone: 0222-61-3219 *
* *
* Edited & tested by Y. Monma (JUG-C/M Disk Editor) *
* *
*****************************************************************
*/
/* sort - sort and merge */
#include "stdio.h"
#include "def.h"
#include <dio.h>
#define LINES 2000
#define MAXLEN 128
#define MAXBUF 16
#define MERGEORDER 7
char allocbuf[1024][MAXBUF], *alloc_bp, *alloc_ep;
char opt_d; /* dictionary order */
char opt_f; /* fold order */
char opt_n; /* numeric order */
char opt_l; /* line_no listing */
char opt_r; /* reverse order */
main(argc, argv)
int argc;
char *argv[];
{
char *ap;
int i;
dioinit(&argc, argv);
if (argc <3) {
error("Usage: sort -{dfnlr} file1 file2 ... >outfile");
exit();
}
else
opt_d = opt_f = opt_n = opt_l = opt_r = OFF;
i = 0;
while (--argc > 0 && (*++argv)[0] == '-')
for (ap = argv[0]+1; *ap != '\0'; ap++)
switch (tolower(*ap)) {
case 'd':
opt_d = ON;
break;
case 'f':
opt_f = ON;
break;
case 'n':
opt_n = ON;
break;
case 'l' :
opt_l = ON;
break;
case 'r':
opt_r = ON;
break;
}
FileSort();
dioflush();
}
FileSort()
{
char fname[15], *lineptr[LINES], opt_ll;
int nlines, t, high, low, lim;
FILE infp[MERGEORDER], outfp;
high = 0;
t = Gtext(lineptr, &nlines, LINES, STDIN);
Sort(lineptr, nlines);
if (t == EOF) {
Ptext(lineptr, nlines, STDOUT);
return;
}
opt_ll = opt_l;
opt_l = OFF;
MakeFile(high, &outfp);
Ptext(lineptr, nlines, &outfp);
putc(CPMEOF, &outfp);
fclose(&outfp);
while (t != EOF) {
t = Gtext(lineptr, &nlines, LINES, STDIN);
Sort(lineptr, nlines);
MakeFile(++high, &outfp);
Ptext(lineptr, nlines, &outfp);
putc(CPMEOF, &outfp);
fclose(&outfp);
}
opt_l = opt_ll;
for (low = 0; low <= high; low += MERGEORDER) {
lim = min(low + MERGEORDER - 1, high);
Gopen(infp, low, lim);
MakeFile(++high, &outfp);
Merge(infp, lim-low+1, &outfp);
putc(CPMEOF, &outfp);
fclose(&outfp);
Gremove(infp, low, lim);
}
sprintf(fname, "stemp.%d", high);
if (fopen(fname, infp) == ERROR) {
fprintf(STDERR, "file not open: %s\n", fname);
exit();
}
Fcopy(infp, STDOUT);
fclose(infp);
unlink(fname);
}
MakeFile(fno, fp)
FILE *fp;
{
char fname[15];
sprintf(fname, "stemp.%d", fno);
if (fcreat(fname, fp) == ERROR) {
fprintf(STDERR, "file not creat: %s\n", fname);
exit();
}
}
Fcopy(inbuf, outbuf)
FILE *inbuf, *outbuf;
{
int c, lno;
lno = 1;
while (fgetlin(inbuf, allocbuf, MAXLEN) > 0) {
if( opt_l == ON )
fputdec(outbuf, lno++, 6);
fputlin(outbuf, allocbuf);
if (outbuf != STDOUT)
putch(NEWLINE, outbuf);
}
}
Gopen(fp, low, lim)
FILE fp[];
{
int i;
char fname[15];
for (i = 0; i < lim - low + 1; i++) {
sprintf(fname, "stemp.%d", low + i);
if (fopen(fname, fp[i]) == ERROR) {
fprintf(STDERR, "file not open: %s\n", fname);
exit();
}
}
}
Gremove(fp, low, lim)
FILE fp[];
{
char fname[15];
int i;
for (i = 0; i < lim - low + 1; i++) {
putc(CPMEOF, fp[i]);
fclose(fp[i]);
sprintf(fname, "stemp.%d", low + i);
unlink(fname);
}
}
/* merge - merge infile(1)...infile(nfiles) onto outfile */
Merge(infile, nfiles, outfile)
FILE infile[], *outfile;
{
char *lineptr[MERGEORDER], *p;
int i, nl, inf, len;
int strdfcmp(), strfcmp(), strcmp(), strdcmp(), numcmp(), swap();
p = alloc_bp = allocbuf;
for (nl = 0, i = 0; i < nfiles; i++)
if ((len = fgetlin(infile[i], alloc_bp, MAXLEN)) > 0) {
*(alloc_bp + len - 1) = '\0';
lineptr[nl++] = alloc_bp;
alloc_bp += MAXLINE;
}
Sort(lineptr, nl--);
while (nl >= 0) {
fputlin(outfile, lineptr[0]);
putch(NEWLINE, outfile);
inf = (lineptr[0] - p) / MAXLINE;
if ((len =fgetlin(infile[inf], lineptr[0], MAXLEN)) <= 0)
lineptr[0] = lineptr[nl--];
else
*(lineptr[0] + len - 1) = '\0';
if (opt_n == ON)
reheap(lineptr, nl, numcmp, swap);
else if (opt_d == ON && opt_f == ON)
reheap(lineptr, nl, strdfcmp, swap);
else if (opt_d == ON)
reheap(lineptr, nl, strdcmp, swap);
else if (opt_f == ON)
reheap(lineptr, nl, strfcmp, swap);
else
reheap(lineptr, nl, strcmp, swap);
}
}
/* reheap - propagat inbuf(lineptr(1)) to proper place in heap */
reheap(lineptr, nl, comp, exch)
char *lineptr[];
int (*comp)(), (*exch)();
{
int i, f;
char *p;
for (i = 1; i <= nl; i++) {
f = (*comp)(lineptr[i-1], lineptr[i]);
if (opt_r == ON && f >= 0)
break;
else if (opt_r==OFF && f <= 0)
break;
(*exch)(&lineptr[i-1], &lineptr[i]);
}
}
Sort(lineptr, nlines)
char *lineptr[];
{
int strdfcmp(), strfcmp(), strcmp(), strdcmp(), numcmp(), swap();
if (opt_n == ON)
quick(lineptr, 0, nlines-1, numcmp, swap);
else if (opt_d == ON && opt_f == ON)
quick(lineptr, 0, nlines-1, strdfcmp, swap);
else if (opt_d == ON)
quick(lineptr, 0, nlines-1, strdcmp, swap);
else if (opt_f == ON)
quick(lineptr, 0, nlines-1, strfcmp, swap);
else
quick(lineptr, 0, nlines-1, strcmp, swap);
}
/* quick - quicksort for character lines */
quick(v, l, r, comp, exch)
char *v[];
int l, r;
int (*comp)(), (*exch)();
{
int vx, i, j;
i = l; j = r;
vx = v[ (l+r)/2 ];
while(i <= j) {
while( (*comp)(v[i], vx) < 0 )
i++;
while( (*comp)(vx, v[j]) < 0 )
j--;
if(i <= j) {
(*exch)(&v[j], &v[i]);
i++;
j--;
}
}
if(l < j) quick(v, l, j, comp, exch);
if(i < r) quick(v, i, r, comp, exch);
}
numcmp(s1, s2)
char *s1, *s2;
{
int atoi(), v1, v2;
v1 = atoi(s1);
v2 = atoi(s2);
if (v1 < v2)
return(-1);
else if (v1 > v2)
return(1);
else
return(0);
}
Gtext(lineptr, nlines, maxlines, fp)
char *lineptr[];
int *nlines;
FILE *fp;
{
int len;
*nlines = 0;
alloc_bp = allocbuf;
alloc_ep = &allocbuf[1023][(MAXBUF-1)];
do {
if ((len = fgetlin(fp, alloc_bp, MAXLEN)) <= 0)
return EOF;
lineptr[(*nlines)++] = alloc_bp;
alloc_bp += len;
*(alloc_bp - 1) = '\0';
} while (alloc_bp + MAXLEN <= alloc_ep && *nlines < maxlines);
return(len);
}
Ptext(lineptr, nlines, fp)
char *lineptr[];
int nlines;
FILE *fp;
{
int lno;
lno = 1;
if (opt_r == ON) lineptr += nlines;
while (nlines--) {
if (opt_l == ON)
fputdec(fp, lno++, 6);
fputlin(fp, (opt_r == ON ? *--lineptr : *lineptr++));
putch(NEWLINE, fp);
}
}
/* fputdec - put decimal integer in field width >= w for FILE *fp */
fputdec(fp, n, w)
FILE *fp;
{
char s[64], itoa();
int len;
len = strlen(itoa(s,n));
if ((len = w - len) > 0)
while (len--)
putch(BLANK, fp);
fputlin(fp, s);
putch(':', fp);
}
fputlin(fp, s)
char *s;
FILE *fp;
{
while (*s)
putch(*s++, fp);
}
putch(c,fp)
FILE *fp;
{
if (fp == STDOUT)
putchar(c);
else {
if (c == NEWLINE)
putc(CRETURN, fp);
putc(c, fp);
}
}
fgetlin(fp, s, lim)
char *s;
int lim;
{
char *p;
int c;
p = s;
while (--lim > 0 && (c = getch(fp)) != EOF && c != NEWLINE)
*s++ = c;
if(c == NEWLINE)
*s++ = c;
*s = '\0';
return(s-p);
}
getch(fp)
FILE *fp;
{
int c;
if (fp == STDIN)
return getchar();
else {
if ((c = getc(fp)) == CRETURN)
return getch(fp);
if (c == CPMEOF || c == EOF)
c = EOF;
return c;
}
}