2 **********************************************************************
3 * Copyright (C) 1997-2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
9 * Modification History:
11 * Date Name Description
12 * 07/06/2001 Ram Creation.
13 ******************************************************************************
16 #include "unicode/uchar.h"
17 #include "unicode/uscript.h"
18 #include "unicode/uloc.h"
22 static const UScriptCode JAPANESE
[3] = { USCRIPT_KATAKANA
, USCRIPT_HIRAGANA
, USCRIPT_HAN
};
23 static const UScriptCode KOREAN
[2] = { USCRIPT_HANGUL
, USCRIPT_HAN
};
24 static const UScriptCode HAN_BOPO
[2] = { USCRIPT_HAN
, USCRIPT_BOPOMOFO
};
27 setCodes(const UScriptCode
*src
, int32_t length
,
28 UScriptCode
*dest
, int32_t capacity
, UErrorCode
*err
) {
30 if(U_FAILURE(*err
)) { return 0; }
31 if(length
> capacity
) {
32 *err
= U_BUFFER_OVERFLOW_ERROR
;
35 for(i
= 0; i
< length
; ++i
) {
42 setOneCode(UScriptCode script
, UScriptCode
*scripts
, int32_t capacity
, UErrorCode
*err
) {
43 if(U_FAILURE(*err
)) { return 0; }
45 *err
= U_BUFFER_OVERFLOW_ERROR
;
53 getCodesFromLocale(const char *locale
,
54 UScriptCode
*scripts
, int32_t capacity
, UErrorCode
*err
) {
55 UErrorCode internalErrorCode
= U_ZERO_ERROR
;
59 if(U_FAILURE(*err
)) { return 0; }
60 // Multi-script languages, equivalent to the LocaleScript data
61 // that we used to load from locale resource bundles.
62 /*length = */ uloc_getLanguage(locale
, lang
, UPRV_LENGTHOF(lang
), &internalErrorCode
);
63 if(U_FAILURE(internalErrorCode
) || internalErrorCode
== U_STRING_NOT_TERMINATED_WARNING
) {
66 if(0 == uprv_strcmp(lang
, "ja")) {
67 return setCodes(JAPANESE
, UPRV_LENGTHOF(JAPANESE
), scripts
, capacity
, err
);
69 if(0 == uprv_strcmp(lang
, "ko")) {
70 return setCodes(KOREAN
, UPRV_LENGTHOF(KOREAN
), scripts
, capacity
, err
);
72 scriptLength
= uloc_getScript(locale
, script
, UPRV_LENGTHOF(script
), &internalErrorCode
);
73 if(U_FAILURE(internalErrorCode
) || internalErrorCode
== U_STRING_NOT_TERMINATED_WARNING
) {
76 if(0 == uprv_strcmp(lang
, "zh") && 0 == uprv_strcmp(script
, "Hant")) {
77 return setCodes(HAN_BOPO
, UPRV_LENGTHOF(HAN_BOPO
), scripts
, capacity
, err
);
79 // Explicit script code.
80 if(scriptLength
!= 0) {
81 UScriptCode scriptCode
= (UScriptCode
)u_getPropertyValueEnum(UCHAR_SCRIPT
, script
);
82 if(scriptCode
!= USCRIPT_INVALID_CODE
) {
83 if(scriptCode
== USCRIPT_SIMPLIFIED_HAN
|| scriptCode
== USCRIPT_TRADITIONAL_HAN
) {
84 scriptCode
= USCRIPT_HAN
;
86 return setOneCode(scriptCode
, scripts
, capacity
, err
);
92 /* TODO: this is a bad API and should be deprecated, ticket #11141 */
93 U_CAPI
int32_t U_EXPORT2
94 uscript_getCode(const char* nameOrAbbrOrLocale
,
99 char likely
[ULOC_FULLNAME_CAPACITY
];
100 UErrorCode internalErrorCode
;
103 if(U_FAILURE(*err
)) {
106 if(nameOrAbbrOrLocale
==NULL
||
107 (fillIn
== NULL
? capacity
!= 0 : capacity
< 0)) {
108 *err
= U_ILLEGAL_ARGUMENT_ERROR
;
113 if(uprv_strchr(nameOrAbbrOrLocale
, '-')==NULL
&& uprv_strchr(nameOrAbbrOrLocale
, '_')==NULL
){
114 /* try long and abbreviated script names first */
115 UScriptCode code
= (UScriptCode
) u_getPropertyValueEnum(UCHAR_SCRIPT
, nameOrAbbrOrLocale
);
116 if(code
!=USCRIPT_INVALID_CODE
) {
117 return setOneCode(code
, fillIn
, capacity
, err
);
121 internalErrorCode
= U_ZERO_ERROR
;
122 length
= getCodesFromLocale(nameOrAbbrOrLocale
, fillIn
, capacity
, err
);
123 if(U_FAILURE(*err
) || length
!= 0) {
126 (void)uloc_addLikelySubtags(nameOrAbbrOrLocale
,
127 likely
, UPRV_LENGTHOF(likely
), &internalErrorCode
);
128 if(U_SUCCESS(internalErrorCode
) && internalErrorCode
!= U_STRING_NOT_TERMINATED_WARNING
) {
129 length
= getCodesFromLocale(likely
, fillIn
, capacity
, err
);
130 if(U_FAILURE(*err
) || length
!= 0) {
135 /* still not found .. try long and abbreviated script names again */
136 UScriptCode code
= (UScriptCode
) u_getPropertyValueEnum(UCHAR_SCRIPT
, nameOrAbbrOrLocale
);
137 if(code
!=USCRIPT_INVALID_CODE
) {
138 return setOneCode(code
, fillIn
, capacity
, err
);