#include "unicode/ugender.h"
#include "unicode/ures.h"
+#include "cmemory.h"
#include "cstring.h"
#include "mutex.h"
#include "ucln_in.h"
return TRUE;
}
+static void U_CALLCONV deleteChars(void* chars) {
+ uprv_free(chars);
+}
+
U_CDECL_END
U_NAMESPACE_BEGIN
if (needed) {
Mutex lock(&gGenderMetaLock);
if (gGenderInfoCache == NULL) {
- gGenderInfoCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
- if (U_FAILURE(status)) {
- return NULL;
- }
gObjs = new GenderInfo[GENDER_STYLE_LENGTH];
if (gObjs == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
- uhash_close(gGenderInfoCache);
- gGenderInfoCache = NULL;
return NULL;
}
for (int i = 0; i < GENDER_STYLE_LENGTH; i++) {
gObjs[i]._style = i;
}
+ gGenderInfoCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
+ if (U_FAILURE(status)) {
+ delete [] gObjs;
+ return NULL;
+ }
+ uhash_setKeyDeleter(gGenderInfoCache, deleteChars);
ucln_i18n_registerCleanup(UCLN_I18N_GENDERINFO, gender_cleanup);
}
}
- GenderInfo* result = NULL;
+ const GenderInfo* result = NULL;
const char* key = locale.getName();
{
Mutex lock(&gGenderMetaLock);
- result = (GenderInfo*) uhash_get(gGenderInfoCache, key);
+ result = (const GenderInfo*) uhash_get(gGenderInfoCache, key);
}
if (result) {
return result;
if (temp) {
result = temp;
} else {
- uhash_put(gGenderInfoCache, (void*) key, result, &status);
+ char* keyDup = uprv_strdup(key);
+ uhash_put(gGenderInfoCache, keyDup, (void*) result, &status);
if (U_FAILURE(status)) {
+ uprv_free(keyDup);
return NULL;
}
}
return result;
}
-GenderInfo* GenderInfo::loadInstance(const Locale& locale, UErrorCode& status) {
+const GenderInfo* GenderInfo::loadInstance(const Locale& locale, UErrorCode& status) {
LocalUResourceBundlePointer rb(
ures_openDirect(NULL, "genderList", &status));
if (U_FAILURE(status)) {
}
char type_str[256];
u_UCharsToChars(s, type_str, resLen + 1);
- if (!uprv_strcmp(type_str, gNeutralStr)) {
+ if (uprv_strcmp(type_str, gNeutralStr) == 0) {
return &gObjs[NEUTRAL];
}
- if (!uprv_strcmp(type_str, gMixedNeutralStr)) {
+ if (uprv_strcmp(type_str, gMixedNeutralStr) == 0) {
return &gObjs[MIXED_NEUTRAL];
}
- if (!uprv_strcmp(type_str, gMailTaintsStr)) {
+ if (uprv_strcmp(type_str, gMailTaintsStr) == 0) {
return &gObjs[MALE_TAINTS];
}
return &gObjs[NEUTRAL];
U_CAPI const UGenderInfo* U_EXPORT2
ugender_getInstance(const char* locale, UErrorCode* status) {
- return (UGenderInfo*) icu::GenderInfo::getInstance(icu::Locale::createFromName(locale), *status);
+ return (const UGenderInfo*) icu::GenderInfo::getInstance(locale, *status);
}
U_CAPI UGender U_EXPORT2
-ugender_getListGender(const UGenderInfo* genderInfo, UGender* genders, int32_t size, UErrorCode* status) {
+ugender_getListGender(const UGenderInfo* genderInfo, const UGender* genders, int32_t size, UErrorCode* status) {
return ((const icu::GenderInfo *)genderInfo)->getListGender(genders, size, *status);
}
#include "unicode/utypes.h"
-/**
- * \file
- * \brief C++ API: The purpose of this API is to compute the gender of a list as
- * a whole given the gender of each element.
- */
-
#if !UCONFIG_NO_FORMATTING
#include "unicode/locid.h"
U_NAMESPACE_BEGIN
+/**
+ * GenderInfo computes the gender of a list as a whole given the gender of
+ * each element.
+ * @draft ICU 50
+ */
class U_I18N_API GenderInfo : public UObject {
public:
/**
* No "poor man's RTTI"
- *
- * @draft ICU 50
*/
virtual UClassID getDynamicClassID() const;
/**
* Copy constructor. One object per locale invariant. Clients
* must never copy GenderInfo objects.
- * @draft ICU 50
*/
GenderInfo(const GenderInfo& other);
/**
* Assignment operator. Not applicable to immutable objects.
- * @draft ICU 50
*/
GenderInfo& operator=(const GenderInfo&);
static const GenderInfo* getMaleTaintsInstance();
- static GenderInfo* loadInstance(const Locale& locale, UErrorCode& status);
+ static const GenderInfo* loadInstance(const Locale& locale, UErrorCode& status);
friend class ::GenderInfoTest;
};
* @draft ICU 50
*/
enum UGender {
+ /**
+ * Male gender.
+ * @draft ICU 50
+ */
UGENDER_MALE,
+ /**
+ * Female gender.
+ * @draft ICU 50
+ */
UGENDER_FEMALE,
+ /**
+ * Neutral gender.
+ * @draft ICU 50
+ */
UGENDER_OTHER
};
/**
* Opens a new UGenderInfo object given locale.
* @param locale The locale for which the rules are desired.
* @return A UGenderInfo for the specified locale, or NULL if an error occurred.
- * @stable ICU 4.8
+ * @draft ICU 50
*/
U_STABLE const UGenderInfo* U_EXPORT2
ugender_getInstance(const char *locale, UErrorCode *status);
* @draft ICU 50
*/
U_DRAFT UGender U_EXPORT2
-ugender_getListGender(const UGenderInfo* genderinfo, UGender *genders, int32_t size, UErrorCode *status);
+ugender_getListGender(const UGenderInfo* genderinfo, const UGender *genders, int32_t size, UErrorCode *status);
#endif /* #if !UCONFIG_NO_FORMATTING */
#******************************************************************************
#
-# Copyright (C) 1999-2011, International Business Machines
+# Copyright (C) 1999-2012, International Business Machines
# Corporation and others. All Rights Reserved.
#
#******************************************************************************
stdnmtst.o usrchtst.o custrtrn.o sorttest.o trietest.o trie2test.o usettest.o \
uenumtst.o utmstest.o currtest.o \
idnatest.o nfsprep.o spreptst.o sprpdata.o \
-hpmufn.o tracetst.o reapits.o utexttst.o ucsdetst.o spooftest.o
+hpmufn.o tracetst.o reapits.o utexttst.o ucsdetst.o spooftest.o \
+cgendtst.o
DEPS = $(OBJECTS:.o=.d)
endif
endif
endif
-
/********************************************************************
* COPYRIGHT:
- * Copyright (c) 1996-2010, International Business Machines Corporation and
+ * Copyright (c) 1996-2012, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/********************************************************************************
void addUCsdetTest(TestNode** root);
void addCnvSelTest(TestNode** root);
void addUSpoofTest(TestNode** root);
+void addGendInfoForTest(TestNode** root);
void addAllTests(TestNode** root)
{
addUSpoofTest(root);
#endif
addPUtilTest(root);
+ addGendInfoForTest(root);
}
-
--- /dev/null
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 1997-2012, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+/********************************************************************************
+*
+* File CGENDTST.C
+*********************************************************************************
+*/
+
+/* C API TEST FOR GENDER INFO */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "cintltst.h"
+#include "unicode/ugender.h"
+
+static const UGender kAllFemale[] = {UGENDER_FEMALE, UGENDER_FEMALE};
+
+#define LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
+
+void addGendInfoForTest(TestNode** root);
+static void TestGenderInfo(void);
+
+#define TESTCASE(x) addTest(root, &x, "tsformat/cgendtst/" #x)
+
+void addGendInfoForTest(TestNode** root)
+{
+ TESTCASE(TestGenderInfo);
+}
+
+static void TestGenderInfo(void) {
+ UErrorCode status = U_ZERO_ERROR;
+ const UGenderInfo* actual_gi = ugender_getInstance("fr_CA", &status);
+ if (U_FAILURE(status)) {
+ log_err("Fail to create UGenderInfo - %s\n", u_errorName(status));
+ return;
+ }
+ UGender actual = ugender_getListGender(actual_gi, kAllFemale, LENGTH(kAllFemale), &status);
+ if (U_FAILURE(status)) {
+ log_err("Fail to get gender of list - %s\n", u_errorName(status));
+ return;
+ }
+ if (actual != UGENDER_FEMALE) {
+ log_err("Expected UGENDER_FEMALE got %d\n", actual);
+ }
+}
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
<ClCompile Include="cdtdptst.c" />\r
<ClCompile Include="cdtrgtst.c" />\r
<ClCompile Include="cformtst.c" />\r
+ <ClCompile Include="cgendtst.c" />\r
<ClCompile Include="cmsgtst.c" />\r
<ClCompile Include="cnmdptst.c" />\r
<ClCompile Include="cnumtst.c" />\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<ImportGroup Label="ExtensionTargets">\r
</ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
<ClCompile Include="cformtst.c">\r
<Filter>formatting</Filter>\r
</ClCompile>\r
+ <ClCompile Include="cgendtst.c">\r
+ <Filter>formatting</Filter>\r
+ </ClCompile>\r
<ClCompile Include="cmsgtst.c">\r
<Filter>formatting</Filter>\r
</ClCompile>\r
<Filter>sprep & idna</Filter>\r
</ClInclude>\r
</ItemGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
-UGender kSingleFemale[] = {UGENDER_FEMALE};
-UGender kSingleMale[] = {UGENDER_MALE};
-UGender kSingleOther[] = {UGENDER_OTHER};
+static const UGender kSingleFemale[] = {UGENDER_FEMALE};
+static const UGender kSingleMale[] = {UGENDER_MALE};
+static const UGender kSingleOther[] = {UGENDER_OTHER};
-UGender kAllFemale[] = {UGENDER_FEMALE, UGENDER_FEMALE};
-UGender kAllMale[] = {UGENDER_MALE, UGENDER_MALE};
-UGender kAllOther[] = {UGENDER_OTHER, UGENDER_OTHER};
+static const UGender kAllFemale[] = {UGENDER_FEMALE, UGENDER_FEMALE};
+static const UGender kAllMale[] = {UGENDER_MALE, UGENDER_MALE};
+static const UGender kAllOther[] = {UGENDER_OTHER, UGENDER_OTHER};
-UGender kFemaleMale[] = {UGENDER_FEMALE, UGENDER_MALE};
-UGender kFemaleOther[] = {UGENDER_FEMALE, UGENDER_OTHER};
-UGender kMaleOther[] = {UGENDER_MALE, UGENDER_OTHER};
+static const UGender kFemaleMale[] = {UGENDER_FEMALE, UGENDER_MALE};
+static const UGender kFemaleOther[] = {UGENDER_FEMALE, UGENDER_OTHER};
+static const UGender kMaleOther[] = {UGENDER_MALE, UGENDER_OTHER};
class GenderInfoTest : public IntlTest {
private:
void TestGetListGender();
void TestFallback();
- void TestCApi();
void check(UGender expected_neutral, UGender expected_mixed, UGender expected_taints, const UGender* genderList, int32_t listLength);
void checkLocale(const Locale& locale, UGender expected, const UGender* genderList, int32_t listLength);
};
TESTCASE_AUTO_BEGIN;
TESTCASE_AUTO(TestGetListGender);
TESTCASE_AUTO(TestFallback);
- TESTCASE_AUTO(TestCApi);
TESTCASE_AUTO_END;
}
void GenderInfoTest::TestGetListGender() {
check(UGENDER_OTHER, UGENDER_OTHER, UGENDER_OTHER, NULL, 0);
- // JAVA version always returns OTHER if gender style is NEUTRAL. Is this
- // really correct?
check(UGENDER_OTHER, UGENDER_FEMALE, UGENDER_FEMALE, kSingleFemale, LENGTHOF(kSingleFemale));
check(UGENDER_OTHER, UGENDER_MALE, UGENDER_MALE, kSingleMale, LENGTHOF(kSingleMale));
- // JAVA version has MALE_TAINTS return OTHER for {OTHER}. Is this really correct?
check(UGENDER_OTHER, UGENDER_OTHER, UGENDER_OTHER, kSingleOther, LENGTHOF(kSingleOther));
check(UGENDER_OTHER, UGENDER_FEMALE, UGENDER_FEMALE, kAllFemale, LENGTHOF(kAllFemale));
void GenderInfoTest::TestFallback() {
UErrorCode status = U_ZERO_ERROR;
- const GenderInfo* actual = GenderInfo::getInstance(Locale::createFromName("xx"), status);
+ const GenderInfo* actual = GenderInfo::getInstance("xx", status);
if (U_FAILURE(status)) {
errcheckln(status, "Fail to create GenderInfo - %s", u_errorName(status));
return;
if (expected != actual) {
errln("For Neutral, expected %d got %d", expected, actual);
}
- actual = GenderInfo::getInstance(Locale::createFromName("fr_CA"), status);
+ actual = GenderInfo::getInstance("fr_CA", status);
if (U_FAILURE(status)) {
errcheckln(status, "Fail to create GenderInfo - %s", u_errorName(status));
return;
}
}
-void GenderInfoTest::TestCApi() {
- UErrorCode status = U_ZERO_ERROR;
- const UGenderInfo* actual_gi = ugender_getInstance("fr_CA", &status);
- if (U_FAILURE(status)) {
- errcheckln(status, "Fail to create UGenderInfo - %s", u_errorName(status));
- return;
- }
- const UGenderInfo* expected_gi = (const UGenderInfo*) GenderInfo::getMaleTaintsInstance();
- if (expected_gi != actual_gi) {
- errln("Expected UGenderInfo %d got %d", expected_gi, actual_gi);
- }
- UGender actual = ugender_getListGender(actual_gi, kAllFemale, LENGTHOF(kAllFemale), &status);
- if (U_FAILURE(status)) {
- errcheckln(status, "Fail to create UGenderInfo - %s", u_errorName(status));
- return;
- }
- if (actual != UGENDER_FEMALE) {
- errln("Expected UGENDER_FEMALE got %d", actual);
- }
-}
-
void GenderInfoTest::check(
UGender expected_neutral, UGender expected_mixed, UGender expected_taints, const UGender* genderList, int32_t listLength) {
checkLocale(Locale::getUS(), expected_neutral, genderList, listLength);
- checkLocale(Locale::createFromName("is"), expected_mixed, genderList, listLength);
+ checkLocale("is", expected_mixed, genderList, listLength);
checkLocale(Locale::getFrench(), expected_taints, genderList, listLength);
}