Exemplo n.º 1
0
/*
 * Compare two sort list items, according to the sort specs.
 */
int
list_coll_offset(struct sort_list_item **ss1, struct sort_list_item **ss2,
    size_t offset)
{
	int ret;

	ret = key_coll(&((*ss1)->ka), &((*ss2)->ka), offset);

	if (debug_sort) {
		if (offset)
			printf("; offset=%d", (int) offset);
		bwsprintf(stdout, ((*ss1)->str), "; s1=<", ">");
		bwsprintf(stdout, ((*ss2)->str), ", s2=<", ">");
		printf("; cmp1=%d\n", ret);
	}

	if (ret)
		return (ret);

	if (!(sort_opts_vals.sflag) && sort_opts_vals.complex_sort) {
		ret = top_level_str_coll(((*ss1)->str), ((*ss2)->str));
		if (debug_sort)
			printf("; cmp2=%d\n", ret);
	}

	return (ret);
}
Exemplo n.º 2
0
/*
 * Implements random sort (-R).
 */
static int
randomcoll(struct key_value *kv1, struct key_value *kv2, size_t offset)
{
	struct bwstring *s1, *s2;
	MD5_CTX ctx1, ctx2;
	char *b1, *b2;

	UNUSED_ARG(offset);

	s1 = kv1->k;
	s2 = kv2->k;

	if (debug_sort) {
		bwsprintf(stdout, s1, "; k1=<", ">");
		bwsprintf(stdout, s2, ", k2=<", ">");
	}

	if (s1 == s2)
		return (0);

	memcpy(&ctx1,&md5_ctx,sizeof(MD5_CTX));
	memcpy(&ctx2,&md5_ctx,sizeof(MD5_CTX));

	MD5Update(&ctx1, bwsrawdata(s1), bwsrawlen(s1));
	MD5Update(&ctx2, bwsrawdata(s2), bwsrawlen(s2));
	b1 = MD5End(&ctx1, NULL);
	b2 = MD5End(&ctx2, NULL);
	if (b1 == NULL) {
		if (b2 == NULL)
			return (0);
		else {
			sort_free(b2);
			return (-1);
		}
	} else if (b2 == NULL) {
		sort_free(b1);
		return (+1);
	} else {
		int cmp_res;

		cmp_res = strcmp(b1,b2);
		sort_free(b1);
		sort_free(b2);

		if (!cmp_res)
			cmp_res = bwscoll(s1, s2, 0);

		return (cmp_res);
	}
}
Exemplo n.º 3
0
/*
 * Implements month sort (-M).
 */
static int
monthcoll(struct key_value *kv1, struct key_value *kv2, size_t offset)
{
	int val1, val2;
	bool key1_read, key2_read;

	val1 = val2 = 0;
	key1_read = key2_read = false;

	UNUSED_ARG(offset);

	if (debug_sort) {
		bwsprintf(stdout, kv1->k, "; k1=<", ">");
		bwsprintf(stdout, kv2->k, "; k2=<", ">");
	}

	if (kv1->hint->status == HS_UNINITIALIZED) {
		kv1->hint->v.Mh.m = bws_month_score(kv1->k);
		key1_read = true;
		kv1->hint->status = HS_INITIALIZED;
	}

	if (kv2->hint->status == HS_UNINITIALIZED) {
		kv2->hint->v.Mh.m = bws_month_score(kv2->k);
		key2_read = true;
		kv2->hint->status = HS_INITIALIZED;
	}

	if (kv1->hint->status == HS_INITIALIZED) {
		val1 = kv1->hint->v.Mh.m;
		key1_read = true;
	}

	if (kv2->hint->status == HS_INITIALIZED) {
		val2 = kv2->hint->v.Mh.m;
		key2_read = true;
	}

	if (!key1_read)
		val1 = bws_month_score(kv1->k);
	if (!key2_read)
		val2 = bws_month_score(kv2->k);

	if (val1 == val2) {
		return (0);
	}
	if (val1 < val2)
		return (-1);
	return (+1);
}
Exemplo n.º 4
0
/*
 * Implements string sort.
 */
static int
wstrcoll(struct key_value *kv1, struct key_value *kv2, size_t offset)
{

	if (debug_sort) {
		if (offset)
			printf("; offset=%d\n", (int) offset);
		bwsprintf(stdout, kv1->k, "; k1=<", ">");
		printf("(%zu)", BWSLEN(kv1->k));
		bwsprintf(stdout, kv2->k, ", k2=<", ">");
		printf("(%zu)", BWSLEN(kv2->k));
	}

	return (bwscoll(kv1->k, kv2->k, offset));
}
Exemplo n.º 5
0
/*
 * Implements random sort (-R).
 */
