* Source/NSUserDefaults.m:

- Refactoring of the code to read the system language list
  into a separate function, systemLanguages().
- Add support for the LANGUAGE environment variable, a GNU extension.
  It holds a colon-separated list of locales, and is intended to let
  the user specify a list of their preferred languages in order.
  For example, the language settings GUI in Ubuntu modifies the
  LANGUAGE variable.

  More info here:
  http://www.gnu.org/software/gettext/manual/gettext.html#The-LANGUAGE-variable
- When populating NSLanguages, "expand" locales into a list of
  related variants, formed by stripping off region suffixes. This
  ensures that if a user's environment is set to a regional version
  of a language (say CanadaFrench) but an application is only
  traslated into French, the plain French translation will still be used.

  e.g. if the system locales are {fr_CA, en_CA}, expand the list to
  {fr_CA, fr, en_CA, en}.
* Headers/GNUstepBase/GSLocale.h:
* Source/GSLocale.m:
New functions GSLocaleVariants and GSLanguagesFromLocale


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@33910 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ericwa 2011-09-29 19:00:46 +00:00
parent eebba60c4b
commit 6352d91406
4 changed files with 135 additions and 28 deletions

View file

@ -1,3 +1,28 @@
2011-09-07 Eric Wasylishen <ewasylishen@gmail.com>
* Source/NSUserDefaults.m:
- Refactoring of the code to read the system language list
into a separate function, systemLanguages().
- Add support for the LANGUAGE environment variable, a GNU extension.
It holds a colon-separated list of locales, and is intended to let
the user specify a list of their preferred languages in order.
For example, the language settings GUI in Ubuntu modifies the
LANGUAGE variable.
More info here:
http://www.gnu.org/software/gettext/manual/gettext.html#The-LANGUAGE-variable
- When populating NSLanguages, "expand" locales into a list of
related variants, formed by stripping off region suffixes. This
ensures that if a user's environment is set to a regional version
of a language (say CanadaFrench) but an application is only
traslated into French, the plain French translation will still be used.
e.g. if the system locales are {fr_CA, en_CA}, expand the list to
{fr_CA, fr, en_CA, en}.
* Headers/GNUstepBase/GSLocale.h:
* Source/GSLocale.m:
New functions GSLocaleVariants and GSLanguagesFromLocale
2011-09-28 Niels Grewe <niels.grewe@halbordnung.de>
* Tests/base/NSXMLNode/*: Some initial tests for NSXMLNode. Passes on

View file

@ -44,8 +44,31 @@ GS_EXPORT NSString *GSSetLocale(int category, NSString *locale);
GS_EXPORT NSDictionary *GSDomainFromDefaultLocale(void);
/**
* Returns a language name string for a given locale.
* e.g. GSLanguageFromLocale(@"en_CA") returns @"CanadaEnglish"
*/
GS_EXPORT NSString *GSLanguageFromLocale(NSString *locale);
/**
* Return an array of variants of a locale, formed by stripping
* off parts of the identifier, ordered from most similar to
* least similar.
*
* e.g. GSLocaleVariants(@"en_CA") returns (@"en_CA", @"en").
*/
GS_EXPORT NSArray *GSLocaleVariants(NSString *locale);
/**
* Convenience function which calls GSLocaleVariants to expand
* the given locale to a list of variants, and then calls
* GSLanguageFromLocale on each.
*
* e.g. GSLanguagesFromLocale(@"en_CA") returns
* (@"CanadaEnglish", @"English")
*/
GS_EXPORT NSArray *GSLanguagesFromLocale(NSString *locale);
#if defined(__cplusplus)
}
#endif

View file

@ -247,7 +247,8 @@ GSLanguageFromLocale(NSString *locale)
NSString *aliases = nil;
NSBundle *gbundle;
if (locale == nil || [locale isEqual: @"C"] || [locale isEqual: @"POSIX"])
if (locale == nil || [locale isEqual: @"C"] || [locale isEqual: @"POSIX"]
|| [locale length] < 2)
return @"English";
gbundle = [NSBundle bundleForLibrary: @"gnustep-base"];
@ -276,3 +277,36 @@ GSLanguageFromLocale(NSString *locale)
return language;
}
NSArray *
GSLocaleVariants(NSString *locale)
{
NSRange under = [locale rangeOfString: @"_"];
if (under.location != NSNotFound)
{
return [NSArray arrayWithObjects:
locale,
[locale substringToIndex: under.location],
nil];
}
return [NSArray arrayWithObject: locale];
}
NSArray *
GSLanguagesFromLocale(NSString *locale)
{
NSArray *variants = GSLocaleVariants(locale);
NSMutableArray *result = [NSMutableArray arrayWithCapacity: [variants count]];
NSEnumerator *enumerator = [variants objectEnumerator];
NSString *variant;
while ((variant = [enumerator nextObject]) != nil)
{
NSString *language = GSLanguageFromLocale(variant);
if (language != nil)
{
[result addObject: language];
}
}
return result;
}

View file

@ -178,44 +178,69 @@ writeDictionary(NSDictionary *dict, NSString *file)
return NO;
}
/**
* Returns the list of languages retrieved from the operating system, in
* decreasing order of preference. Returns an empty array if the information
* could not be retrieved.
*/
static NSArray *
systemLanguages()
{
NSMutableArray *names = [NSMutableArray arrayWithCapacity: 10];
// Add the languages listed in the LANGUAGE environment variable
// (a non-POSIX GNU extension)
{
NSString *env = [[[NSProcessInfo processInfo] environment]
objectForKey: @"LANGUAGE"];
if (env != nil && [env length] > 0)
{
NSArray *array = [env componentsSeparatedByString: @":"];
NSEnumerator *enumerator = [array objectEnumerator];
NSString *locale;
while (nil != (locale = [enumerator nextObject]))
{
[names addObjectsFromArray: GSLanguagesFromLocale(locale)];
}
}
}
// If LANGUAGES did not yield any languages, try LC_MESSAGES
#ifdef HAVE_LOCALE_H
#ifdef LC_MESSAGES
if ([names count] == 0)
{
NSString *locale = GSSetLocale(LC_MESSAGES, nil);
if (locale != nil)
{
[names addObjectsFromArray: GSLanguagesFromLocale(locale)];
}
}
#endif
#endif
return names;
}
static NSMutableArray *
newLanguages(NSArray *oldNames)
{
NSMutableArray *newNames;
NSEnumerator *enumerator;
NSString *language;
NSString *locale = nil;
#ifdef HAVE_LOCALE_H
#ifdef LC_MESSAGES
locale = GSSetLocale(LC_MESSAGES, nil);
#endif
#endif
newNames = [NSMutableArray arrayWithCapacity: 5];
if (oldNames == nil && locale != nil)
if (oldNames == nil || [oldNames count] == 0)
{
NSString *locLang = GSLanguageFromLocale(locale);
if (nil != locLang)
{
oldNames = [NSArray arrayWithObject: locLang];
}
#ifdef __MINGW__
if (oldNames == nil)
{
/* Check for language as the first part of the locale string */
NSRange under = [locale rangeOfString: @"_"];
if (under.location)
{
oldNames = [NSArray arrayWithObject:
[locale substringToIndex: under.location]];
}
}
#endif
oldNames = systemLanguages();
}
if (oldNames == nil)
// If the user default was not set, and the system languages couldn't
// be retrieved, try the GNUstep environment variable LANGUAGES
if (oldNames == nil || [oldNames count] == 0)
{
NSString *env;