]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/nfrs.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / nfrs.cpp
index a066614f046870348ff76aa848f175d5bfe81ffd..e2c41f2b7d084c0e6111919fb8d987e0f0dad8c2 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ******************************************************************************
-*   Copyright (C) 1997-2004, International Business Machines
+*   Copyright (C) 1997-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ******************************************************************************
 *   file name:  nfrs.cpp
 #include "unicode/uchar.h"
 #include "nfrule.h"
 #include "nfrlist.h"
+#include "patternprops.h"
 
 #ifdef RBNF_DEBUG
 #include "cmemory.h"
 #endif
 
-#include "util.h"
+enum {
+    /** -x */
+    NEGATIVE_RULE_INDEX = 0,
+    /** x.x */
+    IMPROPER_FRACTION_RULE_INDEX = 1,
+    /** 0.x */
+    PROPER_FRACTION_RULE_INDEX = 2,
+    /** x.0 */
+    MASTER_RULE_INDEX = 3,
+    /** Inf */
+    INFINITY_RULE_INDEX = 4,
+    /** NaN */
+    NAN_RULE_INDEX = 5,
+    NON_NUMERICAL_RULE_LENGTH = 6
+};
 
 U_NAMESPACE_BEGIN
 
@@ -105,25 +120,27 @@ static const UChar gColon = 0x003a;
 static const UChar gSemicolon = 0x003b;
 static const UChar gLineFeed = 0x000a;
 
-static const UChar gFourSpaces[] =
-{
-    0x20, 0x20, 0x20, 0x20, 0
-}; /* "    " */
 static const UChar gPercentPercent[] =
 {
     0x25, 0x25, 0
 }; /* "%%" */
 
-NFRuleSet::NFRuleSet(UnicodeString* descriptions, int32_t index, UErrorCode& status)
+static const UChar gNoparse[] =
+{
+    0x40, 0x6E, 0x6F, 0x70, 0x61, 0x72, 0x73, 0x65, 0
+}; /* "@noparse" */
+
+NFRuleSet::NFRuleSet(RuleBasedNumberFormat *_owner, UnicodeString* descriptions, int32_t index, UErrorCode& status)
   : name()
   , rules(0)
-  , negativeNumberRule(NULL)
+  , owner(_owner)
+  , fractionRules()
   , fIsFractionRuleSet(FALSE)
   , fIsPublic(FALSE)
