diff --git a/.gitattributes b/.gitattributes
index d15c513fefe..b7e48fd8173 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -83,7 +83,9 @@ icu4c/source/extra/uconv/uconv.vcxproj -text
icu4c/source/extra/uconv/uconv.vcxproj.filters -text
icu4c/source/i18n/i18n.vcxproj -text
icu4c/source/i18n/i18n.vcxproj.filters -text
+icu4c/source/i18n/unicode/unumsys.h -text
icu4c/source/i18n/unicode/uregion.h -text
+icu4c/source/i18n/unumsys.cpp -text
icu4c/source/i18n/uregion.cpp -text
icu4c/source/io/io.vcxproj -text
icu4c/source/io/io.vcxproj.filters -text
diff --git a/icu4c/source/i18n/Makefile.in b/icu4c/source/i18n/Makefile.in
index c908801dd7f..2b8bc89e70f 100644
--- a/icu4c/source/i18n/Makefile.in
+++ b/icu4c/source/i18n/Makefile.in
@@ -66,7 +66,7 @@ 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 udatpg.o \
-nfrs.o nfrule.o nfsubs.o rbnf.o numsys.o ucsdet.o \
+nfrs.o nfrule.o nfsubs.o rbnf.o numsys.o unumsys.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 chnsecal.o cecal.o coptccal.o dangical.o ethpccal.o \
diff --git a/icu4c/source/i18n/i18n.vcxproj b/icu4c/source/i18n/i18n.vcxproj
index fc33d41529b..3c1eebb04c3 100644
--- a/icu4c/source/i18n/i18n.vcxproj
+++ b/icu4c/source/i18n/i18n.vcxproj
@@ -344,6 +344,7 @@
+
@@ -1402,6 +1403,20 @@
..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+
+
+ copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+ copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+ copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+ copy "%(FullPath)" ..\..\include\unicode
..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
diff --git a/icu4c/source/i18n/i18n.vcxproj.filters b/icu4c/source/i18n/i18n.vcxproj.filters
index c8fe93e73e5..da3b9aa8665 100644
--- a/icu4c/source/i18n/i18n.vcxproj.filters
+++ b/icu4c/source/i18n/i18n.vcxproj.filters
@@ -291,6 +291,9 @@
formatting
+
+ formatting
+
formatting
@@ -993,6 +996,9 @@
formatting
+
+ formatting
+
formatting
diff --git a/icu4c/source/i18n/unicode/unumsys.h b/icu4c/source/i18n/unicode/unumsys.h
new file mode 100644
index 00000000000..bf26b226aeb
--- /dev/null
+++ b/icu4c/source/i18n/unicode/unumsys.h
@@ -0,0 +1,137 @@
+/*
+*****************************************************************************************
+* Copyright (C) 2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*****************************************************************************************
+*/
+
+#ifndef UNUMSYS_H
+#define UNUMSYS_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/uenum.h"
+#include "unicode/localpointer.h"
+
+/**
+ * \file
+ * \brief C API: UNumberingSystem, information about numbering systems
+ *
+ * Defines numbering systems. A numbering system describes the scheme by which
+ * numbers are to be presented to the end user. In its simplest form, a numbering
+ * system describes the set of digit characters that are to be used to display
+ * numbers, such as Western digits, Thai digits, Arabic-Indic digits, etc.
+ * More complicated numbering systems are algorithmic in nature, and require use
+ * of an RBNF formatter (rule based number formatter), in order to calculate
+ * the characters to be displayed for a given number. Examples of algorithmic
+ * numbering systems include Roman numerals, Chinese numerals, and Hebrew numerals.
+ * Formatting rules for many commonly used numbering systems are included in
+ * the ICU package, based on the numbering system rules defined in CLDR.
+ * Alternate numbering systems can be specified to a locale by using the
+ * numbers locale keyword.
+ */
+
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Opaque UNumberingSystem object for use in C programs.
+ * @draft ICU 52
+ */
+struct UNumberingSystem;
+typedef struct UNumberingSystem UNumberingSystem; /**< C typedef for struct UNumberingSystem. @draft ICU 52 */
+
+/**
+ * Opens a UNumberingSystem object using the default numbering system for the specified locale.
+ * @param locale The locale for which the default numbering system should be opened.
+ * @param status A pointer to a UErrorCode to receive any errors. For example, this may be U_UNSUPPORTED_ERROR
+ * for a locale such as "en@numbers=xyz" that specifies a numbering system unknown to ICU.
+ * @return A UNumberingSystem for the specified locale, or NULL if an error occurred.
+ * @draft ICU 52
+ */
+U_DRAFT UNumberingSystem * U_EXPORT2
+unumsys_open(const char *locale, UErrorCode *status);
+
+/**
+ * Opens a UNumberingSystem object using the name of one of the predefined numbering systems defined by CLDR
+ * and known to ICU, such as "latn", "arabext", or "hanidec"; the full list is returned by unumsys_openAvailableNames.
+ * Note that some of the numbering systems names listed at
+ * http://unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml
+ * do not identify specific numbering systems, but rather types that may only be used as part of a locale which
+ * defines how they are mapped to a specific numbering system such as "latn" or "hant".
+ *
+ * @param name The name of the numbering system for which a UNumberingSystem object should be opened.
+ * @param status A pointer to a UErrorCode to receive any errors. For example, this may be U_UNSUPPORTED_ERROR
+ * for a numbering system such as "xyz" that is unknown to ICU.
+ * @return A UNumberingSystem for the specified name, or NULL if an error occurred.
+ * @draft ICU 52
+ */
+U_DRAFT UNumberingSystem * U_EXPORT2
+unumsys_openByName(const char *name, UErrorCode *status);
+
+/**
+ * Close a UNumberingSystem object. Once closed it may no longer be used.
+ * @param unumsys The UNumberingSystem object to close.
+ * @draft ICU 52
+ */
+U_DRAFT void U_EXPORT2
+unumsys_close(UNumberingSystem *unumsys);
+
+#if U_SHOW_CPLUSPLUS_API
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUNumberingSystemPointer
+ * "Smart pointer" class, closes a UNumberingSystem via unumsys_close().
+ * For most methods see the LocalPointerBase base class.
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @draft ICU 52
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUNumberingSystemPointer, UNumberingSystem, unumsys_close);
+
+U_NAMESPACE_END
+#endif
+
+/**
+ * Returns an enumeration over the names of all of the predefined numbering systems known to ICU.
+ * @param status A pointer to a UErrorCode to receive any errors.
+ * @return A pointer to a UEnumeration that must be closed with uenum_close(), or NULL if an error occurred.
+ * @draft ICU 52
+ */
+U_DRAFT UEnumeration * U_EXPORT2
+unumsys_openAvailableNames(UErrorCode *status);
+
+/**
+ * Returns the name of the specified UNumberingSystem object (if it is one of the predefined names known to ICU).
+ * @param unumsys The UNumberingSystem whose name is desired.
+ * @return A pointer to the name of the specified UNumberingSystem object, or NULL if the name is not one of the ICU predefined names.
+ * @draft ICU 52
+ */
+U_DRAFT const char * U_EXPORT2
+unumsys_getName(UNumberingSystem *unumsys);
+
+/**
+ * Returns the radix of the specified UNumberingSystem object.
+ * @param unumsys The UNumberingSystem whose radix is desired.
+ * @return The radix of the specified UNumberingSystem object.
+ * @draft ICU 52
+ */
+U_DRAFT int32_t U_EXPORT2
+unumsys_getRadix(UNumberingSystem *unumsys);
+
+/**
+ * Returns whether the given UNumberingSystem object is for an algorithmic (not purely decimal) system.
+ * @param unumsys The UNumberingSystem whose algorithmic status is desired.
+ * @return TRUE if the specified UNumberingSystem object is for an algorithmic system.
+ * @draft ICU 52
+ */
+U_DRAFT UBool U_EXPORT2
+unumsys_isAlgorithmic(UNumberingSystem *unumsys);
+
+#endif /* U_HIDE_DRAFT_API */
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif
diff --git a/icu4c/source/i18n/unumsys.cpp b/icu4c/source/i18n/unumsys.cpp
new file mode 100644
index 00000000000..f8eb6c7d654
--- /dev/null
+++ b/icu4c/source/i18n/unumsys.cpp
@@ -0,0 +1,68 @@
+/*
+*****************************************************************************************
+* Copyright (C) 2013, International Business Machines Corporation and others.
+* All Rights Reserved.
+*****************************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/unumsys.h"
+#include "unicode/numsys.h"
+#include "unicode/uenum.h"
+
+U_NAMESPACE_USE
+
+
+U_CAPI UNumberingSystem* U_EXPORT2
+unumsys_open(const char *locale, UErrorCode *status)
+{
+ return (UNumberingSystem*)NumberingSystem::createInstance(Locale(locale), *status);
+}
+
+
+U_CAPI UNumberingSystem* U_EXPORT2
+unumsys_openByName(const char *name, UErrorCode *status)
+{
+ return (UNumberingSystem*)NumberingSystem::createInstanceByName(name, *status);
+}
+
+
+U_CAPI void U_EXPORT2
+unumsys_close(UNumberingSystem *unumsys)
+{
+ delete ((NumberingSystem*)unumsys);
+}
+
+
+U_CAPI UEnumeration* U_EXPORT2
+unumsys_openAvailableNames(UErrorCode *status)
+{
+ return uenum_openFromStringEnumeration(NumberingSystem::getAvailableNames(*status), status);
+}
+
+
+U_CAPI const char * U_EXPORT2
+unumsys_getName(UNumberingSystem *unumsys)
+{
+ return ((NumberingSystem*)unumsys)->getName();
+}
+
+
+U_CAPI int32_t U_EXPORT2
+unumsys_getRadix(UNumberingSystem *unumsys)
+{
+ return ((NumberingSystem*)unumsys)->getRadix();
+}
+
+
+U_CAPI UBool U_EXPORT2
+unumsys_isAlgorithmic(UNumberingSystem *unumsys)
+{
+ return ((NumberingSystem*)unumsys)->isAlgorithmic();
+}
+
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/test/cintltst/cnumtst.c b/icu4c/source/test/cintltst/cnumtst.c
index e2bdbc3978e..7898f36e786 100644
--- a/icu4c/source/test/cintltst/cnumtst.c
+++ b/icu4c/source/test/cintltst/cnumtst.c
@@ -26,11 +26,13 @@
#include "unicode/uloc.h"
#include "unicode/umisc.h"
#include "unicode/unum.h"
+#include "unicode/unumsys.h"
#include "unicode/ustring.h"
#include "cintltst.h"
#include "cnumtst.h"
#include "cmemory.h"
+#include "cstring.h"
#include "putilimp.h"
#include
@@ -52,6 +54,7 @@ static void TestParseCurrency(void);
static void TestMaxInt(void);
static void TestNoExponent(void);
static void TestUFormattable(void);
+static void TestUNumberingSystem(void);
#define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x)
@@ -75,6 +78,7 @@ void addNumForTest(TestNode** root)
TESTCASE(TestMaxInt);
TESTCASE(TestNoExponent);
TESTCASE(TestUFormattable);
+ TESTCASE(TestUNumberingSystem);
}
/* test Parse int 64 */
@@ -2284,4 +2288,76 @@ static void TestUFormattable(void) {
}
}
+typedef struct {
+ const char * locale;
+ const char * numsys;
+ int32_t radix;
+ UBool isAlgorithmic;
+} NumSysTestItem;
+
+static const NumSysTestItem numSysTestItems[] = {
+ //locale numsys radix isAlgorithmic
+ { "en", "latn", 10, FALSE },
+ { "en@numbers=roman", "roman", 10, TRUE },
+ { "en@numbers=finance", "latn", 10, FALSE },
+ { "ar", "arab", 10, FALSE },
+ { "fa", "arabext", 10, FALSE },
+ { "zh_Hant@numbers=traditional", "hant", 10, TRUE },
+ { NULL, NULL, 0, FALSE },
+};
+
+static void TestUNumberingSystem(void) {
+ const NumSysTestItem * itemPtr;
+ UNumberingSystem * unumsys;
+ UEnumeration * uenum;
+ const char * numsys;
+ UErrorCode status;
+
+ for (itemPtr = numSysTestItems; itemPtr->locale != NULL; itemPtr++) {
+ status = U_ZERO_ERROR;
+ unumsys = unumsys_open(itemPtr->locale, &status);
+ if ( U_SUCCESS(status) ) {
+ int32_t radix = unumsys_getRadix(unumsys);
+ UBool isAlgorithmic = unumsys_isAlgorithmic(unumsys);
+ numsys = unumsys_getName(unumsys);
+ if ( uprv_strcmp(numsys, itemPtr->numsys) != 0 || radix != itemPtr->radix || !isAlgorithmic != !itemPtr->isAlgorithmic ) {
+ log_err("unumsys name/radix/isAlgorithmic for locale %s, expected %s/%d/%d, got %s/%d/%d\n",
+ itemPtr->locale, itemPtr->numsys, itemPtr->radix, itemPtr->isAlgorithmic, numsys, radix, isAlgorithmic);
+ }
+ unumsys_close(unumsys);
+ } else {
+ log_data_err("unumsys_open for locale %s fails with status %s\n", itemPtr->locale, myErrorName(status));
+ }
+ }
+
+ status = U_ZERO_ERROR;
+ uenum = unumsys_openAvailableNames(&status);
+ if ( U_SUCCESS(status) ) {
+ int32_t numsysCount = 0;
+ // sanity check for a couple of number systems that must be in the enumeration
+ UBool foundLatn = FALSE;
+ UBool foundArab = FALSE;
+ while ( (numsys = uenum_next(uenum, NULL, &status)) != NULL && U_SUCCESS(status) ) {
+ status = U_ZERO_ERROR;
+ unumsys = unumsys_openByName(numsys, &status);
+ if ( U_SUCCESS(status) ) {
+ numsysCount++;
+ if ( uprv_strcmp(numsys, "latn") ) foundLatn = TRUE;
+ if ( uprv_strcmp(numsys, "arab") ) foundArab = TRUE;
+ unumsys_close(unumsys);
+ } else {
+ log_err("unumsys_openAvailableNames includes %s but unumsys_openByName on it fails with status %s\n",
+ numsys, myErrorName(status));
+ }
+ }
+ uenum_close(uenum);
+ if ( numsysCount < 40 || !foundLatn || !foundArab ) {
+ log_err("unumsys_openAvailableNames results incomplete: numsysCount %d, foundLatn %d, foundArab %d\n",
+ numsysCount, foundLatn, foundArab);
+ }
+ } else {
+ log_data_err("unumsys_openAvailableNames fails with status %s\n", myErrorName(status));
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */