1 /*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/06/93"; 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 if (*keylist == '\0' && UNIQUE) 52 return; 53 wts1 = wts = ftbl[0].weights; 54 if ((!UNIQUE) && SINGL_FLD) { 55 if (ftbl[0].flags & F && ftbl[0].flags & R) 56 wts1 = Rascii; 57 else if (ftbl[0].flags & F) 58 wts1 = ascii; 59 odepth = depth; 60 } 61 lastkey = keylist + nelem; 62 depth += sizeof(TRECHEADER); 63 if (SINGL_FLD && (UNIQUE || wts1 != wts)) { 64 ppos = keylist; 65 prec = (RECHEADER *) (*ppos - depth); 66 if (UNIQUE) 67 put(prec, fd); 68 for (cpos = keylist+1; cpos < lastkey; cpos++) { 69 crec = (RECHEADER *) (*cpos - depth); 70 if (crec->length == prec->length) { 71 pend = (u_char *) &prec->offset + prec->length; 72 cend = (u_char *) &crec->offset + crec->length; 73 for (start = *cpos; cend >= start; cend--) { 74 if (wts[*cend] != wts[*pend]) 75 break; 76 pend--; 77 } 78 if (pend + 1 != *ppos) { 79 if (!UNIQUE) { 80 OUTPUT; 81 } else 82 put(crec, fd); 83 ppos = cpos; 84 prec = crec; 85 } 86 } else { 87 if (!UNIQUE) { 88 OUTPUT; 89 } else 90 put(crec, fd); 91 ppos = cpos; 92 prec = crec; 93 } 94 } 95 if (!UNIQUE) { OUTPUT; } 96 } else if (UNIQUE) { 97 ppos = keylist; 98 prec = (RECHEADER *) (*ppos - depth); 99 put(prec, fd); 100 for (cpos = keylist+1; cpos < lastkey; cpos++) { 101 crec = (RECHEADER *) (*cpos - depth); 102 if (crec->offset == prec->offset) { 103 pend = (u_char *) &prec->offset + prec->offset; 104 cend = (u_char *) &crec->offset + crec->offset; 105 for (start = *cpos; cend >= start; cend--) { 106 if (wts[*cend] != wts[*pend]) 107 break; 108 pend--; 109 } 110 if (pend + 1 != *ppos) { 111 ppos = cpos; 112 prec = crec; 113 put(prec, fd); 114 } 115 } else { 116 ppos = cpos; 117 prec = crec; 118 put(prec, fd); 119 } 120 } 121 } else for (cpos = keylist; cpos < lastkey; cpos++) { 122 crec = (RECHEADER *) (*cpos - depth); 123 put(crec, fd); 124 } 125 } 126 127 /* 128 * output the already sorted eol bin. 129 */ 130 void 131 rd_append(binno, infl0, nfiles, outfd, buffer, bufend) 132 u_char *buffer, *bufend; 133 int binno, nfiles; 134 union f_handle infl0; 135 FILE *outfd; 136 { 137 struct recheader *rec; 138 rec = (RECHEADER *) buffer; 139 if (!getnext(binno, infl0, nfiles, (RECHEADER *) buffer, bufend, 0)) { 140 putline(rec, outfd); 141 while (getnext(binno, infl0, nfiles, (RECHEADER *) buffer, 142 bufend, 0) == 0) { 143 if (!UNIQUE) 144 putline(rec, outfd); 145 } 146 } 147 } 148 149 /* 150 * append plain text--used after sorting the biggest bin. 151 */ 152 void 153 concat(a, b) 154 FILE *a, *b; 155 { 156 int nread; 157 char buffer[4096]; 158 159 rewind(b); 160 while ((nread = fread(buffer, 1, 4096, b)) > 0) 161 EWRITE(buffer, 1, nread, a); 162 } 163