ICU-10039 Add basic C wrapper for NumberingSystem (numsys.h), version 1

X-SVN-Rev: 34268
This commit is contained in:
Peter Edberg 2013-09-11 05:07:00 +00:00
parent 90522bf7b1
commit 5a1e66e343
7 changed files with 305 additions and 1 deletions

2
.gitattributes vendored
View 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

View 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 \

View file

@ -344,6 +344,7 @@
<ClCompile Include="ulocdata.c" />
<ClCompile Include="umsg.cpp" />
<ClCompile Include="unum.cpp" />
<ClCompile Include="unumsys.cpp" />
<ClCompile Include="upluralrules.cpp" />
<ClCompile Include="utmscale.c" />
<ClCompile Include="vtzone.cpp" />
@ -1402,6 +1403,20 @@
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="unicode\unumsys.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
</CustomBuild>

View file

@ -291,6 +291,9 @@
<ClCompile Include="unum.cpp">
<Filter>formatting</Filter>
</ClCompile>
<ClCompile Include="unumsys.cpp">
<Filter>formatting</Filter>
</ClCompile>
<ClCompile Include="upluralrules.cpp">
<Filter>formatting</Filter>
</ClCompile>
@ -993,6 +996,9 @@
<CustomBuild Include="unicode\unum.h">
<Filter>formatting</Filter>
</CustomBuild>
<CustomBuild Include="unicode\unumsys.h">
<Filter>formatting</Filter>
</CustomBuild>
<CustomBuild Include="unicode\upluralrules.h">
<Filter>formatting</Filter>
</CustomBuild>

View file

@ -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

View file

@ -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 */

View file

@ -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 <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 */