158f0484fSRodney W. Grimes /*- 2a4d5d0cbSAndrey A. Chernov * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 3a4d5d0cbSAndrey A. Chernov * at Electronni Visti IA, Kiev, Ukraine. 4a4d5d0cbSAndrey A. Chernov * All rights reserved. 558f0484fSRodney W. Grimes * 6*3c87aa1dSDavid Chisnall * Copyright (c) 2011 The FreeBSD Foundation 7*3c87aa1dSDavid Chisnall * All rights reserved. 8*3c87aa1dSDavid Chisnall * Portions of this software were developed by David Chisnall 9*3c87aa1dSDavid Chisnall * under sponsorship from the FreeBSD Foundation. 10*3c87aa1dSDavid Chisnall * 1158f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 1258f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 1358f0484fSRodney W. Grimes * are met: 1458f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 1558f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1658f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1758f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1858f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 1958f0484fSRodney W. Grimes * 20a4d5d0cbSAndrey A. Chernov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 2158f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2258f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23a4d5d0cbSAndrey A. Chernov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 2458f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2558f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2658f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2758f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2858f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2958f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3058f0484fSRodney W. Grimes * SUCH DAMAGE. 3158f0484fSRodney W. Grimes */ 3258f0484fSRodney W. Grimes 33de5fe5d5SDavid E. O'Brien #include <sys/cdefs.h> 34de5fe5d5SDavid E. O'Brien __FBSDID("$FreeBSD$"); 355864b79cSDavid E. O'Brien 36a4d5d0cbSAndrey A. Chernov #include <stdlib.h> 3758f0484fSRodney W. Grimes #include <string.h> 38a4d5d0cbSAndrey A. Chernov #include "collate.h" 3958f0484fSRodney W. Grimes 4058f0484fSRodney W. Grimes size_t 41*3c87aa1dSDavid Chisnall strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, locale_t loc); 42*3c87aa1dSDavid Chisnall size_t 4333f9b60eSRobert Drehmel strxfrm(char * __restrict dest, const char * __restrict src, size_t len) 4458f0484fSRodney W. Grimes { 45*3c87aa1dSDavid Chisnall return strxfrm_l(dest, src, len, __get_locale()); 46*3c87aa1dSDavid Chisnall } 47*3c87aa1dSDavid Chisnall 48*3c87aa1dSDavid Chisnall size_t 49*3c87aa1dSDavid Chisnall strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, locale_t locale) 50*3c87aa1dSDavid Chisnall { 51a4d5d0cbSAndrey A. Chernov int prim, sec, l; 52f0e6ee9fSAndrey A. Chernov size_t slen; 53f0e6ee9fSAndrey A. Chernov char *s, *ss; 54*3c87aa1dSDavid Chisnall FIX_LOCALE(locale); 55*3c87aa1dSDavid Chisnall struct xlocale_collate *table = 56*3c87aa1dSDavid Chisnall (struct xlocale_collate*)locale->components[XLC_COLLATE]; 57a4d5d0cbSAndrey A. Chernov 58a4d5d0cbSAndrey A. Chernov if (!*src) { 59f0e6ee9fSAndrey A. Chernov if (len > 0) 60f0e6ee9fSAndrey A. Chernov *dest = '\0'; 61a4d5d0cbSAndrey A. Chernov return 0; 6258f0484fSRodney W. Grimes } 63a4d5d0cbSAndrey A. Chernov 64*3c87aa1dSDavid Chisnall if (table->__collate_load_error) 65ecc61e2fSXin LI return strlcpy(dest, src, len); 66a4d5d0cbSAndrey A. Chernov 67f0e6ee9fSAndrey A. Chernov slen = 0; 68a4d5d0cbSAndrey A. Chernov prim = sec = 0; 69*3c87aa1dSDavid Chisnall ss = s = __collate_substitute(table, src); 70f0e6ee9fSAndrey A. Chernov while (*s) { 71a4d5d0cbSAndrey A. Chernov while (*s && !prim) { 72*3c87aa1dSDavid Chisnall __collate_lookup(table, s, &l, &prim, &sec); 73a4d5d0cbSAndrey A. Chernov s += l; 74a4d5d0cbSAndrey A. Chernov } 75a4d5d0cbSAndrey A. Chernov if (prim) { 76f0e6ee9fSAndrey A. Chernov if (len > 1) { 77f0e6ee9fSAndrey A. Chernov *dest++ = (char)prim; 78a4d5d0cbSAndrey A. Chernov len--; 79f0e6ee9fSAndrey A. Chernov } 80f0e6ee9fSAndrey A. Chernov slen++; 810ea569ffSAndrey A. Chernov prim = 0; 82a4d5d0cbSAndrey A. Chernov } 83a4d5d0cbSAndrey A. Chernov } 84a4d5d0cbSAndrey A. Chernov free(ss); 85f0e6ee9fSAndrey A. Chernov if (len > 0) 86f0e6ee9fSAndrey A. Chernov *dest = '\0'; 87a4d5d0cbSAndrey A. Chernov 88f0e6ee9fSAndrey A. Chernov return slen; 8958f0484fSRodney W. Grimes } 90