MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ctype-czech.c
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 /* File strings/ctype-czech.c for MySQL.
17 
18  This file implements the Czech sorting for the MySQL database
19  server (www.mysql.com). Due to some complicated rules the
20  Czech language has for sorting strings, a more complex
21  solution was needed than the one-to-one conversion table. To
22  note a few, here is an example of a Czech sorting sequence:
23 
24  co < hlaska < hláska < hlava < chlapec < krtek
25 
26  It because some of the rules are: double char 'ch' is sorted
27  between 'h' and 'i'. Accented character 'á' (a with acute) is
28  sorted after 'a' and before 'b', but only if the word is
29  otherwise the same. However, because 's' is sorted before 'v'
30  in hlava, the accentness of 'á' is overridden. There are many
31  more rules.
32 
33  This file defines functions my_strxfrm and my_strcoll for
34  C-like zero terminated strings and my_strnxfrm and my_strnncoll
35  for strings where the length comes as an parameter. Also
36  defined here you will find function my_like_range that returns
37  index range strings for LIKE expression and the
38  MY_STRXFRM_MULTIPLY set to value 4 -- this is the ratio the
39  strings grows during my_strxfrm. The algorithm has four
40  passes, that's why we need four times more space for expanded
41  string.
42 
43  This file also contains the ISO-Latin-2 definitions of
44  characters.
45 
46  Author: (c) 1997--1998 Jan Pazdziora, adelton@fi.muni.cz
47  Jan Pazdziora has a shared copyright for this code
48 
49  The original of this file can also be found at
50  http://www.fi.muni.cz/~adelton/l10n/
51 
52  Bug reports and suggestions are always welcome.
53 */
54 
55 /*
56  * This comment is parsed by configure to create ctype.c,
57  * so don't change it unless you know what you are doing.
58  *
59  * .configure. strxfrm_multiply_czech=4
60  */
61 
62 #define SKIP_TRAILING_SPACES 1
63 
64 #include <my_global.h>
65 #include "m_string.h"
66 #include "m_ctype.h"
67 
68 #ifdef HAVE_CHARSET_latin2
69 
70 /*
71  These are four tables for four passes of the algorithm. Please see
72  below for what are the "special values"
73 */
74 
75 static uchar *CZ_SORT_TABLE[] = {
76  (uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\043\044\045\046\047\050\051\052\053\054\000\000\000\000\000\000\000\003\004\377\007\010\011\012\013\015\016\017\020\022\023\024\025\026\027\031\033\034\035\036\037\040\041\000\000\000\000\000\000\003\004\377\007\010\011\012\013\015\016\017\020\022\023\024\025\026\027\031\033\034\035\036\037\040\041\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\021\000\020\032\000\000\032\032\033\042\000\042\042\000\003\000\021\000\020\032\000\000\032\032\033\042\000\042\042\027\003\003\003\003\020\006\006\006\010\010\010\010\015\015\007\007\023\023\024\024\024\024\000\030\034\034\034\034\040\033\000\027\003\003\003\003\020\006\006\006\010\010\010\010\015\015\007\007\023\023\024\024\024\024\000\030\034\034\034\034\040\033\000",
77  (uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\106\107\110\111\112\113\114\115\116\117\000\000\000\000\000\000\000\003\011\377\016\021\026\027\030\032\035\036\037\043\044\047\054\055\056\061\065\070\075\076\077\100\102\000\000\000\000\000\000\003\011\377\016\021\026\027\030\032\035\036\037\043\044\047\054\055\056\061\065\070\075\076\077\100\102\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\042\000\041\063\000\000\062\064\066\104\000\103\105\000\010\000\042\000\041\063\000\000\062\064\066\104\000\103\105\057\004\005\007\006\040\014\015\013\022\025\024\023\033\034\017\020\046\045\050\051\053\052\000\060\072\071\074\073\101\067\000\057\004\005\007\006\040\014\015\013\022\025\024\023\033\034\017\020\046\045\050\051\053\052\000\060\072\071\074\073\101\067\000",
78 (uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\213\214\215\216\217\220\221\222\223\000\000\000\000\000\000\000\004\020\377\032\040\052\054\056\063\071\073\075\105\107\115\127\131\133\141\151\157\171\173\175\177\203\000\000\000\000\000\000\003\017\377\031\037\051\053\055\062\070\072\074\104\106\114\126\130\132\140\150\156\170\172\174\176\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\103\000\101\145\000\000\143\147\153\207\000\205\211\000\015\000\102\000\100\144\000\000\142\146\152\206\000\204\210\135\006\010\014\012\077\026\030\024\042\050\046\044\065\067\034\036\113\111\117\121\125\123\000\137\163\161\167\165\201\155\000\134\005\007\013\011\076\025\027\023\041\047\045\043\064\066\033\035\112\110\116\120\124\122\000\136\162\160\166\164\200\154\000",
79 (uchar*) "\264\265\266\267\270\271\272\273\274\002\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\002\230\232\253\324\252\251\234\240\241\261\260\225\262\224\235\212\213\214\215\216\217\220\221\222\223\231\226\244\257\245\227\250\004\020\377\032\040\052\054\056\063\071\073\075\105\107\115\127\131\133\141\151\157\171\173\175\177\203\242\237\243\254\255\233\003\017\377\031\037\051\053\055\062\070\072\074\104\106\114\126\130\132\140\150\156\170\172\174\176\202\246\236\247\256\325\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\326\016\327\103\330\101\145\331\332\143\147\153\207\333\205\211\334\015\335\102\336\100\144\337\340\142\146\152\206\341\204\210\135\006\010\014\012\077\026\030\024\042\050\046\044\065\067\034\036\113\111\117\121\125\123\263\137\163\161\167\165\201\155\342\134\005\007\013\011\076\025\027\023\041\047\045\043\064\066\033\035\112\110\116\120\124\122\343\136\162\160\166\164\200\154\344",
80 };
81 
82 /*
83  These define the valuse for the double chars that need to be
84  sorted as they were single characters -- in Czech these are
85  'ch', 'Ch' and 'CH'.
86 */
87 
88 struct wordvalue
89  {
90  const char * word;
91  uchar *outvalue;
92  };
93 static struct wordvalue doubles[] = {
94  { "ch", (uchar*) "\014\031\057\057" },
95  { "Ch", (uchar*) "\014\031\060\060" },
96  { "CH", (uchar*) "\014\031\061\061" },
97  { "c", (uchar*) "\005\012\021\021" },
98  { "C", (uchar*) "\005\012\022\022" },
99  };
100 
101 /*
102  Unformal description of the algorithm:
103 
104  We walk the string left to right.
105 
106  The end of the string is either passed as parameter, or is
107  *p == 0. This is hidden in the IS_END macro.
108 
109  In the first two passes, we compare word by word. So we make
110  first and second pass on the first word, first and second pass
111  on the second word, etc. If we come to the end of the string
112  during the first pass, we need to jump to the last word of the
113  second pass.
114 
115  End of pass is marked with value 1 on the output.
116 
117  For each character, we read it's value from the table.
118 
119  If the value is ignore (0), we go straight to the next character.
120 
121  If the value is space/end of word (2) and we are in the first
122  or second pass, we skip all characters having value 0 -- 2 and
123  switch the passwd.
124 
125  If it's the compose character (255), we check if the double
126  exists behind it, find its value.
127 
128  We append 0 to the end.
129 ---
130  Neformální popis algoritmu:
131 
132  Procházíme řetězec zleva doprava.
133 
134  Konec řetězce je předán buď jako parametr, nebo je to *p == 0.
135  Toto je ošetřeno makrem IS_END.
136 
137  Pokud jsme došli na konec řetězce při průchodu 0, nejdeme na
138  začátek, ale na uloženou pozici, protože první a druhý průchod
139  běží současně.
140 
141  Konec vstupu (průchodu) označíme na výstupu hodnotou 1.
142 
143  Pro každý znak řetězce načteme hodnotu z třídící tabulky.
144 
145  Jde-li o hodnotu ignorovat (0), skočíme ihned na další znak..
146 
147  Jde-li o hodnotu konec slova (2) a je to průchod 0 nebo 1,
148  přeskočíme všechny další 0 -- 2 a prohodíme průchody.
149 
150  Jde-li o kompozitní znak (255), otestujeme, zda následuje
151  správný do dvojice, dohledáme správnou hodnotu.
152 
153  Na konci připojíme znak 0
154  */
155 
156 #define ADD_TO_RESULT(dest, len, totlen, value) \
157 { if ((totlen) < (len)) { dest[totlen++]= value; } }
158 #define IS_END(p, src, len) (((char *)p - (char *)src) >= (len))
159 
160 #define NEXT_CMP_VALUE(src, p, store, pass, value, len) \
161 while (1) \
162 { \
163  if (IS_END(p, src, len)) \
164  { \
165  /* when we are at the end of string */ \
166  /* return either 0 for end of string */ \
167  /* or 1 for end of pass */ \
168  value= 0; \
169  if (pass != 3) \
170  { \
171  p= (pass++ == 0) ? store : src; \
172  value = 1; \
173  } \
174  break; \
175  } \
176  /* not at end of string */ \
177  value = CZ_SORT_TABLE[pass][*p]; \
178  if (value == 0) \
179  { p++; continue; } /* ignore value */ \
180  if (value == 2) /* space */ \
181  { \
182  const uchar *tmp; \
183  const uchar *runner = ++p; \
184  while (!(IS_END(runner, src, len)) && (CZ_SORT_TABLE[pass][*runner] == 2)) \
185  runner++; /* skip all spaces */ \
186  if (IS_END(runner, src, len) && SKIP_TRAILING_SPACES) \
187  p = runner; \
188  if ((pass <= 2) && !(IS_END(runner, src, len))) \
189  p = runner; \
190  if (IS_END(p, src, len)) \
191  continue; \
192  /* we switch passes */ \
193  if (pass > 1) \
194  break; \
195  tmp = p; \
196  pass= 1-pass; \
197  p = store; store = tmp; \
198  break; \
199  } \
200  if (value == 255) \
201  { \
202  int i; \
203  for (i = 0; i < (int) sizeof(doubles); i++) \
204  { \
205  const char * pattern = doubles[i].word; \
206  const char * q = (const char *) p; \
207  int j = 0; \
208  while (pattern[j]) \
209  { \
210  if (IS_END(q, src, len) || (*q != pattern[j])) \
211  break; \
212  j++; q++; \
213  } \
214  if (!(pattern[j])) \
215  { \
216  value = (int)(doubles[i].outvalue[pass]); \
217  p= (const uchar *) q - 1; \
218  break; \
219  } \
220  } \
221  } \
222  p++; \
223  break; \
224 }
225 
226 /*
227  Function strnncoll, actually strcoll, with Czech sorting, which expect
228  the length of the strings being specified
229 */
230 
231 static int my_strnncoll_czech(const CHARSET_INFO *cs __attribute__((unused)),
232  const uchar *s1, size_t len1,
233  const uchar *s2, size_t len2,
234  my_bool s2_is_prefix)
235 {
236  int v1, v2;
237  const uchar *p1, * p2, * store1, * store2;
238  int pass1 = 0, pass2 = 0;
239 
240  if (s2_is_prefix && len1 > len2)
241  len1=len2;
242 
243  p1 = s1; p2 = s2;
244  store1 = s1; store2 = s2;
245 
246  do
247  {
248  int diff;
249  NEXT_CMP_VALUE(s1, p1, store1, pass1, v1, (int)len1);
250  NEXT_CMP_VALUE(s2, p2, store2, pass2, v2, (int)len2);
251  if ((diff = v1 - v2))
252  return diff;
253  }
254  while (v1);
255  return 0;
256 }
257 
258 
259 
260 /*
261  TODO: Fix this one to compare strings as they are done in ctype-simple1
262 */
263 
264 static
265 int my_strnncollsp_czech(const CHARSET_INFO *cs,
266  const uchar *s, size_t slen,
267  const uchar *t, size_t tlen,
268  my_bool diff_if_only_endspace_difference
269  __attribute__((unused)))
270 {
271  for ( ; slen && s[slen-1] == ' ' ; slen--);
272  for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
273  return my_strnncoll_czech(cs,s,slen,t,tlen,0);
274 }
275 
276 
277 /*
278  Returns the number of bytes required for strnxfrm().
279 */
280 static size_t
281 my_strnxfrmlen_czech(const CHARSET_INFO *cs
282  __attribute__((unused)), size_t len)
283 {
284  return len * 4 + 4;
285 }
286 
287 
288 /*
289  Function strnxfrm, actually strxfrm, with Czech sorting, which expect
290  the length of the strings being specified
291 */
292 
293 static size_t
294 my_strnxfrm_czech(const CHARSET_INFO *cs __attribute__((unused)),
295  uchar *dest, size_t len,
296  uint nweights_arg __attribute__((unused)),
297  const uchar *src, size_t srclen, uint flags)
298 {
299  int value;
300  const uchar *p, * store;
301  int pass = 0;
302  size_t totlen = 0;
303  p = src; store = src;
304 
305  if (!(flags & 0x0F)) /* All levels by default */
306  flags|= 0x0F;
307 
308  do
309  {
310  int add= (1 << pass) & flags; /* If this level is needed */
311  NEXT_CMP_VALUE(src, p, store, pass, value, (int)srclen);
312  if (add)
313  ADD_TO_RESULT(dest, len, totlen, value);
314  }
315  while (value);
316  if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && len > totlen)
317  {
318  memset(dest + totlen, ' ', len - totlen);
319  totlen= len;
320  }
321  return totlen;
322 }
323 
324 #undef IS_END
325 
326 
327 /*
328  Neformální popis algoritmu:
329 
330  procházíme řetězec zleva doprava
331  konec řetězce poznáme podle *p == 0
332  pokud jsme došli na konec řetězce při průchodu 0, nejdeme na
333  začátek, ale na uloženou pozici, protože první a druhý
334  průchod běží současně
335  konec vstupu (průchodu) označíme na výstupu hodnotou 1
336 
337  načteme hodnotu z třídící tabulky
338  jde-li o hodnotu ignorovat (0), skočíme na další průchod
339  jde-li o hodnotu konec slova (2) a je to průchod 0 nebo 1,
340  přeskočíme všechny další 0 -- 2 a prohodíme
341  průchody
342  jde-li o kompozitní znak (255), otestujeme, zda následuje
343  správný do dvojice, dohledáme správnou hodnotu
344 
345  na konci připojíme znak 0
346  */
347 
348 
349 /*
350 ** Calculate min_str and max_str that ranges a LIKE string.
351 ** Arguments:
352 ** ptr Pointer to LIKE string.
353 ** ptr_length Length of LIKE string.
354 ** escape Escape character in LIKE. (Normally '\').
355 ** All escape characters should be removed from min_str and max_str
356 ** res_length Length of min_str and max_str.
357 ** min_str Smallest case sensitive string that ranges LIKE.
358 ** Should be space padded to res_length.
359 ** max_str Largest case sensitive string that ranges LIKE.
360 ** Normally padded with the biggest character sort value.
361 **
362 ** The function should return 0 if ok and 1 if the LIKE string can't be
363 ** optimized !
364 */
365 
366 
367 #define min_sort_char ' '
368 #define max_sort_char '9'
369 
370 
371 static my_bool my_like_range_czech(const CHARSET_INFO *cs
372  __attribute__((unused)),
373  const char *ptr,size_t ptr_length,
374  pbool escape, pbool w_one, pbool w_many,
375  size_t res_length, char *min_str,
376  char *max_str,
377  size_t *min_length,size_t *max_length)
378 {
379  uchar value;
380  const char *end=ptr+ptr_length;
381  char *min_org=min_str;
382  char *min_end=min_str+res_length;
383 
384  for (; ptr != end && min_str != min_end ; ptr++)
385  {
386  if (*ptr == w_one) /* '_' in SQL */
387  { break; }
388  if (*ptr == w_many) /* '%' in SQL */
389  { break; }
390 
391  if (*ptr == escape && ptr+1 != end)
392  { ptr++; } /* Skip escape */
393 
394  value = CZ_SORT_TABLE[0][(int) (uchar) *ptr];
395 
396  if (value == 0) /* Ignore in the first pass */
397  { continue; }
398  if (value <= 2) /* End of pass or end of string */
399  { break; }
400  if (value == 255) /* Double char too compicated */
401  { break; }
402 
403  *min_str++= *max_str++ = *ptr;
404  }
405 
406  if (cs->state & MY_CS_BINSORT)
407  *min_length= (size_t) (min_str - min_org);
408  else
409  {
410  /* 'a\0\0... is the smallest possible string */
411  *min_length= res_length;
412  }
413  /* a\ff\ff... is the biggest possible string */
414  *max_length= res_length;
415 
416  while (min_str != min_end)
417  {
418  *min_str++ = min_sort_char; /* Because of key compression */
419  *max_str++ = max_sort_char;
420  }
421  return 0;
422 }
423 
424 
425 /*
426  * File generated by cset
427  * (C) Abandoned 1997 Zarko Mocnik <zarko.mocnik@dem.si>
428  *
429  * definition table reworked by Jaromir Dolecek <dolecek@ics.muni.cz>
430  */
431 
432 static uchar ctype_czech[257] = {
433 0,
434  32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
435  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
436  72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
437 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
438  16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
439  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
440  16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
441  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
442  32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 32,
443  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 72,
444  1, 16, 1, 16, 1, 1, 16, 0, 0, 1, 1, 1, 1, 16, 1, 1,
445  16, 2, 16, 2, 16, 2, 2, 16, 16, 2, 2, 2, 2, 16, 2, 2,
446  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
447  16, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 16,
448  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
449  2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 16,
450 };
451 
452 static uchar to_lower_czech[] = {
453  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
454  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
455  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
456  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
457  64, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
458 112,113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95,
459  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
460 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
461 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
462 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
463 177,161,179,163,181,182,166,167,168,185,186,187,188,173,190,191,
464 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
465 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
466 208,241,242,243,244,245,246,215,248,249,250,251,252,253,254,223,
467 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
468 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
469 };
470 
471 static uchar to_upper_czech[] = {
472  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
473  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
474  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
475  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
476  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
477  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
478  96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
479  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
480 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
481 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
482 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
483 176,160,178,162,180,164,165,183,184,169,170,171,172,189,174,175,
484 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
485 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
486 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
487 240,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255,
488 };
489 
490 static uchar sort_order_czech[] = {
491  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
492  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
493  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
494  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
495  64, 65, 71, 72, 76, 78, 83, 84, 85, 86, 90, 91, 92, 96, 97,100,
496 105,106,107,110,114,117,122,123,124,125,127,131,132,133,134,135,
497 136, 65, 71, 72, 76, 78, 83, 84, 85, 86, 90, 91, 92, 96, 97,100,
498 105,106,107,110,114,117,122,123,124,125,127,137,138,139,140, 0,
499  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
500  17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,255,
501  66,255, 93,255, 94,111,255,255,255,112,113,115,128,255,129,130,
502 255, 66,255, 93,255, 94,111,255,255,112,113,115,128,255,129,130,
503 108, 67, 68, 69, 70, 95, 73, 75, 74, 79, 81, 82, 80, 89, 87, 77,
504 255, 98, 99,101,102,103,104,255,109,119,118,120,121,126,116,255,
505 108, 67, 68, 69, 70, 95, 73, 75, 74, 79, 81, 82, 80, 89, 88, 77,
506 255, 98, 99,101,102,103,104,255,109,119,118,120,121,126,116,255,
507 };
508 
509 static uint16 tab_8859_2_uni[256]={
510  0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
511 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
512 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
513 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
514 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
515 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
516 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
517 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
518 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
519 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
520 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
521 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
522 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
523 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
524 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
525 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E, 0,
526  0, 0, 0, 0, 0, 0, 0, 0,
527  0, 0, 0, 0, 0, 0, 0, 0,
528  0, 0, 0, 0, 0, 0, 0, 0,
529  0, 0, 0, 0, 0, 0, 0, 0,
530 0x00A0,0x0104,0x02D8,0x0141,0x00A4,0x013D,0x015A,0x00A7,
531 0x00A8,0x0160,0x015E,0x0164,0x0179,0x00AD,0x017D,0x017B,
532 0x00B0,0x0105,0x02DB,0x0142,0x00B4,0x013E,0x015B,0x02C7,
533 0x00B8,0x0161,0x015F,0x0165,0x017A,0x02DD,0x017E,0x017C,
534 0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,
535 0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,
536 0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,
537 0x0158,0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,
538 0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,
539 0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,
540 0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7,
541 0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9
542 };
543 
544 
545 /* 0000-00FD , 254 chars */
546 static uchar tab_uni_8859_2_plane00[]={
547 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
548 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
549 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
550 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
551 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
552 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
553 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
554 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x00,
555 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0xA0,0x00,0x00,0x00,0xA4,0x00,0x00,0xA7,0xA8,0x00,0x00,0x00,0x00,0xAD,0x00,0x00,
558 0xB0,0x00,0x00,0x00,0xB4,0x00,0x00,0x00,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0xC1,0xC2,0x00,0xC4,0x00,0x00,0xC7,0x00,0xC9,0x00,0xCB,0x00,0xCD,0xCE,0x00,
560 0x00,0x00,0x00,0xD3,0xD4,0x00,0xD6,0xD7,0x00,0x00,0xDA,0x00,0xDC,0xDD,0x00,0xDF,
561 0x00,0xE1,0xE2,0x00,0xE4,0x00,0x00,0xE7,0x00,0xE9,0x00,0xEB,0x00,0xED,0xEE,0x00,
562 0x00,0x00,0x00,0xF3,0xF4,0x00,0xF6,0xF7,0x00,0x00,0xFA,0x00,0xFC,0xFD};
563 
564 /* 0102-017E , 125 chars */
565 static uchar tab_uni_8859_2_plane01[]={
566 0xC3,0xE3,0xA1,0xB1,0xC6,0xE6,0x00,0x00,0x00,0x00,0xC8,0xE8,0xCF,0xEF,0xD0,0xF0,
567 0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,
568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0xE5,0x00,0x00,0xA5,0xB5,0x00,0x00,0xA3,
570 0xB3,0xD1,0xF1,0x00,0x00,0xD2,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD5,0xF5,
571 0x00,0x00,0xC0,0xE0,0x00,0x00,0xD8,0xF8,0xA6,0xB6,0x00,0x00,0xAA,0xBA,0xA9,0xB9,
572 0xDE,0xFE,0xAB,0xBB,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xF9,0xDB,0xFB,
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xBC,0xAF,0xBF,0xAE,0xBE};
574 
575 /* 02C7-02DD , 23 chars */
576 static uchar tab_uni_8859_2_plane02[]={
577 0xB7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
578 0x00,0xA2,0xFF,0x00,0xB2,0x00,0xBD};
579 
580 static MY_UNI_IDX idx_uni_8859_2[]={
581  {0x0000,0x00FD,tab_uni_8859_2_plane00},
582  {0x0102,0x017E,tab_uni_8859_2_plane01},
583  {0x02C7,0x02DD,tab_uni_8859_2_plane02},
584  {0,0,NULL}
585 };
586 
587 
588 static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler =
589 {
590  NULL, /* init */
591  my_strnncoll_czech,
592  my_strnncollsp_czech,
593  my_strnxfrm_czech,
594  my_strnxfrmlen_czech,
595  my_like_range_czech,
596  my_wildcmp_bin,
597  my_strcasecmp_8bit,
598  my_instr_simple,
599  my_hash_sort_simple,
600  my_propagate_simple
601 };
602 
603 CHARSET_INFO my_charset_latin2_czech_ci =
604 {
605  2,0,0, /* number */
606  MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */
607  "latin2", /* cs name */
608  "latin2_czech_cs", /* name */
609  "", /* comment */
610  NULL, /* tailoring */
611  ctype_czech,
612  to_lower_czech,
613  to_upper_czech,
614  sort_order_czech,
615  NULL, /* uca */
616  tab_8859_2_uni, /* tab_to_uni */
617  idx_uni_8859_2, /* tab_from_uni */
618  &my_unicase_default,/* caseinfo */
619  NULL, /* state_map */
620  NULL, /* ident_map */
621  4, /* strxfrm_multiply */
622  1, /* caseup_multiply */
623  1, /* casedn_multiply */
624  1, /* mbminlen */
625  1, /* mbmaxlen */
626  0, /* min_sort_char */
627  0, /* max_sort_char */
628  ' ', /* pad char */
629  0, /* escape_with_backslash_is_dangerous */
630  4, /* levels_for_compare */
631  4, /* levels_for_order */
632  &my_charset_8bit_handler,
633  &my_collation_latin2_czech_ci_handler
634 };
635 
636 
637 #endif