aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/common/uresbund.cpp
diff options
context:
space:
mode:
authorromankoshelev <romankoshelev@yandex-team.com>2024-05-13 11:00:27 +0300
committerromankoshelev <romankoshelev@yandex-team.com>2024-05-13 11:13:05 +0300
commit5b22fadb0f035a3b82c328e0ae710ad2b92f6eac (patch)
treee15dc649c79c4fb78f35cd6694dfe9af9bfcc0ad /contrib/libs/icu/common/uresbund.cpp
parent5946aa7d3cbca62f6bcf074e8a2b9346e7a96af4 (diff)
downloadydb-5b22fadb0f035a3b82c328e0ae710ad2b92f6eac.tar.gz
Update ICU to 75.1
904da4ae1c86fc5542eac7f1cd18d97b72eb8517
Diffstat (limited to 'contrib/libs/icu/common/uresbund.cpp')
-rw-r--r--contrib/libs/icu/common/uresbund.cpp373
1 files changed, 242 insertions, 131 deletions
diff --git a/contrib/libs/icu/common/uresbund.cpp b/contrib/libs/icu/common/uresbund.cpp
index d02bba8921..ea4327b314 100644
--- a/contrib/libs/icu/common/uresbund.cpp
+++ b/contrib/libs/icu/common/uresbund.cpp
@@ -24,6 +24,7 @@
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/ucnv.h"
+#include "bytesinkutil.h"
#include "charstr.h"
#include "uresimp.h"
#include "ustr_imp.h"
@@ -93,8 +94,16 @@ static UBool chopLocale(char *name) {
static UBool hasVariant(const char* localeID) {
UErrorCode err = U_ZERO_ERROR;
- int32_t variantLength = uloc_getVariant(localeID, nullptr, 0, &err);
- return variantLength != 0;
+ CheckedArrayByteSink sink(nullptr, 0);
+ ulocimp_getSubtags(
+ localeID,
+ nullptr,
+ nullptr,
+ nullptr,
+ &sink,
+ nullptr,
+ err);
+ return sink.NumberOfBytesAppended() != 0;
}
// This file contains the tables for doing locale fallback, which are generated
@@ -208,17 +217,11 @@ static bool getParentLocaleID(char *name, const char *origName, UResOpenType ope
}
UErrorCode err = U_ZERO_ERROR;
- const char* tempNamePtr = name;
- CharString language = ulocimp_getLanguage(tempNamePtr, &tempNamePtr, err);
- if (*tempNamePtr == '_') {
- ++tempNamePtr;
- }
- CharString script = ulocimp_getScript(tempNamePtr, &tempNamePtr, err);
- if (*tempNamePtr == '_') {
- ++tempNamePtr;
- }
- CharString region = ulocimp_getCountry(tempNamePtr, &tempNamePtr, err);
- CharString workingLocale;
+ CharString language;
+ CharString script;
+ CharString region;
+ ulocimp_getSubtags(name, &language, &script, &region, nullptr, nullptr, err);
+
if (U_FAILURE(err)) {
// hopefully this never happens...
return chopLocale(name);
@@ -237,13 +240,15 @@ static bool getParentLocaleID(char *name, const char *origName, UResOpenType ope
}
}
+ CharString workingLocale;
+
// if it's not in the parent locale table, figure out the fallback script algorithmically
// (see CLDR-15265 for an explanation of the algorithm)
if (!script.isEmpty() && !region.isEmpty()) {
// if "name" has both script and region, is the script the default script?
// - if so, remove it and keep the region
// - if not, remove the region and keep the script
- if (getDefaultScript(language, region) == script.toStringPiece()) {
+ if (getDefaultScript(language, region) == script) {
workingLocale.append(language, err).append("_", err).append(region, err);
} else {
workingLocale.append(language, err).append("_", err).append(script, err);
@@ -253,12 +258,9 @@ static bool getParentLocaleID(char *name, const char *origName, UResOpenType ope
// - if yes, replace the region with the script from the original locale ID
// - if no, replace the region with the default script for that language and region
UErrorCode err = U_ZERO_ERROR;
- tempNamePtr = origName;
- CharString origNameLanguage = ulocimp_getLanguage(tempNamePtr, &tempNamePtr, err);
- if (*tempNamePtr == '_') {
- ++tempNamePtr;
- }
- CharString origNameScript = ulocimp_getScript(origName, nullptr, err);
+ CharString origNameLanguage;
+ CharString origNameScript;
+ ulocimp_getSubtags(origName, &origNameLanguage, &origNameScript, nullptr, nullptr, nullptr, err);
if (!origNameScript.isEmpty()) {
workingLocale.append(language, err).append("_", err).append(origNameScript, err);
} else {
@@ -271,7 +273,7 @@ static bool getParentLocaleID(char *name, const char *origName, UResOpenType ope
// - if not, return false to continue up the chain
// (we don't do this for other open types for the same reason we don't look things up in the parent
// locale table for other open types-- see the reference to UTS #35 above)
- if (openType != URES_OPEN_LOCALE_DEFAULT_ROOT || getDefaultScript(language, CharString()) == script.toStringPiece()) {
+ if (openType != URES_OPEN_LOCALE_DEFAULT_ROOT || getDefaultScript(language, CharString()) == script) {
workingLocale.append(language, err);
} else {
return false;
@@ -1707,7 +1709,7 @@ U_CAPI int32_t U_EXPORT2 ures_getSize(const UResourceBundle *resB) {
static const char16_t* ures_getStringWithAlias(const UResourceBundle *resB, Resource r, int32_t sIndex, int32_t *len, UErrorCode *status) {
if(RES_GET_TYPE(r) == URES_ALIAS) {
- const char16_t* result = 0;
+ const char16_t* result = nullptr;
UResourceBundle *tempRes = ures_getByIndex(resB, sIndex, nullptr, status);
result = ures_getString(tempRes, len, status);
ures_close(tempRes);
@@ -2351,7 +2353,66 @@ struct GetAllChildrenSink : public ResourceSink {
aliasedValue.setData(aliasRB->getResData());
aliasedValue.setValidLocaleDataEntry(aliasRB->fValidLocaleDataEntry);
aliasedValue.setResource(aliasRB->fRes, ResourceTracer(aliasRB));
- dest.put(key, aliasedValue, isRoot, errorCode);
+
+ if (aliasedValue.getType() != URES_TABLE) {
+ dest.put(key, aliasedValue, isRoot, errorCode);
+ } else {
+ // if the resource we're aliasing over to is a table, the sink might iterate over its contents.
+ // If it does, it'll get only the things defined in the actual alias target, not the things
+ // the target inherits from its parent resources. So we walk the parent chain for the *alias target*,
+ // calling dest.put() for each of the parent tables we could be inheriting from. This means
+ // that dest.put() has to iterate over the children of multiple tables to get all of the inherited
+ // resource values, but it already has to do that to handle normal vertical inheritance.
+ UResType aliasedValueType = URES_TABLE;
+ CharString tablePath;
+ tablePath.append(aliasRB->fResPath, errorCode);
+ const char* parentKey = key; // dest.put() changes the key
+ dest.put(parentKey, aliasedValue, isRoot, errorCode);
+ UResourceDataEntry* entry = aliasRB->fData;
+ Resource res = aliasRB->fRes;
+ while (aliasedValueType == URES_TABLE && entry->fParent != nullptr) {
+ CharString localPath;
+ localPath.copyFrom(tablePath, errorCode);
+ char* localPathAsCharPtr = localPath.data();
+ const char* childKey;
+ entry = entry->fParent;
+ res = entry->fData.rootRes;
+ Resource newRes = res_findResource(&entry->fData, res, &localPathAsCharPtr, &childKey);
+ if (newRes != RES_BOGUS) {
+ aliasedValue.setData(entry->fData);
+ // TODO: do I also need to call aliasedValue.setValueLocaleDataEntry() ?
+ aliasedValue.setResource(newRes, ResourceTracer(aliasRB)); // probably wrong to use aliasRB here
+ aliasedValueType = aliasedValue.getType();
+ if (aliasedValueType == URES_ALIAS) {
+ // in a few rare cases, when we get to the root resource bundle, the resource in question
+ // won't be an actual table, but will instead be an alias to a table. That is, we have
+ // two aliases in the inheritance path. (For some locales, such as Zulu, we see this with
+ // children of the "fields" resource: "day-narrow" aliases to "day-short", which aliases
+ // to "day".) When this happens, we need to make sure we follow all the aliases.
+ ResourceDataValue& rdv2 = static_cast<ResourceDataValue&>(aliasedValue);
+ aliasRB = getAliasTargetAsResourceBundle(rdv2.getData(), rdv2.getResource(), nullptr, -1,
+ rdv2.getValidLocaleDataEntry(), nullptr, 0,
+ stackTempBundle.getAlias(), &errorCode);
+ tablePath.clear();
+ tablePath.append(aliasRB->fResPath, errorCode);
+ entry = aliasRB->fData;
+ res = aliasRB->fRes;
+ aliasedValue.setData(entry->fData);
+ // TODO: do I also need to call aliasedValue.setValueLocaleDataEntry() ?
+ aliasedValue.setResource(res, ResourceTracer(aliasRB)); // probably wrong to use aliasRB here
+ aliasedValueType = aliasedValue.getType();
+ }
+ if (aliasedValueType == URES_TABLE) {
+ dest.put(parentKey, aliasedValue, isRoot, errorCode);
+ } else {
+ // once we've followed the alias, the resource we're looking at really should
+ // be a table
+ errorCode = U_INTERNAL_PROGRAM_ERROR;
+ return;
+ }
+ }
+ }
+ }
}
} else {
dest.put(key, value, isRoot, errorCode);
@@ -2513,7 +2574,7 @@ U_CAPI const char16_t* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB
return res_getString({resB, key}, &dataEntry->fData, res, len);
case URES_ALIAS:
{
- const char16_t* result = 0;
+ const char16_t* result = nullptr;
UResourceBundle *tempRes = ures_getByKey(resB, inKey, nullptr, status);
result = ures_getString(tempRes, len, status);
ures_close(tempRes);
@@ -2535,7 +2596,7 @@ U_CAPI const char16_t* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB
return res_getString({resB, key}, &resB->getResData(), res, len);
case URES_ALIAS:
{
- const char16_t* result = 0;
+ const char16_t* result = nullptr;
UResourceBundle *tempRes = ures_getByKey(resB, inKey, nullptr, status);
result = ures_getString(tempRes, len, status);
ures_close(tempRes);
@@ -2657,13 +2718,12 @@ ures_openWithType(UResourceBundle *r, const char* path, const char* localeID,
UResourceDataEntry *entry;
if(openType != URES_OPEN_DIRECT) {
/* first "canonicalize" the locale ID */
- char canonLocaleID[ULOC_FULLNAME_CAPACITY];
- uloc_getBaseName(localeID, canonLocaleID, UPRV_LENGTHOF(canonLocaleID), status);
- if(U_FAILURE(*status) || *status == U_STRING_NOT_TERMINATED_WARNING) {
+ CharString canonLocaleID = ulocimp_getBaseName(localeID, *status);
+ if(U_FAILURE(*status)) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
- entry = entryOpen(path, canonLocaleID, openType, status);
+ entry = entryOpen(path, canonLocaleID.data(), openType, status);
} else {
entry = entryOpenDirect(path, localeID, status);
}
@@ -2889,7 +2949,7 @@ ures_loc_nextLocale(UEnumeration* en,
UResourceBundle *k = nullptr;
const char *result = nullptr;
int32_t len = 0;
- if(ures_hasNext(res) && (k = ures_getNextResource(res, &ctx->curr, status)) != 0) {
+ if (ures_hasNext(res) && (k = ures_getNextResource(res, &ctx->curr, status)) != nullptr) {
result = ures_getKey(k);
len = (int32_t)uprv_strlen(result);
}
@@ -2974,44 +3034,66 @@ static UBool isLocaleInList(UEnumeration *locEnum, const char *locToSearch, UErr
return false;
}
+static void getParentForFunctionalEquivalent(const char* localeID,
+ UResourceBundle* res,
+ UResourceBundle* bund1,
+ CharString& parent) {
+ // Get parent.
+ // First check for a parent from %%Parent resource (Note that in resource trees
+ // such as collation, data may have different parents than in parentLocales).
+ UErrorCode subStatus = U_ZERO_ERROR;
+ parent.clear();
+ if (res != nullptr) {
+ ures_getByKey(res, "%%Parent", bund1, &subStatus);
+ if (U_SUCCESS(subStatus)) {
+ int32_t length16;
+ const char16_t* s16 = ures_getString(bund1, &length16, &subStatus);
+ parent.appendInvariantChars(s16, length16, subStatus);
+ }
+ }
+
+ // If none there, use normal truncation parent
+ if (U_FAILURE(subStatus) || parent.isEmpty()) {
+ subStatus = U_ZERO_ERROR;
+ parent = ulocimp_getParent(localeID, subStatus);
+ }
+}
+
U_CAPI int32_t U_EXPORT2
ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
const char *path, const char *resName, const char *keyword, const char *locid,
UBool *isAvailable, UBool omitDefault, UErrorCode *status)
{
- char kwVal[1024] = ""; /* value of keyword 'keyword' */
- char defVal[1024] = ""; /* default value for given locale */
- char defLoc[1024] = ""; /* default value for given locale */
- char base[1024] = ""; /* base locale */
- char found[1024] = "";
- char parent[1024] = "";
- char full[1024] = "";
+ CharString defVal; /* default value for given locale */
+ CharString defLoc; /* default value for given locale */
+ CharString found;
+ CharString parent;
+ CharString full;
UResourceBundle bund1, bund2;
UResourceBundle *res = nullptr;
UErrorCode subStatus = U_ZERO_ERROR;
int32_t length = 0;
if(U_FAILURE(*status)) return 0;
- uloc_getKeywordValue(locid, keyword, kwVal, 1024-1,&subStatus);
- if(!uprv_strcmp(kwVal, DEFAULT_TAG)) {
- kwVal[0]=0;
+ CharString kwVal = ulocimp_getKeywordValue(locid, keyword, subStatus);
+ if(kwVal == DEFAULT_TAG) {
+ kwVal.clear();
}
- uloc_getBaseName(locid, base, 1024-1,&subStatus);
+ CharString base = ulocimp_getBaseName(locid, subStatus);
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "getFunctionalEquivalent: \"%s\" [%s=%s] in %s - %s\n",
- locid, keyword, kwVal, base, u_errorName(subStatus));
+ locid, keyword, kwVal.data(), base.data(), u_errorName(subStatus));
#endif
ures_initStackObject(&bund1);
ures_initStackObject(&bund2);
-
-
- uprv_strcpy(parent, base);
- uprv_strcpy(found, base);
- if(isAvailable) {
+ parent.copyFrom(base, subStatus);
+ found.copyFrom(base, subStatus);
+
+ if(isAvailable) {
UEnumeration *locEnum = ures_openAvailableLocales(path, &subStatus);
*isAvailable = true;
if (U_SUCCESS(subStatus)) {
- *isAvailable = isLocaleInList(locEnum, parent, &subStatus);
+ *isAvailable = isLocaleInList(locEnum, parent.data(), &subStatus);
}
uenum_close(locEnum);
}
@@ -3023,7 +3105,7 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
do {
subStatus = U_ZERO_ERROR;
- res = ures_open(path, parent, &subStatus);
+ res = ures_open(path, parent.data(), &subStatus);
if(((subStatus == U_USING_FALLBACK_WARNING) ||
(subStatus == U_USING_DEFAULT_WARNING)) && isAvailable)
{
@@ -3032,7 +3114,7 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
isAvailable = nullptr; /* only want to set this the first time around */
#if defined(URES_TREE_DEBUG)
- fprintf(stderr, "%s;%s -> %s [%s]\n", path?path:"ICUDATA", parent, u_errorName(subStatus), ures_getLocale(res, &subStatus));
+ fprintf(stderr, "%s;%s -> %s [%s]\n", path?path:"ICUDATA", parent.data(), u_errorName(subStatus), ures_getLocale(res, &subStatus));
#endif
if(U_FAILURE(subStatus)) {
*status = subStatus;
@@ -3044,21 +3126,21 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
/* look for default item */
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s : loaded default -> %s\n",
- path?path:"ICUDATA", parent, u_errorName(subStatus));
+ path?path:"ICUDATA", parent.data(), u_errorName(subStatus));
#endif
defUstr = ures_getStringByKey(&bund1, DEFAULT_TAG, &defLen, &subStatus);
if(U_SUCCESS(subStatus) && defLen) {
- u_UCharsToChars(defUstr, defVal, u_strlen(defUstr));
+ defVal.clear().appendInvariantChars(defUstr, defLen, subStatus);
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> default %s=%s, %s\n",
- path?path:"ICUDATA", parent, keyword, defVal, u_errorName(subStatus));
+ path?path:"ICUDATA", parent.data(), keyword, defVal.data(), u_errorName(subStatus));
#endif
- uprv_strcpy(defLoc, parent);
- if(kwVal[0]==0) {
- uprv_strcpy(kwVal, defVal);
+ defLoc.copyFrom(parent, subStatus);
+ if(kwVal.isEmpty()) {
+ kwVal.append(defVal, subStatus);
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> kwVal = %s\n",
- path?path:"ICUDATA", parent, keyword, kwVal);
+ path?path:"ICUDATA", parent.data(), keyword, kwVal.data());
#endif
}
}
@@ -3068,20 +3150,23 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
subStatus = U_ZERO_ERROR;
if (res != nullptr) {
- uprv_strcpy(found, ures_getLocaleByType(res, ULOC_VALID_LOCALE, &subStatus));
+ found.clear().append(ures_getLocaleByType(res, ULOC_VALID_LOCALE, &subStatus), subStatus);
}
- uloc_getParent(found,parent,sizeof(parent),&subStatus);
+ if (found != parent) {
+ parent.copyFrom(found, subStatus);
+ } else {
+ getParentForFunctionalEquivalent(found.data(),res,&bund1,parent);
+ }
ures_close(res);
- } while(!defVal[0] && *found && uprv_strcmp(found, "root") != 0 && U_SUCCESS(*status));
+ } while(defVal.isEmpty() && !found.isEmpty() && found != "root" && U_SUCCESS(*status));
/* Now, see if we can find the kwVal collator.. start the search over.. */
- uprv_strcpy(parent, base);
- uprv_strcpy(found, base);
-
+ parent.copyFrom(base, subStatus);
+ found.copyFrom(base, subStatus);
+
do {
- subStatus = U_ZERO_ERROR;
- res = ures_open(path, parent, &subStatus);
+ res = ures_open(path, parent.data(), &subStatus);
if((subStatus == U_USING_FALLBACK_WARNING) && isAvailable) {
*isAvailable = false;
}
@@ -3089,7 +3174,7 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> %s (looking for %s)\n",
- path?path:"ICUDATA", parent, u_errorName(subStatus), kwVal);
+ path?path:"ICUDATA", parent.data(), u_errorName(subStatus), kwVal.data());
#endif
if(U_FAILURE(subStatus)) {
*status = subStatus;
@@ -3099,70 +3184,92 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
/**/ fprintf(stderr,"@%d [%s] %s\n", __LINE__, resName, u_errorName(subStatus));
#endif
if(subStatus == U_ZERO_ERROR) {
- ures_getByKey(&bund1, kwVal, &bund2, &subStatus);
+ ures_getByKey(&bund1, kwVal.data(), &bund2, &subStatus);
#if defined(URES_TREE_DEBUG)
-/**/ fprintf(stderr,"@%d [%s] %s\n", __LINE__, kwVal, u_errorName(subStatus));
+/**/ fprintf(stderr,"@%d [%s] %s\n", __LINE__, kwVal.data(), u_errorName(subStatus));
#endif
if(subStatus == U_ZERO_ERROR) {
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> full0 %s=%s, %s\n",
- path?path:"ICUDATA", parent, keyword, kwVal, u_errorName(subStatus));
+ path?path:"ICUDATA", parent.data(), keyword, kwVal.data(), u_errorName(subStatus));
#endif
- uprv_strcpy(full, parent);
- if(*full == 0) {
- uprv_strcpy(full, "root");
+ if (parent.isEmpty()) {
+ full.clear().append("root", subStatus);
+ } else {
+ full.copyFrom(parent, subStatus);
}
/* now, recalculate default kw if need be */
- if(uprv_strlen(defLoc) > uprv_strlen(full)) {
+ if(defLoc.length() > full.length()) {
const char16_t *defUstr;
int32_t defLen;
/* look for default item */
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> recalculating Default0\n",
- path?path:"ICUDATA", full);
+ path?path:"ICUDATA", full.data());
#endif
defUstr = ures_getStringByKey(&bund1, DEFAULT_TAG, &defLen, &subStatus);
if(U_SUCCESS(subStatus) && defLen) {
- u_UCharsToChars(defUstr, defVal, u_strlen(defUstr));
+ defVal.clear().appendInvariantChars(defUstr, defLen, subStatus);
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> default0 %s=%s, %s\n",
- path?path:"ICUDATA", full, keyword, defVal, u_errorName(subStatus));
+ path?path:"ICUDATA", full.data(), keyword, defVal.data(), u_errorName(subStatus));
#endif
- uprv_strcpy(defLoc, full);
+ defLoc.copyFrom(full, subStatus);
}
} /* end of recalculate default KW */
#if defined(URES_TREE_DEBUG)
else {
- fprintf(stderr, "No trim0, %s <= %s\n", defLoc, full);
+ fprintf(stderr, "No trim0, %s <= %s\n", defLoc.data(), full.data());
}
#endif
} else {
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "err=%s in %s looking for %s\n",
- u_errorName(subStatus), parent, kwVal);
+ u_errorName(subStatus), parent.data(), kwVal.data());
#endif
}
}
}
subStatus = U_ZERO_ERROR;
-
- uprv_strcpy(found, parent);
- uloc_getParent(found,parent,1023,&subStatus);
+ UBool haveFound = false;
+ // At least for collations which may be aliased, we need to use the VALID locale
+ // as the parent instead of just truncating, as long as the VALID locale is not
+ // root and has a different language than the parent. Use of the VALID locale
+ // here is similar to the procedure used at the end of the previous do-while loop
+ // for all resource types.
+ if (res != nullptr && uprv_strcmp(resName, "collations") == 0) {
+ const char *validLoc = ures_getLocaleByType(res, ULOC_VALID_LOCALE, &subStatus);
+ if (U_SUCCESS(subStatus) && validLoc != nullptr && validLoc[0] != 0 && uprv_strcmp(validLoc, "root") != 0) {
+ CharString validLang = ulocimp_getLanguage(validLoc, subStatus);
+ CharString parentLang = ulocimp_getLanguage(parent.data(), subStatus);
+ if (U_SUCCESS(subStatus) && validLang != parentLang) {
+ // validLoc is not root and has a different language than parent, use it instead
+ found.clear().append(validLoc, subStatus);
+ haveFound = true;
+ }
+ }
+ subStatus = U_ZERO_ERROR;
+ }
+ if (!haveFound) {
+ found.copyFrom(parent, subStatus);
+ }
+
+ getParentForFunctionalEquivalent(found.data(),res,&bund1,parent);
ures_close(res);
- } while(!full[0] && *found && U_SUCCESS(*status));
-
- if((full[0]==0) && uprv_strcmp(kwVal, defVal)) {
+ subStatus = U_ZERO_ERROR;
+ } while(full.isEmpty() && !found.isEmpty() && U_SUCCESS(*status));
+
+ if(full.isEmpty() && kwVal != defVal) {
#if defined(URES_TREE_DEBUG)
- fprintf(stderr, "Failed to locate kw %s - try default %s\n", kwVal, defVal);
+ fprintf(stderr, "Failed to locate kw %s - try default %s\n", kwVal.data(), defVal.data());
#endif
- uprv_strcpy(kwVal, defVal);
- uprv_strcpy(parent, base);
- uprv_strcpy(found, base);
-
+ kwVal.clear().append(defVal, subStatus);
+ parent.copyFrom(base, subStatus);
+ found.copyFrom(base, subStatus);
+
do { /* search for 'default' named item */
- subStatus = U_ZERO_ERROR;
- res = ures_open(path, parent, &subStatus);
+ res = ures_open(path, parent.data(), &subStatus);
if((subStatus == U_USING_FALLBACK_WARNING) && isAvailable) {
*isAvailable = false;
}
@@ -3170,91 +3277,95 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> %s (looking for default %s)\n",
- path?path:"ICUDATA", parent, u_errorName(subStatus), kwVal);
+ path?path:"ICUDATA", parent.data(), u_errorName(subStatus), kwVal.data());
#endif
if(U_FAILURE(subStatus)) {
*status = subStatus;
} else if(subStatus == U_ZERO_ERROR) {
ures_getByKey(res,resName,&bund1, &subStatus);
if(subStatus == U_ZERO_ERROR) {
- ures_getByKey(&bund1, kwVal, &bund2, &subStatus);
+ ures_getByKey(&bund1, kwVal.data(), &bund2, &subStatus);
if(subStatus == U_ZERO_ERROR) {
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> full1 %s=%s, %s\n", path?path:"ICUDATA",
- parent, keyword, kwVal, u_errorName(subStatus));
+ parent.data(), keyword, kwVal.data(), u_errorName(subStatus));
#endif
- uprv_strcpy(full, parent);
- if(*full == 0) {
- uprv_strcpy(full, "root");
+ if (parent.isEmpty()) {
+ full.clear().append("root", subStatus);
+ } else {
+ full.copyFrom(parent, subStatus);
}
/* now, recalculate default kw if need be */
- if(uprv_strlen(defLoc) > uprv_strlen(full)) {
+ if(defLoc.length() > full.length()) {
const char16_t *defUstr;
int32_t defLen;
/* look for default item */
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> recalculating Default1\n",
- path?path:"ICUDATA", full);
+ path?path:"ICUDATA", full.data());
#endif
defUstr = ures_getStringByKey(&bund1, DEFAULT_TAG, &defLen, &subStatus);
if(U_SUCCESS(subStatus) && defLen) {
- u_UCharsToChars(defUstr, defVal, u_strlen(defUstr));
+ defVal.clear().appendInvariantChars(defUstr, defLen, subStatus);
#if defined(URES_TREE_DEBUG)
fprintf(stderr, "%s;%s -> default %s=%s, %s\n",
- path?path:"ICUDATA", full, keyword, defVal, u_errorName(subStatus));
+ path?path:"ICUDATA", full.data(), keyword, defVal.data(), u_errorName(subStatus));
#endif
- uprv_strcpy(defLoc, full);
+ defLoc.copyFrom(full, subStatus);
}
} /* end of recalculate default KW */
#if defined(URES_TREE_DEBUG)
else {
- fprintf(stderr, "No trim1, %s <= %s\n", defLoc, full);
+ fprintf(stderr, "No trim1, %s <= %s\n", defLoc.data(), full.data());
}
#endif
}
}
}
- subStatus = U_ZERO_ERROR;
- uprv_strcpy(found, parent);
- uloc_getParent(found,parent,1023,&subStatus);
+ subStatus = U_ZERO_ERROR;
+ found.copyFrom(parent, subStatus);
+ getParentForFunctionalEquivalent(found.data(),res,&bund1,parent);
ures_close(res);
- } while(!full[0] && *found && U_SUCCESS(*status));
+ subStatus = U_ZERO_ERROR;
+ } while(full.isEmpty() && !found.isEmpty() && U_SUCCESS(*status));
}
if(U_SUCCESS(*status)) {
- if(!full[0]) {
+ if(full.isEmpty()) {
#if defined(URES_TREE_DEBUG)
- fprintf(stderr, "Still could not load keyword %s=%s\n", keyword, kwVal);
+ fprintf(stderr, "Still could not load keyword %s=%s\n", keyword, kwVal.data());
#endif
*status = U_MISSING_RESOURCE_ERROR;
} else if(omitDefault) {
#if defined(URES_TREE_DEBUG)
- fprintf(stderr,"Trim? full=%s, defLoc=%s, found=%s\n", full, defLoc, found);
+ fprintf(stderr,"Trim? full=%s, defLoc=%s, found=%s\n", full.data(), defLoc.data(), found.data());
#endif
- if(uprv_strlen(defLoc) <= uprv_strlen(full)) {
+ if(defLoc.length() <= full.length()) {
/* found the keyword in a *child* of where the default tag was present. */
- if(!uprv_strcmp(kwVal, defVal)) { /* if the requested kw is default, */
+ if(kwVal == defVal) { /* if the requested kw is default, */
/* and the default is in or in an ancestor of the current locale */
#if defined(URES_TREE_DEBUG)
- fprintf(stderr, "Removing unneeded var %s=%s\n", keyword, kwVal);
+ fprintf(stderr, "Removing unneeded var %s=%s\n", keyword, kwVal.data());
#endif
- kwVal[0]=0;
+ kwVal.clear();
}
}
}
- uprv_strcpy(found, full);
- if(kwVal[0]) {
- uprv_strcat(found, "@");
- uprv_strcat(found, keyword);
- uprv_strcat(found, "=");
- uprv_strcat(found, kwVal);
+ found.copyFrom(full, subStatus);
+ if(!kwVal.isEmpty()) {
+ found
+ .append("@", subStatus)
+ .append(keyword, subStatus)
+ .append("=", subStatus)
+ .append(kwVal, subStatus);
} else if(!omitDefault) {
- uprv_strcat(found, "@");
- uprv_strcat(found, keyword);
- uprv_strcat(found, "=");
- uprv_strcat(found, defVal);
+ found
+ .append("@", subStatus)
+ .append(keyword, subStatus)
+ .append("=", subStatus)
+ .append(defVal, subStatus);
}
}
/* we found the default locale - no need to repeat it.*/
@@ -3262,12 +3373,12 @@ ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
ures_close(&bund1);
ures_close(&bund2);
- length = (int32_t)uprv_strlen(found);
+ length = found.length();
if(U_SUCCESS(*status)) {
int32_t copyLength = uprv_min(length, resultCapacity);
if(copyLength>0) {
- uprv_strncpy(result, found, copyLength);
+ found.extract(result, copyLength, subStatus);
}
if(length == 0) {
*status = U_MISSING_RESOURCE_ERROR;
@@ -3310,8 +3421,8 @@ ures_getKeywordValues(const char *path, const char *keyword, UErrorCode *status)
valuesBuf[0]=0;
valuesBuf[1]=0;
-
- while((locale = uenum_next(locs, &locLen, status)) != 0) {
+
+ while ((locale = uenum_next(locs, &locLen, status)) != nullptr) {
UResourceBundle *bund = nullptr;
UResourceBundle *subPtr = nullptr;
UErrorCode subStatus = U_ZERO_ERROR; /* don't fail if a bundle is unopenable */
@@ -3335,8 +3446,8 @@ ures_getKeywordValues(const char *path, const char *keyword, UErrorCode *status)
bund = nullptr;
continue;
}
-
- while((subPtr = ures_getNextResource(&item,&subItem,&subStatus)) != 0
+
+ while ((subPtr = ures_getNextResource(&item, &subItem, &subStatus)) != nullptr
&& U_SUCCESS(subStatus)) {
const char *k;
int32_t i;