/src/server/strings/strcoll.inl
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright (c) 2015, MariaDB Foundation |
3 | | Copyright (c) 2015, 2020, MariaDB Corporation. |
4 | | |
5 | | This program is free software; you can redistribute it and/or modify |
6 | | it under the terms of the GNU General Public License as published by |
7 | | the Free Software Foundation; version 2 of the License. |
8 | | |
9 | | This program is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with this program; if not, write to the Free Software |
16 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA |
17 | | */ |
18 | | |
19 | | #include "ctype-ascii.h" |
20 | | |
21 | | #ifndef MY_FUNCTION_NAME |
22 | | #error MY_FUNCTION_NAME is not defined |
23 | | #endif |
24 | | |
25 | | /* |
26 | | Define strnncoll() and strnncollsp() by default, |
27 | | unless "#define DEFINE_STRNNCOLL 0" is specified. |
28 | | */ |
29 | | #ifndef DEFINE_STRNNCOLL |
30 | | #define DEFINE_STRNNCOLL 1 |
31 | | #endif |
32 | | |
33 | | |
34 | | /* |
35 | | The weight for automatically padded spaces when comparing strings with |
36 | | the PAD SPACE property. |
37 | | Should normally be equal to the weight of a regular space. |
38 | | */ |
39 | | #ifndef WEIGHT_PAD_SPACE |
40 | 0 | #define WEIGHT_PAD_SPACE (' ') |
41 | | #endif |
42 | | |
43 | | |
44 | | /* |
45 | | For binary collations: |
46 | | - on 32bit platforms perform only 4 byte optimization |
47 | | - on 64bit platforms perform both 4 byte and 8 byte optimization |
48 | | */ |
49 | | #if defined(STRCOLL_MB7_BIN) |
50 | 0 | #define MY_STRCOLL_MB7_4BYTES(a,b) my_strcoll_mb7_bin_4bytes((a),(b)) |
51 | | #if SIZEOF_VOIDP == 8 |
52 | | #define STRCOLL_MB7_8BYTES |
53 | 0 | #define MY_STRCOLL_MB7_8BYTES(a,b) my_strcoll_mb7_bin_8bytes((a),(b)) |
54 | | #endif /* Architecture test */ |
55 | | #endif /* STRCOLL_MB7_BIN */ |
56 | | |
57 | | |
58 | | /* |
59 | | For case insensitive collations with trivial mapping from [a-z] to [A-Z] |
60 | | perform optimization only on 64 bit platforms. |
61 | | There is no sense to perform my_ascii_to_upper_magic_uint64() based |
62 | | optimization on 32bit platforms. The idea of this optimization |
63 | | is that it handles 8bytes at a time, using 64bit CPU registers. |
64 | | Enabling this optimization on 32bit platform may only slow things down. |
65 | | */ |
66 | | #if defined(STRCOLL_MB7_TOUPPER) |
67 | | #if SIZEOF_VOIDP == 8 |
68 | 0 | #define MY_STRCOLL_MB7_4BYTES(a,b) my_strcoll_ascii_toupper_4bytes((a),(b)) |
69 | 0 | #define MY_STRCOLL_MB7_8BYTES(a,b) my_strcoll_ascii_toupper_8bytes((a),(b)) |
70 | | #endif /* Architecture test */ |
71 | | #endif /* STRCOLL_MB7_TOUPPER */ |
72 | | |
73 | | |
74 | | /* |
75 | | A helper macro to shift two pointers forward, to the given amount. |
76 | | */ |
77 | 0 | #define MY_STRING_SHIFT_PTR_PTR(a,b,len) do { a+= len; b+= len; } while(0) |
78 | | |
79 | | |
80 | | /* |
81 | | Weight of an illegal byte, must follow these rules: |
82 | | 1. Must be greater than weight of any normal character in the collation. |
83 | | 2. Two different bad bytes must have different weights and must be |
84 | | compared in their binary order. |
85 | | |
86 | | Depends on mbmaxlen of the character set, as well as how the collation |
87 | | sorts various single-byte and multi-byte character blocks. |
88 | | |
89 | | The macro below is the default definition, it is suitable for mbmaxlen=2 |
90 | | character sets that sort all multi-byte characters after all single-byte |
91 | | characters: big5, euckr, gb2312, gbk. |
92 | | |
93 | | All mbmaxlen>2 character sets must provide their own definitions. |
94 | | All collations that have a more complex order (than just MB1 followed by MB2) |
95 | | must also provide their own definitions (see definitions for |
96 | | cp932_japanese_ci and sjis_japanese_ci as examples of a more complex order). |
97 | | */ |
98 | | #ifndef WEIGHT_ILSEQ |
99 | 0 | #define WEIGHT_ILSEQ(x) (0xFF00 + (x)) |
100 | | #endif |
101 | | |
102 | | |
103 | | #if defined(WEIGHT_SIZE) && WEIGHT_SIZE == 3 |
104 | 0 | #define PUT_WC_BE_HAVE_1BYTE(dst, de, wc) PUT_WC_BE3_HAVE_1BYTE((dst), (de), (wc)) |
105 | 0 | #define PAD_NWEIGHTS_UNICODE_BE(str, end, n) my_strxfrm_pad_nweights_unicode_be3(str, end, n) |
106 | 0 | #define PAD_UNICODE_BE(str, end) my_strxfrm_pad_unicode_be3(str, end) |
107 | | #else |
108 | 0 | #define WEIGHT_SIZE 2 |
109 | 0 | #define PUT_WC_BE_HAVE_1BYTE(dst, de, wc) PUT_WC_BE2_HAVE_1BYTE((dst), (de), (wc)) |
110 | 0 | #define PAD_NWEIGHTS_UNICODE_BE(str, end, n) my_strxfrm_pad_nweights_unicode_be2(str, end, n) |
111 | 0 | #define PAD_UNICODE_BE(str, end) my_strxfrm_pad_unicode_be2(str, end) |
112 | | #endif |
113 | | |
114 | | |
115 | | #if DEFINE_STRNNCOLL |
116 | | |
117 | | /** |
118 | | Scan a valid character, or a bad byte, or an auto-padded space |
119 | | from a string and calculate the weight of the scanned sequence. |
120 | | |
121 | | @param [OUT] weight - the weight is returned here |
122 | | @param str - the string |
123 | | @param end - the end of the string |
124 | | @return - the number of bytes scanned |
125 | | |
126 | | The including source file must define the following macros: |
127 | | IS_MB1_CHAR(b0) - for character sets that have MB1 characters |
128 | | IS_MB1_MB2HEAD_GAP(b0) - optional, for better performance |
129 | | IS_MB2_CHAR(b0,b1) - for character sets that have MB2 characters |
130 | | IS_MB3_CHAR(b0,b1,b2) - for character sets that have MB3 characters |
131 | | IS_MB4_CHAR(b0,b1,b2,b3) - for character sets with have MB4 characters |
132 | | WEIGHT_PAD_SPACE |
133 | | WEIGHT_MB1(b0) - for character sets that have MB1 characters |
134 | | WEIGHT_MB2(b0,b1) - for character sets that have MB2 characters |
135 | | WEIGHT_MB3(b0,b1,b2) - for character sets that have MB3 characters |
136 | | WEIGHT_MB4(b0,b1,b2,b3) - for character sets that have MB4 characters |
137 | | WEIGHT_ILSEQ(x) |
138 | | */ |
139 | | static inline uint |
140 | | MY_FUNCTION_NAME(scan_weight)(int *weight, const uchar *str, const uchar *end) |
141 | 0 | { |
142 | 0 | if (str >= end) |
143 | 0 | { |
144 | 0 | *weight= WEIGHT_PAD_SPACE; |
145 | 0 | return 0; |
146 | 0 | } |
147 | | |
148 | | #ifdef IS_MB1_CHAR |
149 | 0 | if (IS_MB1_CHAR(*str)) |
150 | 0 | { |
151 | 0 | *weight= WEIGHT_MB1(*str); /* A valid single byte character*/ |
152 | 0 | return 1; |
153 | 0 | } |
154 | 0 | #endif |
155 | | |
156 | | #ifdef IS_MB1_MBHEAD_UNUSED_GAP |
157 | | /* |
158 | | Quickly filter out unused bytes that are neither MB1 nor MBHEAD. |
159 | | E.g. [0x80..0xC1] in utf8mb(3|4). This allows using simplified conditions |
160 | | in IS_MB2_CHAR(), IS_MB3_CHAR(), etc. |
161 | | */ |
162 | 0 | if (IS_MB1_MBHEAD_UNUSED_GAP(*str)) |
163 | 0 | goto bad; |
164 | 0 | #endif |
165 | | |
166 | | #ifdef IS_MB2_CHAR |
167 | 0 | if (str + 2 > end) /* The string ended unexpectedly */ |
168 | 0 | goto bad; /* Treat as a bad byte */ |
169 | | |
170 | 0 | if (IS_MB2_CHAR(str[0], str[1])) |
171 | 0 | { |
172 | 0 | *weight= WEIGHT_MB2(str[0], str[1]); |
173 | 0 | return 2; /* A valid two-byte character */ |
174 | 0 | } |
175 | 0 | #endif |
176 | | |
177 | | #ifdef IS_MB3_CHAR |
178 | 0 | if (str + 3 > end) /* Incomplete three-byte character */ |
179 | 0 | goto bad; |
180 | | |
181 | 0 | if (IS_MB3_CHAR(str[0], str[1], str[2])) |
182 | 0 | { |
183 | 0 | *weight= WEIGHT_MB3(str[0], str[1], str[2]); |
184 | 0 | return 3; /* A valid three-byte character */ |
185 | 0 | } |
186 | 0 | #endif |
187 | | |
188 | | #ifdef IS_MB4_CHAR |
189 | 0 | if (str + 4 > end) /* Incomplete four-byte character */ |
190 | 0 | goto bad; |
191 | | |
192 | 0 | if (IS_MB4_CHAR(str[0], str[1], str[2], str[3])) |
193 | 0 | { |
194 | 0 | *weight= WEIGHT_MB4(str[0], str[1], str[2], str[3]); |
195 | 0 | return 4; /* A valid four-byte character */ |
196 | 0 | } |
197 | | |
198 | 0 | #endif |
199 | | |
200 | 0 | bad: |
201 | 0 | *weight= WEIGHT_ILSEQ(str[0]); /* Bad byte */ |
202 | 0 | return 1; |
203 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16le_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16le_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf16le_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf32_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf32_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_utf32_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_ucs2_general_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_ucs2_general_mysql500_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_ucs2_bin Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_ucs2_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_scan_weight_ucs2_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb3_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb3_general1400_as_ci Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb3_bin Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb3_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb3_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb4_general_ci Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb4_bin Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb4_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb4_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_scan_weight_utf8mb4_general1400_as_ci Unexecuted instantiation: ctype-big5.c:my_scan_weight_big5_chinese_ci Unexecuted instantiation: ctype-big5.c:my_scan_weight_big5_bin Unexecuted instantiation: ctype-big5.c:my_scan_weight_big5_chinese_nopad_ci Unexecuted instantiation: ctype-big5.c:my_scan_weight_big5_nopad_bin Unexecuted instantiation: ctype-cp932.c:my_scan_weight_cp932_japanese_ci Unexecuted instantiation: ctype-cp932.c:my_scan_weight_cp932_bin Unexecuted instantiation: ctype-cp932.c:my_scan_weight_cp932_japanese_nopad_ci Unexecuted instantiation: ctype-cp932.c:my_scan_weight_cp932_nopad_bin Unexecuted instantiation: ctype-euc_kr.c:my_scan_weight_euckr_korean_ci Unexecuted instantiation: ctype-euc_kr.c:my_scan_weight_euckr_bin Unexecuted instantiation: ctype-euc_kr.c:my_scan_weight_euckr_korean_nopad_ci Unexecuted instantiation: ctype-euc_kr.c:my_scan_weight_euckr_nopad_bin Unexecuted instantiation: ctype-eucjpms.c:my_scan_weight_eucjpms_japanese_ci Unexecuted instantiation: ctype-eucjpms.c:my_scan_weight_eucjpms_bin Unexecuted instantiation: ctype-eucjpms.c:my_scan_weight_eucjpms_japanese_nopad_ci Unexecuted instantiation: ctype-eucjpms.c:my_scan_weight_eucjpms_nopad_bin Unexecuted instantiation: ctype-gb2312.c:my_scan_weight_gb2312_chinese_ci Unexecuted instantiation: ctype-gb2312.c:my_scan_weight_gb2312_bin Unexecuted instantiation: ctype-gb2312.c:my_scan_weight_gb2312_chinese_nopad_ci Unexecuted instantiation: ctype-gb2312.c:my_scan_weight_gb2312_nopad_bin Unexecuted instantiation: ctype-gbk.c:my_scan_weight_gbk_chinese_ci Unexecuted instantiation: ctype-gbk.c:my_scan_weight_gbk_bin Unexecuted instantiation: ctype-gbk.c:my_scan_weight_gbk_chinese_nopad_ci Unexecuted instantiation: ctype-gbk.c:my_scan_weight_gbk_nopad_bin Unexecuted instantiation: ctype-sjis.c:my_scan_weight_sjis_japanese_ci Unexecuted instantiation: ctype-sjis.c:my_scan_weight_sjis_bin Unexecuted instantiation: ctype-sjis.c:my_scan_weight_sjis_japanese_nopad_ci Unexecuted instantiation: ctype-sjis.c:my_scan_weight_sjis_nopad_bin Unexecuted instantiation: ctype-ujis.c:my_scan_weight_ujis_japanese_ci Unexecuted instantiation: ctype-ujis.c:my_scan_weight_ujis_bin Unexecuted instantiation: ctype-ujis.c:my_scan_weight_ujis_japanese_nopad_ci Unexecuted instantiation: ctype-ujis.c:my_scan_weight_ujis_nopad_bin |
204 | | |
205 | | |
206 | | /** |
207 | | Compare two strings according to the collation, |
208 | | without handling the PAD SPACE property. |
209 | | |
210 | | Note, strnncoll() is usually used to compare identifiers. |
211 | | Perhaps we should eventually (in 10.2?) create a new collation |
212 | | my_charset_utf8mb3_general_ci_no_pad and have only one comparison function |
213 | | in MY_COLLATION_HANDLER. |
214 | | |
215 | | @param cs - the character set and collation |
216 | | @param a - the left string |
217 | | @param a_length - the length of the left string |
218 | | @param b - the right string |
219 | | @param b_length - the length of the right string |
220 | | @param b_is_prefix - if the caller wants to check if "b" is a prefix of "a" |
221 | | @return - the comparison result |
222 | | */ |
223 | | static int |
224 | | MY_FUNCTION_NAME(strnncoll)(CHARSET_INFO *cs __attribute__((unused)), |
225 | | const uchar *a, size_t a_length, |
226 | | const uchar *b, size_t b_length, |
227 | | my_bool b_is_prefix) |
228 | 0 | { |
229 | 0 | const uchar *a_end= a + a_length; |
230 | 0 | const uchar *b_end= b + b_length; |
231 | 0 | for ( ; ; ) |
232 | 0 | { |
233 | 0 | int a_weight, b_weight, res; |
234 | 0 | uint a_wlen= MY_FUNCTION_NAME(scan_weight)(&a_weight, a, a_end); |
235 | 0 | uint b_wlen; |
236 | |
|
237 | | #ifdef MY_STRCOLL_MB7_4BYTES |
238 | 0 | if (a_wlen == 1 && my_strcoll_ascii_4bytes_found(a, a_end, b, b_end)) |
239 | 0 | { |
240 | 0 | int res; |
241 | 0 | #ifdef MY_STRCOLL_MB7_8BYTES |
242 | | /*TODO: a a loop here >='a' <='z' here, for automatic vectorization*/ |
243 | 0 | if (my_strcoll_ascii_4bytes_found(a + 4, a_end, b + 4, b_end)) |
244 | 0 | { |
245 | 0 | if ((res= MY_STRCOLL_MB7_8BYTES(a, b))) |
246 | 0 | return res; |
247 | 0 | MY_STRING_SHIFT_PTR_PTR(a, b, 8); |
248 | 0 | continue; |
249 | 0 | } |
250 | 0 | #endif |
251 | 0 | if ((res= MY_STRCOLL_MB7_4BYTES(a, b))) |
252 | 0 | return res; |
253 | 0 | MY_STRING_SHIFT_PTR_PTR(a, b, 4); |
254 | 0 | continue; |
255 | 0 | } |
256 | 0 | #endif /* MY_STRCOLL_MB7_4BYTES */ |
257 | | |
258 | 0 | b_wlen= MY_FUNCTION_NAME(scan_weight)(&b_weight, b, b_end); |
259 | | |
260 | | /* |
261 | | a_wlen b_wlen Comment |
262 | | ------ ------ ------- |
263 | | 0 0 Strings ended simultaneously, "a" and "b" are equal. |
264 | | 0 >0 "a" is a prefix of "b", so "a" is smaller. |
265 | | >0 0 "b" is a prefix of "a", check b_is_prefix. |
266 | | >0 >0 Two weights were scanned, check weight difference. |
267 | | |
268 | | Note: weights can be zero and positive (never negative). |
269 | | */ |
270 | 0 | if (!a_wlen) |
271 | 0 | return b_wlen ? -1 : 0; |
272 | | |
273 | 0 | if (!b_wlen) |
274 | 0 | return b_is_prefix ? 0 : +1; |
275 | | |
276 | 0 | if ((res= (a_weight - b_weight))) |
277 | 0 | return res; |
278 | | /* |
279 | | None of the strings has ended yet. |
280 | | */ |
281 | 0 | DBUG_ASSERT(a < a_end); |
282 | 0 | DBUG_ASSERT(b < b_end); |
283 | 0 | a+= a_wlen; |
284 | 0 | b+= b_wlen; |
285 | 0 | } |
286 | 0 | DBUG_ASSERT(0); |
287 | 0 | return 0; |
288 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16le_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16le_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf16le_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf32_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf32_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_utf32_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_ucs2_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_ucs2_general_mysql500_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_ucs2_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_ucs2_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncoll_ucs2_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb3_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb3_general1400_as_ci Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb3_bin Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb3_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb3_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb4_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb4_bin Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb4_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb4_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncoll_utf8mb4_general1400_as_ci Unexecuted instantiation: ctype-big5.c:my_strnncoll_big5_chinese_ci Unexecuted instantiation: ctype-big5.c:my_strnncoll_big5_bin Unexecuted instantiation: ctype-big5.c:my_strnncoll_big5_chinese_nopad_ci Unexecuted instantiation: ctype-big5.c:my_strnncoll_big5_nopad_bin Unexecuted instantiation: ctype-cp932.c:my_strnncoll_cp932_japanese_ci Unexecuted instantiation: ctype-cp932.c:my_strnncoll_cp932_bin Unexecuted instantiation: ctype-cp932.c:my_strnncoll_cp932_japanese_nopad_ci Unexecuted instantiation: ctype-cp932.c:my_strnncoll_cp932_nopad_bin Unexecuted instantiation: ctype-euc_kr.c:my_strnncoll_euckr_korean_ci Unexecuted instantiation: ctype-euc_kr.c:my_strnncoll_euckr_bin Unexecuted instantiation: ctype-euc_kr.c:my_strnncoll_euckr_korean_nopad_ci Unexecuted instantiation: ctype-euc_kr.c:my_strnncoll_euckr_nopad_bin Unexecuted instantiation: ctype-eucjpms.c:my_strnncoll_eucjpms_japanese_ci Unexecuted instantiation: ctype-eucjpms.c:my_strnncoll_eucjpms_bin Unexecuted instantiation: ctype-eucjpms.c:my_strnncoll_eucjpms_japanese_nopad_ci Unexecuted instantiation: ctype-eucjpms.c:my_strnncoll_eucjpms_nopad_bin Unexecuted instantiation: ctype-gb2312.c:my_strnncoll_gb2312_chinese_ci Unexecuted instantiation: ctype-gb2312.c:my_strnncoll_gb2312_bin Unexecuted instantiation: ctype-gb2312.c:my_strnncoll_gb2312_chinese_nopad_ci Unexecuted instantiation: ctype-gb2312.c:my_strnncoll_gb2312_nopad_bin Unexecuted instantiation: ctype-gbk.c:my_strnncoll_gbk_chinese_ci Unexecuted instantiation: ctype-gbk.c:my_strnncoll_gbk_bin Unexecuted instantiation: ctype-gbk.c:my_strnncoll_gbk_chinese_nopad_ci Unexecuted instantiation: ctype-gbk.c:my_strnncoll_gbk_nopad_bin Unexecuted instantiation: ctype-sjis.c:my_strnncoll_sjis_japanese_ci Unexecuted instantiation: ctype-sjis.c:my_strnncoll_sjis_bin Unexecuted instantiation: ctype-sjis.c:my_strnncoll_sjis_japanese_nopad_ci Unexecuted instantiation: ctype-sjis.c:my_strnncoll_sjis_nopad_bin Unexecuted instantiation: ctype-ujis.c:my_strnncoll_ujis_japanese_ci Unexecuted instantiation: ctype-ujis.c:my_strnncoll_ujis_bin Unexecuted instantiation: ctype-ujis.c:my_strnncoll_ujis_japanese_nopad_ci Unexecuted instantiation: ctype-ujis.c:my_strnncoll_ujis_nopad_bin |
289 | | |
290 | | |
291 | | #ifdef DEFINE_STRNNCOLLSP_NOPAD |
292 | | |
293 | | /** |
294 | | Compare two strings according to the collation, with NO PAD handling. |
295 | | |
296 | | @param cs - the character set and collation |
297 | | @param a - the left string |
298 | | @param a_length - the length of the left string |
299 | | @param b - the right string |
300 | | @param b_length - the length of the right string |
301 | | @return - the comparison result |
302 | | */ |
303 | | static int |
304 | | MY_FUNCTION_NAME(strnncollsp)(CHARSET_INFO *cs __attribute__((unused)), |
305 | | const uchar *a, size_t a_length, |
306 | | const uchar *b, size_t b_length) |
307 | 0 | { |
308 | 0 | return MY_FUNCTION_NAME(strnncoll)(cs, a, a_length, b, b_length, FALSE); |
309 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16le_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16le_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf32_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf32_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_ucs2_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_ucs2_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb3_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb3_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb4_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb4_nopad_bin Unexecuted instantiation: ctype-big5.c:my_strnncollsp_big5_chinese_nopad_ci Unexecuted instantiation: ctype-big5.c:my_strnncollsp_big5_nopad_bin Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_cp932_japanese_nopad_ci Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_cp932_nopad_bin Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_euckr_korean_nopad_ci Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_euckr_nopad_bin Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_eucjpms_japanese_nopad_ci Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_eucjpms_nopad_bin Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_gb2312_chinese_nopad_ci Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_gb2312_nopad_bin Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_gbk_chinese_nopad_ci Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_gbk_nopad_bin Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_sjis_japanese_nopad_ci Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_sjis_nopad_bin Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_ujis_japanese_nopad_ci Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_ujis_nopad_bin |
310 | | #else |
311 | | /** |
312 | | Compare two strings according to the collation, with PAD SPACE handling. |
313 | | |
314 | | @param cs - the character set and collation |
315 | | @param a - the left string |
316 | | @param a_length - the length of the left string |
317 | | @param b - the right string |
318 | | @param b_length - the length of the right string |
319 | | @return - the comparison result |
320 | | */ |
321 | | static int |
322 | | MY_FUNCTION_NAME(strnncollsp)(CHARSET_INFO *cs __attribute__((unused)), |
323 | | const uchar *a, size_t a_length, |
324 | | const uchar *b, size_t b_length) |
325 | 0 | { |
326 | 0 | const uchar *a_end= a + a_length; |
327 | 0 | const uchar *b_end= b + b_length; |
328 | 0 | for ( ; ; ) |
329 | 0 | { |
330 | 0 | int a_weight, b_weight, res; |
331 | 0 | uint a_wlen= MY_FUNCTION_NAME(scan_weight)(&a_weight, a, a_end); |
332 | 0 | uint b_wlen; |
333 | |
|
334 | | #ifdef MY_STRCOLL_MB7_4BYTES |
335 | 0 | if (a_wlen == 1 && my_strcoll_ascii_4bytes_found(a, a_end, b, b_end)) |
336 | 0 | { |
337 | 0 | int res; |
338 | 0 | #ifdef MY_STRCOLL_MB7_8BYTES |
339 | 0 | if (my_strcoll_ascii_4bytes_found(a + 4, a_end, b + 4, b_end)) |
340 | 0 | { |
341 | 0 | if ((res= MY_STRCOLL_MB7_8BYTES(a, b))) |
342 | 0 | return res; |
343 | 0 | MY_STRING_SHIFT_PTR_PTR(a, b, 8); |
344 | 0 | continue; |
345 | 0 | } |
346 | 0 | #endif |
347 | 0 | if ((res= MY_STRCOLL_MB7_4BYTES(a, b))) |
348 | 0 | return res; |
349 | 0 | MY_STRING_SHIFT_PTR_PTR(a, b, 4); |
350 | 0 | continue; |
351 | 0 | } |
352 | 0 | #endif /* MY_STRCOLL_MB7_4BYTES */ |
353 | | |
354 | 0 | b_wlen= MY_FUNCTION_NAME(scan_weight)(&b_weight, b, b_end); |
355 | |
|
356 | 0 | if ((res= (a_weight - b_weight))) |
357 | 0 | { |
358 | | /* |
359 | | Got two different weights. Each weight can be generated by either of: |
360 | | - a real character |
361 | | - a bad byte sequence or an incomplete byte sequence |
362 | | - an auto-generated trailing space (PAD SPACE) |
363 | | It does not matter how exactly each weight was generated. |
364 | | Just return the weight difference. |
365 | | */ |
366 | 0 | return res; |
367 | 0 | } |
368 | 0 | if (!a_wlen && !b_wlen) |
369 | 0 | { |
370 | | /* |
371 | | Got two auto-generated trailing spaces, i.e. |
372 | | both strings have now ended, so they are equal. |
373 | | */ |
374 | 0 | DBUG_ASSERT(a == a_end); |
375 | 0 | DBUG_ASSERT(b == b_end); |
376 | 0 | return 0; |
377 | 0 | } |
378 | | /* |
379 | | At least one of the strings has not ended yet, continue comparison. |
380 | | */ |
381 | 0 | DBUG_ASSERT(a < a_end || b < b_end); |
382 | 0 | a+= a_wlen; |
383 | 0 | b+= b_wlen; |
384 | 0 | } |
385 | 0 | DBUG_ASSERT(0); |
386 | 0 | return 0; |
387 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf16le_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_utf32_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_ucs2_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_ucs2_general_mysql500_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_ucs2_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb3_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb3_general1400_as_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb3_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb4_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb4_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_utf8mb4_general1400_as_ci Unexecuted instantiation: ctype-big5.c:my_strnncollsp_big5_chinese_ci Unexecuted instantiation: ctype-big5.c:my_strnncollsp_big5_bin Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_cp932_japanese_ci Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_cp932_bin Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_euckr_korean_ci Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_euckr_bin Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_eucjpms_japanese_ci Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_eucjpms_bin Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_gb2312_chinese_ci Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_gb2312_bin Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_gbk_chinese_ci Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_gbk_bin Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_sjis_japanese_ci Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_sjis_bin Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_ujis_japanese_ci Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_ujis_bin |
388 | | #endif /* DEFINE_STRNNCOLLSP_NOPAD */ |
389 | | |
390 | | |
391 | | /** |
392 | | Compare two strings according to the collation, |
393 | | with trailing space padding or trimming, according to "nchars". |
394 | | |
395 | | @param cs - the character set and collation |
396 | | @param a - the left string |
397 | | @param a_length - the length of the left string |
398 | | @param b - the right string |
399 | | @param b_length - the length of the right string |
400 | | @param nchars - compare this amount of characters only |
401 | | @return - the comparison result |
402 | | */ |
403 | | static int |
404 | | MY_FUNCTION_NAME(strnncollsp_nchars)(CHARSET_INFO *cs __attribute__((unused)), |
405 | | const uchar *a, size_t a_length, |
406 | | const uchar *b, size_t b_length, |
407 | | size_t nchars, |
408 | | uint flags) |
409 | 0 | { |
410 | 0 | const uchar *a_end= a + a_length; |
411 | 0 | const uchar *b_end= b + b_length; |
412 | 0 | for ( ; nchars ; nchars--) |
413 | 0 | { |
414 | 0 | int a_weight, b_weight, res; |
415 | 0 | uint a_wlen= MY_FUNCTION_NAME(scan_weight)(&a_weight, a, a_end); |
416 | 0 | uint b_wlen= MY_FUNCTION_NAME(scan_weight)(&b_weight, b, b_end); |
417 | |
|
418 | 0 | if ((res= (a_weight - b_weight))) |
419 | 0 | { |
420 | | /* Got two different weights. See comments in strnncollsp above. */ |
421 | 0 | return res; |
422 | 0 | } |
423 | 0 | if (!a_wlen && !b_wlen) |
424 | 0 | { |
425 | | /* Got two auto-generated trailing spaces. */ |
426 | 0 | DBUG_ASSERT(a == a_end); |
427 | 0 | DBUG_ASSERT(b == b_end); |
428 | 0 | return 0; |
429 | 0 | } |
430 | | /* |
431 | | At least one of the strings has not ended yet, continue comparison. |
432 | | */ |
433 | 0 | DBUG_ASSERT(a < a_end || b < b_end); |
434 | 0 | a+= a_wlen; |
435 | 0 | b+= b_wlen; |
436 | 0 | } |
437 | 0 | return 0; |
438 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16le_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16le_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf16le_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf32_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf32_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_utf32_nopad_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_ucs2_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_ucs2_general_mysql500_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_ucs2_bin Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_ucs2_general_nopad_ci Unexecuted instantiation: ctype-ucs2.c:my_strnncollsp_nchars_ucs2_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb3_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb3_general1400_as_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb3_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb3_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb3_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb4_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb4_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb4_general_nopad_ci Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb4_nopad_bin Unexecuted instantiation: ctype-utf8.c:my_strnncollsp_nchars_utf8mb4_general1400_as_ci Unexecuted instantiation: ctype-big5.c:my_strnncollsp_nchars_big5_chinese_ci Unexecuted instantiation: ctype-big5.c:my_strnncollsp_nchars_big5_bin Unexecuted instantiation: ctype-big5.c:my_strnncollsp_nchars_big5_chinese_nopad_ci Unexecuted instantiation: ctype-big5.c:my_strnncollsp_nchars_big5_nopad_bin Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_nchars_cp932_japanese_ci Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_nchars_cp932_bin Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_nchars_cp932_japanese_nopad_ci Unexecuted instantiation: ctype-cp932.c:my_strnncollsp_nchars_cp932_nopad_bin Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_nchars_euckr_korean_ci Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_nchars_euckr_bin Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_nchars_euckr_korean_nopad_ci Unexecuted instantiation: ctype-euc_kr.c:my_strnncollsp_nchars_euckr_nopad_bin Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_nchars_eucjpms_japanese_ci Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_nchars_eucjpms_bin Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_nchars_eucjpms_japanese_nopad_ci Unexecuted instantiation: ctype-eucjpms.c:my_strnncollsp_nchars_eucjpms_nopad_bin Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_nchars_gb2312_chinese_ci Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_nchars_gb2312_bin Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_nchars_gb2312_chinese_nopad_ci Unexecuted instantiation: ctype-gb2312.c:my_strnncollsp_nchars_gb2312_nopad_bin Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_nchars_gbk_chinese_ci Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_nchars_gbk_bin Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_nchars_gbk_chinese_nopad_ci Unexecuted instantiation: ctype-gbk.c:my_strnncollsp_nchars_gbk_nopad_bin Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_nchars_sjis_japanese_ci Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_nchars_sjis_bin Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_nchars_sjis_japanese_nopad_ci Unexecuted instantiation: ctype-sjis.c:my_strnncollsp_nchars_sjis_nopad_bin Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_nchars_ujis_japanese_ci Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_nchars_ujis_bin Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_nchars_ujis_japanese_nopad_ci Unexecuted instantiation: ctype-ujis.c:my_strnncollsp_nchars_ujis_nopad_bin |
439 | | |
440 | | |
441 | | #endif /* DEFINE_STRNNCOLL */ |
442 | | |
443 | | |
444 | | #ifdef DEFINE_STRNXFRM |
445 | | #ifndef WEIGHT_MB2_FRM |
446 | 0 | #define WEIGHT_MB2_FRM(x,y) WEIGHT_MB2(x,y) |
447 | | #endif |
448 | | |
449 | | static my_strnxfrm_ret_t |
450 | | MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, |
451 | | uchar *dst, size_t dstlen, uint nweights, |
452 | | const uchar *src, size_t srclen, uint flags) |
453 | 0 | { |
454 | 0 | uchar *d0= dst; |
455 | 0 | uchar *de= dst + dstlen; |
456 | 0 | const uchar *src0= src; |
457 | 0 | const uchar *se= src + srclen; |
458 | 0 | const uchar *sort_order= cs->sort_order; |
459 | 0 | uint warnings= 0; |
460 | 0 | my_strnxfrm_ret_t rcpad; |
461 | |
|
462 | 0 | for (; dst < de && src < se && nweights; nweights--) |
463 | 0 | { |
464 | 0 | if (my_ci_charlen(cs, src, se) > 1) |
465 | 0 | { |
466 | | /* |
467 | | Note, it is safe not to check (src < se) |
468 | | in the code below, because my_ci_charlen() would |
469 | | not return 2 if src was too short |
470 | | */ |
471 | 0 | uint16 e= WEIGHT_MB2_FRM(src[0], src[1]); |
472 | 0 | *dst++= (uchar) (e >> 8); |
473 | 0 | if (dst < de) |
474 | 0 | *dst++= (uchar) (e & 0xFF); |
475 | 0 | else |
476 | 0 | warnings|= MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR; |
477 | 0 | src+= 2; |
478 | 0 | } |
479 | 0 | else |
480 | 0 | *dst++= sort_order ? sort_order[*src++] : *src++; |
481 | 0 | } |
482 | 0 | rcpad= |
483 | | #ifdef DEFINE_STRNNCOLLSP_NOPAD |
484 | | my_strxfrm_pad_desc_and_reverse_nopad(cs, d0, dst, de, |
485 | | nweights, flags, 0); |
486 | | #else |
487 | | my_strxfrm_pad_desc_and_reverse(cs, d0, dst, de, nweights, flags, 0); |
488 | | #endif |
489 | |
|
490 | 0 | return my_strnxfrm_ret_construct(rcpad.m_result_length, src - src0, |
491 | 0 | rcpad.m_warnings | warnings | |
492 | 0 | (src < se ? MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0)); |
493 | 0 | } Unexecuted instantiation: ctype-big5.c:my_strnxfrm_big5_chinese_ci Unexecuted instantiation: ctype-big5.c:my_strnxfrm_big5_chinese_nopad_ci Unexecuted instantiation: ctype-gbk.c:my_strnxfrm_gbk_chinese_ci Unexecuted instantiation: ctype-gbk.c:my_strnxfrm_gbk_chinese_nopad_ci |
494 | | #endif /* DEFINE_STRNXFRM */ |
495 | | |
496 | | |
497 | | #if defined(DEFINE_STRNXFRM_UNICODE) || defined(DEFINE_STRNXFRM_UNICODE_NOPAD) |
498 | | |
499 | | /* |
500 | | Store sorting weights using 2 bytes per character. |
501 | | |
502 | | This function is shared between |
503 | | - utf8mb3_general_ci, utf8mb3_bin, ucs2_general_ci, ucs2_bin |
504 | | which support BMP only (U+0000..U+FFFF). |
505 | | - utf8mb4_general_ci, utf16_general_ci, utf32_general_ci, |
506 | | which map all supplementary characters to weight 0xFFFD. |
507 | | */ |
508 | | |
509 | | #ifndef MY_MB_WC |
510 | | #error MY_MB_WC must be defined for DEFINE_STRNXFRM_UNICODE |
511 | | #endif |
512 | | |
513 | | #ifndef OPTIMIZE_ASCII |
514 | | #error OPTIMIZE_ASCII must be defined for DEFINE_STRNXFRM_UNICODE |
515 | | #endif |
516 | | |
517 | | #if OPTIMIZE_ASCII && !defined(WEIGHT_MB1) |
518 | | #error WEIGHT_MB1 must be defined for DEFINE_STRNXFRM_UNICODE |
519 | | #endif |
520 | | |
521 | | #ifndef MY_WC_WEIGHT |
522 | | #error MY_WC_WEIGHT must be defined for DEFINE_STRNXFRM_UNICODE |
523 | | #endif |
524 | | |
525 | | static my_strnxfrm_ret_t |
526 | | MY_FUNCTION_NAME(strnxfrm_internal)(CHARSET_INFO *cs __attribute__((unused)), |
527 | | uchar *dst, uchar *de, |
528 | | uint *nweights, |
529 | | const uchar *src, const uchar *se) |
530 | 0 | { |
531 | 0 | my_wc_t UNINIT_VAR(wc); |
532 | 0 | uchar *dst0= dst; |
533 | 0 | const uchar *src0= src; |
534 | 0 | uint warnings= 0; |
535 | |
|
536 | 0 | DBUG_ASSERT(src || !se); |
537 | 0 | DBUG_ASSERT((cs->state & MY_CS_LOWER_SORT) == 0); |
538 | |
|
539 | 0 | for (; dst < de && *nweights; (*nweights)--) |
540 | 0 | { |
541 | 0 | int res; |
542 | | #if OPTIMIZE_ASCII |
543 | 0 | if (src >= se) |
544 | 0 | break; |
545 | 0 | if (src[0] <= 0x7F) |
546 | 0 | { |
547 | 0 | wc= WEIGHT_MB1(*src++); |
548 | 0 | warnings|= de - dst < WEIGHT_SIZE ? |
549 | 0 | MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0; |
550 | 0 | PUT_WC_BE_HAVE_1BYTE(dst, de, wc); |
551 | 0 | continue; |
552 | 0 | } |
553 | 0 | #endif |
554 | 0 | if ((res= MY_MB_WC(cs, &wc, src, se)) <= 0) |
555 | 0 | break; |
556 | 0 | src+= res; |
557 | 0 | wc= MY_WC_WEIGHT(wc); |
558 | 0 | warnings|= de - dst < WEIGHT_SIZE ? |
559 | 0 | MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0; |
560 | 0 | PUT_WC_BE_HAVE_1BYTE(dst, de, wc); |
561 | 0 | } |
562 | 0 | return my_strnxfrm_ret_construct(dst - dst0, src - src0, |
563 | 0 | warnings | |
564 | 0 | (src < se ? MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0)); |
565 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_internal_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_internal_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_internal_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_internal_ucs2_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_internal_ucs2_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_utf8mb3_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_utf8mb3_general1400_as_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_filename Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_utf8mb4_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_utf8mb4_general1400_as_ci |
566 | | |
567 | | |
568 | | static my_strnxfrm_ret_t |
569 | | MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, |
570 | | uchar *dst, size_t dstlen, uint nweights, |
571 | | const uchar *src, size_t srclen, uint flags) |
572 | 0 | { |
573 | 0 | uchar *dst0= dst; |
574 | 0 | uchar *de= dst + dstlen; |
575 | 0 | my_strnxfrm_ret_t rc= MY_FUNCTION_NAME(strnxfrm_internal)(cs, dst, de, |
576 | 0 | &nweights, |
577 | 0 | src, src + srclen); |
578 | 0 | dst+= rc.m_result_length; |
579 | 0 | DBUG_ASSERT(dst <= de); /* Safety */ |
580 | |
|
581 | 0 | if (nweights && (flags & MY_STRXFRM_PAD_WITH_SPACE)) |
582 | 0 | { |
583 | 0 | my_strnxfrm_pad_ret_t rcpad= PAD_NWEIGHTS_UNICODE_BE(dst, de, nweights); |
584 | 0 | rc.m_warnings|= rcpad.m_warnings; |
585 | 0 | dst+= rcpad.m_result_length; |
586 | 0 | } |
587 | |
|
588 | 0 | my_strxfrm_desc_and_reverse(dst0, dst, flags, 0); |
589 | |
|
590 | 0 | if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && dst < de) |
591 | 0 | dst+= PAD_UNICODE_BE(dst, de); |
592 | 0 | rc.m_result_length= dst - dst0; |
593 | 0 | return rc; |
594 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_ucs2_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_ucs2_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_utf8mb3_general_mysql500_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_utf8mb3_general1400_as_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_filename Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_utf8mb4_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_utf8mb4_general1400_as_ci |
595 | | |
596 | | |
597 | | #ifdef DEFINE_STRNXFRM_UNICODE_NOPAD |
598 | | static my_strnxfrm_ret_t |
599 | | MY_FUNCTION_NAME(strnxfrm_nopad)(CHARSET_INFO *cs, |
600 | | uchar *dst, size_t dstlen, |
601 | | uint nweights, |
602 | | const uchar *src, size_t srclen, uint flags) |
603 | 0 | { |
604 | 0 | uchar *dst0= dst; |
605 | 0 | uchar *de= dst + dstlen; |
606 | 0 | my_strnxfrm_ret_t rc= MY_FUNCTION_NAME(strnxfrm_internal)(cs, |
607 | 0 | dst, de, &nweights, |
608 | 0 | src, src + srclen); |
609 | 0 | dst+= rc.m_result_length; |
610 | 0 | DBUG_ASSERT(dst <= de); /* Safety */ |
611 | |
|
612 | 0 | if (nweights && (flags & MY_STRXFRM_PAD_WITH_SPACE)) |
613 | 0 | { |
614 | 0 | size_t len= de - dst; |
615 | 0 | if (len < nweights * 2) |
616 | 0 | rc.m_warnings|= MY_STRNXFRM_TRUNCATED_WEIGHT_TRAILING_SPACE; |
617 | 0 | set_if_smaller(len, nweights * 2); |
618 | 0 | memset(dst, 0x00, len); |
619 | 0 | dst+= len; |
620 | 0 | } |
621 | |
|
622 | 0 | my_strxfrm_desc_and_reverse(dst0, dst, flags, 0); |
623 | |
|
624 | 0 | if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && dst < de) |
625 | 0 | { |
626 | 0 | memset(dst, 0x00, de - dst); |
627 | 0 | dst= de; |
628 | 0 | } |
629 | 0 | rc.m_result_length= dst - dst0; |
630 | 0 | return rc; |
631 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_nopad_utf16_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_nopad_utf16le_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_nopad_utf32_general_ci Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_nopad_ucs2_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_nopad_utf8mb3_general_ci Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_nopad_utf8mb4_general_ci |
632 | | #endif |
633 | | |
634 | | #endif /* DEFINE_STRNXFRM_UNICODE || DEFINE_STRNXFRM_UNICODE_NOPAD */ |
635 | | |
636 | | |
637 | | |
638 | | #ifdef DEFINE_STRNXFRM_UNICODE_BIN2 |
639 | | |
640 | | /* |
641 | | Store sorting weights using 2 bytes per character. |
642 | | |
643 | | These functions are shared between |
644 | | - utf8mb3_general_ci, utf8mb3_bin, ucs2_general_ci, ucs2_bin |
645 | | which support BMP only (U+0000..U+FFFF). |
646 | | - utf8mb4_general_ci, utf16_general_ci, utf32_general_ci, |
647 | | which map all supplementary characters to weight 0xFFFD. |
648 | | */ |
649 | | |
650 | | #ifndef MY_MB_WC |
651 | | #error MY_MB_WC must be defined for DEFINE_STRNXFRM_UNICODE_BIN2 |
652 | | #endif |
653 | | |
654 | | #ifndef OPTIMIZE_ASCII |
655 | | #error OPTIMIZE_ASCII must be defined for DEFINE_STRNXFRM_UNICODE_BIN2 |
656 | | #endif |
657 | | |
658 | | |
659 | | static my_strnxfrm_ret_t |
660 | | MY_FUNCTION_NAME(strnxfrm_internal)(CHARSET_INFO *cs __attribute__((unused)), |
661 | | uchar *dst, uchar *de, |
662 | | uint *nweights, |
663 | | const uchar *src, |
664 | | const uchar *se) |
665 | 0 | { |
666 | 0 | my_wc_t UNINIT_VAR(wc); |
667 | 0 | const uchar *src0= src; |
668 | 0 | uchar *dst0= dst; |
669 | 0 | uint warnings= 0; |
670 | |
|
671 | 0 | DBUG_ASSERT(src || !se); |
672 | |
|
673 | 0 | for (; dst < de && *nweights; (*nweights)--) |
674 | 0 | { |
675 | 0 | int res; |
676 | | #if OPTIMIZE_ASCII |
677 | 0 | if (src >= se) |
678 | 0 | break; |
679 | 0 | if (src[0] <= 0x7F) |
680 | 0 | { |
681 | 0 | wc= *src++; |
682 | 0 | warnings|= de - dst < WEIGHT_SIZE ? |
683 | 0 | MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0; |
684 | 0 | PUT_WC_BE2_HAVE_1BYTE(dst, de, wc); |
685 | 0 | continue; |
686 | 0 | } |
687 | 0 | #endif |
688 | 0 | if ((res= MY_MB_WC(cs, &wc, src, se)) <= 0) |
689 | 0 | break; |
690 | 0 | src+= res; |
691 | 0 | if (wc > 0xFFFF) |
692 | 0 | wc= MY_CS_REPLACEMENT_CHARACTER; |
693 | 0 | warnings|= de - dst < WEIGHT_SIZE ? |
694 | 0 | MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0; |
695 | 0 | PUT_WC_BE2_HAVE_1BYTE(dst, de, wc); |
696 | 0 | } |
697 | 0 | return my_strnxfrm_ret_construct(dst - dst0, src - src0, |
698 | 0 | warnings | |
699 | 0 | ((src - se) ? MY_STRNXFRM_TRUNCATED_WEIGHT_REAL_CHAR : 0)); |
700 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_internal_ucs2_bin Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_internal_utf8mb3_bin |
701 | | |
702 | | |
703 | | static my_strnxfrm_ret_t |
704 | | MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, |
705 | | uchar *dst, size_t dstlen, uint nweights, |
706 | | const uchar *src, size_t srclen, uint flags) |
707 | 0 | { |
708 | 0 | uchar *dst0= dst; |
709 | 0 | uchar *de= dst + dstlen; |
710 | 0 | my_strnxfrm_ret_t rc= MY_FUNCTION_NAME(strnxfrm_internal)(cs, dst, de, |
711 | 0 | &nweights, |
712 | 0 | src, src + srclen); |
713 | 0 | dst+= rc.m_result_length; |
714 | 0 | DBUG_ASSERT(dst <= de); /* Safety */ |
715 | |
|
716 | 0 | if (nweights && (flags & MY_STRXFRM_PAD_WITH_SPACE)) |
717 | 0 | { |
718 | 0 | my_strnxfrm_pad_ret_t rcpad= PAD_NWEIGHTS_UNICODE_BE(dst, de, nweights); |
719 | 0 | rc.m_warnings|= rcpad.m_warnings; |
720 | 0 | dst+= rcpad.m_result_length; |
721 | 0 | } |
722 | |
|
723 | 0 | my_strxfrm_desc_and_reverse(dst0, dst, flags, 0); |
724 | |
|
725 | 0 | if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && dst < de) |
726 | 0 | dst+= PAD_UNICODE_BE(dst, de); |
727 | 0 | rc.m_result_length= dst - dst0; |
728 | 0 | return rc; |
729 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_ucs2_bin Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_utf8mb3_bin |
730 | | |
731 | | |
732 | | static my_strnxfrm_ret_t |
733 | | MY_FUNCTION_NAME(strnxfrm_nopad)(CHARSET_INFO *cs, |
734 | | uchar *dst, size_t dstlen, uint nweights, |
735 | | const uchar *src, size_t srclen, uint flags) |
736 | 0 | { |
737 | 0 | uchar *dst0= dst; |
738 | 0 | uchar *de= dst + dstlen; |
739 | 0 | my_strnxfrm_ret_t rc= MY_FUNCTION_NAME(strnxfrm_internal)(cs, dst, de, |
740 | 0 | &nweights, |
741 | 0 | src, src + srclen); |
742 | 0 | dst+= rc.m_result_length; |
743 | 0 | DBUG_ASSERT(dst <= de); /* Safety */ |
744 | |
|
745 | 0 | if (nweights && (flags & MY_STRXFRM_PAD_WITH_SPACE)) |
746 | 0 | { |
747 | 0 | size_t len= de - dst; |
748 | 0 | if (len < nweights * 2) |
749 | 0 | rc.m_warnings|= MY_STRNXFRM_TRUNCATED_WEIGHT_TRAILING_SPACE; |
750 | 0 | set_if_smaller(len, nweights * 2); |
751 | 0 | memset(dst, 0x00, len); |
752 | 0 | dst+= len; |
753 | 0 | } |
754 | |
|
755 | 0 | my_strxfrm_desc_and_reverse(dst0, dst, flags, 0); |
756 | |
|
757 | 0 | if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && dst < de) |
758 | 0 | { |
759 | 0 | memset(dst, 0x00, de - dst); |
760 | 0 | dst= de; |
761 | 0 | } |
762 | 0 | rc.m_result_length= dst - dst0; |
763 | 0 | return rc; |
764 | 0 | } Unexecuted instantiation: ctype-ucs2.c:my_strnxfrm_nopad_ucs2_bin Unexecuted instantiation: ctype-utf8.c:my_strnxfrm_nopad_utf8mb3_bin |
765 | | |
766 | | #endif /* DEFINE_STRNXFRM_UNICODE_BIN2 */ |
767 | | |
768 | | |
769 | | /* |
770 | | We usually include this file at least two times from the same source file, |
771 | | for the _ci and the _bin collations. Prepare for the second inclusion. |
772 | | */ |
773 | | #undef MY_FUNCTION_NAME |
774 | | #undef MY_MB_WC |
775 | | #undef OPTIMIZE_ASCII |
776 | | #undef MY_WC_WEIGHT |
777 | | #undef WEIGHT_ILSEQ |
778 | | #undef WEIGHT_MB1 |
779 | | #undef WEIGHT_MB2 |
780 | | #undef WEIGHT_MB3 |
781 | | #undef WEIGHT_MB4 |
782 | | #undef WEIGHT_PAD_SPACE |
783 | | #undef WEIGHT_MB2_FRM |
784 | | #undef WEIGHT_SIZE |
785 | | #undef DEFINE_STRNXFRM |
786 | | #undef DEFINE_STRNXFRM_UNICODE |
787 | | #undef DEFINE_STRNXFRM_UNICODE_NOPAD |
788 | | #undef DEFINE_STRNXFRM_UNICODE_BIN2 |
789 | | #undef DEFINE_STRNNCOLL |
790 | | #undef DEFINE_STRNNCOLLSP_NOPAD |
791 | | |
792 | | #undef STRCOLL_MB7_TOUPPER |
793 | | #undef STRCOLL_MB7_BIN |
794 | | #undef MY_STRCOLL_MB7_4BYTES |
795 | | #undef MY_STRCOLL_MB7_8BYTES |
796 | | #undef PUT_WC_BE_HAVE_1BYTE |
797 | | #undef PAD_NWEIGHTS_UNICODE_BE |
798 | | #undef PAD_UNICODE_BE |