Annotation of win32/pcre/pcre_ucp_searchfuncs.c, revision 1.1

1.1     ! misha       1: /*************************************************
        !             2: *      Perl-Compatible Regular Expressions       *
        !             3: *************************************************/
        !             4: 
        !             5: /* PCRE is a library of functions to support regular expressions whose syntax
        !             6: and semantics are as close as possible to those of the Perl 5 language.
        !             7: 
        !             8:                        Written by Philip Hazel
        !             9:            Copyright (c) 1997-2008 University of Cambridge
        !            10: 
        !            11: -----------------------------------------------------------------------------
        !            12: Redistribution and use in source and binary forms, with or without
        !            13: modification, are permitted provided that the following conditions are met:
        !            14: 
        !            15:     * Redistributions of source code must retain the above copyright notice,
        !            16:       this list of conditions and the following disclaimer.
        !            17: 
        !            18:     * Redistributions in binary form must reproduce the above copyright
        !            19:       notice, this list of conditions and the following disclaimer in the
        !            20:       documentation and/or other materials provided with the distribution.
        !            21: 
        !            22:     * Neither the name of the University of Cambridge nor the names of its
        !            23:       contributors may be used to endorse or promote products derived from
        !            24:       this software without specific prior written permission.
        !            25: 
        !            26: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        !            27: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            28: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            29: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
        !            30: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            31: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            32: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            33: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            34: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            35: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            36: POSSIBILITY OF SUCH DAMAGE.
        !            37: -----------------------------------------------------------------------------
        !            38: */
        !            39: 
        !            40: 
        !            41: /* This module contains code for searching the table of Unicode character
        !            42: properties. */
        !            43: 
        !            44: #ifdef HAVE_CONFIG_H
        !            45: #include "config.h"
        !            46: #endif
        !            47: 
        !            48: #include "pcre_internal.h"
        !            49: 
        !            50: #include "ucp.h"               /* Category definitions */
        !            51: #include "ucpinternal.h"       /* Internal table details */
        !            52: #include "ucptable.h"          /* The table itself */
        !            53: 
        !            54: 
        !            55: /* Table to translate from particular type value to the general value. */
        !            56: 
        !            57: static const int ucp_gentype[] = {
        !            58:   ucp_C, ucp_C, ucp_C, ucp_C, ucp_C,  /* Cc, Cf, Cn, Co, Cs */
        !            59:   ucp_L, ucp_L, ucp_L, ucp_L, ucp_L,  /* Ll, Lu, Lm, Lo, Lt */
        !            60:   ucp_M, ucp_M, ucp_M,                /* Mc, Me, Mn */
        !            61:   ucp_N, ucp_N, ucp_N,                /* Nd, Nl, No */
        !            62:   ucp_P, ucp_P, ucp_P, ucp_P, ucp_P,  /* Pc, Pd, Pe, Pf, Pi */
        !            63:   ucp_P, ucp_P,                       /* Ps, Po */
        !            64:   ucp_S, ucp_S, ucp_S, ucp_S,         /* Sc, Sk, Sm, So */
        !            65:   ucp_Z, ucp_Z, ucp_Z                 /* Zl, Zp, Zs */
        !            66: };
        !            67: 
        !            68: 
        !            69: 
        !            70: /*************************************************
        !            71: *         Search table and return type           *
        !            72: *************************************************/
        !            73: 
        !            74: /* Three values are returned: the category is ucp_C, ucp_L, etc. The detailed
        !            75: character type is ucp_Lu, ucp_Nd, etc. The script is ucp_Latin, etc.
        !            76: 
        !            77: Arguments:
        !            78:   c           the character value
        !            79:   type_ptr    the detailed character type is returned here
        !            80:   script_ptr  the script is returned here
        !            81: 
        !            82: Returns:      the character type category
        !            83: */
        !            84: 
        !            85: int
        !            86: _pcre_ucp_findprop(const unsigned int c, int *type_ptr, int *script_ptr)
        !            87: {
        !            88: int bot = 0;
        !            89: int top = sizeof(ucp_table)/sizeof(cnode);
        !            90: int mid;
        !            91: 
        !            92: /* The table is searched using a binary chop. You might think that using
        !            93: intermediate variables to hold some of the common expressions would speed
        !            94: things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
        !            95: makes things a lot slower. */
        !            96: 
        !            97: for (;;)
        !            98:   {
        !            99:   if (top <= bot)
        !           100:     {
        !           101:     *type_ptr = ucp_Cn;
        !           102:     *script_ptr = ucp_Common;
        !           103:     return ucp_C;
        !           104:     }
        !           105:   mid = (bot + top) >> 1;
        !           106:   if (c == (ucp_table[mid].f0 & f0_charmask)) break;
        !           107:   if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
        !           108:   else
        !           109:     {
        !           110:     if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
        !           111:         c <= (ucp_table[mid].f0 & f0_charmask) +
        !           112:              (ucp_table[mid].f1 & f1_rangemask)) break;
        !           113:     bot = mid + 1;
        !           114:     }
        !           115:   }
        !           116: 
        !           117: /* Found an entry in the table. Set the script and detailed type values, and
        !           118: return the general type. */
        !           119: 
        !           120: *script_ptr = (ucp_table[mid].f0 & f0_scriptmask) >> f0_scriptshift;
        !           121: *type_ptr = (ucp_table[mid].f1 & f1_typemask) >> f1_typeshift;
        !           122: 
        !           123: return ucp_gentype[*type_ptr];
        !           124: }
        !           125: 
        !           126: 
        !           127: 
        !           128: /*************************************************
        !           129: *       Search table and return other case       *
        !           130: *************************************************/
        !           131: 
        !           132: /* If the given character is a letter, and there is another case for the
        !           133: letter, return the other case. Otherwise, return -1.
        !           134: 
        !           135: Arguments:
        !           136:   c           the character value
        !           137: 
        !           138: Returns:      the other case or NOTACHAR if none
        !           139: */
        !           140: 
        !           141: unsigned int
        !           142: _pcre_ucp_othercase(const unsigned int c)
        !           143: {
        !           144: int bot = 0;
        !           145: int top = sizeof(ucp_table)/sizeof(cnode);
        !           146: int mid, offset;
        !           147: 
        !           148: /* The table is searched using a binary chop. You might think that using
        !           149: intermediate variables to hold some of the common expressions would speed
        !           150: things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
        !           151: makes things a lot slower. */
        !           152: 
        !           153: for (;;)
        !           154:   {
        !           155:   if (top <= bot) return -1;
        !           156:   mid = (bot + top) >> 1;
        !           157:   if (c == (ucp_table[mid].f0 & f0_charmask)) break;
        !           158:   if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
        !           159:   else
        !           160:     {
        !           161:     if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
        !           162:         c <= (ucp_table[mid].f0 & f0_charmask) +
        !           163:              (ucp_table[mid].f1 & f1_rangemask)) break;
        !           164:     bot = mid + 1;
        !           165:     }
        !           166:   }
        !           167: 
        !           168: /* Found an entry in the table. Return NOTACHAR for a range entry. Otherwise
        !           169: return the other case if there is one, else NOTACHAR. */
        !           170: 
        !           171: if ((ucp_table[mid].f0 & f0_rangeflag) != 0) return NOTACHAR;
        !           172: 
        !           173: offset = ucp_table[mid].f1 & f1_casemask;
        !           174: if ((offset & f1_caseneg) != 0) offset |= f1_caseneg;
        !           175: return (offset == 0)? NOTACHAR : c + offset;
        !           176: }
        !           177: 
        !           178: 
        !           179: /* End of pcre_ucp_searchfuncs.c */

E-mail: