Coverage Report

Created: 2025-06-13 06:34

/src/icu/icu4c/source/common/locresdata.cpp
Line
Count
Source (jump to first uncovered line)
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/*
4
*******************************************************************************
5
*
6
*   Copyright (C) 1997-2012, International Business Machines
7
*   Corporation and others.  All Rights Reserved.
8
*
9
*******************************************************************************
10
*   file name:  loclikely.cpp
11
*   encoding:   UTF-8
12
*   tab size:   8 (not used)
13
*   indentation:4
14
*
15
*   created on: 2010feb25
16
*   created by: Markus W. Scherer
17
*
18
*   Code for miscellaneous locale-related resource bundle data access,
19
*   separated out from other .cpp files
20
*   that then do not depend on resource bundle code and this data.
21
*/
22
23
#include "unicode/utypes.h"
24
#include "unicode/putil.h"
25
#include "unicode/uloc.h"
26
#include "unicode/ures.h"
27
#include "charstr.h"
28
#include "cstring.h"
29
#include "ulocimp.h"
30
#include "uresimp.h"
31
32
/*
33
 * Lookup a resource bundle table item with fallback on the table level.
34
 * Regular resource bundle lookups perform fallback to parent locale bundles
35
 * and eventually the root bundle, but only for top-level items.
36
 * This function takes the name of a top-level table and of an item in that table
37
 * and performs a lookup of both, falling back until a bundle contains a table
38
 * with this item.
39
 *
40
 * Note: Only the opening of entire bundles falls back through the default locale
41
 * before root. Once a bundle is open, item lookups do not go through the
42
 * default locale because that would result in a mix of languages that is
43
 * unpredictable to the programmer and most likely useless.
44
 */
45
U_CAPI const char16_t * U_EXPORT2
46
uloc_getTableStringWithFallback(const char *path, const char *locale,
47
                              const char *tableKey, const char *subTableKey,
48
                              const char *itemKey,
49
                              int32_t *pLength,
50
                              UErrorCode *pErrorCode)
