xref: /csrg-svn/contrib/sort/append.c (revision 62247)
160901Sbostic /*-
2*62247Sbostic  * Copyright (c) 1993
3*62247Sbostic  *	The Regents of the University of California.  All rights reserved.
460901Sbostic  *
560901Sbostic  * This code is derived from software contributed to Berkeley by
660901Sbostic  * Peter McIlroy.
760901Sbostic  *
860901Sbostic  * %sccs.include.redist.c%
960901Sbostic  */
1060901Sbostic 
1160901Sbostic #ifndef lint
12*62247Sbostic static char sccsid[] = "@(#)append.c	8.1 (Berkeley) 06/06/93";
1360901Sbostic #endif /* not lint */
1460901Sbostic 
1560901Sbostic #include "sort.h"
1660901Sbostic 
1760901Sbostic #include <stdlib.h>
1860901Sbostic #include <string.h>
1960901Sbostic 
2060901Sbostic #define OUTPUT {							\
2160901Sbostic 	if ((n = cpos - ppos) > 1) {					\
2260901Sbostic 		for (; ppos < cpos; ++ppos)				\
2360901Sbostic 			*ppos -= odepth;				\
2460901Sbostic 		ppos -= n;						\
2560901Sbostic 		radixsort(ppos, n, wts1, REC_D);			\
2660901Sbostic 		for (; ppos < cpos; ppos++) {				\
2760901Sbostic 			prec = (RECHEADER *) (*ppos - sizeof(TRECHEADER));\
2860901Sbostic 			put(prec, fd);					\
2960901Sbostic 		}							\
3060901Sbostic 	} else put(prec, fd);						\
3160901Sbostic }
3260901Sbostic 
3360901Sbostic /*
3460901Sbostic  * copy sorted lines to output; check for uniqueness
3560901Sbostic  */
3660901Sbostic void
append(keylist,nelem,depth,fd,put,ftbl)3760901Sbostic append(keylist, nelem, depth, fd, put, ftbl)
3860901Sbostic 	u_char **keylist;
3960901Sbostic 	int nelem;
4060901Sbostic 	register int depth;
4160901Sbostic 	FILE *fd;
4260901Sbostic 	void (*put)(RECHEADER *, FILE *);
4360901Sbostic 	struct field *ftbl;
4460901Sbostic {
4560901Sbostic 	register u_char *wts, *wts1;
4660901Sbostic 	register n, odepth;
4760901Sbostic 	register u_char **cpos, **ppos, **lastkey;
4860901Sbostic 	register u_char *cend, *pend, *start;
4960901Sbostic 	register struct recheader *crec, *prec;
5060901Sbostic 
5160929Sbostic 	if (*keylist == '\0' && UNIQUE)
5260929Sbostic 		return;
5360901Sbostic 	wts1 = wts = ftbl[0].weights;
5460901Sbostic 	if ((!UNIQUE) && SINGL_FLD) {
5560901Sbostic 		if (ftbl[0].flags & F && ftbl[0].flags & R)
5660901Sbostic 			wts1 = Rascii;
5760901Sbostic 		else if (ftbl[0].flags & F)
5860901Sbostic 			wts1 = ascii;
5960901Sbostic 		odepth = depth;
6060901Sbostic 	}
6160901Sbostic 	lastkey = keylist + nelem;
6260901Sbostic 	depth += sizeof(TRECHEADER);
6360901Sbostic 	if (SINGL_FLD && (UNIQUE || wts1 != wts)) {
6460901Sbostic 		ppos = keylist;
6560901Sbostic 		prec = (RECHEADER *) (*ppos - depth);
6660901Sbostic 		if (UNIQUE)
6760901Sbostic 			put(prec, fd);
6860901Sbostic 		for (cpos = keylist+1; cpos < lastkey; cpos++) {
6960901Sbostic 			crec = (RECHEADER *) (*cpos - depth);
7060901Sbostic 			if (crec->length  == prec->length) {
7160901Sbostic 				pend = (u_char *) &prec->offset + prec->length;
7260901Sbostic 				cend = (u_char *) &crec->offset + crec->length;
7360901Sbostic 				for (start = *cpos; cend >= start; cend--) {
7460901Sbostic 					if (wts[*cend] != wts[*pend])
7560901Sbostic 						break;
7660901Sbostic 					pend--;
7760901Sbostic 				}
7860901Sbostic 				if (pend + 1 != *ppos) {
7960901Sbostic 					if (!UNIQUE) {
8060901Sbostic 						OUTPUT;
8160901Sbostic 					} else
8260901Sbostic 						put(crec, fd);
8360901Sbostic 					ppos = cpos;
8460901Sbostic 					prec = crec;
8560901Sbostic 				}
8660901Sbostic 			} else {
8760901Sbostic 				if (!UNIQUE) {
8860901Sbostic 					OUTPUT;
8960901Sbostic 				} else
9060901Sbostic 					put(crec, fd);
9160901Sbostic 				ppos = cpos;
9260901Sbostic 				prec = crec;
9360901Sbostic 			}
9460901Sbostic 		}
9560901Sbostic 		if (!UNIQUE)  { OUTPUT; }
9660901Sbostic 	} else if (UNIQUE) {
9760901Sbostic 		ppos = keylist;
9860901Sbostic 		prec = (RECHEADER *) (*ppos - depth);
9960901Sbostic 		put(prec, fd);
10060901Sbostic 		for (cpos = keylist+1; cpos < lastkey; cpos++) {
10160901Sbostic 			crec = (RECHEADER *) (*cpos - depth);
10260901Sbostic 			if (crec->offset == prec->offset) {
10360901Sbostic 				pend = (u_char *) &prec->offset + prec->offset;
10460901Sbostic 				cend = (u_char *) &crec->offset + crec->offset;
10560901Sbostic 				for (start = *cpos; cend >= start; cend--) {
10660901Sbostic 					if (wts[*cend] != wts[*pend])
10760901Sbostic 						break;
10860901Sbostic 					pend--;
10960901Sbostic 				}
11060901Sbostic 				if (pend + 1 != *ppos) {
11160901Sbostic 					ppos = cpos;
11260901Sbostic 					prec = crec;
11360901Sbostic 					put(prec, fd);
11460901Sbostic 				}
11560901Sbostic 			} else {
11660901Sbostic 				ppos = cpos;
11760901Sbostic 				prec = crec;
11860901Sbostic 				put(prec, fd);
11960901Sbostic 			}
12060901Sbostic 		}
12160901Sbostic 	} else for (cpos = keylist; cpos < lastkey; cpos++) {
12260901Sbostic 		crec = (RECHEADER *) (*cpos - depth);
12360901Sbostic 		put(crec, fd);
12460901Sbostic 	}
12560901Sbostic }
12660901Sbostic 
12760901Sbostic /*
12860901Sbostic  * output the already sorted eol bin.
12960901Sbostic  */
13060901Sbostic void
rd_append(binno,infl0,nfiles,outfd,buffer,bufend)13160901Sbostic rd_append(binno, infl0, nfiles, outfd, buffer, bufend)
13260901Sbostic 	u_char *buffer, *bufend;
13360901Sbostic 	int binno, nfiles;
13460901Sbostic 	union f_handle infl0;
13560901Sbostic 	FILE *outfd;
13660901Sbostic {
13760901Sbostic 	struct recheader *rec;
13860901Sbostic 	rec = (RECHEADER *) buffer;
13960901Sbostic 	if (!getnext(binno, infl0, nfiles, (RECHEADER *) buffer, bufend, 0)) {
14060901Sbostic 		putline(rec, outfd);
14160901Sbostic 		while (getnext(binno, infl0, nfiles, (RECHEADER *) buffer,
14260901Sbostic 			bufend, 0) == 0) {
14360901Sbostic 			if (!UNIQUE)
14460901Sbostic 				putline(rec, outfd);
14560901Sbostic 		}
14660901Sbostic 	}
14760901Sbostic }
14860901Sbostic 
14960901Sbostic /*
15060901Sbostic  * append plain text--used after sorting the biggest bin.
15160901Sbostic  */
15260901Sbostic void
concat(a,b)15360901Sbostic concat(a, b)
15460901Sbostic 	FILE *a, *b;
15560901Sbostic {
15660901Sbostic         int nread;
15760901Sbostic         char buffer[4096];
15860901Sbostic 
15960901Sbostic 	rewind(b);
16060901Sbostic         while ((nread = fread(buffer, 1, 4096, b)) > 0)
16160901Sbostic                 EWRITE(buffer, 1, nread, a);
16260901Sbostic }
163