static int
randomcoll(struct key_value *kv1, struct key_value *kv2,
    size_t offset __unused)
{
	struct bwstring *s1, *s2;
	MD5_CTX ctx1, ctx2;
	unsigned char hash1[MD5_DIGEST_LENGTH], hash2[MD5_DIGEST_LENGTH];
	int cmp;

	s1 = kv1->k;
	s2 = kv2->k;

	if (debug_sort) {
		bwsprintf(stdout, s1, "; k1=<", ">");
		bwsprintf(stdout, s2, ", k2=<", ">");
	}

	if (s1 == s2)
		return (0);

	if (kv1->hint->status == HS_INITIALIZED &&
	    kv2->hint->status == HS_INITIALIZED) {
		cmp = memcmp(kv1->hint->v.Rh.cached,
		    kv2->hint->v.Rh.cached, sizeof(kv1->hint->v.Rh.cached));
		if (cmp != 0)
			return (cmp);
	}

	memcpy(&ctx1, &md5_ctx, sizeof(MD5_CTX));
	memcpy(&ctx2, &md5_ctx, sizeof(MD5_CTX));

	MD5Update(&ctx1, bwsrawdata(s1), bwsrawlen(s1));
	MD5Update(&ctx2, bwsrawdata(s2), bwsrawlen(s2));

	MD5Final(hash1, &ctx1);
	MD5Final(hash2, &ctx2);

	if (kv1->hint->status == HS_UNINITIALIZED)
		randomcoll_init_hint(kv1, hash1);
	if (kv2->hint->status == HS_UNINITIALIZED)
		randomcoll_init_hint(kv2, hash2);

	return (memcmp(hash1, hash2, sizeof(hash1)));
}
Exemplo n.º 6
0
/*
 * Implements version sort (-V).
 */
static int
versioncoll(struct key_value *kv1, struct key_value *kv2,
    size_t offset __unused)
{
	struct bwstring *s1, *s2;

	s1 = kv1->k;
	s2 = kv2->k;

	if (debug_sort) {
		bwsprintf(stdout, s1, "; k1=<", ">");
		bwsprintf(stdout, s2, ", k2=<", ">");
	}

	if (s1 == s2)
		return (0);

	return (vcmp(s1, s2));
}
Exemplo n.º 7
0
/*
 * Compare a string and a sort list item, according to the sort specs.
 */
int
str_list_coll(struct bwstring *str1, struct sort_list_item **ss2)
{
	struct keys_array *ka1;
	int ret = 0;

	ka1 = keys_array_alloc();

	preproc(str1, ka1);

	sort_list_item_make_key(*ss2);

	if (debug_sort) {
		bwsprintf(stdout, str1, "; s1=<", ">");
		bwsprintf(stdout, (*ss2)->str, ", s2=<", ">");
	}

	ret = key_coll(ka1, &((*ss2)->ka), 0);

	if (debug_sort)
		printf("; cmp1=%d", ret);

	clean_keys_array(str1, ka1);
	sort_free(ka1);

	if ((ret == 0) && !(sort_opts_vals.sflag) && sort_opts_vals.complex_sort) {
		ret = top_level_str_coll(str1, ((*ss2)->str));
		if (debug_sort)
			printf("; cmp2=%d", ret);
	}

	if (debug_sort)
		printf("\n");

	return (ret);
}
Exemplo n.º 8
0
/*
 * Implements numeric sort for -n and -h.
 */
