diff options
author | bapt <bapt@FreeBSD.org> | 2015-08-07 23:41:26 +0000 |
---|---|---|
committer | bapt <bapt@FreeBSD.org> | 2015-08-07 23:41:26 +0000 |
commit | 11a5726cda4d7b191129ed4220970bf8e00a8db6 (patch) | |
tree | 063f1101225b65ad20c1a8be3c96300b958d5a20 /lib/libc/string/wcsxfrm.c | |
parent | cbf6cdcbbb6c0212ee9911bbbe9e87053b54ab9f (diff) | |
download | FreeBSD-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.c | 84 |
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); -} |