Line data Source code
1 : // © 2016 and later: Unicode, Inc. and others.
2 : // License & terms of use: http://www.unicode.org/copyright.html
3 : /*
4 : **********************************************************************
5 : * Copyright (C) 1997-2014, International Business Machines
6 : * Corporation and others. All Rights Reserved.
7 : **********************************************************************
8 : *
9 : * File USCRIPT.C
10 : *
11 : * Modification History:
12 : *
13 : * Date Name Description
14 : * 07/06/2001 Ram Creation.
15 : ******************************************************************************
16 : */
17 :
18 : #include "unicode/uchar.h"
19 : #include "unicode/uscript.h"
20 : #include "unicode/uloc.h"
21 : #include "cmemory.h"
22 : #include "cstring.h"
23 :
24 : static const UScriptCode JAPANESE[3] = { USCRIPT_KATAKANA, USCRIPT_HIRAGANA, USCRIPT_HAN };
25 : static const UScriptCode KOREAN[2] = { USCRIPT_HANGUL, USCRIPT_HAN };
26 : static const UScriptCode HAN_BOPO[2] = { USCRIPT_HAN, USCRIPT_BOPOMOFO };
27 :
28 : static int32_t
29 0 : setCodes(const UScriptCode *src, int32_t length,
30 : UScriptCode *dest, int32_t capacity, UErrorCode *err) {
31 : int32_t i;
32 0 : if(U_FAILURE(*err)) { return 0; }
33 0 : if(length > capacity) {
34 0 : *err = U_BUFFER_OVERFLOW_ERROR;
35 0 : return length;
36 : }
37 0 : for(i = 0; i < length; ++i) {
38 0 : dest[i] = src[i];
39 : }
40 0 : return length;
41 : }
42 :
43 : static int32_t
44 0 : setOneCode(UScriptCode script, UScriptCode *scripts, int32_t capacity, UErrorCode *err) {
45 0 : if(U_FAILURE(*err)) { return 0; }
46 0 : if(1 > capacity) {
47 0 : *err = U_BUFFER_OVERFLOW_ERROR;
48 0 : return 1;
49 : }
50 0 : scripts[0] = script;
51 0 : return 1;
52 : }
53 :
54 : static int32_t
55 0 : getCodesFromLocale(const char *locale,
56 : UScriptCode *scripts, int32_t capacity, UErrorCode *err) {
57 0 : UErrorCode internalErrorCode = U_ZERO_ERROR;
58 : char lang[8];
59 : char script[8];
60 : int32_t scriptLength;
61 0 : if(U_FAILURE(*err)) { return 0; }
62 : // Multi-script languages, equivalent to the LocaleScript data
63 : // that we used to load from locale resource bundles.
64 0 : /*length = */ uloc_getLanguage(locale, lang, UPRV_LENGTHOF(lang), &internalErrorCode);
65 0 : if(U_FAILURE(internalErrorCode) || internalErrorCode == U_STRING_NOT_TERMINATED_WARNING) {
66 0 : return 0;
67 : }
68 0 : if(0 == uprv_strcmp(lang, "ja")) {
69 0 : return setCodes(JAPANESE, UPRV_LENGTHOF(JAPANESE), scripts, capacity, err);
70 : }
71 0 : if(0 == uprv_strcmp(lang, "ko")) {
72 0 : return setCodes(KOREAN, UPRV_LENGTHOF(KOREAN), scripts, capacity, err);
73 : }
74 0 : scriptLength = uloc_getScript(locale, script, UPRV_LENGTHOF(script), &internalErrorCode);
75 0 : if(U_FAILURE(internalErrorCode) || internalErrorCode == U_STRING_NOT_TERMINATED_WARNING) {
76 0 : return 0;
77 : }
78 0 : if(0 == uprv_strcmp(lang, "zh") && 0 == uprv_strcmp(script, "Hant")) {
79 0 : return setCodes(HAN_BOPO, UPRV_LENGTHOF(HAN_BOPO), scripts, capacity, err);
80 : }
81 : // Explicit script code.
82 0 : if(scriptLength != 0) {
83 0 : UScriptCode scriptCode = (UScriptCode)u_getPropertyValueEnum(UCHAR_SCRIPT, script);
84 0 : if(scriptCode != USCRIPT_INVALID_CODE) {
85 0 : if(scriptCode == USCRIPT_SIMPLIFIED_HAN || scriptCode == USCRIPT_TRADITIONAL_HAN) {
86 0 : scriptCode = USCRIPT_HAN;
87 : }
88 0 : return setOneCode(scriptCode, scripts, capacity, err);
89 : }
90 : }
91 0 : return 0;
92 : }
93 :
94 : /* TODO: this is a bad API and should be deprecated, ticket #11141 */
95 : U_CAPI int32_t U_EXPORT2
96 0 : uscript_getCode(const char* nameOrAbbrOrLocale,
97 : UScriptCode* fillIn,
98 : int32_t capacity,
99 : UErrorCode* err){
100 : UBool triedCode;
101 : char likely[ULOC_FULLNAME_CAPACITY];
102 : UErrorCode internalErrorCode;
103 : int32_t length;
104 :
105 0 : if(U_FAILURE(*err)) {
106 0 : return 0;
107 : }
108 0 : if(nameOrAbbrOrLocale==NULL ||
109 0 : (fillIn == NULL ? capacity != 0 : capacity < 0)) {
110 0 : *err = U_ILLEGAL_ARGUMENT_ERROR;
111 0 : return 0;
112 : }
113 :
114 0 : triedCode = FALSE;
115 0 : if(uprv_strchr(nameOrAbbrOrLocale, '-')==NULL && uprv_strchr(nameOrAbbrOrLocale, '_')==NULL ){
116 : /* try long and abbreviated script names first */
117 0 : UScriptCode code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT, nameOrAbbrOrLocale);
118 0 : if(code!=USCRIPT_INVALID_CODE) {
119 0 : return setOneCode(code, fillIn, capacity, err);
120 : }
121 0 : triedCode = TRUE;
122 : }
123 0 : internalErrorCode = U_ZERO_ERROR;
124 0 : length = getCodesFromLocale(nameOrAbbrOrLocale, fillIn, capacity, err);
125 0 : if(U_FAILURE(*err) || length != 0) {
126 0 : return length;
127 : }
128 : (void)uloc_addLikelySubtags(nameOrAbbrOrLocale,
129 0 : likely, UPRV_LENGTHOF(likely), &internalErrorCode);
130 0 : if(U_SUCCESS(internalErrorCode) && internalErrorCode != U_STRING_NOT_TERMINATED_WARNING) {
131 0 : length = getCodesFromLocale(likely, fillIn, capacity, err);
132 0 : if(U_FAILURE(*err) || length != 0) {
133 0 : return length;
134 : }
135 : }
136 0 : if(!triedCode) {
137 : /* still not found .. try long and abbreviated script names again */
138 0 : UScriptCode code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT, nameOrAbbrOrLocale);
139 0 : if(code!=USCRIPT_INVALID_CODE) {
140 0 : return setOneCode(code, fillIn, capacity, err);
141 : }
142 : }
143 0 : return 0;
144 : }
|