51
0
{
52
0
    if (U_FAILURE(*pErrorCode)) { return nullptr; }
53
/*    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
54
0
    const char16_t *item=nullptr;
55
0
    UErrorCode errorCode;
56
57
    /*
58
     * open the bundle for the current locale
59
     * this falls back through the locale's chain to root
60
     */
61
0
    errorCode=U_ZERO_ERROR;
62
0
    icu::LocalUResourceBundlePointer rb(ures_open(path, locale, &errorCode));
63
64
0
    if(U_FAILURE(errorCode)) {
65
        /* total failure, not even root could be opened */
66
0
        *pErrorCode=errorCode;
67
0
        return nullptr;
68
0
    } else if(errorCode==U_USING_DEFAULT_WARNING ||
69
0
                (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING)
70
0
    ) {
71
        /* set the "strongest" error code (success->fallback->default->failure) */
72
0
        *pErrorCode=errorCode;
73
0
    }
74
75
0
    for(;;){
76
0
        icu::StackUResourceBundle table;
77
0
        icu::StackUResourceBundle subTable;
78
0
        ures_getByKeyWithFallback(rb.getAlias(), tableKey, table.getAlias(), &errorCode);
79
80
0
        if (subTableKey != nullptr) {
81
            /*
82
            ures_getByKeyWithFallback(table.getAlias(), subTableKey, subTable.getAlias(), &errorCode);
83
            item = ures_getStringByKeyWithFallback(subTable.getAlias(), itemKey, pLength, &errorCode);
84
            if(U_FAILURE(errorCode)){
85
                *pErrorCode = errorCode;
86
            }
87
            
88
            break;*/
89
            
90
0
            ures_getByKeyWithFallback(table.getAlias(), subTableKey, table.getAlias(), &errorCode);
91
0
        }
92
0
        if(U_SUCCESS(errorCode)){
93
0
            item = ures_getStringByKeyWithFallback(table.getAlias(), itemKey, pLength, &errorCode);
94
0
            if(U_FAILURE(errorCode)){
95
0
                const char* replacement = nullptr;
96
0
                *pErrorCode = errorCode; /*save the errorCode*/
97
0
                errorCode = U_ZERO_ERROR;
98
                /* may be a deprecated code */
99
0
                if(uprv_strcmp(tableKey, "Countries")==0){
100
0
                    replacement =  uloc_getCurrentCountryID(itemKey);
101
0
                }else if(uprv_strcmp(tableKey, "Languages")==0){
102
0
                    replacement =  uloc_getCurrentLanguageID(itemKey);
103
0
                }
104
                /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
105
0
                if(replacement!=nullptr && itemKey != replacement){
106
0
                    item = ures_getStringByKeyWithFallback(table.getAlias(), replacement, pLength, &errorCode);
107
0
                    if(U_SUCCESS(errorCode)){
108
0
                        *pErrorCode = errorCode;
109
0
                        break;
110
0
                    }
111
0
                }
112
0
            }else{
113
0
                break;
114
0
            }
115
0
        }
116
        
117
0
        if(U_FAILURE(errorCode)){    
118
119
            /* still can't figure out ?.. try the fallback mechanism */
120
0
            int32_t len = 0;
121
0
            const char16_t* fallbackLocale =  nullptr;
122
0
            *pErrorCode = errorCode;
123
0
            errorCode = U_ZERO_ERROR;
124
125
0
            fallbackLocale = ures_getStringByKeyWithFallback(table.getAlias(), "Fallback", &len, &errorCode);
126
0
            if(U_FAILURE(errorCode)){
127
0
               *pErrorCode = errorCode;
128
0
                break;
129
0
            }
130
131
0
            icu::CharString explicitFallbackName;
132
0
            explicitFallbackName.appendInvariantChars(fallbackLocale, len, errorCode);
133
134
            /* guard against recursive fallback */
135
0
            if (explicitFallbackName == locale) {
136
0
                *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
137
0
                break;
138
0
            }
139
0
            rb.adoptInstead(ures_open(path, explicitFallbackName.data(), &errorCode));
140
0
            if(U_FAILURE(errorCode)){
141
0
                *pErrorCode = errorCode;
142
0
                break;
143
0
            }
144
            /* succeeded in opening the fallback bundle .. continue and try to fetch the item */
145
0
        }else{
146
0
            break;
147
0
        }
148
0
    }
149
150
0
    return item;
151
0
}
152
153
namespace {
154
155
ULayoutType
156
_uloc_getOrientationHelper(const char* localeId,
157
                           const char* key,
158
                           UErrorCode& status)
159
0
{
160
0
    ULayoutType result = ULOC_LAYOUT_UNKNOWN;
161
162
0
    if (U_FAILURE(status)) { return result; }
163
164
0
    if (localeId == nullptr) {
165
0
        localeId = uloc_getDefault();
166
0
    }
167
0
    icu::CharString localeBuffer = ulocimp_canonicalize(localeId, status);
168
169
0
    if (U_FAILURE(status)) { return result; }
170
171
0
    int32_t length = 0;
172
0
    const char16_t* const value =
173
0
        uloc_getTableStringWithFallback(
174
0
            nullptr,
175
0
            localeBuffer.data(),
176
0
            "layout",
177
0
            nullptr,
178
0
            key,
179
0
            &length,
180
0
            &status);
181
182
0
    if (U_FAILURE(status)) { return result; }
183
184
0
    if (length != 0) {
185
0
        switch(value[0])
186
0
        {
187
0
        case 0x0062: /* 'b' */
188
0
            result = ULOC_LAYOUT_BTT;
189
0
            break;
190
0
        case 0x006C: /* 'l' */
191
0
            result = ULOC_LAYOUT_LTR;
192
0
            break;
193
0
        case 0x0072: /* 'r' */
194
0
            result = ULOC_LAYOUT_RTL;
195
0
            break;
196
0
        case 0x0074: /* 't' */
197
0
            result = ULOC_LAYOUT_TTB;
198
0
            break;
199
0
        default:
200
0
            status = U_INTERNAL_PROGRAM_ERROR;
201
0
            break;
202
0
        }
203
0
    }
204
205
0
    return result;
206
0
}
207
208
}  // namespace
209
210
U_CAPI ULayoutType U_EXPORT2
211
uloc_getCharacterOrientation(const char* localeId,
212
                             UErrorCode *status)
213
0
{
214
0
    return _uloc_getOrientationHelper(localeId, "characters", *status);
215
0
}
216
217
/**
218
 * Get the layout line orientation for the specified locale.
219
 * 
220
 * @param localeID locale name
221
 * @param status Error status
222
 * @return an enum indicating the layout orientation for lines.
223
 */
224
U_CAPI ULayoutType U_EXPORT2
225
uloc_getLineOrientation(const char* localeId,
226
                        UErrorCode *status)
227
0
{
228
0
    return _uloc_getOrientationHelper(localeId, "lines", *status);
229
0
}