| 3180 | the output file is standard output. */ |
| 3181 | |
| 3182 | static void |
| 3183 | mergefps (struct sortfile *files, size_t ntemps, size_t nfiles, |
| 3184 | FILE *ofp, char const *output_file, FILE **fps) |
| 3185 | { |
| 3186 | struct buffer *buffer = xnmalloc (nfiles, sizeof *buffer); |
| 3187 | /* Input buffers for each file. */ |
| 3188 | struct line saved; /* Saved line storage for unique check. */ |
| 3189 | struct line const *savedline = NULL; |
| 3190 | /* &saved if there is a saved line. */ |
| 3191 | size_t savealloc = 0; /* Size allocated for the saved line. */ |
| 3192 | struct line const **cur = xnmalloc (nfiles, sizeof *cur); |
| 3193 | /* Current line in each line table. */ |
| 3194 | struct line const **base = xnmalloc (nfiles, sizeof *base); |
| 3195 | /* Base of each line table. */ |
| 3196 | size_t *ord = xnmalloc (nfiles, sizeof *ord); |
| 3197 | /* Table representing a permutation of fps, |
| 3198 | such that cur[ord[0]] is the smallest line |
| 3199 | and will be next output. */ |
| 3200 | size_t t; |
| 3201 | struct keyfield const *key = keylist; |
| 3202 | saved.text = NULL; |
| 3203 | |
| 3204 | /* Read initial lines from each input file. */ |
| 3205 | for (size_t i = 0; i < nfiles; ) |
| 3206 | { |
| 3207 | initbuf (&buffer[i], sizeof (struct line), |
| 3208 | MAX (merge_buffer_size, sort_size / nfiles)); |
| 3209 | if (fillbuf (&buffer[i], fps[i], files[i].name)) |
| 3210 | { |
| 3211 | struct line const *linelim = buffer_linelim (&buffer[i]); |
| 3212 | cur[i] = linelim - 1; |
| 3213 | base[i] = linelim - buffer[i].nlines; |
| 3214 | i++; |
| 3215 | } |
| 3216 | else |
| 3217 | { |
| 3218 | /* fps[i] is empty; eliminate it from future consideration. */ |
| 3219 | xfclose (fps[i], files[i].name); |
| 3220 | if (i < ntemps) |
| 3221 | { |
| 3222 | ntemps--; |
| 3223 | zaptemp (files[i].name); |
| 3224 | } |
| 3225 | free (buffer[i].buf); |
| 3226 | --nfiles; |
| 3227 | for (size_t j = i; j < nfiles; ++j) |
| 3228 | { |
| 3229 | files[j] = files[j + 1]; |
| 3230 | fps[j] = fps[j + 1]; |
| 3231 | } |
| 3232 | } |
| 3233 | } |
| 3234 | |
| 3235 | /* Set up the ord table according to comparisons among input lines. |
| 3236 | Since this only reorders two items if one is strictly greater than |
| 3237 | the other, it is stable. */ |
| 3238 | for (size_t i = 0; i < nfiles; ++i) |
| 3239 | ord[i] = i; |
no test coverage detected