xref: /freebsd/lib/libc/string/wcsxfrm.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
1fd4f1dd9STim J. Robbins /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3d915a14eSPedro F. Giffuni  *
42a6abeebSBaptiste Daroussin  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
5fd4f1dd9STim J. Robbins  * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
6fd4f1dd9STim J. Robbins  *		at Electronni Visti IA, Kiev, Ukraine.
7fd4f1dd9STim J. Robbins  *			All rights reserved.
8fd4f1dd9STim J. Robbins  *
93c87aa1dSDavid Chisnall  * Copyright (c) 2011 The FreeBSD Foundation
105b5fa75aSEd Maste  *
113c87aa1dSDavid Chisnall  * Portions of this software were developed by David Chisnall
123c87aa1dSDavid Chisnall  * under sponsorship from the FreeBSD Foundation.
133c87aa1dSDavid Chisnall  *
14fd4f1dd9STim J. Robbins  * Redistribution and use in source and binary forms, with or without
15fd4f1dd9STim J. Robbins  * modification, are permitted provided that the following conditions
16fd4f1dd9STim J. Robbins  * are met:
17fd4f1dd9STim J. Robbins  * 1. Redistributions of source code must retain the above copyright
18fd4f1dd9STim J. Robbins  *    notice, this list of conditions and the following disclaimer.
19fd4f1dd9STim J. Robbins  * 2. Redistributions in binary form must reproduce the above copyright
20fd4f1dd9STim J. Robbins  *    notice, this list of conditions and the following disclaimer in the
21fd4f1dd9STim J. Robbins  *    documentation and/or other materials provided with the distribution.
22fd4f1dd9STim J. Robbins  *
23fd4f1dd9STim J. Robbins  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
24fd4f1dd9STim J. Robbins  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25fd4f1dd9STim J. Robbins  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26fd4f1dd9STim J. Robbins  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
27fd4f1dd9STim J. Robbins  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28fd4f1dd9STim J. Robbins  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29fd4f1dd9STim J. Robbins  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30fd4f1dd9STim J. Robbins  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31fd4f1dd9STim J. Robbins  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32fd4f1dd9STim J. Robbins  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33fd4f1dd9STim J. Robbins  * SUCH DAMAGE.
34fd4f1dd9STim J. Robbins  */
35fd4f1dd9STim J. Robbins 
36fd4f1dd9STim J. Robbins #include <stdlib.h>
37fd4f1dd9STim J. Robbins #include <string.h>
38fd4f1dd9STim J. Robbins #include <wchar.h>
39fd4f1dd9STim J. Robbins #include "collate.h"
40fd4f1dd9STim J. Robbins 
41fd4f1dd9STim J. Robbins size_t
wcsxfrm_l(wchar_t * __restrict dest,const wchar_t * __restrict src,size_t len,locale_t locale)423c87aa1dSDavid Chisnall wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len, locale_t locale)
43fd4f1dd9STim J. Robbins {
44fd4f1dd9STim J. Robbins 	size_t slen;
453c87aa1dSDavid Chisnall 	FIX_LOCALE(locale);
463c87aa1dSDavid Chisnall 	struct xlocale_collate *table =
473c87aa1dSDavid Chisnall 		(struct xlocale_collate*)locale->components[XLC_COLLATE];
48fd4f1dd9STim J. Robbins 
49fd4f1dd9STim J. Robbins 	if (*src == L'\0') {
50fd4f1dd9STim J. Robbins 		if (len != 0)
51fd4f1dd9STim J. Robbins 			*dest = L'\0';
52fd4f1dd9STim J. Robbins 		return (0);
53fd4f1dd9STim J. Robbins 	}
54fd4f1dd9STim J. Robbins 
552a6abeebSBaptiste Daroussin 	if ((table->__collate_load_error) ||
562a6abeebSBaptiste Daroussin 	    ((slen = _collate_wxfrm(table, src, dest, len)) == (size_t)-1)) {
572a6abeebSBaptiste Daroussin 		goto error;
582a6abeebSBaptiste Daroussin 	}
592a6abeebSBaptiste Daroussin 
602a6abeebSBaptiste Daroussin 	/* Add null termination at the correct location. */
612a6abeebSBaptiste Daroussin 	if (len > slen) {
622a6abeebSBaptiste Daroussin 		dest[slen] = 0;
632a6abeebSBaptiste Daroussin 	} else if (len) {
642a6abeebSBaptiste Daroussin 		dest[len-1] = 0;
652a6abeebSBaptiste Daroussin 	}
662a6abeebSBaptiste Daroussin 
672a6abeebSBaptiste Daroussin 	return (slen);
682a6abeebSBaptiste Daroussin 
692a6abeebSBaptiste Daroussin error:
70fd4f1dd9STim J. Robbins 	slen = wcslen(src);
71fd4f1dd9STim J. Robbins 	if (slen < len)
722a6abeebSBaptiste Daroussin 		(void) wcscpy(dest, src);
73aa8d1268SDimitry Andric 	else if (len > 0) {
742a6abeebSBaptiste Daroussin 		(void) wcsncpy(dest, src, len - 1);
75fd4f1dd9STim J. Robbins 		dest[len - 1] = L'\0';
76fd4f1dd9STim J. Robbins 	}
77fd4f1dd9STim J. Robbins 	return (slen);
78fd4f1dd9STim J. Robbins }
79fd4f1dd9STim J. Robbins 
803c87aa1dSDavid Chisnall size_t
wcsxfrm(wchar_t * __restrict dest,const wchar_t * __restrict src,size_t len)813c87aa1dSDavid Chisnall wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
823c87aa1dSDavid Chisnall {
833c87aa1dSDavid Chisnall 	return wcsxfrm_l(dest, src, len, __get_locale());
843c87aa1dSDavid Chisnall }
85