Commit | Line | Data |
---|---|---|
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 | |
12 | static 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 | */ | |
36 | void | |
37 | append(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 | */ | |
128 | void | |
129 | rd_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 | */ | |
150 | void | |
151 | concat(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 | } |