static void add_to_sublevel(struct sort_level *sl, struct sort_list_item *item, int indx) { struct sort_level *ssl; ssl = sl->sublevels[indx]; if (ssl == NULL) { ssl = sort_malloc(sizeof(struct sort_level)); memset(ssl, 0, sizeof(struct sort_level)); ssl->level = sl->level + 1; sl->sublevels[indx] = ssl; ++(sl->real_sln); } if (++(ssl->tosort_num) > ssl->tosort_sz) { ssl->tosort_sz = ssl->tosort_num + 128; ssl->tosort = sort_realloc(ssl->tosort, sizeof(struct sort_list_item*) * (ssl->tosort_sz)); } ssl->tosort[ssl->tosort_num - 1] = item; }
/* * Read input file names from a file (file0-from option). */ static void read_fns_from_file0(const char *fn) { if (fn) { struct file0_reader f0r; FILE *f; f = fopen(fn, "r"); if (f == NULL) err(2, NULL); memset(&f0r, 0, sizeof(f0r)); f0r.f = f; while (!feof(f)) { char *line = read_file0_line(&f0r); if (line && *line) { ++argc_from_file0; if (argc_from_file0 < 1) argc_from_file0 = 1; argv_from_file0 = sort_realloc(argv_from_file0, argc_from_file0 * sizeof(char *)); if (argv_from_file0 == NULL) err(2, NULL); argv_from_file0[argc_from_file0 - 1] = sort_strdup(line); } } closefile(f, fn); } }
static inline void add_leaf(struct sort_level *sl, struct sort_list_item *item) { if (++(sl->leaves_num) > sl->leaves_sz) { sl->leaves_sz = sl->leaves_num + 128; sl->leaves = sort_realloc(sl->leaves, (sizeof(struct sort_list_item*) * (sl->leaves_sz))); } sl->leaves[sl->leaves_num - 1] = item; }
/* * Read input file names from a file (file0-from option). */ static void read_fns_from_file0(const char *fn) { FILE *f; char *line = NULL; size_t linesize = 0; ssize_t linelen; if (fn == NULL) return; f = fopen(fn, "r"); if (f == NULL) err(2, "%s", fn); while ((linelen = getdelim(&line, &linesize, '\0', f)) != -1) { if (*line != '\0') { if (argc_from_file0 == (size_t) - 1) argc_from_file0 = 0; ++argc_from_file0; argv_from_file0 = sort_realloc(argv_from_file0, argc_from_file0 * sizeof(char *)); if (argv_from_file0 == NULL) err(2, NULL); argv_from_file0[argc_from_file0 - 1] = line; } else { free(line); } line = NULL; linesize = 0; } if (ferror(f)) err(2, "%s: getdelim", fn); closefile(f, fn); }
static void run_sort_level_next(struct sort_level *sl) { struct sort_level *slc; size_t i, sln, tosort_num; if (sl->sublevels) { sort_free(sl->sublevels); sl->sublevels = NULL; } switch (sl->tosort_num){ case 0: goto end; case (1): sl->sorted[sl->start_position] = sl->tosort[0]; sort_left_dec(1); goto end; case (2): if (list_coll_offset(&(sl->tosort[0]), &(sl->tosort[1]), sl->level) > 0) { sl->sorted[sl->start_position++] = sl->tosort[1]; sl->sorted[sl->start_position] = sl->tosort[0]; } else { sl->sorted[sl->start_position++] = sl->tosort[0]; sl->sorted[sl->start_position] = sl->tosort[1]; } sort_left_dec(2); goto end; default: if (TINY_NODE(sl) || (sl->level > 15)) { listcoll_t func; func = get_list_call_func(sl->level); sl->leaves = sl->tosort; sl->leaves_num = sl->tosort_num; sl->leaves_sz = sl->leaves_num; sl->leaves = sort_realloc(sl->leaves, (sizeof(struct sort_list_item *) * (sl->leaves_sz))); sl->tosort = NULL; sl->tosort_num = 0; sl->tosort_sz = 0; sl->sln = 0; sl->real_sln = 0; if (sort_opts_vals.sflag) { if (mergesort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) func) == -1) /* NOTREACHED */ err(2, "Radix sort error 3"); } else qsort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) func); memcpy(sl->sorted + sl->start_position, sl->leaves, sl->leaves_num * sizeof(struct sort_list_item*)); sort_left_dec(sl->leaves_num); goto end; } else { sl->tosort_sz = sl->tosort_num; sl->tosort = sort_realloc(sl->tosort, sizeof(struct sort_list_item*) * (sl->tosort_sz)); } } sl->sln = 256; sl->sublevels = sort_malloc(slsz); memset(sl->sublevels, 0, slsz); sl->real_sln = 0; tosort_num = sl->tosort_num; for (i = 0; i < tosort_num; ++i) place_item(sl, i); sort_free(sl->tosort); sl->tosort = NULL; sl->tosort_num = 0; sl->tosort_sz = 0; if (sl->leaves_num > 1) { if (keys_num > 1) { if (sort_opts_vals.sflag) { mergesort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) list_coll); } else { qsort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) list_coll); } } else if (!sort_opts_vals.sflag && sort_opts_vals.complex_sort) { qsort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) list_coll_by_str_only); } } sl->leaves_sz = sl->leaves_num; sl->leaves = sort_realloc(sl->leaves, (sizeof(struct sort_list_item *) * (sl->leaves_sz))); if (!reverse_sort) { memcpy(sl->sorted + sl->start_position, sl->leaves, sl->leaves_num * sizeof(struct sort_list_item*)); sl->start_position += sl->leaves_num; sort_left_dec(sl->leaves_num); sort_free(sl->leaves); sl->leaves = NULL; sl->leaves_num = 0; sl->leaves_sz = 0; sln = sl->sln; for (i = 0; i < sln; ++i) { slc = sl->sublevels[i]; if (slc) { slc->sorted = sl->sorted; slc->start_position = sl->start_position; sl->start_position += slc->tosort_num; if (SMALL_NODE(slc)) run_sort_level_next(slc); else push_ls(slc); sl->sublevels[i] = NULL; } } } else { size_t n; sln = sl->sln; for (i = 0; i < sln; ++i) { n = sln - i - 1; slc = sl->sublevels[n]; if (slc) { slc->sorted = sl->sorted; slc->start_position = sl->start_position; sl->start_position += slc->tosort_num; if (SMALL_NODE(slc)) run_sort_level_next(slc); else push_ls(slc); sl->sublevels[n] = NULL; } } memcpy(sl->sorted + sl->start_position, sl->leaves, sl->leaves_num * sizeof(struct sort_list_item*)); sort_left_dec(sl->leaves_num); } end: free_sort_level(sl); }
/* * Allocate and read a binary string from file. * The strings are nl-ended or zero-ended, depending on the sort setting. */ struct bwstring * bwsfgetln(FILE *f, size_t *len, bool zero_ended, struct reader_buffer *rb) { wint_t eols; eols = zero_ended ? btowc('\0') : btowc('\n'); if (!zero_ended && (MB_CUR_MAX > 1)) { wchar_t *ret; ret = fgetwln(f, len); if (ret == NULL) { if (!feof(f)) err(2, NULL); return (NULL); } if (*len > 0) { if (ret[*len - 1] == (wchar_t)eols) --(*len); } return (bwssbdup(ret, *len)); } else if (!zero_ended && (MB_CUR_MAX == 1)) { char *ret; ret = fgetln(f, len); if (ret == NULL) { if (!feof(f)) err(2, NULL); return (NULL); } if (*len > 0) { if (ret[*len - 1] == '\n') --(*len); } return (bwscsbdup((unsigned char*)ret, *len)); } else { *len = 0; if (feof(f)) return (NULL); if (2 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, sizeof(wchar_t) * rb->fgetwln_z_buffer_size); } rb->fgetwln_z_buffer[*len] = 0; if (MB_CUR_MAX == 1) while (!feof(f)) { int c; c = fgetc(f); if (c == EOF) { if (*len == 0) return (NULL); goto line_read_done; } if (c == eols) goto line_read_done; if (*len + 1 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, SIZEOF_WCHAR_STRING(rb->fgetwln_z_buffer_size)); } rb->fgetwln_z_buffer[*len] = c; rb->fgetwln_z_buffer[++(*len)] = 0; } else while (!feof(f)) { wint_t c = 0; c = fgetwc(f); if (c == WEOF) { if (*len == 0) return (NULL); goto line_read_done; } if (c == eols) goto line_read_done; if (*len + 1 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, SIZEOF_WCHAR_STRING(rb->fgetwln_z_buffer_size)); } rb->fgetwln_z_buffer[*len] = c; rb->fgetwln_z_buffer[++(*len)] = 0; } line_read_done: /* we do not count the last 0 */ return (bwssbdup(rb->fgetwln_z_buffer, *len)); } }