Home | History | Annotate | Download | only in unicode
      1 /*
      2 *******************************************************************************
      3 * Copyright (C) 2007-2013, International Business Machines Corporation and
      4 * others. All Rights Reserved.
      5 *******************************************************************************
      6 *
      7 
      8 * File PLURFMT.H
      9 ********************************************************************************
     10 */
     11 
     12 #ifndef PLURFMT
     13 #define PLURFMT
     14 
     15 #include "unicode/utypes.h"
     16 
     17 /**
     18  * \file
     19  * \brief C++ API: PluralFormat object
     20  */
     21 
     22 #if !UCONFIG_NO_FORMATTING
     23 
     24 #include "unicode/messagepattern.h"
     25 #include "unicode/numfmt.h"
     26 #include "unicode/plurrule.h"
     27 
     28 U_NAMESPACE_BEGIN
     29 
     30 class Hashtable;
     31 
     32 /**
     33  * <p>
     34  * <code>PluralFormat</code> supports the creation of internationalized
     35  * messages with plural inflection. It is based on <i>plural
     36  * selection</i>, i.e. the caller specifies messages for each
     37  * plural case that can appear in the user's language and the
     38  * <code>PluralFormat</code> selects the appropriate message based on
     39  * the number.
     40  * </p>
     41  * <h4>The Problem of Plural Forms in Internationalized Messages</h4>
     42  * <p>
     43  * Different languages have different ways to inflect
     44  * plurals. Creating internationalized messages that include plural
     45  * forms is only feasible when the framework is able to handle plural
     46  * forms of <i>all</i> languages correctly. <code>ChoiceFormat</code>
     47  * doesn't handle this well, because it attaches a number interval to
     48  * each message and selects the message whose interval contains a
     49  * given number. This can only handle a finite number of
     50  * intervals. But in some languages, like Polish, one plural case
     51  * applies to infinitely many intervals (e.g., the plural case applies to
     52  * numbers ending with 2, 3, or 4 except those ending with 12, 13, or
     53  * 14). Thus <code>ChoiceFormat</code> is not adequate.
     54  * </p><p>
     55  * <code>PluralFormat</code> deals with this by breaking the problem
     56  * into two parts:
     57  * <ul>
     58  * <li>It uses <code>PluralRules</code> that can define more complex
     59  *     conditions for a plural case than just a single interval. These plural
     60  *     rules define both what plural cases exist in a language, and to
     61  *     which numbers these cases apply.
     62  * <li>It provides predefined plural rules for many languages. Thus, the programmer
     63  *     need not worry about the plural cases of a language and
     64  *     does not have to define the plural cases; they can simply
     65  *     use the predefined keywords. The whole plural formatting of messages can
     66  *     be done using localized patterns from resource bundles. For predefined plural
     67  *     rules, see the CLDR <i>Language Plural Rules</i> page at
     68  *    http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
     69  * </ul>
     70  * </p>
     71  * <h4>Usage of <code>PluralFormat</code></h4>
     72  * <p>Note: Typically, plural formatting is done via <code>MessageFormat</code>
     73  * with a <code>plural</code> argument type,
     74  * rather than using a stand-alone <code>PluralFormat</code>.
     75  * </p><p>
     76  * This discussion assumes that you use <code>PluralFormat</code> with
     77  * a predefined set of plural rules. You can create one using one of
     78  * the constructors that takes a <code>locale</code> object. To
     79  * specify the message pattern, you can either pass it to the
     80  * constructor or set it explicitly using the
     81  * <code>applyPattern()</code> method. The <code>format()</code>
     82  * method takes a number object and selects the message of the
     83  * matching plural case. This message will be returned.
     84  * </p>
     85  * <h5>Patterns and Their Interpretation</h5>
     86  * <p>
     87  * The pattern text defines the message output for each plural case of the
     88  * specified locale. Syntax:
     89  * <pre>
     90  * pluralStyle = [offsetValue] (selector '{' message '}')+
     91  * offsetValue = "offset:" number
     92  * selector = explicitValue | keyword
     93  * explicitValue = '=' number  // adjacent, no white space in between
     94  * keyword = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
     95  * message: see {@link MessageFormat}
     96  * </pre>
     97  * Pattern_White_Space between syntax elements is ignored, except
     98  * between the {curly braces} and their sub-message,
     99  * and between the '=' and the number of an explicitValue.
    100  *
    101  * </p><p>
    102  * There are 6 predefined casekeyword in CLDR/ICU - 'zero', 'one', 'two', 'few', 'many' and
    103  * 'other'. You always have to define a message text for the default plural case
    104  * <code>other</code> which is contained in every rule set.
    105  * If you do not specify a message text for a particular plural case, the
    106  * message text of the plural case <code>other</code> gets assigned to this
    107  * plural case.
    108  * </p><p>
    109  * When formatting, the input number is first matched against the explicitValue clauses.
    110  * If there is no exact-number match, then a keyword is selected by calling
    111  * the <code>PluralRules</code> with the input number <em>minus the offset</em>.
    112  * (The offset defaults to 0 if it is omitted from the pattern string.)
    113  * If there is no clause with that keyword, then the "other" clauses is returned.
    114  * </p><p>
    115  * An unquoted pound sign (<code>#</code>) in the selected sub-message
    116  * itself (i.e., outside of arguments nested in the sub-message)
    117  * is replaced by the input number minus the offset.
    118  * The number-minus-offset value is formatted using a
    119  * <code>NumberFormat</code> for the <code>PluralFormat</code>'s locale. If you
    120  * need special number formatting, you have to use a <code>MessageFormat</code>
    121  * and explicitly specify a <code>NumberFormat</code> argument.
    122  * <strong>Note:</strong> That argument is formatting without subtracting the offset!
    123  * If you need a custom format and have a non-zero offset, then you need to pass the
    124  * number-minus-offset value as a separate parameter.
    125  * </p>
    126  * For a usage example, see the {@link MessageFormat} class documentation.
    127  *
    128  * <h4>Defining Custom Plural Rules</h4>
    129  * <p>If you need to use <code>PluralFormat</code> with custom rules, you can
    130  * create a <code>PluralRules</code> object and pass it to
    131  * <code>PluralFormat</code>'s constructor. If you also specify a locale in this
    132  * constructor, this locale will be used to format the number in the message
    133  * texts.
    134  * </p><p>
    135  * For more information about <code>PluralRules</code>, see
    136  * {@link PluralRules}.
    137  * </p>
    138  *
    139  * ported from Java
    140  * @stable ICU 4.0
    141  */
    142 
    143 class U_I18N_API PluralFormat : public Format {
    144 public:
    145 
    146     /**
    147      * Creates a new cardinal-number <code>PluralFormat</code> for the default locale.
    148      * This locale will be used to get the set of plural rules and for standard
    149      * number formatting.
    150      * @param status  output param set to success/failure code on exit, which
    151      *                must not indicate a failure before the function call.
    152      * @stable ICU 4.0
    153      */
    154     PluralFormat(UErrorCode& status);
    155 
    156     /**
    157      * Creates a new cardinal-number <code>PluralFormat</code> for a given locale.
    158      * @param locale the <code>PluralFormat</code> will be configured with
    159      *               rules for this locale. This locale will also be used for
    160      *               standard number formatting.
    161      * @param status output param set to success/failure code on exit, which
    162      *               must not indicate a failure before the function call.
    163      * @stable ICU 4.0
    164      */
    165     PluralFormat(const Locale& locale, UErrorCode& status);
    166 
    167     /**
    168      * Creates a new <code>PluralFormat</code> for a given set of rules.
    169      * The standard number formatting will be done using the default locale.
    170      * @param rules   defines the behavior of the <code>PluralFormat</code>
    171      *                object.
    172      * @param status  output param set to success/failure code on exit, which
    173      *                must not indicate a failure before the function call.
    174      * @stable ICU 4.0
    175      */
    176     PluralFormat(const PluralRules& rules, UErrorCode& status);
    177 
    178     /**
    179      * Creates a new <code>PluralFormat</code> for a given set of rules.
    180      * The standard number formatting will be done using the given locale.
    181      * @param locale  the default number formatting will be done using this
    182      *                locale.
    183      * @param rules   defines the behavior of the <code>PluralFormat</code>
    184      *                object.
    185      * @param status  output param set to success/failure code on exit, which
    186      *                must not indicate a failure before the function call.
    187      * @stable ICU 4.0
    188 	 * <p>
    189 	 * <h4>Sample code</h4>
    190 	 * \snippet samples/plurfmtsample/plurfmtsample.cpp PluralFormatExample1
    191 	 * \snippet samples/plurfmtsample/plurfmtsample.cpp PluralFormatExample
    192 	 * <p>
    193      */
    194     PluralFormat(const Locale& locale, const PluralRules& rules, UErrorCode& status);
    195 
    196     /**
    197      * Creates a new <code>PluralFormat</code> for the plural type.
    198      * The standard number formatting will be done using the given locale.
    199      * @param locale  the default number formatting will be done using this
    200      *                locale.
    201      * @param type    The plural type (e.g., cardinal or ordinal).
    202      * @param status  output param set to success/failure code on exit, which
    203      *                must not indicate a failure before the function call.
    204      * @stable ICU 50
    205      */
    206     PluralFormat(const Locale& locale, UPluralType type, UErrorCode& status);
    207 
    208     /**
    209      * Creates a new cardinal-number <code>PluralFormat</code> for a given pattern string.
    210      * The default locale will be used to get the set of plural rules and for
    211      * standard number formatting.
    212      * @param  pattern the pattern for this <code>PluralFormat</code>.
    213      *                 errors are returned to status if the pattern is invalid.
    214      * @param status   output param set to success/failure code on exit, which
    215      *                 must not indicate a failure before the function call.
    216      * @stable ICU 4.0
    217      */
    218     PluralFormat(const UnicodeString& pattern, UErrorCode& status);
    219 
    220     /**
    221      * Creates a new cardinal-number <code>PluralFormat</code> for a given pattern string and
    222      * locale.
    223      * The locale will be used to get the set of plural rules and for
    224      * standard number formatting.
    225      * @param locale   the <code>PluralFormat</code> will be configured with
    226      *                 rules for this locale. This locale will also be used for
    227      *                 standard number formatting.
    228      * @param pattern  the pattern for this <code>PluralFormat</code>.
    229      *                 errors are returned to status if the pattern is invalid.
    230      * @param status   output param set to success/failure code on exit, which
    231      *                 must not indicate a failure before the function call.
    232      * @stable ICU 4.0
    233      */
    234     PluralFormat(const Locale& locale, const UnicodeString& pattern, UErrorCode& status);
    235 
    236     /**
    237      * Creates a new <code>PluralFormat</code> for a given set of rules, a
    238      * pattern and a locale.
    239      * @param rules    defines the behavior of the <code>PluralFormat</code>
    240      *                 object.
    241      * @param pattern  the pattern for this <code>PluralFormat</code>.
    242      *                 errors are returned to status if the pattern is invalid.
    243      * @param status   output param set to success/failure code on exit, which
    244      *                 must not indicate a failure before the function call.
    245      * @stable ICU 4.0
    246      */
    247     PluralFormat(const PluralRules& rules,
    248                  const UnicodeString& pattern,
    249                  UErrorCode& status);
    250 
    251     /**
    252      * Creates a new <code>PluralFormat</code> for a given set of rules, a
    253      * pattern and a locale.
    254      * @param locale  the <code>PluralFormat</code> will be configured with
    255      *                rules for this locale. This locale will also be used for
    256      *                standard number formatting.
    257      * @param rules   defines the behavior of the <code>PluralFormat</code>
    258      *                object.
    259      * @param pattern the pattern for this <code>PluralFormat</code>.
    260      *                errors are returned to status if the pattern is invalid.
    261      * @param status  output param set to success/failure code on exit, which
    262      *                must not indicate a failure before the function call.
    263      * @stable ICU 4.0
    264      */
    265     PluralFormat(const Locale& locale,
    266                  const PluralRules& rules,
    267                  const UnicodeString& pattern,
    268                  UErrorCode& status);
    269 
    270     /**
    271      * Creates a new <code>PluralFormat</code> for a plural type, a
    272      * pattern and a locale.
    273      * @param locale  the <code>PluralFormat</code> will be configured with
    274      *                rules for this locale. This locale will also be used for
    275      *                standard number formatting.
    276      * @param type    The plural type (e.g., cardinal or ordinal).
    277      * @param pattern the pattern for this <code>PluralFormat</code>.
    278      *                errors are returned to status if the pattern is invalid.
    279      * @param status  output param set to success/failure code on exit, which
    280      *                must not indicate a failure before the function call.
    281      * @stable ICU 50
    282      */
    283     PluralFormat(const Locale& locale,
    284                  UPluralType type,
    285                  const UnicodeString& pattern,
    286                  UErrorCode& status);
    287 
    288     /**
    289       * copy constructor.
    290       * @stable ICU 4.0
    291       */
    292     PluralFormat(const PluralFormat& other);
    293 
    294     /**
    295      * Destructor.
    296      * @stable ICU 4.0
    297      */
    298     virtual ~PluralFormat();
    299 
    300     /**
    301      * Sets the pattern used by this plural format.
    302      * The method parses the pattern and creates a map of format strings
    303      * for the plural rules.
    304      * Patterns and their interpretation are specified in the class description.
    305      *
    306      * @param pattern the pattern for this plural format
    307      *                errors are returned to status if the pattern is invalid.
    308      * @param status  output param set to success/failure code on exit, which
    309      *                must not indicate a failure before the function call.
    310      * @stable ICU 4.0
    311      */
    312     void applyPattern(const UnicodeString& pattern, UErrorCode& status);
    313 
    314 
    315     using Format::format;
    316 
    317     /**
    318      * Formats a plural message for a given number.
    319      *
    320      * @param number  a number for which the plural message should be formatted
    321      *                for. If no pattern has been applied to this
    322      *                <code>PluralFormat</code> object yet, the formatted number
    323      *                will be returned.
    324      * @param status  output param set to success/failure code on exit, which
    325      *                must not indicate a failure before the function call.
    326      * @return        the string containing the formatted plural message.
    327      * @stable ICU 4.0
    328      */
    329     UnicodeString format(int32_t number, UErrorCode& status) const;
    330 
    331     /**
    332      * Formats a plural message for a given number.
    333      *
    334      * @param number  a number for which the plural message should be formatted
    335      *                for. If no pattern has been applied to this
    336      *                PluralFormat object yet, the formatted number
    337      *                will be returned.
    338      * @param status  output param set to success or failure code on exit, which
    339      *                must not indicate a failure before the function call.
    340      * @return        the string containing the formatted plural message.
    341      * @stable ICU 4.0
    342      */
    343     UnicodeString format(double number, UErrorCode& status) const;
    344 
    345     /**
    346      * Formats a plural message for a given number.
    347      *
    348      * @param number   a number for which the plural message should be formatted
    349      *                 for. If no pattern has been applied to this
    350      *                 <code>PluralFormat</code> object yet, the formatted number
    351      *                 will be returned.
    352      * @param appendTo output parameter to receive result.
    353      *                 result is appended to existing contents.
    354      * @param pos      On input: an alignment field, if desired.
    355      *                 On output: the offsets of the alignment field.
    356      * @param status   output param set to success/failure code on exit, which
    357      *                 must not indicate a failure before the function call.
    358      * @return         the string containing the formatted plural message.
    359      * @stable ICU 4.0
    360      */
    361     UnicodeString& format(int32_t number,
    362                           UnicodeString& appendTo,
    363                           FieldPosition& pos,
    364                           UErrorCode& status) const;
    365 
    366     /**
    367      * Formats a plural message for a given number.
    368      *
    369      * @param number   a number for which the plural message should be formatted
    370      *                 for. If no pattern has been applied to this
    371      *                 PluralFormat object yet, the formatted number
    372      *                 will be returned.
    373      * @param appendTo output parameter to receive result.
    374      *                 result is appended to existing contents.
    375      * @param pos      On input: an alignment field, if desired.
    376      *                 On output: the offsets of the alignment field.
    377      * @param status   output param set to success/failure code on exit, which
    378      *                 must not indicate a failure before the function call.
    379      * @return         the string containing the formatted plural message.
    380      * @stable ICU 4.0
    381      */
    382     UnicodeString& format(double number,
    383                           UnicodeString& appendTo,
    384                           FieldPosition& pos,
    385                           UErrorCode& status) const;
    386 
    387 #ifndef U_HIDE_DEPRECATED_API
    388     /**
    389      * Sets the locale used by this <code>PluraFormat</code> object.
    390      * Note: Calling this method resets this <code>PluraFormat</code> object,
    391      *     i.e., a pattern that was applied previously will be removed,
    392      *     and the NumberFormat is set to the default number format for
    393      *     the locale.  The resulting format behaves the same as one
    394      *     constructed from {@link #PluralFormat(const Locale& locale, UPluralType type, UErrorCode& status)}
    395      *     with UPLURAL_TYPE_CARDINAL.
    396      * @param locale  the <code>locale</code> to use to configure the formatter.
    397      * @param status  output param set to success/failure code on exit, which
    398      *                must not indicate a failure before the function call.
    399      * @deprecated ICU 50 This method clears the pattern and might create
    400      *             a different kind of PluralRules instance;
    401      *             use one of the constructors to create a new instance instead.
    402      */
    403     void setLocale(const Locale& locale, UErrorCode& status);
    404 #endif  /* U_HIDE_DEPRECATED_API */
    405 
    406     /**
    407       * Sets the number format used by this formatter.  You only need to
    408       * call this if you want a different number format than the default
    409       * formatter for the locale.
    410       * @param format  the number format to use.
    411       * @param status  output param set to success/failure code on exit, which
    412       *                must not indicate a failure before the function call.
    413       * @stable ICU 4.0
    414       */
    415     void setNumberFormat(const NumberFormat* format, UErrorCode& status);
    416 
    417     /**
    418        * Assignment operator
    419        *
    420        * @param other    the PluralFormat object to copy from.
    421        * @stable ICU 4.0
    422        */
    423     PluralFormat& operator=(const PluralFormat& other);
    424 
    425     /**
    426       * Return true if another object is semantically equal to this one.
    427       *
    428       * @param other    the PluralFormat object to be compared with.
    429       * @return         true if other is semantically equal to this.
    430       * @stable ICU 4.0
    431       */
    432     virtual UBool operator==(const Format& other) const;
    433 
    434     /**
    435      * Return true if another object is semantically unequal to this one.
    436      *
    437      * @param other    the PluralFormat object to be compared with.
    438      * @return         true if other is semantically unequal to this.
    439      * @stable ICU 4.0
    440      */
    441     virtual UBool operator!=(const Format& other) const;
    442 
    443     /**
    444      * Clones this Format object polymorphically.  The caller owns the
    445      * result and should delete it when done.
    446      * @stable ICU 4.0
    447      */
    448     virtual Format* clone(void) const;
    449 
    450    /**
    451     * Formats a plural message for a number taken from a Formattable object.
    452     *
    453     * @param obj       The object containing a number for which the
    454     *                  plural message should be formatted.
    455     *                  The object must be of a numeric type.
    456     * @param appendTo  output parameter to receive result.
    457     *                  Result is appended to existing contents.
    458     * @param pos       On input: an alignment field, if desired.
    459     *                  On output: the offsets of the alignment field.
    460     * @param status    output param filled with success/failure status.
    461     * @return          Reference to 'appendTo' parameter.
    462     * @stable ICU 4.0
    463     */
    464    UnicodeString& format(const Formattable& obj,
    465                          UnicodeString& appendTo,
    466                          FieldPosition& pos,
    467                          UErrorCode& status) const;
    468 
    469    /**
    470     * Returns the pattern from applyPattern() or constructor().
    471     *
    472     * @param  appendTo  output parameter to receive result.
    473      *                  Result is appended to existing contents.
    474     * @return the UnicodeString with inserted pattern.
    475     * @stable ICU 4.0
    476     */
    477    UnicodeString& toPattern(UnicodeString& appendTo);
    478 
    479    /**
    480     * This method is not yet supported by <code>PluralFormat</code>.
    481     * <P>
    482     * Before calling, set parse_pos.index to the offset you want to start
    483     * parsing at in the source. After calling, parse_pos.index is the end of
    484     * the text you parsed. If error occurs, index is unchanged.
    485     * <P>
    486     * When parsing, leading whitespace is discarded (with a successful parse),
    487     * while trailing whitespace is left as is.
    488     * <P>
    489     * See Format::parseObject() for more.
    490     *
    491     * @param source    The string to be parsed into an object.
    492     * @param result    Formattable to be set to the parse result.
    493     *                  If parse fails, return contents are undefined.
    494     * @param parse_pos The position to start parsing at. Upon return
    495     *                  this param is set to the position after the
    496     *                  last character successfully parsed. If the
    497     *                  source is not parsed successfully, this param
    498     *                  will remain unchanged.
    499     * @stable ICU 4.0
    500     */
    501    virtual void parseObject(const UnicodeString& source,
    502                             Formattable& result,
    503                             ParsePosition& parse_pos) const;
    504 
    505     /**
    506      * ICU "poor man's RTTI", returns a UClassID for this class.
    507      *
    508      * @stable ICU 4.0
    509      *
    510      */
    511     static UClassID U_EXPORT2 getStaticClassID(void);
    512 
    513     /**
    514      * ICU "poor man's RTTI", returns a UClassID for the actual class.
    515      *
    516      * @stable ICU 4.0
    517      */
    518      virtual UClassID getDynamicClassID() const;
    519 
    520 #if (defined(__xlC__) && (__xlC__ < 0x0C00)) || (U_PLATFORM == U_PF_OS390) || (U_PLATFORM ==U_PF_OS400)
    521 // Work around a compiler bug on xlC 11.1 on AIX 7.1 that would
    522 // prevent PluralSelectorAdapter from implementing private PluralSelector.
    523 // xlC error message:
    524 // 1540-0300 (S) The "private" member "class icu_49::PluralFormat::PluralSelector" cannot be accessed.
    525 public:
    526 #else
    527 private:
    528 #endif
    529      /**
    530       * @internal
    531       */
    532     class U_I18N_API PluralSelector : public UMemory {
    533       public:
    534         virtual ~PluralSelector();
    535         /**
    536          * Given a number, returns the appropriate PluralFormat keyword.
    537          *
    538          * @param context worker object for the selector.
    539          * @param number The number to be plural-formatted.
    540          * @param ec Error code.
    541          * @return The selected PluralFormat keyword.
    542          * @internal
    543          */
    544         virtual UnicodeString select(void *context, double number, UErrorCode& ec) const = 0;
    545     };
    546 
    547     /**
    548      * @internal
    549      */
    550     class U_I18N_API PluralSelectorAdapter : public PluralSelector {
    551       public:
    552         PluralSelectorAdapter() : pluralRules(NULL) {
    553         }
    554 
    555         virtual ~PluralSelectorAdapter();
    556 
    557         virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const; /**< @internal */
    558 
    559         void reset();
    560 
    561         PluralRules* pluralRules;
    562     };
    563 
    564 #if defined(__xlC__)
    565 // End of xlC bug workaround, keep remaining definitions private.
    566 private:
    567 #endif
    568     Locale  locale;
    569     MessagePattern msgPattern;
    570     NumberFormat*  numberFormat;
    571     double offset;
    572     PluralSelectorAdapter pluralRulesWrapper;
    573 
    574     PluralFormat();   // default constructor not implemented
    575     void init(const PluralRules* rules, UPluralType type, UErrorCode& status);
    576     /**
    577      * Copies dynamically allocated values (pointer fields).
    578      * Others are copied using their copy constructors and assignment operators.
    579      */
    580     void copyObjects(const PluralFormat& other);
    581 
    582     UnicodeString& format(const Formattable& numberObject, double number,
    583                           UnicodeString& appendTo,
    584                           FieldPosition& pos,
    585                           UErrorCode& status) const; /**< @internal */
    586 
    587     /**
    588      * Finds the PluralFormat sub-message for the given number, or the "other" sub-message.
    589      * @param pattern A MessagePattern.
    590      * @param partIndex the index of the first PluralFormat argument style part.
    591      * @param selector the PluralSelector for mapping the number (minus offset) to a keyword.
    592      * @param context worker object for the selector.
    593      * @param number a number to be matched to one of the PluralFormat argument's explicit values,
    594      *        or mapped via the PluralSelector.
    595      * @param ec ICU error code.
    596      * @return the sub-message start part index.
    597      */
    598     static int32_t findSubMessage(
    599          const MessagePattern& pattern, int32_t partIndex,
    600          const PluralSelector& selector, void *context, double number, UErrorCode& ec); /**< @internal */
    601 
    602     friend class MessageFormat;
    603 };
    604 
    605 U_NAMESPACE_END
    606 
    607 #endif /* #if !UCONFIG_NO_FORMATTING */
    608 
    609 #endif // _PLURFMT
    610 //eof
    611