git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@35272 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2012-07-09 05:22:03 +00:00
parent 99b20009a9
commit 2b30f01d2d
5 changed files with 170 additions and 33 deletions

View file

@ -1,8 +1,16 @@
2012-07-09 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSBundle.m: Fixes for bug #34815 ... map between old and
new style language names and use the best language specific
resource available.
2012-07-08 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/GNUstepBase/GSVersionMacros.h:
fix for bug #36650
* Source/NSFileManager.m: Apply rewritten patch by Sergey Golovin
* Source/NSBundle.m: Fix for bug #34815 ... we shoudl now move to
using ISO names.
2012-07-08 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -75,6 +75,56 @@ manager()
return mgr;
}
static NSDictionary *alternativeLanguageMap = nil;
/* Map a language name to any alternative versions. This function should
* return an array of alternative language/localisation directry names in
* the preferred order of precedence (ie resources in the directories named
* earlier in the array are to be preferred to those in directories named
* later).
* We should support regional language specifications (such as en-GB)
* as our first priority, and then fall back to the more general names.
*/
static NSArray *
altLang(NSString *lang)
{
if (lang)
{
NSArray *a;
NSRange r;
r = [lang rangeOfString: @"-"];
if (r.length > 0)
{
NSString *full = lang;
lang = [full substringToIndex: r.location];
a = [alternativeLanguageMap objectForKey: lang];
if (nil == a)
{
return [NSArray arrayWithObjects: full, lang, nil];
}
else
{
NSMutableArray *m = [a mutableCopy];
[m insertObject: full atIndex: 0];
return [m autorelease];
}
}
else
{
a = [alternativeLanguageMap objectForKey: lang];
if (nil == a)
{
return [NSArray arrayWithObject: lang];
}
return a;
}
}
return nil;
}
static NSLock *pathCacheLock = nil;
static NSMutableDictionary *pathCache = nil;
@ -400,8 +450,9 @@ addBundlePath(NSMutableArray *list, NSArray *contents,
}
if (nil != subdir)
{
NSEnumerator *e = [[subdir pathComponents] objectEnumerator];
NSString *subdirComponent;
NSEnumerator *e = [[subdir pathComponents] objectEnumerator];
NSString *subdirComponent;
while ((subdirComponent = [e nextObject]) != nil)
{
if (NO == [contents containsObject: subdirComponent])
@ -415,20 +466,30 @@ addBundlePath(NSMutableArray *list, NSArray *contents,
}
}
}
if (nil != lang)
if (nil == lang)
{
lang = [lang stringByAppendingPathExtension: @"lproj"];
if (NO == [contents containsObject: lang])
{
return;
}
path = [path stringByAppendingPathComponent: lang];
if (nil == (contents = bundle_directory_readable(path)))
{
return;
}
[list addObject: path];
}
else
{
NSEnumerator *enumerator = [altLang(lang) objectEnumerator];
NSString *alt;
/* Add each language specific subdirectory in order.
*/
while (nil != (alt = [enumerator nextObject]))
{
alt = [alt stringByAppendingPathExtension: @"lproj"];
if (YES == [contents containsObject: alt])
{
alt = [path stringByAppendingPathComponent: alt];
if (nil != (contents = bundle_directory_readable(alt)))
{
[list addObject: alt];
}
}
}
}
[list addObject: path];
}
/* Try to locate name framework in standard places
@ -964,6 +1025,27 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
mode = GSPathHandling("right");
_emptyTable = RETAIN([NSDictionary dictionary]);
/* Check ... I think this is all the languages we traditionally
* support ... but maybe we need others.
*/
alternativeLanguageMap = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSArray arrayWithObjects: @"zh", @"Chinese", nil], @"Chinese",
[NSArray arrayWithObjects: @"en", @"English", nil], @"English",
[NSArray arrayWithObjects: @"eo", @"Esperanto", nil], @"Esperanto",
[NSArray arrayWithObjects: @"fr", @"French", nil], @"French",
[NSArray arrayWithObjects: @"de", @"German", nil], @"German",
[NSArray arrayWithObjects: @"it", @"Italian", nil], @"Italian",
[NSArray arrayWithObjects: @"ko", @"Korean", nil], @"Korean",
[NSArray arrayWithObjects: @"zh", @"Chinese", nil], @"zh",
[NSArray arrayWithObjects: @"en", @"English", nil], @"en",
[NSArray arrayWithObjects: @"eo", @"Esperanto", nil], @"eo",
[NSArray arrayWithObjects: @"fr", @"French", nil], @"fr",
[NSArray arrayWithObjects: @"de", @"German", nil], @"de",
[NSArray arrayWithObjects: @"it", @"Italian", nil], @"it",
[NSArray arrayWithObjects: @"ko", @"Korean", nil], @"ko",
[NSArray arrayWithObjects: @"es", @"Spanish", nil], @"es",
nil];
/* Initialise manager here so it's thread-safe.
*/
manager();
@ -2162,16 +2244,22 @@ IF_NO_GC(
{
/* Add all non-localized paths, plus ones in the particular localization
(if there is one). */
NSString *theDir = [path stringByDeletingLastPathComponent];
NSString *theDir = [path stringByDeletingLastPathComponent];
NSString *last = [theDir lastPathComponent];
if ([[theDir pathExtension] isEqual: @"lproj"] == NO)
if ([[last pathExtension] isEqual: @"lproj"] == NO)
{
[result addObject: path];
}
else if ([localizationName length] > 0
&& [[theDir lastPathComponent] hasPrefix: localizationName])
{
[result insertObject: path atIndex: 0];
else
{
NSString *lang = [last stringByDeletingPathExtension];
NSArray *alternatives = altLang(lang);
if ([alternatives count] > 0)
{
[result addObject: path];
}
}
}

View file

@ -5,7 +5,7 @@ BUNDLE_NAME = TestBundle
TestBundle_OBJC_FILES = TestBundle.m
TestBundle_RESOURCE_FILES = NonLocalRes.txt
TestBundle_LANGUAGES = English French
TestBundle_LANGUAGES = English French de
TestBundle_LOCALIZED_RESOURCE_FILES = TextRes.txt
TestBundle_NEEDS_GUI = NO

View file

@ -0,0 +1 @@
Deutsche Ressource

View file

@ -20,23 +20,63 @@ int main()
/* --- [NSBundle -pathsForResourcesOfType:inDirectory:] --- */
bundle = [NSBundle bundleWithPath: path];
arr = [bundle pathsForResourcesOfType:@"txt" inDirectory: nil];
PASS((arr && [arr count]), "-pathsForResourcesOfType:inDirectory: returns an array");
localPath = [path stringByAppendingPathComponent: @"Resources/NonLocalRes.txt"];
PASS([arr containsObject: localPath], "Returned array contains non-localized resource");
localPath = [path stringByAppendingPathComponent: @"Resources/English.lproj/TextRes.txt"];
PASS([arr containsObject: localPath], "Returned array contains localized resource");
PASS((arr && [arr count]),
"-pathsForResourcesOfType:inDirectory: returns an array");
localPath = [path stringByAppendingPathComponent:
@"Resources/NonLocalRes.txt"];
PASS([arr containsObject: localPath],
"Returned array contains non-localized resource");
localPath = [path stringByAppendingPathComponent:
@"Resources/English.lproj/TextRes.txt"];
PASS([arr containsObject: localPath],
"Returned array contains localized resource");
/* --- [NSBundle +pathsForResourcesOfType:inDirectory:] --- */
carr = [NSBundle pathsForResourcesOfType:@"txt" inDirectory: path];
PASS([arr isEqual: carr], "+pathsForResourcesOfType:inDirectory: returns same array");
PASS([arr isEqual: carr],
"+pathsForResourcesOfType:inDirectory: returns same array");
/* --- [NSBundle -pathsForResourcesOfType:inDirectory:forLocalization:] --- */
arr = [bundle pathsForResourcesOfType:@"txt" inDirectory: nil forLocalization: @"English"];
PASS((arr && [arr count]), "-pathsForResourcesOfType:inDirectory:forLocalization returns an array");
localPath = [path stringByAppendingPathComponent: @"Resources/NonLocalRes.txt"];
PASS([arr containsObject: localPath], "Returned array contains non-localized resource");
localPath = [path stringByAppendingPathComponent: @"Resources/English.lproj/TextRes.txt"];
PASS([arr containsObject: localPath], "Returned array contains localized resource");
arr = [bundle pathsForResourcesOfType:@"txt" inDirectory: nil
forLocalization: @"English"];
PASS((arr && [arr count]),
"-pathsForResourcesOfType:inDirectory:forLocalization returns an array");
localPath = [path stringByAppendingPathComponent:
@"Resources/NonLocalRes.txt"];
PASS([arr containsObject: localPath],
"Returned array contains non-localized resource");
localPath = [path stringByAppendingPathComponent:
@"Resources/English.lproj/TextRes.txt"];
PASS([arr containsObject: localPath],
"Returned array contains localized resource");
/* --- [NSBundle -pathsForResourcesOfType:inDirectory:forLocalization:] --- */
arr = [bundle pathsForResourcesOfType:@"txt" inDirectory: nil
forLocalization: @"en"];
PASS((arr && [arr count]),
"-pathsForResources... returns an array for 'en'");
localPath = [path stringByAppendingPathComponent:
@"Resources/NonLocalRes.txt"];
PASS([arr containsObject: localPath],
"Returned array for 'en' contains non-localized resource");
localPath = [path stringByAppendingPathComponent:
@"Resources/English.lproj/TextRes.txt"];
PASS([arr containsObject: localPath],
"Returned array for 'en' contains localized resource");
/* --- [NSBundle -pathsForResourcesOfType:inDirectory:forLocalization:] --- */
arr = [bundle pathsForResourcesOfType:@"txt" inDirectory: nil
forLocalization: @"German"];
PASS((arr && [arr count]),
"-pathsForResources... returns an array for 'German'");
localPath = [path stringByAppendingPathComponent:
@"Resources/NonLocalRes.txt"];
PASS([arr containsObject: localPath],
"Returned array for 'German' contains non-localized resource");
localPath = [path stringByAppendingPathComponent:
@"Resources/de.lproj/TextRes.txt"];
PASS([arr containsObject: localPath],
"Returned array for 'German' contains localized resource");
[arp release]; arp = nil;
return 0;