xref: /freebsd/usr.bin/sort/coll.c (revision 0957b409)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (C) 2009 Gabor Kovesdan <gabor@FreeBSD.org>
5  * Copyright (C) 2012 Oleg Moskalenko <mom040267@gmail.com>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/types.h>
34 
35 #include <errno.h>
36 #include <err.h>
37 #include <langinfo.h>
38 #include <limits.h>
39 #include <math.h>
40 #include <md5.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <wchar.h>
44 #include <wctype.h>
45 
46 #include "coll.h"
47 #include "vsort.h"
48 
49 struct key_specs *keys;
50 size_t keys_num = 0;
51 
52 wint_t symbol_decimal_point = L'.';
53 /* there is no default thousands separator in collate rules: */
54 wint_t symbol_thousands_sep = 0;
55 wint_t symbol_negative_sign = L'-';
56 wint_t symbol_positive_sign = L'+';
57 
58 static int wstrcoll(struct key_value *kv1, struct key_value *kv2, size_t offset);
59 static int gnumcoll(struct key_value*, struct key_value *, size_t offset);
60 static int monthcoll(struct key_value*, struct key_value *, size_t offset);
61 static int numcoll(struct key_value*, struct key_value *, size_t offset);
62 static int hnumcoll(struct key_value*, struct key_value *, size_t offset);
63 static int randomcoll(struct key_value*, struct key_value *, size_t offset);
64 static int versioncoll(struct key_value*, struct key_value *, size_t offset);
65 
66 /*
67  * Allocate keys array
68  */
69 struct keys_array *
70 keys_array_alloc(void)
71 {
72 	struct keys_array *ka;
73 	size_t sz;
74 
75 	sz = keys_array_size();
76 	ka = sort_malloc(sz);
77 	memset(ka, 0, sz);
78 
79 	return (ka);
80 }
81 
82 /*
83  * Calculate whether we need key hint space
84  */
85 static size_t
86 key_hint_size(void)
87 {
88 
89 	return (need_hint ? sizeof(struct key_hint) : 0);
90 }
91 
92 /*
93  * Calculate keys array size
94  */
95 size_t
96 keys_array_size(void)
97 {
98 
99 	return (keys_num * (sizeof(struct key_value) + key_hint_size()));
100 }
101 
102 /*
103  * Clean data of keys array
104  */
105 void
106 clean_keys_array(const struct bwstring *s, struct keys_array *ka)
107 {
108 
109 	if (ka) {
110 		for (size_t i = 0; i < keys_num; ++i) {
111 			const struct key_value *kv;
112 
113 			kv = get_key_from_keys_array(ka, i);
114 			if (kv->k && kv->k != s)
115 				bwsfree(kv->k);
116 		}
117 		memset(ka, 0, keys_array_size());
118 	}
119 }
120 
121 /*
122  * Get pointer to a key value in the keys set
123  */
124 struct key_value *
125 get_key_from_keys_array(struct keys_array *ka, size_t ind)
126 {
127 
128 	return ((struct key_value *)((caddr_t)ka->key +
129 	    ind * (sizeof(struct key_value) + key_hint_size())));
130 }
131 
132 /*
133  * Set value of a key in the keys set
134  */
135 void
136 set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind)
137 {
138 
139 	if (ka && keys_num > ind) {
140 		struct key_value *kv;
141 
142 		kv = get_key_from_keys_array(ka, ind);
143 
144 		if (kv->k && kv->k != s)
145 			bwsfree(kv->k);
146 		kv->k = s;
147 	}
148 }
149 
150 /*
151  * Initialize a sort list item
152  */
153 struct sort_list_item *
154 sort_list_item_alloc(void)
155 {
156 	struct sort_list_item *si;
157 	size_t sz;
158 
159 	sz = sizeof(struct sort_list_item) + keys_array_size();
160 	si = sort_malloc(sz);
161 	memset(si, 0, sz);
162 
163 	return (si);
164 }
165 
166 size_t
167 sort_list_item_size(struct sort_list_item *si)
168 {
169 	size_t ret = 0;
170 
171 	if (si) {
172 		ret = sizeof(struct sort_list_item) + keys_array_size();
173 		if (si->str)
174 			ret += bws_memsize(si->str);
175 		for (size_t i = 0; i < keys_num; ++i) {
176 			const struct key_value *kv;
177 
178 			kv = get_key_from_keys_array(&si->ka, i);
179 
180 			if (kv->k != si->str)
181 				ret += bws_memsize(kv->k);
182 		}
183 	}
184 	return (ret);
185 }
186 
187 /*
188  * Calculate key for a sort list item
189  */
190 static void
191 sort_list_item_make_key(struct sort_list_item *si)
192 {
193 
194 	preproc(si->str, &(si->ka));
195 }
196 
197 /*
198  * Set value of a sort list item.
199  * Return combined string and keys memory size.
200  */
201 void
202 sort_list_item_set(struct sort_list_item *si, struct bwstring *str)
203 {
204 
205 	if (si) {
206 		clean_keys_array(si->str, &(si->ka));
207 		if (si->str) {
208 			if (si->str == str) {
209 				/* we are trying to reset the same string */
210 				return;
211 			} else {
212 				bwsfree(si->str);
213 				si->str = NULL;
214 			}
215 		}
216 		si->str = str;
217 		sort_list_item_make_key(si);
218 	}
219 }
220 
221 /*
222  * De-allocate a sort list item object memory
223  */
224 void
225 sort_list_item_clean(struct sort_list_item *si)
226 {
227 
228 	if (si) {
229 		clean_keys_array(si->str, &(si->ka));
230 		if (si->str) {
231 			bwsfree(si->str);
232 			si->str = NULL;
233 		}
234 	}
235 }
236 
237 /*
238  * Skip columns according to specs
239  */
240 static size_t
241 skip_cols_to_start(const struct bwstring *s, size_t cols, size_t start,
242     bool skip_blanks, bool *empty_key)
243 {
244 	if (cols < 1)
245 		return (BWSLEN(s) + 1);
246 
247 	if (skip_blanks)
248 		while (start < BWSLEN(s) && iswblank(BWS_GET(s,start)))
249 			++start;
250 
251 	while (start < BWSLEN(s) && cols > 1) {
252 		--cols;
253 		++start;
254 	}
255 
256 	if (start >= BWSLEN(s))
257 		*empty_key = true;
258 
259 	return (start);
260 }
261 
262 /*
263  * Skip fields according to specs
264  */
265 static size_t
266 skip_fields_to_start(const struct bwstring *s, size_t fields, bool *empty_field)
267 {
268 
269 	if (fields < 2) {
270 		if (BWSLEN(s) == 0)
271 			*empty_field = true;
272 		return (0);
273 	} else if (!(sort_opts_vals.tflag)) {
274 		size_t cpos = 0;
275 		bool pb = true;
276 
277 		while (cpos < BWSLEN(s)) {
278 			bool isblank;
279 
280 			isblank = iswblank(BWS_GET(s, cpos));
281 
282 			if (isblank && !pb) {
283 				--fields;
284 				if (fields <= 1)
285 					return (cpos);
286 			}
287 			pb = isblank;
288 			++cpos;
289 		}
290 		if (fields > 1)
291 			*empty_field = true;
292 		return (cpos);
293 	} else {
294 		size_t cpos = 0;
295 
296 		while (cpos < BWSLEN(s)) {
297 			if (BWS_GET(s,cpos) == (wchar_t)sort_opts_vals.field_sep) {
298 				--fields;
299 				if (fields <= 1)
300 					return (cpos + 1);
301 			}
302 			++cpos;
303 		}
304 		if (fields > 1)
305 			*empty_field = true;
306 		return (cpos);
307 	}
308 }
309 
310 /*
311  * Find fields start
312  */
313 static void
314 find_field_start(const struct bwstring *s, struct key_specs *ks,
315     size_t *field_start, size_t *key_start, bool *empty_field, bool *empty_key)
316 {
317 
318 	*field_start = skip_fields_to_start(s, ks->f1, empty_field);
319 	if (!*empty_field)
320 		*key_start = skip_cols_to_start(s, ks->c1, *field_start,
321 		    ks->pos1b, empty_key);
322 	else
323 		*empty_key = true;
324 }
325 
326 /*
327  * Find end key position
328  */
329 static size_t
330 find_field_end(const struct bwstring *s, struct key_specs *ks)
331 {
332 	size_t f2, next_field_start, pos_end;
333 	bool empty_field, empty_key;
334 
335 	empty_field = false;
336 	empty_key = false;
337 	f2 = ks->f2;
338 
339 	if (f2 == 0)
340 		return (BWSLEN(s) + 1);
341 	else {
342 		if (ks->c2 == 0) {
343 			next_field_start = skip_fields_to_start(s, f2 + 1,
344 			    &empty_field);
345 			if ((next_field_start > 0) && sort_opts_vals.tflag &&
346 			    ((wchar_t)sort_opts_vals.field_sep == BWS_GET(s,
347 			    next_field_start - 1)))
348 				--next_field_start;
349 		} else
350 			next_field_start = skip_fields_to_start(s, f2,
351 			    &empty_field);
352 	}
353 
354 	if (empty_field || (next_field_start >= BWSLEN(s)))
355 		return (BWSLEN(s) + 1);
356 
357 	if (ks->c2) {
358 		pos_end = skip_cols_to_start(s, ks->c2, next_field_start,
359 		    ks->pos2b, &empty_key);
360 		if (pos_end < BWSLEN(s))
361 			++pos_end;
362 	} else
363 		pos_end = next_field_start;
364 
365 	return (pos_end);
366 }
367 
368 /*
369  * Cut a field according to the key specs
370  */
371 static struct bwstring *
372 cut_field(const struct bwstring *s, struct key_specs *ks)
373 {
374 	struct bwstring *ret = NULL;
375 
376 	if (s && ks) {
377 		size_t field_start, key_end, key_start, sz;
378 		bool empty_field, empty_key;
379 
380 		field_start = 0;
381 		key_start = 0;
382 		empty_field = false;
383 		empty_key = false;
384 
385 		find_field_start(s, ks, &field_start, &key_start,
386 		    &empty_field, &empty_key);
387 
388 		if (empty_key)
389 			sz = 0;
390 		else {
391 			key_end = find_field_end(s, ks);
392 			sz = (key_end < key_start) ? 0 : (key_end - key_start);
393 		}
394 
395 		ret = bwsalloc(sz);
396 		if (sz)
397 			bwsnocpy(ret, s, key_start, sz);
398 	} else
399 		ret = bwsalloc(0);
400 
401 	return (ret);
402 }
403 
404 /*
405  * Preprocesses a line applying the necessary transformations
406  * specified by command line options and returns the preprocessed
407  * string, which can be used to compare.
408  */
409 int
410 preproc(struct bwstring *s, struct keys_array *ka)
411 {
412 
413 	if (sort_opts_vals.kflag)
414 		for (size_t i = 0; i < keys_num; i++) {
415 			struct bwstring *key;
416 			struct key_specs *kspecs;
417 			struct sort_mods *sm;
418 
419 			kspecs = &(keys[i]);
420 			key = cut_field(s, kspecs);
421 
422 			sm = &(kspecs->sm);
423 			if (sm->dflag)
424 				key = dictionary_order(key);
425 			else if (sm->iflag)
426 				key = ignore_nonprinting(key);
427 			if (sm->fflag || sm->Mflag)
428 				key = ignore_case(key);
429 
430 			set_key_on_keys_array(ka, key, i);
431 		}
432 	else {
433 		struct bwstring *ret = NULL;
434 		struct sort_mods *sm = default_sort_mods;
435 
436 		if (sm->bflag) {
437 			if (ret == NULL)
438 				ret = bwsdup(s);
439 			ret = ignore_leading_blanks(ret);
440 		}
441 		if (sm->dflag) {
442 			if (ret == NULL)
443 				ret = bwsdup(s);
444 			ret = dictionary_order(ret);
445 		} else if (sm->iflag) {
446 			if (ret == NULL)
447 				ret = bwsdup(s);
448 			ret = ignore_nonprinting(ret);
449 		}
450 		if (sm->fflag || sm->Mflag) {
451 			if (ret == NULL)
452 				ret = bwsdup(s);
453 			ret = ignore_case(ret);
454 		}
455 		if (ret == NULL)
456 			set_key_on_keys_array(ka, s, 0);
457 		else
458 			set_key_on_keys_array(ka, ret, 0);
459 	}
460 
461 	return 0;
462 }
463 
464 cmpcoll_t
465 get_sort_func(struct sort_mods *sm)
466 {
467 
468 	if (sm->nflag)
469 		return (numcoll);
470 	else if (sm->hflag)
471 		return (hnumcoll);
472 	else if (sm->gflag)
473 		return (gnumcoll);
474 	else if (sm->Mflag)
475 		return (monthcoll);
476 	else if (sm->Rflag)
477 		return (randomcoll);
478 	else if (sm->Vflag)
479 		return (versioncoll);
480 	else
481 		return (wstrcoll);
482 }
483 
484 /*
485  * Compares the given strings.  Returns a positive number if
486  * the first precedes the second, a negative number if the second is
487  * the preceding one, and zero if they are equal.  This function calls
488  * the underlying collate functions, which done the actual comparison.
489  */
490 int
491 key_coll(struct keys_array *ps1, struct keys_array *ps2, size_t offset)
492 {
493 	struct key_value *kv1, *kv2;
494 	struct sort_mods *sm;
495 	int res = 0;
496 
497 	for (size_t i = 0; i < keys_num; ++i) {
498 		kv1 = get_key_from_keys_array(ps1, i);
499 		kv2 = get_key_from_keys_array(ps2, i);
500 		sm = &(keys[i].sm);
501 
502 		if (sm->rflag)
503 			res = sm->func(kv2, kv1, offset);
504 		else
505 			res = sm->func(kv1, kv2, offset);
506 
507 		if (res)
508 			break;
509 
510 		/* offset applies to only the first key */
511 		offset = 0;
512 	}
513 	return (res);
514 }
515 
516 /*
517  * Compare two strings.
518  * Plain symbol-by-symbol comparison.
519  */
520 int
521 top_level_str_coll(const struct bwstring *s1, const struct bwstring *s2)
522 {
523 
524 	if (default_sort_mods->rflag) {
525 		const struct bwstring *tmp;
526 
527 		tmp = s1;
528 		s1 = s2;
529 		s2 = tmp;
530 	}
531 
532 	return (bwscoll(s1, s2, 0));
533 }
534 
535 /*
536  * Compare a string and a sort list item, according to the sort specs.
537  */
538 int
539 str_list_coll(struct bwstring *str1, struct sort_list_item **ss2)
540 {
541 	struct keys_array *ka1;
542 	int ret = 0;
543 
544 	ka1 = keys_array_alloc();
545 
546 	preproc(str1, ka1);
547 
548 	sort_list_item_make_key(*ss2);
549 
550 	if (debug_sort) {
551 		bwsprintf(stdout, str1, "; s1=<", ">");
552 		bwsprintf(stdout, (*ss2)->str, ", s2=<", ">");
553 	}
554 
555 	ret = key_coll(ka1, &((*ss2)->ka), 0);
556 
557 	if (debug_sort)
558 		printf("; cmp1=%d", ret);
559 
560 	clean_keys_array(str1, ka1);
561 	sort_free(ka1);
562 
563 	if ((ret == 0) && !(sort_opts_vals.sflag) && sort_opts_vals.complex_sort) {
564 		ret = top_level_str_coll(str1, ((*ss2)->str));
565 		if (debug_sort)
566 			printf("; cmp2=%d", ret);
567 	}
568 
569 	if (debug_sort)
570 		printf("\n");
571 
572 	return (ret);
573 }
574 
575 /*
576  * Compare two sort list items, according to the sort specs.
577  */
578 int
579 list_coll_offset(struct sort_list_item **ss1, struct sort_list_item **ss2,
580     size_t offset)
581 {
582 	int ret;
583 
584 	ret = key_coll(&((*ss1)->ka), &((*ss2)->ka), offset);
585 
586 	if (debug_sort) {
587 		if (offset)
588 			printf("; offset=%d", (int) offset);
589 		bwsprintf(stdout, ((*ss1)->str), "; s1=<", ">");
590 		bwsprintf(stdout, ((*ss2)->str), ", s2=<", ">");
591 		printf("; cmp1=%d\n", ret);
592 	}
593 
594 	if (ret)
595 		return (ret);
596 
597 	if (!(sort_opts_vals.sflag) && sort_opts_vals.complex_sort) {
598 		ret = top_level_str_coll(((*ss1)->str), ((*ss2)->str));
599 		if (debug_sort)
600 			printf("; cmp2=%d\n", ret);
601 	}
602 
603 	return (ret);
604 }
605 
606 /*
607  * Compare two sort list items, according to the sort specs.
608  */
609 int
610 list_coll(struct sort_list_item **ss1, struct sort_list_item **ss2)
611 {
612 
613 	return (list_coll_offset(ss1, ss2, 0));
614 }
615 
616 #define	LSCDEF(N)							\
617 static int 								\
618 list_coll_##N(struct sort_list_item **ss1, struct sort_list_item **ss2)	\
619 {									\
620 									\
621 	return (list_coll_offset(ss1, ss2, N));				\
622 }
623 
624 LSCDEF(1)
625 LSCDEF(2)
626 LSCDEF(3)
627 LSCDEF(4)
628 LSCDEF(5)
629 LSCDEF(6)
630 LSCDEF(7)
631 LSCDEF(8)
632 LSCDEF(9)
633 LSCDEF(10)
634 LSCDEF(11)
635 LSCDEF(12)
636 LSCDEF(13)
637 LSCDEF(14)
638 LSCDEF(15)
639 LSCDEF(16)
640 LSCDEF(17)
641 LSCDEF(18)
642 LSCDEF(19)
643 LSCDEF(20)
644 
645 listcoll_t
646 get_list_call_func(size_t offset)
647 {
648 	static const listcoll_t lsarray[] = { list_coll, list_coll_1,
649 	    list_coll_2, list_coll_3, list_coll_4, list_coll_5,
650 	    list_coll_6, list_coll_7, list_coll_8, list_coll_9,
651 	    list_coll_10, list_coll_11, list_coll_12, list_coll_13,
652 	    list_coll_14, list_coll_15, list_coll_16, list_coll_17,
653 	    list_coll_18, list_coll_19, list_coll_20 };
654 
655 	if (offset <= 20)
656 		return (lsarray[offset]);
657 
658 	return (list_coll);
659 }
660 
661 /*
662  * Compare two sort list items, only by their original string.
663  */
664 int
665 list_coll_by_str_only(struct sort_list_item **ss1, struct sort_list_item **ss2)
666 {
667 
668 	return (top_level_str_coll(((*ss1)->str), ((*ss2)->str)));
669 }
670 
671 /*
672  * Maximum size of a number in the string (before or after decimal point)
673  */
674 #define MAX_NUM_SIZE (128)
675 
676 /*
677  * Set suffix value
678  */
679 static void setsuffix(wchar_t c, unsigned char *si)
680 {
681 	switch (c){
682 	case L'k':
683 	case L'K':
684 		*si = 1;
685 		break;
686 	case L'M':
687 		*si = 2;
688 		break;
689 	case L'G':
690 		*si = 3;
691 		break;
692 	case L'T':
693 		*si = 4;
694 		break;
695 	case L'P':
696 		*si = 5;
697 		break;
698 	case L'E':
699 		*si = 6;
700 		break;
701 	case L'Z':
702 		*si = 7;
703 		break;
704 	case L'Y':
705 		*si = 8;
706 		break;
707 	default:
708 		*si = 0;
709 	}
710 }
711 
712 /*
713  * Read string s and parse the string into a fixed-decimal-point number.
714  * sign equals -1 if the number is negative (explicit plus is not allowed,
715  * according to GNU sort's "info sort".
716  * The number part before decimal point is in the smain, after the decimal
717  * point is in sfrac, tail is the pointer to the remainder of the string.
718  */
719 static int
720 read_number(struct bwstring *s0, int *sign, wchar_t *smain, size_t *main_len, wchar_t *sfrac, size_t *frac_len, unsigned char *si)
721 {
722 	bwstring_iterator s;
723 
724 	s = bws_begin(s0);
725 
726 	/* always end the fraction with zero, even if we have no fraction */
727 	sfrac[0] = 0;
728 
729 	while (iswblank(bws_get_iter_value(s)))
730 		s = bws_iterator_inc(s, 1);
731 
732 	if (bws_get_iter_value(s) == (wchar_t)symbol_negative_sign) {
733 		*sign = -1;
734 		s = bws_iterator_inc(s, 1);
735 	}
736 
737 	// This is '0', not '\0', do not change this
738 	while (iswdigit(bws_get_iter_value(s)) &&
739 	    (bws_get_iter_value(s) == L'0'))
740 		s = bws_iterator_inc(s, 1);
741 
742 	while (bws_get_iter_value(s) && *main_len < MAX_NUM_SIZE) {
743 		if (iswdigit(bws_get_iter_value(s))) {
744 			smain[*main_len] = bws_get_iter_value(s);
745 			s = bws_iterator_inc(s, 1);
746 			*main_len += 1;
747 		} else if (symbol_thousands_sep &&
748 		    (bws_get_iter_value(s) == (wchar_t)symbol_thousands_sep))
749 			s = bws_iterator_inc(s, 1);
750 		else
751 			break;
752 	}
753 
754 	smain[*main_len] = 0;
755 
756 	if (bws_get_iter_value(s) == (wchar_t)symbol_decimal_point) {
757 		s = bws_iterator_inc(s, 1);
758 		while (iswdigit(bws_get_iter_value(s)) &&
759 		    *frac_len < MAX_NUM_SIZE) {
760 			sfrac[*frac_len] = bws_get_iter_value(s);
761 			s = bws_iterator_inc(s, 1);
762 			*frac_len += 1;
763 		}
764 		sfrac[*frac_len] = 0;
765 
766 		while (*frac_len > 0 && sfrac[*frac_len - 1] == L'0') {
767 			--(*frac_len);
768 			sfrac[*frac_len] = L'\0';
769 		}
770 	}
771 
772 	setsuffix(bws_get_iter_value(s),si);
773 
774 	if ((*main_len + *frac_len) == 0)
775 		*sign = 0;
776 
777 	return (0);
778 }
779 
780 /*
781  * Implements string sort.
782  */
783 static int
784 wstrcoll(struct key_value *kv1, struct key_value *kv2, size_t offset)
785 {
786 
787 	if (debug_sort) {
788 		if (offset)
789 			printf("; offset=%d\n", (int) offset);
790 		bwsprintf(stdout, kv1->k, "; k1=<", ">");
791 		printf("(%zu)", BWSLEN(kv1->k));
792 		bwsprintf(stdout, kv2->k, ", k2=<", ">");
793 		printf("(%zu)", BWSLEN(kv2->k));
794 	}
795 
796 	return (bwscoll(kv1->k, kv2->k, offset));
797 }
798 
799 /*
800  * Compare two suffixes
801  */
802 static inline int
803 cmpsuffix(unsigned char si1, unsigned char si2)
804 {
805 
806 	return ((char)si1 - (char)si2);
807 }
808 
809 /*
810  * Implements numeric sort for -n and -h.
811  */
812 static int
813 numcoll_impl(struct key_value *kv1, struct key_value *kv2,
814     size_t offset __unused, bool use_suffix)
815 {
816 	struct bwstring *s1, *s2;
817 	wchar_t sfrac1[MAX_NUM_SIZE + 1], sfrac2[MAX_NUM_SIZE + 1];
818 	wchar_t smain1[MAX_NUM_SIZE + 1], smain2[MAX_NUM_SIZE + 1];
819 	int cmp_res, sign1, sign2;
820 	size_t frac1, frac2, main1, main2;
821 	unsigned char SI1, SI2;
822 	bool e1, e2, key1_read, key2_read;
823 
824 	s1 = kv1->k;
825 	s2 = kv2->k;
826 	sign1 = sign2 = 0;
827 	main1 = main2 = 0;
828 	frac1 = frac2 = 0;
829 
830 	key1_read = key2_read = false;
831 
832 	if (debug_sort) {
833 		bwsprintf(stdout, s1, "; k1=<", ">");
834 		bwsprintf(stdout, s2, ", k2=<", ">");
835 	}
836 
837 	if (s1 == s2)
838 		return (0);
839 
840 	if (kv1->hint->status == HS_UNINITIALIZED) {
841 		/* read the number from the string */
842 		read_number(s1, &sign1, smain1, &main1, sfrac1, &frac1, &SI1);
843 		key1_read = true;
844 		kv1->hint->v.nh.n1 = wcstoull(smain1, NULL, 10);
845 		if(main1 < 1 && frac1 < 1)
846 			kv1->hint->v.nh.empty=true;
847 		kv1->hint->v.nh.si = SI1;
848 		kv1->hint->status = (kv1->hint->v.nh.n1 != ULLONG_MAX) ?
849 		    HS_INITIALIZED : HS_ERROR;
850 		kv1->hint->v.nh.neg = (sign1 < 0) ? true : false;
851 	}
852 
853 	if (kv2->hint->status == HS_UNINITIALIZED) {
854 		/* read the number from the string */
855 		read_number(s2, &sign2, smain2, &main2, sfrac2, &frac2,&SI2);
856 		key2_read = true;
857 		kv2->hint->v.nh.n1 = wcstoull(smain2, NULL, 10);
858 		if(main2 < 1 && frac2 < 1)
859 			kv2->hint->v.nh.empty=true;
860 		kv2->hint->v.nh.si = SI2;
861 		kv2->hint->status = (kv2->hint->v.nh.n1 != ULLONG_MAX) ?
862 		    HS_INITIALIZED : HS_ERROR;
863 		kv2->hint->v.nh.neg = (sign2 < 0) ? true : false;
864 	}
865 
866 	if (kv1->hint->status == HS_INITIALIZED && kv2->hint->status ==
867 	    HS_INITIALIZED) {
868 		unsigned long long n1, n2;
869 		bool neg1, neg2;
870 
871 		e1 = kv1->hint->v.nh.empty;
872 		e2 = kv2->hint->v.nh.empty;
873 
874 		if (e1 && e2)
875 			return (0);
876 
877 		neg1 = kv1->hint->v.nh.neg;
878 		neg2 = kv2->hint->v.nh.neg;
879 
880 		if (neg1 && !neg2)
881 			return (-1);
882 		if (neg2 && !neg1)
883 			return (+1);
884 
885 		if (e1)
886 			return (neg2 ? +1 : -1);
887 		else if (e2)
888 			return (neg1 ? -1 : +1);
889 
890 
891 		if (use_suffix) {
892 			cmp_res = cmpsuffix(kv1->hint->v.nh.si, kv2->hint->v.nh.si);
893 			if (cmp_res)
894 				return (neg1 ? -cmp_res : cmp_res);
895 		}
896 
897 		n1 = kv1->hint->v.nh.n1;
898 		n2 = kv2->hint->v.nh.n1;
899 		if (n1 < n2)
900 			return (neg1 ? +1 : -1);
901 		else if (n1 > n2)
902 			return (neg1 ? -1 : +1);
903 	}
904 
905 	/* read the numbers from the strings */
906 	if (!key1_read)
907 		read_number(s1, &sign1, smain1, &main1, sfrac1, &frac1, &SI1);
908 	if (!key2_read)
909 		read_number(s2, &sign2, smain2, &main2, sfrac2, &frac2, &SI2);
910 
911 	e1 = ((main1 + frac1) == 0);
912 	e2 = ((main2 + frac2) == 0);
913 
914 	if (e1 && e2)
915 		return (0);
916 
917 	/* we know the result if the signs are different */
918 	if (sign1 < 0 && sign2 >= 0)
919 		return (-1);
920 	if (sign1 >= 0 && sign2 < 0)
921 		return (+1);
922 
923 	if (e1)
924 		return ((sign2 < 0) ? +1 : -1);
925 	else if (e2)
926 		return ((sign1 < 0) ? -1 : +1);
927 
928 	if (use_suffix) {
929 		cmp_res = cmpsuffix(SI1, SI2);
930 		if (cmp_res)
931 			return ((sign1 < 0) ? -cmp_res : cmp_res);
932 	}
933 
934 	/* if both numbers are empty assume that the strings are equal */
935 	if (main1 < 1 && main2 < 1 && frac1 < 1 && frac2 < 1)
936 		return (0);
937 
938 	/*
939 	 * if the main part is of different size, we know the result
940 	 * (because the leading zeros are removed)
941 	 */
942 	if (main1 < main2)
943 		cmp_res = -1;
944 	else if (main1 > main2)
945 		cmp_res = +1;
946 	/* if the sizes are equal then simple non-collate string compare gives the correct result */
947 	else
948 		cmp_res = wcscmp(smain1, smain2);
949 
950 	/* check fraction */
951 	if (!cmp_res)
952 		cmp_res = wcscmp(sfrac1, sfrac2);
953 
954 	if (!cmp_res)
955 		return (0);
956 
957 	/* reverse result if the signs are negative */
958 	if (sign1 < 0 && sign2 < 0)
959 		cmp_res = -cmp_res;
960 
961 	return (cmp_res);
962 }
963 
964 /*
965  * Implements numeric sort (-n).
966  */
967 static int
968 numcoll(struct key_value *kv1, struct key_value *kv2, size_t offset)
969 {
970 
971 	return (numcoll_impl(kv1, kv2, offset, false));
972 }
973 
974 /*
975  * Implements 'human' numeric sort (-h).
976  */
977 static int
978 hnumcoll(struct key_value *kv1, struct key_value *kv2, size_t offset)
979 {
980 
981 	return (numcoll_impl(kv1, kv2, offset, true));
982 }
983 
984 /*
985  * Implements random sort (-R).
986  */
987 static int
988 randomcoll(struct key_value *kv1, struct key_value *kv2,
989     size_t offset __unused)
990 {
991 	struct bwstring *s1, *s2;
992 	MD5_CTX ctx1, ctx2;
993 	char *b1, *b2;
994 
995 	s1 = kv1->k;
996 	s2 = kv2->k;
997 
998 	if (debug_sort) {
999 		bwsprintf(stdout, s1, "; k1=<", ">");
1000 		bwsprintf(stdout, s2, ", k2=<", ">");
1001 	}
1002 
1003 	if (s1 == s2)
1004 		return (0);
1005 
1006 	memcpy(&ctx1,&md5_ctx,sizeof(MD5_CTX));
1007 	memcpy(&ctx2,&md5_ctx,sizeof(MD5_CTX));
1008 
1009 	MD5Update(&ctx1, bwsrawdata(s1), bwsrawlen(s1));
1010 	MD5Update(&ctx2, bwsrawdata(s2), bwsrawlen(s2));
1011 	b1 = MD5End(&ctx1, NULL);
1012 	b2 = MD5End(&ctx2, NULL);
1013 	if (b1 == NULL) {
1014 		if (b2 == NULL)
1015 			return (0);
1016 		else {
1017 			sort_free(b2);
1018 			return (-1);
1019 		}
1020 	} else if (b2 == NULL) {
1021 		sort_free(b1);
1022 		return (+1);
1023 	} else {
1024 		int cmp_res;
1025 
1026 		cmp_res = strcmp(b1,b2);
1027 		sort_free(b1);
1028 		sort_free(b2);
1029 
1030 		if (!cmp_res)
1031 			cmp_res = bwscoll(s1, s2, 0);
1032 
1033 		return (cmp_res);
1034 	}
1035 }
1036 
1037 /*
1038  * Implements version sort (-V).
1039  */
1040 static int
1041 versioncoll(struct key_value *kv1, struct key_value *kv2,
1042     size_t offset __unused)
1043 {
1044 	struct bwstring *s1, *s2;
1045 
1046 	s1 = kv1->k;
1047 	s2 = kv2->k;
1048 
1049 	if (debug_sort) {
1050 		bwsprintf(stdout, s1, "; k1=<", ">");
1051 		bwsprintf(stdout, s2, ", k2=<", ">");
1052 	}
1053 
1054 	if (s1 == s2)
1055 		return (0);
1056 
1057 	return (vcmp(s1, s2));
1058 }
1059 
1060 /*
1061  * Check for minus infinity
1062  */
1063 static inline bool
1064 huge_minus(double d, int err1)
1065 {
1066 
1067 	if (err1 == ERANGE)
1068 		if (d == -HUGE_VAL || d == -HUGE_VALF || d == -HUGE_VALL)
1069 			return (+1);
1070 
1071 	return (0);
1072 }
1073 
1074 /*
1075  * Check for plus infinity
1076  */
1077 static inline bool
1078 huge_plus(double d, int err1)
1079 {
1080 
1081 	if (err1 == ERANGE)
1082 		if (d == HUGE_VAL || d == HUGE_VALF || d == HUGE_VALL)
1083 			return (+1);
1084 
1085 	return (0);
1086 }
1087 
1088 /*
1089  * Check whether a function is a NAN
1090  */
1091 static bool
1092 is_nan(double d)
1093 {
1094 
1095 	return ((d == NAN) || (isnan(d)));
1096 }
1097 
1098 /*
1099  * Compare two NANs
1100  */
1101 static int
1102 cmp_nans(double d1, double d2)
1103 {
1104 
1105 	if (d1 < d2)
1106 		return (-1);
1107 	if (d1 > d2)
1108 		return (+1);
1109 	return (0);
1110 }
1111 
1112 /*
1113  * Implements general numeric sort (-g).
1114  */
1115 static int
1116 gnumcoll(struct key_value *kv1, struct key_value *kv2,
1117     size_t offset __unused)
1118 {
1119 	double d1, d2;
1120 	int err1, err2;
1121 	bool empty1, empty2, key1_read, key2_read;
1122 
1123 	d1 = d2 = 0;
1124 	err1 = err2 = 0;
1125 	key1_read = key2_read = false;
1126 
1127 	if (debug_sort) {
1128 		bwsprintf(stdout, kv1->k, "; k1=<", ">");
1129 		bwsprintf(stdout, kv2->k, "; k2=<", ">");
1130 	}
1131 
1132 	if (kv1->hint->status == HS_UNINITIALIZED) {
1133 		errno = 0;
1134 		d1 = bwstod(kv1->k, &empty1);
1135 		err1 = errno;
1136 
1137 		if (empty1)
1138 			kv1->hint->v.gh.notnum = true;
1139 		else if (err1 == 0) {
1140 			kv1->hint->v.gh.d = d1;
1141 			kv1->hint->v.gh.nan = is_nan(d1);
1142 			kv1->hint->status = HS_INITIALIZED;
1143 		} else
1144 			kv1->hint->status = HS_ERROR;
1145 
1146 		key1_read = true;
1147 	}
1148 
1149 	if (kv2->hint->status == HS_UNINITIALIZED) {
1150 		errno = 0;
1151 		d2 = bwstod(kv2->k, &empty2);
1152 		err2 = errno;
1153 
1154 		if (empty2)
1155 			kv2->hint->v.gh.notnum = true;
1156 		else if (err2 == 0) {
1157 			kv2->hint->v.gh.d = d2;
1158 			kv2->hint->v.gh.nan = is_nan(d2);
1159 			kv2->hint->status = HS_INITIALIZED;
1160 		} else
1161 			kv2->hint->status = HS_ERROR;
1162 
1163 		key2_read = true;
1164 	}
1165 
1166 	if (kv1->hint->status == HS_INITIALIZED &&
1167 	    kv2->hint->status == HS_INITIALIZED) {
1168 		if (kv1->hint->v.gh.notnum)
1169 			return ((kv2->hint->v.gh.notnum) ? 0 : -1);
1170 		else if (kv2->hint->v.gh.notnum)
1171 			return (+1);
1172 
1173 		if (kv1->hint->v.gh.nan)
1174 			return ((kv2->hint->v.gh.nan) ?
1175 			    cmp_nans(kv1->hint->v.gh.d, kv2->hint->v.gh.d) :
1176 			    -1);
1177 		else if (kv2->hint->v.gh.nan)
1178 			return (+1);
1179 
1180 		d1 = kv1->hint->v.gh.d;
1181 		d2 = kv2->hint->v.gh.d;
1182 
1183 		if (d1 < d2)
1184 			return (-1);
1185 		else if (d1 > d2)
1186 			return (+1);
1187 		else
1188 			return (0);
1189 	}
1190 
1191 	if (!key1_read) {
1192 		errno = 0;
1193 		d1 = bwstod(kv1->k, &empty1);
1194 		err1 = errno;
1195 	}
1196 
1197 	if (!key2_read) {
1198 		errno = 0;
1199 		d2 = bwstod(kv2->k, &empty2);
1200 		err2 = errno;
1201 	}
1202 
1203 	/* Non-value case: */
1204 	if (empty1)
1205 		return (empty2 ? 0 : -1);
1206 	else if (empty2)
1207 		return (+1);
1208 
1209 	/* NAN case */
1210 	if (is_nan(d1))
1211 		return (is_nan(d2) ? cmp_nans(d1, d2) : -1);
1212 	else if (is_nan(d2))
1213 		return (+1);
1214 
1215 	/* Infinities */
1216 	if (err1 == ERANGE || err2 == ERANGE) {
1217 		/* Minus infinity case */
1218 		if (huge_minus(d1, err1)) {
1219 			if (huge_minus(d2, err2)) {
1220 				if (d1 < d2)
1221 					return (-1);
1222 				if (d1 > d2)
1223 					return (+1);
1224 				return (0);
1225 			} else
1226 				return (-1);
1227 
1228 		} else if (huge_minus(d2, err2)) {
1229 			if (huge_minus(d1, err1)) {
1230 				if (d1 < d2)
1231 					return (-1);
1232 				if (d1 > d2)
1233 					return (+1);
1234 				return (0);
1235 			} else
1236 				return (+1);
1237 		}
1238 
1239 		/* Plus infinity case */
1240 		if (huge_plus(d1, err1)) {
1241 			if (huge_plus(d2, err2)) {
1242 				if (d1 < d2)
1243 					return (-1);
1244 				if (d1 > d2)
1245 					return (+1);
1246 				return (0);
1247 			} else
1248 				return (+1);
1249 		} else if (huge_plus(d2, err2)) {
1250 			if (huge_plus(d1, err1)) {
1251 				if (d1 < d2)
1252 					return (-1);
1253 				if (d1 > d2)
1254 					return (+1);
1255 				return (0);
1256 			} else
1257 				return (-1);
1258 		}
1259 	}
1260 
1261 	if (d1 < d2)
1262 		return (-1);
1263 	if (d1 > d2)
1264 		return (+1);
1265 
1266 	return (0);
1267 }
1268 
1269 /*
1270  * Implements month sort (-M).
1271  */
1272 static int
1273 monthcoll(struct key_value *kv1, struct key_value *kv2, size_t offset __unused)
1274 {
1275 	int val1, val2;
1276 	bool key1_read, key2_read;
1277 
1278 	val1 = val2 = 0;
1279 	key1_read = key2_read = false;
1280 
1281 	if (debug_sort) {
1282 		bwsprintf(stdout, kv1->k, "; k1=<", ">");
1283 		bwsprintf(stdout, kv2->k, "; k2=<", ">");
1284 	}
1285 
1286 	if (kv1->hint->status == HS_UNINITIALIZED) {
1287 		kv1->hint->v.Mh.m = bws_month_score(kv1->k);
1288 		key1_read = true;
1289 		kv1->hint->status = HS_INITIALIZED;
1290 	}
1291 
1292 	if (kv2->hint->status == HS_UNINITIALIZED) {
1293 		kv2->hint->v.Mh.m = bws_month_score(kv2->k);
1294 		key2_read = true;
1295 		kv2->hint->status = HS_INITIALIZED;
1296 	}
1297 
1298 	if (kv1->hint->status == HS_INITIALIZED) {
1299 		val1 = kv1->hint->v.Mh.m;
1300 		key1_read = true;
1301 	}
1302 
1303 	if (kv2->hint->status == HS_INITIALIZED) {
1304 		val2 = kv2->hint->v.Mh.m;
1305 		key2_read = true;
1306 	}
1307 
1308 	if (!key1_read)
1309 		val1 = bws_month_score(kv1->k);
1310 	if (!key2_read)
1311 		val2 = bws_month_score(kv2->k);
1312 
1313 	if (val1 == val2) {
1314 		return (0);
1315 	}
1316 	if (val1 < val2)
1317 		return (-1);
1318 	return (+1);
1319 }
1320