ICU-6434 ICU4C toLanguageTag/forLanguageTag implementation.

X-SVN-Rev: 25756
This commit is contained in:
Yoshito Umaoka 2009-04-10 22:30:39 +00:00
parent f4e2fd63ae
commit 6b1a0829a6
7 changed files with 2439 additions and 6 deletions

View file

@ -87,7 +87,7 @@ rbbi.o rbbidata.o rbbinode.o rbbirb.o rbbiscan.o rbbisetb.o rbbistbl.o rbbitblb.
serv.o servnotf.o servls.o servlk.o servlkf.o servrbf.o servslkf.o \
uidna.o usprep.o punycode.o \
util.o util_props.o parsepos.o locbased.o cwchar.o wintz.o mutex.o dtintrv.o ucnvsel.o propsvec.o \
ulist.o
ulist.o ultag.o
## Header files to install
HEADERS = $(srcdir)/unicode/*.h unicode/*.h

View file

@ -2677,6 +2677,14 @@
RelativePath=".\ulocimp.h"
>
</File>
<File
RelativePath=".\ultag.c"
>
</File>
<File
RelativePath=".\ultag.h"
>
</File>
<File
RelativePath=".\unicode\ures.h"
>

View file

@ -45,6 +45,7 @@
#include "uarrsort.h"
#include "uenumimp.h"
#include "uassert.h"
#include "ultag.h"
#include <stdio.h> /* for sprintf */
@ -4381,8 +4382,7 @@ uloc_forLanguageTag(const char* langtag,
int32_t* parsedLength,
UErrorCode* err)
{
/* TODO */
return 0;
return ultag_languageTagToLocale(langtag, localeID, localeIDCapacity, parsedLength, err);
}
U_DRAFT int32_t U_EXPORT2
@ -4392,8 +4392,7 @@ uloc_toLanguageTag(const char* localeID,
UBool strict,
UErrorCode* err)
{
/* TODO */
return 0;
return ultag_localeToLanguageTag(localeID, langtag, langtagCapacity, strict, err);
}
/*eof*/

2190
icu4c/source/common/ultag.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,74 @@
/*
**********************************************************************
* Copyright (C) 2009, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
#ifndef ULTAG_H
#define ULTAG_H
#include "unicode/utypes.h"
typedef struct ULanguageTag ULanguageTag;
U_CFUNC ULanguageTag*
ultag_parse(const char* tag, int32_t tagLen, int32_t* parsedLen, UErrorCode* status);
U_CFUNC void
ultag_close(ULanguageTag* langtag);
U_CFUNC const char*
ultag_getLanguage(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getJDKLanguage(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getExtlang(const ULanguageTag* langtag, int32_t idx);
U_CFUNC int32_t
ultag_getExtlangSize(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getScript(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getRegion(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getVariant(const ULanguageTag* langtag, int32_t idx);
U_CFUNC int32_t
ultag_getVariantsSize(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getExtensionKey(const ULanguageTag* langtag, int32_t idx);
U_CFUNC const char*
ultag_getExtensionValue(const ULanguageTag* langtag, int32_t idx);
U_CFUNC int32_t
ultag_getExtensionsSize(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getPrivateUse(const ULanguageTag* langtag);
U_CFUNC const char*
ultag_getGrandfathered(const ULanguageTag* langtag);
U_CFUNC int32_t
ultag_languageTagToLocale(const char* langtag,
char* localeID,
int32_t localeIDCapacity,
int32_t* parsedLength,
UErrorCode* status);
U_CFUNC int32_t
ultag_localeToLanguageTag(const char* localeID,
char* langtag,
int32_t langtagCapacity,
UBool strict,
UErrorCode* status);
#endif /* ULTAG_H */

View file

