Esempio n. 1
0
__private_extern__ int
__collate_range_cmp(wchar_t c1, wchar_t c2, locale_t loc)
{
	static wchar_t s1[2], s2[2];

	s1[0] = c1;
	s2[0] = c2;
	return (wcscoll_l(s1, s2, loc));
}
Esempio n. 2
0
int _Locale_strwcmp(struct _Locale_collate *__loc,
                    const wchar_t *s1, size_t n1,
                    const wchar_t *s2, size_t n2) {
  int ret;
  wchar_t buf1[64], buf2[64];
  while (n1 > 0 && n2 > 0) {
    size_t bufsize1 = n1 < 63 ? n1 : 63;
    size_t bufsize2 = n2 < 63 ? n2 : 63;
    wcsncpy(buf1, s1, bufsize1); buf1[bufsize1] = 0;
    wcsncpy(buf2, s2, bufsize2); buf2[bufsize2] = 0;

    ret = wcscoll_l(buf1, buf2, (__c_locale)__loc);
    if (ret != 0) return ret;
    s1 += bufsize1; n1 -= bufsize1;
    s2 += bufsize2; n2 -= bufsize2;
  }
  return ret;
}
Esempio n. 3
0
int
strcoll_l(const char *s, const char *s2, locale_t loc)
{
	int ret;
	const wchar_t *t = NULL, *t2 = NULL;
	int sverrno;

	NORMALIZE_LOCALE(loc);
	if (loc->__collate_load_error || (t = __collate_mbstowcs(s, loc)) == NULL || (t2 = __collate_mbstowcs(s2, loc)) == NULL) {
		sverrno = errno;
		free((void *)t);
		free((void *)t2);
		errno = sverrno;
		return strcmp(s, s2);
	}

	ret = wcscoll_l(t, t2, loc);
	sverrno = errno;
	free((void *)t);
	free((void *)t2);
	errno = sverrno;

	return ret;
}
Esempio n. 4
0
int
wcscoll(const wchar_t *ws1, const wchar_t *ws2)
{
	return wcscoll_l(ws1, ws2, __get_locale());
}
Esempio n. 5
0
 static size_t coll(wchar_t const *left,wchar_t const *right,locale_t l)
 {
     return wcscoll_l(left,right,l);
 }
Esempio n. 6
0
/*
 * In order to properly handle multibyte locales, its easiest to just
 * convert to wide characters and then use wcscoll.  However if an
 * error occurs, we gracefully fall back to simple strcmp.  Caller
 * should check errno.
 */
int
strcoll_l(const char *s, const char *s2, locale_t locale)
{
	int ret;
	wchar_t *t1 = NULL, *t2 = NULL;
	wchar_t *w1 = NULL, *w2 = NULL;
	const char *cs1, *cs2;
	mbstate_t mbs1;
	mbstate_t mbs2;
	size_t sz1, sz2;

	memset(&mbs1, 0, sizeof (mbstate_t));
	memset(&mbs2, 0, sizeof (mbstate_t));

	/*
	 * The mbsrtowcs_l function can set the src pointer to null upon
	 * failure, so it should act on a copy to avoid:
	 *   - sending null pointer to strcmp
	 *   - having strcoll/strcoll_l change *s or *s2 to null
	 */
	cs1 = s;
	cs2 = s2;

	FIX_LOCALE(locale);
	struct xlocale_collate *table =
		(struct xlocale_collate*)locale->components[XLC_COLLATE];

	if (table->__collate_load_error)
		goto error;

	sz1 = strlen(s) + 1;
	sz2 = strlen(s2) + 1;

	/*
	 * Simple assumption: conversion to wide format is strictly
	 * reducing, i.e. a single byte (or multibyte character)
	 * cannot result in multiple wide characters.
	 */
	if ((t1 = malloc(sz1 * sizeof (wchar_t))) == NULL)
		goto error;
	w1 = t1;
	if ((t2 = malloc(sz2 * sizeof (wchar_t))) == NULL)
		goto error;
	w2 = t2;

	if ((mbsrtowcs_l(w1, &cs1, sz1, &mbs1, locale)) == (size_t)-1)
		goto error;

	if ((mbsrtowcs_l(w2, &cs2, sz2, &mbs2, locale)) == (size_t)-1)
		goto error;

	ret = wcscoll_l(w1, w2, locale);
	free(t1);
	free(t2);

	return (ret);

error:
	free(t1);
	free(t2);
	return (strcmp(s, s2));
}
Esempio n. 7
0
/*
 * In order to properly handle multibyte locales, its easiet to just
 * convert to wide characters and then use wcscoll.  However if an
 * error occurs, we gracefully fall back to simple strcmp.  Caller
 * should check errno.
 */
int
strcoll_l(const char *s1, const char *s2, locale_t loc)
{
	int ret;
	wchar_t *t1 = NULL, *t2 = NULL;
	wchar_t *w1 = NULL, *w2 = NULL;
	size_t sz1, sz2;
	const struct lc_collate *lcc = loc->collate;

	if (lcc->lc_is_posix)
		return (strcmp(s1, s2));

	sz1 = strlen(s1) + 1;
	sz2 = strlen(s2) + 1;

	/*
	 * Simple assumption: conversion to wide format is strictly
	 * reducing, i.e. a single byte (or multibyte character)
	 * cannot result in multiple wide characters.
	 *
	 * We gain a bit of performance by giving preference to alloca
	 * for small string allocations.
	 */
	if (sz1 > ALLOCA_LIMIT) {
		if ((t1 = malloc(sz1 * sizeof (wchar_t))) == NULL)
			goto error;
		w1 = t1;
	} else {
		if ((w1 = alloca(sz1 * sizeof (wchar_t))) == NULL)
			goto error;
	}
	if (sz2 > ALLOCA_LIMIT) {
		if ((t2 = malloc(sz2 * sizeof (wchar_t))) == NULL)
			goto error;
		w2 = t2;
	} else {
		if ((w2 = alloca(sz2 * sizeof (wchar_t))) == NULL)
			goto error;
	}

	if ((mbstowcs_l(w1, s1, sz1, loc)) == (size_t)-1)
		goto error;

	if ((mbstowcs_l(w2, s2, sz2, loc)) == (size_t)-1)
		goto error;

	ret = wcscoll_l(w1, w2, loc);
	if (t1)
		free(t1);
	if (t2)
		free(t2);

	return (ret);

error:
	if (t1)
		free(t1);
	if (t2)
		free(t2);
	return (strcmp(s1, s2));
}
Esempio n. 8
0
int
wcscoll(const wchar_t *s1, const wchar_t *s2)
{
	return wcscoll_l(s1, s2, _current_locale());
}