On Dec 11, 2006, at 5:49 PM, Pierre d'Herbemont wrote:
On 12 déc. 06, at 00:20, Pierre d'Herbemont wrote:
- }
- closedir(dir);
I think the above code to scan /usr/share/locale is unnecessary. Doesn't CFLocaleCopyAvailableLocaleIdentifiers provide the equivalent?
You're quite right. I though setlocale didn't handle 'en' properly expecting full 'en_US' or 'en_GB', I can't understand why now. Probably didn't have enough sleep last night.
I do remember now :) setlocale don't handle properly two letters language code like 'es' it expect a full locale name like 'es_ES' . And using the CFLocale API to obtain the full local from 'es' does not seem possible.
And even with CFLocaleCopyAvailableLocaleIdentifiers() the returned array will contain 'es' among 'es_ES' and 'en_GB' so, when intersecting with the preferred languages [1] threw CFBundleCopyLocalizationsForPreferences() 'es' will be returned. setlocale(LC_MESSAGES, NULL) will return "C", and thus fallback the standard english language (LC_CTYPE is not set on Mac OS X), whereas setlocale should have returned es.
The fix for this is to provide to setlocale a full locale name like 'es_ES', that's why I did it that way.
Do you see any better way to do this rather than probably filling a bug report to Apple?
[1] #defaults read -g AppleLanguages ( es, fr, en, de, ja, it, nl, sv, nb, da, fi, pt, "zh-Hans", "zh- Hant", ko)
Hmm. Well, it probably results in more cumbersome code, but you could filter the array returned by CFLocaleCopyAvailableLocaleIdentifiers by testing which elements have a country code. For each, call CFLocaleCreateComponentsFromLocaleIdentifier and check if the resulting dictionary has an object for the kCFLocaleCountryCode key. You'd accumulate the locale IDs which pass the test in the mutable array.
However, this whole strategy (however it's implemented, by scanning / usr/share/locale or the above method) seems to produce bad results. When I test here, CFBundleCopyLocalizationsForPreferences() spits out "en_ZW" (English, Zimbabwe). Some testing reveals that it is *not* just picking the last entry in the locale array whose language matches. It's not entirely predictable. I suspect it's doing a binary search.
In System Preferences, I have my language preference set to English. If I edit the list and add U.S. English and put it at the top, then the above method does produce U.S. English. However, that's not how most people have things set up.
I suppose we could use a multi-step approach. If the first element of the AppleLanguages array has a country code, use it directly. Otherwise, combine the language code from that element with the country code from the current locale. If that combination is present in the array of available locales, use that. Otherwise, fall back to CFBundleCopyLocalizationsForPreferences.
-Ken