LCOV - code coverage report
Current view: top level - intl/icu/source/common - uprops.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 6 185 3.2 %
Date: 2017-07-14 16:53:18 Functions: 2 37 5.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : *
       6             : *   Copyright (C) 2002-2016, International Business Machines
       7             : *   Corporation and others.  All Rights Reserved.
       8             : *
       9             : *******************************************************************************
      10             : *   file name:  uprops.cpp
      11             : *   encoding:   UTF-8
      12             : *   tab size:   8 (not used)
      13             : *   indentation:4
      14             : *
      15             : *   created on: 2002feb24
      16             : *   created by: Markus W. Scherer
      17             : *
      18             : *   Implementations for mostly non-core Unicode character properties
      19             : *   stored in uprops.icu.
      20             : *
      21             : *   With the APIs implemented here, almost all properties files and
      22             : *   their associated implementation files are used from this file,
      23             : *   including those for normalization and case mappings.
      24             : */
      25             : 
      26             : #include "unicode/utypes.h"
      27             : #include "unicode/uchar.h"
      28             : #include "unicode/unorm2.h"
      29             : #include "unicode/uscript.h"
      30             : #include "unicode/ustring.h"
      31             : #include "cstring.h"
      32             : #include "normalizer2impl.h"
      33             : #include "umutex.h"
      34             : #include "ubidi_props.h"
      35             : #include "uprops.h"
      36             : #include "ucase.h"
      37             : #include "ustr_imp.h"
      38             : 
      39             : U_NAMESPACE_USE
      40             : 
      41             : #define GET_BIDI_PROPS() ubidi_getSingleton()
      42             : 
      43             : /* general properties API functions ----------------------------------------- */
      44             : 
      45             : struct BinaryProperty;
      46             : 
      47             : typedef UBool BinaryPropertyContains(const BinaryProperty &prop, UChar32 c, UProperty which);
      48             : 
      49             : struct BinaryProperty {
      50             :     int32_t column;  // SRC_PROPSVEC column, or "source" if mask==0
      51             :     uint32_t mask;
      52             :     BinaryPropertyContains *contains;
      53             : };
      54             : 
      55         265 : static UBool defaultContains(const BinaryProperty &prop, UChar32 c, UProperty /*which*/) {
      56             :     /* systematic, directly stored properties */
      57         265 :     return (u_getUnicodeProperties(c, prop.column)&prop.mask)!=0;
      58             : }
      59             : 
      60           0 : static UBool caseBinaryPropertyContains(const BinaryProperty &/*prop*/, UChar32 c, UProperty which) {
      61           0 :     return ucase_hasBinaryProperty(c, which);
      62             : }
      63             : 
      64           0 : static UBool isBidiControl(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
      65           0 :     return ubidi_isBidiControl(GET_BIDI_PROPS(), c);
      66             : }
      67             : 
      68           0 : static UBool isMirrored(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
      69           0 :     return ubidi_isMirrored(GET_BIDI_PROPS(), c);
      70             : }
      71             : 
      72           0 : static UBool isJoinControl(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
      73           0 :     return ubidi_isJoinControl(GET_BIDI_PROPS(), c);
      74             : }
      75             : 
      76             : #if UCONFIG_NO_NORMALIZATION
      77             : static UBool hasFullCompositionExclusion(const BinaryProperty &, UChar32, UProperty) {
      78             :     return FALSE;
      79             : }
      80             : #else
      81           0 : static UBool hasFullCompositionExclusion(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
      82             :     // By definition, Full_Composition_Exclusion is the same as NFC_QC=No.
      83           0 :     UErrorCode errorCode=U_ZERO_ERROR;
      84           0 :     const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
      85           0 :     return U_SUCCESS(errorCode) && impl->isCompNo(impl->getNorm16(c));
      86             : }
      87             : #endif
      88             : 
      89             : // UCHAR_NF*_INERT properties
      90             : #if UCONFIG_NO_NORMALIZATION
      91             : static UBool isNormInert(const BinaryProperty &, UChar32, UProperty) {
      92             :     return FALSE;
      93             : }
      94             : #else
      95           0 : static UBool isNormInert(const BinaryProperty &/*prop*/, UChar32 c, UProperty which) {
      96           0 :     UErrorCode errorCode=U_ZERO_ERROR;
      97           0 :     const Normalizer2 *norm2=Normalizer2Factory::getInstance(
      98           0 :         (UNormalizationMode)(which-UCHAR_NFD_INERT+UNORM_NFD), errorCode);
      99           0 :     return U_SUCCESS(errorCode) && norm2->isInert(c);
     100             : }
     101             : #endif
     102             : 
     103             : #if UCONFIG_NO_NORMALIZATION
     104             : static UBool changesWhenCasefolded(const BinaryProperty &, UChar32, UProperty) {
     105             :     return FALSE;
     106             : }
     107             : #else
     108           0 : static UBool changesWhenCasefolded(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     109           0 :     UnicodeString nfd;
     110           0 :     UErrorCode errorCode=U_ZERO_ERROR;
     111           0 :     const Normalizer2 *nfcNorm2=Normalizer2::getNFCInstance(errorCode);
     112           0 :     if(U_FAILURE(errorCode)) {
     113           0 :         return FALSE;
     114             :     }
     115           0 :     if(nfcNorm2->getDecomposition(c, nfd)) {
     116             :         /* c has a decomposition */
     117           0 :         if(nfd.length()==1) {
     118           0 :             c=nfd[0];  /* single BMP code point */
     119           0 :         } else if(nfd.length()<=U16_MAX_LENGTH &&
     120           0 :                   nfd.length()==U16_LENGTH(c=nfd.char32At(0))
     121             :         ) {
     122             :             /* single supplementary code point */
     123             :         } else {
     124           0 :             c=U_SENTINEL;
     125             :         }
     126           0 :     } else if(c<0) {
     127           0 :         return FALSE;  /* protect against bad input */
     128             :     }
     129           0 :     if(c>=0) {
     130             :         /* single code point */
     131             :         const UChar *resultString;
     132           0 :         return (UBool)(ucase_toFullFolding(c, &resultString, U_FOLD_CASE_DEFAULT)>=0);
     133             :     } else {
     134             :         /* guess some large but stack-friendly capacity */
     135             :         UChar dest[2*UCASE_MAX_STRING_LENGTH];
     136             :         int32_t destLength;
     137           0 :         destLength=u_strFoldCase(dest, UPRV_LENGTHOF(dest),
     138             :                                   nfd.getBuffer(), nfd.length(),
     139           0 :                                   U_FOLD_CASE_DEFAULT, &errorCode);
     140           0 :         return (UBool)(U_SUCCESS(errorCode) &&
     141           0 :                        0!=u_strCompare(nfd.getBuffer(), nfd.length(),
     142           0 :                                        dest, destLength, FALSE));
     143             :     }
     144             : }
     145             : #endif
     146             : 
     147             : #if UCONFIG_NO_NORMALIZATION
     148             : static UBool changesWhenNFKC_Casefolded(const BinaryProperty &, UChar32, UProperty) {
     149             :     return FALSE;
     150             : }
     151             : #else
     152           0 : static UBool changesWhenNFKC_Casefolded(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     153           0 :     UErrorCode errorCode=U_ZERO_ERROR;
     154           0 :     const Normalizer2Impl *kcf=Normalizer2Factory::getNFKC_CFImpl(errorCode);
     155           0 :     if(U_FAILURE(errorCode)) {
     156           0 :         return FALSE;
     157             :     }
     158           0 :     UnicodeString src(c);
     159           0 :     UnicodeString dest;
     160             :     {
     161             :         // The ReorderingBuffer must be in a block because its destructor
     162             :         // needs to release dest's buffer before we look at its contents.
     163           0 :         ReorderingBuffer buffer(*kcf, dest);
     164             :         // Small destCapacity for NFKC_CF(c).
     165           0 :         if(buffer.init(5, errorCode)) {
     166           0 :             const UChar *srcArray=src.getBuffer();
     167           0 :             kcf->compose(srcArray, srcArray+src.length(), FALSE,
     168           0 :                           TRUE, buffer, errorCode);
     169             :         }
     170             :     }
     171           0 :     return U_SUCCESS(errorCode) && dest!=src;
     172             : }
     173             : #endif
     174             : 
     175             : #if UCONFIG_NO_NORMALIZATION
     176             : static UBool isCanonSegmentStarter(const BinaryProperty &, UChar32, UProperty) {
     177             :     return FALSE;
     178             : }
     179             : #else
     180           0 : static UBool isCanonSegmentStarter(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     181           0 :     UErrorCode errorCode=U_ZERO_ERROR;
     182           0 :     const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
     183             :     return
     184           0 :         U_SUCCESS(errorCode) && impl->ensureCanonIterData(errorCode) &&
     185           0 :         impl->isCanonSegmentStarter(c);
     186             : }
     187             : #endif
     188             : 
     189           0 : static UBool isPOSIX_alnum(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     190           0 :     return u_isalnumPOSIX(c);
     191             : }
     192             : 
     193           0 : static UBool isPOSIX_blank(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     194           0 :     return u_isblank(c);
     195             : }
     196             : 
     197           0 : static UBool isPOSIX_graph(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     198           0 :     return u_isgraphPOSIX(c);
     199             : }
     200             : 
     201           0 : static UBool isPOSIX_print(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     202           0 :     return u_isprintPOSIX(c);
     203             : }
     204             : 
     205           0 : static UBool isPOSIX_xdigit(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     206           0 :     return u_isxdigit(c);
     207             : }
     208             : 
     209             : static const BinaryProperty binProps[UCHAR_BINARY_LIMIT]={
     210             :     /*
     211             :      * column and mask values for binary properties from u_getUnicodeProperties().
     212             :      * Must be in order of corresponding UProperty,
     213             :      * and there must be exactly one entry per binary UProperty.
     214             :      *
     215             :      * Properties with mask==0 are handled in code.
     216             :      * For them, column is the UPropertySource value.
     217             :      */
     218             :     { 1,                U_MASK(UPROPS_ALPHABETIC), defaultContains },
     219             :     { 1,                U_MASK(UPROPS_ASCII_HEX_DIGIT), defaultContains },
     220             :     { UPROPS_SRC_BIDI,  0, isBidiControl },
     221             :     { UPROPS_SRC_BIDI,  0, isMirrored },
     222             :     { 1,                U_MASK(UPROPS_DASH), defaultContains },
     223             :     { 1,                U_MASK(UPROPS_DEFAULT_IGNORABLE_CODE_POINT), defaultContains },
     224             :     { 1,                U_MASK(UPROPS_DEPRECATED), defaultContains },
     225             :     { 1,                U_MASK(UPROPS_DIACRITIC), defaultContains },
     226             :     { 1,                U_MASK(UPROPS_EXTENDER), defaultContains },
     227             :     { UPROPS_SRC_NFC,   0, hasFullCompositionExclusion },
     228             :     { 1,                U_MASK(UPROPS_GRAPHEME_BASE), defaultContains },
     229             :     { 1,                U_MASK(UPROPS_GRAPHEME_EXTEND), defaultContains },
     230             :     { 1,                U_MASK(UPROPS_GRAPHEME_LINK), defaultContains },
     231             :     { 1,                U_MASK(UPROPS_HEX_DIGIT), defaultContains },
     232             :     { 1,                U_MASK(UPROPS_HYPHEN), defaultContains },
     233             :     { 1,                U_MASK(UPROPS_ID_CONTINUE), defaultContains },
     234             :     { 1,                U_MASK(UPROPS_ID_START), defaultContains },
     235             :     { 1,                U_MASK(UPROPS_IDEOGRAPHIC), defaultContains },
     236             :     { 1,                U_MASK(UPROPS_IDS_BINARY_OPERATOR), defaultContains },
     237             :     { 1,                U_MASK(UPROPS_IDS_TRINARY_OPERATOR), defaultContains },
     238             :     { UPROPS_SRC_BIDI,  0, isJoinControl },
     239             :     { 1,                U_MASK(UPROPS_LOGICAL_ORDER_EXCEPTION), defaultContains },
     240             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_LOWERCASE
     241             :     { 1,                U_MASK(UPROPS_MATH), defaultContains },
     242             :     { 1,                U_MASK(UPROPS_NONCHARACTER_CODE_POINT), defaultContains },
     243             :     { 1,                U_MASK(UPROPS_QUOTATION_MARK), defaultContains },
     244             :     { 1,                U_MASK(UPROPS_RADICAL), defaultContains },
     245             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_SOFT_DOTTED
     246             :     { 1,                U_MASK(UPROPS_TERMINAL_PUNCTUATION), defaultContains },
     247             :     { 1,                U_MASK(UPROPS_UNIFIED_IDEOGRAPH), defaultContains },
     248             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_UPPERCASE
     249             :     { 1,                U_MASK(UPROPS_WHITE_SPACE), defaultContains },
     250             :     { 1,                U_MASK(UPROPS_XID_CONTINUE), defaultContains },
     251             :     { 1,                U_MASK(UPROPS_XID_START), defaultContains },
     252             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CASE_SENSITIVE
     253             :     { 1,                U_MASK(UPROPS_S_TERM), defaultContains },
     254             :     { 1,                U_MASK(UPROPS_VARIATION_SELECTOR), defaultContains },
     255             :     { UPROPS_SRC_NFC,   0, isNormInert },  // UCHAR_NFD_INERT
     256             :     { UPROPS_SRC_NFKC,  0, isNormInert },  // UCHAR_NFKD_INERT
     257             :     { UPROPS_SRC_NFC,   0, isNormInert },  // UCHAR_NFC_INERT
     258             :     { UPROPS_SRC_NFKC,  0, isNormInert },  // UCHAR_NFKC_INERT
     259             :     { UPROPS_SRC_NFC_CANON_ITER, 0, isCanonSegmentStarter },
     260             :     { 1,                U_MASK(UPROPS_PATTERN_SYNTAX), defaultContains },
     261             :     { 1,                U_MASK(UPROPS_PATTERN_WHITE_SPACE), defaultContains },
     262             :     { UPROPS_SRC_CHAR_AND_PROPSVEC,  0, isPOSIX_alnum },
     263             :     { UPROPS_SRC_CHAR,  0, isPOSIX_blank },
     264             :     { UPROPS_SRC_CHAR,  0, isPOSIX_graph },
     265             :     { UPROPS_SRC_CHAR,  0, isPOSIX_print },
     266             :     { UPROPS_SRC_CHAR,  0, isPOSIX_xdigit },
     267             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CASED
     268             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CASE_IGNORABLE
     269             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_LOWERCASED
     270             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_UPPERCASED
     271             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_TITLECASED
     272             :     { UPROPS_SRC_CASE_AND_NORM,  0, changesWhenCasefolded },
     273             :     { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_CASEMAPPED
     274             :     { UPROPS_SRC_NFKC_CF, 0, changesWhenNFKC_Casefolded },
     275             :     { 2,                U_MASK(UPROPS_2_EMOJI), defaultContains },
     276             :     { 2,                U_MASK(UPROPS_2_EMOJI_PRESENTATION), defaultContains },
     277             :     { 2,                U_MASK(UPROPS_2_EMOJI_MODIFIER), defaultContains },
     278             :     { 2,                U_MASK(UPROPS_2_EMOJI_MODIFIER_BASE), defaultContains },
     279             : };
     280             : 
     281             : U_CAPI UBool U_EXPORT2
     282         265 : u_hasBinaryProperty(UChar32 c, UProperty which) {
     283             :     /* c is range-checked in the functions that are called from here */
     284         265 :     if(which<UCHAR_BINARY_START || UCHAR_BINARY_LIMIT<=which) {
     285             :         /* not a known binary property */
     286           0 :         return FALSE;
     287             :     } else {
     288         265 :         const BinaryProperty &prop=binProps[which];
     289         265 :         return prop.contains(prop, c, which);
     290             :     }
     291             : }
     292             : 
     293             : struct IntProperty;
     294             : 
     295             : typedef int32_t IntPropertyGetValue(const IntProperty &prop, UChar32 c, UProperty which);
     296             : typedef int32_t IntPropertyGetMaxValue(const IntProperty &prop, UProperty which);
     297             : 
     298             : struct IntProperty {
     299             :     int32_t column;  // SRC_PROPSVEC column, or "source" if mask==0
     300             :     uint32_t mask;
     301             :     int32_t shift;  // =maxValue if getMaxValueFromShift() is used
     302             :     IntPropertyGetValue *getValue;
     303             :     IntPropertyGetMaxValue *getMaxValue;
     304             : };
     305             : 
     306           0 : static int32_t defaultGetValue(const IntProperty &prop, UChar32 c, UProperty /*which*/) {
     307             :     /* systematic, directly stored properties */
     308           0 :     return (int32_t)(u_getUnicodeProperties(c, prop.column)&prop.mask)>>prop.shift;
     309             : }
     310             : 
     311           0 : static int32_t defaultGetMaxValue(const IntProperty &prop, UProperty /*which*/) {
     312           0 :     return (uprv_getMaxValues(prop.column)&prop.mask)>>prop.shift;
     313             : }
     314             : 
     315           0 : static int32_t getMaxValueFromShift(const IntProperty &prop, UProperty /*which*/) {
     316           0 :     return prop.shift;
     317             : }
     318             : 
     319           0 : static int32_t getBiDiClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     320           0 :     return (int32_t)u_charDirection(c);
     321             : }
     322             : 
     323           0 : static int32_t getBiDiPairedBracketType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     324           0 :     return (int32_t)ubidi_getPairedBracketType(GET_BIDI_PROPS(), c);
     325             : }
     326             : 
     327           0 : static int32_t biDiGetMaxValue(const IntProperty &/*prop*/, UProperty which) {
     328           0 :     return ubidi_getMaxValue(GET_BIDI_PROPS(), which);
     329             : }
     330             : 
     331             : #if UCONFIG_NO_NORMALIZATION
     332             : static int32_t getCombiningClass(const IntProperty &, UChar32, UProperty) {
     333             :     return 0;
     334             : }
     335             : #else
     336           0 : static int32_t getCombiningClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     337           0 :     return u_getCombiningClass(c);
     338             : }
     339             : #endif
     340             : 
     341           0 : static int32_t getGeneralCategory(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     342           0 :     return (int32_t)u_charType(c);
     343             : }
     344             : 
     345           0 : static int32_t getJoiningGroup(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     346           0 :     return ubidi_getJoiningGroup(GET_BIDI_PROPS(), c);
     347             : }
     348             : 
     349           0 : static int32_t getJoiningType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     350           0 :     return ubidi_getJoiningType(GET_BIDI_PROPS(), c);
     351             : }
     352             : 
     353           0 : static int32_t getNumericType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     354           0 :     int32_t ntv=(int32_t)GET_NUMERIC_TYPE_VALUE(u_getMainProperties(c));
     355           0 :     return UPROPS_NTV_GET_TYPE(ntv);
     356             : }
     357             : 
     358           0 : static int32_t getScript(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     359           0 :     UErrorCode errorCode=U_ZERO_ERROR;
     360           0 :     return (int32_t)uscript_getScript(c, &errorCode);
     361             : }
     362             : 
     363             : /*
     364             :  * Map some of the Grapheme Cluster Break values to Hangul Syllable Types.
     365             :  * Hangul_Syllable_Type is fully redundant with a subset of Grapheme_Cluster_Break.
     366             :  */
     367             : static const UHangulSyllableType gcbToHst[]={
     368             :     U_HST_NOT_APPLICABLE,   /* U_GCB_OTHER */
     369             :     U_HST_NOT_APPLICABLE,   /* U_GCB_CONTROL */
     370             :     U_HST_NOT_APPLICABLE,   /* U_GCB_CR */
     371             :     U_HST_NOT_APPLICABLE,   /* U_GCB_EXTEND */
     372             :     U_HST_LEADING_JAMO,     /* U_GCB_L */
     373             :     U_HST_NOT_APPLICABLE,   /* U_GCB_LF */
     374             :     U_HST_LV_SYLLABLE,      /* U_GCB_LV */
     375             :     U_HST_LVT_SYLLABLE,     /* U_GCB_LVT */
     376             :     U_HST_TRAILING_JAMO,    /* U_GCB_T */
     377             :     U_HST_VOWEL_JAMO        /* U_GCB_V */
     378             :     /*
     379             :      * Omit GCB values beyond what we need for hst.
     380             :      * The code below checks for the array length.
     381             :      */
     382             : };
     383             : 
     384           0 : static int32_t getHangulSyllableType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     385             :     /* see comments on gcbToHst[] above */
     386           0 :     int32_t gcb=(int32_t)(u_getUnicodeProperties(c, 2)&UPROPS_GCB_MASK)>>UPROPS_GCB_SHIFT;
     387           0 :     if(gcb<UPRV_LENGTHOF(gcbToHst)) {
     388           0 :         return gcbToHst[gcb];
     389             :     } else {
     390           0 :         return U_HST_NOT_APPLICABLE;
     391             :     }
     392             : }
     393             : 
     394             : #if UCONFIG_NO_NORMALIZATION
     395             : static int32_t getNormQuickCheck(const IntProperty &, UChar32, UProperty) {
     396             :     return 0;
     397             : }
     398             : #else
     399           0 : static int32_t getNormQuickCheck(const IntProperty &/*prop*/, UChar32 c, UProperty which) {
     400           0 :     return (int32_t)unorm_getQuickCheck(c, (UNormalizationMode)(which-UCHAR_NFD_QUICK_CHECK+UNORM_NFD));
     401             : }
     402             : #endif
     403             : 
     404             : #if UCONFIG_NO_NORMALIZATION
     405             : static int32_t getLeadCombiningClass(const IntProperty &, UChar32, UProperty) {
     406             :     return 0;
     407             : }
     408             : #else
     409           0 : static int32_t getLeadCombiningClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     410           0 :     return unorm_getFCD16(c)>>8;
     411             : }
     412             : #endif
     413             : 
     414             : #if UCONFIG_NO_NORMALIZATION
     415             : static int32_t getTrailCombiningClass(const IntProperty &, UChar32, UProperty) {
     416             :     return 0;
     417             : }
     418             : #else
     419           0 : static int32_t getTrailCombiningClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
     420           0 :     return unorm_getFCD16(c)&0xff;
     421             : }
     422             : #endif
     423             : 
     424             : static const IntProperty intProps[UCHAR_INT_LIMIT-UCHAR_INT_START]={
     425             :     /*
     426             :      * column, mask and shift values for int-value properties from u_getUnicodeProperties().
     427             :      * Must be in order of corresponding UProperty,
     428             :      * and there must be exactly one entry per int UProperty.
     429             :      *
     430             :      * Properties with mask==0 are handled in code.
     431             :      * For them, column is the UPropertySource value.
     432             :      */
     433             :     { UPROPS_SRC_BIDI,  0, 0,                               getBiDiClass, biDiGetMaxValue },
     434             :     { 0,                UPROPS_BLOCK_MASK, UPROPS_BLOCK_SHIFT, defaultGetValue, defaultGetMaxValue },
     435             :     { UPROPS_SRC_NFC,   0, 0xff,                            getCombiningClass, getMaxValueFromShift },
     436             :     { 2,                UPROPS_DT_MASK, 0,                  defaultGetValue, defaultGetMaxValue },
     437             :     { 0,                UPROPS_EA_MASK, UPROPS_EA_SHIFT,    defaultGetValue, defaultGetMaxValue },
     438             :     { UPROPS_SRC_CHAR,  0, (int32_t)U_CHAR_CATEGORY_COUNT-1,getGeneralCategory, getMaxValueFromShift },
     439             :     { UPROPS_SRC_BIDI,  0, 0,                               getJoiningGroup, biDiGetMaxValue },
     440             :     { UPROPS_SRC_BIDI,  0, 0,                               getJoiningType, biDiGetMaxValue },
     441             :     { 2,                UPROPS_LB_MASK, UPROPS_LB_SHIFT,    defaultGetValue, defaultGetMaxValue },
     442             :     { UPROPS_SRC_CHAR,  0, (int32_t)U_NT_COUNT-1,           getNumericType, getMaxValueFromShift },
     443             :     { 0,                UPROPS_SCRIPT_MASK, 0,              getScript, defaultGetMaxValue },
     444             :     { UPROPS_SRC_PROPSVEC, 0, (int32_t)U_HST_COUNT-1,       getHangulSyllableType, getMaxValueFromShift },
     445             :     // UCHAR_NFD_QUICK_CHECK: max=1=YES -- never "maybe", only "no" or "yes"
     446             :     { UPROPS_SRC_NFC,   0, (int32_t)UNORM_YES,              getNormQuickCheck, getMaxValueFromShift },
     447             :     // UCHAR_NFKD_QUICK_CHECK: max=1=YES -- never "maybe", only "no" or "yes"
     448             :     { UPROPS_SRC_NFKC,  0, (int32_t)UNORM_YES,              getNormQuickCheck, getMaxValueFromShift },
     449             :     // UCHAR_NFC_QUICK_CHECK: max=2=MAYBE
     450             :     { UPROPS_SRC_NFC,   0, (int32_t)UNORM_MAYBE,            getNormQuickCheck, getMaxValueFromShift },
     451             :     // UCHAR_NFKC_QUICK_CHECK: max=2=MAYBE
     452             :     { UPROPS_SRC_NFKC,  0, (int32_t)UNORM_MAYBE,            getNormQuickCheck, getMaxValueFromShift },
     453             :     { UPROPS_SRC_NFC,   0, 0xff,                            getLeadCombiningClass, getMaxValueFromShift },
     454             :     { UPROPS_SRC_NFC,   0, 0xff,                            getTrailCombiningClass, getMaxValueFromShift },
     455             :     { 2,                UPROPS_GCB_MASK, UPROPS_GCB_SHIFT,  defaultGetValue, defaultGetMaxValue },
     456             :     { 2,                UPROPS_SB_MASK, UPROPS_SB_SHIFT,    defaultGetValue, defaultGetMaxValue },
     457             :     { 2,                UPROPS_WB_MASK, UPROPS_WB_SHIFT,    defaultGetValue, defaultGetMaxValue },
     458             :     { UPROPS_SRC_BIDI,  0, 0,                               getBiDiPairedBracketType, biDiGetMaxValue },
     459             : };
     460             : 
     461             : U_CAPI int32_t U_EXPORT2
     462           0 : u_getIntPropertyValue(UChar32 c, UProperty which) {
     463           0 :     if(which<UCHAR_INT_START) {
     464           0 :         if(UCHAR_BINARY_START<=which && which<UCHAR_BINARY_LIMIT) {
     465           0 :             const BinaryProperty &prop=binProps[which];
     466           0 :             return prop.contains(prop, c, which);
     467             :         }
     468           0 :     } else if(which<UCHAR_INT_LIMIT) {
     469           0 :         const IntProperty &prop=intProps[which-UCHAR_INT_START];
     470           0 :         return prop.getValue(prop, c, which);
     471           0 :     } else if(which==UCHAR_GENERAL_CATEGORY_MASK) {
     472           0 :         return U_MASK(u_charType(c));
     473             :     }
     474           0 :     return 0;  // undefined
     475             : }
     476             : 
     477             : U_CAPI int32_t U_EXPORT2
     478           0 : u_getIntPropertyMinValue(UProperty /*which*/) {
     479           0 :     return 0; /* all binary/enum/int properties have a minimum value of 0 */
     480             : }
     481             : 
     482             : U_CAPI int32_t U_EXPORT2
     483           0 : u_getIntPropertyMaxValue(UProperty which) {
     484           0 :     if(which<UCHAR_INT_START) {
     485           0 :         if(UCHAR_BINARY_START<=which && which<UCHAR_BINARY_LIMIT) {
     486           0 :             return 1;  // maximum TRUE for all binary properties
     487             :         }
     488           0 :     } else if(which<UCHAR_INT_LIMIT) {
     489           0 :         const IntProperty &prop=intProps[which-UCHAR_INT_START];
     490           0 :         return prop.getMaxValue(prop, which);
     491             :     }
     492           0 :     return -1;  // undefined
     493             : }
     494             : 
     495             : U_CFUNC UPropertySource U_EXPORT2
     496           0 : uprops_getSource(UProperty which) {
     497           0 :     if(which<UCHAR_BINARY_START) {
     498           0 :         return UPROPS_SRC_NONE; /* undefined */
     499           0 :     } else if(which<UCHAR_BINARY_LIMIT) {
     500           0 :         const BinaryProperty &prop=binProps[which];
     501           0 :         if(prop.mask!=0) {
     502           0 :             return UPROPS_SRC_PROPSVEC;
     503             :         } else {
     504           0 :             return (UPropertySource)prop.column;
     505             :         }
     506           0 :     } else if(which<UCHAR_INT_START) {
     507           0 :         return UPROPS_SRC_NONE; /* undefined */
     508           0 :     } else if(which<UCHAR_INT_LIMIT) {
     509           0 :         const IntProperty &prop=intProps[which-UCHAR_INT_START];
     510           0 :         if(prop.mask!=0) {
     511           0 :             return UPROPS_SRC_PROPSVEC;
     512             :         } else {
     513           0 :             return (UPropertySource)prop.column;
     514             :         }
     515           0 :     } else if(which<UCHAR_STRING_START) {
     516           0 :         switch(which) {
     517             :         case UCHAR_GENERAL_CATEGORY_MASK:
     518             :         case UCHAR_NUMERIC_VALUE:
     519           0 :             return UPROPS_SRC_CHAR;
     520             : 
     521             :         default:
     522           0 :             return UPROPS_SRC_NONE;
     523             :         }
     524           0 :     } else if(which<UCHAR_STRING_LIMIT) {
     525           0 :         switch(which) {
     526             :         case UCHAR_AGE:
     527           0 :             return UPROPS_SRC_PROPSVEC;
     528             : 
     529             :         case UCHAR_BIDI_MIRRORING_GLYPH:
     530           0 :             return UPROPS_SRC_BIDI;
     531             : 
     532             :         case UCHAR_CASE_FOLDING:
     533             :         case UCHAR_LOWERCASE_MAPPING:
     534             :         case UCHAR_SIMPLE_CASE_FOLDING:
     535             :         case UCHAR_SIMPLE_LOWERCASE_MAPPING:
     536             :         case UCHAR_SIMPLE_TITLECASE_MAPPING:
     537             :         case UCHAR_SIMPLE_UPPERCASE_MAPPING:
     538             :         case UCHAR_TITLECASE_MAPPING:
     539             :         case UCHAR_UPPERCASE_MAPPING:
     540           0 :             return UPROPS_SRC_CASE;
     541             : 
     542             :         case UCHAR_ISO_COMMENT:
     543             :         case UCHAR_NAME:
     544             :         case UCHAR_UNICODE_1_NAME:
     545           0 :             return UPROPS_SRC_NAMES;
     546             : 
     547             :         default:
     548           0 :             return UPROPS_SRC_NONE;
     549             :         }
     550             :     } else {
     551           0 :         switch(which) {
     552             :         case UCHAR_SCRIPT_EXTENSIONS:
     553           0 :             return UPROPS_SRC_PROPSVEC;
     554             :         default:
     555           0 :             return UPROPS_SRC_NONE; /* undefined */
     556             :         }
     557             :     }
     558             : }
     559             : 
     560             : #if !UCONFIG_NO_NORMALIZATION
     561             : 
     562             : U_CAPI int32_t U_EXPORT2
     563           0 : u_getFC_NFKC_Closure(UChar32 c, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode) {
     564           0 :     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
     565           0 :         return 0;
     566             :     }
     567           0 :     if(destCapacity<0 || (dest==NULL && destCapacity>0)) {
     568           0 :         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
     569           0 :         return 0;
     570             :     }
     571             :     // Compute the FC_NFKC_Closure on the fly:
     572             :     // We have the API for complete coverage of Unicode properties, although
     573             :     // this value by itself is not useful via API.
     574             :     // (What could be useful is a custom normalization table that combines
     575             :     // case folding and NFKC.)
     576             :     // For the derivation, see Unicode's DerivedNormalizationProps.txt.
     577           0 :     const Normalizer2 *nfkc=Normalizer2::getNFKCInstance(*pErrorCode);
     578           0 :     if(U_FAILURE(*pErrorCode)) {
     579           0 :         return 0;
     580             :     }
     581             :     // first: b = NFKC(Fold(a))
     582           0 :     UnicodeString folded1String;
     583             :     const UChar *folded1;
     584           0 :     int32_t folded1Length=ucase_toFullFolding(c, &folded1, U_FOLD_CASE_DEFAULT);
     585           0 :     if(folded1Length<0) {
     586           0 :         const Normalizer2Impl *nfkcImpl=Normalizer2Factory::getImpl(nfkc);
     587           0 :         if(nfkcImpl->getCompQuickCheck(nfkcImpl->getNorm16(c))!=UNORM_NO) {
     588           0 :             return u_terminateUChars(dest, destCapacity, 0, pErrorCode);  // c does not change at all under CaseFolding+NFKC
     589             :         }
     590           0 :         folded1String.setTo(c);
     591             :     } else {
     592           0 :         if(folded1Length>UCASE_MAX_STRING_LENGTH) {
     593           0 :             folded1String.setTo(folded1Length);
     594             :         } else {
     595           0 :             folded1String.setTo(FALSE, folded1, folded1Length);
     596             :         }
     597             :     }
     598           0 :     UnicodeString kc1=nfkc->normalize(folded1String, *pErrorCode);
     599             :     // second: c = NFKC(Fold(b))
     600           0 :     UnicodeString folded2String(kc1);
     601           0 :     UnicodeString kc2=nfkc->normalize(folded2String.foldCase(), *pErrorCode);
     602             :     // if (c != b) add the mapping from a to c
     603           0 :     if(U_FAILURE(*pErrorCode) || kc1==kc2) {
     604           0 :         return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
     605             :     } else {
     606           0 :         return kc2.extract(dest, destCapacity, *pErrorCode);
     607             :     }
     608             : }
     609             : 
     610             : #endif

Generated by: LCOV version 1.13