Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/string/strcoll.c
39476 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
5
* Copyright (c) 1995 Alex Tatmanjants <[email protected]>
6
* at Electronni Visti IA, Kiev, Ukraine.
7
* All rights reserved.
8
*
9
* Copyright (c) 2011 The FreeBSD Foundation
10
*
11
* Portions of this software were developed by David Chisnall
12
* under sponsorship from the FreeBSD Foundation.
13
*
14
* Redistribution and use in source and binary forms, with or without
15
* modification, are permitted provided that the following conditions
16
* are met:
17
* 1. Redistributions of source code must retain the above copyright
18
* notice, this list of conditions and the following disclaimer.
19
* 2. Redistributions in binary form must reproduce the above copyright
20
* notice, this list of conditions and the following disclaimer in the
21
* documentation and/or other materials provided with the distribution.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
24
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
27
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* SUCH DAMAGE.
34
*/
35
36
#include <stdlib.h>
37
#include <string.h>
38
#include <errno.h>
39
#include <wchar.h>
40
#include "collate.h"
41
42
43
/*
44
* In order to properly handle multibyte locales, its easiest to just
45
* convert to wide characters and then use wcscoll. However if an
46
* error occurs, we gracefully fall back to simple strcmp. Caller
47
* should check errno.
48
*/
49
int
50
strcoll_l(const char *s, const char *s2, locale_t locale)
51
{
52
int ret;
53
wchar_t *t1 = NULL, *t2 = NULL;
54
wchar_t *w1 = NULL, *w2 = NULL;
55
const char *cs1, *cs2;
56
mbstate_t mbs1;
57
mbstate_t mbs2;
58
size_t sz1, sz2;
59
60
memset(&mbs1, 0, sizeof (mbstate_t));
61
memset(&mbs2, 0, sizeof (mbstate_t));
62
63
/*
64
* The mbsrtowcs_l function can set the src pointer to null upon
65
* failure, so it should act on a copy to avoid:
66
* - sending null pointer to strcmp
67
* - having strcoll/strcoll_l change *s or *s2 to null
68
*/
69
cs1 = s;
70
cs2 = s2;
71
72
FIX_LOCALE(locale);
73
struct xlocale_collate *table =
74
(struct xlocale_collate*)locale->components[XLC_COLLATE];
75
76
if (table->__collate_load_error)
77
goto error;
78
79
sz1 = strlen(s) + 1;
80
sz2 = strlen(s2) + 1;
81
82
/*
83
* Simple assumption: conversion to wide format is strictly
84
* reducing, i.e. a single byte (or multibyte character)
85
* cannot result in multiple wide characters.
86
*/
87
if ((t1 = malloc(sz1 * sizeof (wchar_t))) == NULL)
88
goto error;
89
w1 = t1;
90
if ((t2 = malloc(sz2 * sizeof (wchar_t))) == NULL)
91
goto error;
92
w2 = t2;
93
94
if ((mbsrtowcs_l(w1, &cs1, sz1, &mbs1, locale)) == (size_t)-1)
95
goto error;
96
97
if ((mbsrtowcs_l(w2, &cs2, sz2, &mbs2, locale)) == (size_t)-1)
98
goto error;
99
100
ret = wcscoll_l(w1, w2, locale);
101
free(t1);
102
free(t2);
103
104
return (ret);
105
106
error:
107
free(t1);
108
free(t2);
109
return (strcmp(s, s2));
110
}
111
112
int
113
strcoll(const char *s, const char *s2)
114
{
115
return strcoll_l(s, s2, __get_locale());
116
}
117
118
119