diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2009-07-17 17:37:52 -0700 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2009-07-17 17:37:52 -0700 |
commit | 7c971b21cb09c84a9bd948bdf2918b727d46992c (patch) | |
tree | 01d4b6cdbaf19f87ed9ef9ec99954d9ba4f11356 /i18n | |
parent | 51cfa1a9a96cad34675a6415fe86dfdf3f525bb6 (diff) | |
download | icu4c-7c971b21cb09c84a9bd948bdf2918b727d46992c.tar.gz |
import cl @31437
Diffstat (limited to 'i18n')
-rw-r--r-- | i18n/Makefile | 65 | ||||
-rw-r--r-- | i18n/Makefile.org | 181 | ||||
-rw-r--r-- | i18n/decimfmt.cpp | 222 | ||||
-rw-r--r-- | i18n/msgfmt.cpp | 2 | ||||
-rw-r--r-- | i18n/nfrs.cpp | 2 | ||||
-rw-r--r-- | i18n/nfrule.cpp | 2 | ||||
-rw-r--r-- | i18n/rbnf.cpp | 2 | ||||
-rw-r--r-- | i18n/regexcmp.cpp | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | i18n/regexcst.pl | 0 | ||||
-rw-r--r-- | i18n/smpdtfmt.cpp | 2 | ||||
-rw-r--r-- | i18n/ucol_tok.cpp | 2 | ||||
-rw-r--r-- | i18n/unicode/decimfmt.h | 43 |
12 files changed, 494 insertions, 31 deletions
diff --git a/i18n/Makefile b/i18n/Makefile new file mode 100644 index 00000000..de835beb --- /dev/null +++ b/i18n/Makefile @@ -0,0 +1,65 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# LOCAL_ARM_MODE := arm + +LOCAL_SRC_FILES := \ + bocsu.c ucln_in.c ucol_wgt.c \ + ulocdata.c utmscale.c + +LOCAL_SRC_FILES += \ + indiancal.cpp dtptngen.cpp dtrule.cpp \ + persncal.cpp rbtz.cpp reldtfmt.cpp \ + taiwncal.cpp tzrule.cpp tztrans.cpp \ + udatpg.cpp vtzone.cpp \ + anytrans.cpp astro.cpp buddhcal.cpp \ + basictz.cpp calendar.cpp casetrn.cpp \ + choicfmt.cpp coleitr.cpp coll.cpp \ + cpdtrans.cpp csdetect.cpp csmatch.cpp \ + csr2022.cpp csrecog.cpp csrmbcs.cpp \ + csrsbcs.cpp csrucode.cpp csrutf8.cpp \ + curramt.cpp currfmt.cpp currunit.cpp \ + datefmt.cpp dcfmtsym.cpp decimfmt.cpp \ + digitlst.cpp dtfmtsym.cpp esctrn.cpp \ + fmtable_cnv.cpp fmtable.cpp format.cpp \ + funcrepl.cpp gregocal.cpp gregoimp.cpp \ + hebrwcal.cpp inputext.cpp islamcal.cpp \ + japancal.cpp measfmt.cpp measure.cpp \ + msgfmt.cpp name2uni.cpp nfrs.cpp \ + nfrule.cpp nfsubs.cpp nortrans.cpp \ + nultrans.cpp numfmt.cpp olsontz.cpp \ + quant.cpp rbnf.cpp rbt.cpp \ + rbt_data.cpp rbt_pars.cpp rbt_rule.cpp \ + rbt_set.cpp regexcmp.cpp regexst.cpp \ + rematch.cpp remtrans.cpp repattrn.cpp \ + search.cpp simpletz.cpp smpdtfmt.cpp \ + sortkey.cpp strmatch.cpp strrepl.cpp \ + stsearch.cpp tblcoll.cpp timezone.cpp \ + titletrn.cpp tolowtrn.cpp toupptrn.cpp \ + translit.cpp transreg.cpp tridpars.cpp \ + ucal.cpp ucol_bld.cpp ucol_cnt.cpp \ + ucol.cpp ucoleitr.cpp ucol_elm.cpp \ + ucol_res.cpp ucol_sit.cpp ucol_tok.cpp \ + ucsdet.cpp ucurr.cpp udat.cpp \ + umsg.cpp unesctrn.cpp uni2name.cpp \ + unum.cpp uregexc.cpp uregex.cpp \ + usearch.cpp utrans.cpp windtfmt.cpp \ + winnmfmt.cpp + +LOCAL_C_INCLUDES = \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../common + +LOCAL_CFLAGS += -D_REENTRANT -DPIC -DU_I18N_IMPLEMENTATION -fPIC +LOCAL_CFLAGS += -O3 + +ifeq ($(DEVICE_ARCH),arm) +LOCAL_CFLAGS += -DARM_FLAG +endif + +LOCAL_SHARED_LIBRARIES += libicuuc libicudata +LOCAL_LDLIBS += -lpthread -lm + +LOCAL_TARGET := libicui18n + +include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file diff --git a/i18n/Makefile.org b/i18n/Makefile.org new file mode 100644 index 00000000..595b2467 --- /dev/null +++ b/i18n/Makefile.org @@ -0,0 +1,181 @@ +#****************************************************************************** +# +# Copyright (C) 1998-2007, International Business Machines +# Corporation and others. All Rights Reserved. +# +#****************************************************************************** +## Makefile.in for ICU - icui18n.so +## Stephen F. Booth + +## Source directory information +srcdir = . +top_srcdir = .. + +top_builddir = .. + +## All the flags and other definitions are included here. +include $(top_builddir)/icudefs.mk + +## Build directory information +subdir = i18n + +## Extra files to remove for 'make clean' +CLEANFILES = *~ $(DEPS) $(IMPORT_LIB) $(MIDDLE_IMPORT_LIB) $(FINAL_IMPORT_LIB) + +## Target information + +TARGET_STUBNAME=$(I18N_STUBNAME) + +ifneq ($(ENABLE_STATIC),) +TARGET = $(LIBDIR)/$(LIBSICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(A) +endif + +ifneq ($(ENABLE_SHARED),) +SO_TARGET = $(LIBDIR)/$(LIBICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(SO) +ALL_SO_TARGETS = $(SO_TARGET) $(MIDDLE_SO_TARGET) $(FINAL_SO_TARGET) $(SHARED_OBJECT) + +ifeq ($(ENABLE_SO_VERSION_DATA),1) +SO_VERSION_DATA = i18n.res +endif + +ifeq ($(OS390BATCH),1) +BATCH_TARGET = $(BATCH_I18N_TARGET) +BATCH_LIBS = $(BATCH_LIBICUUC) -lm +endif # OS390BATCH + +endif # ENABLE_SHARED + +ALL_TARGETS = $(TARGET) $(ALL_SO_TARGETS) $(BATCH_TARGET) + +DYNAMICCPPFLAGS = $(SHAREDLIBCPPFLAGS) +DYNAMICCFLAGS = $(SHAREDLIBCFLAGS) +DYNAMICCXXFLAGS = $(SHAREDLIBCXXFLAGS) +CFLAGS += $(LIBCFLAGS) +CXXFLAGS += $(LIBCXXFLAGS) + +ifneq ($(top_builddir),$(top_srcdir)) +CPPFLAGS += -I$(top_builddir)/common +endif +CPPFLAGS += -I$(srcdir) -I$(top_srcdir)/common $(LIBCPPFLAGS) +DEFS += -DU_I18N_IMPLEMENTATION +LDFLAGS += $(LDFLAGSICUI18N) +LIBS = $(LIBICUUC) $(DEFAULT_LIBS) + +OBJECTS = ucln_in.o \ +fmtable.o format.o msgfmt.o umsg.o numfmt.o unum.o decimfmt.o dcfmtsym.o \ +ucurr.o digitlst.o fmtable_cnv.o \ +choicfmt.o datefmt.o smpdtfmt.o reldtfmt.o dtfmtsym.o udat.o dtptngen.o \ +nfrs.o nfrule.o nfsubs.o rbnf.o ucsdet.o \ +ucal.o calendar.o gregocal.o timezone.o simpletz.o olsontz.o \ +astro.o taiwncal.o buddhcal.o persncal.o islamcal.o japancal.o gregoimp.o hebrwcal.o indiancal.o \ +coleitr.o coll.o tblcoll.o sortkey.o bocsu.o ucoleitr.o \ +ucol.o ucol_res.o ucol_bld.o ucol_sit.o ucol_tok.o ucol_wgt.o ucol_cnt.o ucol_elm.o \ +strmatch.o usearch.o search.o stsearch.o \ +translit.o utrans.o esctrn.o unesctrn.o funcrepl.o strrepl.o tridpars.o \ +cpdtrans.o rbt.o rbt_data.o rbt_pars.o rbt_rule.o rbt_set.o \ +nultrans.o remtrans.o casetrn.o titletrn.o tolowtrn.o toupptrn.o anytrans.o \ +name2uni.o uni2name.o nortrans.o quant.o transreg.o \ +regexcmp.o rematch.o repattrn.o regexst.o udatpg.o uregex.o uregexc.o \ +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 \ +windtfmt.o winnmfmt.o basictz.o dtrule.o rbtz.o tzrule.o tztrans.o vtzone.o + +## Header files to install +HEADERS = $(srcdir)/unicode/*.h + +STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O)) + +DEPS = $(OBJECTS:.o=.d) + +-include Makefile.local + +## List of phony targets +.PHONY : all all-local install install-local clean clean-local \ +distclean distclean-local install-library install-headers dist \ +dist-local check check-local + +## Clear suffix list +.SUFFIXES : + +## List of standard targets +all: all-local +install: install-local +clean: clean-local +distclean : distclean-local +dist: dist-local +check: all check-local + +all-local: $(ALL_TARGETS) + +install-local: install-headers install-library + +install-library: all-local + $(MKINSTALLDIRS) $(DESTDIR)$(libdir) +ifneq ($(ENABLE_STATIC),) + $(INSTALL-L) $(TARGET) $(DESTDIR)$(libdir) +endif +ifneq ($(ENABLE_SHARED),) + $(INSTALL-L) $(FINAL_SO_TARGET) $(DESTDIR)$(libdir) +ifneq ($(FINAL_SO_TARGET),$(SO_TARGET)) + cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(SO_TARGET)) && ln -s $(notdir $(FINAL_SO_TARGET)) $(notdir $(SO_TARGET)) +ifneq ($(FINAL_SO_TARGET),$(MIDDLE_SO_TARGET)) + cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(MIDDLE_SO_TARGET)) && ln -s $(notdir $(FINAL_SO_TARGET)) $(notdir $(MIDDLE_SO_TARGET)) +endif +endif +ifneq ($(IMPORT_LIB_EXT),) + $(INSTALL-L) $(FINAL_IMPORT_LIB) $(DESTDIR)$(libdir) +ifneq ($(IMPORT_LIB),$(FINAL_IMPORT_LIB)) + cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(IMPORT_LIB)) && ln -s $(notdir $(FINAL_IMPORT_LIB)) $(notdir $(IMPORT_LIB)) +endif +ifneq ($(MIDDLE_IMPORT_LIB),$(FINAL_IMPORT_LIB)) + cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(MIDDLE_IMPORT_LIB)) && ln -s $(notdir $(FINAL_IMPORT_LIB)) $(notdir $(MIDDLE_IMPORT_LIB)) +endif +endif +endif + +install-headers: + $(MKINSTALLDIRS) $(DESTDIR)$(includedir)/unicode + @for file in $(HEADERS); do \ + echo "$(INSTALL_DATA) $$file $(DESTDIR)$(includedir)/unicode"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(includedir)/unicode || exit; \ + done + +dist-local: + +clean-local: + test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES) + $(RMV) $(OBJECTS) $(STATIC_OBJECTS) $(ALL_TARGETS) $(SO_VERSION_DATA) + +distclean-local: clean-local + $(RMV) Makefile + +check-local: + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +ifneq ($(ENABLE_STATIC),) +$(TARGET): $(STATIC_OBJECTS) + $(AR) $(ARFLAGS) $(AR_OUTOPT)$@ $^ + $(RANLIB) $@ +endif + +ifneq ($(ENABLE_SHARED),) +$(SHARED_OBJECT): $(OBJECTS) $(SO_VERSION_DATA) + $(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS) + +ifeq ($(OS390BATCH),1) +$(BATCH_TARGET):$(OBJECTS) + $(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(BATCH_LIBS) +endif # OS390BATCH +endif # ENABLE_SHARED + +ifeq (,$(MAKECMDGOALS)) +-include $(DEPS) +else +ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),) +-include $(DEPS) +endif +endif + diff --git a/i18n/decimfmt.cpp b/i18n/decimfmt.cpp index 0598bbbd..a472088c 100644 --- a/i18n/decimfmt.cpp +++ b/i18n/decimfmt.cpp @@ -50,13 +50,15 @@ #include "unicode/uchar.h" #include "unicode/curramt.h" #include "ucurrimp.h" -#include "util.h" +#include "../common/util.h" #include "digitlst.h" #include "cmemory.h" #include "cstring.h" #include "umutex.h" #include "uassert.h" #include "putilimp.h" +#include <stdio.h> + U_NAMESPACE_BEGIN @@ -614,7 +616,16 @@ DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPosition& fieldPosition) const { - return format((int64_t)number, appendTo, fieldPosition); + return format((int64_t)number, appendTo, fieldPosition, NULL); +} + +UnicodeString& +DecimalFormat::format(int32_t number, + UnicodeString& appendTo, + FieldPosition& fieldPosition, + AttrBuffer attrBuffer) const +{ + return format((int64_t)number, appendTo, fieldPosition, attrBuffer); } //------------------------------------------------------------------------------ @@ -624,6 +635,15 @@ DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPosition& fieldPosition) const { + return format(number, appendTo, fieldPosition, NULL); +} + +UnicodeString& +DecimalFormat::format(int64_t number, + UnicodeString& appendTo, + FieldPosition& fieldPosition, + AttrBuffer attrBuffer) const +{ DigitList digits; // Clears field positions. @@ -652,7 +672,7 @@ DecimalFormat::format(int64_t number, digits.set(number * fMultiplier, precision(TRUE)); } - return subformat(appendTo, fieldPosition, digits, TRUE); + return subformat(appendTo, fieldPosition, attrBuffer, digits, TRUE); } //------------------------------------------------------------------------------ @@ -662,6 +682,15 @@ DecimalFormat::format( double number, UnicodeString& appendTo, FieldPosition& fieldPosition) const { + return format(number, appendTo, fieldPosition, NULL); +} + +UnicodeString& +DecimalFormat::format( double number, + UnicodeString& appendTo, + FieldPosition& fieldPosition, + AttrBuffer attrBuffer) const +{ // Clears field positions. fieldPosition.setBeginIndex(0); fieldPosition.setEndIndex(0); @@ -670,13 +699,18 @@ DecimalFormat::format( double number, // the string length of localized name of NaN. if (uprv_isNaN(number)) { + int begin = appendTo.length(); if (fieldPosition.getField() == NumberFormat::kIntegerField) - fieldPosition.setBeginIndex(appendTo.length()); + fieldPosition.setBeginIndex(begin); appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); + int end = appendTo.length(); + if (fieldPosition.getField() == NumberFormat::kIntegerField) - fieldPosition.setEndIndex(appendTo.length()); + fieldPosition.setEndIndex(end); + + addAttribute(attrBuffer, "integer", begin, end); addPadding(appendTo, fieldPosition, 0, 0); return appendTo; @@ -714,17 +748,23 @@ DecimalFormat::format( double number, // Special case for INFINITE, if (uprv_isInfinite(number)) { - int32_t prefixLen = appendAffix(appendTo, number, isNegative, TRUE); + int32_t prefixLen = appendAffix(appendTo, number, attrBuffer, isNegative, TRUE); + + int begin = appendTo.length(); if (fieldPosition.getField() == NumberFormat::kIntegerField) - fieldPosition.setBeginIndex(appendTo.length()); + fieldPosition.setBeginIndex(begin); appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); + int end = appendTo.length(); + if (fieldPosition.getField() == NumberFormat::kIntegerField) - fieldPosition.setEndIndex(appendTo.length()); + fieldPosition.setEndIndex(end); + + addAttribute(attrBuffer, "integer", begin, end); - int32_t suffixLen = appendAffix(appendTo, number, isNegative, FALSE); + int32_t suffixLen = appendAffix(appendTo, number, attrBuffer, isNegative, FALSE); addPadding(appendTo, fieldPosition, prefixLen, suffixLen); return appendTo; @@ -740,7 +780,7 @@ DecimalFormat::format( double number, digits.set(number, precision(FALSE), !fUseExponentialNotation && !areSignificantDigitsUsed()); - return subformat(appendTo, fieldPosition, digits, FALSE); + return subformat(appendTo, fieldPosition, attrBuffer, digits, FALSE); } /** @@ -821,6 +861,20 @@ DecimalFormat::subformat(UnicodeString& appendTo, DigitList& digits, UBool isInteger) const { + return subformat(appendTo, fieldPosition, NULL, digits, isInteger); +} + +/** + * Complete the formatting of a finite number. On entry, the fDigitList must + * be filled in with the correct digits. + */ +UnicodeString& +DecimalFormat::subformat(UnicodeString& appendTo, + FieldPosition& fieldPosition, + AttrBuffer attrBuffer, + DigitList& digits, + UBool isInteger) const +{ // Gets the localized zero Unicode character. UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero @@ -853,7 +907,7 @@ DecimalFormat::subformat(UnicodeString& appendTo, // Appends the prefix. double doubleValue = digits.getDouble(); - int32_t prefixLen = appendAffix(appendTo, doubleValue, !digits.fIsPositive, TRUE); + int32_t prefixLen = appendAffix(appendTo, doubleValue, attrBuffer, !digits.fIsPositive, TRUE); if (fUseExponentialNotation) { @@ -868,6 +922,11 @@ DecimalFormat::subformat(UnicodeString& appendTo, fieldPosition.setBeginIndex(-1); } + int currentLength = appendTo.length(); + int intBegin = currentLength; + int intEnd = -1; + int fracBegin = -1; + int32_t minFracDig = 0; if (useSigDig) { maxIntDig = minIntDig = 1; @@ -930,15 +989,21 @@ DecimalFormat::subformat(UnicodeString& appendTo, { if (i == integerDigits) { + intEnd = appendTo.length(); + addAttribute(attrBuffer, "integer", intBegin, intEnd); + // Record field information for caller. if (fieldPosition.getField() == NumberFormat::kIntegerField) - fieldPosition.setEndIndex(appendTo.length()); + fieldPosition.setEndIndex(intEnd); appendTo += *decimal; + fracBegin = appendTo.length(); + addAttribute(attrBuffer, "decimal_separator", fracBegin - 1, fracBegin); + // Record field information for caller. if (fieldPosition.getField() == NumberFormat::kFractionField) - fieldPosition.setBeginIndex(appendTo.length()); + fieldPosition.setBeginIndex(fracBegin); } // Restores the digit character or pads the buffer with zeros. UChar32 c = (UChar32)((i < digits.fCount) ? @@ -947,17 +1012,26 @@ DecimalFormat::subformat(UnicodeString& appendTo, appendTo += c; } + currentLength = appendTo.length(); + // Record field information if (fieldPosition.getField() == NumberFormat::kIntegerField) { if (fieldPosition.getEndIndex() < 0) - fieldPosition.setEndIndex(appendTo.length()); + fieldPosition.setEndIndex(currentLength); } else if (fieldPosition.getField() == NumberFormat::kFractionField) { if (fieldPosition.getBeginIndex() < 0) fieldPosition.setBeginIndex(appendTo.length()); - fieldPosition.setEndIndex(appendTo.length()); + fieldPosition.setEndIndex(currentLength); + } + + if (intEnd < 0) { + addAttribute(attrBuffer, "integer", intBegin, currentLength); + } + if (fracBegin > 0) { + addAttribute(attrBuffer, "fraction", fracBegin, currentLength); } // The exponent is output using the pattern-specified minimum @@ -966,6 +1040,9 @@ DecimalFormat::subformat(UnicodeString& appendTo, // unacceptable inaccuracy. appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); + addAttribute(attrBuffer, "exponent_symbol",currentLength, appendTo.length()); + currentLength = appendTo.length(); + // For zero values, we force the exponent to zero. We // must do this here, and not earlier, because the value // is used to determine integer digit count above. @@ -974,10 +1051,15 @@ DecimalFormat::subformat(UnicodeString& appendTo, if (exponent < 0) { appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); + addAttribute(attrBuffer, "exponent_sign",currentLength,appendTo.length()); } else if (fExponentSignAlwaysShown) { appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); + addAttribute(attrBuffer, "exponent_sign",currentLength,appendTo.length()); } + + currentLength = appendTo.length(); + DigitList expDigits; expDigits.set(exponent); { @@ -994,9 +1076,14 @@ DecimalFormat::subformat(UnicodeString& appendTo, (expDigits.fDigits[i] + zeroDelta) : zero); appendTo += c; } + + addAttribute(attrBuffer, "exponent", currentLength, appendTo.length()); } else // Not using exponential notation { + int currentLength = appendTo.length(); + int intBegin = currentLength; + // Record field information for caller. if (fieldPosition.getField() == NumberFormat::kIntegerField) fieldPosition.setBeginIndex(appendTo.length()); @@ -1052,7 +1139,9 @@ DecimalFormat::subformat(UnicodeString& appendTo, // Output grouping separator if necessary. if (isGroupingPosition(i)) { + currentLength = appendTo.length(); appendTo.append(*grouping); + addAttribute(attrBuffer, "grouping_separator",currentLength,appendTo.length()); } } @@ -1071,13 +1160,21 @@ DecimalFormat::subformat(UnicodeString& appendTo, if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart) appendTo += (zero); + currentLength = appendTo.length(); + addAttribute(attrBuffer, "integer", intBegin, currentLength); + // Output the decimal separator if we always do so. - if (fDecimalSeparatorAlwaysShown || fractionPresent) + if (fDecimalSeparatorAlwaysShown || fractionPresent) { appendTo += *decimal; + addAttribute(attrBuffer, "decimal_separator", currentLength, appendTo.length()); + currentLength = appendTo.length(); + } + + int fracBegin = currentLength; // Record field information for caller. if (fieldPosition.getField() == NumberFormat::kFractionField) - fieldPosition.setBeginIndex(appendTo.length()); + fieldPosition.setBeginIndex(fracBegin); count = useSigDig ? INT32_MAX : getMaximumFractionDigits(); if (useSigDig && (sigCount == maxSigDig || @@ -1129,9 +1226,11 @@ DecimalFormat::subformat(UnicodeString& appendTo, // Record field information for caller. if (fieldPosition.getField() == NumberFormat::kFractionField) fieldPosition.setEndIndex(appendTo.length()); + + addAttribute(attrBuffer, "fraction", fracBegin, appendTo.length()); } - int32_t suffixLen = appendAffix(appendTo, doubleValue, !digits.fIsPositive, FALSE); + int32_t suffixLen = appendAffix(appendTo, doubleValue, attrBuffer, !digits.fIsPositive, FALSE); addPadding(appendTo, fieldPosition, prefixLen, suffixLen); return appendTo; @@ -2099,9 +2198,9 @@ DecimalFormat::setMultiplier(int32_t newValue) // if (newValue <= 0) { // throw new IllegalArgumentException("Bad multiplier: " + newValue); // } - if (newValue > 0) { +// if (newValue > 0) { fMultiplier = newValue; - } +// } // else No way to return an error. } @@ -2439,6 +2538,14 @@ void DecimalFormat::expandAffixes() { #endif } +void DecimalFormat::expandAffix(const UnicodeString& pattern, + UnicodeString& affix, + double number, + UBool doFormat) const { + + expandAffix(pattern, affix, number, NULL, doFormat); +} + /** * Expand an affix pattern into an affix string. All characters in the * pattern are literal unless prefixed by kQuote. The following characters @@ -2473,6 +2580,7 @@ void DecimalFormat::expandAffixes() { void DecimalFormat::expandAffix(const UnicodeString& pattern, UnicodeString& affix, double number, + AttrBuffer attrBuffer, UBool doFormat) const { affix.remove(); for (int i=0; i<pattern.length(); ) { @@ -2481,6 +2589,7 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern, if (c == kQuote) { c = pattern.char32At(i); i += U16_LENGTH(c); + int beginIdx = affix.length(); switch (c) { case kCurrencySign: { // As of ICU 2.2 we use the currency object, and @@ -2498,6 +2607,7 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern, UErrorCode ec = U_ZERO_ERROR; if(intl) { affix += currencyUChars; + addAttribute(attrBuffer, "currency", beginIdx, affix.length()); } else { int32_t len; UBool isChoiceFormat; @@ -2546,11 +2656,13 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern, // We only arrive here if the currency choice // format in the locale data is INVALID. affix += currencyUChars; + addAttribute(attrBuffer, "currency", beginIdx, affix.length()); } } continue; } affix += UnicodeString(s, len); + addAttribute(attrBuffer, "currency", beginIdx, affix.length()); } } else { if(intl) { @@ -2558,20 +2670,25 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern, } else { affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); } + addAttribute(attrBuffer, "currency", beginIdx, affix.length()); } break; } case kPatternPercent: affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); + addAttribute(attrBuffer, "percent", beginIdx, affix.length()); break; case kPatternPerMill: affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); + addAttribute(attrBuffer, "permille", beginIdx, affix.length()); break; case kPatternPlus: affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); + addAttribute(attrBuffer, "sign", beginIdx, affix.length()); break; case kPatternMinus: affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); + addAttribute(attrBuffer, "sign", beginIdx, affix.length()); break; default: affix.append(c); @@ -2584,6 +2701,11 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern, } } +int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, + UBool isNegative, UBool isPrefix) const { + return appendAffix(buf, number, NULL, isNegative, isPrefix); +} + /** * Append an affix to the given StringBuffer. * @param buf buffer to append to @@ -2591,7 +2713,8 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern, * @param isPrefix */ int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, - UBool isNegative, UBool isPrefix) const { + AttrBuffer attrBuffer, UBool isNegative, + UBool isPrefix) const { if (fCurrencyChoice != 0) { const UnicodeString* affixPat; if (isPrefix) { @@ -2601,7 +2724,7 @@ int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, } if (affixPat) { UnicodeString affixBuf; - expandAffix(*affixPat, affixBuf, number, TRUE); + expandAffix(*affixPat, affixBuf, number, attrBuffer, TRUE); buf.append(affixBuf); return affixBuf.length(); } @@ -2614,7 +2737,41 @@ int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, } else { affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix; } + + int begin = (int)buf.length(); + buf.append(*affix); + + int offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol)); + if (offset > -1) { + UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); + addAttribute(attrBuffer, "currency", begin + offset, begin + offset + aff.length()); + } + + offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); + if (offset > -1) { + UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); + addAttribute(attrBuffer, "currency", begin + offset, begin + offset + aff.length()); + } + + offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)); + if (offset > -1) { + UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); + addAttribute(attrBuffer, "sign", begin + offset, begin + offset + aff.length()); + } + + offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)); + if (offset > -1) { + UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol); + addAttribute(attrBuffer, "percent", begin + offset, begin + offset + aff.length()); + } + + offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)); + if (offset > -1) { + UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); + addAttribute(attrBuffer, "permille", begin + offset, begin + offset + aff.length()); + } + return affix->length(); } @@ -3741,6 +3898,27 @@ DecimalFormat::precision(UBool isIntegral) const { } } +void DecimalFormat::addAttribute(AttrBuffer attrBuffer, char *fieldname, + int begin, int end) const { + if(attrBuffer == NULL || begin == end) { + return; + } + + char * tmp; + tmp = attrBuffer->buffer; + + if((128 + strlen(attrBuffer->buffer)) > attrBuffer->bufferSize) { + attrBuffer->bufferSize = 2 * attrBuffer->bufferSize; + attrBuffer->buffer = + (char *) malloc(attrBuffer->bufferSize * sizeof(char)); + attrBuffer->buffer[0] = '\0'; + sprintf(attrBuffer->buffer,"%s;%s;%d;%d", tmp, fieldname, begin, end); + free(tmp); + return; + } + sprintf(attrBuffer->buffer,"%s;%s;%d;%d", tmp, fieldname, begin, end); +} + U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/i18n/msgfmt.cpp b/i18n/msgfmt.cpp index 9eb7bcb3..6530828c 100644 --- a/i18n/msgfmt.cpp +++ b/i18n/msgfmt.cpp @@ -35,7 +35,7 @@ #include "unicode/rbnf.h" #include "ustrfmt.h" #include "cmemory.h" -#include "util.h" +#include "../common/util.h" #include "uassert.h" // ***************************************************************************** diff --git a/i18n/nfrs.cpp b/i18n/nfrs.cpp index ccf42b89..4387b74c 100644 --- a/i18n/nfrs.cpp +++ b/i18n/nfrs.cpp @@ -25,7 +25,7 @@ #include "cmemory.h" #endif -#include "util.h" +#include "../common/util.h" U_NAMESPACE_BEGIN diff --git a/i18n/nfrule.cpp b/i18n/nfrule.cpp index d6cf1850..028f99ca 100644 --- a/i18n/nfrule.cpp +++ b/i18n/nfrule.cpp @@ -25,7 +25,7 @@ #include "nfrlist.h" #include "nfsubs.h" -#include "util.h" +#include "../common/util.h" U_NAMESPACE_BEGIN diff --git a/i18n/rbnf.cpp b/i18n/rbnf.cpp index f9a9ae3d..3cef7cad 100644 --- a/i18n/rbnf.cpp +++ b/i18n/rbnf.cpp @@ -23,7 +23,7 @@ #include "cmemory.h" #include "cstring.h" -#include "util.h" +#include "../common/util.h" // debugging // #define DEBUG diff --git a/i18n/regexcmp.cpp b/i18n/regexcmp.cpp index 558f80b6..860333c0 100644 --- a/i18n/regexcmp.cpp +++ b/i18n/regexcmp.cpp @@ -21,7 +21,7 @@ #include "unicode/parsepos.h" #include "unicode/parseerr.h" #include "unicode/regex.h" -#include "util.h" +#include "../common/util.h" #include "cmemory.h" #include "cstring.h" #include "uvectr32.h" diff --git a/i18n/regexcst.pl b/i18n/regexcst.pl index b525cf88..b525cf88 100755..100644 --- a/i18n/regexcst.pl +++ b/i18n/regexcst.pl diff --git a/i18n/smpdtfmt.cpp b/i18n/smpdtfmt.cpp index 78917c17..17e9a520 100644 --- a/i18n/smpdtfmt.cpp +++ b/i18n/smpdtfmt.cpp @@ -41,7 +41,7 @@ #include "unicode/dcfmtsym.h" #include "unicode/uchar.h" #include "unicode/ustring.h" -#include "util.h" +#include "../common/util.h" #include "gregoimp.h" #include "cstring.h" #include "uassert.h" diff --git a/i18n/ucol_tok.cpp b/i18n/ucol_tok.cpp index 8a8ea445..d7d993a1 100644 --- a/i18n/ucol_tok.cpp +++ b/i18n/ucol_tok.cpp @@ -28,7 +28,7 @@ #include "ucol_tok.h" #include "cmemory.h" -#include "util.h" +#include "../common/util.h" U_CDECL_BEGIN static int32_t U_CALLCONV diff --git a/i18n/unicode/decimfmt.h b/i18n/unicode/decimfmt.h index 296906fb..9789043e 100644 --- a/i18n/unicode/decimfmt.h +++ b/i18n/unicode/decimfmt.h @@ -631,6 +631,11 @@ public: kPadAfterSuffix }; + typedef struct attributeBuffer { + char * buffer; + size_t bufferSize; + } AttributeBuffer, *AttrBuffer; + /** * Create a DecimalFormat using the default pattern and symbols * for the default locale. This is a convenient way to obtain a @@ -784,6 +789,12 @@ public: virtual UnicodeString& format(double number, UnicodeString& appendTo, FieldPosition& pos) const; + + virtual UnicodeString& format(double number, + UnicodeString& appendTo, + FieldPosition& pos, + AttrBuffer attrBuffer) const; + /** * Format a long number using base-10 representation. * @@ -798,6 +809,12 @@ public: virtual UnicodeString& format(int32_t number, UnicodeString& appendTo, FieldPosition& pos) const; + + virtual UnicodeString& format(int32_t number, + UnicodeString& appendTo, + FieldPosition& pos, + AttrBuffer attrBuffer) const; + /** * Format an int64 number using base-10 representation. * @@ -813,6 +830,11 @@ public: UnicodeString& appendTo, FieldPosition& pos) const; + virtual UnicodeString& format(int64_t number, + UnicodeString& appendTo, + FieldPosition& pos, + AttrBuffer attrBuffer) const; + /** * Format a Formattable using base-10 representation. * @@ -1704,6 +1726,12 @@ private: DigitList& digits, UBool isInteger) const; + UnicodeString& subformat(UnicodeString& appendTo, + FieldPosition& fieldPosition, + AttrBuffer attrBuffer, + DigitList& digits, + UBool isInteger) const; + void parse(const UnicodeString& text, Formattable& result, ParsePosition& pos, @@ -1753,6 +1781,9 @@ private: int32_t appendAffix(UnicodeString& buf, double number, UBool isNegative, UBool isPrefix) const; + int32_t appendAffix(UnicodeString& buf, double number, AttrBuffer attrBuffer, + UBool isNegative, UBool isPrefix) const; + /** * Append an affix to the given UnicodeString, using quotes if * there are special characters. Single quotes themselves must be @@ -1770,6 +1801,12 @@ private: double number, UBool doFormat) const; + void expandAffix(const UnicodeString& pattern, + UnicodeString& affix, + double number, + AttrBuffer attrBuffer, + UBool doFormat) const; + void expandAffixes(); static double round(double a, ERoundingMode mode, UBool isNegative); @@ -1832,6 +1869,8 @@ private: int32_t fFormatWidth; EPadPosition fPadPosition; + void addAttribute(AttrBuffer attrBuffer, char *fieldname, int begin, int end) const; + protected: /** @@ -1879,14 +1918,14 @@ inline UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo) const { FieldPosition pos(0); - return format(number, appendTo, pos); + return format(number, appendTo, pos, NULL); } inline UnicodeString& DecimalFormat::format(int32_t number, UnicodeString& appendTo) const { FieldPosition pos(0); - return format((int64_t)number, appendTo, pos); + return format((int64_t)number, appendTo, pos, NULL); } inline const UnicodeString & |