From 46ab731b393ae156a6b26da9a137333eed858d7d Mon Sep 17 00:00:00 2001 From: mirko Date: Sun, 13 Oct 2002 10:29:54 +0000 Subject: [PATCH] * Source/NSBundle.m ([NSBundle +_addFrameworkFromClass:]): remove the classes in the _loadingBundle that does not belong to it but with frameworks linked with it. ([NSBundle +bundleForClass:]): construct a list of NSFramework_* classes loaded with the bundle. ([NSBundle -load]): call _addFrameworkFromClass: for all linked frameworks with the bundle. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14761 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 10 +++++++ Source/NSBundle.m | 68 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 238029215..9cfc77d48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2002-10-13 Mirko Viviani + + * Source/NSBundle.m ([NSBundle +_addFrameworkFromClass:]): remove + the classes in the _loadingBundle that does not belong to it but with + frameworks linked with it. + ([NSBundle +bundleForClass:]): construct a list of NSFramework_* + classes loaded with the bundle. + ([NSBundle -load]): call _addFrameworkFromClass: for all linked + frameworks with the bundle. + 2002-10-13 Richard Frith-Macdonald * Tools/AGSHtml.m: Create automatic references to protocols in diff --git a/Source/NSBundle.m b/Source/NSBundle.m index 1403b99f9..f2f8b423f 100644 --- a/Source/NSBundle.m +++ b/Source/NSBundle.m @@ -87,6 +87,10 @@ static NSBundle *_gnustep_bundle = nil; static NSRecursiveLock *load_lock = nil; static BOOL _strip_after_loading = NO; +/* List of framework linked in the _loadingBundle */ +static NSMutableArray *_loadingFrameworks = nil; +static NSString *_currentFrameworkName = nil; + static NSString *gnustep_target_dir = #ifdef GNUSTEP_TARGET_DIR @GNUSTEP_TARGET_DIR; @@ -219,7 +223,7 @@ _bundle_name_first_match(NSString* directory, NSString* name) } @interface NSBundle (Private) -+ (void) _addFrameworkFromClass:(Class)frameworkClass; ++ (void) _addFrameworkFromClass: (Class)frameworkClass; - (NSArray *) _bundleClasses; @end @@ -261,8 +265,15 @@ _bundle_name_first_match(NSString* directory, NSString* name) the classes belonging to it, and tries to determine the path on disk to the framework bundle. + Mirko: + + Bundles (ie frameworks) could depend to other frameworks (linked + togheter on platform that supports this behaviour) so in + _bundle_load_callback() we construct a list of all NSFramework_* classes + loaded and call this method to build the correct list of bundles. + */ -+ (void) _addFrameworkFromClass:(Class)frameworkClass ++ (void) _addFrameworkFromClass: (Class)frameworkClass { NSBundle *bundle; NSString **fmClasses; @@ -274,20 +285,13 @@ _bundle_name_first_match(NSString* directory, NSString* name) return; } - /* FIXME NICOLA :-) Hmmm ... consider the case that the framework - was linked (using xxx_LIBRARIES_DEPEND_UPON) into a bundle. */ - if (_loadingBundle != nil) - { - return; - } - len = strlen (frameworkClass->name); - + if (len > 12 * sizeof(char) && !strncmp("NSFramework_", frameworkClass->name, 12)) { NSString *varEnv, *path, *name; - + /* The name of the framework. */ name = [NSString stringWithCString: &frameworkClass->name[12]]; @@ -355,18 +359,22 @@ _bundle_name_first_match(NSString* directory, NSString* name) /* A NULL terminated list of class names - the classes contained in the framework. */ fmClasses = [frameworkClass frameworkClasses]; - + while (*fmClasses != NULL) { NSValue *value; Class class = NSClassFromString(*fmClasses); - + value = [NSValue valueWithNonretainedObject: class]; [(NSMutableArray *)[bundle _bundleClasses] addObject: value]; fmClasses++; } + + if (_loadingBundle) + [(NSMutableArray *)[_loadingBundle _bundleClasses] + removeObjectsInArray: [bundle _bundleClasses]]; } } @@ -381,6 +389,7 @@ void _bundle_load_callback(Class theClass, struct objc_category *theCategory) { NSCAssert(_loadingBundle, NSInternalInconsistencyException); + NSCAssert(_loadingFrameworks, NSInternalInconsistencyException); /* We never record categories - if this is a category, just do nothing. */ if (theCategory != 0) @@ -389,10 +398,22 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) } /* Don't store the internal NSFramework_xxx class into the list of - bundle classes. */ + bundle classes, but store the linked frameworks in _loadingFrameworks */ if (strlen (theClass->name) > 12 && !strncmp ("NSFramework_", theClass->name, 12)) { + if (_currentFrameworkName) + { + const char *frameworkName; + + frameworkName = [_currentFrameworkName cString]; + + if (!strcmp(theClass->name, frameworkName)) + return; + } + + [_loadingFrameworks + addObject: [NSValue valueWithNonretainedObject: (id)theClass]]; return; } @@ -902,6 +923,10 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) if (_bundleType == NSBUNDLE_FRAMEWORK) { path = [_path stringByAppendingPathComponent:@"Versions/Current"]; + + _currentFrameworkName = RETAIN(([NSString stringWithFormat: + @"NSFramework_%@", + object])); } else { @@ -911,13 +936,25 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) object = bundle_object_name(path, object); _loadingBundle = self; _bundleClasses = RETAIN([NSMutableArray arrayWithCapacity: 2]); + _loadingFrameworks = RETAIN([NSMutableArray arrayWithCapacity: 2]); if (objc_load_module([object fileSystemRepresentation], stderr, _bundle_load_callback, NULL, NULL)) { + DESTROY(_loadingFrameworks); + DESTROY(_currentFrameworkName); [load_lock unlock]; return NO; } _codeLoaded = YES; + + /* We now construct the list of bundles from frameworks linked with + this one */ + classEnumerator = [_loadingFrameworks objectEnumerator]; + while ((class = [classEnumerator nextObject]) != nil) + { + [NSBundle _addFrameworkFromClass: [class nonretainedObjectValue]]; + } + /* After we load code from a bundle, we retain the bundle until we unload it (because we never unload bundles, that is forever). The reason why we retain it is that we need it! @@ -926,6 +963,9 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) +allBundles. */ RETAIN (self); _loadingBundle = nil; + + DESTROY(_loadingFrameworks); + DESTROY(_currentFrameworkName); classNames = [NSMutableArray arrayWithCapacity: [_bundleClasses count]]; classEnumerator = [_bundleClasses objectEnumerator];