2 * Copyright 2013 Garrett D'Amore <garrett@damore.org>
3 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
4 * Copyright (c) 2002 Tim J. Robbins
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include "localeimpl.h"
39 wcscoll_l(const wchar_t *ws1
, const wchar_t *ws2
, locale_t loc
)
41 int len1
, len2
, pri1
, pri2
, ret
;
42 wchar_t *tr1
= NULL
, *tr2
= NULL
;
44 const struct lc_collate
*lcc
= loc
->collate
;
48 * Locale has no special collating order or could not be
49 * loaded, do a fast binary comparison.
51 return (wcscmp(ws1
, ws2
));
56 * Once upon a time we had code to try to optimize this, but
57 * it turns out that you really can't make many assumptions
58 * safely. You absolutely have to run this pass by pass,
59 * because some passes will be ignored for a given character,
60 * while others will not. Simpler locales will benefit from
61 * having fewer passes, and most comparisons should resolve
62 * during the primary pass anyway.
64 * Note that we do one final extra pass at the end to pick
65 * up UNDEFINED elements. There is special handling for them.
67 for (pass
= 0; pass
<= lcc
->lc_directive_count
; pass
++) {
69 const int32_t *st1
= NULL
;
70 const int32_t *st2
= NULL
;
71 const wchar_t *w1
= ws1
;
72 const wchar_t *w2
= ws2
;
75 /* special pass for UNDEFINED */
76 if (pass
== lcc
->lc_directive_count
) {
77 direc
= DIRECTIVE_FORWARD
| DIRECTIVE_UNDEFINED
;
79 direc
= lcc
->lc_directive
[pass
];
82 if (direc
& DIRECTIVE_BACKWARD
) {
84 if ((tr1
= wcsdup(w1
)) == NULL
)
87 fp
= tr1
+ wcslen(tr1
) - 1;
93 if ((tr2
= wcsdup(w2
)) == NULL
)
96 fp
= tr2
+ wcslen(tr2
) - 1;
106 if (direc
& DIRECTIVE_POSITION
) {
110 while ((pri1
== pri2
) && (check1
|| check2
)) {
112 _collate_lookup(lcc
, w1
, &len1
,
119 pri1
= COLLATE_MAX_PRIORITY
;
122 check1
= (st1
!= NULL
);
125 _collate_lookup(lcc
, w2
, &len2
,
132 pri2
= COLLATE_MAX_PRIORITY
;
135 check2
= (st2
!= NULL
);
149 while ((pri1
== pri2
) && (check1
|| check2
)) {
150 while (check1
&& *w1
) {
151 _collate_lookup(lcc
, w1
, &len1
,
162 check1
= (st1
!= NULL
);
163 while (check2
&& *w2
) {
164 _collate_lookup(lcc
, w2
, &len2
,
175 check2
= (st2
!= NULL
);
208 ret
= wcscmp(ws1
, ws2
);
214 wcscoll(const wchar_t *ws1
, const wchar_t *ws2
)
216 return (wcscoll_l(ws1
, ws2
, uselocale(NULL
)));