diff --git a/ChangeLog b/ChangeLog index b84375127..fe12562cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-31 Stefan Bidigaray + + * Resources/GNUmakefile: + * Resources/Languages/Locale.canonical: Added mapping to go from long + locale identifiers to short identifiers used by ICU. + * Source/NSLocale.m: Implemented -canonical* and -preferredLanaguges methods. + 2010-12-31 14:03 David Chisnall * libs/base/trunk/Headers/Foundation/NSBundle.h: Add __attribute__ diff --git a/Resources/GNUmakefile b/Resources/GNUmakefile index 9763adf02..7e440708e 100644 --- a/Resources/GNUmakefile +++ b/Resources/GNUmakefile @@ -74,7 +74,7 @@ Languages/Ukrainian \ Languages/Esperanto \ Languages/Korean LANGUAGE_INSTALL_FILES = $(LANGUAGE_FILES) Languages/Locale.aliases \ - Languages/Locale.encodings + Languages/Locale.encodings Languages/Locale.canonical include $(GNUSTEP_MAKEFILES)/resource-set.make diff --git a/Resources/Languages/Locale.canonical b/Resources/Languages/Locale.canonical new file mode 100644 index 000000000..f4093f40e --- /dev/null +++ b/Resources/Languages/Locale.canonical @@ -0,0 +1,391 @@ +{ + Abkhazian = ab; + Achinese = ace; + Acoli = ach; + Adangme = ada; + Adyghe = ady; + Afar = aa; + Afrikaans = af; + Akan = ak; + Albanian = sq; + AlgeriaArabic = ar_DZ; + AmericanEnglish = en_US; + Amharic = am; + Angika = anp; + Arabic = ar; + Aragonese = an; + ArgentinaSpanish = es_AR; + Armenian = hy; + Aromanian = rup; + Assamese = as; + Asturian = ast; + AustraliaEnglish = en_AU; + AustriaGerman = de_AT; + Avaric = av; + Awadhi = awa; + Aymara = ay; + Azerbaijani = az; /* -Cyrl, or -Latn ?*/ + BahrainArabic = ar_BH; + Balinese = ban; + Baluchi = bal; + Bambara = bm; + BangladeshBengali = bn_BD; + Basa = bas; + Bashkir = ba; + Basque = eu; + Beja = bej; + Belarusian = be; + BelgiumDutch = nl_BE; + BelgiumFrench = fr_BE; + BelgiumGerman = de_BE; + Bemba = bem; + Bengali = bn; + Bhojpuri = bho; + Bhutani = dz; + Bihari = bh; + Bikol = bik; + Bini = bin; + Bislama = bi; + Blin = byn; + BoliviaSpanish = es_BO; + Bosnian = bs; + BotswanaEnglish = en_BW; + BrasilPortuguese = pt_BR; + Breton = br; + BritainEnglish = en_GB; + Buginese = bug; + Bulgarian = bg; + Buriat = bua; + Burmese = my; + Cambodian = km; + CanadaEnglish = en_CA; + CanadaFrench = fr_CA; + Catalan = ca; + Cebuano = ceb; + Chamorro = ch; + Chechen = ce; + Chichewa = ny; + ChileSpanish = es_CL; + Chinese = zh; + ChurchSlavic = cu; + Chuvash = cv; + ColombiaSpanish = es_CO; + Cornish = kw; + Corsican = co; + CostaRicaSpanish = es_CR; + Cree = cr; + CrimeanTatar = crh; + Croatian = hr; + Czech = cs; + Danish = da; + Dargwa = dar; + DenmarkEnglish = en_DK; + Dinka = din; + DjiboutiAfar = aa_DJ; + DjiboutiSomali = so_DJ; + Dogri = doi; + DominicanRepublicSpanish = es_DO; + Dutch = nl; + Dyula = dyu; + EcuadorSpanish = es_EC; + Efik = efi; + EgyptArabic = ar_EG; + ElSalvadorSpanish = es_SV; + English = en; + EritreaAfar = aa_ER; + EritreaGeez = gez_ER; + EritreaTigrinya = ti_ER; + Erzya = myv; + Esperanto = eo; + EstoniaEstonian = et_EE; + Estonian = et; + EthiopiaAfar = aa_ET; + EthiopiaGeez = gez_ET; + EthiopiaOromo = om_ET; + EthiopiaSomali = so_ET; + EthiopiaTigrinya = ti_ET; + Ewondo = ewo; + Fang = fan; + Faroese = fo; + Fijian = fj; + Filipino = fil; + FinlandSwedish = sv_FI; + Finnish = fi; + Fon = fon; + French = fr; + Friulian = fur; + Fulah = ff; + Ga = gaa; + Gaelic = gd; + Gallegan = gl; + Ganda = lg; + Gayo = gay; + Gbaya = gba; + Geez = gez; + Georgian = ka; + German = de; + Gondi = gon; + Gorontalo = gor; + Grebo = grb; + GreeceGreek = el_GR; + Greek = el; + Greenlandic = kl; + Guarani = gn; + GuatemalaSpanish = es_GT; + Gujarati = gu; + Haitian = ht; + Hausa = ha-Latn; + Hebrew = he; + Hebrew = iw; + Herero = hz; + Hiligaynon = hil; + Hindi = hi; + HiriMotu = ho; + Hmong = hmn; + HondurasSpanish = es_HN; + HongKongChinese = zh-Hant_HK; + HongKongEnglish = en_HK; + Hungarian = hu; + Iban = iba; + Icelandic = is; + Ido = io; + Igbo = ig; + Iloko = ilo; + IndiaArabic = ar_IN; + IndiaBengali = bn_IN; + IndiaEnglish = en_IN; + Indonesian = id; + Ingush = inh; + Interlingua = ia; + Interlingue = ie; + Inuktitut = iu; + Inupiak = ik; + IraqArabic = ar_IQ; + IrelandEnglish = en_IE; + Irish = ga; + Italian = it; + Japanese = ja; + Javanese = jv; + JordanArabic = ar_JO; + Kabardian = kbd; + Kabyle = kab; + Kachin = kac; + Kalmyk = xal; + Kamba = kam; + Kannada = kn; + Kanuri = kr; + KarachayBalkar = krc; + KaraKalpak = kaa; + Karelian = krl; + Kashmiri = ks; + Kazakh = kk-Cyrl; + KenyaOromo = om_KE; + KenyaSomali = so_KE; + Khasi = kha; + Kikuyu = ki; + Kimbundu = kmb; + Kinyarwanda = rw; + Kirghiz = ky; + Komi = kv; + Kongo = kg; + Korean = ko; + Kumyk = kum; + Kurdish = ku; + Kurukh = kru; + KuwaitArabic = ar_KW; + Kwanyama = kj; + Ladino = lad; + Lamba = lam; + Lao = lo; + Latin = la; + Latvian = lv; + LebanonArabic = ar_LB; + Lezghian = lez; + LibyaArabic = ar_LY; + Limburgish = li; + Lingala = ln; + Lithuanian = lt; + Lozi = loz; + LubaKatanga = lu; + LubaLulua = lua; + Luganda = lug; + Lunda = lun; + Luo = luo; + Lushai = lus; + Luxembourgish = lb; + LuxemburgFrench = fr_LU; + LuxemburgGerman = de_LU; + Macedonian = mk; + Madurese = mad; + Magahi = mag; + Maithili = mai; + Makasar = mak; + Malagasy = mg; + Malay = ms; + Malayalam = ml; + Maldivian = dv; + Maltese = mt; + Mandar = mdr; + Mandingo = man; + Manipuri = mni; + Manx = gv; + Maori = mi; + Mapudungun = arn; + Marathi = mr; + Mari = chm; + Marshallese = mh; + Masai = mas; + Mende = men; + MexicoSpanish = es_MX; + Minangkabau = min; + Moksha = mdf; + Moldavian = mo; + Mongo = lol; + Mongolian = mn; + MoroccoArabic = ar_MA; + Mossi = mos; + Nauru = na; + Navajo = nv; + NdebeleNorth = nd; + NdebeleSouth = nr; + Ndonga = ng; + Neapolitan = nap; + NepalBhasa = new; + Nepali = ne; + NetherlandsDutch = nl_NL; + NewZealandEnglish = en_NZ; + Nias = nia; + NicaraguaSpanish = es_NI; + NorthernSaami = se; + Norwegian = no; + NorwegianBokmal = nb; + NorwegianNynorsk = nn; + Nyamwezi = nym; + Nyankole = nyn; + Nyoro = nyo; + Nzima = nzi; + Occitan = oc; + Ojibwa = oj; + OmanArabic = ar_OM; + Oriya = or; + Oromo = om; + Ossetian = os; + Pali = pi; + Pampanga = pam; + PanamaSpanish = es_PA; + Pangasinan = pag; + Papiamento = pap; + ParaguaySpanish = es_PY; + Pashto = ps; + Pedi = nso; + Persian = fa; + PeruSpanish = es_PE; + PhilippinesEnglish = en_PH; + Polish = pl; + Portuguese = pt; + PuertoRicoSpanish = es_PR; + Punjabi = pa; /* -Arab, or -Guru ?*/ + QatarArabic = ar_QA; + Quechua = qu; + Rajasthani = raj; + Romanian = ro; + Romansh = rm; + Rundi = rn; + Russian = ru; + Samoan = sm; + Sango = sg; + Sanskrit = sa; + Santali = sat; + Sardinian = sc; + Sasak = sas; + SaudiArabiaArabic = ar_SA; + Scots = sco; + ScotsGaelic = gd_GB; + Serbian = sr; /* -Cyrl, or -Latn ?*/ + Serer = srr; + Shan = shn; + Shona = sn; + SichuanYi = ii; + Sicilian = scn; + Sidamo = sid; + SimplifiedChinese = zh-Hans; + Sindhi = sd; + SingaporeChinese = zh-Hans_SG; + SingaporeEnglish = en_SG; + Sinhala = si; + Slovak = sk; + Slovenian = sl; + Somali = so; + SomaliaSomali = so_SO; + Soninke = snk; + Sotho = st; + SouthAfricaEnglish = en_ZA; + SpainBasque = eu_ES; + SpainSpanish = es_ES; + Spanish = es; + SudanArabic = ar_SD; + Sukuma = suk; + Sundanese = su; + Susu = sus; + Swahili = sw; + Swati = ss; + Swedish = sv; + SwitzerlandFrench = fr_CH; + SwitzerlandGerman = de_CH; + SwitzerlandItalian = it_CH; + SyriaArabic = ar_SY; + Tagalog = tl; + Tahitian = ty; + Tajik = tg; + Tamil = ta; + Tatar = tt; + Telugu = te; + Tetum = tet; + Thai = th; + Tibetan = bo; + Tigre = tig; + Tigrinya = ti; + Timne = tem; + Tiv = tiv; + TokPisin = tpi; + Tonga = to; + TongaNyasa = tog; + TraditionalChinese = zh-Hant; + Tsonga = ts; + Tswana = tn; + Tumbuka = tum; + TunisiaArabic = ar_TN; + Turkish = tr; + Turkmen = tk; + Tuvinian = tyv; + Twi = tw; + Udmurt = udm; + Uighur = ug; + UkraineRussian = ru_UA; + Ukrainian = uk; + Umbundu = umb; + UnitedArabEmiratesArabic = ar_AE; + Urdu = ur; + UruguaySpanish = es_UY; + USASpanish = es_US; + Uzbek = uz; /* -Arab, -Cyrl, or -Latn ?*/ + Vai = vai; + Venda = ve; + VenezuelaSpanish = es_VE; + Vietnamese = vi; + Walamo = wal; + Walloon = wa; + Waray = war; + Welsh = cy; + WesternFrisian = fy; + Wolof = wo; + Xhosa = xh; + Yakut = sah; + Yao = yao; + YemenArabic = ar_YE; + Yiddish = yi; + Yoruba = yo; + Zhuang = za; + ZimbabweEnglish = en_ZW; + Zulu = zu; +} \ No newline at end of file diff --git a/Source/NSLocale.m b/Source/NSLocale.m index ea7dbd9d2..1477a8f1c 100644 --- a/Source/NSLocale.m +++ b/Source/NSLocale.m @@ -25,6 +25,7 @@ #import "common.h" #import "Foundation/NSLocale.h" #import "Foundation/NSArray.h" +#import "Foundation/NSBundle.h" #import "Foundation/NSCalendar.h" #import "Foundation/NSCoder.h" #import "Foundation/NSCharacterSet.h" @@ -316,6 +317,7 @@ static NSLocale *autoupdatingLocale = nil; static NSLocale *currentLocale = nil; static NSLocale *systemLocale = nil; static NSMutableDictionary *allLocales = nil; +static NSDictionary *canonicalLocales = nil; static NSRecursiveLock *classLock = nil; + (void) initialize @@ -375,14 +377,45 @@ static NSRecursiveLock *classLock = nil; + (NSString *) canonicalLanguageIdentifierFromString: (NSString *) string { - // FIXME - return string; + NSString *result; + NSString *localeId; + NSArray *localeComps; + + /* Can't use the ICU functions here because, according to Apple locale docs, + the language has a format like "zh-Hant". ICU, however, uses an + underscore to separate Scripts "zh_Hant". */ + localeId = [self canonicalLocaleIdentifierFromString: string]; + localeComps = [localeId componentsSeparatedByString: @"_"]; + result = [localeComps objectAtIndex: 0]; + + return result; } + (NSString *) canonicalLocaleIdentifierFromString: (NSString *) string { - // FIXME - return string; + /* The way this works, according to Apple docs, is a mess. It seems + that both BCP 47's "-" and ICU's "_" separators are used. According to + "Language and Locale Designations" (Apple docs) Taiwan, for example, has + zh-Hant_TW as it's locale identifier (was zh_TW on 10.3.9 and below). + Since ICU doesn't use "-" as a separator it will modify that identifier + to zh_Hant_TW. */ + NSString *result; + + if (canonicalLocales == nil) + { + NSBundle *gbundle = [NSBundle bundleForLibrary: @"gnustep-base"]; + NSString *file = [gbundle pathForResource: @"Locale" + ofType: @"canonical" + inDirectory: @"Languages"]; + if (file != nil) + canonicalLocales = [[NSDictionary alloc] initWithContentsOfFile: file]; + } + + result = [canonicalLocales objectForKey: string]; + if (result == nil) + result = string; + + return result; } + (NSLocaleLanguageDirection) characterDirectionForLanguage: @@ -590,8 +623,26 @@ static NSRecursiveLock *classLock = nil; + (NSArray *) preferredLanguages { - // FIXME - return [NSUserDefaults userLanguages]; + NSArray *result; + NSMutableArray *mArray; + NSUInteger cnt; + NSUInteger idx = 0; + NSArray *languages = [NSUserDefaults userLanguages]; + + if (languages == nil) + return [NSArray arrayWithObject: @"en"]; + + mArray = [NSMutableArray array]; + cnt = [languages count]; + while (idx < cnt) + { + NSString *lang = [languages objectAtIndex: idx]; + [mArray addObject: [self canonicalLanguageIdentifierFromString: lang]]; + ++idx; + } + + result = [NSArray arrayWithArray: mArray]; + return result; } + (id) systemLocale @@ -662,7 +713,8 @@ static NSRecursiveLock *classLock = nil; return [NSString stringWithUTF8String: buffer]; #else - return nil; // FIXME + return nil; // FIXME Check + // msdn.microsoft.com/en-us/library/0h88fahh%28v=vs.85%29.aspx #endif } @@ -671,7 +723,8 @@ static NSRecursiveLock *classLock = nil; #if GS_USE_ICU == 1 return uloc_getLCID ([localeIdentifier UTF8String]); #else - return 0; // FIXME + return 0; // FIXME: Check + // msdn.microsoft.com/en-us/library/0h88fahh%28v=vs.85%29.aspx #endif } @@ -753,14 +806,17 @@ static NSRecursiveLock *classLock = nil; int32_t length; char cLocaleId[ULOC_FULLNAME_CAPACITY]; UErrorCode error = U_ZERO_ERROR; - - length = uloc_canonicalize ([string UTF8String], cLocaleId, + + localeId = [NSLocale canonicalLocaleIdentifierFromString: string]; + // Normalize locale ID + length = uloc_canonicalize ([localeId UTF8String], cLocaleId, ULOC_FULLNAME_CAPACITY, &error); if (U_FAILURE(error)) { [self release]; return nil; } + localeId = [NSString stringWithUTF8String: cLocaleId]; #else localeId = string;