Revision: 3855
          http://skim-app.svn.sourceforge.net/skim-app/?rev=3855&view=rev
Author:   hofman
Date:     2008-05-06 09:46:09 -0700 (Tue, 06 May 2008)

Log Message:
-----------
Add functions to add/swizzle class methods. Avoid redefining 
newlineCharacterSet on Leopard.

Modified Paths:
--------------
    trunk/NSCharacterSet_SKExtensions.h
    trunk/NSCharacterSet_SKExtensions.m
    trunk/PDFDisplayView_SKExtensions.m
    trunk/SKUtilities.h
    trunk/SKUtilities.m

Modified: trunk/NSCharacterSet_SKExtensions.h
===================================================================
--- trunk/NSCharacterSet_SKExtensions.h 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/NSCharacterSet_SKExtensions.h 2008-05-06 16:46:09 UTC (rev 3855)
@@ -40,7 +40,6 @@
 
 
 @interface NSCharacterSet (SKExtensions)
-+ (id)newlineCharacterSet;
 + (id)nonWhitespaceCharacterSet;
 + (id)nonWhitespaceAndNewlineCharacterSet;
 @end

Modified: trunk/NSCharacterSet_SKExtensions.m
===================================================================
--- trunk/NSCharacterSet_SKExtensions.m 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/NSCharacterSet_SKExtensions.m 2008-05-06 16:46:09 UTC (rev 3855)
@@ -37,11 +37,12 @@
  */
 
 #import "NSCharacterSet_SKExtensions.h"
+#import "SKUtilities.h"
 
 
 @implementation NSCharacterSet (SKExtensions)
 
-+ (id)newlineCharacterSet {
++ (id)replacementNewlineCharacterSet {
     static NSCharacterSet *newlineCharacterSet = nil;
     if (newlineCharacterSet == nil) {
         NSMutableCharacterSet *tmpSet = [[NSCharacterSet 
whitespaceCharacterSet] mutableCopy];
@@ -67,4 +68,9 @@
     return nonWhitespaceAndNewlineCharacterSet;
 }
 
++ (void)load {
+    if ([self respondsToSelector:@selector(newlineCharacterSet)] == NO)
+        SKRegisterClassMethodImplementationWithSelector(self, 
@selector(newlineCharacterSet), @selector(replacementNewlineCharacterSet));
+}
+
 @end

Modified: trunk/PDFDisplayView_SKExtensions.m
===================================================================
--- trunk/PDFDisplayView_SKExtensions.m 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/PDFDisplayView_SKExtensions.m 2008-05-06 16:46:09 UTC (rev 3855)
@@ -267,13 +267,13 @@
     if ([self 
instancesRespondToSelector:@selector(accessibilityFocusedUIElement)])
         originalAccessibilityFocusedUIElement = 
SKReplaceMethodImplementationWithSelector(self, 
@selector(accessibilityFocusedUIElement), 
@selector(replacementAccessibilityFocusedUIElement));
     if ([self 
instancesRespondToSelector:@selector(accessibilityRangeForPositionAttributeForParameter:)]
 == NO)
-        SKAddMethodImplementationWithSelector(self, 
@selector(accessibilityRangeForPositionAttributeForParameter:), 
@selector(replacementAccessibilityRangeForPositionAttributeForParameter:));
+        SKRegisterMethodImplementationWithSelector(self, 
@selector(accessibilityRangeForPositionAttributeForParameter:), 
@selector(replacementAccessibilityRangeForPositionAttributeForParameter:));
     if ([self 
instancesRespondToSelector:@selector(accessibilityRTFForRangeAttributeForParameter:)]
 == NO)
-        SKAddMethodImplementationWithSelector(self, 
@selector(accessibilityRTFForRangeAttributeForParameter:), 
@selector(replacementAccessibilityRTFForRangeAttributeForParameter:));
+        SKRegisterMethodImplementationWithSelector(self, 
@selector(accessibilityRTFForRangeAttributeForParameter:), 
@selector(replacementAccessibilityRTFForRangeAttributeForParameter:));
     if ([self 
instancesRespondToSelector:@selector(accessibilityAttributedStringForRangeAttributeForParameter:)]
 == NO)
-        SKAddMethodImplementationWithSelector(self, 
@selector(accessibilityAttributedStringForRangeAttributeForParameter:), 
@selector(replacementAccessibilityAttributedStringForRangeAttributeForParameter:));
+        SKRegisterMethodImplementationWithSelector(self, 
@selector(accessibilityAttributedStringForRangeAttributeForParameter:), 
@selector(replacementAccessibilityAttributedStringForRangeAttributeForParameter:));
     if ([self 
instancesRespondToSelector:@selector(accessibilityStyleRangeForIndexAttributeForParameter:)]
 == NO)
-        SKAddMethodImplementationWithSelector(self, 
@selector(accessibilityStyleRangeForIndexAttributeForParameter:), 
@selector(replacementAccessibilityStyleRangeForIndexAttributeForParameter:));
+        SKRegisterMethodImplementationWithSelector(self, 
@selector(accessibilityStyleRangeForIndexAttributeForParameter:), 
@selector(replacementAccessibilityStyleRangeForIndexAttributeForParameter:));
 }
 
 @end

Modified: trunk/SKUtilities.h
===================================================================
--- trunk/SKUtilities.h 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/SKUtilities.h 2008-05-06 16:46:09 UTC (rev 3855)
@@ -17,9 +17,11 @@
 #import <objc/objc-class.h>
 #import <objc/objc-runtime.h>
 
-IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp);
+IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp, BOOL 
isInstance);
 IMP SKReplaceMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL 
