]> err.no Git - sope/commitdiff
improved Tiger support in bundle manager
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Wed, 14 Sep 2005 16:10:17 +0000 (16:10 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Wed, 14 Sep 2005 16:10:17 +0000 (16:10 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1106 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-core/NGExtensions/ChangeLog
sope-core/NGExtensions/NGBundleManager.m
sope-core/NGExtensions/Version

index b871e4f5d554b4823aeb65fd95ee0ef9670ab702..d2ff66c8f95370bd19cf76056aa85f1eeddaadcf 100644 (file)
@@ -1,3 +1,8 @@
+2005-09-14  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGBundleManager.m: avoid an autorelease call in class lookup, added
+         some lookup hacks for Tiger Foundation (v4.5.174)
+
 2005-08-26  Helge Hess  <helge.hess@opengroupware.org>
 
        * added common.h files to support PCH compilation of subprojects (just
index 23463b008ff7a7a2cecaadf6d3768acaa50bb2e3..5d006c7f0f24d83b3cb62a015eb6ef54ddf556e0 100644 (file)
 //OBJC_EXPORT void objc_setClassHandler(int (*)(const char *));
 
 static BOOL debugClassHook = NO;
+static BOOL hookDoLookup   = YES;
 
 static int _getClassHook(const char *className) {
+  // Cocoa variant
   if (className == NULL) return 0;
   
   if (debugClassHook)
@@ -59,18 +61,21 @@ static int _getClassHook(const char *className) {
   if (objc_lookUpClass(className))
     return 1;
   
-  {
+  if (hookDoLookup) {
     static NGBundleManager *manager = nil;
     NSBundle *bundle;
+    NSString *cns;
     
     if (debugClassHook)
-      NSLog(@"%s: look for class %s", __PRETTY_FUNCTION__, className);
+      printf("%s: look for class %s\n", __PRETTY_FUNCTION__, className);
     if (manager == nil)
       manager = [NGBundleManager defaultBundleManager];
     
-    bundle  = [manager bundleForClassNamed:
-                        [NSString stringWithCString:className]];
-    if (bundle) {
+    cns = [[NSString alloc] initWithCString:className];
+    bundle = [manager bundleForClassNamed:cns];
+    [cns release]; cns = nil;
+    
+    if (bundle != nil) {
       if (debugClassHook) {
        NSLog(@"%s: found bundle %@", __PRETTY_FUNCTION__, 
              [bundle bundlePath]);
@@ -126,7 +131,7 @@ static Class _classLoadHook(const char *_name) {
       manager = [NGBundleManager defaultBundleManager];
     
     bundle  = [manager bundleForClassNamed:[NSString stringWithCString:_name]];
-    if (bundle) {
+    if (bundle != nil) {
 #if 0
       NSLog(@"%s: found bundle %@", __PRETTY_FUNCTION__, [bundle bundlePath]);
 #endif
@@ -248,9 +253,7 @@ static NSString *NGEnvVarPathSeparator = @":";
        objc_setClassHandler(_getClassHook);
       }
     }
-#endif
-
-#if GNU_RUNTIME
+#elif GNU_RUNTIME
     if (_objc_lookup_class != _classLoadHook) {
       oldClassLoadHook = _objc_lookup_class;
       _objc_lookup_class = _classLoadHook;
@@ -377,9 +380,9 @@ static NSString *NGEnvVarPathSeparator = @":";
 - (void)_registerLoadedBundles {
   NSEnumerator *currentBundles;
   NSBundle     *loadedBundle;
-  
+
   currentBundles = [[NSBundle allBundles] objectEnumerator];
-  while ((loadedBundle = [currentBundles nextObject]))
+  while ((loadedBundle = [currentBundles nextObject]) != nil)
     [self registerBundle:loadedBundle classes:nil categories:nil];
 }
 
@@ -468,16 +471,35 @@ static NSString *NGEnvVarPathSeparator = @":";
   NSEnumerator *e;
   id v;
 
-  //NSLog(@"NGBundleManager: register loaded bundle %@", [_bundle bundlePath]);
-
+#if NeXT_RUNTIME || APPLE_RUNTIME
+  v = [_bundle bundlePath];
+  if ([v hasSuffix:@"Libraries"] || [v hasSuffix:@"Tools"]) {
+    if (debugOn)
+      fprintf(stderr, "INVALID BUNDLE: %s\n", [[_bundle bundlePath] cString]);
+    return;
+  }
+#endif
+  
+#if 0
+  NSLog(@"NGBundleManager: register loaded bundle %@", [_bundle bundlePath]);
+#endif
+  
   e = [_classes objectEnumerator];
-  while ((v = [e nextObject])) {
+  while ((v = [e nextObject]) != nil) {
+#if NeXT_RUNTIME || APPLE_RUNTIME
+    hookDoLookup = NO;
+#endif
+
     NSMapInsert(self->classToBundle, NSClassFromString(v), _bundle);
     NSMapInsert(self->classNameToBundle, v, _bundle);
+    
+#if NeXT_RUNTIME || APPLE_RUNTIME
+    hookDoLookup = YES;
+#endif
   }
-
+  
   e = [_categories objectEnumerator];
-  while ((v = [e nextObject]))
+  while ((v = [e nextObject]) != nil)
     NSMapInsert(self->categoryNameToBundle, v, _bundle);
 }
 
@@ -529,14 +551,38 @@ static NSString *NGEnvVarPathSeparator = @":";
 - (NSBundle *)bundleForClass:(Class)aClass {
   /* this method never loads a dynamic bundle (since the class is set up) */
   NSBundle *bundle;
-
+  
+  if (aClass == Nil)
+    return nil;
+  
   bundle = NSMapGet(self->classToBundle, aClass);
 
 #if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
-  if (bundle == nil){
+  if (bundle == nil) {
+    NSString *p;
+    
     bundle = [NSBundle bundleForClass:aClass];
     if (bundle == [NSBundle mainBundle])
       bundle = nil;
+    else {
+      p = [bundle bundlePath];
+      if ([p hasSuffix:@"Libraries"]) {
+       if (debugOn) {
+         fprintf(stderr, "%s: Dylib bundle: 0x%08X: %s\n",
+                 __PRETTY_FUNCTION__,
+                 (unsigned int )bundle, [[bundle bundlePath] cString]);
+       }
+       bundle = nil;
+      }
+      else if ([p hasSuffix:@"Tools"]) {
+       if (debugOn) {
+         fprintf(stderr, "%s: Tool bundle: 0x%08X: %s\n",
+                 __PRETTY_FUNCTION__,
+                 (unsigned int )bundle, [[bundle bundlePath] cString]);
+       }
+       bundle = nil;
+      }
+    }
   }
 #endif
   if (bundle == nil) {
@@ -617,13 +663,13 @@ static NSString *NGEnvVarPathSeparator = @":";
 - (NSBundle *)bundleForClassNamed:(NSString *)_className {
   NSString *path   = nil;
   NSBundle *bundle = nil;
-  
+
   if (_className == nil)
     return nil;
 
   /* first check in table */
   
-  if ((bundle = NSMapGet(self->classNameToBundle, _className)))
+  if ((bundle = NSMapGet(self->classNameToBundle, _className)) != nil)
     return bundle;
   
 #if GNU_RUNTIME
@@ -633,26 +679,47 @@ static NSString *NGEnvVarPathSeparator = @":";
     void  *loadCallback;
     Class clazz;
     
-    
     loadCallback = _objc_lookup_class;
     _objc_lookup_class = NULL;
     clazz = NSClassFromString(_className);
     _objc_lookup_class = loadCallback;
 
-    if (clazz) {
+    if (clazz != Nil) {
       /* the class is already loaded */
       bundle = [self bundleForClass:clazz];
       NSMapInsert(self->classNameToBundle, _className, bundle);
       return bundle;
     }
   }
+#elif NeXT_RUNTIME || APPLE_RUNTIME
+  {
+    Class clazz;
+    
+    hookDoLookup = NO; // THREAD
+    clazz = NSClassFromString(_className);
+    hookDoLookup = YES;
+    
+    if (clazz != Nil) {
+      /* the class is already loaded */
+#if 0
+      printf("found class in runtime: %s\n", [_className cString]);
+#endif
+      bundle = [self bundleForClass:clazz];
+      NSMapInsert(self->classNameToBundle, _className, bundle);
+      return bundle;
+    }
+#if 0
+    else
+      printf("did NOT find class in runtime: %s\n", [_className cString]);
+#endif
+  }
 #endif
   
   path = [self pathForBundleProvidingResource:_className
                ofType:@"classes"
                resourceSelector:_selectClassByVersion
                context:NULL /* version */];
-  if (path) {
+  if (path != nil) {
     path = [path stringByResolvingSymlinksInPath];
     NSAssert(path, @"couldn't resolve symlinks in path ..");
   }
@@ -660,7 +727,7 @@ static NSString *NGEnvVarPathSeparator = @":";
   if (path == nil)
     return nil;
   
-  if ((bundle = [self bundleWithPath:path]))
+  if ((bundle = [self bundleWithPath:path]) != nil)
     NSMapInsert(self->classNameToBundle, _className, bundle);
 
   return bundle;
@@ -732,9 +799,15 @@ static NSString *NGEnvVarPathSeparator = @":";
     [self debugWithFormat:
            @"no bundle handler, lookup principal class of bundle: %@",
            _bundle];
-    if ((handler = [_bundle principalClass]) == nil)
+    if ((handler = [_bundle principalClass]) == nil) {
       /* use NGBundle class as default bundle handler */
+#if !(NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY)
+      [self warnWithFormat:@"bundle has no principal class: %@", _bundle];
+#endif
       handler = [NGBundle class];
+    }
+    else
+      [self debugWithFormat:@"  => %@", handler];
   }
   
   return handler;
@@ -779,6 +852,16 @@ static NSString *NGEnvVarPathSeparator = @":";
     return nil;
   }
   
+  // TODO: do we need to check the runtime for already loaded classes?
+  //       Yes, I think so. But avoid recursions
+#if 0
+#if APPLE_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
+  // TODO: HACK, see above. w/o this, we get issues.
+  if ([className hasPrefix:@"NS"])
+    return nil;
+#endif
+#endif
+  
   if ((bundle = [self bundleForClassNamed:className]) == nil) {
 #if 0 // class might be already loaded
     NSLog(@"ERROR: did not find class %@ required by bundle %@.",
@@ -786,6 +869,9 @@ static NSString *NGEnvVarPathSeparator = @":";
 #endif
   }
   
+  if (debugOn)
+    NSLog(@"CLASS %@ => BUNDLE %@", className, bundle);
+  
   return bundle;
 }
 - (NSArray *)_locateBundlesForClassInfos:(NSEnumerator *)_classInfos {
@@ -793,7 +879,7 @@ static NSString *NGEnvVarPathSeparator = @":";
   NSDictionary   *i;
   
   requiredBundles = [NSMutableArray arrayWithCapacity:16];
-  while ((i = [_classInfos nextObject])) {
+  while ((i = [_classInfos nextObject]) != nil) {
     NSBundle *bundle;
     
     if ((bundle = [self _locateBundleForClassInfo:i]) == nil)
@@ -806,7 +892,7 @@ static NSString *NGEnvVarPathSeparator = @":";
 
 - (BOOL)_preLoadBundle:(NSBundle *)_bundle info:(NSDictionary *)_bundleInfo {
   /* TODO: split up this huge method */
-  NSDictionary   *requires      = nil;
+  NSDictionary   *requires;
   NSMutableArray *requiredBundles = nil;
   NSBundle       *requiredBundle  = nil;
 
@@ -824,7 +910,7 @@ static NSString *NGEnvVarPathSeparator = @":";
     /* locate required bundles */
     
     e = [[requires objectForKey:@"bundles"] objectEnumerator];
-    while ((i = [e nextObject])) {
+    while ((i = [e nextObject]) != nil) {
       NSString *bundleName;
       
       if (![i respondsToSelector:@selector(objectForKey:)]) {
@@ -857,18 +943,19 @@ static NSString *NGEnvVarPathSeparator = @":";
         NSLog(@"ERROR: error in bundle-info.plist of bundle %@", _bundle);
     }
   }
-
+  
   /* load located bundles */
   {
     NSEnumerator *e;
     
     e = [requiredBundles objectEnumerator];
-    while ((requiredBundle = [e nextObject])) {
+    while ((requiredBundle = [e nextObject]) != nil) {
       Class bundleMaster;
       
       if ((bundleMaster = [self loadBundle:requiredBundle]) == Nil) {
         NSLog(@"ERROR: could not load bundle %@ (%@) required by bundle %@.",
-              [requiredBundle bundlePath], requiredBundle, [_bundle bundlePath]);
+              [requiredBundle bundlePath], requiredBundle,
+             [_bundle bundlePath]);
        continue;
       }
     }
@@ -880,23 +967,25 @@ static NSString *NGEnvVarPathSeparator = @":";
     NSArray *reqClasses;
     
     reqClasses = [requires objectForKey:@"classes"];
+    
     bundles = [self _locateBundlesForClassInfos:[reqClasses objectEnumerator]];
     if (requiredBundles == nil)
       requiredBundles = [NSMutableArray arrayWithCapacity:16];
     [requiredBundles addObjectsFromArray:bundles];
   }
-  
+
   /* load located bundles */
   {
     NSEnumerator *e;
     
     e = [requiredBundles objectEnumerator];
-    while ((requiredBundle = [e nextObject])) {
+    while ((requiredBundle = [e nextObject]) != nil) {
       Class bundleMaster;
       
       if ((bundleMaster = [self loadBundle:requiredBundle]) == Nil) {
         NSLog(@"ERROR: could not load bundle %@ (%@) required by bundle %@.",
-              [requiredBundle bundlePath], requiredBundle, [_bundle bundlePath]);
+              [requiredBundle bundlePath], requiredBundle,
+             [_bundle bundlePath]);
        continue;
       }
     }
@@ -908,7 +997,7 @@ static NSString *NGEnvVarPathSeparator = @":";
     NSDictionary *i;
 
     e = [[requires objectForKey:@"classes"] objectEnumerator];
-    while ((i = [e nextObject])) {
+    while ((i = [e nextObject]) != nil) {
       NSString *className;
       Class clazz;
 
@@ -1377,7 +1466,7 @@ static BOOL _doesInfoMatch(NSArray *keys, NSDictionary *dict, NSDictionary *info
     /* check whether an appropriate bundle is contained in 'path' */
        
     dir = [[fm directoryContentsAtPath:path] objectEnumerator];
-    while ((tmp = [dir nextObject])) {
+    while ((tmp = [dir nextObject]) != nil) {
       NSDictionary *bundleInfo      = nil;
       NSString     *infoPath;
       
index 2a3637f287eb157a15b8a13c85033f551917be41..002850532b284de6b3bea7703583c065dab8ab98 100644 (file)
@@ -1,6 +1,6 @@
 # version
 
-SUBMINOR_VERSION:=173
+SUBMINOR_VERSION:=174
 
 # v4.3.115 requires libFoundation v1.0.59
 # v4.2.72  requires libEOControl  v4.2.39