Permalink
Browse files

[NEW] Xmod: Migrate from MethodSwizzle to JRSwizzle. Modify project t…

…o generate single binary that works on Xcode 2.4 through 3.0 (targeting 10.4u SDK on ppc, 10.5 SDK on x86_64).
  • Loading branch information...
1 parent b15a9fc commit 9d3a214ed1cd00d034722d35bd243710f7f6d00f @rentzsch committed Feb 3, 2008
View
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
@@ -19,10 +19,12 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>1.6</string>
+ <string>1.8</string>
<key>NSPrincipalClass</key>
<string></string>
<key>XCPluginHasUI</key>
<false/>
+ <key>XCGCReady</key>
+ <string>YES</string>
</dict>
</plist>
View
@@ -1,27 +0,0 @@
-//
-// MethodSwizzle.h
-//
-// Copyright (c) 2006 Tildesoft. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#import <objc/objc.h>
-
-BOOL ClassMethodSwizzle(Class klass, SEL origSel, SEL altSel);
-BOOL MethodSwizzle(Class klass, SEL origSel, SEL altSel);
View
@@ -1,122 +0,0 @@
-//
-// MethodSwizzle.m
-//
-// Copyright (c) 2006 Tildesoft. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-// Implementation of Method Swizzling, inspired by
-// http://www.cocoadev.com/index.pl?MethodSwizzling
-
-// solves the inherited method problem
-
-#import "MethodSwizzle.h"
-#import <stdlib.h>
-#import <string.h>
-#import <objc/objc-runtime.h>
-#import <objc/objc-class.h>
-#import <uuid/uuid.h>
-
-static BOOL _PerformSwizzle(Class klass, SEL origSel, SEL altSel, BOOL forInstance);
-
-BOOL ClassMethodSwizzle(Class klass, SEL origSel, SEL altSel) {
- return _PerformSwizzle(klass, origSel, altSel, NO);
-}
-
-BOOL MethodSwizzle(Class klass, SEL origSel, SEL altSel) {
- return _PerformSwizzle(klass, origSel, altSel, YES);
-}
-
-// if the origSel isn't present in the class, pull it up from where it exists
-// then do the swizzle
-BOOL _PerformSwizzle(Class klass, SEL origSel, SEL altSel, BOOL forInstance) {
- // First, make sure the class isn't nil
- if (klass != nil) {
- Method origMethod = NULL, altMethod = NULL;
-
- // Next, look for the methods
- Class iterKlass = (forInstance ? klass : klass->isa);
- void *iterator = NULL;
- struct objc_method_list *mlist = class_nextMethodList(iterKlass, &iterator);
- while (mlist != NULL) {
- int i;
- for (i = 0; i < mlist->method_count; ++i) {
- if (mlist->method_list[i].method_name == origSel) {
- origMethod = &mlist->method_list[i];
- break;
- }
- if (mlist->method_list[i].method_name == altSel) {
- altMethod = &mlist->method_list[i];
- break;
- }
- }
- mlist = class_nextMethodList(iterKlass, &iterator);
- }
-
- if (origMethod == NULL || altMethod == NULL) {
- // one or both methods are not in the immediate class
- // try searching the entire hierarchy
- // remember, iterKlass is the class we care about - klass || klass->isa
- // class_getInstanceMethod on a metaclass is the same as class_getClassMethod on the real class
- BOOL pullOrig = NO, pullAlt = NO;
- if (origMethod == NULL) {
- origMethod = class_getInstanceMethod(iterKlass, origSel);
- pullOrig = YES;
- }
- if (altMethod == NULL) {
- altMethod = class_getInstanceMethod(iterKlass, altSel);
- pullAlt = YES;
- }
-
- // die now if one of the methods doesn't exist anywhere in the hierarchy
- // this way we won't make any changes to the class if we can't finish
- if (origMethod == NULL || altMethod == NULL) {
- return NO;
- }
-
- // we can safely assume one of the two methods, at least, will be pulled
- // pull them up
- size_t listSize = sizeof(struct objc_method_list);
- if (pullOrig && pullAlt) listSize += sizeof(struct objc_method); // need 2 methods
- struct objc_method_list *mlist = malloc(listSize);
- mlist->obsolete = NULL;
- int i = 0;
- if (pullOrig) {
- memcpy(&mlist->method_list[i], origMethod, sizeof(struct objc_method));
- origMethod = &mlist->method_list[i];
- i++;
- }
- if (pullAlt) {
- memcpy(&mlist->method_list[i], altMethod, sizeof(struct objc_method));
- altMethod = &mlist->method_list[i];
- i++;
- }
- mlist->method_count = i;
- class_addMethods(iterKlass, mlist);
- }
-
- // now swizzle
- IMP temp = origMethod->method_imp;
- origMethod->method_imp = altMethod->method_imp;
- altMethod->method_imp = temp;
-
- return YES;
- }
- return NO;
-}
View
@@ -1,5 +1,5 @@
#import "Xmod.h"
-#import "MethodSwizzle.h"
+#import "JRSwizzle.h"
@interface NSObject (xmod_saveModelToFile)
@end
@@ -47,7 +47,7 @@ - (void)applicationDidFinishLaunching:(NSNotification*)notification_ {
} else if ([xcodeVersion isEqualToString:@"2.5"]) {
coreDataPlugin = [NSBundle bundleWithPath:@"/Xcode2.5/Library/Xcode/Plug-ins/XDCoreDataModel.xdplugin"];
} else {
- // Unknown territory, exit.
+ NSLog(@"Xmod: unknown Xcode version (%@), exiting.", xcodeVersion);
return;
}
NSAssert(coreDataPlugin, @"failed to load XDCoreDataModel.xdplugin");
@@ -56,10 +56,11 @@ - (void)applicationDidFinishLaunching:(NSNotification*)notification_ {
Class persistenceDocumentController = NSClassFromString(@"XDPersistenceDocumentController");
NSAssert(persistenceDocumentController, @"failed to load XDPersistenceDocumentController");
- BOOL swizzled = MethodSwizzle(persistenceDocumentController,
- @selector(saveModelToFile:),
- @selector(xmod_saveModelToFile:));
- NSAssert(swizzled, @"failed to swizzle -[XDPersistenceDocumentController saveModelToFile:]");
+ NSError *error = nil;
+ BOOL swizzled = [persistenceDocumentController jr_swizzleMethod:@selector(saveModelToFile:)
+ withMethod:@selector(xmod_saveModelToFile:)
+ error:&error];
+ NSAssert1(swizzled, @"failed to swizzle -[XDPersistenceDocumentController saveModelToFile:]: %@", error);
// Install the Autocustomize menu item.
NSMenu *designMenu = [[[NSApp mainMenu] itemWithTitle:@"Design"] submenu];
@@ -23,7 +23,7 @@
/* Begin PBXBuildFile section */
79D150FE0C8FBE01006706AF /* Xmod.applescript in AppleScript */ = {isa = PBXBuildFile; fileRef = 79D150FA0C8FBDE9006706AF /* Xmod.applescript */; settings = {ATTRIBUTES = (Debug, ); }; };
79DFC11F0B59B8C80056C80E /* Xmod.m in Sources */ = {isa = PBXBuildFile; fileRef = 79DFC11E0B59B8C80056C80E /* Xmod.m */; };
- 79DFC1290B59BFD60056C80E /* MethodSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 79DFC1280B59BFD60056C80E /* MethodSwizzle.m */; };
+ 79E65E0D0D5631EA00B09941 /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E65E0B0D5631EA00B09941 /* JRSwizzle.m */; };
79F8A9C30C8FF06700082291 /* Autocustomize Entity Classes.applescript in AppleScript */ = {isa = PBXBuildFile; fileRef = 79F8A9C20C8FF06600082291 /* Autocustomize Entity Classes.applescript */; settings = {ATTRIBUTES = (Debug, ); }; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -38,8 +38,8 @@
79D150FA0C8FBDE9006706AF /* Xmod.applescript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.applescript; path = Xmod.applescript; sourceTree = "<group>"; };
79DFC11D0B59B8C80056C80E /* Xmod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xmod.h; sourceTree = "<group>"; };
79DFC11E0B59B8C80056C80E /* Xmod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Xmod.m; sourceTree = "<group>"; };
- 79DFC1270B59BFD60056C80E /* MethodSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MethodSwizzle.h; sourceTree = "<group>"; };
- 79DFC1280B59BFD60056C80E /* MethodSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MethodSwizzle.m; sourceTree = "<group>"; };
+ 79E65E0B0D5631EA00B09941 /* JRSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JRSwizzle.m; path = ../../JRSwizzle/JRSwizzle.m; sourceTree = "<group>"; };
+ 79E65E0C0D5631EA00B09941 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JRSwizzle.h; path = ../../JRSwizzle/JRSwizzle.h; sourceTree = "<group>"; };
79F8A9C20C8FF06600082291 /* Autocustomize Entity Classes.applescript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.applescript; path = "Autocustomize Entity Classes.applescript"; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* Xmod.pbplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Xmod.pbplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -95,8 +95,8 @@
children = (
79DFC11D0B59B8C80056C80E /* Xmod.h */,
79DFC11E0B59B8C80056C80E /* Xmod.m */,
- 79DFC1270B59BFD60056C80E /* MethodSwizzle.h */,
- 79DFC1280B59BFD60056C80E /* MethodSwizzle.m */,
+ 79E65E0C0D5631EA00B09941 /* JRSwizzle.h */,
+ 79E65E0B0D5631EA00B09941 /* JRSwizzle.m */,
);
name = Classes;
sourceTree = "<group>";
@@ -163,9 +163,11 @@
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Xmod" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* Xmod */;
projectDirPath = "";
+ projectRoot = "";
targets = (
8D5B49AC048680CD000E48DA /* Xmod */,
);
@@ -189,7 +191,7 @@
buildActionMask = 2147483647;
files = (
79DFC11F0B59B8C80056C80E /* Xmod.m in Sources */,
- 79DFC1290B59BFD60056C80E /* MethodSwizzle.m in Sources */,
+ 79E65E0D0D5631EA00B09941 /* JRSwizzle.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -210,6 +212,12 @@
1DEB913B08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ARCHS = (
+ ppc64,
+ i386,
+ ppc,
+ x86_64,
+ );
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
@@ -229,8 +237,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
- ppc,
+ ppc64,
i386,
+ ppc,
+ x86_64,
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
@@ -246,20 +256,34 @@
1DEB913F08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ GCC_ENABLE_OBJC_GC = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT = "$(SDKROOT_$(CURRENT_ARCH))";
+ SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_ppc = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_ppc64 = /Developer/SDKs/MacOSX10.5.sdk;
+ SDKROOT_ppc7400 = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_ppc970 = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_x86_64 = /Developer/SDKs/MacOSX10.5.sdk;
};
name = Debug;
};
1DEB914008733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ GCC_ENABLE_OBJC_GC = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT = "$(SDKROOT_$(CURRENT_ARCH))";
+ SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_ppc = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_ppc64 = /Developer/SDKs/MacOSX10.5.sdk;
+ SDKROOT_ppc7400 = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_ppc970 = /Developer/SDKs/MacOSX10.4u.sdk;
+ SDKROOT_x86_64 = /Developer/SDKs/MacOSX10.5.sdk;
};
name = Release;
};
Oops, something went wrong.

0 comments on commit 9d3a214

Please sign in to comment.