From 4c96f9a866a62c44d783c615f8666d00e84a98a5 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Mon, 14 Dec 2015 21:57:41 +0000 Subject: [PATCH] ICU-12031 port enum StandardPlural to C++ X-SVN-Rev: 38130 --- icu4c/source/i18n/Makefile.in | 2 +- icu4c/source/i18n/i18n.vcxproj | 2 + icu4c/source/i18n/i18n.vcxproj.filters | 6 ++ icu4c/source/i18n/plurrule_impl.h | 7 +- icu4c/source/i18n/quantityformatter.cpp | 51 ++------------- icu4c/source/i18n/quantityformatter.h | 3 +- icu4c/source/i18n/standardplural.cpp | 79 ++++++++++++++++++++++ icu4c/source/i18n/standardplural.h | 87 +++++++++++++++++++++++++ 8 files changed, 186 insertions(+), 51 deletions(-) create mode 100644 icu4c/source/i18n/standardplural.cpp create mode 100644 icu4c/source/i18n/standardplural.h diff --git a/icu4c/source/i18n/Makefile.in b/icu4c/source/i18n/Makefile.in index 53dd5fdf60..b59b2cea14 100644 --- a/icu4c/source/i18n/Makefile.in +++ b/icu4c/source/i18n/Makefile.in @@ -88,7 +88,7 @@ regexcmp.o rematch.o repattrn.o regexst.o regextxt.o regeximp.o uregex.o uregexc ulocdata.o measfmt.o currfmt.o curramt.o currunit.o measure.o utmscale.o \ csdetect.o csmatch.o csr2022.o csrecog.o csrmbcs.o csrsbcs.o csrucode.o csrutf8.o inputext.o \ wintzimpl.o windtfmt.o winnmfmt.o basictz.o dtrule.o rbtz.o tzrule.o tztrans.o vtzone.o zonemeta.o \ -upluralrules.o plurrule.o plurfmt.o selfmt.o dtitvfmt.o dtitvinf.o udateintervalformat.o \ +standardplural.o upluralrules.o plurrule.o plurfmt.o selfmt.o dtitvfmt.o dtitvinf.o udateintervalformat.o \ tmunit.o tmutamt.o tmutfmt.o currpinf.o \ uspoof.o uspoof_impl.o uspoof_build.o uspoof_conf.o uspoof_wsconf.o decfmtst.o smpdtfst.o \ ztrans.o zrule.o vzone.o fphdlimp.o fpositer.o ufieldpositer.o locdspnm.o \ diff --git a/icu4c/source/i18n/i18n.vcxproj b/icu4c/source/i18n/i18n.vcxproj index 8c586a9cb3..b036d95e32 100644 --- a/icu4c/source/i18n/i18n.vcxproj +++ b/icu4c/source/i18n/i18n.vcxproj @@ -364,6 +364,7 @@ + @@ -1278,6 +1279,7 @@ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs) + copy "%(FullPath)" ..\..\include\unicode diff --git a/icu4c/source/i18n/i18n.vcxproj.filters b/icu4c/source/i18n/i18n.vcxproj.filters index 35c3fe2317..9164f5a3cc 100644 --- a/icu4c/source/i18n/i18n.vcxproj.filters +++ b/icu4c/source/i18n/i18n.vcxproj.filters @@ -282,6 +282,9 @@ formatting + + formatting + formatting @@ -787,6 +790,9 @@ formatting + + formatting + formatting diff --git a/icu4c/source/i18n/plurrule_impl.h b/icu4c/source/i18n/plurrule_impl.h index 7416fa7f48..785600bff5 100644 --- a/icu4c/source/i18n/plurrule_impl.h +++ b/icu4c/source/i18n/plurrule_impl.h @@ -10,18 +10,19 @@ */ -#ifndef PLURRULE_IMPLE -#define PLURRULE_IMPLE +#ifndef PLURRULE_IMPL +#define PLURRULE_IMPL // Internal definitions for the PluralRules implementation. +#include "unicode/utypes.h" + #if !UCONFIG_NO_FORMATTING #include "unicode/format.h" #include "unicode/locid.h" #include "unicode/parseerr.h" #include "unicode/ures.h" -#include "unicode/utypes.h" #include "uvector.h" #include "hash.h" diff --git a/icu4c/source/i18n/quantityformatter.cpp b/icu4c/source/i18n/quantityformatter.cpp index 901b3f7edb..53ec2a83ac 100644 --- a/icu4c/source/i18n/quantityformatter.cpp +++ b/icu4c/source/i18n/quantityformatter.cpp @@ -21,46 +21,12 @@ #include "unicode/fmtable.h" #include "unicode/fieldpos.h" #include "resource.h" +#include "standardplural.h" #include "visibledigits.h" #include "uassert.h" U_NAMESPACE_BEGIN -/** - * Plural forms in index order: "other", "zero", "one", "two", "few", "many" - * "other" must be first. - */ -static int32_t getPluralIndex(const char *pluralForm) { - switch (*pluralForm++) { - case 'f': - if (uprv_strcmp(pluralForm, "ew") == 0) { - return 4; - } - case 'm': - if (uprv_strcmp(pluralForm, "any") == 0) { - return 5; - } - case 'o': - if (uprv_strcmp(pluralForm, "ther") == 0) { - return 0; - } else if (uprv_strcmp(pluralForm, "ne") == 0) { - return 2; - } - break; - case 't': - if (uprv_strcmp(pluralForm, "wo") == 0) { - return 3; - } - case 'z': - if (uprv_strcmp(pluralForm, "ero") == 0) { - return 1; - } - default: - break; - } - return -1; -} - QuantityFormatter::QuantityFormatter() { for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { formatters[i] = NULL; @@ -111,14 +77,10 @@ UBool QuantityFormatter::addIfAbsent( const UnicodeString *rawPattern, const ResourceValue *patternValue, UErrorCode &status) { + int32_t pluralIndex = StandardPlural::indexFromString(variant, status); if (U_FAILURE(status)) { return FALSE; } - int32_t pluralIndex = getPluralIndex(variant); - if (pluralIndex < 0) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return FALSE; - } if (formatters[pluralIndex] != NULL) { return TRUE; } @@ -139,19 +101,16 @@ UBool QuantityFormatter::addIfAbsent( } UBool QuantityFormatter::isValid() const { - return formatters[0] != NULL; + return formatters[StandardPlural::OTHER] != NULL; } const SimplePatternFormatter *QuantityFormatter::getByVariant( const char *variant) const { U_ASSERT(isValid()); - int32_t pluralIndex = getPluralIndex(variant); - if (pluralIndex == -1) { - pluralIndex = 0; - } + int32_t pluralIndex = StandardPlural::indexOrOtherIndexFromString(variant); const SimplePatternFormatter *pattern = formatters[pluralIndex]; if (pattern == NULL) { - pattern = formatters[0]; + pattern = formatters[StandardPlural::OTHER]; } return pattern; } diff --git a/icu4c/source/i18n/quantityformatter.h b/icu4c/source/i18n/quantityformatter.h index 97bf91c40b..cbc7fd3ea3 100644 --- a/icu4c/source/i18n/quantityformatter.h +++ b/icu4c/source/i18n/quantityformatter.h @@ -15,6 +15,7 @@ #if !UCONFIG_NO_FORMATTING #include "resource.h" +#include "standardplural.h" U_NAMESPACE_BEGIN @@ -130,7 +131,7 @@ private: const ResourceValue *patternValue, UErrorCode &status); - SimplePatternFormatter *formatters[6]; + SimplePatternFormatter *formatters[StandardPlural::COUNT]; }; U_NAMESPACE_END diff --git a/icu4c/source/i18n/standardplural.cpp b/icu4c/source/i18n/standardplural.cpp new file mode 100644 index 0000000000..651a9bcc3a --- /dev/null +++ b/icu4c/source/i18n/standardplural.cpp @@ -0,0 +1,79 @@ +/* + ******************************************************************************* + * Copyright (C) 2015, International Business Machines Corporation + * and others. All Rights Reserved. + ******************************************************************************* + * standardplural.cpp + * + * created on: 2015dec14 + * created by: Markus W. Scherer + */ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "cstring.h" +#include "standardplural.h" +#include "uassert.h" + +U_NAMESPACE_BEGIN + +static const char *gKeywords[StandardPlural::COUNT] = { + "zero", "one", "two", "few", "many", "other" +}; + +const char *StandardPlural::getKeyword(Form p) { + U_ASSERT(ZERO <= p && p < COUNT); + return gKeywords[p]; +} + +int32_t StandardPlural::indexOrNegativeFromString(const char *keyword) { + switch (*keyword++) { + case 'f': + if (uprv_strcmp(keyword, "ew") == 0) { + return FEW; + } + break; + case 'm': + if (uprv_strcmp(keyword, "any") == 0) { + return MANY; + } + break; + case 'o': + if (uprv_strcmp(keyword, "ther") == 0) { + return OTHER; + } else if (uprv_strcmp(keyword, "ne") == 0) { + return ONE; + } + break; + case 't': + if (uprv_strcmp(keyword, "wo") == 0) { + return TWO; + } + break; + case 'z': + if (uprv_strcmp(keyword, "ero") == 0) { + return ZERO; + } + break; + default: + break; + } + return -1; +} + +int32_t StandardPlural::indexFromString(const char *keyword, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return OTHER; } + int32_t i = indexOrNegativeFromString(keyword); + if (i >= 0) { + return i; + } else { + errorCode = U_ILLEGAL_ARGUMENT_ERROR; + return OTHER; + } +} + +U_NAMESPACE_END + +#endif // !UCONFIG_NO_FORMATTING diff --git a/icu4c/source/i18n/standardplural.h b/icu4c/source/i18n/standardplural.h new file mode 100644 index 0000000000..174f2a4a4a --- /dev/null +++ b/icu4c/source/i18n/standardplural.h @@ -0,0 +1,87 @@ +/* + ******************************************************************************* + * Copyright (C) 2015, International Business Machines Corporation + * and others. All Rights Reserved. + ******************************************************************************* + * standardplural.h + * + * created on: 2015dec14 + * created by: Markus W. Scherer + */ + +#ifndef __STANDARDPLURAL_H__ +#define __STANDARDPLURAL_H__ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +U_NAMESPACE_BEGIN + +/** + * Standard CLDR plural form/category constants. + * See http://www.unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules + */ +class U_I18N_API StandardPlural { +public: + enum Form { + ZERO, + ONE, + TWO, + FEW, + MANY, + OTHER, + COUNT + }; + + /** + * @return the lowercase CLDR keyword string for the plural form + */ + static const char *getKeyword(Form p); + + /** + * @param keyword for example "few" or "other" + * @return the plural form corresponding to the keyword, or OTHER + */ + static Form orOtherFromString(const char *keyword) { + return static_cast
(indexOrOtherIndexFromString(keyword)); + } + + /** + * Sets U_ILLEGAL_ARGUMENT_ERROR if the keyword is not a plural form. + * + * @param keyword for example "few" or "other" + * @return the plural form corresponding to the keyword + */ + static Form fromString(const char *keyword, UErrorCode &errorCode) { + return static_cast(indexFromString(keyword, errorCode)); + } + + /** + * @param keyword for example "few" or "other" + * @return the index of the plural form corresponding to the keyword, or a negative value + */ + static int32_t indexOrNegativeFromString(const char *keyword); + + /** + * @param keyword for example "few" or "other" + * @return the index of the plural form corresponding to the keyword, or OTHER_INDEX + */ + static int32_t indexOrOtherIndexFromString(const char *keyword) { + int32_t i = indexOrNegativeFromString(keyword); + return i >= 0 ? i : OTHER; + } + + /** + * Sets U_ILLEGAL_ARGUMENT_ERROR if the keyword is not a plural form. + * + * @param keyword for example "few" or "other" + * @return the index of the plural form corresponding to the keyword + */ + static int32_t indexFromString(const char *keyword, UErrorCode &errorCode); +}; + +U_NAMESPACE_END + +#endif // !UCONFIG_NO_FORMATTING +#endif // __STANDARDPLURAL_H__