@ -233,6 +233,8 @@ void addLocaleTest(TestNode** root)
TESTCASE(TestGetLocaleForLCID);
TESTCASE(TestOrientation);
TESTCASE(TestLikelySubtags);
TESTCASE(TestToLanguageTag);
TESTCASE(TestForLanguageTag);
}
@ -5343,3 +5345,158 @@ static void TestLikelySubtags()
}
}
}
const char* const locale_to_langtag[][3] = {
{"", "und", "und"},
{"en", "en", "en"},
{"en_US", "en-us", "en-us"},
{"iw_IL", "he-il", "he-il"},
{"sr_Latn_SR", "sr-latn-sr", "sr-latn-sr"},
{"en__POSIX", "en-posix", "en-posix"},
{"en_POSIX", "en", NULL},
{"und_555", "und-555", "und-555"},
{"123", "und", NULL},
{"%$#&", "und", NULL},
{"_Latn", "und-latn", "und-latn"},
{"_DE", "und-de", "und-de"},
{"und_FR", "und-fr", "und-fr"},
{"th_TH_TH", "th-th", NULL},
{"bogus", "bogus", "bogus"},
{"foooobarrr", "und", NULL},
{"az_AZ_CYRL", "az-cyrl-az", "az-cyrl-az"},
{"aa_BB_CYRL", "aa-bb", NULL},
{"en_US_1234", "en-us-1234", "en-us-1234"},
{"en_US_VARIANTA_VARIANTB", "en-us-varianta-variantb", "en-us-varianta-variantb"},
{"en_US_VARIANTB_VARIANTA", "en-us-varianta-variantb", "en-us-varianta-variantb"},
{"ja__9876_5432", "ja-5432-9876", "ja-5432-9876"},
{"zh_Hant__VAR", "zh-hant", NULL},
{"es__BADVARIANT_GOODVAR", "es-goodvar", NULL},
{"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
{"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
{"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"},
{"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
{"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL},
{"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-ks-identic", NULL},
{NULL, NULL, NULL}
};
static void TestToLanguageTag(void) {
char langtag[256];
int32_t i;
UErrorCode status;
int32_t len;
const char *inloc;
const char *expected;
for (i = 0; locale_to_langtag[i][0] != NULL; i++) {
inloc = locale_to_langtag[i][0];
/* testing non-strict mode */
status = U_ZERO_ERROR;
langtag[0] = 0;
expected = locale_to_langtag[i][1];
len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), FALSE, &status);
if (U_FAILURE(status)) {
if (expected != NULL) {
log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
inloc, u_errorName(status));
}
} else {
if (expected == NULL) {
log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
inloc, langtag);
} else if (uprv_strcmp(langtag, expected) != 0) {
log_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]\n",
langtag, inloc, expected);
}
}
/* testing strict mode */
status = U_ZERO_ERROR;
langtag[0] = 0;
expected = locale_to_langtag[i][2];
len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), TRUE, &status);
if (U_FAILURE(status)) {
if (expected != NULL) {
log_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s\n",
inloc, u_errorName(status));
}
} else {
if (expected == NULL) {
log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
inloc, langtag);
} else if (uprv_strcmp(langtag, expected) != 0) {
log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
langtag, inloc, expected);
}
}
}
}
static const struct {
const char *bcpID;
const char *locID;
int32_t len;
} langtag_to_locale[] = {
{"en", "en", 2},
{"en-us", "en_US", 5},
{"und-us", "_US", 6},
{"und-latn", "_Latn", 8},
{"en-us-posix", "en_US_POSIX", 11},
{"de-de_euro", "de", 2},
{"kok-in", "kok_IN", 6},
{"123", "", 0},
{"en_us", "", 0},
{"en-latn-x", "en_Latn", 7},
{"art-lojban", "jbo", 10},
{"zh-hakka", "hak", 8},
{"xxx-yy", "xxx_YY", 6},
{"fr-234", "fr_234", 6},
{"i-default", "", 9},
{"i-test", "", 0},
{"ja-jp-jp", "ja_JP", 5},
{"bogus", "bogus", 5},
{"boguslang", "", 0},
{"EN-lATN-us", "en_Latn_US", 10},
{"und-variant-1234", "__1234_VARIANT", 16},
{"und-varzero-var1-vartwo", "__VARZERO", 11},
{"en-u-ca-gregory", "en@calendar=gregorian", 15},
{"en-U-cu-USD", "en@currency=usd", 11},
{"ar-x-1-2-3", "ar@x=1-2-3", 10},
{"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", 19},
{"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", 30},
{"ja-u-cu-jpy-ca-jp", "ja@currency=jpy", 11},
{"en-us-u-tz-usnyc", "en_US@timezone=america/new_york", 16},
{"und-a-abc-def", "und@a=abc-def", 13},
{"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", 30},
{NULL, NULL, 0}
};
static void TestForLanguageTag(void) {
char locale[256];
int32_t i;
UErrorCode status;
int32_t parsedLen;
for (i = 0; langtag_to_locale[i].bcpID != NULL; i++) {
status = U_ZERO_ERROR;
locale[0] = 0;
uloc_forLanguageTag(langtag_to_locale[i].bcpID, locale, sizeof(locale), &parsedLen, &status);
if (U_FAILURE(status)) {
log_err("Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
langtag_to_locale[i].bcpID, u_errorName(status));
} else {
if (uprv_strcmp(langtag_to_locale[i].locID, locale) != 0) {
log_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
locale, langtag_to_locale[i].bcpID, langtag_to_locale[i].locID);
}
if (parsedLen != langtag_to_locale[i].len) {
log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
parsedLen, langtag_to_locale[i].bcpID, langtag_to_locale[i].len);
}
}
}
}

View file

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2008, International Business Machines Corporation and
* Copyright (c) 1997-2009, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/********************************************************************************
@ -115,4 +115,9 @@ static void TestOrientation(void);
static void TestLikelySubtags(void);
/**
* lanuage tag
*/
static void TestForLanguageTag(void);
static void TestToLanguageTag(void);
#endif