enc/unicode.c

Go to the documentation of this file.
00001 /**********************************************************************
00002   unicode.c -  Oniguruma (regular expression library)
00003 **********************************************************************/
00004 /*-
00005  * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 #include "regint.h"
00031 
00032 #define ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code,ctype) \
00033   ((EncUNICODE_ISO_8859_1_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
00034 #if 0
00035 #define ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(code,cbit) \
00036   ((EncUNICODE_ISO_8859_1_CtypeTable[code] & (cbit)) != 0)
00037 #endif
00038 
00039 static const unsigned short EncUNICODE_ISO_8859_1_CtypeTable[256] = {
00040   0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
00041   0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
00042   0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
00043   0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
00044   0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
00045   0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
00046   0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
00047   0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
00048   0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
00049   0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
00050   0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
00051   0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
00052   0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
00053   0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
00054   0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
00055   0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
00056   0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0288, 0x0008, 0x0008,
00057   0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
00058   0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
00059   0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
00060   0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
00061   0x00a0, 0x00a0, 0x30e2, 0x01a0, 0x00a0, 0x00a8, 0x00a0, 0x00a0,
00062   0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x00a0, 0x01a0,
00063   0x00a0, 0x10a0, 0x30e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
00064   0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
00065   0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
00066   0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
00067   0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
00068   0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
00069   0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
00070   0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
00071   0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
00072 };
00073 
00074 #include "enc/unicode/name2ctype.h"
00075 
00076 typedef struct {
00077   int n;
00078   OnigCodePoint code[3];
00079 } CodePointList3;
00080 
00081 typedef struct {
00082   OnigCodePoint  from;
00083   CodePointList3 to;
00084 } CaseFold_11_Type;
00085 
00086 typedef struct {
00087   OnigCodePoint  from;
00088   CodePointList3 to;
00089 } CaseUnfold_11_Type;
00090 
00091 typedef struct {
00092   int n;
00093   OnigCodePoint code[2];
00094 } CodePointList2;
00095 
00096 typedef struct {
00097   OnigCodePoint  from[2];
00098   CodePointList2 to;
00099 } CaseUnfold_12_Type;
00100 
00101 typedef struct {
00102   OnigCodePoint  from[3];
00103   CodePointList2 to;
00104 } CaseUnfold_13_Type;
00105 
00106 #include "enc/unicode/casefold.h"
00107 
00108 
00109 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
00110 #define CODE_RANGES_NUM numberof(CodeRanges)
00111 
00112 extern int
00113 onigenc_unicode_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc ARG_UNUSED)
00114 {
00115   if (
00116 #ifdef USE_UNICODE_PROPERTIES
00117       ctype <= ONIGENC_MAX_STD_CTYPE &&
00118 #endif
00119       code < 256) {
00120     return ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code, ctype);
00121   }
00122 
00123   if (ctype >= CODE_RANGES_NUM) {
00124     return ONIGERR_TYPE_BUG;
00125   }
00126 
00127   return onig_is_in_code_range((UChar* )CodeRanges[ctype], code);
00128 }
00129 
00130 
00131 extern int
00132 onigenc_unicode_ctype_code_range(int ctype, const OnigCodePoint* ranges[])
00133 {
00134   if (ctype >= CODE_RANGES_NUM) {
00135     return ONIGERR_TYPE_BUG;
00136   }
00137 
00138   *ranges = CodeRanges[ctype];
00139 
00140   return 0;
00141 }
00142 
00143 extern int
00144 onigenc_utf16_32_get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
00145                                       const OnigCodePoint* ranges[],
00146                                       struct OnigEncodingTypeST* enc ARG_UNUSED)
00147 {
00148   *sb_out = 0x00;
00149   return onigenc_unicode_ctype_code_range(ctype, ranges);
00150 }
00151 
00152 #include "ruby/st.h"
00153 
00154 #define PROPERTY_NAME_MAX_SIZE    (MAX_WORD_LENGTH + 1)
00155 
00156 extern int
00157 onigenc_unicode_property_name_to_ctype(OnigEncoding enc, UChar* name, UChar* end)
00158 {
00159   int len;
00160   int ctype;
00161   UChar buf[PROPERTY_NAME_MAX_SIZE];
00162   UChar *p;
00163   OnigCodePoint code;
00164 
00165   len = 0;
00166   for (p = name; p < end; p += enclen(enc, p, end)) {
00167     code = ONIGENC_MBC_TO_CODE(enc, p, end);
00168     if (code == ' ' || code == '-' || code == '_')
00169       continue;
00170     if (code >= 0x80)
00171       return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
00172 
00173     buf[len++] = ONIGENC_ASCII_CODE_TO_LOWER_CASE(code);
00174     if (len >= PROPERTY_NAME_MAX_SIZE)
00175       return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
00176   }
00177 
00178   buf[len] = 0;
00179 
00180   if ((ctype = uniname2ctype(buf, len)) < 0) {
00181     return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
00182   }
00183 
00184   return ctype;
00185 }
00186 
00187 
00188 static int
00189 code2_cmp(OnigCodePoint* x, OnigCodePoint* y)
00190 {
00191   if (x[0] == y[0] && x[1] == y[1]) return 0;
00192   return 1;
00193 }
00194 
00195 static st_index_t
00196 code2_hash(OnigCodePoint* x)
00197 {
00198   return (st_index_t )(x[0] + x[1]);
00199 }
00200 
00201 static const struct st_hash_type type_code2_hash = {
00202   code2_cmp,
00203   code2_hash,
00204 };
00205 
00206 static int
00207 code3_cmp(OnigCodePoint* x, OnigCodePoint* y)
00208 {
00209   if (x[0] == y[0] && x[1] == y[1] && x[2] == y[2]) return 0;
00210   return 1;
00211 }
00212 
00213 static st_index_t
00214 code3_hash(OnigCodePoint* x)
00215 {
00216   return (st_index_t )(x[0] + x[1] + x[2]);
00217 }
00218 
00219 static const struct st_hash_type type_code3_hash = {
00220   code3_cmp,
00221   code3_hash,
00222 };
00223 
00224 
00225 static st_table* FoldTable;    /* fold-1, fold-2, fold-3 */
00226 static st_table* Unfold1Table;
00227 static st_table* Unfold2Table;
00228 static st_table* Unfold3Table;
00229 static int CaseFoldInited = 0;
00230 
00231 static int init_case_fold_table(void)
00232 {
00233   const CaseFold_11_Type   *p;
00234   const CaseUnfold_11_Type *p1;
00235   const CaseUnfold_12_Type *p2;
00236   const CaseUnfold_13_Type *p3;
00237   int i;
00238 
00239   THREAD_ATOMIC_START;
00240 
00241   FoldTable = st_init_numtable_with_size(FOLD_TABLE_SIZE);
00242   if (ONIG_IS_NULL(FoldTable)) return ONIGERR_MEMORY;
00243   for (i = 0; i < numberof(CaseFold); i++) {
00244     p = &CaseFold[i];
00245     st_add_direct(FoldTable, (st_data_t )p->from, (st_data_t )&(p->to));
00246   }
00247   for (i = 0; i < numberof(CaseFold_Locale); i++) {
00248     p = &CaseFold_Locale[i];
00249     st_add_direct(FoldTable, (st_data_t )p->from, (st_data_t )&(p->to));
00250   }
00251 
00252   Unfold1Table = st_init_numtable_with_size(UNFOLD1_TABLE_SIZE);
00253   if (ONIG_IS_NULL(Unfold1Table)) return ONIGERR_MEMORY;
00254 
00255   for (i = 0; i < numberof(CaseUnfold_11); i++) {
00256     p1 = &CaseUnfold_11[i];
00257     st_add_direct(Unfold1Table, (st_data_t )p1->from, (st_data_t )&(p1->to));
00258   }
00259   for (i = 0; i < numberof(CaseUnfold_11_Locale); i++) {
00260     p1 = &CaseUnfold_11_Locale[i];
00261     st_add_direct(Unfold1Table, (st_data_t )p1->from, (st_data_t )&(p1->to));
00262   }
00263 
00264   Unfold2Table = st_init_table_with_size(&type_code2_hash, UNFOLD2_TABLE_SIZE);
00265   if (ONIG_IS_NULL(Unfold2Table)) return ONIGERR_MEMORY;
00266 
00267   for (i = 0; i < numberof(CaseUnfold_12); i++) {
00268     p2 = &CaseUnfold_12[i];
00269     st_add_direct(Unfold2Table, (st_data_t )p2->from, (st_data_t )(&p2->to));
00270   }
00271   for (i = 0; i < numberof(CaseUnfold_12_Locale); i++) {
00272     p2 = &CaseUnfold_12_Locale[i];
00273     st_add_direct(Unfold2Table, (st_data_t )p2->from, (st_data_t )(&p2->to));
00274   }
00275 
00276   Unfold3Table = st_init_table_with_size(&type_code3_hash, UNFOLD3_TABLE_SIZE);
00277   if (ONIG_IS_NULL(Unfold3Table)) return ONIGERR_MEMORY;
00278 
00279   for (i = 0; i < numberof(CaseUnfold_13); i++) {
00280     p3 = &CaseUnfold_13[i];
00281     st_add_direct(Unfold3Table, (st_data_t )p3->from, (st_data_t )(&p3->to));
00282   }
00283 
00284   CaseFoldInited = 1;
00285   THREAD_ATOMIC_END;
00286   return 0;
00287 }
00288 
00289 extern int
00290 onigenc_unicode_mbc_case_fold(OnigEncoding enc,
00291     OnigCaseFoldType flag ARG_UNUSED, const UChar** pp, const UChar* end,
00292     UChar* fold)
00293 {
00294   CodePointList3 *to;
00295   OnigCodePoint code;
00296   int i, len, rlen;
00297   const UChar *p = *pp;
00298 
00299   if (CaseFoldInited == 0) init_case_fold_table();
00300 
00301   code = ONIGENC_MBC_TO_CODE(enc, p, end);
00302   len = enclen(enc, p, end);
00303   *pp += len;
00304 
00305 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00306   if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
00307     if (code == 0x0049) {
00308       return ONIGENC_CODE_TO_MBC(enc, 0x0131, fold);
00309     }
00310     else if (code == 0x0130) {
00311       return ONIGENC_CODE_TO_MBC(enc, 0x0069, fold);
00312     }
00313   }
00314 #endif
00315 
00316   if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0) {
00317     if (to->n == 1) {
00318       return ONIGENC_CODE_TO_MBC(enc, to->code[0], fold);
00319     }
00320 #if 0
00321     /* NO NEEDS TO CHECK */
00322     else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0)
00323 #else
00324     else
00325 #endif
00326     {
00327       rlen = 0;
00328       for (i = 0; i < to->n; i++) {
00329         len = ONIGENC_CODE_TO_MBC(enc, to->code[i], fold);
00330         fold += len;
00331         rlen += len;
00332       }
00333       return rlen;
00334     }
00335   }
00336 
00337   for (i = 0; i < len; i++) {
00338     *fold++ = *p++;
00339   }
00340   return len;
00341 }
00342 
00343 extern int
00344 onigenc_unicode_apply_all_case_fold(OnigCaseFoldType flag,
00345                                     OnigApplyAllCaseFoldFunc f, void* arg,
00346                                     OnigEncoding enc ARG_UNUSED)
00347 {
00348   const CaseUnfold_11_Type* p11;
00349   OnigCodePoint code;
00350   int i, j, k, r;
00351 
00352   /* if (CaseFoldInited == 0) init_case_fold_table(); */
00353 
00354   for (i = 0; i < numberof(CaseUnfold_11); i++) {
00355     p11 = &CaseUnfold_11[i];
00356     for (j = 0; j < p11->to.n; j++) {
00357       code = p11->from;
00358       r = (*f)(p11->to.code[j], &code, 1, arg);
00359       if (r != 0) return r;
00360 
00361       code = p11->to.code[j];
00362       r = (*f)(p11->from, &code, 1, arg);
00363       if (r != 0) return r;
00364 
00365       for (k = 0; k < j; k++) {
00366         r = (*f)(p11->to.code[j], (OnigCodePoint* )(&p11->to.code[k]), 1, arg);
00367         if (r != 0) return r;
00368 
00369         r = (*f)(p11->to.code[k], (OnigCodePoint* )(&p11->to.code[j]), 1, arg);
00370         if (r != 0) return r;
00371       }
00372     }
00373   }
00374 
00375 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00376   if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
00377     code = 0x0131;
00378     r = (*f)(0x0049, &code, 1, arg);
00379     if (r != 0) return r;
00380     code = 0x0049;
00381     r = (*f)(0x0131, &code, 1, arg);
00382     if (r != 0) return r;
00383 
00384     code = 0x0130;
00385     r = (*f)(0x0069, &code, 1, arg);
00386     if (r != 0) return r;
00387     code = 0x0069;
00388     r = (*f)(0x0130, &code, 1, arg);
00389     if (r != 0) return r;
00390   }
00391   else {
00392 #endif
00393     for (i = 0; i < numberof(CaseUnfold_11_Locale); i++) {
00394       p11 = &CaseUnfold_11_Locale[i];
00395       for (j = 0; j < p11->to.n; j++) {
00396         code = p11->from;
00397         r = (*f)(p11->to.code[j], &code, 1, arg);
00398         if (r != 0) return r;
00399 
00400         code = p11->to.code[j];
00401         r = (*f)(p11->from, &code, 1, arg);
00402         if (r != 0) return r;
00403 
00404         for (k = 0; k < j; k++) {
00405           r = (*f)(p11->to.code[j], (OnigCodePoint* )(&p11->to.code[k]),
00406                    1, arg);
00407           if (r != 0) return r;
00408 
00409           r = (*f)(p11->to.code[k], (OnigCodePoint* )(&p11->to.code[j]),
00410                    1, arg);
00411           if (r != 0) return r;
00412         }
00413       }
00414     }
00415 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00416   }
00417 #endif
00418 
00419   if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
00420     for (i = 0; i < numberof(CaseUnfold_12); i++) {
00421       for (j = 0; j < CaseUnfold_12[i].to.n; j++) {
00422         r = (*f)(CaseUnfold_12[i].to.code[j],
00423                  (OnigCodePoint* )CaseUnfold_12[i].from, 2, arg);
00424         if (r != 0) return r;
00425 
00426         for (k = 0; k < CaseUnfold_12[i].to.n; k++) {
00427           if (k == j) continue;
00428 
00429           r = (*f)(CaseUnfold_12[i].to.code[j],
00430                    (OnigCodePoint* )(&CaseUnfold_12[i].to.code[k]), 1, arg);
00431           if (r != 0) return r;
00432         }
00433       }
00434     }
00435 
00436 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00437     if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) == 0) {
00438 #endif
00439       for (i = 0; i < numberof(CaseUnfold_12_Locale); i++) {
00440         for (j = 0; j < CaseUnfold_12_Locale[i].to.n; j++) {
00441           r = (*f)(CaseUnfold_12_Locale[i].to.code[j],
00442                    (OnigCodePoint* )CaseUnfold_12_Locale[i].from, 2, arg);
00443           if (r != 0) return r;
00444 
00445           for (k = 0; k < CaseUnfold_12_Locale[i].to.n; k++) {
00446             if (k == j) continue;
00447 
00448             r = (*f)(CaseUnfold_12_Locale[i].to.code[j],
00449                      (OnigCodePoint* )(&CaseUnfold_12_Locale[i].to.code[k]),
00450                      1, arg);
00451             if (r != 0) return r;
00452           }
00453         }
00454       }
00455 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00456     }
00457 #endif
00458 
00459     for (i = 0; i < numberof(CaseUnfold_13); i++) {
00460       for (j = 0; j < CaseUnfold_13[i].to.n; j++) {
00461         r = (*f)(CaseUnfold_13[i].to.code[j],
00462                  (OnigCodePoint* )CaseUnfold_13[i].from, 3, arg);
00463         if (r != 0) return r;
00464 
00465         for (k = 0; k < CaseUnfold_13[i].to.n; k++) {
00466           if (k == j) continue;
00467 
00468           r = (*f)(CaseUnfold_13[i].to.code[j],
00469                    (OnigCodePoint* )(&CaseUnfold_13[i].to.code[k]), 1, arg);
00470           if (r != 0) return r;
00471         }
00472       }
00473     }
00474   }
00475 
00476   return 0;
00477 }
00478 
00479 extern int
00480 onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc,
00481     OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end,
00482     OnigCaseFoldCodeItem items[])
00483 {
00484   int n, i, j, k, len;
00485   OnigCodePoint code, codes[3];
00486   CodePointList3 *to, *z3;
00487   CodePointList2 *z2;
00488 
00489   if (CaseFoldInited == 0) init_case_fold_table();
00490 
00491   n = 0;
00492 
00493   code = ONIGENC_MBC_TO_CODE(enc, p, end);
00494   len = enclen(enc, p, end);
00495 
00496 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00497   if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
00498     if (code == 0x0049) {
00499       items[0].byte_len = len;
00500       items[0].code_len = 1;
00501       items[0].code[0]  = 0x0131;
00502       return 1;
00503     }
00504     else if (code == 0x0130) {
00505       items[0].byte_len = len;
00506       items[0].code_len = 1;
00507       items[0].code[0]  = 0x0069;
00508       return 1;
00509     }
00510     else if (code == 0x0131) {
00511       items[0].byte_len = len;
00512       items[0].code_len = 1;
00513       items[0].code[0]  = 0x0049;
00514       return 1;
00515     }
00516     else if (code == 0x0069) {
00517       items[0].byte_len = len;
00518       items[0].code_len = 1;
00519       items[0].code[0]  = 0x0130;
00520       return 1;
00521     }
00522   }
00523 #endif
00524 
00525   if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0) {
00526     if (to->n == 1) {
00527       OnigCodePoint orig_code = code;
00528 
00529       items[0].byte_len = len;
00530       items[0].code_len = 1;
00531       items[0].code[0]  = to->code[0];
00532       n++;
00533 
00534       code = to->code[0];
00535       if (onig_st_lookup(Unfold1Table, (st_data_t )code, (void* )&to) != 0) {
00536         for (i = 0; i < to->n; i++) {
00537           if (to->code[i] != orig_code) {
00538             items[n].byte_len = len;
00539             items[n].code_len = 1;
00540             items[n].code[0]  = to->code[i];
00541             n++;
00542           }
00543         }
00544       }
00545     }
00546     else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
00547       OnigCodePoint cs[3][4];
00548       int fn, ncs[3];
00549 
00550       for (fn = 0; fn < to->n; fn++) {
00551         cs[fn][0] = to->code[fn];
00552         if (onig_st_lookup(Unfold1Table, (st_data_t )cs[fn][0],
00553                            (void* )&z3) != 0) {
00554           for (i = 0; i < z3->n; i++) {
00555             cs[fn][i+1] = z3->code[i];
00556           }
00557           ncs[fn] = z3->n + 1;
00558         }
00559         else
00560           ncs[fn] = 1;
00561       }
00562 
00563       if (fn == 2) {
00564         for (i = 0; i < ncs[0]; i++) {
00565           for (j = 0; j < ncs[1]; j++) {
00566             items[n].byte_len = len;
00567             items[n].code_len = 2;
00568             items[n].code[0]  = cs[0][i];
00569             items[n].code[1]  = cs[1][j];
00570             n++;
00571           }
00572         }
00573 
00574         if (onig_st_lookup(Unfold2Table, (st_data_t )to->code,
00575                            (void* )&z2) != 0) {
00576           for (i = 0; i < z2->n; i++) {
00577             if (z2->code[i] == code) continue;
00578 
00579             items[n].byte_len = len;
00580             items[n].code_len = 1;
00581             items[n].code[0]  = z2->code[i];
00582             n++;
00583           }
00584         }
00585       }
00586       else {
00587         for (i = 0; i < ncs[0]; i++) {
00588           for (j = 0; j < ncs[1]; j++) {
00589             for (k = 0; k < ncs[2]; k++) {
00590               items[n].byte_len = len;
00591               items[n].code_len = 3;
00592               items[n].code[0]  = cs[0][i];
00593               items[n].code[1]  = cs[1][j];
00594               items[n].code[2]  = cs[2][k];
00595               n++;
00596             }
00597           }
00598         }
00599 
00600         if (onig_st_lookup(Unfold3Table, (st_data_t )to->code,
00601                            (void* )&z2) != 0) {
00602           for (i = 0; i < z2->n; i++) {
00603             if (z2->code[i] == code) continue;
00604 
00605             items[n].byte_len = len;
00606             items[n].code_len = 1;
00607             items[n].code[0]  = z2->code[i];
00608             n++;
00609           }
00610         }
00611       }
00612 
00613       /* multi char folded code is not head of another folded multi char */
00614       flag = 0; /* DISABLE_CASE_FOLD_MULTI_CHAR(flag); */
00615     }
00616   }
00617   else {
00618     if (onig_st_lookup(Unfold1Table, (st_data_t )code, (void* )&to) != 0) {
00619       for (i = 0; i < to->n; i++) {
00620         items[n].byte_len = len;
00621         items[n].code_len = 1;
00622         items[n].code[0]  = to->code[i];
00623         n++;
00624       }
00625     }
00626   }
00627 
00628 
00629   if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
00630     p += len;
00631     if (p < end) {
00632       int clen;
00633 
00634       codes[0] = code;
00635       code = ONIGENC_MBC_TO_CODE(enc, p, end);
00636       if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0
00637           && to->n == 1) {
00638         codes[1] = to->code[0];
00639       }
00640       else
00641         codes[1] = code;
00642 
00643       clen = enclen(enc, p, end);
00644       len += clen;
00645       if (onig_st_lookup(Unfold2Table, (st_data_t )codes, (void* )&z2) != 0) {
00646         for (i = 0; i < z2->n; i++) {
00647           items[n].byte_len = len;
00648           items[n].code_len = 1;
00649           items[n].code[0]  = z2->code[i];
00650           n++;
00651         }
00652       }
00653 
00654       p += clen;
00655       if (p < end) {
00656         code = ONIGENC_MBC_TO_CODE(enc, p, end);
00657         if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0
00658             && to->n == 1) {
00659           codes[2] = to->code[0];
00660         }
00661         else
00662           codes[2] = code;
00663 
00664         clen = enclen(enc, p, end);
00665         len += clen;
00666         if (onig_st_lookup(Unfold3Table, (st_data_t )codes,
00667                            (void* )&z2) != 0) {
00668           for (i = 0; i < z2->n; i++) {
00669             items[n].byte_len = len;
00670             items[n].code_len = 1;
00671             items[n].code[0]  = z2->code[i];
00672             n++;
00673           }
00674         }
00675       }
00676     }
00677   }
00678 
00679   return n;
00680 }
00681 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7