1 /* Copyright (C) 2000 MySQL AB
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; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21 #include "my_global.h"
25 using namespace stardict_collation;
31 void my_caseup_str_mb(CHARSET_INFO * cs, char *str)
34 register char *end=str+strlen(str); /* BAR TODO: remove strlen() call */
35 register uchar *map=cs->to_upper;
39 if ((l=my_ismbchar(cs, str,end)))
43 *str=(char) map[(uchar)*str];
49 void my_casedn_str_mb(CHARSET_INFO * cs, char *str)
52 register char *end=str+strlen(str);
53 register uchar *map=cs->to_lower;
57 if ((l=my_ismbchar(cs, str,end)))
61 *str=(char) map[(uchar)*str];
67 uint my_caseup_mb(CHARSET_INFO * cs, char *src, uint srclen,
68 char *dst __attribute__((unused)),
69 uint dstlen __attribute__((unused)))
72 register char *srcend= src + srclen;
73 register uchar *map= cs->to_upper;
75 DBUG_ASSERT(src == dst && srclen == dstlen);
78 if ((l=my_ismbchar(cs, src, srcend)))
82 *src=(char) map[(uchar) *src];
89 uint my_casedn_mb(CHARSET_INFO * cs, char *src, uint srclen,
90 char *dst __attribute__((unused)),
91 uint dstlen __attribute__((unused)))
94 register char *srcend= src + srclen;
95 register uchar *map=cs->to_lower;
97 DBUG_ASSERT(src == dst && srclen == dstlen);
100 if ((l= my_ismbchar(cs, src, srcend)))
104 *src= (char) map[(uchar)*src];
111 int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t)
114 register const char *end=s+strlen(s);
115 register uchar *map=cs->to_upper;
119 if ((l=my_ismbchar(cs, s,end)))
125 else if (my_mbcharlen(cs, *t) > 1)
127 else if (map[(uchar) *s++] != map[(uchar) *t++])
135 ** Compare string against string with wildcard
137 ** -1 if not matched with wildcard
138 ** 1 if matched with wildcard
141 #define INC_PTR(cs,A,B) A+=(my_ismbchar(cs,A,B) ? my_ismbchar(cs,A,B) : 1)
143 #define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)]
145 int my_wildcmp_mb(CHARSET_INFO *cs,
146 const char *str,const char *str_end,
147 const char *wildstr,const char *wildend,
148 int escape, int w_one, int w_many)
150 int result= -1; /* Not found, using wildcards */
152 while (wildstr != wildend)
154 while (*wildstr != w_many && *wildstr != w_one)
157 if (*wildstr == escape && wildstr+1 != wildend)
159 if ((l = my_ismbchar(cs, wildstr, wildend)))
161 if (str+l > str_end || memcmp(str, wildstr, l) != 0)
167 if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
168 return(1); /* No match */
169 if (wildstr == wildend)
170 return (str != str_end); /* Match if both are at end */
171 result=1; /* Found an anchor char */
173 if (*wildstr == w_one)
177 if (str == str_end) /* Skip one char if possible */
179 INC_PTR(cs,str,str_end);
180 } while (++wildstr < wildend && *wildstr == w_one);
181 if (wildstr == wildend)
184 if (*wildstr == w_many)
187 const char* mb = wildstr;
191 /* Remove any '%' and '_' from the wild search string */
192 for (; wildstr != wildend ; wildstr++)
194 if (*wildstr == w_many)
196 if (*wildstr == w_one)
200 INC_PTR(cs,str,str_end);
203 break; /* Not a wild character */
205 if (wildstr == wildend)
206 return(0); /* Ok if w_many is last */
210 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
214 mblen= my_ismbchar(cs, wildstr, wildend);
215 INC_PTR(cs,wildstr,wildend); /* This is compared trough cmp */
216 cmp=likeconv(cs,cmp);
225 if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0)
231 else if (!my_ismbchar(cs, str, str_end) &&
232 likeconv(cs,*str) == cmp)
237 INC_PTR(cs,str, str_end);
240 int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,
245 } while (str != str_end && wildstr[0] != w_many);
249 return (str != str_end ? 1 : 0);
253 uint my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)),
254 const char *pos, const char *end)
256 register uint32 count=0;
260 pos+= (mblen= my_ismbchar(cs,pos,end)) ? mblen : 1;
267 uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
268 const char *pos, const char *end, uint length)
270 const char *start= pos;
272 while (length && pos < end)
275 pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
278 return (uint) (length ? end+2-start : pos-start);
282 uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e,
283 uint pos, int *error)
285 const char *b_start= b;
292 if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0)
294 *error= b < e ? 1 : 0;
300 return (uint) (b - b_start);
305 uint my_instr_mb(CHARSET_INFO *cs,
306 const char *b, uint b_length,
307 const char *s, uint s_length,
308 my_match_t *match, uint nmatch)
310 register const char *end, *b0;
313 if (s_length <= b_length)
323 return 1; /* Empty string is always found */
327 end= b+b_length-s_length+1;
333 if (!cs->coll->strnncoll(cs, (unsigned char*) b, s_length,
334 (unsigned char*) s, s_length, 0))
339 match[0].end= (uint) (b-b0);
343 match[1].beg= match[0].end;
344 match[1].end= match[0].end+s_length;
345 match[1].mblen= 0; /* Not computed */
350 mblen= (mblen= my_ismbchar(cs, b, end)) ? mblen : 1;
360 /* BINARY collations handlers for MB charsets */
362 static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
363 const uchar *s, uint slen,
364 const uchar *t, uint tlen,
367 uint len=min(slen,tlen);
368 int cmp= memcmp(s,t,len);
369 return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
377 my_strnncollsp_mb_bin()
383 diff_if_only_endspace_difference
384 Set to 1 if the strings should be regarded as different
385 if they only difference in end space
388 This function is used for character strings with binary collations.
389 The shorter string is extended with end space to be as long as the longer
393 A negative number if s < t
394 A positive number if s > t
395 0 if strings are equal
398 static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
399 const uchar *a, uint a_length,
400 const uchar *b, uint b_length,
401 my_bool diff_if_only_endspace_difference)
407 #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
408 diff_if_only_endspace_difference= 0;
411 end= a + (length= min(a_length, b_length));
415 return ((int) a[-1] - (int) b[-1]);
418 if (a_length != b_length)
421 if (diff_if_only_endspace_difference)
422 res= 1; /* Assume 'a' is bigger */
424 Check the next not space character of the longer key. If it's < ' ',
425 then it's smaller than the other key.
427 if (a_length < b_length)
429 /* put shorter key in s */
432 swap= -1; /* swap sign of result */
435 for (end= a + a_length-length; a < end ; a++)
438 return (*a < ' ') ? -swap : swap;
445 static int my_strnxfrm_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
446 uchar * dest, uint dstlen,
447 const uchar *src, uint srclen)
450 memcpy(dest, src, min(dstlen, srclen));
452 bfill(dest + srclen, dstlen - srclen, ' ');
457 static int my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
458 const char *s, const char *t)
463 static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
464 const uchar *key, uint len,ulong *nr1, ulong *nr2)
466 const uchar *pos = key;
470 for (; pos < (uchar*) key ; pos++)
472 nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
473 ((uint)*pos)) + (nr1[0] << 8);
480 Write max key: create a buffer with multibyte
481 representation of the max_sort_char character,
482 and copy it into max_str in a loop.
484 static void pad_max_char(CHARSET_INFO *cs, char *str, char *end)
487 char buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
488 (uchar*) buf + sizeof(buf));
489 DBUG_ASSERT(buflen > 0);
492 if ((str + buflen) < end)
494 /* Enough space for the characer */
495 memcpy(str, buf, buflen);
501 There is no space for whole multibyte
502 character, then add trailing spaces.
510 ** Calculate min_str and max_str that ranges a LIKE string.
512 ** ptr Pointer to LIKE string.
513 ** ptr_length Length of LIKE string.
514 ** escape Escape character in LIKE. (Normally '\').
515 ** All escape characters should be removed from min_str and max_str
516 ** res_length Length of min_str and max_str.
517 ** min_str Smallest case sensitive string that ranges LIKE.
518 ** Should be space padded to res_length.
519 ** max_str Largest case sensitive string that ranges LIKE.
520 ** Normally padded with the biggest character sort value.
522 ** The function should return 0 if ok and 1 if the LIKE string can't be
526 my_bool my_like_range_mb(CHARSET_INFO *cs,
527 const char *ptr,uint ptr_length,
528 pbool escape, pbool w_one, pbool w_many,
530 char *min_str,char *max_str,
531 uint *min_length,uint *max_length)
533 const char *end= ptr + ptr_length;
534 char *min_org= min_str;
535 char *min_end= min_str + res_length;
536 char *max_end= max_str + res_length;
537 uint charlen= res_length / cs->mbmaxlen;
539 for (; ptr != end && min_str != min_end && charlen > 0 ; ptr++, charlen--)
541 if (*ptr == escape && ptr+1 != end)
543 ptr++; /* Skip escape */
544 *min_str++= *max_str++ = *ptr;
547 if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */
549 charlen= my_charpos(cs, min_org, min_str, res_length/cs->mbmaxlen);
551 if (charlen < (uint) (min_str - min_org))
552 min_str= min_org + charlen;
555 Calculate length of keys:
556 'a\0\0... is the smallest possible string when we have space expand
557 a\ff\ff... is the biggest possible string
559 *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) :
561 *max_length= res_length;
565 *min_str++= (char) cs->min_sort_char;
566 } while (min_str != min_end);
569 Write max key: create a buffer with multibyte
570 representation of the max_sort_char character,
571 and copy it into max_str in a loop.
573 *max_length= res_length;
574 pad_max_char(cs, max_str, max_end);
577 *min_str++= *max_str++ = *ptr;
580 *min_length= *max_length = (uint) (min_str - min_org);
581 while (min_str != min_end)
582 *min_str++= *max_str++= ' '; /* Because if key compression */
587 static int my_wildcmp_mb_bin(CHARSET_INFO *cs,
588 const char *str,const char *str_end,
589 const char *wildstr,const char *wildend,
590 int escape, int w_one, int w_many)
592 int result= -1; /* Not found, using wildcards */
594 while (wildstr != wildend)
596 while (*wildstr != w_many && *wildstr != w_one)
599 if (*wildstr == escape && wildstr+1 != wildend)
601 if ((l = my_ismbchar(cs, wildstr, wildend)))
603 if (str+l > str_end || memcmp(str, wildstr, l) != 0)
609 if (str == str_end || *wildstr++ != *str++)
610 return(1); /* No match */
611 if (wildstr == wildend)
612 return (str != str_end); /* Match if both are at end */
613 result=1; /* Found an anchor char */
615 if (*wildstr == w_one)
619 if (str == str_end) /* Skip one char if possible */
621 INC_PTR(cs,str,str_end);
622 } while (++wildstr < wildend && *wildstr == w_one);
623 if (wildstr == wildend)
626 if (*wildstr == w_many)
629 const char* mb = wildstr;
633 /* Remove any '%' and '_' from the wild search string */
634 for (; wildstr != wildend ; wildstr++)
636 if (*wildstr == w_many)
638 if (*wildstr == w_one)
642 INC_PTR(cs,str,str_end);
645 break; /* Not a wild character */
647 if (wildstr == wildend)
648 return(0); /* Ok if w_many is last */
652 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
656 mblen= my_ismbchar(cs, wildstr, wildend);
657 INC_PTR(cs,wildstr,wildend); /* This is compared trough cmp */
666 if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0)
672 else if (!my_ismbchar(cs, str, str_end) && *str == cmp)
677 INC_PTR(cs,str, str_end);
680 int tmp=my_wildcmp_mb_bin(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
684 } while (str != str_end && wildstr[0] != w_many);
688 return (str != str_end ? 1 : 0);
693 Data was produced from EastAsianWidth.txt
694 using utt11-dump utility.
696 static char pg11[256]=
698 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
699 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
700 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,
701 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
702 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
705 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
708 static char pg23[256]=
710 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
711 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
713 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
714 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
717 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
720 static char pg2E[256]=
722 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
723 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
724 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
725 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
726 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,
727 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
728 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
729 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
732 static char pg2F[256]=
734 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
735 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
736 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
737 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
738 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
739 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
740 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
741 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
744 static char pg30[256]=
746 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
747 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
748 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
749 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
750 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
751 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
752 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
753 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
756 static char pg31[256]=
758 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
759 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
760 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
761 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
762 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
763 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
764 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
765 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
768 static char pg32[256]=
770 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
771 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
772 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
773 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,
774 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
775 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
776 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
777 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
780 static char pg4D[256]=
782 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
783 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
784 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
785 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
786 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
787 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
788 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
789 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
792 static char pg9F[256]=
794 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
795 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
796 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
797 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
798 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
799 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
800 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
801 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
804 static char pgA4[256]=
806 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
807 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
808 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
809 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
810 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
811 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
812 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
813 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
816 static char pgD7[256]=
818 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
819 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
820 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
821 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
822 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
823 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
824 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
825 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
828 static char pgFA[256]=
830 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
831 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
832 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
833 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
834 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
835 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
836 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
837 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
840 static char pgFE[256]=
842 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
843 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
844 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
845 1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
846 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
847 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
848 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
849 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
852 static char pgFF[256]=
854 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
855 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
856 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
857 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
858 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
859 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
860 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
861 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
864 static struct {int page; char *p;} utr11_data[256]=
866 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
867 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
868 {0,NULL},{0,pg11},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
869 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
870 {0,NULL},{0,NULL},{0,NULL},{0,pg23},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
871 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,pg2E},{0,pg2F},
872 {0,pg30},{0,pg31},{0,pg32},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
873 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
874 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
875 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pg4D},{1,NULL},{1,NULL},
876 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
877 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
878 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
879 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
880 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
881 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
882 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
883 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
884 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
885 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pg9F},
886 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pgA4},{0,NULL},{0,NULL},{0,NULL},
887 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
888 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
889 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
890 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
891 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},
892 {1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pgD7},
893 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
894 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
895 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
896 {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},
897 {0,NULL},{1,NULL},{0,pgFA},{0,NULL},{0,NULL},{0,NULL},{0,pgFE},{0,pgFF}
900 uint my_numcells_mb(CHARSET_INFO *cs, const char *b, const char *e)
909 if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0)
911 mblen= 1; /* Let's think a wrong sequence takes 1 dysplay cell */
916 pg= (wc >> 8) & 0xFF;
917 clen+= utr11_data[pg].p ? utr11_data[pg].p[wc & 0xFF] : utr11_data[pg].page;
924 int my_mb_ctype_mb(CHARSET_INFO *cs, int *ctype,
925 const unsigned char *s, const unsigned char *e)
928 int res= cs->cset->mb_wc(cs, &wc, s, e);
932 *ctype= my_uni_ctype[wc>>8].ctype ?
933 my_uni_ctype[wc>>8].ctype[wc&0xFF] :
934 my_uni_ctype[wc>>8].pctype;
940 namespace stardict_collation {
942 MY_COLLATION_HANDLER my_collation_mb_bin_handler =
946 //my_strnncollsp_mb_bin,
947 //my_strnxfrm_mb_bin,
948 //my_strnxfrmlen_simple,
949 //my_like_range_simple,
951 //my_strcasecmp_mb_bin,
953 //my_hash_sort_mb_bin,
954 //my_propagate_simple