-  , fRecursionCount(0)
+  , fIsParseable(TRUE)
 {
-    for (int i = 0; i < 3; ++i) {
-        fractionRules[i] = NULL;
+    for (int32_t i = 0; i < NON_NUMERICAL_RULE_LENGTH; ++i) {
+        nonNumericalRules[i] = NULL;
     }
 
     if (U_FAILURE(status)) {
@@ -135,7 +152,7 @@ NFRuleSet::NFRuleSet(UnicodeString* descriptions, int32_t index, UErrorCode& sta
     if (description.length() == 0) {
         // throw new IllegalArgumentException("Empty rule set description");
         status = U_PARSE_ERROR;
-    return;
+        return;
     }
 
     // if the description begins with a rule set name (the rule set
@@ -149,7 +166,7 @@ NFRuleSet::NFRuleSet(UnicodeString* descriptions, int32_t index, UErrorCode& sta
             status = U_PARSE_ERROR;
         } else {
             name.setTo(description, 0, pos);
-            while (pos < description.length() && uprv_isRuleWhiteSpace(description.charAt(++pos))) {
+            while (pos < description.length() && PatternProps::isWhiteSpace(description.charAt(++pos))) {
             }
             description.remove(0, pos);
         }
@@ -162,14 +179,19 @@ NFRuleSet::NFRuleSet(UnicodeString* descriptions, int32_t index, UErrorCode& sta
         status = U_PARSE_ERROR;
     }
 
-    fIsPublic = name.indexOf(gPercentPercent) != 0;
+    fIsPublic = name.indexOf(gPercentPercent, 2, 0) != 0;
+
+    if ( name.endsWith(gNoparse,8) ) {
+        fIsParseable = FALSE;
+        name.truncate(name.length()-8); // remove the @noparse from the name
+    }
 
     // all of the other members of NFRuleSet are initialized
     // by parseRules()
 }
 
 void
-NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* owner, UErrorCode& status)
+NFRuleSet::parseRules(UnicodeString& description, UErrorCode& status)
 {
     // start by creating a Vector whose elements are Strings containing
     // the descriptions of the rules (one rule per element).  The rules
@@ -180,6 +202,9 @@ NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* o
         return;
     }
 
+    // ensure we are starting with an empty rule list
+    rules.deleteAll();
+
     // dlf - the original code kept a separate description array for no reason,
     // so I got rid of it.  The loop was too complex so I simplified it.
 
@@ -204,73 +229,103 @@ NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* o
     // (this isn't a for loop because we might be deleting items from
     // the vector-- we want to make sure we only increment i when
     // we _didn't_ delete aything from the vector)
-    uint32_t i = 0;
-    while (i < rules.size()) {
+    int32_t rulesSize = rules.size();
+    for (int32_t i = 0; i < rulesSize; i++) {
         NFRule* rule = rules[i];
+        int64_t baseValue = rule->getBaseValue();
 
-        switch (rule->getType()) {
+        if (baseValue == 0) {
             // if the rule's base value is 0, fill in a default
             // base value (this will be 1 plus the preceding
             // rule's base value for regular rule sets, and the
             // same as the preceding rule's base value in fraction
             // rule sets)
-        case NFRule::kNoBase:
             rule->setBaseValue(defaultBaseValue, status);
-            if (!isFractionRuleSet()) {
-                ++defaultBaseValue;
-            }
-            ++i;
-            break;
-
-            // if it's the negative-number rule, copy it into its own
-            // data member and delete it from the list
-        case NFRule::kNegativeNumberRule:
-            negativeNumberRule = rules.remove(i);
-            break;
-
-            // if it's the improper fraction rule, copy it into the
-            // correct element of fractionRules
-        case NFRule::kImproperFractionRule:
-            fractionRules[0] = rules.remove(i);
-            break;
-
-            // if it's the proper fraction rule, copy it into the
-            // correct element of fractionRules
-        case NFRule::kProperFractionRule:
-            fractionRules[1] = rules.remove(i);
-            break;
-
-            // if it's the master rule, copy it into the
-            // correct element of fractionRules
-        case NFRule::kMasterRule:
-            fractionRules[2] = rules.remove(i);
-            break;
-
+        }
+        else {
             // if it's a regular rule that already knows its base value,
             // check to make sure the rules are in order, and update
             // the default base value for the next rule
-        default:
-            if (rule->getBaseValue() < defaultBaseValue) {
+            if (baseValue < defaultBaseValue) {
                 // throw new IllegalArgumentException("Rules are not in order");
                 status = U_PARSE_ERROR;
                 return;
             }
-            defaultBaseValue = rule->getBaseValue();
-            if (!isFractionRuleSet()) {
-                ++defaultBaseValue;
-            }
-            ++i;
-            break;
+            defaultBaseValue = baseValue;
         }
+        if (!fIsFractionRuleSet) {
+            ++defaultBaseValue;
+        }
+    }
+}
+
+/**
+ * Set one of the non-numerical rules.
+ * @param rule The rule to set.
+ */
+void NFRuleSet::setNonNumericalRule(NFRule *rule) {
+    int64_t baseValue = rule->getBaseValue();
+    if (baseValue == NFRule::kNegativeNumberRule) {
+        delete nonNumericalRules[NEGATIVE_RULE_INDEX];
+        nonNumericalRules[NEGATIVE_RULE_INDEX] = rule;
+    }
+    else if (baseValue == NFRule::kImproperFractionRule) {
+        setBestFractionRule(IMPROPER_FRACTION_RULE_INDEX, rule, TRUE);
+    }
+    else if (baseValue == NFRule::kProperFractionRule) {
+        setBestFractionRule(PROPER_FRACTION_RULE_INDEX, rule, TRUE);
+    }
+    else if (baseValue == NFRule::kMasterRule) {
+        setBestFractionRule(MASTER_RULE_INDEX, rule, TRUE);
+    }
+    else if (baseValue == NFRule::kInfinityRule) {
+        delete nonNumericalRules[INFINITY_RULE_INDEX];
+        nonNumericalRules[INFINITY_RULE_INDEX] = rule;
+    }
+    else if (baseValue == NFRule::kNaNRule) {
+        delete nonNumericalRules[NAN_RULE_INDEX];
+        nonNumericalRules[NAN_RULE_INDEX] = rule;
+    }
+}
+
+/**
+ * Determine the best fraction rule to use. Rules matching the decimal point from
+ * DecimalFormatSymbols become the main set of rules to use.
+ * @param originalIndex The index into nonNumericalRules
+ * @param newRule The new rule to consider
+ * @param rememberRule Should the new rule be added to fractionRules.
+ */
+void NFRuleSet::setBestFractionRule(int32_t originalIndex, NFRule *newRule, UBool rememberRule) {
+    if (rememberRule) {
+        fractionRules.add(newRule);
+    }
+    NFRule *bestResult = nonNumericalRules[originalIndex];
+    if (bestResult == NULL) {
+        nonNumericalRules[originalIndex] = newRule;
+    }
+    else {
+        // We have more than one. Which one is better?
+        const DecimalFormatSymbols *decimalFormatSymbols = owner->getDecimalFormatSymbols();
+        if (decimalFormatSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol).charAt(0)
+            == newRule->getDecimalPoint())
+        {
+            nonNumericalRules[originalIndex] = newRule;
+        }
+        // else leave it alone
     }
 }
 
 NFRuleSet::~NFRuleSet()
 {
-    delete negativeNumberRule;
-    delete fractionRules[0];
-    delete fractionRules[1];
-    delete fractionRules[2];
+    for (int i = 0; i < NON_NUMERICAL_RULE_LENGTH; i++) {
+        if (i != IMPROPER_FRACTION_RULE_INDEX
+            && i != PROPER_FRACTION_RULE_INDEX
+            && i != MASTER_RULE_INDEX)
+        {
+            delete nonNumericalRules[i];
+        }
+        // else it will be deleted via NFRuleList fractionRules
+    }
 }
 
 static UBool
@@ -291,12 +346,16 @@ NFRuleSet::operator==(const NFRuleSet& rhs) const
 {
     if (rules.size() == rhs.rules.size() &&
         fIsFractionRuleSet == rhs.fIsFractionRuleSet &&
-        name == rhs.name &&
-        util_equalRules(negativeNumberRule, rhs.negativeNumberRule) &&
-        util_equalRules(fractionRules[0], rhs.fractionRules[0]) &&
-        util_equalRules(fractionRules[1], rhs.fractionRules[1]) &&
-        util_equalRules(fractionRules[2], rhs.fractionRules[2])) {
+        name == rhs.name) {
 
+        // ...then compare the non-numerical rule lists...
+        for (int i = 0; i < NON_NUMERICAL_RULE_LENGTH; i++) {
+            if (!util_equalRules(nonNumericalRules[i], rhs.nonNumericalRules[i])) {
+                return FALSE;
+            }
+        }
+
+        // ...then compare the rule lists...
         for (uint32_t i = 0; i < rules.size(); ++i) {
             if (*rules[i] != *rhs.rules[i]) {
                 return FALSE;
@@ -307,41 +366,62 @@ NFRuleSet::operator==(const NFRuleSet& rhs) const
     return FALSE;
 }
 
-#define RECURSION_LIMIT 50
+void
+NFRuleSet::setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status) {
+    for (uint32_t i = 0; i < rules.size(); ++i) {
+        rules[i]->setDecimalFormatSymbols(newSymbols, status);
+    }
+    // Switch the fraction rules to mirror the DecimalFormatSymbols.
+    for (int32_t nonNumericalIdx = IMPROPER_FRACTION_RULE_INDEX; nonNumericalIdx <= MASTER_RULE_INDEX; nonNumericalIdx++) {
+        if (nonNumericalRules[nonNumericalIdx]) {
+            for (uint32_t fIdx = 0; fIdx < fractionRules.size(); fIdx++) {
+                NFRule *fractionRule = fractionRules[fIdx];
+                if (nonNumericalRules[nonNumericalIdx]->getBaseValue() == fractionRule->getBaseValue()) {
+                    setBestFractionRule(nonNumericalIdx, fractionRule, FALSE);
+                }
+            }
+        }
+    }
+
+    for (uint32_t nnrIdx = 0; nnrIdx < NON_NUMERICAL_RULE_LENGTH; nnrIdx++) {
+        NFRule *rule = nonNumericalRules[nnrIdx];
+        if (rule) {
+            rule->setDecimalFormatSymbols(newSymbols, status);
+        }
+    }
+}
+
+#define RECURSION_LIMIT 64
 
 void
-NFRuleSet::format(int64_t number, UnicodeString& toAppendTo, int32_t pos) const
+NFRuleSet::format(int64_t number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const
 {
-    NFRule *rule = findNormalRule(number);
+    if (recursionCount >= RECURSION_LIMIT) {
+        // stop recursion
+        status = U_INVALID_STATE_ERROR;
+        return;
+    }
+    const NFRule *rule = findNormalRule(number);
     if (rule) { // else error, but can't report it
-        NFRuleSet* ncThis = (NFRuleSet*)this;
-        if (ncThis->fRecursionCount++ >= RECURSION_LIMIT) {
-            // stop recursion
-            ncThis->fRecursionCount = 0;
-        } else {
-            rule->doFormat(number, toAppendTo, pos);
-            ncThis->fRecursionCount--;
-        }
+        rule->doFormat(number, toAppendTo, pos, ++recursionCount, status);
     }
 }
 
 void
-NFRuleSet::format(double number, UnicodeString& toAppendTo, int32_t pos) const
+NFRuleSet::format(double number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const
 {
-    NFRule *rule = findDoubleRule(number);
+    if (recursionCount >= RECURSION_LIMIT) {
+        // stop recursion
+        status = U_INVALID_STATE_ERROR;
+        return;
+    }
+    const NFRule *rule = findDoubleRule(number);
     if (rule) { // else error, but can't report it
-        NFRuleSet* ncThis = (NFRuleSet*)this;
-        if (ncThis->fRecursionCount++ >= RECURSION_LIMIT) {
-            // stop recursion
-            ncThis->fRecursionCount = 0;
-        } else {
-            rule->doFormat(number, toAppendTo, pos);
-            ncThis->fRecursionCount--;
-        }
+        rule->doFormat(number, toAppendTo, pos, ++recursionCount, status);
     }
 }
 
-NFRule*
+const NFRule*
 NFRuleSet::findDoubleRule(double number) const
 {
     // if this is a fraction rule set, use findFractionRuleSetRule()
@@ -349,33 +429,49 @@ NFRuleSet::findDoubleRule(double number) const
         return findFractionRuleSetRule(number);
     }
 
+    if (uprv_isNaN(number)) {
+        const NFRule *rule = nonNumericalRules[NAN_RULE_INDEX];
+        if (!rule) {
+            rule = owner->getDefaultNaNRule();
+        }
+        return rule;
+    }
+
     // if the number is negative, return the negative number rule
     // (if there isn't a negative-number rule, we pretend it's a
     // positive number)
     if (number < 0) {
-        if (negativeNumberRule) {
-            return  negativeNumberRule;
+        if (nonNumericalRules[NEGATIVE_RULE_INDEX]) {
+            return  nonNumericalRules[NEGATIVE_RULE_INDEX];
         } else {
             number = -number;
         }
     }
 
+    if (uprv_isInfinite(number)) {
+        const NFRule *rule = nonNumericalRules[INFINITY_RULE_INDEX];
+        if (!rule) {
+            rule = owner->getDefaultInfinityRule();
+        }
+        return rule;
+    }
+
     // if the number isn't an integer, we use one of the fraction rules...
     if (number != uprv_floor(number)) {
         // if the number is between 0 and 1, return the proper
         // fraction rule
-        if (number < 1 && fractionRules[1]) {
-            return fractionRules[1];
+        if (number < 1 && nonNumericalRules[PROPER_FRACTION_RULE_INDEX]) {
+            return nonNumericalRules[PROPER_FRACTION_RULE_INDEX];
         }
         // otherwise, return the improper fraction rule
-        else if (fractionRules[0]) {
-            return fractionRules[0];
+        else if (nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX]) {
+            return nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX];
         }
     }
 
     // if there's a master rule, use it to format the number
-    if (fractionRules[2]) {
-        return fractionRules[2];
+    if (nonNumericalRules[MASTER_RULE_INDEX]) {
+        return nonNumericalRules[MASTER_RULE_INDEX];
     }
 
     // and if we haven't yet returned a rule, use findNormalRule()
@@ -384,7 +480,7 @@ NFRuleSet::findDoubleRule(double number) const
     return findNormalRule(r);
 }
 
-NFRule *
+const NFRule *
 NFRuleSet::findNormalRule(int64_t number) const
 {
     // if this is a fraction rule set, use findFractionRuleSetRule()
@@ -397,8 +493,8 @@ NFRuleSet::findNormalRule(int64_t number) const
     // if the number is negative, return the negative-number rule
     // (if there isn't one, pretend the number is positive)
     if (number < 0) {
-        if (negativeNumberRule) {
-            return negativeNumberRule;
+        if (nonNumericalRules[NEGATIVE_RULE_INDEX]) {
+            return nonNumericalRules[NEGATIVE_RULE_INDEX];
         } else {
             number = -number;
         }
@@ -455,7 +551,7 @@ NFRuleSet::findNormalRule(int64_t number) const
         return result;
     }
     // else use the master rule
-    return fractionRules[2];
+    return nonNumericalRules[MASTER_RULE_INDEX];
 }
 
 /**
@@ -473,7 +569,7 @@ NFRuleSet::findNormalRule(int64_t number) const
  * a number between 0 and 1)
  * @return The rule to use to format this number
  */
-NFRule*
+const NFRule*
 NFRuleSet::findFractionRuleSetRule(double number) const
 {
     // the obvious way to do this (multiply the value being formatted
@@ -572,15 +668,17 @@ NFRuleSet::findFractionRuleSetRule(double number) const
 static void dumpUS(FILE* f, const UnicodeString& us) {
   int len = us.length();
   char* buf = (char *)uprv_malloc((len+1)*sizeof(char)); //new char[len+1];
-  us.extract(0, len, buf);
-  buf[len] = 0;
-  fprintf(f, "%s", buf);
-  uprv_free(buf); //delete[] buf;
+  if (buf != NULL) {
+         us.extract(0, len, buf);
+         buf[len] = 0;
+         fprintf(f, "%s", buf);
+         uprv_free(buf); //delete[] buf;
+  }
 }
 #endif
 
 UBool
-NFRuleSet::parse(const UnicodeString& text, ParsePosition& pos, double upperBound, Formattable& result) const
+NFRuleSet::parse(const UnicodeString& text, ParsePosition& pos, double upperBound, Formattable& result, UBool lenient) const
 {
     // try matching each rule in the rule set against the text being
     // parsed.  Whichever one matches the most characters is the one
@@ -604,40 +702,16 @@ NFRuleSet::parse(const UnicodeString& text, ParsePosition& pos, double upperBoun
     fprintf(stderr, "'\n");
     fprintf(stderr, "  parse negative: %d\n", this, negativeNumberRule != 0);
 #endif
-
-    // start by trying the negative number rule (if there is one)
-    if (negativeNumberRule) {
-        Formattable tempResult;
-#ifdef RBNF_DEBUG
-        fprintf(stderr, "  <nfrs before negative> %x ub: %g\n", negativeNumberRule, upperBound);
-#endif
-        UBool success = negativeNumberRule->doParse(text, workingPos, 0, upperBound, tempResult);
-#ifdef RBNF_DEBUG
-        fprintf(stderr, "  <nfrs after negative> success: %d wpi: %d\n", success, workingPos.getIndex());
-#endif
-        if (success && workingPos.getIndex() > highWaterMark.getIndex()) {
-            result = tempResult;
-            highWaterMark = workingPos;
-        }
-        workingPos = pos;
-    }
-#ifdef RBNF_DEBUG
-    fprintf(stderr, "<nfrs> continue fractional with text '");
-    dumpUS(stderr, text);
-    fprintf(stderr, "' hwm: %d\n", highWaterMark.getIndex());
-#endif
-    // then try each of the fraction rules
-    {
-        for (int i = 0; i < 3; i++) {
-            if (fractionRules[i]) {
-                Formattable tempResult;
-                UBool success = fractionRules[i]->doParse(text, workingPos, 0, upperBound, tempResult);
-                if (success && (workingPos.getIndex() > highWaterMark.getIndex())) {
-                    result = tempResult;
-                    highWaterMark = workingPos;
-                }
-                workingPos = pos;
+    // Try each of the negative rules, fraction rules, infinity rules and NaN rules
+    for (int i = 0; i < NON_NUMERICAL_RULE_LENGTH; i++) {
+        if (nonNumericalRules[i]) {
+            Formattable tempResult;
+            UBool success = nonNumericalRules[i]->doParse(text, workingPos, 0, upperBound, tempResult, lenient || isDecimalFormatRuleParseable() );
+            if (success && (workingPos.getIndex() > highWaterMark.getIndex())) {
+                result = tempResult;
+                highWaterMark = workingPos;
             }
+            workingPos = pos;
         }
     }
 #ifdef RBNF_DEBUG
@@ -693,30 +767,37 @@ NFRuleSet::parse(const UnicodeString& text, ParsePosition& pos, double upperBoun
 void
 NFRuleSet::appendRules(UnicodeString& result) const
 {
+    uint32_t i;
+
     // the rule set name goes first...
     result.append(name);
     result.append(gColon);
     result.append(gLineFeed);
 
     // followed by the regular rules...
-    for (uint32_t i = 0; i < rules.size(); i++) {
-        result.append(gFourSpaces);
-        rules[i]->appendRuleText(result);
+    for (i = 0; i < rules.size(); i++) {
+        rules[i]->_appendRuleText(result);
         result.append(gLineFeed);
     }
 
     // followed by the special rules (if they exist)
-    if (negativeNumberRule) {
-        result.append(gFourSpaces);
-        negativeNumberRule->appendRuleText(result);
-        result.append(gLineFeed);
-    }
-
-    {
-        for (uint32_t i = 0; i < 3; ++i) {
-            if (fractionRules[i]) {
-                result.append(gFourSpaces);
-                fractionRules[i]->appendRuleText(result);
+    for (i = 0; i < NON_NUMERICAL_RULE_LENGTH; ++i) {
+        NFRule *rule = nonNumericalRules[i];
+        if (nonNumericalRules[i]) {
+            if (rule->getBaseValue() == NFRule::kImproperFractionRule
+                || rule->getBaseValue() == NFRule::kProperFractionRule
+                || rule->getBaseValue() == NFRule::kMasterRule)
+            {
+                for (uint32_t fIdx = 0; fIdx < fractionRules.size(); fIdx++) {
+                    NFRule *fractionRule = fractionRules[fIdx];
+                    if (fractionRule->getBaseValue() == rule->getBaseValue()) {
+                        fractionRule->_appendRuleText(result);
+                        result.append(gLineFeed);
+                    }
+                }
+            }
+            else {
+                rule->_appendRuleText(result);
                 result.append(gLineFeed);
             }
         }
@@ -770,6 +851,7 @@ static const uint8_t asciiDigits[] = {
 
 static const UChar kUMinus = (UChar)0x002d;
 
+#ifdef RBNF_DEBUG
 static const char kMinus = '-';
 
 static const uint8_t digitInfo[] = {
@@ -791,7 +873,6 @@ static const uint8_t digitInfo[] = {
     0xa1u, 0xa2u, 0xa3u,     0,     0,     0,     0,     0,
 };
 
-#ifdef RBNF_DEBUG
 int64_t util64_atoi(const char* str, uint32_t radix)
 {
     if (radix > 36) {
@@ -817,7 +898,6 @@ int64_t util64_atoi(const char* str, uint32_t radix)
     }
     return result;
 }
-#endif
 
 int64_t util64_utoi(const UChar* str, uint32_t radix)
 {
@@ -846,7 +926,6 @@ int64_t util64_utoi(const UChar* str, uint32_t radix)
     return result;
 }
 
-#ifdef RBNF_DEBUG
 uint32_t util64_toa(int64_t w, char* buf, uint32_t len, uint32_t radix, UBool raw)
 {    
     if (radix > 36) {