summaryrefslogtreecommitdiffstats
path: root/lib/libc/string/wcsxfrm.c
diff options
context:
space:
mode:
authorbapt <bapt@FreeBSD.org>2015-08-07 23:41:26 +0000
committerbapt <bapt@FreeBSD.org>2015-08-07 23:41:26 +0000
commit11a5726cda4d7b191129ed4220970bf8e00a8db6 (patch)
tree063f1101225b65ad20c1a8be3c96300b958d5a20 /lib/libc/string/wcsxfrm.c
parentcbf6cdcbbb6c0212ee9911bbbe9e87053b54ab9f (diff)
downloadFreeBSD-src-11a5726cda4d7b191129ed4220970bf8e00a8db6.zip
FreeBSD-src-11a5726cda4d7b191129ed4220970bf8e00a8db6.tar.gz
The collate functions within libc have been using version 1 and 1.2 of the
packed LC_COLLATE binary formats. These were generated with the colldef tool, but the new LC_COLLATE files are going to be generated by the new localedef tool using CLDR POSIX files as input. The BSD-flavored version of localedef identifies the format as "BSD 1.0". Any LC_COLLATE file with a different version will simply not be loaded, and all LC* categories will get set to "C" (aka "POSIX") locale. This work is based off of Nexenta's contribution to Illumos. The integration with xlocale is John Marino's work for Dragonfly. The following commits will enable localedef tool, disable the colldef tool, add generated colldef directory, and finally remove colldef from base. The only difference with Dragonfly are: - a few fixes to build with clang - And identification of the flavor as "BSD 1.0" instead of "Dragonfly 4.4" Obtained from: Dragonfly
Diffstat (limited to 'lib/libc/string/wcsxfrm.c')
-rw-r--r--lib/libc/string/wcsxfrm.c84
1 files changed, 20 insertions, 64 deletions
diff --git a/lib/libc/string/wcsxfrm.c b/lib/libc/string/wcsxfrm.c
index cea667e..3d6c960 100644
--- a/lib/libc/string/wcsxfrm.c
+++ b/lib/libc/string/wcsxfrm.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
* at Electronni Visti IA, Kiev, Ukraine.
* All rights reserved.
@@ -31,9 +32,6 @@
*/
#include <sys/cdefs.h>
-#if 0
-__FBSDID("FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp ");
-#endif
__FBSDID("$FreeBSD$");
#include <stdlib.h>
@@ -41,18 +39,10 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
#include "collate.h"
-static char *__mbsdup(const wchar_t *);
-
-/*
- * Placeholder wcsxfrm() implementation. See wcscoll.c for a description of
- * the logic used.
- */
size_t
wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len, locale_t locale)
{
- int prim, sec, l;
size_t slen;
- char *mbsrc, *s, *ss;
FIX_LOCALE(locale);
struct xlocale_collate *table =
(struct xlocale_collate*)locale->components[XLC_COLLATE];
@@ -63,67 +53,33 @@ wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len,
return (0);
}
- if (table->__collate_load_error || MB_CUR_MAX > 1) {
- slen = wcslen(src);
- if (len > 0) {
- if (slen < len)
- wcscpy(dest, src);
- else {
- wcsncpy(dest, src, len - 1);
- dest[len - 1] = L'\0';
- }
- }
- return (slen);
+ if ((table->__collate_load_error) ||
+ ((slen = _collate_wxfrm(table, src, dest, len)) == (size_t)-1)) {
+ goto error;
}
- mbsrc = __mbsdup(src);
- slen = 0;
- prim = sec = 0;
- ss = s = __collate_substitute(table, mbsrc);
- while (*s != '\0') {
- while (*s != '\0' && prim == 0) {
- __collate_lookup(table, s, &l, &prim, &sec);
- s += l;
- }
- if (prim != 0) {
- if (len > 1) {
- *dest++ = (wchar_t)prim;
- len--;
- }
- slen++;
- prim = 0;
- }
+ /* Add null termination at the correct location. */
+ if (len > slen) {
+ dest[slen] = 0;
+ } else if (len) {
+ dest[len-1] = 0;
}
- free(ss);
- free(mbsrc);
- if (len != 0)
- *dest = L'\0';
return (slen);
+
+error:
+ slen = wcslen(src);
+ if (slen < len)
+ (void) wcscpy(dest, src);
+ else {
+ (void) wcsncpy(dest, src, len - 1);
+ dest[len - 1] = L'\0';
+ }
+ return (slen);
}
+
size_t
wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
{
return wcsxfrm_l(dest, src, len, __get_locale());
}
-
-static char *
-__mbsdup(const wchar_t *ws)
-{
- static const mbstate_t initial;
- mbstate_t st;
- const wchar_t *wcp;
- size_t len;
- char *mbs;
-
- wcp = ws;
- st = initial;
- if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1)
- return (NULL);
- if ((mbs = malloc(len + 1)) == NULL)
- return (NULL);
- st = initial;
- wcsrtombs(mbs, &ws, len + 1, &st);
-
- return (mbs);
-}
OpenPOWER on IntegriCloud