static int
numcoll_impl(struct key_value *kv1, struct key_value *kv2,
    size_t offset __unused, bool use_suffix)
{
	struct bwstring *s1, *s2;
	wchar_t sfrac1[MAX_NUM_SIZE + 1], sfrac2[MAX_NUM_SIZE + 1];
	wchar_t smain1[MAX_NUM_SIZE + 1], smain2[MAX_NUM_SIZE + 1];
	int cmp_res, sign1, sign2;
	size_t frac1, frac2, main1, main2;
	unsigned char SI1, SI2;
	bool e1, e2, key1_read, key2_read;

	s1 = kv1->k;
	s2 = kv2->k;
	sign1 = sign2 = 0;
	main1 = main2 = 0;
	frac1 = frac2 = 0;

	key1_read = key2_read = false;

	if (debug_sort) {
		bwsprintf(stdout, s1, "; k1=<", ">");
		bwsprintf(stdout, s2, ", k2=<", ">");
	}

	if (s1 == s2)
		return (0);

	if (kv1->hint->status == HS_UNINITIALIZED) {
		/* read the number from the string */
		read_number(s1, &sign1, smain1, &main1, sfrac1, &frac1, &SI1);
		key1_read = true;
		kv1->hint->v.nh.n1 = wcstoull(smain1, NULL, 10);
		if(main1 < 1 && frac1 < 1)
			kv1->hint->v.nh.empty=true;
		kv1->hint->v.nh.si = SI1;
		kv1->hint->status = (kv1->hint->v.nh.n1 != ULLONG_MAX) ?
		    HS_INITIALIZED : HS_ERROR;
		kv1->hint->v.nh.neg = (sign1 < 0) ? true : false;
	}

	if (kv2->hint->status == HS_UNINITIALIZED) {
		/* read the number from the string */
		read_number(s2, &sign2, smain2, &main2, sfrac2, &frac2,&SI2);
		key2_read = true;
		kv2->hint->v.nh.n1 = wcstoull(smain2, NULL, 10);
		if(main2 < 1 && frac2 < 1)
			kv2->hint->v.nh.empty=true;
		kv2->hint->v.nh.si = SI2;
		kv2->hint->status = (kv2->hint->v.nh.n1 != ULLONG_MAX) ?
		    HS_INITIALIZED : HS_ERROR;
		kv2->hint->v.nh.neg = (sign2 < 0) ? true : false;
	}

	if (kv1->hint->status == HS_INITIALIZED && kv2->hint->status ==
	    HS_INITIALIZED) {
		unsigned long long n1, n2;
		bool neg1, neg2;

		e1 = kv1->hint->v.nh.empty;
		e2 = kv2->hint->v.nh.empty;

		if (e1 && e2)
			return (0);

		neg1 = kv1->hint->v.nh.neg;
		neg2 = kv2->hint->v.nh.neg;

		if (neg1 && !neg2)
			return (-1);
		if (neg2 && !neg1)
			return (+1);

		if (e1)
			return (neg2 ? +1 : -1);
		else if (e2)
			return (neg1 ? -1 : +1);


		if (use_suffix) {
			cmp_res = cmpsuffix(kv1->hint->v.nh.si, kv2->hint->v.nh.si);
			if (cmp_res)
				return (neg1 ? -cmp_res : cmp_res);
		}

		n1 = kv1->hint->v.nh.n1;
		n2 = kv2->hint->v.nh.n1;
		if (n1 < n2)
			return (neg1 ? +1 : -1);
		else if (n1 > n2)
			return (neg1 ? -1 : +1);
	}

	/* read the numbers from the strings */
	if (!key1_read)
		read_number(s1, &sign1, smain1, &main1, sfrac1, &frac1, &SI1);
	if (!key2_read)
		read_number(s2, &sign2, smain2, &main2, sfrac2, &frac2, &SI2);

	e1 = ((main1 + frac1) == 0);
	e2 = ((main2 + frac2) == 0);

	if (e1 && e2)
		return (0);

	/* we know the result if the signs are different */
	if (sign1 < 0 && sign2 >= 0)
		return (-1);
	if (sign1 >= 0 && sign2 < 0)
		return (+1);

	if (e1)
		return ((sign2 < 0) ? +1 : -1);
	else if (e2)
		return ((sign1 < 0) ? -1 : +1);

	if (use_suffix) {
		cmp_res = cmpsuffix(SI1, SI2);
		if (cmp_res)
			return ((sign1 < 0) ? -cmp_res : cmp_res);
	}

	/* if both numbers are empty assume that the strings are equal */
	if (main1 < 1 && main2 < 1 && frac1 < 1 && frac2 < 1)
		return (0);

	/*
	 * if the main part is of different size, we know the result
	 * (because the leading zeros are removed)
	 */
	if (main1 < main2)
		cmp_res = -1;
	else if (main1 > main2)
		cmp_res = +1;
	/* if the sizes are equal then simple non-collate string compare gives the correct result */
	else
		cmp_res = wcscmp(smain1, smain2);

	/* check fraction */
	if (!cmp_res)
		cmp_res = wcscmp(sfrac1, sfrac2);

	if (!cmp_res)
		return (0);

	/* reverse result if the signs are negative */
	if (sign1 < 0 && sign2 < 0)
		cmp_res = -cmp_res;

	return (cmp_res);
}
Exemplo n.º 9
0
/*
 * Implements general numeric sort (-g).
 */
