Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libc/port/locale/wcscoll.c
+++ new/usr/src/lib/libc/port/locale/wcscoll.c
1 1 /*
2 + * Copyright 2013 Garrett D'Amore <garrett@damore.org>
2 3 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
3 4 * Copyright (c) 2002 Tim J. Robbins
4 5 * All rights reserved.
5 6 *
6 7 * Redistribution and use in source and binary forms, with or without
7 8 * modification, are permitted provided that the following conditions
8 9 * are met:
9 10 * 1. Redistributions of source code must retain the above copyright
10 11 * notice, this list of conditions and the following disclaimer.
11 12 * 2. Redistributions in binary form must reproduce the above copyright
12 13 * notice, this list of conditions and the following disclaimer in the
13 14 * documentation and/or other materials provided with the distribution.
14 15 *
15 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
25 26 * SUCH DAMAGE.
26 27 */
27 28
28 29 #include "lint.h"
29 30 #include <errno.h>
30 31 #include <stdlib.h>
31 32 #include <string.h>
32 33 #include <wchar.h>
33 34 #include <assert.h>
34 35 #include "collate.h"
36 +#include "localeimpl.h"
35 37
36 38 int
37 -wcscoll(const wchar_t *ws1, const wchar_t *ws2)
39 +wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc)
38 40 {
39 41 int len1, len2, pri1, pri2, ret;
40 42 wchar_t *tr1 = NULL, *tr2 = NULL;
41 43 int direc, pass;
44 + const struct lc_collate *lcc = loc->collate;
42 45
43 - collate_info_t *info = _collate_info;
44 -
45 - if (_collate_load_error)
46 + if (lcc->lc_is_posix)
46 47 /*
47 48 * Locale has no special collating order or could not be
48 49 * loaded, do a fast binary comparison.
49 50 */
50 51 return (wcscmp(ws1, ws2));
51 52
52 53 ret = 0;
53 54
54 55 /*
55 56 * Once upon a time we had code to try to optimize this, but
56 57 * it turns out that you really can't make many assumptions
57 58 * safely. You absolutely have to run this pass by pass,
58 59 * because some passes will be ignored for a given character,
59 60 * while others will not. Simpler locales will benefit from
60 61 * having fewer passes, and most comparisions should resolve
61 62 * during the primary pass anyway.
62 63 *
63 64 * Note that we do one final extra pass at the end to pick
64 65 * up UNDEFINED elements. There is special handling for them.
65 66 */
66 - for (pass = 0; pass <= info->directive_count; pass++) {
67 + for (pass = 0; pass <= lcc->lc_directive_count; pass++) {
67 68
68 - int32_t *st1 = NULL;
69 - int32_t *st2 = NULL;
69 + const int32_t *st1 = NULL;
70 + const int32_t *st2 = NULL;
70 71 const wchar_t *w1 = ws1;
71 72 const wchar_t *w2 = ws2;
72 73
73 74 /* special pass for UNDEFINED */
74 - if (pass == info->directive_count) {
75 + if (pass == lcc->lc_directive_count) {
75 76 direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED;
76 77 } else {
77 - direc = info->directive[pass];
78 + direc = lcc->lc_directive[pass];
78 79 }
79 80
80 81 if (direc & DIRECTIVE_BACKWARD) {
81 82 wchar_t *bp, *fp, c;
82 83 if ((tr1 = wcsdup(w1)) == NULL)
83 84 goto fail;
84 85 bp = tr1;
85 86 fp = tr1 + wcslen(tr1) - 1;
86 87 while (bp < fp) {
87 88 c = *bp;
88 89 *bp++ = *fp;
89 90 *fp-- = c;
90 91 }
91 92 if ((tr2 = wcsdup(w2)) == NULL)
92 93 goto fail;
93 94 bp = tr2;
94 95 fp = tr2 + wcslen(tr2) - 1;
95 96 while (bp < fp) {
96 97 c = *bp;
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
97 98 *bp++ = *fp;
98 99 *fp-- = c;
99 100 }
100 101 w1 = tr1;
101 102 w2 = tr2;
102 103 }
103 104
104 105 if (direc & DIRECTIVE_POSITION) {
105 106 while ((*w1 || st1) && (*w2 || st2)) {
106 107 pri1 = pri2 = 0;
107 - _collate_lookup(w1, &len1, &pri1, pass, &st1);
108 + _collate_lookup(lcc, w1, &len1, &pri1, pass,
109 + &st1);
108 110 if (pri1 <= 0) {
109 111 if (pri1 < 0) {
110 112 errno = EINVAL;
111 113 goto fail;
112 114 }
113 115 pri1 = COLLATE_MAX_PRIORITY;
114 116 }
115 - _collate_lookup(w2, &len2, &pri2, pass, &st2);
117 + _collate_lookup(lcc, w2, &len2, &pri2, pass,
118 + &st2);
116 119 if (pri2 <= 0) {
117 120 if (pri2 < 0) {
118 121 errno = EINVAL;
119 122 goto fail;
120 123 }
121 124 pri2 = COLLATE_MAX_PRIORITY;
122 125 }
123 126 if (pri1 != pri2) {
124 127 ret = pri1 - pri2;
125 128 goto end;
126 129 }
127 130 w1 += len1;
128 131 w2 += len2;
129 132 }
130 133 } else {
131 134 while ((*w1 || st1) && (*w2 || st2)) {
132 135 pri1 = pri2 = 0;
133 136 while (*w1) {
134 - _collate_lookup(w1, &len1,
137 + _collate_lookup(lcc, w1, &len1,
135 138 &pri1, pass, &st1);
136 139 if (pri1 > 0)
137 140 break;
138 141 if (pri1 < 0) {
139 142 errno = EINVAL;
140 143 goto fail;
141 144 }
142 145 w1 += len1;
143 146 }
144 147 while (*w2) {
145 - _collate_lookup(w2, &len2,
148 + _collate_lookup(lcc, w2, &len2,
146 149 &pri2, pass, &st2);
147 150 if (pri2 > 0)
148 151 break;
149 152 if (pri2 < 0) {
150 153 errno = EINVAL;
151 154 goto fail;
152 155 }
153 156 w2 += len2;
154 157 }
155 158 if (!pri1 || !pri2)
156 159 break;
157 160 if (pri1 != pri2) {
158 161 ret = pri1 - pri2;
159 162 goto end;
160 163 }
161 164 w1 += len1;
162 165 w2 += len2;
163 166 }
164 167 }
165 168 if (!*w1) {
166 169 if (*w2) {
167 170 ret = -(int)*w2;
168 171 goto end;
169 172 }
170 173 } else {
171 174 ret = *w1;
172 175 goto end;
173 176 }
174 177 }
175 178 ret = 0;
176 179
177 180 end:
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
178 181 if (tr1)
179 182 free(tr1);
180 183 if (tr2)
181 184 free(tr2);
182 185
183 186 return (ret);
184 187
185 188 fail:
186 189 ret = wcscmp(ws1, ws2);
187 190 goto end;
191 +}
192 +
193 +
194 +int
195 +wcscoll(const wchar_t *ws1, const wchar_t *ws2)
196 +{
197 + return (wcscoll_l(ws1, ws2, uselocale(NULL)));
188 198 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX