]> granicus.if.org Git - icu/commitdiff
ICU-9598 C/C++ implementation of GenderInfo.
authorTravis Keep <keep94@gmail.com>
Fri, 5 Oct 2012 19:02:05 +0000 (19:02 +0000)
committerTravis Keep <keep94@gmail.com>
Fri, 5 Oct 2012 19:02:05 +0000 (19:02 +0000)
X-SVN-Rev: 32527

.gitattributes
icu4c/source/i18n/Makefile.in
icu4c/source/i18n/gender.cpp [new file with mode: 0644]
icu4c/source/i18n/ucln_in.h
icu4c/source/i18n/unicode/gender.h [new file with mode: 0644]
icu4c/source/i18n/unicode/ugender.h [new file with mode: 0644]
icu4c/source/test/intltest/Makefile.in
icu4c/source/test/intltest/genderinfotest.cpp [new file with mode: 0644]
icu4c/source/test/intltest/intltest.vcxproj
icu4c/source/test/intltest/itformat.cpp

index 9e966402cf76e9bc7e87eb5ccc569d4177789783..e0b95dc3b2a4ac8571e1e8de43063e39c9769dc2 100644 (file)
@@ -74,6 +74,8 @@ 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/gender.h -text
+icu4c/source/i18n/unicode/ugender.h -text
 icu4c/source/io/io.vcxproj -text
 icu4c/source/io/io.vcxproj.filters -text
 icu4c/source/layout/layout.vcxproj -text
index 0c5009312787574abc2e81f47defbcf3ce9ffd70..6ea83dce865dc48afb93edc3f0b87b09e0d51820 100644 (file)
@@ -86,7 +86,7 @@ tmunit.o tmutamt.o tmutfmt.o colldata.o bmsearch.o bms.o currpinf.o \
 uspoof.o uspoof_impl.o uspoof_build.o uspoof_conf.o uspoof_wsconf.o decfmtst.o smpdtfst.o \
 ztrans.o zrule.o vzone.o fphdlimp.o fpositer.o locdspnm.o \
 decNumber.o decContext.o alphaindex.o tznames.o tznames_impl.o tzgnames.o \
-tzfmt.o
+tzfmt.o gender.o
 
 ## Header files to install
 HEADERS = $(srcdir)/unicode/*.h
@@ -193,4 +193,3 @@ ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
 -include $(DEPS)
 endif
 endif
-
diff --git a/icu4c/source/i18n/gender.cpp b/icu4c/source/i18n/gender.cpp
new file mode 100644 (file)
index 0000000..051c345
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+*******************************************************************************
+* Copyright (C) 2008-2012, International Business Machines Corporation and
+* others. All Rights Reserved.
+*******************************************************************************
+*
+*
+* File GENDER.CPP
+*
+* Modification History:*
+*   Date        Name        Description
+*
+********************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/gender.h"
+#include "unicode/ugender.h"
+#include "unicode/ures.h"
+
+#include "cstring.h"
+#include "mutex.h"
+#include "ucln_in.h"
+#include "umutex.h"
+#include "uhash.h"
+
+static UHashtable* gGenderInfoCache = NULL;
+static UMTX gGenderMetaLock = NULL;
+static const char* gNeutralStr = "neutral";
+static const char* gMailTaintsStr = "maleTaints";
+static const char* gMixedNeutralStr = "mixedNeutral";
+static icu::GenderInfo* gObjs = NULL;
+
+enum GenderStyle {
+  NEUTRAL,
+  MIXED_NEUTRAL,
+  MALE_TAINTS,
+  GENDER_STYLE_LENGTH
+};
+
+U_CDECL_BEGIN
+
+static UBool U_CALLCONV gender_cleanup(void) {
+  umtx_destroy(&gGenderMetaLock);
+  if (gGenderInfoCache != NULL) {
+    uhash_close(gGenderInfoCache);
+    gGenderInfoCache = NULL;
+    delete [] gObjs;
+  }
+  return TRUE;
+}
+
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+GenderInfo::GenderInfo() {
+}
+
+GenderInfo::~GenderInfo() {
+}
+
+UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(GenderInfo)
+
+const GenderInfo* GenderInfo::getInstance(const Locale& locale, UErrorCode& status) {
+  if (U_FAILURE(status)) {
+    return NULL;
+  }
+
+  // Make sure our cache exists.
+  bool needed;
+  UMTX_CHECK(&gGenderMetaLock, (gGenderInfoCache == NULL), needed);
+  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;
+      }
+      ucln_i18n_registerCleanup(UCLN_I18N_GENDERINFO, gender_cleanup);
+    }
+  }
+
+  GenderInfo* result = NULL;
+  const char* key = locale.getName();
+  {
+    Mutex lock(&gGenderMetaLock);
+    result = (GenderInfo*) uhash_get(gGenderInfoCache, key);
+  }
+  if (result) {
+    return result;
+  }
+
+  // On cache miss, try to create GenderInfo from CLDR data
+  result = loadInstance(locale, status);
+
+  // Try to put our GenderInfo object in cache. If there is a race condition,
+  // favor the GenderInfo object that is already in the cache.
+  {
+    Mutex lock(&gGenderMetaLock);
+    GenderInfo* temp = (GenderInfo*) uhash_get(gGenderInfoCache, key);
+    if (temp) {
+      result = temp;
+    } else {
+      uhash_put(gGenderInfoCache, (void*) key, result, &status);
+      if (U_FAILURE(status)) {
+        return NULL;
+      }
+    }
+  }
+  return result;
+}
+
+GenderInfo* GenderInfo::loadInstance(const Locale& locale, UErrorCode& status) {
+  LocalUResourceBundlePointer rb(
+      ures_openDirect(NULL, "genderList", &status));
+  if (U_FAILURE(status)) {
+    return NULL;
+  }
+  LocalUResourceBundlePointer locRes(ures_getByKey(rb.getAlias(), "genderList", NULL, &status));
+  if (U_FAILURE(status)) {
+    return NULL;
+  }
+  int32_t resLen = 0;
+  const char* curLocaleName = locale.getName();
+  UErrorCode key_status = U_ZERO_ERROR;
+  const UChar* s = ures_getStringByKey(locRes.getAlias(), curLocaleName, &resLen, &key_status);
+  if (s == NULL) {
+    key_status = U_ZERO_ERROR;
+    char parentLocaleName[ULOC_FULLNAME_CAPACITY];
+    uprv_strcpy(parentLocaleName, curLocaleName);
+    while (s == NULL && uloc_getParent(parentLocaleName, parentLocaleName, ULOC_FULLNAME_CAPACITY, &key_status) > 0) {
+      key_status = U_ZERO_ERROR;
+      resLen = 0;
+      s = ures_getStringByKey(locRes.getAlias(), parentLocaleName, &resLen, &key_status);
+      key_status = U_ZERO_ERROR;
+    }
+  }
+  if (s == NULL) {
+    return &gObjs[NEUTRAL];
+  }
+  char type_str[256];
+  u_UCharsToChars(s, type_str, resLen + 1);
+  if (!uprv_strcmp(type_str, gNeutralStr)) {
+    return &gObjs[NEUTRAL];
+  }
+  if (!uprv_strcmp(type_str, gMixedNeutralStr)) {
+    return &gObjs[MIXED_NEUTRAL]; 
+  }
+  if (!uprv_strcmp(type_str, gMailTaintsStr)) {
+    return &gObjs[MALE_TAINTS];
+  }
+  return &gObjs[NEUTRAL];
+}
+
+UGender GenderInfo::getListGender(const UGender* genders, int32_t length, UErrorCode& status) const {
+  if (U_FAILURE(status)) {
+    return UGENDER_OTHER;
+  }
+  if (length == 0 || _style == NEUTRAL) {
+    return UGENDER_OTHER;
+  }
+  if (length == 1) {
+    return genders[0];
+  }
+  bool has_female = false;
+  bool has_male = false;
+  switch (_style) {
+    case MIXED_NEUTRAL:
+      for (int32_t i = 0; i < length; ++i) {
+        switch (genders[i]) {
+          case UGENDER_OTHER:
+            return UGENDER_OTHER;
+            break;
+          case UGENDER_FEMALE:
+            if (has_male) {
+              return UGENDER_OTHER;
+            }
+            has_female = true;
+            break;
+          case UGENDER_MALE:
+            if (has_female) {
+              return UGENDER_OTHER;
+            }
+            has_male = true;
+            break;
+          default:
+            break;
+        }
+      }
+      return has_male ? UGENDER_MALE : UGENDER_FEMALE;
+      break;
+    case MALE_TAINTS:
+      for (int32_t i = 0; i < length; ++i) {
+        if (genders[i] != UGENDER_FEMALE) {
+          return UGENDER_MALE;
+        }
+      }
+      return UGENDER_FEMALE;
+      break;
+    default:
+      return UGENDER_OTHER;
+      break;
+  }
+}
+
+const GenderInfo* GenderInfo::getNeutralInstance() {
+  return &gObjs[NEUTRAL];
+}
+
+const GenderInfo* GenderInfo::getMixedNeutralInstance() {
+  return &gObjs[MIXED_NEUTRAL];
+}
+
+const GenderInfo* GenderInfo::getMaleTaintsInstance() {
+  return &gObjs[MALE_TAINTS];
+}
+
+U_NAMESPACE_END
+
+U_DRAFT const UGenderInfo* U_EXPORT2
+ugender_getInstance(const char* locale, UErrorCode* status) {
+  return (UGenderInfo*) icu::GenderInfo::getInstance(icu::Locale::createFromName(locale), *status);
+}
+
+U_DRAFT UGender U_EXPORT2
+ugender_getListGender(const UGenderInfo* genderInfo, UGender* genders, int32_t size, UErrorCode* status) {
+  return ((const icu::GenderInfo *)genderInfo)->getListGender(genders, size, *status);
+}
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
index 152674c9933c8d6d78cc7fa8514ce6e45cdbb5d5..a8daca589d03b48a15aaf01611d24a8688219415 100644 (file)
@@ -50,6 +50,7 @@ typedef enum ECleanupI18NType {
     UCLN_I18N_CSDET,
     UCLN_I18N_COLL_DATA,
     UCLN_I18N_INDEX_CHARACTERS,
+    UCLN_I18N_GENDERINFO,
     UCLN_I18N_COUNT /* This must be last */
 } ECleanupI18NType;
 
diff --git a/icu4c/source/i18n/unicode/gender.h b/icu4c/source/i18n/unicode/gender.h
new file mode 100644 (file)
index 0000000..6732052
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+*******************************************************************************
+* Copyright (C) 2008-2012, International Business Machines Corporation and
+* others. All Rights Reserved.
+*******************************************************************************
+*
+*
+* File GENDER.H
+*
+* Modification History:*
+*   Date        Name        Description
+*
+********************************************************************************
+*/
+
+#ifndef _GENDER
+#define _GENDER
+
+#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"
+#include "unicode/ugender.h"
+#include "unicode/uobject.h"
+
+class GenderInfoTest;
+
+U_NAMESPACE_BEGIN
+
+class U_I18N_API GenderInfo : public UObject {
+public:
+
+    /**
+     * Provides access to the predefined GenderInfo object for a given
+     * locale.
+     *
+     * @param locale  The locale for which a <code>GenderInfo</code> object is
+     *                returned.
+     * @param status  Output param set to success/failure code on exit, which
+     *                must not indicate a failure before the function call.
+     * @return        The predefined <code>GenderInfo</code> object pointer for
+     *                this locale. The returned object is immutable, so it is
+     *                declared as const. Caller does not own the returned
+     *                pointer, so it must not attempt to free it.
+     * @draft ICU 50
+     */
+    static const GenderInfo* U_EXPORT2 getInstance(const Locale& locale, UErrorCode& status);
+
+    /**
+     * Determines the gender of a list as a whole given the gender of each
+     * of the elements.
+     * 
+     * @param genders the gender of each element in the list.
+     * @param length the length of gender array.
+     * @param status  Output param set to success/failure code on exit, which
+     *                must not indicate a failure before the function call.
+     * @return        the gender of the whole list.
+     * @draft ICU 50
+     */
+    UGender getListGender(const UGender* genders, int32_t length, UErrorCode& status) const;
+
+    /**
+     * Destructor.
+     *
+     * @draft ICU 50
+     * @internal
+     */
+    virtual ~GenderInfo();
+
+private:
+    int32_t _style;
+
+
+    /**
+     * 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&);
+
+    GenderInfo();
+
+    static const GenderInfo* getNeutralInstance();
+
+    static const GenderInfo* getMixedNeutralInstance();
+
+    static const GenderInfo* getMaleTaintsInstance();
+
+    static GenderInfo* loadInstance(const Locale& locale, UErrorCode& status);
+    friend class ::GenderInfoTest;
+};
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif // _GENDER
+//eof
diff --git a/icu4c/source/i18n/unicode/ugender.h b/icu4c/source/i18n/unicode/ugender.h
new file mode 100644 (file)
index 0000000..3071be8
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+*****************************************************************************************
+* Copyright (C) 2010-2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*****************************************************************************************
+*/
+
+#ifndef UGENDER_H
+#define UGENDER_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/localpointer.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.
+ *
+ */
+
+/**
+ * Genders
+ * @draft ICU 50
+ */
+enum UGender {
+    UGENDER_MALE,
+    UGENDER_FEMALE,
+    UGENDER_OTHER
+};
+/**
+ * @draft ICU 50
+ */
+typedef enum UGender UGender;
+
+/**
+ * Opaque UGenderInfo object for use in C programs.
+ * @draft ICU 50
+ */
+struct UGenderInfo;
+typedef struct UGenderInfo UGenderInfo;
+
+/**
+ * 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
+ */
+U_DRAFT const UGenderInfo* U_EXPORT2
+ugender_getInstance(const char *locale, UErrorCode *status);
+
+
+/**
+ * Given a list, returns the gender of the list as a whole.
+ * @param genderInfo pointer that ugender_getInstance returns.
+ * @param genders the gender of each element in the list.
+ * @param size the size of the list.
+ * @param status A pointer to a UErrorCode to receive any errors.
+ * @return The gender of the list.
+ * @draft ICU 50
+ */
+U_DRAFT UGender U_EXPORT2
+ugender_getListGender(const UGenderInfo* genderinfo, UGender *genders, int32_t size, UErrorCode *status);
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif
index b664c97b70c0cc0993ce849e24cfaaf51a8562d9..099f9e1929c04fd9f4b9d97041a0c97bd23dd029 100644 (file)
@@ -55,7 +55,7 @@ itrbnf.o itrbnfrt.o itrbnfp.o ucaconf.o icusvtst.o \
 uobjtest.o idnaref.o idnaconf.o nptrans.o punyref.o testidn.o testidna.o uts46test.o \
 incaltst.o calcasts.o v32test.o uvectest.o textfile.o tokiter.o utxttest.o \
 windttst.o winnmtst.o winutil.o csdetest.o tzrulets.o tzoffloc.o tzfmttst.o ssearch.o dtifmtts.o \
-tufmtts.o itspoof.o simplethread.o bidiconf.o locnmtst.o dcfmtest.o alphaindextst.o listformattertest.o
+tufmtts.o itspoof.o simplethread.o bidiconf.o locnmtst.o dcfmtest.o alphaindextst.o listformattertest.o genderinfotest.o
 
 DEPS = $(OBJECTS:.o=.d)
 
@@ -119,4 +119,3 @@ ifneq ($(patsubst %install,,$(MAKECMDGOALS)),)
 endif
 endif
 endif
-
diff --git a/icu4c/source/test/intltest/genderinfotest.cpp b/icu4c/source/test/intltest/genderinfotest.cpp
new file mode 100644 (file)
index 0000000..ce5b6c3
--- /dev/null
@@ -0,0 +1,157 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 1997-2012, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+/* Modification History:
+*/
+
+#include <stdlib.h>
+
+#include "intltest.h"
+#include "unicode/gender.h"
+#include "unicode/unum.h"
+
+#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
+
+UGender kSingleFemale[] = {UGENDER_FEMALE};
+UGender kSingleMale[] = {UGENDER_MALE};
+UGender kSingleOther[] = {UGENDER_OTHER};
+
+UGender kAllFemale[] = {UGENDER_FEMALE, UGENDER_FEMALE};
+UGender kAllMale[] = {UGENDER_MALE, UGENDER_MALE};
+UGender kAllOther[] = {UGENDER_OTHER, UGENDER_OTHER};
+
+UGender kFemaleMale[] = {UGENDER_FEMALE, UGENDER_MALE};
+UGender kFemaleOther[] = {UGENDER_FEMALE, UGENDER_OTHER};
+UGender kMaleOther[] = {UGENDER_MALE, UGENDER_OTHER};
+
+
+class GenderInfoTest : public IntlTest {
+public:
+    GenderInfoTest() {
+    }
+
+    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
+private:
+    void TestGetListGender();
+    void TestFallback();
+    void TestCApi();
+    void check(UGender expected_neutral, UGender expected_mixed, UGender expected_taints, const UGender* genderList, int32_t listSize);
+    void checkLocale(const Locale& locale, UGender expected, const UGender* genderList, int32_t listSize);
+};
+
+void GenderInfoTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *par) {
+  switch(index) {
+    case 0:
+      name = "TestGetListGender";
+      if (exec) {
+        TestGetListGender();
+      }
+      break;
+    case 1:
+      name = "TestFallback";
+      if (exec) {
+        TestFallback();
+      }
+      break;
+    case 2:
+      name = "TestCApi";
+      if (exec) {
+        TestCApi();
+      }
+      break;
+    default: name = ""; break;
+  }
+}
+
+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));
+    check(UGENDER_OTHER, UGENDER_MALE, UGENDER_MALE, kAllMale, LENGTHOF(kAllMale));
+    check(UGENDER_OTHER, UGENDER_OTHER, UGENDER_MALE, kAllOther, LENGTHOF(kAllOther));
+
+    check(UGENDER_OTHER, UGENDER_OTHER, UGENDER_MALE, kFemaleMale, LENGTHOF(kFemaleMale));
+    check(UGENDER_OTHER, UGENDER_OTHER, UGENDER_MALE, kFemaleOther, LENGTHOF(kFemaleOther));
+    check(UGENDER_OTHER, UGENDER_OTHER, UGENDER_MALE, kMaleOther, LENGTHOF(kMaleOther));
+}
+
+void GenderInfoTest::TestFallback() {
+  UErrorCode status = U_ZERO_ERROR;
+  const GenderInfo* actual = GenderInfo::getInstance(Locale::createFromName("xx"), status);
+  if (U_FAILURE(status)) {
+    errcheckln(status, "Fail to create GenderInfo - %s", u_errorName(status));
+    return;
+  }
+  const GenderInfo* expected = GenderInfo::getNeutralInstance();
+  if (expected != actual) {
+    errln("For Neutral, expected %d got %d", expected, actual);
+  }
+  actual = GenderInfo::getInstance(Locale::createFromName("fr_CA"), status);
+  if (U_FAILURE(status)) {
+    errcheckln(status, "Fail to create GenderInfo - %s", u_errorName(status));
+    return;
+  }
+  expected = GenderInfo::getMaleTaintsInstance();
+  if (expected != actual) {
+    errln("For Male Taints, Expected %d got %d", expected, actual);
+  }
+}
+
+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);
+    return;
+  }
+  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 listSize) {
+  checkLocale(Locale::getUS(), expected_neutral, genderList, listSize);
+  checkLocale(Locale::createFromName("is"), expected_mixed, genderList, listSize);
+  checkLocale(Locale::getFrench(), expected_taints, genderList, listSize);
+}
+
+void GenderInfoTest::checkLocale(
+    const Locale& locale, UGender expected, const UGender* genderList, int32_t listSize) {
+  UErrorCode status = U_ZERO_ERROR;
+  const GenderInfo* gi = GenderInfo::getInstance(locale, status);
+  if (U_FAILURE(status)) {
+    errcheckln(status, "Fail to create GenderInfo - %s", u_errorName(status));
+    return;
+  }
+  UGender actual = gi->getListGender(genderList, listSize, status);
+  if (U_FAILURE(status)) {
+    errcheckln(status, "Fail to get gender of list - %s", u_errorName(status));
+    return;
+  }
+  if (actual != expected) {
+    errln("For locale: %s expected: %d got %d", locale.getName(), expected, actual);
+  }
+}
+
+extern IntlTest *createGenderInfoTest() {
+  return new GenderInfoTest();
+}
index f1140db68c574ffcdbff81715ad24105878b0e43..54809d16db67f9c7d03f343bdfaf1432bc1ffc5f 100644 (file)
     <ClCompile Include="calregts.cpp" />\r
     <ClCompile Include="caltest.cpp" />\r
     <ClCompile Include="caltztst.cpp" />\r
+    <ClCompile Include="genderinfotest.cpp" />\r
     <ClCompile Include="dadrcal.cpp" />\r
     <ClCompile Include="dadrfmt.cpp" />\r
     <ClCompile Include="dcfmapts.cpp" />\r
index 5e9d38f98d1fbe316a1514dc0bf593611d48b499..a4018ffdc47e123ff0d7337e7296277cc1c607da 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "unicode/utypes.h"
+#include "unicode/localpointer.h"
 
 #if !UCONFIG_NO_FORMATTING
 
@@ -57,6 +58,8 @@
 #include "dcfmtest.h"       // DecimalFormatTest
 #include "listformattertest.h"  // ListFormatterTest
 
+extern IntlTest *createGenderInfoTest();
+
 #define TESTCLASS(id, TestClass)          \
     case id:                              \
         name = #TestClass;                \
@@ -133,7 +136,15 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam
         TESTCLASS(41,DecimalFormatTest);
 #endif
         TESTCLASS(42,ListFormatterTest);
-
+        case 43:
+          name = "GenderInfoTest";
+          if (exec) {
+            logln("GenderInfoTest test---");
+            logln((UnicodeString)"");
+            LocalPointer<IntlTest> test(createGenderInfoTest());
+            callTest(*test, par);
+          }
+          break;
         default: name = ""; break; //needed to end loop
     }
     if (exec) {