]>
git.saurik.com Git - apple/libc.git/blob - string/FreeBSD/wcscoll.c
2 * Copyright (c) 2002 Tim J. Robbins
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: src/lib/libc/string/wcscoll.c,v 1.3 2004/04/07 09:47:56 tjr Exp $");
30 #include "xlocale_private.h"
38 #define NOTFORWARD (DIRECTIVE_BACKWARD | DIRECTIVE_POSITION)
41 wcscoll_l(const wchar_t *ws1
, const wchar_t *ws2
, locale_t loc
)
44 int len
, len2
, prim
, prim2
, sec
, sec2
, ret
, ret2
;
45 const wchar_t *t
, *t2
;
46 wchar_t *tt
= NULL
, *tt2
= NULL
;
47 wchar_t *tr
= NULL
, *tr2
= NULL
;
48 struct __collate_st_info
*info
;
50 NORMALIZE_LOCALE(loc
);
51 if (loc
->__collate_load_error
)
53 * Locale has no special collating order or could not be
54 * loaded, do a fast binary comparison.
56 return (wcscmp(ws1
, ws2
));
58 info
= &loc
->__lc_collate
->__info
;
62 if ((info
->directive
[0] & NOTFORWARD
) ||
63 (info
->directive
[1] & NOTFORWARD
) ||
64 (!(info
->flags
&& COLLATE_SUBST_DUP
) &&
65 (info
->subst_count
[0] > 0 || info
->subst_count
[1] > 0))) {
67 for(pass
= 0; pass
< info
->directive_count
; pass
++) {
68 direc
= info
->directive
[pass
];
69 if (pass
== 0 || !(info
->flags
& COLLATE_SUBST_DUP
)) {
71 tt
= __collate_substitute(ws1
, pass
, loc
);
73 tt2
= tt
? __collate_substitute(ws2
, pass
, loc
) : NULL
;
75 if (direc
& DIRECTIVE_BACKWARD
) {
77 tr
= __collate_wcsdup(tt
? tt
: ws1
);
79 fp
= tr
+ wcslen(tr
) - 1;
85 tr2
= __collate_wcsdup(tt2
? tt2
: ws2
);
87 fp
= tr2
+ wcslen(tr2
) - 1;
93 t
= (const wchar_t *)tr
;
94 t2
= (const wchar_t *)tr2
;
96 t
= (const wchar_t *)tt
;
97 t2
= (const wchar_t *)tt2
;
99 t
= (const wchar_t *)ws1
;
100 t2
= (const wchar_t *)ws2
;
102 if(direc
& DIRECTIVE_POSITION
) {
105 __collate_lookup_which(t
, &len
, &prim
, pass
, loc
);
112 prim
= COLLATE_MAX_PRIORITY
;
114 __collate_lookup_which(t2
, &len2
, &prim2
, pass
, loc
);
121 prim2
= COLLATE_MAX_PRIORITY
;
134 __collate_lookup_which(t
, &len
, &prim
, pass
, loc
);
145 __collate_lookup_which(t2
, &len2
, &prim2
, pass
, loc
);
179 /* optimized common case: order_start forward;forward and duplicate
180 * (or no) substitute tables */
181 tt
= __collate_substitute(ws1
, 0, loc
);
184 t
= (const wchar_t *)ws1
;
185 t2
= (const wchar_t *)ws2
;
187 tt2
= __collate_substitute(ws2
, 0, loc
);
188 t
= (const wchar_t *)tt
;
189 t2
= (const wchar_t *)tt2
;
194 __collate_lookup_l(t
, &len
, &prim
, &sec
, loc
);
205 __collate_lookup_l(t2
, &len2
, &prim2
, &sec2
, loc
);
244 wcscoll(const wchar_t *ws1
, const wchar_t *ws2
)
246 return wcscoll_l(ws1
, ws2
, __current_locale());