date and time created 93/06/01 16:44:56 by bostic
[unix-history] / usr / src / contrib / sort / append.c
CommitLineData
acf7f35e
KB
1/*-
2 * Copyright (c) 1993 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy.
7 *
8 * %sccs.include.redist.c%
9 */
10
11#ifndef lint
12static char sccsid[] = "@(#)append.c 5.1 (Berkeley) %G%";
13#endif /* not lint */
14
15#include "sort.h"
16
17#include <stdlib.h>
18#include <string.h>
19
20#define OUTPUT { \
21 if ((n = cpos - ppos) > 1) { \
22 for (; ppos < cpos; ++ppos) \
23 *ppos -= odepth; \
24 ppos -= n; \
25 radixsort(ppos, n, wts1, REC_D); \
26 for (; ppos < cpos; ppos++) { \
27 prec = (RECHEADER *) (*ppos - sizeof(TRECHEADER));\
28 put(prec, fd); \
29 } \
30 } else put(prec, fd); \
31}
32
33/*
34 * copy sorted lines to output; check for uniqueness
35 */
36void
37append(keylist, nelem, depth, fd, put, ftbl)
38 u_char **keylist;
39 int nelem;
40 register int depth;
41 FILE *fd;
42 void (*put)(RECHEADER *, FILE *);
43 struct field *ftbl;
44{
45 register u_char *wts, *wts1;
46 register n, odepth;
47 register u_char **cpos, **ppos, **lastkey;
48 register u_char *cend, *pend, *start;
49 register struct recheader *crec, *prec;
50
51 wts1 = wts = ftbl[0].weights;
52 if ((!UNIQUE) && SINGL_FLD) {
53 if (ftbl[0].flags & F && ftbl[0].flags & R)
54 wts1 = Rascii;
55 else if (ftbl[0].flags & F)
56 wts1 = ascii;
57 odepth = depth;
58 }
59 lastkey = keylist + nelem;
60 depth += sizeof(TRECHEADER);
61 if (SINGL_FLD && (UNIQUE || wts1 != wts)) {
62 ppos = keylist;
63 prec = (RECHEADER *) (*ppos - depth);
64 if (UNIQUE)
65 put(prec, fd);
66 for (cpos = keylist+1; cpos < lastkey; cpos++) {
67 crec = (RECHEADER *) (*cpos - depth);
68 if (crec->length == prec->length) {
69 pend = (u_char *) &prec->offset + prec->length;
70 cend = (u_char *) &crec->offset + crec->length;
71 for (start = *cpos; cend >= start; cend--) {
72 if (wts[*cend] != wts[*pend])
73 break;
74 pend--;
75 }
76 if (pend + 1 != *ppos) {
77 if (!UNIQUE) {
78 OUTPUT;
79 } else
80 put(crec, fd);
81 ppos = cpos;
82 prec = crec;
83 }
84 } else {
85 if (!UNIQUE) {
86 OUTPUT;
87 } else
88 put(crec, fd);
89 ppos = cpos;
90 prec = crec;
91 }
92 }
93 if (!UNIQUE) { OUTPUT; }
94 } else if (UNIQUE) {
95 ppos = keylist;
96 prec = (RECHEADER *) (*ppos - depth);
97 put(prec, fd);
98 for (cpos = keylist+1; cpos < lastkey; cpos++) {
99 crec = (RECHEADER *) (*cpos - depth);
100 if (crec->offset == prec->offset) {
101 pend = (u_char *) &prec->offset + prec->offset;
102 cend = (u_char *) &crec->offset + crec->offset;
103 for (start = *cpos; cend >= start; cend--) {
104 if (wts[*cend] != wts[*pend])
105 break;
106 pend--;
107 }
108 if (pend + 1 != *ppos) {
109 ppos = cpos;
110 prec = crec;
111 put(prec, fd);
112 }
113 } else {
114 ppos = cpos;
115 prec = crec;
116 put(prec, fd);
117 }
118 }
119 } else for (cpos = keylist; cpos < lastkey; cpos++) {
120 crec = (RECHEADER *) (*cpos - depth);
121 put(crec, fd);
122 }
123}
124
125/*
126 * output the already sorted eol bin.
127 */
128void
129rd_append(binno, infl0, nfiles, outfd, buffer, bufend)
130 u_char *buffer, *bufend;
131 int binno, nfiles;
132 union f_handle infl0;
133 FILE *outfd;
134{
135 struct recheader *rec;
136 rec = (RECHEADER *) buffer;
137 if (!getnext(binno, infl0, nfiles, (RECHEADER *) buffer, bufend, 0)) {
138 putline(rec, outfd);
139 while (getnext(binno, infl0, nfiles, (RECHEADER *) buffer,
140 bufend, 0) == 0) {
141 if (!UNIQUE)
142 putline(rec, outfd);
143 }
144 }
145}
146
147/*
148 * append plain text--used after sorting the biggest bin.
149 */
150void
151concat(a, b)
152 FILE *a, *b;
153{
154 int nread;
155 char buffer[4096];
156
157 rewind(b);
158 while ((nread = fread(buffer, 1, 4096, b)) > 0)
159 EWRITE(buffer, 1, nread, a);
160}