}
}
+ // if we didn't see a decimal and it is required, check to see if the pattern had one
+ if(!sawDecimal && isDecimalPatternMatchRequired())
+ {
+ if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0)
+ {
+ parsePosition.setIndex(oldStart);
+ parsePosition.setErrorIndex(position);
+ debug("decimal point match required fail!");
+ return FALSE;
+ }
+ }
+
if (backup != -1)
{
position = backup;
parsePosition.setErrorIndex(position);
return FALSE;
}
+
+ // check if we missed a required decimal point
+ if(fastParseOk && isDecimalPatternMatchRequired())
+ {
+ if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0)
+ {
+ parsePosition.setIndex(oldStart);
+ parsePosition.setErrorIndex(position);
+ debug("decimal point match required fail!");
+ return FALSE;
+ }
+ }
+
+
return TRUE;
}
#endif
}
+//------------------------------------------------------------------------------
+// Checks if decimal point pattern match is required
+UBool
+DecimalFormat::isDecimalPatternMatchRequired(void) const
+{
+ return fBoolFlags.contains(UNUM_PARSE_DECIMAL_MARK_REQUIRED);
+}
+
+//------------------------------------------------------------------------------
+// Checks if decimal point pattern match is required
+
+void
+DecimalFormat::setDecimalPatternMatchRequired(UBool newValue)
+{
+ fBoolFlags.set(UNUM_PARSE_DECIMAL_MARK_REQUIRED, newValue);
+}
+
+
//------------------------------------------------------------------------------
// Emits the pattern of this DecimalFormat instance.
/* These are stored in fBoolFlags */
case UNUM_PARSE_NO_EXPONENT:
case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
+ case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
if(!fBoolFlags.isValidValue(newValue)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
} else {
/* These are stored in fBoolFlags */
case UNUM_PARSE_NO_EXPONENT:
case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
+ case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
return fBoolFlags.get(attr);
case UNUM_SCALE:
*/
virtual void setDecimalSeparatorAlwaysShown(UBool newValue);
+ /**
+ * Allows you to get the parse behavior of the pattern decimal mark.
+ *
+ * @return TRUE if input must contain a match to decimal mark in pattern
+ * @draft ICU 54
+ */
+ UBool isDecimalPatternMatchRequired(void) const;
+
+ /**
+ * Allows you to set the behavior of the pattern decimal mark.
+ *
+ * if TRUE, the input must have a decimal mark if one was specified in the pattern. When
+ * FALSE the decimal mark may be omitted from the input.
+ *
+ * @param newValue set TRUE if input must contain a match to decimal mark in pattern
+ * @draft ICU 54
+ */
+ virtual void setDecimalPatternMatchRequired(UBool newValue);
+
+
/**
* Synthesizes a pattern string that represents the current state
* of this Format object.
*/
UNUM_PARSE_NO_EXPONENT,
+ /**
+ * if this attribute is set to 1, specifies that, if the pattern contains a
+ * decimal mark the input is required to have one. If this attribute is set to 0,
+ * specifies that input does not have to contain a decimal mark.
+ * Has no effect on formatting.
+ * Default: 0 (unset)
+ * @draft ICU 54
+ */
+ UNUM_PARSE_DECIMAL_MARK_REQUIRED,
+
/* The following cannot be #ifndef U_HIDE_INTERNAL_API, needed in .h file variable declararions */
/** Limit of boolean attributes.
* @internal */
TestBadFastpath();
}
break;
+ case 7: name = "TestRequiredDecimalPoint";
+ if(exec) {
+ logln((UnicodeString)"TestRequiredDecimalPoint ---");
+ TestRequiredDecimalPoint();
+ }
+ break;
default: name = ""; break;
}
}
assertEquals("Format 1234 w/ grouping", "1,234", df->format(1234, fmt));
}
+void IntlTestDecimalFormatAPI::TestRequiredDecimalPoint() {
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString text("99");
+ double expected = 99;
+ double whatIGot = 0.0;
+ Formattable result1;
+ UnicodeString pat1("##.0000");
+ UnicodeString pat2("00.0");
+
+ LocalPointer<DecimalFormat> df(new DecimalFormat(pat1, status));
+ if (U_FAILURE(status)) {
+ dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
+ return;
+ }
+
+ status = U_ZERO_ERROR;
+ df->applyPattern(pat1, status);
+ if(U_FAILURE(status)) {
+ errln((UnicodeString)"ERROR: applyPattern() failed");
+ }
+ df->parse(text, result1, status);
+ if(U_FAILURE(status)) {
+ errln((UnicodeString)"ERROR: parse() failed");
+ }
+ df->setDecimalPatternMatchRequired(TRUE);
+ df->parse(text, result1, status);
+ if(U_SUCCESS(status)) {
+ errln((UnicodeString)"ERROR: unexpected parse()");
+ }
+
+
+ status = U_ZERO_ERROR;
+ df->applyPattern(pat2, status);
+ df->setDecimalPatternMatchRequired(FALSE);
+ if(U_FAILURE(status)) {
+ errln((UnicodeString)"ERROR: applyPattern(2) failed");
+ }
+ df->parse(text, result1, status);
+ if(U_FAILURE(status)) {
+ errln((UnicodeString)"ERROR: parse(2) failed - " + u_errorName(status));
+ }
+ df->setDecimalPatternMatchRequired(TRUE);
+ df->parse(text, result1, status);
+ if(U_SUCCESS(status)) {
+ errln((UnicodeString)"ERROR: unexpected parse(2)");
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
void TestScale();
void TestFixedDecimal();
void TestBadFastpath();
+ void TestRequiredDecimalPoint();
private:
/*Helper functions */
void verify(const UnicodeString& message, const UnicodeString& got, double expected);