]> granicus.if.org Git - icu/commitdiff
ICU-10039 Add basic C wrapper for NumberingSystem (numsys.h), version 1
authorPeter Edberg <pedberg@unicode.org>
Wed, 11 Sep 2013 05:07:00 +0000 (05:07 +0000)
committerPeter Edberg <pedberg@unicode.org>
Wed, 11 Sep 2013 05:07:00 +0000 (05:07 +0000)
X-SVN-Rev: 34268

.gitattributes
icu4c/source/i18n/Makefile.in
icu4c/source/i18n/i18n.vcxproj
icu4c/source/i18n/i18n.vcxproj.filters
icu4c/source/i18n/unicode/unumsys.h [new file with mode: 0644]
icu4c/source/i18n/unumsys.cpp [new file with mode: 0644]
icu4c/source/test/cintltst/cnumtst.c

index d15c513fefef7f7b4bbb44f70de22a18bcb92044..b7e48fd8173254ffb2ce0b2b1903107c00676e2b 100644 (file)
@@ -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
index c908801dd7f9763ec5002a9f1c6bf8ff5eec9804..2b8bc89e70f500d926e7a3794c873a1f57b096d1 100644 (file)
@@ -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 \
index fc33d41529b013b290dde94cbb568e5729c11c06..3c1eebb04c3ea8e284790de057620a27088ba909 100644 (file)
     <ClCompile Include="ulocdata.c" />\r
     <ClCompile Include="umsg.cpp" />\r
     <ClCompile Include="unum.cpp" />\r
+    <ClCompile Include="unumsys.cpp" />\r
     <ClCompile Include="upluralrules.cpp" />\r
     <ClCompile Include="utmscale.c" />\r
     <ClCompile Include="vtzone.cpp" />\r
 </Command>\r
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
       <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode\r
+</Command>\r
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
+    </CustomBuild>\r
+    <CustomBuild Include="unicode\unumsys.h">\r
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode\r
+</Command>\r
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode\r
+</Command>\r
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode\r
+</Command>\r
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode\r
 </Command>\r
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
     </CustomBuild>\r
index c8fe93e73e51b929684450a3f671d6487c735038..da3b9aa8665c61e86232b258538f869ca2b65e77 100644 (file)
     <ClCompile Include="unum.cpp">\r
       <Filter>formatting</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="unumsys.cpp">\r
+      <Filter>formatting</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="upluralrules.cpp">\r
       <Filter>formatting</Filter>\r
     </ClCompile>\r
     <CustomBuild Include="unicode\unum.h">\r
       <Filter>formatting</Filter>\r
     </CustomBuild>\r
+    <CustomBuild Include="unicode\unumsys.h">\r
+      <Filter>formatting</Filter>\r
+    </CustomBuild>\r
     <CustomBuild Include="unicode\upluralrules.h">\r
       <Filter>formatting</Filter>\r
     </CustomBuild>\r
diff --git a/icu4c/source/i18n/unicode/unumsys.h b/icu4c/source/i18n/unicode/unumsys.h
new file mode 100644 (file)
index 0000000..bf26b22
--- /dev/null
@@ -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 (file)
index 0000000..f8eb6c7
--- /dev/null
@@ -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 */
index e2bdbc3978ef4ba0a3b58f0827886df93dd10e39..7898f36e78648a67a6ee87b13b0fbcd9ac34ee0a 100644 (file)
 #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 <stdio.h>
 
@@ -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 */