static int
gnumcoll(struct key_value *kv1, struct key_value *kv2,
    size_t offset __unused)
{
	double d1, d2;
	int err1, err2;
	bool empty1, empty2, key1_read, key2_read;

	d1 = d2 = 0;
	err1 = err2 = 0;
	key1_read = key2_read = false;

	if (debug_sort) {
		bwsprintf(stdout, kv1->k, "; k1=<", ">");
		bwsprintf(stdout, kv2->k, "; k2=<", ">");
	}

	if (kv1->hint->status == HS_UNINITIALIZED) {
		errno = 0;
		d1 = bwstod(kv1->k, &empty1);
		err1 = errno;

		if (empty1)
			kv1->hint->v.gh.notnum = true;
		else if (err1 == 0) {
			kv1->hint->v.gh.d = d1;
			kv1->hint->v.gh.nan = is_nan(d1);
			kv1->hint->status = HS_INITIALIZED;
		} else
			kv1->hint->status = HS_ERROR;

		key1_read = true;
	}

	if (kv2->hint->status == HS_UNINITIALIZED) {
		errno = 0;
		d2 = bwstod(kv2->k, &empty2);
		err2 = errno;

		if (empty2)
			kv2->hint->v.gh.notnum = true;
		else if (err2 == 0) {
			kv2->hint->v.gh.d = d2;
			kv2->hint->v.gh.nan = is_nan(d2);
			kv2->hint->status = HS_INITIALIZED;
		} else
			kv2->hint->status = HS_ERROR;

		key2_read = true;
	}

	if (kv1->hint->status == HS_INITIALIZED &&
	    kv2->hint->status == HS_INITIALIZED) {
		if (kv1->hint->v.gh.notnum)
			return ((kv2->hint->v.gh.notnum) ? 0 : -1);
		else if (kv2->hint->v.gh.notnum)
			return (+1);

		if (kv1->hint->v.gh.nan)
			return ((kv2->hint->v.gh.nan) ?
			    cmp_nans(kv1->hint->v.gh.d, kv2->hint->v.gh.d) :
			    -1);
		else if (kv2->hint->v.gh.nan)
			return (+1);

		d1 = kv1->hint->v.gh.d;
		d2 = kv2->hint->v.gh.d;

		if (d1 < d2)
			return (-1);
		else if (d1 > d2)
			return (+1);
		else
			return (0);
	}

	if (!key1_read) {
		errno = 0;
		d1 = bwstod(kv1->k, &empty1);
		err1 = errno;
	}

	if (!key2_read) {
		errno = 0;
		d2 = bwstod(kv2->k, &empty2);
		err2 = errno;
	}

	/* Non-value case: */
	if (empty1)
		return (empty2 ? 0 : -1);
	else if (empty2)
		return (+1);

	/* NAN case */
	if (is_nan(d1))
		return (is_nan(d2) ? cmp_nans(d1, d2) : -1);
	else if (is_nan(d2))
		return (+1);

	/* Infinities */
	if (err1 == ERANGE || err2 == ERANGE) {
		/* Minus infinity case */
		if (huge_minus(d1, err1)) {
			if (huge_minus(d2, err2)) {
				if (d1 < d2)
					return (-1);
				if (d1 > d2)
					return (+1);
				return (0);
			} else
				return (-1);

		} else if (huge_minus(d2, err2)) {
			if (huge_minus(d1, err1)) {
				if (d1 < d2)
					return (-1);
				if (d1 > d2)
					return (+1);
				return (0);
			} else
				return (+1);
		}

		/* Plus infinity case */
		if (huge_plus(d1, err1)) {
			if (huge_plus(d2, err2)) {
				if (d1 < d2)
					return (-1);
				if (d1 > d2)
					return (+1);
				return (0);
			} else
				return (+1);
		} else if (huge_plus(d2, err2)) {
			if (huge_plus(d1, err1)) {
				if (d1 < d2)
					return (-1);
				if (d1 > d2)
					return (+1);
				return (0);
			} else
				return (-1);
		}
	}

	if (d1 < d2)
		return (-1);
	if (d1 > d2)
		return (+1);

	return (0);
}