/*
******************************************************************************
-* Copyright (C) 1997-2005, International Business Machines
+* Copyright (C) 1997-2012, 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"
-
U_NAMESPACE_BEGIN
#if 0
0x25, 0x25, 0
}; /* "%%" */
+static const UChar gNoparse[] =
+{
+ 0x40, 0x6E, 0x6F, 0x70, 0x61, 0x72, 0x73, 0x65, 0
+}; /* "@noparse" */
+
NFRuleSet::NFRuleSet(UnicodeString* descriptions, int32_t index, UErrorCode& status)
: name()
, rules(0)
, negativeNumberRule(NULL)
, fIsFractionRuleSet(FALSE)
, fIsPublic(FALSE)
+ , fIsParseable(TRUE)
, fRecursionCount(0)
{
for (int i = 0; i < 3; ++i) {
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);
}
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()
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.
// if it's the negative-number rule, copy it into its own
// data member and delete it from the list
case NFRule::kNegativeNumberRule:
+ if (negativeNumberRule) {
+ delete negativeNumberRule;
+ }
negativeNumberRule = rules.remove(i);
break;
// if it's the improper fraction rule, copy it into the
// correct element of fractionRules
case NFRule::kImproperFractionRule:
+ if (fractionRules[0]) {
+ delete fractionRules[0];
+ }
fractionRules[0] = rules.remove(i);
break;
// if it's the proper fraction rule, copy it into the
// correct element of fractionRules
case NFRule::kProperFractionRule:
+ if (fractionRules[1]) {
+ delete fractionRules[1];
+ }
fractionRules[1] = rules.remove(i);
break;
// if it's the master rule, copy it into the
// correct element of fractionRules
case NFRule::kMasterRule:
+ if (fractionRules[2]) {
+ delete fractionRules[2];
+ }
fractionRules[2] = rules.remove(i);
break;
return fractionRules[2];
}
+ // always use the last rule for infinity. It is likely that rule
+ // has a DecimalFormat that will do the right thing with infinity even
+ // if the rule's base value is strange, i.e. something larger than what
+ // util64_fromDouble produces below.
+ if (uprv_isInfinite(number) && (rules.size() > 0)) {
+ return rules[rules.size() - 1];
+ }
+
// and if we haven't yet returned a rule, use findNormalRule()
// to find the applicable rule
int64_t r = util64_fromDouble(number + 0.5);
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
for (int i = 0; i < 3; i++) {
if (fractionRules[i]) {
Formattable tempResult;
- UBool success = fractionRules[i]->doParse(text, workingPos, 0, upperBound, tempResult);
+ UBool success = fractionRules[i]->doParse(text, workingPos, 0, upperBound, tempResult, lenient || isDecimalFormatRuleParseable() );
if (success && (workingPos.getIndex() > highWaterMark.getIndex())) {
result = tempResult;
highWaterMark = workingPos;
// followed by the regular rules...
for (uint32_t i = 0; i < rules.size(); i++) {
- result.append(gFourSpaces);
+ result.append(gFourSpaces, 4);
rules[i]->_appendRuleText(result);
result.append(gLineFeed);
}
// followed by the special rules (if they exist)
if (negativeNumberRule) {
- result.append(gFourSpaces);
+ result.append(gFourSpaces, 4);
negativeNumberRule->_appendRuleText(result);
result.append(gLineFeed);
}
{
for (uint32_t i = 0; i < 3; ++i) {
if (fractionRules[i]) {
- result.append(gFourSpaces);
+ result.append(gFourSpaces, 4);
fractionRules[i]->_appendRuleText(result);
result.append(gLineFeed);
}