version 1.3, 2015/03/29 18:47:19 |
version 1.4, 2015/04/01 20:58:13 |
|
|
static size_t |
static size_t |
key_hint_size(void) |
key_hint_size(void) |
{ |
{ |
|
|
return need_hint ? sizeof(struct key_hint) : 0; |
return need_hint ? sizeof(struct key_hint) : 0; |
} |
} |
|
|
|
|
size_t |
size_t |
keys_array_size(void) |
keys_array_size(void) |
{ |
{ |
|
|
return keys_num * (sizeof(struct key_value) + key_hint_size()); |
return keys_num * (sizeof(struct key_value) + key_hint_size()); |
} |
} |
|
|
|
|
void |
void |
clean_keys_array(const struct bwstring *s, struct keys_array *ka) |
clean_keys_array(const struct bwstring *s, struct keys_array *ka) |
{ |
{ |
|
|
if (ka) { |
if (ka) { |
size_t i; |
size_t i; |
|
|
|
|
void |
void |
set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind) |
set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind) |
{ |
{ |
|
|
if (ka && keys_num > ind) { |
if (ka && keys_num > ind) { |
struct key_value *kv; |
struct key_value *kv; |
|
|
|
|
static void |
static void |
sort_list_item_make_key(struct sort_list_item *si) |
sort_list_item_make_key(struct sort_list_item *si) |
{ |
{ |
|
|
preproc(si->str, &(si->ka)); |
preproc(si->str, &(si->ka)); |
} |
} |
|
|
|
|
void |
void |
sort_list_item_set(struct sort_list_item *si, struct bwstring *str) |
sort_list_item_set(struct sort_list_item *si, struct bwstring *str) |
{ |
{ |
|
|
if (si) { |
if (si) { |
clean_keys_array(si->str, &(si->ka)); |
clean_keys_array(si->str, &(si->ka)); |
if (si->str) { |
if (si->str) { |
|
|
void |
void |
sort_list_item_clean(struct sort_list_item *si) |
sort_list_item_clean(struct sort_list_item *si) |
{ |
{ |
|
|
if (si) { |
if (si) { |
clean_keys_array(si->str, &(si->ka)); |
clean_keys_array(si->str, &(si->ka)); |
if (si->str) { |
if (si->str) { |
|
|
static size_t |
static size_t |
skip_fields_to_start(const struct bwstring *s, size_t fields, bool *empty_field) |
skip_fields_to_start(const struct bwstring *s, size_t fields, bool *empty_field) |
{ |
{ |
|
|
if (fields < 2) { |
if (fields < 2) { |
if (BWSLEN(s) == 0) |
if (BWSLEN(s) == 0) |
*empty_field = true; |
*empty_field = true; |
|
|
find_field_start(const struct bwstring *s, struct key_specs *ks, |
find_field_start(const struct bwstring *s, struct key_specs *ks, |
size_t *field_start, size_t *key_start, bool *empty_field, bool *empty_key) |
size_t *field_start, size_t *key_start, bool *empty_field, bool *empty_key) |
{ |
{ |
|
|
*field_start = skip_fields_to_start(s, ks->f1, empty_field); |
*field_start = skip_fields_to_start(s, ks->f1, empty_field); |
if (!*empty_field) |
if (!*empty_field) |
*key_start = skip_cols_to_start(s, ks->c1, *field_start, |
*key_start = skip_cols_to_start(s, ks->c1, *field_start, |
|
|
int |
int |
preproc(struct bwstring *s, struct keys_array *ka) |
preproc(struct bwstring *s, struct keys_array *ka) |
{ |
{ |
|
|
if (sort_opts_vals.kflag) { |
if (sort_opts_vals.kflag) { |
size_t i; |
size_t i; |
for (i = 0; i < keys_num; i++) { |
for (i = 0; i < keys_num; i++) { |
|
|
cmpcoll_t |
cmpcoll_t |
get_sort_func(struct sort_mods *sm) |
get_sort_func(struct sort_mods *sm) |
{ |
{ |
|
|
if (sm->nflag) |
if (sm->nflag) |
return numcoll; |
return numcoll; |
else if (sm->hflag) |
else if (sm->hflag) |
|
|
int |
int |
top_level_str_coll(const struct bwstring *s1, const struct bwstring *s2) |
top_level_str_coll(const struct bwstring *s1, const struct bwstring *s2) |
{ |
{ |
|
|
if (default_sort_mods->rflag) { |
if (default_sort_mods->rflag) { |
const struct bwstring *tmp; |
const struct bwstring *tmp; |
|
|
|
|
int |
int |
list_coll(const void *ss1, const void *ss2) |
list_coll(const void *ss1, const void *ss2) |
{ |
{ |
|
|
return list_coll_offset((struct sort_list_item **)ss1, |
return list_coll_offset((struct sort_list_item **)ss1, |
(struct sort_list_item **)ss2, 0); |
(struct sort_list_item **)ss2, 0); |
} |
} |
|
|
int |
int |
list_coll_by_str_only(struct sort_list_item **ss1, struct sort_list_item **ss2) |
list_coll_by_str_only(struct sort_list_item **ss1, struct sort_list_item **ss2) |
{ |
{ |
|
|
return top_level_str_coll(((*ss1)->str), ((*ss2)->str)); |
return top_level_str_coll(((*ss1)->str), ((*ss2)->str)); |
} |
} |
|
|
|
|
static inline int |
static inline int |
cmpsuffix(unsigned char si1, unsigned char si2) |
cmpsuffix(unsigned char si1, unsigned char si2) |
{ |
{ |
|
|
return (char)si1 - (char)si2; |
return (char)si1 - (char)si2; |
} |
} |
|
|
|
|
static int |
static int |
numcoll(struct key_value *kv1, struct key_value *kv2, size_t offset) |
numcoll(struct key_value *kv1, struct key_value *kv2, size_t offset) |
{ |
{ |
|
|
return numcoll_impl(kv1, kv2, offset, false); |
return numcoll_impl(kv1, kv2, offset, false); |
} |
} |
|
|
|
|
static int |
static int |
hnumcoll(struct key_value *kv1, struct key_value *kv2, size_t offset) |
hnumcoll(struct key_value *kv1, struct key_value *kv2, size_t offset) |
{ |
{ |
|
|
return numcoll_impl(kv1, kv2, offset, true); |
return numcoll_impl(kv1, kv2, offset, true); |
} |
} |
|
|
|
|
static inline bool |
static inline bool |
huge_minus(double d, int err1) |
huge_minus(double d, int err1) |
{ |
{ |
|
|
if (err1 == ERANGE) |
if (err1 == ERANGE) |
if (d == -HUGE_VAL || d == -HUGE_VALF || d == -HUGE_VALL) |
if (d == -HUGE_VAL || d == -HUGE_VALF || d == -HUGE_VALL) |
return 1; |
return 1; |
|
|
static inline bool |
static inline bool |
huge_plus(double d, int err1) |
huge_plus(double d, int err1) |
{ |
{ |
|
|
if (err1 == ERANGE) |
if (err1 == ERANGE) |
if (d == HUGE_VAL || d == HUGE_VALF || d == HUGE_VALL) |
if (d == HUGE_VAL || d == HUGE_VALF || d == HUGE_VALL) |
return 1; |
return 1; |
|
|
static int |
static int |
cmp_nans(double d1, double d2) |
cmp_nans(double d1, double d2) |
{ |
{ |
|
|
if (d1 == d2) |
if (d1 == d2) |
return 0; |
return 0; |
return d1 < d2 ? -1 : 1; |
return d1 < d2 ? -1 : 1; |