impSelector);
-void SKAddMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL 
impSelector);
+IMP SKReplaceClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector);
+IMP SKRegisterMethodImplementationWithSelector(Class aClass, SEL aSelector, 
SEL impSelector);
+IMP SKRegisterClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector);
 
 #define OBINITIALIZE \
     do { \

Modified: trunk/SKUtilities.m
===================================================================
--- trunk/SKUtilities.m 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/SKUtilities.m 2008-05-06 16:46:09 UTC (rev 3855)
@@ -19,6 +19,11 @@
 
 // wrappers around 10.5 only functions, use 10.4 API when the function is not 
defined
 
+static Class SK_object_getClass(id object)
+{
+    return object_getClass != NULL ? object_getClass(object) : object->isa;
+}
+
 static IMP SK_method_getImplementation(Method aMethod)
 {
     return method_getImplementation != NULL ? 
method_getImplementation(aMethod) : aMethod->method_imp;
@@ -63,21 +68,28 @@
     }
 }
 
-IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp)
+static Method SK_class_getMethod(Class aClass, SEL aSelector, BOOL isInstance)
 {
-    Method localMethod, superMethod = NULL;
+    return isInstance ? class_getInstanceMethod(aClass, aSelector) : 
class_getClassMethod(aClass, aSelector);
+}
+
+IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp, BOOL 
isInstance)
+{
+    Method superMethod = NULL;
+    Method localMethod = SK_class_getMethod(aClass, aSelector, isInstance);
     IMP oldImp = NULL;
     Class superCls = Nil;
+    Class realClass = isInstance ? aClass : SK_object_getClass(aClass);
     extern void _objc_flush_caches(Class);
     
-    if ((localMethod = class_getInstanceMethod(aClass, aSelector))) {
+    if (localMethod) {
         if (superCls = SK_class_getSuperclass(aClass))
-            superMethod = class_getInstanceMethod(superCls, aSelector);
+            superMethod = SK_class_getMethod(superCls, aSelector, isInstance);
         
         if (superMethod == localMethod) {
             // We are inheriting this method from the superclass.  We do *not* 
want to clobber the superclass's Method structure as that would replace the 
implementation on a greater scope than the caller wanted.  In this case, 
install a new method at this class and return the superclass's implementation 
as the old implementation (which it is).
             oldImp = SK_method_getImplementation(localMethod);
-            SK_class_addMethod(aClass, aSelector, anImp, 
SK_method_getTypeEncoding(localMethod));
+            SK_class_addMethod(realClass, aSelector, anImp, 
SK_method_getTypeEncoding(localMethod));
         } else {
             // Replace the method in place
             oldImp = SK_method_setImplementation(localMethod, anImp);
@@ -85,7 +97,7 @@
         
         // Flush the method cache, deprecated on 10.5
         if (_objc_flush_caches != NULL)
-            _objc_flush_caches(aClass);
+            _objc_flush_caches(realClass);
     }
     
     return oldImp;
@@ -93,11 +105,36 @@
 
 IMP SKReplaceMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL 
impSelector)
 {
-    return SKReplaceMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(class_getInstanceMethod(aClass, impSelector)));
+    return SKReplaceMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(class_getInstanceMethod(aClass, impSelector)), YES);
 }
 
-void SKAddMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL 
impSelector)
+IMP SKReplaceClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector)
 {
+    return SKReplaceMethodImplementation(aClass, aSelector, 
SK_method_getImplementation(class_getClassMethod(aClass, impSelector)), NO);
+}
+
+IMP SKRegisterMethodImplementationWithSelector(Class aClass, SEL aSelector, 
SEL impSelector)
+{
+    IMP imp = NULL;
     Method method = class_getInstanceMethod(aClass, impSelector);
-    SK_class_addMethod(aClass, aSelector, SK_method_getImplementation(method), 
SK_method_getTypeEncoding(method));
+    
+    if (method) {
+        imp = SK_method_getImplementation(method);
+        SK_class_addMethod(aClass, aSelector, imp, 
SK_method_getTypeEncoding(method));
+    }
+    
+    return imp;
 }
+
+IMP SKRegisterClassMethodImplementationWithSelector(Class aClass, SEL 
aSelector, SEL impSelector)
+{
+    IMP imp = NULL;
+    Method method = class_getClassMethod(aClass, impSelector);
+    
+    if (method) {
+        imp = SK_method_getImplementation(method);
+        SK_class_addMethod(SK_object_getClass(aClass), aSelector, imp, 
SK_method_getTypeEncoding(method));
+    }
+    
+    return imp;
+}


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to