From 6fe5cbe1fc10532ac67a9fe9bc95b53c5437267e Mon Sep 17 00:00:00 2001 From: Barrett Jacobsen Date: Tue, 14 Jan 2014 15:36:39 -0600 Subject: [PATCH 01/33] Building will now install into Xcode Plugins directory (i.e. just restart Xcode to see changes) --- CodePilot.xcodeproj/project.pbxproj | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj index aad4fd3..e4f6eba 100644 --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -560,7 +560,7 @@ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastUpgradeCheck = 0510; ORGANIZATIONNAME = Macoscope; }; buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "CodePilot" */; @@ -755,6 +755,9 @@ CLANG_ENABLE_OBJC_ARC = NO; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = "$(HOME)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_GC = unsupproted; @@ -763,7 +766,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Other Sources/CodePilot_Prefix.pch"; INFOPLIST_FILE = Resources/Info.plist; - INSTALL_PATH = "$(HOME)/Library/Bundles"; + INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ( "-licucore", @@ -772,6 +775,7 @@ ); PRODUCT_NAME = CodePilot3; SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = NO; WRAPPER_EXTENSION = xcplugin; }; name = Debug; @@ -783,13 +787,16 @@ CLANG_ENABLE_OBJC_ARC = NO; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = "$(HOME)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_ENABLE_OBJC_GC = unsupproted; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Other Sources/CodePilot_Prefix.pch"; INFOPLIST_FILE = Resources/Info.plist; - INSTALL_PATH = "$(HOME)/Library/Bundles"; + INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ( "-licucore", @@ -798,6 +805,7 @@ ); PRODUCT_NAME = CodePilot3; SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = NO; WRAPPER_EXTENSION = xcplugin; }; name = Release; From 951b39bd27c4283e2f4a89c0e58c4994332c8075 Mon Sep 17 00:00:00 2001 From: czajnikowski Date: Sun, 19 Jan 2014 17:15:26 +0000 Subject: [PATCH 02/33] Fix $PROJECT_DIR problem for paths with white spaces --- CodePilot.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj index aad4fd3..f8974d0 100644 --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -619,7 +619,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "bash $PROJECT_DIR/Installer/build_installer_pkg.command\n"; + shellScript = "bash \"$PROJECT_DIR/Installer/build_installer_pkg.command\"\n"; }; /* End PBXShellScriptBuildPhase section */ From 3c24647e85ac52c1896226c9f7ec03df93aecf56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fjo=CC=88lnir=20A=CC=81sgeirsson?= Date: Sun, 2 Feb 2014 17:54:08 +0900 Subject: [PATCH 03/33] Added the ability to open in an external editor --- Classes/CPCodePilotConfig.h | 2 + Classes/CPPreferencesView.h | 3 +- Classes/CPPreferencesView.m | 19 +++++++++ Classes/CPPreferencesViewController.m | 3 ++ Classes/CPSearchController.m | 8 +++- Classes/CPXcodeInterfaces.h | 2 +- Classes/CPXcodeWrapper.h | 3 ++ Classes/CPXcodeWrapper.m | 56 +++++++++++++++++++-------- Classes/NSURL+Xcode.h | 13 +++++++ Classes/NSURL+Xcode.m | 23 +++++++++++ CodePilot.xcodeproj/project.pbxproj | 12 ++++++ 11 files changed, 125 insertions(+), 19 deletions(-) mode change 100644 => 100755 Classes/CPCodePilotConfig.h mode change 100644 => 100755 Classes/CPPreferencesView.h mode change 100644 => 100755 Classes/CPPreferencesView.m mode change 100644 => 100755 Classes/CPPreferencesViewController.m mode change 100644 => 100755 Classes/CPSearchController.m mode change 100644 => 100755 Classes/CPXcodeInterfaces.h mode change 100644 => 100755 Classes/CPXcodeWrapper.h mode change 100644 => 100755 Classes/CPXcodeWrapper.m create mode 100644 Classes/NSURL+Xcode.h create mode 100644 Classes/NSURL+Xcode.m mode change 100644 => 100755 CodePilot.xcodeproj/project.pbxproj diff --git a/Classes/CPCodePilotConfig.h b/Classes/CPCodePilotConfig.h old mode 100644 new mode 100755 index 235e8b9..9a3d4f1 --- a/Classes/CPCodePilotConfig.h +++ b/Classes/CPCodePilotConfig.h @@ -144,6 +144,7 @@ #define PREFS_VIEW_MIN_HEIGHT 230 #define DEFAULTS_AUTOCOPY_SELECTION_KEY @"MCCodePilotAutocopySelection" +#define DEFAULTS_EXTERNAL_EDITOR_KEY @"MCCodePilotUseExternalEditor" #define DEFAULTS_API_SEARCH_KEY @"MCCodePilotAPISearch" #define DEFAULTS_LAST_VERSION_RUN_KEY @"MCCodePilotLastVersionRun" #define DEFAULTS_USER_LEVEL_DEBUG_KEY @"MCCodePilotUserLevelDebug" @@ -153,6 +154,7 @@ #define DEFAULT_INCLUDE_SUBPROJECTS_VALUE NO #define DEFAULT_AUTOCOPY_SELECTION_VALUE NO +#define DEFAULT_EXTERNAL_EDITOR_SELECTION_VALUE NO #define DEFAULT_API_SEARCH_VALUE YES // longest string we accept in autocopying from current editor's selection diff --git a/Classes/CPPreferencesView.h b/Classes/CPPreferencesView.h old mode 100644 new mode 100755 index 679c771..2098067 --- a/Classes/CPPreferencesView.h +++ b/Classes/CPPreferencesView.h @@ -10,7 +10,8 @@ @interface CPPreferencesView : NSView -@property (nonatomic, strong) NSButton *autocopyingSelectionCheckbox; +@property (nonatomic, strong) NSButton *autocopyingSelectionCheckbox, + *externalEditorCheckbox; - (id)initWithPreferredFrame; diff --git a/Classes/CPPreferencesView.m b/Classes/CPPreferencesView.m old mode 100644 new mode 100755 index e0a3660..1f3497f --- a/Classes/CPPreferencesView.m +++ b/Classes/CPPreferencesView.m @@ -46,6 +46,7 @@ - (void)setupAutoCopyingSelectionOption autocopyingSelectionCheckbox.font = [self boldFont]; [autocopyingSelectionCheckbox setButtonType:NSSwitchButton]; + if (nil == [[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_AUTOCOPY_SELECTION_KEY]) { [autocopyingSelectionCheckbox setState:DEFAULT_AUTOCOPY_SELECTION_VALUE]; } else { @@ -57,6 +58,24 @@ - (void)setupAutoCopyingSelectionOption self.autocopyingSelectionCheckbox = autocopyingSelectionCheckbox; [self addSubview:autocopyingSelectionCheckbox]; + + NSButton *externalEditorCheckbox = [[NSButton alloc] initWithFrame:NSMakeRect(Margin, Margin*1.5 + autocopyingSelectionCheckbox.bounds.size.height, LeftSideWidth, TextHeight)]; + + externalEditorCheckbox.title = @"Use external editor"; + externalEditorCheckbox.font = [self boldFont]; + [externalEditorCheckbox setButtonType:NSSwitchButton]; + + if (nil == [[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_EXTERNAL_EDITOR_KEY]) { + [externalEditorCheckbox setState:DEFAULT_EXTERNAL_EDITOR_SELECTION_VALUE]; + } else { + [externalEditorCheckbox setState:[[NSUserDefaults standardUserDefaults] boolForKey:DEFAULTS_EXTERNAL_EDITOR_KEY]]; + } + + [externalEditorCheckbox sizeToFit]; + + self.externalEditorCheckbox = externalEditorCheckbox; + + [self addSubview:externalEditorCheckbox]; } - (void)setupCopyrightLabel diff --git a/Classes/CPPreferencesViewController.m b/Classes/CPPreferencesViewController.m old mode 100644 new mode 100755 index 85908e2..b3ba229 --- a/Classes/CPPreferencesViewController.m +++ b/Classes/CPPreferencesViewController.m @@ -29,6 +29,9 @@ - (void)applyChanges { BOOL autocopySelectionValue = [self.view.autocopyingSelectionCheckbox state]; [[NSUserDefaults standardUserDefaults] setBool:autocopySelectionValue forKey:DEFAULTS_AUTOCOPY_SELECTION_KEY]; + + BOOL externalEditorValue = [self.view.externalEditorCheckbox state]; + [[NSUserDefaults standardUserDefaults] setBool:externalEditorValue forKey:DEFAULTS_EXTERNAL_EDITOR_KEY]; } @end \ No newline at end of file diff --git a/Classes/CPSearchController.m b/Classes/CPSearchController.m old mode 100644 new mode 100755 index 841a96d..6d67d9f --- a/Classes/CPSearchController.m +++ b/Classes/CPSearchController.m @@ -470,7 +470,13 @@ - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBy if (@selector(insertNewline:) == command || @selector(PBX_insertNewlineAndIndent:) == command) { if (self.selectedElement) { [(CPCodePilotWindowDelegate *)[[self.searchField window] delegate] hideWindow]; - [self.xcodeWrapper openFileOrSymbol:self.selectedElement]; + + BOOL external = [[[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_EXTERNAL_EDITOR_KEY] boolValue]; + if([NSEvent modifierFlags] & NSCommandKeyMask) + external = !external; + [self.xcodeWrapper openFileOrSymbol:self.selectedElement + inExternalEditor:external]; + } return YES; diff --git a/Classes/CPXcodeInterfaces.h b/Classes/CPXcodeInterfaces.h old mode 100644 new mode 100755 index a4911b6..1123fcf --- a/Classes/CPXcodeInterfaces.h +++ b/Classes/CPXcodeInterfaces.h @@ -217,7 +217,7 @@ @end @interface IDEIndexSymbolOccurrence : NSObject -- (id)file; +- (DVTFilePath *)file; - (id)location; - (long long)lineNumber; @end diff --git a/Classes/CPXcodeWrapper.h b/Classes/CPXcodeWrapper.h old mode 100644 new mode 100755 index 8edd50e..0004c77 --- a/Classes/CPXcodeWrapper.h +++ b/Classes/CPXcodeWrapper.h @@ -22,8 +22,11 @@ - (NSScreen *)currentScreen; - (BOOL)currentProjectIsIndexing; - (void)openFileOrSymbol:(id)fileOrSymbol; +- (void)openFileOrSymbol:(id)fileOrSymbol inExternalEditor:(BOOL)aUseExternal; - (void)openCPSymbol:(CPSymbol *)symbol; +- (void)openCPSymbol:(CPSymbol *)symbol inExternalEditor:(BOOL)aUseExternal; - (void)openCPFileReference:(CPFileReference *)cpFileReference; +- (void)openCPFileReference:(CPFileReference *)cpFileReference inExternalEditor:(BOOL)aUseExternal; - (NSString *)currentProjectName; - (NSString *)normalizedQueryForQuery:(NSString *)query; - (NSArray *)contentsForQuery:(NSString *)query fromResult:(CPResult *)result; diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m old mode 100644 new mode 100755 index b0a9ec5..deaa2e1 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -15,6 +15,8 @@ #import "NSMutableArray+MiscExtensions.h" #import "CPWorkspaceSymbolCache.h" #import "CPResult.h" +#import "NSURL+Xcode.h" +#import "NSWorkspace+OpenFileOnLine.h" static NSString * const WorkspaceDocumentsKeyPath = @"workspaceDocuments"; static NSString * const IDEIndexWillIndexWorkspaceNotification = @"IDEIndexWillIndexWorkspaceNotification"; @@ -386,30 +388,47 @@ - (BOOL)isSymbolCachingInProgress } - (void)openFileOrSymbol:(id)fileOrSymbol +{ + [self openFileOrSymbol:fileOrSymbol inExternalEditor:NO]; +} + +- (void)openFileOrSymbol:(id)fileOrSymbol inExternalEditor:(BOOL)aUseExternal { if (nil != fileOrSymbol && [fileOrSymbol isOpenable]) { if ([fileOrSymbol isKindOfClass:[CPSymbol class]]) { - [self openCPSymbol:fileOrSymbol]; - + [self openCPSymbol:fileOrSymbol inExternalEditor:aUseExternal]; } else if ([fileOrSymbol isKindOfClass:[CPFileReference class]]) { - [self openCPFileReference:fileOrSymbol]; + [self openCPFileReference:fileOrSymbol inExternalEditor:aUseExternal]; } } } - (void)openCPFileReference:(CPFileReference *)cpFileReference { - DVTDocumentLocation *documentLocation = [[DVTDocumentLocation alloc] initWithDocumentURL:[cpFileReference fileURL] - timestamp:nil]; - - IDEEditorOpenSpecifier *openSpecifier = [IDEEditorOpenSpecifier structureEditorOpenSpecifierForDocumentLocation:documentLocation - inWorkspace:[self currentWorkspace] - error:nil]; - - [[self currentEditorContext] openEditorOpenSpecifier:openSpecifier]; + [self openCPFileReference:cpFileReference inExternalEditor:NO]; +} + +- (void)openCPFileReference:(CPFileReference *)cpFileReference inExternalEditor:(BOOL)aUseExternal +{ + if(aUseExternal && ![cpFileReference.fileURL cp_opensInXcode]) + [[NSWorkspace sharedWorkspace] openURL:cpFileReference.fileURL]; + else { + DVTDocumentLocation *documentLocation = [[DVTDocumentLocation alloc] initWithDocumentURL:[cpFileReference fileURL] + timestamp:nil]; + + IDEEditorOpenSpecifier *openSpecifier = [IDEEditorOpenSpecifier structureEditorOpenSpecifierForDocumentLocation:documentLocation + inWorkspace:[self currentWorkspace] + error:nil]; + + [[self currentEditorContext] openEditorOpenSpecifier:openSpecifier]; + } } - (void)openCPSymbol:(CPSymbol *)symbol +{ + [self openCPSymbol:symbol inExternalEditor:NO]; +} +- (void)openCPSymbol:(CPSymbol *)symbol inExternalEditor:(BOOL)aUseExternal { if (!symbol.hasOccurrences) { LOG(@"WARNING: Tried to open a symbol without occurrences: %@", symbol); @@ -417,11 +436,16 @@ - (void)openCPSymbol:(CPSymbol *)symbol } @try { - IDEEditorOpenSpecifier *openSpecifier = [IDEEditorOpenSpecifier structureEditorOpenSpecifierForDocumentLocation:[symbol relatedDocumentLocation] - inWorkspace:[self currentWorkspace] - error:nil]; - - [[self currentEditorContext] openEditorOpenSpecifier:openSpecifier]; + IDEIndexSymbolOccurrence *occurrence = [symbol relatedSymbolOccurrence]; + NSURL *url = occurrence.file.fileURL; + if (aUseExternal && ![url cp_opensInXcode]) + [[NSWorkspace sharedWorkspace] cp_openURL:url onLine:occurrence.lineNumber]; + else { + IDEEditorOpenSpecifier *openSpecifier = [IDEEditorOpenSpecifier structureEditorOpenSpecifierForDocumentLocation:[symbol relatedDocumentLocation] + inWorkspace:[self currentWorkspace] + error:nil]; + [[self currentEditorContext] openEditorOpenSpecifier:openSpecifier]; + } } @catch (NSException * e) { LOG(@"EXCEPTION OCCURRED: %@", e); diff --git a/Classes/NSURL+Xcode.h b/Classes/NSURL+Xcode.h new file mode 100644 index 0000000..7ba288d --- /dev/null +++ b/Classes/NSURL+Xcode.h @@ -0,0 +1,13 @@ +// +// NSURL+Xcode.h +// CodePilot +// +// Created by Fjölnir Ásgeirsson on 2/2/14. +// Copyright (c) 2014 Macoscope. All rights reserved. +// + +#import + +@interface NSURL (Xcode) +- (BOOL)cp_opensInXcode; +@end diff --git a/Classes/NSURL+Xcode.m b/Classes/NSURL+Xcode.m new file mode 100644 index 0000000..697b1b7 --- /dev/null +++ b/Classes/NSURL+Xcode.m @@ -0,0 +1,23 @@ +// +// NSURL+Xcode.m +// CodePilot +// +// Created by Fjölnir Ásgeirsson on 2/2/14. +// Copyright (c) 2014 Macoscope. All rights reserved. +// + +#import "NSURL+Xcode.h" + +@implementation NSURL (Xcode) + +- (BOOL)cp_opensInXcode +{ + NSURL *appURL = [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:self]; + if(appURL) { + NSBundle *appBundle = [NSBundle bundleWithURL:appURL]; + NSBundle *xcodeBundle = [NSBundle mainBundle]; + return [appBundle.bundleIdentifier isEqualToString:xcodeBundle.bundleIdentifier]; + } + return NO; +} +@end diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index aad4fd3..223216a --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -83,6 +83,8 @@ 4BEE52751339193600DA9881 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B71F65C11561A15005A8471 /* libssl.dylib */; }; 4BEE52761339193600DA9881 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B71F66011561A5E005A8471 /* libcrypto.dylib */; }; 4BEE52771339193600DA9881 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B25285A1165E23700374EB0 /* WebKit.framework */; }; + C79122D6189E3449001776A1 /* NSURL+Xcode.m in Sources */ = {isa = PBXBuildFile; fileRef = C79122D5189E3449001776A1 /* NSURL+Xcode.m */; }; + C79122D9189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m in Sources */ = {isa = PBXBuildFile; fileRef = C79122D8189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m */; }; F93F4FAD17B3FE550077B19E /* NSColor+ColorArithmetic.m in Sources */ = {isa = PBXBuildFile; fileRef = F93F4FAC17B3FE550077B19E /* NSColor+ColorArithmetic.m */; }; F9979794155D52060023D04C /* CPSymbolCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F9979793155D52060023D04C /* CPSymbolCache.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; F9EAED25179D945100701117 /* CPXcodeInterfaces.m in Sources */ = {isa = PBXBuildFile; fileRef = F9EAED24179D945100701117 /* CPXcodeInterfaces.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; @@ -223,6 +225,10 @@ 4BEB7734138E466D00D52605 /* CPResultScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CPResultScrollView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 4BEE527B1339193600DA9881 /* CodePilot3.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodePilot3.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 4BEE52A513391CBF00DA9881 /* CPCodePilotConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CPCodePilotConfig.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + C79122D4189E3449001776A1 /* NSURL+Xcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+Xcode.h"; sourceTree = ""; }; + C79122D5189E3449001776A1 /* NSURL+Xcode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+Xcode.m"; sourceTree = ""; }; + C79122D7189E391D001776A1 /* NSWorkspace+OpenFileOnLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSWorkspace+OpenFileOnLine.h"; sourceTree = ""; }; + C79122D8189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSWorkspace+OpenFileOnLine.m"; sourceTree = ""; }; D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; F90494C017D650DA00B7C1CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F93F4FAB17B3FE550077B19E /* NSColor+ColorArithmetic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+ColorArithmetic.h"; sourceTree = ""; }; @@ -385,6 +391,10 @@ 4BC0BBF213AEBBB80093D04D /* NSURL+Anchors.m */, F93F4FAB17B3FE550077B19E /* NSColor+ColorArithmetic.h */, F93F4FAC17B3FE550077B19E /* NSColor+ColorArithmetic.m */, + C79122D4189E3449001776A1 /* NSURL+Xcode.h */, + C79122D5189E3449001776A1 /* NSURL+Xcode.m */, + C79122D7189E391D001776A1 /* NSWorkspace+OpenFileOnLine.h */, + C79122D8189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m */, ); name = Categories; sourceTree = ""; @@ -638,6 +648,7 @@ F9F596B417BBF78E0037BE7A /* CPResult.m in Sources */, 4BEE52471339193600DA9881 /* CPResultTableViewColumn.m in Sources */, 4BEE52481339193600DA9881 /* CPResultTableView.m in Sources */, + C79122D6189E3449001776A1 /* NSURL+Xcode.m in Sources */, 4BEE52491339193600DA9881 /* NSString+MiscExtensions.m in Sources */, 4BEE524A1339193600DA9881 /* NSAppleEventDescriptor+ToObject.m in Sources */, 4BEE524B1339193600DA9881 /* MCLog.m in Sources */, @@ -667,6 +678,7 @@ 4BEE52691339193600DA9881 /* CPFirstRunWindowView.m in Sources */, 4BEE526A1339193600DA9881 /* NSMutableArray+MiscExtensions.m in Sources */, 4BEE526C1339193600DA9881 /* MCStringScoring.c in Sources */, + C79122D9189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m in Sources */, 4BEE526E1339193600DA9881 /* CPSymbol.m in Sources */, 4B30A186133979A7008A4372 /* CPPluginInstaller.m in Sources */, 4B4DCEF21363543B0009304C /* CPPreferencesToolbarDelegate.m in Sources */, From cc6d986c9691704803f5614f1be05ab61d884800 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Thu, 6 Feb 2014 13:19:39 +0100 Subject: [PATCH 04/33] Ignore build/ folder created with `xcodebuild` --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/ From bcb2b8cc1d89176fd2bab2897358f5a26adae9c0 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Thu, 6 Feb 2014 13:22:08 +0100 Subject: [PATCH 05/33] Support Xcode 5.1 --- Resources/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index dba1354..c1d5653 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -54,6 +54,7 @@ NO DVTPlugInCompatibilityUUIDs + 640F884E-CE55-4B40-87C0-8869546CAB7A 63FC1C47-140D-42B0-BB4D-A10B2D225574 37B30044-3B14-46BA-ABAA-F01000C27B63 From 40fa44971bfcac55fbb29307dec74a9982cb60b3 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Thu, 6 Feb 2014 13:24:33 +0100 Subject: [PATCH 06/33] Add CodePilot to the end of prefs toolbar This solved issue that Xcode5 last tab Locations gets hidden, however likely we gonna use it more often than CodePilot's one. --- Classes/CPPreferencesToolbarDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/CPPreferencesToolbarDelegate.m b/Classes/CPPreferencesToolbarDelegate.m index 9d819eb..aff8039 100644 --- a/Classes/CPPreferencesToolbarDelegate.m +++ b/Classes/CPPreferencesToolbarDelegate.m @@ -34,7 +34,7 @@ + (CPPreferencesToolbarDelegate *)preferencesToolbarDelegateByInterceptingDelega toolbarDelegate = [[CPPreferencesToolbarDelegate alloc] initWithOriginalToolbarDelegate:originalToolbarDelegate toolbar:toolbar]; [toolbar setDelegate:toolbarDelegate]; - [toolbar insertItemWithItemIdentifier:PREFERENCES_TOOLBAR_ITEM_IDENTIFIER atIndex:3]; + [toolbar insertItemWithItemIdentifier:PREFERENCES_TOOLBAR_ITEM_IDENTIFIER atIndex:toolbar.items.count]; return toolbarDelegate; } From 7284de8b48dcc1e28a44613430166e9051ccd2d8 Mon Sep 17 00:00:00 2001 From: Dima Date: Wed, 12 Mar 2014 00:31:10 -0400 Subject: [PATCH 07/33] Xcode 5.1 Compatibility --- Resources/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index dba1354..9c1a24d 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -56,6 +56,7 @@ 63FC1C47-140D-42B0-BB4D-A10B2D225574 37B30044-3B14-46BA-ABAA-F01000C27B63 + A2E4D43F-41F4-4FB9-BB94-7177011C9AED From 2137335d80034cf9bdcf37a19b2c7a85257cb00b Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Wed, 12 Mar 2014 12:55:45 +0100 Subject: [PATCH 08/33] Xcode 5.1 final UUID Previous UUID was different in betas. --- Resources/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index c1d5653..8c0afc1 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -57,6 +57,7 @@ 640F884E-CE55-4B40-87C0-8869546CAB7A 63FC1C47-140D-42B0-BB4D-A10B2D225574 37B30044-3B14-46BA-ABAA-F01000C27B63 + A2E4D43F-41F4-4FB9-BB94-7177011C9AED From 769889cf1ae89f666c50d86e853a70f9146406cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fjo=CC=88lnir=20A=CC=81sgeirsson?= Date: Mon, 12 May 2014 10:49:17 +0900 Subject: [PATCH 09/33] Added missing NSWorkspace category --- Classes/NSWorkspace+OpenFileOnLine.h | 13 ++++++++ Classes/NSWorkspace+OpenFileOnLine.m | 50 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 Classes/NSWorkspace+OpenFileOnLine.h create mode 100644 Classes/NSWorkspace+OpenFileOnLine.m diff --git a/Classes/NSWorkspace+OpenFileOnLine.h b/Classes/NSWorkspace+OpenFileOnLine.h new file mode 100644 index 0000000..7f785e1 --- /dev/null +++ b/Classes/NSWorkspace+OpenFileOnLine.h @@ -0,0 +1,13 @@ +// +// NSWorkspace+OpenFileOnLine.h +// CodePilot +// +// Created by Fjölnir Ásgeirsson on 2/2/14. +// Copyright (c) 2014 Macoscope. All rights reserved. +// + +#import + +@interface NSWorkspace (OpenFileOnLine) +- (void)cp_openURL:(NSURL *)url onLine:(NSUInteger)line; +@end diff --git a/Classes/NSWorkspace+OpenFileOnLine.m b/Classes/NSWorkspace+OpenFileOnLine.m new file mode 100644 index 0000000..d114852 --- /dev/null +++ b/Classes/NSWorkspace+OpenFileOnLine.m @@ -0,0 +1,50 @@ +// +// NSWorkspace+OpenFileOnLine.m +// CodePilot +// +// Created by Fjölnir Ásgeirsson on 2/2/14. +// Copyright (c) 2014 Macoscope. All rights reserved. +// + +#import "NSWorkspace+OpenFileOnLine.h" + +NSString *kSublimeText2Identifier = @"com.sublimetext.2"; +NSString *kSublimeText3Identifier = @"com.sublimetext.3"; +NSString *kMacVimIdentifier = @"org.vim.MacVim"; +NSString *kTextmateIdentifier = @"com.macromates.textmate"; +NSString *kTextmate2Identifier = @"com.macromates.textmate.preview"; +NSString *kBBEditIdentifier = @"com.barebones.bbedit"; + + +@implementation NSWorkspace (OpenFileOnLine) + ++ (NSString *)cp_schemeForEditor:(NSString *)editor +{ + if ([editor isEqualToString:kSublimeText2Identifier] || + [editor isEqualToString:kSublimeText3Identifier]) + return @"subl"; + if ([editor isEqualToString:kMacVimIdentifier]) + return @"mvim"; + if ([editor isEqualToString:kTextmateIdentifier]) + return @"txmt"; + if ([editor isEqualToString:kBBEditIdentifier]) + return @"txmt"; + else + return nil; +} + +- (void)cp_openURL:(NSURL *)url onLine:(NSUInteger)line +{ + NSURL *editorURL = [self URLForApplicationToOpenURL:url]; + NSString *editorIdentifier = [[NSBundle bundleWithURL:editorURL] bundleIdentifier]; + NSString *scheme = [[self class] cp_schemeForEditor:editorIdentifier]; + + if (scheme) + url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://open?url=%@&line=%lu", + scheme, + [[url absoluteString] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], + (unsigned long)line]]; + [self openURL:url]; +} + +@end From 0d108fe51b8fea854da75760d2909e922f68e6bd Mon Sep 17 00:00:00 2001 From: pendowski Date: Mon, 22 Dec 2014 17:27:44 +0100 Subject: [PATCH 10/33] Added missing plug-in compatibility UUID for Xcode 6.1 --- Resources/Info.plist | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Info.plist b/Resources/Info.plist index 8c0afc1..740a79a 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -36,6 +36,14 @@ 0400 DTXcodeBuild + DVTPlugInCompatibilityUUIDs + + 640F884E-CE55-4B40-87C0-8869546CAB7A + 63FC1C47-140D-42B0-BB4D-A10B2D225574 + 37B30044-3B14-46BA-ABAA-F01000C27B63 + A2E4D43F-41F4-4FB9-BB94-7177011C9AED + C4A681B0-4A26-480E-93EC-1218098B9AA0 + NSPrincipalClass CPCodePilotPlugin SUEnableAutomaticChecks @@ -52,12 +60,5 @@ YES XCPluginHasUI NO - DVTPlugInCompatibilityUUIDs - - 640F884E-CE55-4B40-87C0-8869546CAB7A - 63FC1C47-140D-42B0-BB4D-A10B2D225574 - 37B30044-3B14-46BA-ABAA-F01000C27B63 - A2E4D43F-41F4-4FB9-BB94-7177011C9AED - From f91303c198560bcb578626202a6c1a9fbc7e9149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ka=C5=82uz=CC=87ny?= Date: Tue, 31 Mar 2015 16:04:54 +0200 Subject: [PATCH 11/33] Removed ancient Regexp Library and replaced it with stock NSRegularExpression --- Classes/CPCodePilotConfig.h | 1 - Classes/CPFileReference.m | 1 - Classes/CPSymbol.m | 1 - Classes/CPXcodeWrapper.m | 6 +- Classes/RegexKitLite.h | 220 ---- Classes/RegexKitLite.m | 1657 --------------------------- CodePilot.xcodeproj/project.pbxproj | 13 - 7 files changed, 5 insertions(+), 1894 deletions(-) delete mode 100644 Classes/RegexKitLite.h delete mode 100644 Classes/RegexKitLite.m diff --git a/Classes/CPCodePilotConfig.h b/Classes/CPCodePilotConfig.h index 235e8b9..38ca7d8 100644 --- a/Classes/CPCodePilotConfig.h +++ b/Classes/CPCodePilotConfig.h @@ -4,7 +4,6 @@ #import #import "MCCommons.h" #import "MCLog.h" -#import "RegexKitLite.h" #import #import #import "CPCodePilotPlugin.h" diff --git a/Classes/CPFileReference.m b/Classes/CPFileReference.m index 8e77560..12f5817 100644 --- a/Classes/CPFileReference.m +++ b/Classes/CPFileReference.m @@ -7,7 +7,6 @@ // #import "CPFileReference.h" -#import "RegexKitLite.h" #import "CPCodePilotConfig.h" #import "CPXcodeInterfaces.h" #import "objc/objc-class.h" diff --git a/Classes/CPSymbol.m b/Classes/CPSymbol.m index be0bfda..5fa5a53 100644 --- a/Classes/CPSymbol.m +++ b/Classes/CPSymbol.m @@ -6,7 +6,6 @@ // Copyright 2010 Macoscope. All rights reserved. // -#import "RegexKitLite.h" #import "CPFileReference.h" #import "CPSymbol.h" #import diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index b0a9ec5..28ee54a 100644 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -148,7 +148,11 @@ - (BOOL)hasOpenWorkspace - (NSString *)normalizedQueryForQuery:(NSString *)query { - return [query stringByReplacingOccurrencesOfRegex:@"[\\*\\ \\r\\n\\t]" withString:@""]; + NSMutableString *mQuery = [query mutableCopy]; + NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"[\\*\\ \\r\\n\\t]" options:NSRegularExpressionCaseInsensitive error:nil]; + + [regex replaceMatchesInString:mQuery options:NSMatchingAnchored range:NSRangeFromString(mQuery) withTemplate:@""]; + return mQuery; } - (CPWorkspaceSymbolCache *)workspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace diff --git a/Classes/RegexKitLite.h b/Classes/RegexKitLite.h deleted file mode 100644 index 920cb43..0000000 --- a/Classes/RegexKitLite.h +++ /dev/null @@ -1,220 +0,0 @@ -// -// RegexKitLite.h -// http://regexkit.sourceforge.net/ -// Licensed under the terms of the BSD License, as specified below. -// - -/* - Copyright (c) 2008-2009, John Engelhart - - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the Zang Industries nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef __OBJC__ -#import -#import -#import -#import -#import -#endif // __OBJC__ - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef REGEXKITLITE_VERSION_DEFINED -#define REGEXKITLITE_VERSION_DEFINED - -#define _RKL__STRINGIFY(b) #b -#define _RKL_STRINGIFY(a) _RKL__STRINGIFY(a) -#define _RKL_JOIN_VERSION(a,b) _RKL_STRINGIFY(a##.##b) -#define _RKL_VERSION_STRING(a,b) _RKL_JOIN_VERSION(a,b) - -#define REGEXKITLITE_VERSION_MAJOR 3 -#define REGEXKITLITE_VERSION_MINOR 3 - -#define REGEXKITLITE_VERSION_CSTRING _RKL_VERSION_STRING(REGEXKITLITE_VERSION_MAJOR, REGEXKITLITE_VERSION_MINOR) -#define REGEXKITLITE_VERSION_NSSTRING @REGEXKITLITE_VERSION_CSTRING - -#endif // REGEXKITLITE_VERSION_DEFINED - -// For Mac OS X < 10.5. -#ifndef NSINTEGER_DEFINED -#define NSINTEGER_DEFINED -#if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64) -typedef long NSInteger; -typedef unsigned long NSUInteger; -#define NSIntegerMin LONG_MIN -#define NSIntegerMax LONG_MAX -#define NSUIntegerMax ULONG_MAX -#else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64) -typedef int NSInteger; -typedef unsigned int NSUInteger; -#define NSIntegerMin INT_MIN -#define NSIntegerMax INT_MAX -#define NSUIntegerMax UINT_MAX -#endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64) -#endif // NSINTEGER_DEFINED - -#ifndef RKLREGEXOPTIONS_DEFINED -#define RKLREGEXOPTIONS_DEFINED - -// These must be idential to their ICU regex counterparts. See http://www.icu-project.org/userguide/regexp.html -enum { - RKLNoOptions = 0, - RKLCaseless = 2, - RKLComments = 4, - RKLDotAll = 32, - RKLMultiline = 8, - RKLUnicodeWordBoundaries = 256 -}; -typedef uint32_t RKLRegexOptions; // This must be identical to the ICU 'flags' argument type. - -#endif // RKLREGEXOPTIONS_DEFINED - -#ifndef _REGEXKITLITE_H_ -#define _REGEXKITLITE_H_ - -#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__APPLE_CC__) && (__APPLE_CC__ >= 5465) -#define RKL_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) -#else -#define RKL_DEPRECATED_ATTRIBUTE -#endif - -// This requires a few levels of rewriting to get the desired results. -#define _RKL_CONCAT_2(c,d) c ## d -#define _RKL_CONCAT(a,b) _RKL_CONCAT_2(a,b) - -#ifdef RKL_PREPEND_TO_METHODS -#define RKL_METHOD_PREPEND(x) _RKL_CONCAT(RKL_PREPEND_TO_METHODS, x) -#else // RKL_PREPEND_TO_METHODS -#define RKL_METHOD_PREPEND(x) x -#endif // RKL_PREPEND_TO_METHODS - -// If it looks like low memory notifications might be available, add code to register and respond to them. -// This is (should be) harmless if it turns out that this isn't the case, since the notification that we register for, -// UIApplicationDidReceiveMemoryWarningNotification, is dynamically looked up via dlsym(). -#if ((defined(TARGET_OS_EMBEDDED) && (TARGET_OS_EMBEDDED != 0)) || (defined(TARGET_OS_IPHONE) && (TARGET_OS_IPHONE != 0))) && (!defined(RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS) || (RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS != 0)) -#define RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS 1 -#endif - -#ifdef __OBJC__ - -// NSException exception name. -extern NSString * const RKLICURegexException; - -// NSError error domains and user info keys. -extern NSString * const RKLICURegexErrorDomain; - -extern NSString * const RKLICURegexErrorCodeErrorKey; -extern NSString * const RKLICURegexErrorNameErrorKey; -extern NSString * const RKLICURegexLineErrorKey; -extern NSString * const RKLICURegexOffsetErrorKey; -extern NSString * const RKLICURegexPreContextErrorKey; -extern NSString * const RKLICURegexPostContextErrorKey; -extern NSString * const RKLICURegexRegexErrorKey; -extern NSString * const RKLICURegexRegexOptionsErrorKey; - -@interface NSString (RegexKitLiteAdditions) - -+ (void)RKL_METHOD_PREPEND(clearStringCache); - -// Although these are marked as deprecated, a bug in GCC prevents a warning from being issues for + class methods. Filed bug with Apple, #6736857. -+ (NSInteger)RKL_METHOD_PREPEND(captureCountForRegex):(NSString *)regex RKL_DEPRECATED_ATTRIBUTE; -+ (NSInteger)RKL_METHOD_PREPEND(captureCountForRegex):(NSString *)regex options:(RKLRegexOptions)options error:(NSError **)error RKL_DEPRECATED_ATTRIBUTE; - -- (NSArray *)RKL_METHOD_PREPEND(componentsSeparatedByRegex):(NSString *)regex; -- (NSArray *)RKL_METHOD_PREPEND(componentsSeparatedByRegex):(NSString *)regex range:(NSRange)range; -- (NSArray *)RKL_METHOD_PREPEND(componentsSeparatedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range error:(NSError **)error; - -- (BOOL)RKL_METHOD_PREPEND(isMatchedByRegex):(NSString *)regex; -- (BOOL)RKL_METHOD_PREPEND(isMatchedByRegex):(NSString *)regex inRange:(NSRange)range; -- (BOOL)RKL_METHOD_PREPEND(isMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options inRange:(NSRange)range error:(NSError **)error; - -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex; -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex capture:(NSInteger)capture; -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex inRange:(NSRange)range; -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex options:(RKLRegexOptions)options inRange:(NSRange)range capture:(NSInteger)capture error:(NSError **)error; - -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex; -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex capture:(NSInteger)capture; -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex inRange:(NSRange)range; -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex options:(RKLRegexOptions)options inRange:(NSRange)range capture:(NSInteger)capture error:(NSError **)error; - -- (NSString *)RKL_METHOD_PREPEND(stringByReplacingOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement; -- (NSString *)RKL_METHOD_PREPEND(stringByReplacingOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement range:(NSRange)searchRange; -- (NSString *)RKL_METHOD_PREPEND(stringByReplacingOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement options:(RKLRegexOptions)options range:(NSRange)searchRange error:(NSError **)error; - - //// - -- (NSInteger)RKL_METHOD_PREPEND(captureCount); -- (NSInteger)RKL_METHOD_PREPEND(captureCountWithOptions):(RKLRegexOptions)options error:(NSError **)error; - -- (BOOL)RKL_METHOD_PREPEND(isRegexValid); -- (BOOL)RKL_METHOD_PREPEND(isRegexValidWithOptions):(RKLRegexOptions)options error:(NSError **)error; - -- (void)RKL_METHOD_PREPEND(flushCachedRegexData); - -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex; -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex capture:(NSInteger)capture; -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex range:(NSRange)range; -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range capture:(NSInteger)capture error:(NSError **)error; - - -- (NSArray *)RKL_METHOD_PREPEND(captureComponentsMatchedByRegex):(NSString *)regex; -- (NSArray *)RKL_METHOD_PREPEND(captureComponentsMatchedByRegex):(NSString *)regex range:(NSRange)range; -- (NSArray *)RKL_METHOD_PREPEND(captureComponentsMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range error:(NSError **)error; - -- (NSArray *)RKL_METHOD_PREPEND(arrayOfCaptureComponentsMatchedByRegex):(NSString *)regex; -- (NSArray *)RKL_METHOD_PREPEND(arrayOfCaptureComponentsMatchedByRegex):(NSString *)regex range:(NSRange)range; -- (NSArray *)RKL_METHOD_PREPEND(arrayOfCaptureComponentsMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range error:(NSError **)error; - -@end - -@interface NSMutableString (RegexKitLiteAdditions) - -- (NSUInteger)RKL_METHOD_PREPEND(replaceOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement; -- (NSUInteger)RKL_METHOD_PREPEND(replaceOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement range:(NSRange)searchRange; -- (NSUInteger)RKL_METHOD_PREPEND(replaceOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement options:(RKLRegexOptions)options range:(NSRange)searchRange error:(NSError **)error; - -@end - -#endif // __OBJC__ - -#endif // _REGEXKITLITE_H_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/Classes/RegexKitLite.m b/Classes/RegexKitLite.m deleted file mode 100644 index 743edae..0000000 --- a/Classes/RegexKitLite.m +++ /dev/null @@ -1,1657 +0,0 @@ -// -// RegexKitLite.m -// http://regexkit.sourceforge.net/ -// Licensed under the terms of the BSD License, as specified below. -// - -/* - Copyright (c) 2008-2009, John Engelhart - - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the Zang Industries nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#import -#import -#import -#import -#import -#import -#ifdef __OBJC_GC__ -#import -#define RKL_STRONG_REF __strong -#else // __OBJC_GC__ -#define RKL_STRONG_REF -#endif // __OBJC_GC__ - -#if (defined(TARGET_OS_EMBEDDED) && (TARGET_OS_EMBEDDED != 0)) || (defined(TARGET_OS_IPHONE) && (TARGET_OS_IPHONE != 0)) || (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)) -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#import "RegexKitLite.h" - -// If the gcc flag -mmacosx-version-min is used with, for example, '=10.2', give a warning that the libicucore.dylib is only available on >= 10.3. -// If you are reading this comment because of this warning, this is to let you know that linking to /usr/lib/libicucore.dylib will cause your executable to fail on < 10.3. -// You will need to build your own version of the ICU library and link to that in order for RegexKitLite to work successfully on < 10.3. This is not simple. - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030 -#warning The ICU dynamic shared library, /usr/lib/libicucore.dylib, is only available on Mac OS X 10.3 and later. -#warning You will need to supply a version of the ICU library to use RegexKitLite on Mac OS X 10.2 and earlier. -#endif - -//////////// -#pragma mark Compile time tuneables - -#ifndef RKL_CACHE_SIZE -#define RKL_CACHE_SIZE (23UL) -#endif - -#ifndef RKL_FIXED_LENGTH -#define RKL_FIXED_LENGTH (2048UL) -#endif - -#ifndef RKL_STACK_LIMIT -#define RKL_STACK_LIMIT (128UL * 1024UL) -#endif - -#ifdef RKL_APPEND_TO_ICU_FUNCTIONS -#define RKL_ICU_FUNCTION_APPEND(x) _RKL_CONCAT(x, RKL_APPEND_TO_ICU_FUNCTIONS) -#else // RKL_APPEND_TO_ICU_FUNCTIONS -#define RKL_ICU_FUNCTION_APPEND(x) x -#endif // RKL_APPEND_TO_ICU_FUNCTIONS - -#if defined(RKL_DTRACE) && (RKL_DTRACE != 0) -#define _RKL_DTRACE_ENABLED -#endif // defined(RKL_DTRACE) && (RKL_DTRACE != 0) - -// These are internal, non-public tuneables. -#define RKL_SCRATCH_BUFFERS (4UL) -#define RKL_CACHE_LINE_SIZE (64UL) -#define RKL_DTRACE_REGEXUTF8_SIZE (64UL) - -////////////// -#pragma mark - -#pragma mark GCC / Compiler macros - -#if defined (__GNUC__) && (__GNUC__ >= 4) -#define RKL_ATTRIBUTES(attr, ...) __attribute__((attr, ##__VA_ARGS__)) -#define RKL_EXPECTED(cond, expect) __builtin_expect((long)(cond), (expect)) -#define RKL_PREFETCH(ptr) __builtin_prefetch(ptr) -#define RKL_PREFETCH_UNICHAR(ptr, off) { const char *p = ((const char *)(ptr)) + ((off) * sizeof(UniChar)) + RKL_CACHE_LINE_SIZE; RKL_PREFETCH(p); RKL_PREFETCH(p + RKL_CACHE_LINE_SIZE); } -#define RKL_HAVE_CLEANUP -#define RKL_CLEANUP(func) RKL_ATTRIBUTES(cleanup(func)) -#else // defined (__GNUC__) && (__GNUC__ >= 4) -#define RKL_ATTRIBUTES(attr, ...) -#define RKL_EXPECTED(cond, expect) (cond) -#define RKL_PREFETCH(ptr) -#define RKL_PREFETCH_UNICHAR(ptr, off) -#define RKL_CLEANUP(func) -#endif // defined (__GNUC__) && (__GNUC__ >= 4) - -#define RKL_STATIC_INLINE static __inline__ RKL_ATTRIBUTES(always_inline) -#define RKL_UNUSED_ARG RKL_ATTRIBUTES(unused) -#define RKL_NONNULL_ARGS(arg, ...) RKL_ATTRIBUTES(nonnull(arg, ##__VA_ARGS__)) -#define RKL_NONNULL_ARGS_WARN_UNUSED(arg, ...) RKL_ATTRIBUTES(warn_unused_result, nonnull(arg, ##__VA_ARGS__)) - -#if defined (__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) -#define RKL_ALLOC_SIZE_NON_NULL_ARGS_WARN_UNUSED(as, nn, ...) RKL_ATTRIBUTES(warn_unused_result, nonnull(nn, ##__VA_ARGS__), alloc_size(as)) -#else // defined (__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) -#define RKL_ALLOC_SIZE_NON_NULL_ARGS_WARN_UNUSED(as, nn, ...) RKL_ATTRIBUTES(warn_unused_result, nonnull(nn, ##__VA_ARGS__)) -#endif // defined (__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) - - -//////////// -#pragma mark - -#pragma mark Assertion macros - -// These macros are nearly identical to their NSCParameterAssert siblings. -// This is required because nearly everything is done while cacheSpinLock is locked. -// We need to safely unlock before throwing any of these exceptions. -// @try {} @finally {} significantly slows things down so it's not used. - -#define RKLCAssertDictionary(d, ...) rkl_makeAssertDictionary(__PRETTY_FUNCTION__, __FILE__, __LINE__, (d), ##__VA_ARGS__) -#define RKLCDelayedHardAssert(c, e, g) do { id *_e=(e); int _c=(c); if(RKL_EXPECTED(_e == NULL, 0L) || RKL_EXPECTED(*_e != NULL, 0L)) { goto g; } if(RKL_EXPECTED(!_c, 0L)) { *_e = RKLCAssertDictionary(@"Invalid parameter not satisfying: %s", #c); goto g; } } while(0) - -#ifdef NS_BLOCK_ASSERTIONS -#define RKLCDelayedAssert(c, e, g) -#define RKL_UNUSED_ASSERTION_ARG RKL_ATTRIBUTES(unused) -#else // NS_BLOCK_ASSERTIONS -#define RKLCDelayedAssert(c, e, g) RKLCDelayedHardAssert(c, e, g) -#define RKL_UNUSED_ASSERTION_ARG -#endif // NS_BLOCK_ASSERTIONS - -#define RKL_EXCEPTION(e, f, ...) [NSException exceptionWithName:(e) reason:rkl_stringFromClassAndMethod((self), (_cmd), (f), ##__VA_ARGS__) userInfo:NULL] -#define RKL_RAISE_EXCEPTION(e, f, ...) [RKL_EXCEPTION(e, f, ##__VA_ARGS__) raise] - -//////////// -#pragma mark - -#pragma mark Utility functions and macros - -RKL_STATIC_INLINE BOOL NSRangeInsideRange(NSRange cin, NSRange win) RKL_ATTRIBUTES(warn_unused_result); -RKL_STATIC_INLINE BOOL NSRangeInsideRange(NSRange cin, NSRange win) { return((((cin.location - win.location) <= win.length) && ((NSMaxRange(cin) - win.location) <= win.length)) ? YES : NO); } - -#define NSMakeRange(loc, len) ((NSRange){.location=(NSUInteger)(loc), .length=(NSUInteger)(len)}) -#define CFMakeRange(loc, len) ((CFRange){.location= (CFIndex)(loc), .length= (CFIndex)(len)}) -#ifndef NSNotFoundRange -#define NSNotFoundRange ((NSRange){.location=(NSUInteger)NSNotFound, .length= 0UL}) -#endif -#define NSMaxiumRange ((NSRange){.location= 0UL, .length= NSUIntegerMax}) - -//////////// -#pragma mark - -#pragma mark Exported NSString symbols for exception names, error domains, error keys, etc - -NSString * const RKLICURegexException = @"RKLICURegexException"; - -NSString * const RKLICURegexErrorDomain = @"RKLICURegexErrorDomain"; - -NSString * const RKLICURegexErrorCodeErrorKey = @"RKLICURegexErrorCode"; -NSString * const RKLICURegexErrorNameErrorKey = @"RKLICURegexErrorName"; -NSString * const RKLICURegexLineErrorKey = @"RKLICURegexLine"; -NSString * const RKLICURegexOffsetErrorKey = @"RKLICURegexOffset"; -NSString * const RKLICURegexPreContextErrorKey = @"RKLICURegexPreContext"; -NSString * const RKLICURegexPostContextErrorKey = @"RKLICURegexPostContext"; -NSString * const RKLICURegexRegexErrorKey = @"RKLICURegexRegex"; -NSString * const RKLICURegexRegexOptionsErrorKey = @"RKLICURegexRegexOptions"; - -//////////// -#pragma mark - -#pragma mark Type / struct definitions - -// In general, the ICU bits and pieces here must exactly match the definition in the ICU sources. - -#define U_STRING_NOT_TERMINATED_WARNING -124 -#define U_ZERO_ERROR 0 -#define U_INDEX_OUTOFBOUNDS_ERROR 8 -#define U_BUFFER_OVERFLOW_ERROR 15 -#define U_PARSE_CONTEXT_LEN 16 - -typedef struct uregex uregex; // Opaque ICU regex type. - -typedef struct UParseError { // This must be exactly the same as the 'real' ICU declaration. - int32_t line; - int32_t offset; - UniChar preContext[U_PARSE_CONTEXT_LEN]; - UniChar postContext[U_PARSE_CONTEXT_LEN]; -} UParseError; - -// For use with GCC's cleanup() __attribute__. -#define RKLLockedCacheSpinLock ((NSUInteger)(1UL<<0)) -#define RKLUnlockedCacheSpinLock ((NSUInteger)(1UL<<1)) - -enum { - RKLSplitOp = 1, - RKLReplaceOp = 2, - RKLRangeOp = 3, - RKLArrayOfStringsOp = 4, - RKLArrayOfCapturesOp = 5, - RKLCapturesArrayOp = 6, - RKLMaskOp = 0xf, - RKLReplaceMutable = 1 << 4, - RKLSubcapturesArray = 1 << 5, -}; -typedef NSUInteger RKLRegexOp; - -typedef struct { - NSRange *ranges, findInRange; - NSInteger capacity, found, findUpTo, capture; - size_t size, stackUsed; - void **rangesScratchBuffer; - RKL_STRONG_REF void **stringsScratchBuffer; - RKL_STRONG_REF void **arraysScratchBuffer; -} RKLFindAll; - -typedef struct { - CFStringRef string; - CFHashCode hash; - CFIndex length; - RKL_STRONG_REF UniChar *uniChar; -} RKLBuffer; - -typedef struct { - CFStringRef regexString; - RKLRegexOptions options; - uregex *icu_regex; - NSInteger captureCount; - - CFStringRef setToString; - CFHashCode setToHash; - CFIndex setToLength; - NSUInteger setToIsImmutable:1; - NSUInteger setToNeedsConversion:1; - const UniChar *setToUniChar; - NSRange setToRange, lastFindRange, lastMatchRange; -#ifndef __LP64__ - NSUInteger pad[1]; // For 32 bits, this makes the struct 64 bytes exactly, which is good for cache line alignment. -#endif // __LP64__ -} RKLCacheSlot; - -//////////// -#pragma mark - -#pragma mark Translation unit scope global variables - -static UniChar fixedUniChar[(RKL_FIXED_LENGTH)]; // This is the fixed sized UTF-16 conversion buffer. -static RKLCacheSlot rkl_cacheSlots[(RKL_CACHE_SIZE)], *lastCacheSlot; -static OSSpinLock cacheSpinLock = OS_SPINLOCK_INIT; -static RKLBuffer dynamicBuffer, fixedBuffer = {NULL, 0UL, 0L, &fixedUniChar[0]}; -static const UniChar emptyUniCharString[1]; // For safety, icu_regexes are 'set' to this when the string they were searched is cleared. -static RKL_STRONG_REF void *scratchBuffer[(RKL_SCRATCH_BUFFERS)]; // Used to hold temporary allocations that are allocated via reallocf(). - -//////////// -#pragma mark - -#pragma mark CFArray call backs - -// These are used when running under manual memory management for the array that rkl_splitArray creates. -// The split strings are created, but not autoreleased. The (immutable) array is created using these callbacks, which skips the CFRetain() call, effectively transferring ownership to the CFArray object. -// For each split string this saves the overhead of an autorelease, then an array retain, then an NSAutoreleasePool release. This is good for a ~30% speed increase. - -static void RKLCFArrayRelease (CFAllocatorRef allocator RKL_UNUSED_ARG, const void *ptr) { CFRelease((CFTypeRef)ptr); } -static const CFArrayCallBacks rkl_transferOwnershipArrayCallBacks = { (CFIndex)0L, NULL, RKLCFArrayRelease, CFCopyDescription, CFEqual }; - -#ifdef __OBJC_GC__ -//////////// -#pragma mark - -#pragma mark Low-level Garbage Collection aware memory/resource allocation utilities -// If compiled with Garbage Collection, we need to be able to do a few things slightly differently. -// The basic premiss is that under GC we use a trampoline function pointer which is set to a _start function to catch the first invocation. -// The _start function checks if GC is running and then overwrites the function pointer with the appropriate routine. Think of it as 'lazy linking'. - -enum { RKLScannedOption = NSScannedOption }; - -// rkl_collectingEnabled uses objc_getClass() to get the NSGarbageCollector class, which doesn't exist on earlier systems. -// This allows for graceful failure should we find ourselves running on an earlier version of the OS without NSGarbageCollector. -static BOOL rkl_collectingEnabled_first (void); -static BOOL rkl_collectingEnabled_yes (void) { return(YES); } -static BOOL rkl_collectingEnabled_no (void) { return(NO); } -static BOOL(*rkl_collectingEnabled) (void) = rkl_collectingEnabled_first; -static BOOL rkl_collectingEnabled_first (void) { - BOOL gcEnabled = ([objc_getClass("NSGarbageCollector") defaultCollector] != NULL) ? YES : NO; - if(gcEnabled == YES) { - // This section of code is required due to what I consider to be a fundamental design flaw in Cocoas GC system. - // Earlier versions of "Garbage Collection Programming Guide" stated that (paraphrased) "all globals are automatically roots". - // Current versions of the guide now include the following warning: - // "You may pass addresses of strong globals or statics into routines expecting pointers to object pointers (such as id* or NSError**) - // only if they have first been assigned to directly, rather than through a pointer dereference." - // This is a surprisingly non-trivial condition to actually meet in practice and is a recipe for impossible to debug race condition bugs. - // We just happen to be very, very, very lucky in the fact that we can initilize our root set before the first use. - int x; - for(x = 0; x < (int)(RKL_SCRATCH_BUFFERS); x++) { scratchBuffer[x] = NSAllocateCollectable(16UL, 0UL); scratchBuffer[x] = NULL; } - dynamicBuffer.uniChar = (RKL_STRONG_REF UniChar *)NSAllocateCollectable(16UL, 0UL); dynamicBuffer.uniChar = NULL; - } - return((rkl_collectingEnabled = (gcEnabled == YES) ? rkl_collectingEnabled_yes : rkl_collectingEnabled_no)()); -} - -// rkl_realloc() -static void *rkl_realloc_first (RKL_STRONG_REF void **ptr, size_t size, NSUInteger flags); -static void *rkl_realloc_std (RKL_STRONG_REF void **ptr, size_t size, NSUInteger flags RKL_UNUSED_ARG) { return((*ptr = reallocf(*ptr, size))); } -static void *rkl_realloc_gc (RKL_STRONG_REF void **ptr, size_t size, NSUInteger flags) { return((*ptr = NSReallocateCollectable(*ptr, (NSUInteger)size, flags))); } -static void *(*rkl_realloc) (RKL_STRONG_REF void **ptr, size_t size, NSUInteger flags) RKL_ALLOC_SIZE_NON_NULL_ARGS_WARN_UNUSED(2,1) = rkl_realloc_first; -static void *rkl_realloc_first (RKL_STRONG_REF void **ptr, size_t size, NSUInteger flags) { if(rkl_collectingEnabled()==YES) { rkl_realloc = rkl_realloc_gc; } else { rkl_realloc = rkl_realloc_std; } return(rkl_realloc(ptr, size, flags)); } - -// rkl_free() -static void * rkl_free_first (RKL_STRONG_REF void **ptr); -static void * rkl_free_std (RKL_STRONG_REF void **ptr) { if(*ptr != NULL) { free(*ptr); *ptr = NULL; } return(NULL); } -static void * rkl_free_gc (RKL_STRONG_REF void **ptr) { if(*ptr != NULL) { *ptr = NULL; } return(NULL); } -static void *(*rkl_free) (RKL_STRONG_REF void **ptr) RKL_NONNULL_ARGS(1) = rkl_free_first; -static void *rkl_free_first (RKL_STRONG_REF void **ptr) { if(rkl_collectingEnabled()==YES) { rkl_free = rkl_free_gc; } else { rkl_free = rkl_free_std; } return(rkl_free(ptr)); } - -// rkl_CFAutorelease() -static id rkl_CFAutorelease_first (CFTypeRef obj); -static id rkl_CFAutorelease_std (CFTypeRef obj) { return([(id)obj autorelease]); } -static id rkl_CFAutorelease_gc (CFTypeRef obj) { return(NSMakeCollectable(obj)); } -static id(*rkl_CFAutorelease) (CFTypeRef obj) = rkl_CFAutorelease_first; -static id rkl_CFAutorelease_first (CFTypeRef obj) { return((rkl_CFAutorelease = (rkl_collectingEnabled()==YES) ? rkl_CFAutorelease_gc : rkl_CFAutorelease_std)(obj)); } - -// rkl_CreateStringWithSubstring() -static id rkl_CreateStringWithSubstring_first (id string, NSRange range); -static id rkl_CreateStringWithSubstring_std (id string, NSRange range) { return((id)CFStringCreateWithSubstring(NULL, (CFStringRef)string, CFMakeRange((CFIndex)range.location, (CFIndex)range.length))); } -static id rkl_CreateStringWithSubstring_gc (id string, NSRange range) { return([string substringWithRange:range]); } -static id(*rkl_CreateStringWithSubstring) (id string, NSRange range) RKL_NONNULL_ARGS_WARN_UNUSED(1) = rkl_CreateStringWithSubstring_first; -static id rkl_CreateStringWithSubstring_first (id string, NSRange range) { return((rkl_CreateStringWithSubstring = (rkl_collectingEnabled()==YES) ? rkl_CreateStringWithSubstring_gc : rkl_CreateStringWithSubstring_std)(string, range)); } - -// rkl_ReleaseObject() -static id rkl_ReleaseObject_first (id obj); -static id rkl_ReleaseObject_std (id obj) { CFRelease((CFTypeRef)obj); return(NULL); } -static id rkl_ReleaseObject_gc (id obj RKL_UNUSED_ARG) { return(NULL); } -static id (*rkl_ReleaseObject) (id obj) RKL_NONNULL_ARGS(1) = rkl_ReleaseObject_first; -static id rkl_ReleaseObject_first (id obj) { return((rkl_ReleaseObject = (rkl_collectingEnabled()==YES) ? rkl_ReleaseObject_gc : rkl_ReleaseObject_std)(obj)); } - -// rkl_CreateArrayWithObjects() -static id rkl_CreateArrayWithObjects_first (void **objects, NSUInteger count); -static id rkl_CreateArrayWithObjects_std (void **objects, NSUInteger count) { return((id)CFArrayCreate(NULL, (const void **)objects, (CFIndex)count, &rkl_transferOwnershipArrayCallBacks)); } -static id rkl_CreateArrayWithObjects_gc (void **objects, NSUInteger count) { return([NSArray arrayWithObjects:(const id *)objects count:count]); } -static id(*rkl_CreateArrayWithObjects) (void **objects, NSUInteger count) RKL_NONNULL_ARGS_WARN_UNUSED(1) = rkl_CreateArrayWithObjects_first; -static id rkl_CreateArrayWithObjects_first (void **objects, NSUInteger count) { return((rkl_CreateArrayWithObjects = (rkl_collectingEnabled()==YES) ? rkl_CreateArrayWithObjects_gc : rkl_CreateArrayWithObjects_std)(objects, count)); } - -// rkl_CreateAutoreleasedArray() -static id rkl_CreateAutoreleasedArray_first (void **objects, NSUInteger count); -static id rkl_CreateAutoreleasedArray_std (void **objects, NSUInteger count) { return((id)rkl_CFAutorelease(rkl_CreateArrayWithObjects(objects, count))); } -static id rkl_CreateAutoreleasedArray_gc (void **objects, NSUInteger count) { return( rkl_CreateArrayWithObjects(objects, count) ); } -static id(*rkl_CreateAutoreleasedArray) (void **objects, NSUInteger count) RKL_NONNULL_ARGS_WARN_UNUSED(1) = rkl_CreateAutoreleasedArray_first; -static id rkl_CreateAutoreleasedArray_first (void **objects, NSUInteger count) { return((rkl_CreateAutoreleasedArray = (rkl_collectingEnabled()==YES) ? rkl_CreateAutoreleasedArray_gc : rkl_CreateAutoreleasedArray_std)(objects, count)); } - -#else // __OBJC_GC__ not defined -//////////// -#pragma mark - -#pragma mark Low-level explicit memory/resource allocation utilities - -enum { RKLScannedOption = 0 }; - -#define rkl_collectingEnabled() (NO) - -RKL_STATIC_INLINE void *rkl_realloc (void **ptr, size_t size, NSUInteger flags) RKL_ALLOC_SIZE_NON_NULL_ARGS_WARN_UNUSED(2,1); -RKL_STATIC_INLINE void *rkl_free (void **ptr) RKL_NONNULL_ARGS(1); -RKL_STATIC_INLINE id rkl_CFAutorelease (CFTypeRef obj); -RKL_STATIC_INLINE id rkl_CreateAutoreleasedArray (void **objects, NSUInteger count) RKL_NONNULL_ARGS_WARN_UNUSED(1); -RKL_STATIC_INLINE id rkl_CreateArrayWithObjects (void **objects, NSUInteger count) RKL_NONNULL_ARGS_WARN_UNUSED(1); -RKL_STATIC_INLINE id rkl_CreateStringWithSubstring (id string, NSRange range) RKL_NONNULL_ARGS_WARN_UNUSED(1); -RKL_STATIC_INLINE id rkl_ReleaseObject (id obj) RKL_NONNULL_ARGS(1); - -RKL_STATIC_INLINE void *rkl_realloc (void **ptr, size_t size, NSUInteger flags RKL_UNUSED_ARG) { return((*ptr = reallocf(*ptr, size))); } -RKL_STATIC_INLINE void *rkl_free (void **ptr) { if(*ptr != NULL) { free(*ptr); *ptr = NULL; } return(NULL); } -RKL_STATIC_INLINE id rkl_CFAutorelease (CFTypeRef obj) { return([(id)obj autorelease]); } -RKL_STATIC_INLINE id rkl_CreateArrayWithObjects (void **objects, NSUInteger count) { return((id)CFArrayCreate(NULL, (const void **)objects, (CFIndex)count, &rkl_transferOwnershipArrayCallBacks)); } -RKL_STATIC_INLINE id rkl_CreateAutoreleasedArray (void **objects, NSUInteger count) { return(rkl_CFAutorelease(rkl_CreateArrayWithObjects(objects, count))); } -RKL_STATIC_INLINE id rkl_CreateStringWithSubstring (id string, NSRange range) { return((id)CFStringCreateWithSubstring(NULL, (CFStringRef)string, CFMakeRange((CFIndex)range.location, (CFIndex)range.length))); } -RKL_STATIC_INLINE id rkl_ReleaseObject (id obj) { CFRelease((CFTypeRef)obj); return(NULL); } - -#endif // __OBJC_GC__ - -//////////// -#pragma mark - -#pragma mark ICU function prototypes - -// ICU functions. See http://www.icu-project.org/apiref/icu4c/uregex_8h.html Tweaked slightly from the originals, but functionally identical. -const char *RKL_ICU_FUNCTION_APPEND(u_errorName) (int32_t status) RKL_ATTRIBUTES(pure); -int32_t RKL_ICU_FUNCTION_APPEND(u_strlen) (const UniChar *s) RKL_ATTRIBUTES(nonnull(1), pure); -int32_t RKL_ICU_FUNCTION_APPEND(uregex_appendReplacement) (uregex *regexp, const UniChar *replacementText, int32_t replacementLength, UniChar **destBuf, int32_t *destCapacity, int32_t *status) RKL_NONNULL_ARGS(1,2,4,5,6); -int32_t RKL_ICU_FUNCTION_APPEND(uregex_appendTail) (uregex *regexp, UniChar **destBuf, int32_t *destCapacity, int32_t *status) RKL_NONNULL_ARGS(1,2,3,4); -void RKL_ICU_FUNCTION_APPEND(uregex_close) (uregex *regexp) RKL_NONNULL_ARGS(1); -int32_t RKL_ICU_FUNCTION_APPEND(uregex_end) (uregex *regexp, int32_t groupNum, int32_t *status) RKL_NONNULL_ARGS(1,3); -BOOL RKL_ICU_FUNCTION_APPEND(uregex_find) (uregex *regexp, int32_t location, int32_t *status) RKL_NONNULL_ARGS(1,3); -BOOL RKL_ICU_FUNCTION_APPEND(uregex_findNext) (uregex *regexp, int32_t *status) RKL_NONNULL_ARGS(1,2); -int32_t RKL_ICU_FUNCTION_APPEND(uregex_groupCount) (uregex *regexp, int32_t *status) RKL_NONNULL_ARGS(1,2); -uregex *RKL_ICU_FUNCTION_APPEND(uregex_open) (const UniChar *pattern, int32_t patternLength, RKLRegexOptions flags, UParseError *parseError, int32_t *status) RKL_NONNULL_ARGS_WARN_UNUSED(1,4,5); -void RKL_ICU_FUNCTION_APPEND(uregex_reset) (uregex *regexp, int32_t newIndex, int32_t *status) RKL_NONNULL_ARGS(1,3); -void RKL_ICU_FUNCTION_APPEND(uregex_setText) (uregex *regexp, const UniChar *text, int32_t textLength, int32_t *status) RKL_NONNULL_ARGS(1,2,4); -int32_t RKL_ICU_FUNCTION_APPEND(uregex_start) (uregex *regexp, int32_t groupNum, int32_t *status) RKL_NONNULL_ARGS(1,3); - -//////////// -#pragma mark - -#pragma mark RegexKitLite internal, private function prototypes - -static RKLCacheSlot *rkl_getCachedRegex (NSString *regexString, RKLRegexOptions options, NSError **error, id *exception) RKL_NONNULL_ARGS_WARN_UNUSED(1,4); -static NSUInteger rkl_setCacheSlotToString (RKLCacheSlot *cacheSlot, const NSRange *range, int32_t *status, id *exception RKL_UNUSED_ASSERTION_ARG) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,3,4); -static RKLCacheSlot *rkl_getCachedRegexSetToString (NSString *regexString, RKLRegexOptions options, NSString *matchString, NSUInteger *matchLengthPtr, NSRange *matchRange, NSError **error, id *exception, int32_t *status) RKL_NONNULL_ARGS_WARN_UNUSED(1,3,4,5,7,8); -static id rkl_performRegexOp (id self, SEL _cmd, RKLRegexOp regexOp, NSString *regexString, RKLRegexOptions options, NSInteger capture, id matchString, NSRange *matchRange, NSString *replacementString, NSError **error, void *result) RKL_NONNULL_ARGS(1,2); -static void rkl_handleDelayedAssert (id self, SEL _cmd, id exception) RKL_NONNULL_ARGS(1,2,3); - -static NSUInteger rkl_search (RKLCacheSlot *cacheSlot, NSRange *searchRange, NSUInteger updateSearchRange, id *exception RKL_UNUSED_ASSERTION_ARG, int32_t *status) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,4,5); - -static BOOL rkl_findRanges (RKLCacheSlot *cacheSlot, RKLRegexOp regexOp, RKLFindAll *findAll, id *exception, int32_t *status) RKL_NONNULL_ARGS_WARN_UNUSED(1,3,4,5); -static NSUInteger rkl_growFindRanges (RKLCacheSlot *cacheSlot, NSUInteger lastLocation, RKLFindAll *findAll, id *exception RKL_UNUSED_ASSERTION_ARG) RKL_NONNULL_ARGS_WARN_UNUSED(1,3,4); -static NSArray *rkl_makeArray (RKLCacheSlot *cacheSlot, RKLRegexOp regexOp, RKLFindAll *findAll, id *exception RKL_UNUSED_ASSERTION_ARG) RKL_NONNULL_ARGS_WARN_UNUSED(1,3,4); - -static NSString *rkl_replaceString (RKLCacheSlot *cacheSlot, id searchString, NSUInteger searchU16Length, NSString *replacementString, NSUInteger replacementU16Length, NSUInteger *replacedCount, NSUInteger replaceMutable, id *exception, int32_t *status) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,4,8,9); -static int32_t rkl_replaceAll (RKLCacheSlot *cacheSlot, const UniChar *replacementUniChar, int32_t replacementU16Length, UniChar *replacedUniChar, int32_t replacedU16Capacity, NSUInteger *replacedCount, int32_t *needU16Capacity, id *exception RKL_UNUSED_ASSERTION_ARG, int32_t *status) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,4,6,7,8,9); - -static NSUInteger rkl_isRegexValid (id self, SEL _cmd, NSString *regex, RKLRegexOptions options, NSInteger *captureCountPtr, NSError **error) RKL_NONNULL_ARGS(1,2); - -static void rkl_clearStringCache (void); -static void rkl_clearBuffer (RKLBuffer *buffer, NSUInteger freeDynamicBuffer) RKL_NONNULL_ARGS(1); -static void rkl_clearCacheSlotRegex (RKLCacheSlot *cacheSlot) RKL_NONNULL_ARGS(1); -static void rkl_clearCacheSlotSetTo (RKLCacheSlot *cacheSlot) RKL_NONNULL_ARGS(1); - -static NSDictionary *rkl_userInfoDictionary (NSString *regexString, RKLRegexOptions options, const UParseError *parseError, int32_t status, ...) RKL_ATTRIBUTES(sentinel, nonnull(1), warn_unused_result); -static NSError *rkl_NSErrorForRegex (NSString *regexString, RKLRegexOptions options, const UParseError *parseError, int32_t status) RKL_NONNULL_ARGS_WARN_UNUSED(1); -static NSException *rkl_NSExceptionForRegex (NSString *regexString, RKLRegexOptions options, const UParseError *parseError, int32_t status) RKL_NONNULL_ARGS_WARN_UNUSED(1); -static NSDictionary *rkl_makeAssertDictionary (const char *function, const char *file, int line, NSString *format, ...) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,4); -static NSString *rkl_stringFromClassAndMethod (id object, SEL selector, NSString *format, ...) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,3); - -RKL_STATIC_INLINE int32_t rkl_getRangeForCapture(RKLCacheSlot *cs, int32_t *s, int32_t c, NSRange *r) RKL_NONNULL_ARGS_WARN_UNUSED(1,2,4); -RKL_STATIC_INLINE int32_t rkl_getRangeForCapture(RKLCacheSlot *cs, int32_t *s, int32_t c, NSRange *r) { uregex *re = cs->icu_regex; int32_t start = RKL_ICU_FUNCTION_APPEND(uregex_start)(re, c, s); if(RKL_EXPECTED((*s > U_ZERO_ERROR), 0L) || (start == -1)) { *r = NSNotFoundRange; } else { r->location = (NSUInteger)start; r->length = (NSUInteger)RKL_ICU_FUNCTION_APPEND(uregex_end)(re, c, s) - r->location; r->location += cs->setToRange.location; } return(*s); } - -RKL_STATIC_INLINE RKLFindAll rkl_makeFindAll(NSRange *r, NSRange fir, NSInteger c, size_t s, size_t su, void **rsb, RKL_STRONG_REF void **ssb, RKL_STRONG_REF void **asb, NSInteger f, NSInteger cap, NSInteger fut) RKL_ATTRIBUTES(warn_unused_result); -RKL_STATIC_INLINE RKLFindAll rkl_makeFindAll(NSRange *r, NSRange fir, NSInteger c, size_t s, size_t su, void **rsb, RKL_STRONG_REF void **ssb, RKL_STRONG_REF void **asb, NSInteger f, NSInteger cap, NSInteger fut) { return(((RKLFindAll){ .ranges=r, .findInRange=fir, .capacity=c, .found=f, .findUpTo=fut, .capture=cap, .size=s, .stackUsed=su, .rangesScratchBuffer=rsb, .stringsScratchBuffer=ssb, .arraysScratchBuffer=asb})); } - -//////////// -#pragma mark - -#pragma mark RKL_FAST_MUTABLE_CHECK implementation - -#ifdef RKL_FAST_MUTABLE_CHECK -// We use a trampoline function pointer to check at run time if the function __CFStringIsMutable is available. -// If it is, the trampoline function pointer is replaced with the address of that function. -// Otherwise, we assume the worst case that every string is mutable. -// This hopefully helps to protect us since we're using an undocumented, non-public API call. -// We will keep on working if it ever does go away, just with a bit less performance due to the overhead of mutable checks. - -static BOOL rkl_CFStringIsMutable_first (CFStringRef str); -static BOOL rkl_CFStringIsMutable_yes (CFStringRef str RKL_UNUSED_ARG) { return(YES); } -static BOOL(*rkl_CFStringIsMutable) (CFStringRef str) = rkl_CFStringIsMutable_first; -static BOOL rkl_CFStringIsMutable_first (CFStringRef str) { if((rkl_CFStringIsMutable = (BOOL(*)(CFStringRef))dlsym(RTLD_DEFAULT, "__CFStringIsMutable")) == NULL) { rkl_CFStringIsMutable = rkl_CFStringIsMutable_yes; } return(rkl_CFStringIsMutable(str)); } -#else // RKL_FAST_MUTABLE_CHECK is not defined. Assume that all strings are potentially mutable. -#define rkl_CFStringIsMutable(s) (YES) -#endif // RKL_FAST_MUTABLE_CHECK - - -//////////// -#pragma mark - -#pragma mark iPhone / iPod touch low memory notification handler - -#if defined(RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS) && (RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS == 1) - -// The next few lines are specifically for the iPhone to catch low memory conditions. -// The basic idea is that rkl_RegisterForLowMemoryNotifications() is set to be run once by the linker at load time via __attribute((constructor)). -// rkl_RegisterForLowMemoryNotifications() tries to find the iPhone low memory notification symbol. If it can find it, -// it registers with the default NSNotificationCenter to call the RKLLowMemoryWarningObserver class method +lowMemoryWarning:. -// rkl_RegisterForLowMemoryNotifications() uses an atomic compare and swap to guarantee that it initalizes exactly once. -// +lowMemoryWarning tries to acquire the cache lock. If it gets the lock, it clears the cache. If it can't, it calls performSelector: -// with a delay of half a second to try again. This will hopefully prevent any deadlocks, such as a RegexKitLite request for -// memory triggering a notifcation while the lock is held. - -static void rkl_RegisterForLowMemoryNotifications(void) RKL_ATTRIBUTES(used); - -@interface RKLLowMemoryWarningObserver : NSObject +(void)lowMemoryWarning:(id)notification; @end -@implementation RKLLowMemoryWarningObserver -+(void)lowMemoryWarning:(id)notification { - if(OSSpinLockTry(&cacheSpinLock)) { rkl_clearStringCache(); OSSpinLockUnlock(&cacheSpinLock); } - else { [[RKLLowMemoryWarningObserver class] performSelector:@selector(lowMemoryWarning:) withObject:notification afterDelay:(NSTimeInterval)0.1]; } -} -@end - -static volatile int rkl_HaveRegisteredForLowMemoryNotifications = 0; - -__attribute__((constructor)) static void rkl_RegisterForLowMemoryNotifications(void) { - _Bool didSwap = false; - void **memoryWarningNotification = NULL; - - while((rkl_HaveRegisteredForLowMemoryNotifications == 0) && ((didSwap = OSAtomicCompareAndSwapIntBarrier(0, 1, &rkl_HaveRegisteredForLowMemoryNotifications)) == false)) { /* Allows for spurious CAS failures. */ } - if(didSwap == true) { - if((memoryWarningNotification = (void **)dlsym(RTLD_DEFAULT, "UIApplicationDidReceiveMemoryWarningNotification")) != NULL) { - [[NSNotificationCenter defaultCenter] addObserver:[RKLLowMemoryWarningObserver class] selector:@selector(lowMemoryWarning:) name:(NSString *)*memoryWarningNotification object:NULL]; - } - } -} - -#endif // defined(RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS) && (RKL_REGISTER_FOR_IPHONE_LOWMEM_NOTIFICATIONS == 1) - -#ifdef _RKL_DTRACE_ENABLED - -// compiledRegexCache(unsigned long eventID, const char *regexUTF8, int options, int captures, int hitMiss, int icuStatusCode, const char *icuErrorMessage, double *hitRate); -// utf16ConversionCache(unsigned long eventID, unsigned int lookupResultFlags, double *hitRate, const void *string, unsigned long NSRange.location, unsigned long NSRange.length, long length); - -/* -provider RegexKitLite { - probe compiledRegexCache(unsigned long, const char *, unsigned int, int, int, int, const char *, double *); - probe utf16ConversionCache(unsigned long, unsigned int, double *, const void *, unsigned long, unsigned long, long); -}; - -#pragma D attributes Unstable/Unstable/Common provider RegexKitLite provider -#pragma D attributes Private/Private/Common provider RegexKitLite module -#pragma D attributes Private/Private/Common provider RegexKitLite function -#pragma D attributes Unstable/Unstable/Common provider RegexKitLite name -#pragma D attributes Unstable/Unstable/Common provider RegexKitLite args -*/ - -#define REGEXKITLITE_STABILITY "___dtrace_stability$RegexKitLite$v1$4_4_5_1_1_5_1_1_5_4_4_5_4_4_5" -#define REGEXKITLITE_TYPEDEFS "___dtrace_typedefs$RegexKitLite$v1" -#define REGEXKITLITE_COMPILEDREGEXCACHE(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) { __asm__ volatile(".reference " REGEXKITLITE_TYPEDEFS); __dtrace_probe$RegexKitLite$compiledRegexCache$v1$756e7369676e6564206c6f6e67$63686172202a$756e7369676e656420696e74$696e74$696e74$696e74$63686172202a$646f75626c65202a(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); __asm__ volatile(".reference " REGEXKITLITE_STABILITY); } -#define REGEXKITLITE_COMPILEDREGEXCACHE_ENABLED() __dtrace_isenabled$RegexKitLite$compiledRegexCache$v1() -#define REGEXKITLITE_CONVERTEDSTRINGU16CACHE(arg0, arg1, arg2, arg3, arg4, arg5, arg6) { __asm__ volatile(".reference " REGEXKITLITE_TYPEDEFS); __dtrace_probe$RegexKitLite$utf16ConversionCache$v1$756e7369676e6564206c6f6e67$756e7369676e656420696e74$646f75626c65202a$766f6964202a$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$6c6f6e67(arg0, arg1, arg2, arg3, arg4, arg5, arg6); __asm__ volatile(".reference " REGEXKITLITE_STABILITY); } -#define REGEXKITLITE_CONVERTEDSTRINGU16CACHE_ENABLED() __dtrace_isenabled$RegexKitLite$utf16ConversionCache$v1() - -extern void __dtrace_probe$RegexKitLite$compiledRegexCache$v1$756e7369676e6564206c6f6e67$63686172202a$756e7369676e656420696e74$696e74$696e74$696e74$63686172202a$646f75626c65202a(unsigned long, const char *, unsigned int, int, int, int, const char *, double *); -extern int __dtrace_isenabled$RegexKitLite$compiledRegexCache$v1(void); -extern void __dtrace_probe$RegexKitLite$utf16ConversionCache$v1$756e7369676e6564206c6f6e67$756e7369676e656420696e74$646f75626c65202a$766f6964202a$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$6c6f6e67(unsigned long, unsigned int, double *, const void *, unsigned long, unsigned long, long); -extern int __dtrace_isenabled$RegexKitLite$utf16ConversionCache$v1(void); - -//////////////////////////// - -enum { - RKLCacheHitLookupFlag = 1 << 0, - RKLConversionRequiredLookupFlag = 1 << 1, - RKLSetTextLookupFlag = 1 << 2, - RKLDynamicBufferLookupFlag = 1 << 3, - RKLErrorLookupFlag = 1 << 4, -}; - -#define rkl_dtrace_addLookupFlag(a,b) do { a |= (unsigned int)(b); } while(0) - -static char rkl_dtrace_regexUTF8[(RKL_CACHE_SIZE) + 1][(RKL_DTRACE_REGEXUTF8_SIZE)]; -static NSUInteger rkl_dtrace_eventID, rkl_dtrace_compiledCacheLookups, rkl_dtrace_compiledCacheHits, rkl_dtrace_conversionBufferLookups, rkl_dtrace_conversionBufferHits; - -#define rkl_dtrace_incrementEventID() do { rkl_dtrace_eventID++; } while(0) -#define rkl_dtrace_compiledRegexCache(a0, a1, a2, a3, a4, a5) do { int _a3 = (a3); rkl_dtrace_compiledCacheLookups++; if(_a3 == 1) { rkl_dtrace_compiledCacheHits++; } if(RKL_EXPECTED(REGEXKITLITE_COMPILEDREGEXCACHE_ENABLED(), 0L)) { double hitRate = 0.0; if(rkl_dtrace_compiledCacheLookups > 0UL) { hitRate = ((double)rkl_dtrace_compiledCacheHits / (double)rkl_dtrace_compiledCacheLookups) * 100.0; } REGEXKITLITE_COMPILEDREGEXCACHE(rkl_dtrace_eventID, a0, a1, a2, _a3, a4, a5, &hitRate); } } while(0) -#define rkl_dtrace_utf16ConversionCache(a0, a1, a2, a3, a4) do { unsigned int _a0 = (a0); if((_a0 & RKLConversionRequiredLookupFlag) != 0U) { rkl_dtrace_conversionBufferLookups++; if((_a0 & RKLCacheHitLookupFlag) != 0U) { rkl_dtrace_conversionBufferHits++; } } if(RKL_EXPECTED(REGEXKITLITE_CONVERTEDSTRINGU16CACHE_ENABLED(), 0L)) { double hitRate = 0.0; if(rkl_dtrace_conversionBufferLookups > 0UL) { hitRate = ((double)rkl_dtrace_conversionBufferHits / (double)rkl_dtrace_conversionBufferLookups) * 100.0; } REGEXKITLITE_CONVERTEDSTRINGU16CACHE(rkl_dtrace_eventID, _a0, &hitRate, a1, a2, a3, a4); } } while(0) - - -// \342\200\246 == UTF8 for HORIZONTAL ELLIPSIS, aka triple dots '...' -#define RKL_UTF8_ELLIPSE "\342\200\246" - -// rkl_dtrace_getRegexUTF8 will copy the str argument to utf8Buffer using UTF8 as the string encoding. -// If the utf8 encoding would take up more bytes than the utf8Buffers length, then the unicode character 'HORIZONTAL ELLIPSIS' ('...') is appened to indicate truncation occured. -static void rkl_dtrace_getRegexUTF8(CFStringRef str, char *utf8Buffer) RKL_NONNULL_ARGS(2); -static void rkl_dtrace_getRegexUTF8(CFStringRef str, char *utf8Buffer) { - if((str == NULL) || (utf8Buffer == NULL)) { return; } - CFIndex maxLength = ((CFIndex)(RKL_DTRACE_REGEXUTF8_SIZE) - 2L), maxBytes = (maxLength - (CFIndex)sizeof(RKL_UTF8_ELLIPSE) - 1L), stringU16Length = CFStringGetLength(str), usedBytes = 0L; - CFStringGetBytes(str, CFMakeRange(0L, ((stringU16Length < maxLength) ? stringU16Length : maxLength)), kCFStringEncodingUTF8, (UInt8)'?', (Boolean)0, (UInt8 *)utf8Buffer, maxBytes, &usedBytes); - if(usedBytes == maxBytes) { strncpy(utf8Buffer + usedBytes, RKL_UTF8_ELLIPSE, ((size_t)(RKL_DTRACE_REGEXUTF8_SIZE) - (size_t)usedBytes) - 2UL); } else { utf8Buffer[usedBytes] = (char)0; } -} - -#else // _RKL_DTRACE_ENABLED - -#define rkl_dtrace_incrementEventID() -#define rkl_dtrace_compiledRegexCache(a0, a1, a2, a3, a4, a5) -#define rkl_dtrace_utf16ConversionCache(a0, a1, a2, a3, a4) -#define rkl_dtrace_getRegexUTF8(str, buf) -#define rkl_dtrace_addLookupFlag(a,b) - -#endif // _RKL_DTRACE_ENABLED - -//////////// -#pragma mark - -#pragma mark RegexKitLite low-level internal functions - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called with cacheSpinLock already locked! -// ---------- - -static RKLCacheSlot *rkl_getCachedRegex(NSString *regexString, RKLRegexOptions options, NSError **error, id *exception) { - RKLCacheSlot *cacheSlot = NULL; - CFHashCode regexHash = 0UL; - int32_t status = 0; - - RKLCDelayedAssert((cacheSpinLock != (OSSpinLock)0) && (regexString != NULL), exception, exitNow); - - // Fast path the common case where this regex is exactly the same one used last time. - // The pointer equality test is valid under these circumstances since the cacheSlot->regexString is an immutable copy. - // If the regexString argument is mutable, this test will fail, and we'll use the the slow path cache check below. - if(RKL_EXPECTED(lastCacheSlot != NULL, 1L) && RKL_EXPECTED(lastCacheSlot->options == options, 1L) && RKL_EXPECTED(lastCacheSlot->icu_regex != NULL, 1L) && RKL_EXPECTED(lastCacheSlot->regexString != NULL, 1L) && RKL_EXPECTED(lastCacheSlot->regexString == (CFStringRef)regexString, 1L)) { - rkl_dtrace_compiledRegexCache(&rkl_dtrace_regexUTF8[(lastCacheSlot - &rkl_cacheSlots[0])][0], lastCacheSlot->options, (int)lastCacheSlot->captureCount, 1, 0, NULL); - return(lastCacheSlot); - } - - lastCacheSlot = NULL; - regexHash = CFHash((CFTypeRef)regexString); - cacheSlot = &rkl_cacheSlots[(regexHash % (CFHashCode)(RKL_CACHE_SIZE))]; // Retrieve the cache slot for this regex. - - // Return the cached entry if it's a match, otherwise clear the slot and create a new ICU regex in its place. - // If regexString is mutable, the pointer equality test will fail, and CFEqual() is used to determine true - // equality with the immutable cacheSlot copy. CFEqual() performs a slow character by character check. - if(RKL_EXPECTED(cacheSlot->options == options, 1L) && RKL_EXPECTED(cacheSlot->icu_regex != NULL, 1L) && RKL_EXPECTED(cacheSlot->regexString != NULL, 1L) && (RKL_EXPECTED(cacheSlot->regexString == (CFStringRef)regexString, 1L) || RKL_EXPECTED(CFEqual((CFTypeRef)regexString, (CFTypeRef)cacheSlot->regexString) == YES, 1L))) { - lastCacheSlot = cacheSlot; - rkl_dtrace_compiledRegexCache(&rkl_dtrace_regexUTF8[(lastCacheSlot - &rkl_cacheSlots[0])][0], lastCacheSlot->options, (int)lastCacheSlot->captureCount, 1, 0, NULL); - return(cacheSlot); - } - - rkl_clearCacheSlotRegex(cacheSlot); - - if(RKL_EXPECTED((cacheSlot->regexString = CFStringCreateCopy(NULL, (CFStringRef)regexString)) == NULL, 0L)) { goto exitNow; } ; // Get a cheap immutable copy. - rkl_dtrace_getRegexUTF8(cacheSlot->regexString, &rkl_dtrace_regexUTF8[(cacheSlot - &rkl_cacheSlots[0])][0]); - cacheSlot->options = options; - - CFIndex regexStringU16Length = CFStringGetLength(cacheSlot->regexString); // In UTF16 code units. - UParseError parseError = (UParseError){-1, -1, {0}, {0}}; - const UniChar *regexUniChar = NULL; - - if(RKL_EXPECTED(regexStringU16Length >= (CFIndex)INT_MAX, 0L)) { *exception = [NSException exceptionWithName:NSRangeException reason:@"Regex string length exceeds INT_MAX" userInfo:NULL]; goto exitNow; } - - // Try to quickly obtain regexString in UTF16 format. - if((regexUniChar = CFStringGetCharactersPtr(cacheSlot->regexString)) == NULL) { // We didn't get the UTF16 pointer quickly and need to perform a full conversion in a temp buffer. - UniChar *uniCharBuffer = NULL; - if(((size_t)regexStringU16Length * sizeof(UniChar)) < (size_t)(RKL_STACK_LIMIT)) { if(RKL_EXPECTED((uniCharBuffer = (UniChar *)alloca( (size_t)regexStringU16Length * sizeof(UniChar) )) == NULL, 0L)) { goto exitNow; } } // Try to use the stack. - else { if(RKL_EXPECTED((uniCharBuffer = (UniChar *)rkl_realloc(&scratchBuffer[0], (size_t)regexStringU16Length * sizeof(UniChar), 0UL)) == NULL, 0L)) { goto exitNow; } } // Otherwise use the heap. - CFStringGetCharacters(cacheSlot->regexString, CFMakeRange(0L, regexStringU16Length), uniCharBuffer); // Convert regexString to UTF16. - regexUniChar = uniCharBuffer; - } - - // Create the ICU regex. - if(RKL_EXPECTED((cacheSlot->icu_regex = RKL_ICU_FUNCTION_APPEND(uregex_open)(regexUniChar, (int32_t)regexStringU16Length, options, &parseError, &status)) == NULL, 0L)) { goto exitNow; } - if(RKL_EXPECTED(status <= U_ZERO_ERROR, 1L)) { cacheSlot->captureCount = (NSInteger)RKL_ICU_FUNCTION_APPEND(uregex_groupCount)(cacheSlot->icu_regex, &status); } - if(RKL_EXPECTED(status <= U_ZERO_ERROR, 1L)) { lastCacheSlot = cacheSlot; } - -exitNow: - if(RKL_EXPECTED(scratchBuffer[0] != NULL, 0L)) { scratchBuffer[0] = rkl_free(&scratchBuffer[0]); } - if(RKL_EXPECTED(status > U_ZERO_ERROR, 0L)) { rkl_clearCacheSlotRegex(cacheSlot); cacheSlot = NULL; if(error != NULL) { *error = rkl_NSErrorForRegex(regexString, options, &parseError, status); } } - -#ifdef _RKL_DTRACE_ENABLED - if(RKL_EXPECTED(cacheSlot != NULL, 1L)) { rkl_dtrace_compiledRegexCache(&rkl_dtrace_regexUTF8[(cacheSlot - &rkl_cacheSlots[0])][0], cacheSlot->options, (int)cacheSlot->captureCount, 0, status, NULL); } - else { char regexUTF8[(RKL_DTRACE_REGEXUTF8_SIZE)]; const char *err = NULL; if(status != U_ZERO_ERROR) { err = RKL_ICU_FUNCTION_APPEND(u_errorName)(status); } rkl_dtrace_getRegexUTF8((CFStringRef)regexString, regexUTF8); rkl_dtrace_compiledRegexCache(regexUTF8, options, -1, -1, status, err); } -#endif // _RKL_DTRACE_ENABLED - - return(cacheSlot); -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called with cacheSpinLock already locked! -// ---------- - -static NSUInteger rkl_setCacheSlotToString(RKLCacheSlot *cacheSlot, const NSRange *range, int32_t *status, id *exception RKL_UNUSED_ASSERTION_ARG) { - RKLCDelayedAssert((cacheSlot != NULL) && (cacheSlot->setToString != NULL) && ((range != NULL) && (NSEqualRanges(*range, NSNotFoundRange) == NO)) && (status != NULL), exception, exitNow); - const UniChar *stringUniChar = NULL; -#ifdef _RKL_DTRACE_ENABLED - unsigned int lookupResultFlags = 0U; -#endif - - if(cacheSlot->setToNeedsConversion == 0U) { - if(RKL_EXPECTED((stringUniChar = CFStringGetCharactersPtr(cacheSlot->setToString)) == NULL, 0L)) { cacheSlot->setToNeedsConversion = 1U; } - else { if(RKL_EXPECTED(cacheSlot->setToUniChar != stringUniChar, 0L)) { cacheSlot->setToRange = NSNotFoundRange; cacheSlot->setToUniChar = stringUniChar; } goto setRegexText; } - } - rkl_dtrace_addLookupFlag(lookupResultFlags, RKLConversionRequiredLookupFlag); - - NSUInteger useFixedBuffer = (cacheSlot->setToLength < (CFIndex)(RKL_FIXED_LENGTH)) ? 1UL : 0UL; - RKLBuffer *buffer = useFixedBuffer ? &fixedBuffer : &dynamicBuffer; - rkl_dtrace_addLookupFlag(lookupResultFlags, (useFixedBuffer ? 0U : RKLDynamicBufferLookupFlag)); - - if((buffer->uniChar != NULL) && (cacheSlot->setToString == buffer->string) && (cacheSlot->setToLength == buffer->length) && (cacheSlot->setToHash == buffer->hash)) { rkl_dtrace_addLookupFlag(lookupResultFlags, RKLCacheHitLookupFlag); cacheSlot->setToUniChar = buffer->uniChar; goto setRegexText; } - - if((cacheSlot->setToNeedsConversion == 1U) && RKL_EXPECTED((stringUniChar = CFStringGetCharactersPtr(cacheSlot->setToString)) != NULL, 0L)) { cacheSlot->setToNeedsConversion = 0U; cacheSlot->setToRange = NSNotFoundRange; cacheSlot->setToUniChar = stringUniChar; goto setRegexText; } - - rkl_clearBuffer(buffer, 0UL); - - if(useFixedBuffer == 0U) { - RKLCDelayedAssert(buffer == &dynamicBuffer, exception, exitNow); - RKL_STRONG_REF void *p = (RKL_STRONG_REF void *)dynamicBuffer.uniChar; - if(RKL_EXPECTED((dynamicBuffer.uniChar = (RKL_STRONG_REF UniChar *)rkl_realloc(&p, ((size_t)cacheSlot->setToLength * sizeof(UniChar)), 0UL)) == NULL, 0L)) { goto exitNow; } // Resize the buffer. - } - - RKLCDelayedAssert(buffer->uniChar != NULL, exception, exitNow); - CFStringGetCharacters(cacheSlot->setToString, CFMakeRange(0L, cacheSlot->setToLength), (UniChar *)buffer->uniChar); // Convert to a UTF16 string. - - RKLCDelayedAssert(buffer->string == NULL, exception, exitNow); - if(RKL_EXPECTED((buffer->string = (CFStringRef)CFRetain((CFTypeRef)cacheSlot->setToString)) == NULL, 0L)) { goto exitNow; } - buffer->hash = cacheSlot->setToHash; - buffer->length = cacheSlot->setToLength; - - cacheSlot->setToUniChar = buffer->uniChar; - cacheSlot->setToRange = NSNotFoundRange; - -setRegexText: - if(NSEqualRanges(cacheSlot->setToRange, *range) == NO) { - RKLCDelayedAssert((cacheSlot->icu_regex != NULL) && (cacheSlot->setToUniChar != NULL) && (NSMaxRange(*range) <= (NSUInteger)cacheSlot->setToLength) && (cacheSlot->setToRange.length <= INT_MAX), exception, exitNow); - cacheSlot->lastFindRange = cacheSlot->lastMatchRange = NSNotFoundRange; - cacheSlot->setToRange = *range; - RKL_ICU_FUNCTION_APPEND(uregex_setText)(cacheSlot->icu_regex, cacheSlot->setToUniChar + cacheSlot->setToRange.location, (int32_t)cacheSlot->setToRange.length, status); - rkl_dtrace_addLookupFlag(lookupResultFlags, RKLSetTextLookupFlag); - if(RKL_EXPECTED(*status > U_ZERO_ERROR, 0L)) { goto exitNow; } - } - - rkl_dtrace_utf16ConversionCache(lookupResultFlags, cacheSlot->setToString, cacheSlot->setToRange.location, cacheSlot->setToRange.length, cacheSlot->setToLength); - return(1UL); - -exitNow: - return(0UL); -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called with cacheSpinLock already locked! -// ---------- - -static RKLCacheSlot *rkl_getCachedRegexSetToString(NSString *regexString, RKLRegexOptions options, NSString *matchString, NSUInteger *matchLengthPtr, NSRange *matchRange, NSError **error, id *exception, int32_t *status) { - RKLCacheSlot *cacheSlot = NULL; - RKLCDelayedAssert((regexString != NULL) && (exception != NULL) && (status != NULL) && (matchLengthPtr != NULL), exception, exitNow); - - // Fast path the common case where this regex is exactly the same one used last time. - if(RKL_EXPECTED(lastCacheSlot != NULL, 1L) && RKL_EXPECTED(lastCacheSlot->icu_regex != NULL, 1L) && RKL_EXPECTED(lastCacheSlot->regexString == (CFStringRef)regexString, 1L) && RKL_EXPECTED(lastCacheSlot->options == options, 1L)) { cacheSlot = lastCacheSlot; rkl_dtrace_compiledRegexCache(&rkl_dtrace_regexUTF8[(cacheSlot - &rkl_cacheSlots[0])][0], cacheSlot->options, (int)cacheSlot->captureCount, 1, 0, NULL); } - else { lastCacheSlot = NULL; if(RKL_EXPECTED((cacheSlot = rkl_getCachedRegex(regexString, options, error, exception)) == NULL, 0L)) { goto exitNow; } } - RKLCDelayedAssert((cacheSlot != NULL) && (cacheSlot->icu_regex != NULL) && (cacheSlot->regexString != NULL) && (cacheSlot->captureCount >= 0L) && (cacheSlot == lastCacheSlot), exception, exitNow); - - // Optimize the case where the string to search (matchString) is immutable and the setToString immutable copy is the same string with its reference count incremented. - NSUInteger isSetTo = ((cacheSlot->setToString != NULL) && (cacheSlot->setToString == (CFStringRef)matchString)) ? 1UL : 0UL; - CFIndex matchLength = ((isSetTo == 1UL) && (cacheSlot->setToIsImmutable == 1U)) ? cacheSlot->setToLength : CFStringGetLength((CFStringRef)matchString); - - *matchLengthPtr = (NSUInteger)matchLength; - if(matchRange->length == NSUIntegerMax) { matchRange->length = (NSUInteger)matchLength; } // For convenience, allow NSUIntegerMax == string length. - - if(RKL_EXPECTED((NSUInteger)matchLength < NSMaxRange(*matchRange), 0L)) { goto exitNow; } // The match range is out of bounds for the string. performRegexOp will catch and report the problem. - - if((isSetTo == 1UL) && (cacheSlot->setToIsImmutable == 0U) && (cacheSlot->setToString != NULL) && ((cacheSlot->setToLength != CFStringGetLength(cacheSlot->setToString)) || (cacheSlot->setToHash != CFHash((CFTypeRef)cacheSlot->setToString)))) { isSetTo = 0UL; } - else { // If the first pointer equality check failed, check the hash and length. - if(((isSetTo == 0UL) || (cacheSlot->setToIsImmutable == 0U)) && (cacheSlot->setToString != NULL)) { isSetTo = ((cacheSlot->setToString == (CFStringRef)matchString) && (cacheSlot->setToLength == matchLength) && (cacheSlot->setToHash == CFHash((CFTypeRef)matchString))) ? 1UL : 0UL; } - - if(isSetTo == 1UL) { if(RKL_EXPECTED(rkl_setCacheSlotToString(cacheSlot, matchRange, status, exception) == 0UL, 0L)) { cacheSlot = NULL; if(*exception == NULL) { *exception = (id)RKLCAssertDictionary(@"Failed to set up UTF16 buffer."); } } goto exitNow; } - } - - // Sometimes the range that the regex is set to isn't right, in which case we don't want to clear the cache slot. Otherwise, flush it out. - if((cacheSlot->setToString != NULL) && (isSetTo == 0UL)) { rkl_clearCacheSlotSetTo(cacheSlot); } - - if(cacheSlot->setToString == NULL) { - cacheSlot->setToString = (CFStringRef)CFRetain((CFTypeRef)matchString); - RKLCDelayedAssert(cacheSlot->setToString != NULL, exception, exitNow); - cacheSlot->setToUniChar = CFStringGetCharactersPtr(cacheSlot->setToString); - cacheSlot->setToNeedsConversion = (cacheSlot->setToUniChar == NULL) ? 1U : 0U; - cacheSlot->setToIsImmutable = (rkl_CFStringIsMutable(cacheSlot->setToString) == YES) ? 0U : 1U; // If RKL_FAST_MUTABLE_CHECK is not defined then setToIsImmutable will always be set to '0', or in other words mutable.. - cacheSlot->setToHash = CFHash((CFTypeRef)cacheSlot->setToString); - cacheSlot->setToRange = NSNotFoundRange; - cacheSlot->setToLength = matchLength; - } - - if(RKL_EXPECTED(rkl_setCacheSlotToString(cacheSlot, matchRange, status, exception) == 0UL, 0L)) { cacheSlot = NULL; if(*exception == NULL) { *exception = (id)RKLCAssertDictionary(@"Failed to set up UTF16 buffer."); } goto exitNow; } - -exitNow: - return(cacheSlot); -} - -#ifdef RKL_HAVE_CLEANUP - -// rkl_cleanup_cacheSpinLockStatus takes advantage of GCC's 'cleanup' variable attribute. When an 'auto' variable with the 'cleanup' attribute goes out of scope, -// GCC arranges to have the designated function called. In this case, we make sure that if rkl_cacheSpinLock was locked that it was also unlocked. -// If rkl_cacheSpinLock was locked, but the cacheSpinLockStatus unlocked flag was not set, we force cacheSpinLock unlocked with a call to OSSpinLockUnlock. -// This is not a panacea for preventing mutex usage errors. Old style ObjC exceptions will bypass the cleanup call, but newer C++ style ObjC exceptions should cause the cleanup function to be called during the stack unwind. - -// We do not depend on this cleanup function being called. It is used only as an extra safety net. It is probably a bug in RegexKitLite if it is ever invoked and forced to take some kind of protective action. - -volatile NSUInteger rkl_debugCacheSpinLockCount = 0UL; - -void rkl_debugCacheSpinLock (void) RKL_ATTRIBUTES(used, noinline, visibility("default")); -static void rkl_cleanup_cacheSpinLockStatus (volatile NSUInteger *cacheSpinLockStatusPtr) RKL_ATTRIBUTES(used); - -void rkl_debugCacheSpinLock(void) { - rkl_debugCacheSpinLockCount++; // This is here primarily to prevent the optimizer from optimizing away the function. -} - -static void rkl_cleanup_cacheSpinLockStatus(volatile NSUInteger *cacheSpinLockStatusPtr) { - static NSUInteger didPrintForcedUnlockWarning = 0UL, didPrintNotLockedWarning = 0UL; - NSUInteger cacheSpinLockStatus = *cacheSpinLockStatusPtr; - - if(RKL_EXPECTED((cacheSpinLockStatus & RKLUnlockedCacheSpinLock) == 0UL, 0L) && RKL_EXPECTED((cacheSpinLockStatus & RKLLockedCacheSpinLock) != 0UL, 1L)) { - if(cacheSpinLock != (OSSpinLock)0) { - if(didPrintForcedUnlockWarning == 0UL) { didPrintForcedUnlockWarning = 1UL; NSLog(@"[RegexKitLite] Unusual condition detected: Recorded that cacheSpinLock was locked, but for some reason it was not unlocked. Forcibly unlocking cacheSpinLock. Set a breakpoint at rkl_debugCacheSpinLock to debug. This warning is only printed once."); } - rkl_debugCacheSpinLock(); // Since this is an unusual condition, offer an attempt to catch it before we unlock. - OSSpinLockUnlock(&cacheSpinLock); - } else { - if(didPrintNotLockedWarning == 0UL) { didPrintNotLockedWarning = 1UL; NSLog(@"[RegexKitLite] Unusual condition detected: Recorded that cacheSpinLock was locked, but for some reason it was not unlocked, yet cacheSpinLock is currently not locked? Set a breakpoint at rkl_debugCacheSpinLock to debug. This warning is only printed once."); } - rkl_debugCacheSpinLock(); - } - } -} - -#endif // RKL_HAVE_CLEANUP - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// ---------- - -static id rkl_performRegexOp(id self, SEL _cmd, RKLRegexOp regexOp, NSString *regexString, RKLRegexOptions options, NSInteger capture, id matchString, NSRange *matchRange, NSString *replacementString, NSError **error, void *result) { - volatile NSUInteger RKL_CLEANUP(rkl_cleanup_cacheSpinLockStatus) cacheSpinLockStatus = 0UL; - - NSUInteger replaceMutable = 0UL; - RKLRegexOp maskedRegexOp = (regexOp & RKLMaskOp); - - if((error != NULL) && (*error != NULL)) { *error = NULL; } - - if(RKL_EXPECTED(regexString == NULL, 0L)) { RKL_RAISE_EXCEPTION(NSInvalidArgumentException, @"The regular expression argument is NULL."); } - if(RKL_EXPECTED(matchString == NULL, 0L)) { RKL_RAISE_EXCEPTION(NSInternalInconsistencyException, @"The match string argument is NULL."); } - if((maskedRegexOp == RKLReplaceOp) && (replacementString == NULL)) { RKL_RAISE_EXCEPTION(NSInvalidArgumentException, @"The replacement string argument is NULL."); } - - id resultObject = NULL, exception = NULL; - int32_t status = U_ZERO_ERROR; - RKLCacheSlot *cacheSlot = NULL; - NSUInteger stringU16Length = 0UL; - NSRange stackRanges[2048]; - RKLFindAll findAll; - - - // IMPORTANT! Once we have obtained the lock, code MUST exit via 'goto exitNow;' to unlock the lock! NO EXCEPTIONS! - // ---------- - OSSpinLockLock(&cacheSpinLock); // Grab the lock and get cache entry. - cacheSpinLockStatus |= RKLLockedCacheSpinLock; - rkl_dtrace_incrementEventID(); - - if(RKL_EXPECTED((cacheSlot = rkl_getCachedRegexSetToString(regexString, options, matchString, &stringU16Length, matchRange, error, &exception, &status)) == NULL, 0L)) { stringU16Length = (NSUInteger)CFStringGetLength((CFStringRef)matchString); } - if(RKL_EXPECTED(matchRange->length == NSUIntegerMax, 1L)) { matchRange->length = stringU16Length; } // For convenience. - if(RKL_EXPECTED(stringU16Length < NSMaxRange(*matchRange), 0L) && RKL_EXPECTED(exception == NULL, 1L)) { exception = (id)RKL_EXCEPTION(NSRangeException, @"Range or index out of bounds."); goto exitNow; } - if(RKL_EXPECTED(stringU16Length >= (NSUInteger)INT_MAX, 0L) && RKL_EXPECTED(exception == NULL, 1L)) { exception = (id)RKL_EXCEPTION(NSRangeException, @"String length exceeds INT_MAX."); goto exitNow; } - if(((maskedRegexOp == RKLRangeOp) || (maskedRegexOp == RKLArrayOfStringsOp)) && RKL_EXPECTED(cacheSlot != NULL, 1L) && (RKL_EXPECTED(capture < 0L, 0L) || RKL_EXPECTED(capture > cacheSlot->captureCount, 0L)) && RKL_EXPECTED(exception == NULL, 1L)) { exception = (id)RKL_EXCEPTION(NSInvalidArgumentException, @"The capture argument is not valid."); goto exitNow; } - if(RKL_EXPECTED(cacheSlot == NULL, 0L) || RKL_EXPECTED(status > U_ZERO_ERROR, 0L) || RKL_EXPECTED(exception != NULL, 0L)) { goto exitNow; } - - RKLCDelayedAssert((cacheSlot != NULL) && (cacheSlot->icu_regex != NULL) && (cacheSlot->regexString != NULL) && (cacheSlot->captureCount >= 0L) && (cacheSlot->setToString != NULL) && (cacheSlot->setToLength >= 0L) && (cacheSlot->setToUniChar != NULL) && ((CFIndex)NSMaxRange(cacheSlot->setToRange) <= cacheSlot->setToLength), &exception, exitNow); - -#ifndef NS_BLOCK_ASSERTIONS - if(cacheSlot->setToNeedsConversion == 0U) { RKLCDelayedAssert((cacheSlot->setToUniChar == CFStringGetCharactersPtr(cacheSlot->setToString)), &exception, exitNow); } - else { - RKLBuffer *buffer = (cacheSlot->setToLength < (CFIndex)(RKL_FIXED_LENGTH)) ? &fixedBuffer : &dynamicBuffer; - RKLCDelayedAssert((cacheSlot->setToHash == buffer->hash) && (cacheSlot->setToLength == buffer->length) && (cacheSlot->setToUniChar == buffer->uniChar), &exception, exitNow); - } -#endif - - switch(maskedRegexOp) { - case RKLRangeOp: - if((rkl_search(cacheSlot, matchRange, 0UL, &exception, &status) == NO) || (RKL_EXPECTED(status > U_ZERO_ERROR, 0L))) { *(NSRange *)result = NSNotFoundRange; goto exitNow; } - if(RKL_EXPECTED(capture == 0L, 1L)) { *(NSRange *)result = cacheSlot->lastMatchRange; } else { if(RKL_EXPECTED(rkl_getRangeForCapture(cacheSlot, &status, (int32_t)capture, (NSRange *)result) > U_ZERO_ERROR, 0L)) { goto exitNow; } } - break; - - case RKLSplitOp: // Fall-thru... - case RKLArrayOfStringsOp: // Fall-thru... - case RKLCapturesArrayOp: // Fall-thru... - case RKLArrayOfCapturesOp: - findAll = rkl_makeFindAll(stackRanges, *matchRange, 2048L, (2048UL * sizeof(NSRange)), 0UL, (void **)&scratchBuffer[0], &scratchBuffer[1], &scratchBuffer[2], 0L, capture, ((maskedRegexOp == RKLCapturesArrayOp) ? 1L : NSIntegerMax)); - - if(RKL_EXPECTED(rkl_findRanges(cacheSlot, regexOp, &findAll, &exception, &status) == NO, 1L)) { - if(RKL_EXPECTED(findAll.found == 0L, 0L)) { resultObject = [NSArray array]; } else { resultObject = rkl_makeArray(cacheSlot, regexOp, &findAll, &exception); } - } - - if(RKL_EXPECTED(scratchBuffer[0] != NULL, 0L)) { scratchBuffer[0] = rkl_free(&scratchBuffer[0]); } - if(RKL_EXPECTED(scratchBuffer[1] != NULL, 0L)) { scratchBuffer[1] = rkl_free(&scratchBuffer[1]); } - if(RKL_EXPECTED(scratchBuffer[2] != NULL, 0L)) { scratchBuffer[2] = rkl_free(&scratchBuffer[2]); } - - break; - - case RKLReplaceOp: resultObject = rkl_replaceString(cacheSlot, matchString, stringU16Length, replacementString, (NSUInteger)CFStringGetLength((CFStringRef)replacementString), (NSUInteger *)result, (replaceMutable = (((regexOp & RKLReplaceMutable) != 0) ? 1UL : 0UL)), &exception, &status); break; - default: exception = RKLCAssertDictionary(@"Unknown regexOp code."); break; - } - -exitNow: - OSSpinLockUnlock(&cacheSpinLock); - cacheSpinLockStatus |= RKLUnlockedCacheSpinLock; // Warning about cacheSpinLockStatus never being read can be safely ignored. - - if(RKL_EXPECTED(status > U_ZERO_ERROR, 0L) && RKL_EXPECTED(exception == NULL, 0L)) { exception = rkl_NSExceptionForRegex(regexString, options, NULL, status); } // If we had a problem, prepare an exception to be thrown. - if(RKL_EXPECTED(exception != NULL, 0L)) { rkl_handleDelayedAssert(self, _cmd, exception); } // If there is an exception, throw it at this point. - // If we're working on a mutable string and there were successful matches/replacements, then we still have work to do. - // This is done outside the cache lock and with the objc replaceCharactersInRange:withString: method because Core Foundation - // does not assert that the string we are attempting to update is actually a mutable string, whereas Foundation ensures - // the object receiving the message is a mutable string and throws an exception if we're attempting to modify an immutable string. - if(RKL_EXPECTED(status == U_ZERO_ERROR, 1L) && RKL_EXPECTED(resultObject != NULL, 1L) && RKL_EXPECTED(replaceMutable == 1UL, 0L) && RKL_EXPECTED(*((NSUInteger *)result) > 0UL, 1L)) { [matchString replaceCharactersInRange:*matchRange withString:resultObject]; } - // If status < U_ZERO_ERROR, consider it an error, even though status < U_ZERO_ERROR is a 'warning' in ICU nomenclature. - // status > U_ZERO_ERROR are an exception and handled above. - // http://sourceforge.net/tracker/?func=detail&atid=990188&aid=2890810&group_id=204582 - if(RKL_EXPECTED(status < U_ZERO_ERROR, 0L) && RKL_EXPECTED(resultObject == NULL, 0L) && (error != NULL)) { *error = [NSError errorWithDomain:RKLICURegexErrorDomain code:(NSInteger)status userInfo:rkl_userInfoDictionary(regexString, options, NULL, status, @"The ICU library returned an unexpected error code.", @"NSLocalizedDescription", NULL)]; } - return(resultObject); -} - -static void rkl_handleDelayedAssert(id self, SEL _cmd, id exception) { - if(RKL_EXPECTED(exception != NULL, 0L)) { - if([exception isKindOfClass:[NSException class]]) { [[NSException exceptionWithName:[(NSException *)exception name] reason:rkl_stringFromClassAndMethod(self, _cmd, [exception reason]) userInfo:[exception userInfo]] raise]; } - else { - id functionString = [exception objectForKey:@"function"], fileString = [exception objectForKey:@"file"], descriptionString = [exception objectForKey:@"description"], lineNumber = [exception objectForKey:@"line"]; - NSCParameterAssert((functionString != NULL) && (fileString != NULL) && (descriptionString != NULL) && (lineNumber != NULL)); - [[NSAssertionHandler currentHandler] handleFailureInFunction:functionString file:fileString lineNumber:(NSInteger)[lineNumber longValue] description:@"%@", descriptionString]; - } - } -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called from rkl_performRegexOp() or rkl_findRanges(). -// ---------- - -static NSUInteger rkl_search(RKLCacheSlot *cacheSlot, NSRange *searchRange, NSUInteger updateSearchRange, id *exception RKL_UNUSED_ASSERTION_ARG, int32_t *status) { - NSUInteger foundMatch = 0UL, searchEqualsEndOfRange = (RKL_EXPECTED(NSEqualRanges(*searchRange, NSMakeRange(NSMaxRange(cacheSlot->setToRange), 0UL)) == YES, 0L) ? 1UL : 0UL); - - if((NSEqualRanges(*searchRange, cacheSlot->lastFindRange) == YES) || (searchEqualsEndOfRange == 1UL)) { foundMatch = (((cacheSlot->lastMatchRange.location == (NSUInteger)NSNotFound) || (searchEqualsEndOfRange == 1UL)) ? 0UL : 1UL);} - else { // Only perform an expensive 'find' operation iff the current find range is different than the last find range. - NSUInteger findLocation = (searchRange->location - cacheSlot->setToRange.location); - RKLCDelayedAssert(((searchRange->location >= cacheSlot->setToRange.location)) && (NSRangeInsideRange(*searchRange, cacheSlot->setToRange) == YES) && (findLocation < INT_MAX) && (findLocation <= cacheSlot->setToRange.length), exception, exitNow); - - RKL_PREFETCH_UNICHAR(cacheSlot->setToUniChar, searchRange->location); // Spool up the CPU caches. - - // Using uregex_findNext can be a slight performance win. - NSUInteger useFindNext = ((searchRange->location == (NSMaxRange(cacheSlot->lastMatchRange) + (((cacheSlot->lastMatchRange.length == 0UL) && (cacheSlot->lastMatchRange.location < NSMaxRange(cacheSlot->setToRange))) ? 1UL : 0UL))) ? 1UL : 0UL); - - cacheSlot->lastFindRange = *searchRange; - if(RKL_EXPECTED(useFindNext == 0UL, 0L)) { if(RKL_EXPECTED((RKL_ICU_FUNCTION_APPEND(uregex_find) (cacheSlot->icu_regex, (int32_t)findLocation, status) == NO), 0L) || RKL_EXPECTED(*status > U_ZERO_ERROR, 0L)) { goto finishedFind; } } - else { if(RKL_EXPECTED((RKL_ICU_FUNCTION_APPEND(uregex_findNext)(cacheSlot->icu_regex, status) == NO), 0L) || RKL_EXPECTED(*status > U_ZERO_ERROR, 0L)) { goto finishedFind; } } - foundMatch = 1UL; - - if(RKL_EXPECTED(rkl_getRangeForCapture(cacheSlot, status, 0, &cacheSlot->lastMatchRange) > U_ZERO_ERROR, 0L)) { goto finishedFind; } - RKLCDelayedAssert(NSRangeInsideRange(cacheSlot->lastMatchRange, *searchRange) == YES, exception, exitNow); - } - -finishedFind: - if(RKL_EXPECTED(*status > U_ZERO_ERROR, 0L)) { foundMatch = 0UL; cacheSlot->lastFindRange = NSNotFoundRange; } - - if(foundMatch == 0UL) { cacheSlot->lastFindRange = NSNotFoundRange; cacheSlot->lastMatchRange = NSNotFoundRange; if(updateSearchRange == 1UL) { *searchRange = NSMakeRange(NSMaxRange(*searchRange), 0UL); } } - else { - RKLCDelayedAssert(NSRangeInsideRange(cacheSlot->lastMatchRange, *searchRange) == YES, exception, exitNow); - if(updateSearchRange == 1UL) { - NSUInteger nextLocation = (NSMaxRange(cacheSlot->lastMatchRange) + (((cacheSlot->lastMatchRange.length == 0UL) && (cacheSlot->lastMatchRange.location < NSMaxRange(cacheSlot->setToRange))) ? 1UL : 0UL)), locationDiff = nextLocation - searchRange->location; - RKLCDelayedAssert((((locationDiff > 0UL) || ((locationDiff == 0UL) && (cacheSlot->lastMatchRange.location == NSMaxRange(cacheSlot->setToRange)))) && (locationDiff <= searchRange->length)), exception, exitNow); - searchRange->location = nextLocation; - searchRange->length -= locationDiff; - } - } - -#ifndef NS_BLOCK_ASSERTIONS -exitNow: -#endif - return(foundMatch); -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called from rkl_doFindOp(). -// ---------- - -static BOOL rkl_findRanges(RKLCacheSlot *cacheSlot, RKLRegexOp regexOp, RKLFindAll *findAll, id *exception, int32_t *status) { - BOOL returnWithError = YES; - RKLCDelayedAssert((((cacheSlot != NULL) && (cacheSlot->icu_regex != NULL) && (cacheSlot->setToUniChar != NULL) && (cacheSlot->captureCount >= 0L) && (cacheSlot->setToRange.location != (NSUInteger)NSNotFound)) && (status != NULL) && ((findAll != NULL) && (findAll->found == 0L) && ((findAll->capacity >= 0L) && (((findAll->capacity > 0L) || (findAll->size > 0UL)) ? ((findAll->ranges != NULL) && (findAll->capacity > 0L) && (findAll->size > 0UL)) : 1)) && (findAll->rangesScratchBuffer != NULL) && ((findAll->capture >= 0L) && (findAll->capture <= cacheSlot->captureCount)))), exception, exitNow); - - if(RKL_EXPECTED(cacheSlot->setToLength == 0L, 0L) || RKL_EXPECTED(cacheSlot->setToRange.length == 0UL, 0L)) { returnWithError = NO; goto exitNow; } - - NSInteger captureCount = cacheSlot->captureCount; - RKLRegexOp maskedRegexOp = (regexOp & RKLMaskOp); - NSUInteger lastLocation = findAll->findInRange.location; - NSRange searchRange = findAll->findInRange; - - for(findAll->found = 0L; (findAll->found < findAll->findUpTo) && ((findAll->found < findAll->capacity) || (findAll->found == 0L)); findAll->found++) { - NSInteger loopCapture, shouldBreak = 0L; - - if(RKL_EXPECTED(findAll->found >= ((findAll->capacity - ((captureCount + 2L) * 4L)) - 4L), 0L)) { if(RKL_EXPECTED(rkl_growFindRanges(cacheSlot, lastLocation, findAll, exception) == 0UL, 0L)) { goto exitNow; } } - - RKLCDelayedAssert((searchRange.location != (NSUInteger)NSNotFound) && (NSRangeInsideRange(searchRange, cacheSlot->setToRange) == YES) && (NSRangeInsideRange(findAll->findInRange, cacheSlot->setToRange) == YES), exception, exitNow); - - // This fixes a 'bug' that is also present in ICU's uregex_split(). 'Bug', in this case, means that the results of a split operation can differ from those that perl's split() creates for the same input. - // "I|at|ice I eat rice" split using the regex "\b\s*" demonstrates the problem. ICU bug http://bugs.icu-project.org/trac/ticket/6826 - // ICU : "", "I", "|", "at", "|", "ice", "", "I", "", "eat", "", "rice" <- Results that RegexKitLite used to produce. - // PERL: "I", "|", "at", "|", "ice", "I", "eat", "rice" <- Results that RegexKitLite now produces. - do { if((rkl_search(cacheSlot, &searchRange, 1UL, exception, status) == NO) || (RKL_EXPECTED(*status > U_ZERO_ERROR, 0L))) { shouldBreak = 1L; } } - while((maskedRegexOp == RKLSplitOp) && RKL_EXPECTED(shouldBreak == 0L, 1L) && RKL_EXPECTED(cacheSlot->lastMatchRange.length == 0UL, 0L) && RKL_EXPECTED((cacheSlot->lastMatchRange.location - lastLocation) == 0UL, 0L)); - if(RKL_EXPECTED(shouldBreak == 1L, 0L)) { break; } - - RKLCDelayedAssert((searchRange.location != (NSUInteger)NSNotFound) && (NSRangeInsideRange(searchRange, cacheSlot->setToRange) == YES) && (NSRangeInsideRange(findAll->findInRange, cacheSlot->setToRange) == YES) && (NSRangeInsideRange(searchRange, findAll->findInRange) == YES), exception, exitNow); - RKLCDelayedAssert((NSRangeInsideRange(cacheSlot->lastFindRange, cacheSlot->setToRange) == YES) && (NSRangeInsideRange(cacheSlot->lastMatchRange, cacheSlot->setToRange) == YES) && (NSRangeInsideRange(cacheSlot->lastMatchRange, findAll->findInRange) == YES), exception, exitNow); - RKLCDelayedAssert((findAll->ranges != NULL) && (findAll->found >= 0L) && (findAll->capacity >= 0L) && ((findAll->found + (captureCount + 3L) + 1L) < (findAll->capacity - 2L)), exception, exitNow); - - switch(maskedRegexOp) { - case RKLArrayOfStringsOp: - if(findAll->capture == 0L) { findAll->ranges[findAll->found] = cacheSlot->lastMatchRange; } else { if(RKL_EXPECTED(rkl_getRangeForCapture(cacheSlot, status, (int32_t)findAll->capture, &findAll->ranges[findAll->found]) > U_ZERO_ERROR, 0L)) { goto exitNow; } } - break; - - case RKLSplitOp: // Fall-thru... - case RKLCapturesArrayOp: // Fall-thru... - case RKLArrayOfCapturesOp: - findAll->ranges[findAll->found] = ((maskedRegexOp == RKLSplitOp) ? NSMakeRange(lastLocation, cacheSlot->lastMatchRange.location - lastLocation) : cacheSlot->lastMatchRange); - - for(loopCapture = 1L; loopCapture <= captureCount; loopCapture++) { - RKLCDelayedAssert((findAll->found >= 0L) && (findAll->found < (findAll->capacity - 2L)) && (loopCapture < INT_MAX), exception, exitNow); - if(RKL_EXPECTED(rkl_getRangeForCapture(cacheSlot, status, (int32_t)loopCapture, &findAll->ranges[++findAll->found]) > U_ZERO_ERROR, 0L)) { goto exitNow; } - } - break; - - default: if(*exception != NULL) { *exception = RKLCAssertDictionary(@"Unknown regexOp."); } goto exitNow; break; - } - - lastLocation = NSMaxRange(cacheSlot->lastMatchRange); - } - - if(RKL_EXPECTED(*status > U_ZERO_ERROR, 0L)) { goto exitNow; } - - RKLCDelayedAssert((findAll->ranges != NULL) && (findAll->found >= 0L) && (findAll->found < (findAll->capacity - 2L)), exception, exitNow); - if((maskedRegexOp == RKLSplitOp) && (lastLocation != NSMaxRange(findAll->findInRange))) { findAll->ranges[findAll->found++] = NSMakeRange(lastLocation, NSMaxRange(findAll->findInRange) - lastLocation); } - - RKLCDelayedAssert((findAll->ranges != NULL) && (findAll->found >= 0L) && (findAll->found < (findAll->capacity - 2L)), exception, exitNow); - returnWithError = NO; - -exitNow: - return(returnWithError); -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called from rkl_findRanges(). -// ---------- - -static NSUInteger rkl_growFindRanges(RKLCacheSlot *cacheSlot, NSUInteger lastLocation, RKLFindAll *findAll, id *exception RKL_UNUSED_ASSERTION_ARG) { - NSUInteger didGrowRanges = 0UL; - RKLCDelayedAssert((((cacheSlot != NULL) && (cacheSlot->captureCount >= 0L)) && ((findAll != NULL) && (findAll->capacity >= 0L) && (findAll->rangesScratchBuffer != NULL) && (findAll->found >= 0L) && (((findAll->capacity > 0L) || (findAll->size > 0UL) || (findAll->ranges != NULL)) ? ((findAll->capacity > 0L) && (findAll->size > 0UL) && (findAll->ranges != NULL) && (((size_t)findAll->capacity * sizeof(NSRange)) == findAll->size)) : 1))), exception, exitNow); - - // Attempt to guesstimate the required capacity based on: the total length needed to search / (length we've searched so far / ranges found so far). - NSInteger newCapacity = (findAll->capacity + (findAll->capacity / 2L)), estimate = (NSInteger)((float)cacheSlot->setToLength / (((float)lastLocation + 1.0f) / ((float)findAll->found + 1.0f))); - newCapacity = (((newCapacity + ((estimate > newCapacity) ? estimate : newCapacity)) / 2L) + ((cacheSlot->captureCount + 2L) * 4L) + 4L); - - NSUInteger needToCopy = ((findAll->ranges != NULL) && (*findAll->rangesScratchBuffer != findAll->ranges)) ? 1UL : 0UL; // If findAll->ranges is set to a stack allocation then we need to manually copy the data from the stack to the new heap allocation. - size_t newSize = ((size_t)newCapacity * sizeof(NSRange)); - NSRange *newRanges = NULL; - - if(RKL_EXPECTED((newRanges = (NSRange *)rkl_realloc((RKL_STRONG_REF void **)findAll->rangesScratchBuffer, newSize, 0UL)) == NULL, 0L)) { findAll->capacity = 0L; findAll->size = 0UL; findAll->ranges = NULL; *findAll->rangesScratchBuffer = rkl_free((RKL_STRONG_REF void **)findAll->rangesScratchBuffer); goto exitNow; } else { didGrowRanges = 1UL; } - if(needToCopy == 1UL) { memcpy(newRanges, findAll->ranges, findAll->size); } // If necessary, copy the existing data to the new heap allocation. - - findAll->capacity = newCapacity; - findAll->size = newSize; - findAll->ranges = newRanges; - -exitNow: - return(didGrowRanges); -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called from rkl_doFindOp(). -// ---------- - -static NSArray *rkl_makeArray(RKLCacheSlot *cacheSlot, RKLRegexOp regexOp, RKLFindAll *findAll, id *exception RKL_UNUSED_ASSERTION_ARG) { - NSUInteger createdStringsCount = 0UL, createdArraysCount = 0UL, transferedStringsCount = 0UL; - id *matchedStrings = NULL, *subcaptureArrays = NULL, emptyString = @""; - NSArray *resultArray = NULL; - - RKLCDelayedAssert((cacheSlot != NULL) && ((findAll != NULL) && (findAll->found >= 0L) && (findAll->stringsScratchBuffer != NULL) && (findAll->arraysScratchBuffer != NULL)), exception, exitNow); - - size_t matchedStringsSize = ((size_t)findAll->found * sizeof(id)); - CFStringRef setToString = cacheSlot->setToString; - - if((findAll->stackUsed + matchedStringsSize) < (size_t)(RKL_STACK_LIMIT)) { if(RKL_EXPECTED((matchedStrings = (id *)alloca(matchedStringsSize)) == NULL, 0L)) { goto exitNow; } findAll->stackUsed += matchedStringsSize; } - else { if(RKL_EXPECTED((matchedStrings = (id *)rkl_realloc(findAll->stringsScratchBuffer, matchedStringsSize, (NSUInteger)RKLScannedOption)) == NULL, 0L)) { goto exitNow; } } - - { // This sub-block (and its local variables) is here for the benefit of the optimizer. - NSUInteger found = (NSUInteger)findAll->found; - const NSRange *rangePtr = findAll->ranges; - id *matchedStringsPtr = matchedStrings; - - for(createdStringsCount = 0UL; createdStringsCount < found; createdStringsCount++) { - NSRange range = *rangePtr++; - if(RKL_EXPECTED(((*matchedStringsPtr++ = RKL_EXPECTED(range.length == 0UL, 0L) ? emptyString : rkl_CreateStringWithSubstring((id)setToString, range)) == NULL), 0L)) { goto exitNow; } - } - } - - NSUInteger arrayCount = createdStringsCount; - id *arrayObjects = matchedStrings; - - if((regexOp & RKLSubcapturesArray) != 0UL) { - RKLCDelayedAssert(((createdStringsCount % ((NSUInteger)cacheSlot->captureCount + 1UL)) == 0UL) && (createdArraysCount == 0UL), exception, exitNow); - - NSUInteger captureCount = ((NSUInteger)cacheSlot->captureCount + 1UL); - NSUInteger subcaptureArraysCount = (createdStringsCount / captureCount); - size_t subcaptureArraysSize = ((size_t)subcaptureArraysCount * sizeof(id)); - - if((findAll->stackUsed + subcaptureArraysSize) < (size_t)(RKL_STACK_LIMIT)) { if(RKL_EXPECTED((subcaptureArrays = (id *)alloca(subcaptureArraysSize)) == NULL, 0L)) { goto exitNow; } findAll->stackUsed += subcaptureArraysSize; } - else { if(RKL_EXPECTED((subcaptureArrays = (id *)rkl_realloc(findAll->arraysScratchBuffer, subcaptureArraysSize, (NSUInteger)RKLScannedOption)) == NULL, 0L)) { goto exitNow; } } - - { // This sub-block (and its local variables) is here for the benefit of the optimizer. - id *subcaptureArraysPtr = subcaptureArrays; - id *matchedStringsPtr = matchedStrings; - - for(createdArraysCount = 0UL; createdArraysCount < subcaptureArraysCount; createdArraysCount++) { - if(RKL_EXPECTED((*subcaptureArraysPtr++ = rkl_CreateArrayWithObjects((void **)matchedStringsPtr, captureCount)) == NULL, 0L)) { goto exitNow; } - matchedStringsPtr += captureCount; - transferedStringsCount += captureCount; - } - } - - RKLCDelayedAssert((transferedStringsCount == createdStringsCount), exception, exitNow); - arrayCount = createdArraysCount; - arrayObjects = subcaptureArrays; - } - - RKLCDelayedAssert((arrayObjects != NULL), exception, exitNow); - resultArray = rkl_CreateAutoreleasedArray((void **)arrayObjects, (NSUInteger)arrayCount); - -exitNow: - if(RKL_EXPECTED(resultArray == NULL, 0L) && (rkl_collectingEnabled() == NO)) { // If we did not create an array then we need to make sure that we release any objects we created. - NSUInteger x; - if(matchedStrings != NULL) { for(x = transferedStringsCount; x < createdStringsCount; x++) { if((matchedStrings[x] != NULL) && (matchedStrings[x] != emptyString)) { matchedStrings[x] = rkl_ReleaseObject(matchedStrings[x]); } } } - if(subcaptureArrays != NULL) { for(x = 0UL; x < createdArraysCount; x++) { if(subcaptureArrays[x] != NULL) { subcaptureArrays[x] = rkl_ReleaseObject(subcaptureArrays[x]); } } } - } - - return(resultArray); -} - -// IMPORTANT! This code is critical path code. Because of this, it has been written for speed, not clarity. -// IMPORTANT! Should only be called from rkl_performRegexOp(). -// ---------- - -static NSString *rkl_replaceString(RKLCacheSlot *cacheSlot, id searchString, NSUInteger searchU16Length, NSString *replacementString, NSUInteger replacementU16Length, NSUInteger *replacedCountPtr, NSUInteger replaceMutable, id *exception, int32_t *status) { - uint64_t searchU16Length64 = (uint64_t)searchU16Length, replacementU16Length64 = (uint64_t)replacementU16Length; - int32_t resultU16Length = 0, tempUniCharBufferU16Capacity = 0, needU16Capacity = 0; - UniChar *tempUniCharBuffer = NULL; - const UniChar *replacementUniChar = NULL; - id resultObject = NULL; - NSUInteger replacedCount = 0UL; - - if((RKL_EXPECTED(replacementU16Length64 >= (uint64_t)INT_MAX, 0L) || RKL_EXPECTED(((searchU16Length64 / 2ULL) + (replacementU16Length64 * 2ULL)) >= (uint64_t)INT_MAX, 0L))) { *exception = [NSException exceptionWithName:NSRangeException reason:@"Replacement string length exceeds INT_MAX." userInfo:NULL]; goto exitNow; } - - RKLCDelayedAssert((searchU16Length64 < (uint64_t)INT_MAX) && (replacementU16Length64 < (uint64_t)INT_MAX) && (((searchU16Length64 / 2ULL) + (replacementU16Length64 * 2ULL)) < (uint64_t)INT_MAX), exception, exitNow); - - // Zero order approximation of the buffer sizes for holding the replaced string or split strings and split strings pointer offsets. As UTF16 code units. - tempUniCharBufferU16Capacity = (int32_t)(16UL + (searchU16Length + (searchU16Length / 2UL)) + (replacementU16Length * 2UL)); - RKLCDelayedAssert((tempUniCharBufferU16Capacity < INT_MAX) && (tempUniCharBufferU16Capacity > 0), exception, exitNow); - - // Buffer sizes converted from native units to bytes. - size_t stackSize = 0UL, replacementSize = ((size_t)replacementU16Length * sizeof(UniChar)), tempUniCharBufferSize = ((size_t)tempUniCharBufferU16Capacity * sizeof(UniChar)); - - // For the various buffers we require, we first try to allocate from the stack if we're not over the RKL_STACK_LIMIT. If we are, switch to using the heap for the buffer. - if((stackSize + tempUniCharBufferSize) < (size_t)(RKL_STACK_LIMIT)) { if(RKL_EXPECTED((tempUniCharBuffer = (UniChar *)alloca(tempUniCharBufferSize)) == NULL, 0L)) { goto exitNow; } stackSize += tempUniCharBufferSize; } - else { if(RKL_EXPECTED((tempUniCharBuffer = (UniChar *)rkl_realloc(&scratchBuffer[0], tempUniCharBufferSize, 0UL)) == NULL, 0L)) { goto exitNow; } } - - // Try to get the pointer to the replacement strings UTF16 data. If we can't, allocate some buffer space, then covert to UTF16. - if((replacementUniChar = CFStringGetCharactersPtr((CFStringRef)replacementString)) == NULL) { - UniChar *uniCharBuffer = NULL; - if((stackSize + replacementSize) < (size_t)(RKL_STACK_LIMIT)) { if(RKL_EXPECTED((uniCharBuffer = (UniChar *)alloca(replacementSize)) == NULL, 0L)) { goto exitNow; } stackSize += replacementSize; } - else { if(RKL_EXPECTED((uniCharBuffer = (UniChar *)rkl_realloc(&scratchBuffer[1], replacementSize, 0UL)) == NULL, 0L)) { goto exitNow; } } - CFStringGetCharacters((CFStringRef)replacementString, CFMakeRange(0L, replacementU16Length), uniCharBuffer); // Convert to a UTF16 string. - replacementUniChar = uniCharBuffer; - } - - resultU16Length = rkl_replaceAll(cacheSlot, replacementUniChar, (int32_t)replacementU16Length, tempUniCharBuffer, tempUniCharBufferU16Capacity, &replacedCount, &needU16Capacity, exception, status); - RKLCDelayedAssert((resultU16Length <= tempUniCharBufferU16Capacity) && (needU16Capacity >= resultU16Length) && (needU16Capacity >= 0), exception, exitNow); - if(RKL_EXPECTED(needU16Capacity >= INT_MAX, 0L)) { *exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Replaced string length exceeds INT_MAX." userInfo:NULL]; goto exitNow; } - - if(RKL_EXPECTED(*status == U_BUFFER_OVERFLOW_ERROR, 0L)) { // Our buffer guess(es) were too small. Resize the buffers and try again. - tempUniCharBufferSize = ((size_t)(tempUniCharBufferU16Capacity = needU16Capacity + 4) * sizeof(UniChar)); // Use needU16Capacity. Bug 2890810. - if((stackSize + tempUniCharBufferSize) < (size_t)(RKL_STACK_LIMIT)) { if(RKL_EXPECTED((tempUniCharBuffer = (UniChar *)alloca(tempUniCharBufferSize)) == NULL, 0L)) { goto exitNow; } stackSize += tempUniCharBufferSize; } // Warning about stackSize can be safely ignored. - else { if(RKL_EXPECTED((tempUniCharBuffer = (UniChar *)rkl_realloc(&scratchBuffer[0], tempUniCharBufferSize, 0UL)) == NULL, 0L)) { goto exitNow; } } - - *status = U_ZERO_ERROR; // Make sure the status var is cleared and try again. - resultU16Length = rkl_replaceAll(cacheSlot, replacementUniChar, (int32_t)replacementU16Length, tempUniCharBuffer, tempUniCharBufferU16Capacity, &replacedCount, &needU16Capacity, exception, status); - RKLCDelayedAssert((resultU16Length <= tempUniCharBufferU16Capacity) && (needU16Capacity >= resultU16Length) && (needU16Capacity >= 0), exception, exitNow); - } - - // If status != U_ZERO_ERROR, consider it an error, even though status < U_ZERO_ERROR is a 'warning' in ICU nomenclature. - // http://sourceforge.net/tracker/?func=detail&atid=990188&aid=2890810&group_id=204582 - if(RKL_EXPECTED(*status != U_ZERO_ERROR, 0L)) { goto exitNow; } // Something went wrong. - - if(resultU16Length == 0) { resultObject = @""; } // Optimize the case where the replaced text length == 0 with a @"" string. - else if(((NSUInteger)resultU16Length == searchU16Length) && (replacedCount == 0UL)) { // Optimize the case where the replacement == original by creating a copy. Very fast if self is immutable. - if(replaceMutable == 0UL) { resultObject = rkl_CFAutorelease(CFStringCreateCopy(NULL, (CFStringRef)searchString)); } // .. but only if this is not replacing a mutable self. Warning about potential leak can be safely ignored. - } else { resultObject = rkl_CFAutorelease(CFStringCreateWithCharacters(NULL, tempUniCharBuffer, (CFIndex)resultU16Length)); } // otherwise, create a new string. Warning about potential leak can be safely ignored. - - // If replaceMutable == 1UL, we don't do the replacement here. We wait until after we return and unlock the cache lock. - // This is because we may be trying to mutate an immutable string object. - if((replacedCount > 0UL) && (replaceMutable == 1UL)) { // We're working on a mutable string and there were successfull matches with replaced text, so there's work to do. - rkl_clearBuffer((cacheSlot->setToLength < (CFIndex)(RKL_FIXED_LENGTH)) ? &fixedBuffer : &dynamicBuffer, 0UL); - rkl_clearCacheSlotSetTo(cacheSlot); // Flush any cached information about this string since it will mutate. - } - -exitNow: - if(scratchBuffer[0] != NULL) { scratchBuffer[0] = rkl_free(&scratchBuffer[0]); } - if(scratchBuffer[1] != NULL) { scratchBuffer[1] = rkl_free(&scratchBuffer[1]); } - if(replacedCountPtr != NULL) { *replacedCountPtr = replacedCount; } - return(resultObject); -} // The two warnings about potential leaks can be safely ignored. - -// IMPORTANT! Should only be called from rkl_replaceString(). -// ---------- -// Modified version of the ICU libraries uregex_replaceAll() that keeps count of the number of replacements made. - -static int32_t rkl_replaceAll(RKLCacheSlot *cacheSlot, const UniChar *replacementUniChar, int32_t replacementU16Length, UniChar *replacedUniChar, int32_t replacedU16Capacity, NSUInteger *replacedCount, int32_t *needU16Capacity, id *exception RKL_UNUSED_ASSERTION_ARG, int32_t *status) { - int32_t u16Length = 0, initialReplacedU16Capacity = replacedU16Capacity; - NSUInteger replaced = 0UL, bufferOverflowed = 0UL; - RKLCDelayedAssert((cacheSlot != NULL) && (replacementUniChar != NULL) && (replacedUniChar != NULL) && (replacedCount != NULL) && (needU16Capacity != NULL) && (status != NULL) && (replacementU16Length >= 0) && (replacedU16Capacity >= 0), exception, exitNow); - - cacheSlot->lastFindRange = cacheSlot->lastMatchRange = NSNotFoundRange; // Clear the cached find information for this regex so a subsequent find works correctly. - RKL_ICU_FUNCTION_APPEND(uregex_reset)(cacheSlot->icu_regex, 0, status); - - // Work around for ICU uregex_reset() bug, see http://bugs.icu-project.org/trac/ticket/6545 - // http://sourceforge.net/tracker/index.php?func=detail&aid=2105213&group_id=204582&atid=990188 - if(RKL_EXPECTED(cacheSlot->setToRange.length == 0L, 0L) && (*status == U_INDEX_OUTOFBOUNDS_ERROR)) { *status = U_ZERO_ERROR; } - - // This loop originally came from ICU source/i18n/uregex.cpp, uregex_replaceAll. - // There is a bug in that code which causes the size of the buffer required for the replaced text to not be calculated correctly. - // This contains a work around using the variable bufferOverflowed. - // ICU bug: http://bugs.icu-project.org/trac/ticket/6656 - // http://sourceforge.net/tracker/index.php?func=detail&aid=2408447&group_id=204582&atid=990188 - while(RKL_ICU_FUNCTION_APPEND(uregex_findNext)(cacheSlot->icu_regex, status)) { - replaced++; - u16Length += RKL_ICU_FUNCTION_APPEND(uregex_appendReplacement)(cacheSlot->icu_regex, replacementUniChar, replacementU16Length, &replacedUniChar, &replacedU16Capacity, status); - if(RKL_EXPECTED(*status == U_BUFFER_OVERFLOW_ERROR, 0L)) { bufferOverflowed = 1UL; *status = U_ZERO_ERROR; } - } - if(RKL_EXPECTED(*status == U_BUFFER_OVERFLOW_ERROR, 0L)) { bufferOverflowed = 1UL; *status = U_ZERO_ERROR; } - u16Length += RKL_ICU_FUNCTION_APPEND(uregex_appendTail)(cacheSlot->icu_regex, &replacedUniChar, &replacedU16Capacity, status); - - // Check for status <= U_ZERO_ERROR (a 'warning' in ICU nomenclature) rather than just status == U_ZERO_ERROR. - // Under just the right circumstances, status might be equal to U_STRING_NOT_TERMINATED_WARNING. When this occured, - // rkl_replaceString would never get the U_BUFFER_OVERFLOW_ERROR status, and thus never grow the buffer to the size needed. - // http://sourceforge.net/tracker/?func=detail&atid=990188&aid=2890810&group_id=204582 - if(RKL_EXPECTED(*status <= U_ZERO_ERROR, 1L) && RKL_EXPECTED(bufferOverflowed == 1UL, 0L)) { *status = U_BUFFER_OVERFLOW_ERROR; } - -#ifndef NS_BLOCK_ASSERTIONS -exitNow: -#endif - if(replacedCount != NULL) { *replacedCount = replaced; } - if(needU16Capacity != NULL) { *needU16Capacity = u16Length; } // Use needU16Capacity to return the number of characters that are needed for the completely replaced string. Bug 2890810. - return(initialReplacedU16Capacity - replacedU16Capacity); // Return the number of characters of replacedUniChar that were used. -} - -static NSUInteger rkl_isRegexValid(id self, SEL _cmd, NSString *regex, RKLRegexOptions options, NSInteger *captureCountPtr, NSError **error) { - volatile NSUInteger RKL_CLEANUP(rkl_cleanup_cacheSpinLockStatus) cacheSpinLockStatus = 0UL; - - RKLCacheSlot *cacheSlot = NULL; - NSUInteger gotCacheSlot = 0UL; - NSInteger captureCount = -1L; - id exception = NULL; - - if((error != NULL) && (*error != NULL)) { *error = NULL; } - if(regex == NULL) { RKL_RAISE_EXCEPTION(NSInvalidArgumentException, @"The regular expression argument is NULL."); } - - OSSpinLockLock(&cacheSpinLock); - cacheSpinLockStatus |= RKLLockedCacheSpinLock; - rkl_dtrace_incrementEventID(); - if((cacheSlot = rkl_getCachedRegex(regex, options, error, &exception)) != NULL) { gotCacheSlot = 1UL; captureCount = cacheSlot->captureCount; } - cacheSlot = NULL; - OSSpinLockUnlock(&cacheSpinLock); - cacheSpinLockStatus |= RKLUnlockedCacheSpinLock; // Warning about cacheSpinLockStatus never being read can be safely ignored. - - if(captureCountPtr != NULL) { *captureCountPtr = captureCount; } - if(RKL_EXPECTED(exception != NULL, 0L)) { rkl_handleDelayedAssert(self, _cmd, exception); } - return(gotCacheSlot); -} - -static void rkl_clearStringCache(void) { - NSCParameterAssert(cacheSpinLock != (OSSpinLock)0); - lastCacheSlot = NULL; - NSUInteger x = 0UL; - for(x = 0UL; x < (NSUInteger)(RKL_SCRATCH_BUFFERS); x++) { if(scratchBuffer[x] != NULL) { scratchBuffer[x] = rkl_free(&scratchBuffer[x]); } } - for(x = 0UL; x < (NSUInteger)(RKL_CACHE_SIZE); x++) { rkl_clearCacheSlotRegex(&rkl_cacheSlots[x]); } - rkl_clearBuffer(&fixedBuffer, 0UL); - rkl_clearBuffer(&dynamicBuffer, 1UL); -} - -static void rkl_clearBuffer(RKLBuffer *buffer, NSUInteger freeDynamicBuffer) { - if(buffer == NULL) { return; } - if((freeDynamicBuffer == 1UL) && (buffer->uniChar != NULL) && (buffer == &dynamicBuffer)) { RKL_STRONG_REF void *p = (RKL_STRONG_REF void *)dynamicBuffer.uniChar; dynamicBuffer.uniChar = (RKL_STRONG_REF UniChar *)rkl_free(&p); } - if(buffer->string != NULL) { CFRelease((CFTypeRef)buffer->string); buffer->string = NULL; } - buffer->length = 0L; - buffer->hash = 0UL; -} - -static void rkl_clearCacheSlotRegex(RKLCacheSlot *cacheSlot) { - if(cacheSlot == NULL) { return; } - if(cacheSlot->setToString != NULL) { rkl_clearCacheSlotSetTo(cacheSlot); } - if(cacheSlot->icu_regex != NULL) { RKL_ICU_FUNCTION_APPEND(uregex_close)(cacheSlot->icu_regex); cacheSlot->icu_regex = NULL; cacheSlot->captureCount = -1L; } - if(cacheSlot->regexString != NULL) { CFRelease((CFTypeRef)cacheSlot->regexString); cacheSlot->regexString = NULL; cacheSlot->options = 0U; } -} - -static void rkl_clearCacheSlotSetTo(RKLCacheSlot *cacheSlot) { - if(cacheSlot == NULL) { return; } - if(cacheSlot->icu_regex != NULL) { int32_t status = 0; RKL_ICU_FUNCTION_APPEND(uregex_setText)(cacheSlot->icu_regex, &emptyUniCharString[0], 0, &status); } - if(cacheSlot->setToString != NULL) { CFRelease((CFTypeRef)cacheSlot->setToString); cacheSlot->setToString = NULL; } - cacheSlot->lastFindRange = cacheSlot->lastMatchRange = cacheSlot->setToRange = NSNotFoundRange; - cacheSlot->setToIsImmutable = cacheSlot->setToNeedsConversion = 0U; - cacheSlot->setToUniChar = NULL; - cacheSlot->setToHash = 0UL; - cacheSlot->setToLength = 0L; -} - -// Helps to keep things tidy. -#define addKeyAndObject(objs, keys, i, k, o) ({id _o=(o), _k=(k); if((_o != NULL) && (_k != NULL)) { objs[i] = _o; keys[i] = _k; i++; } }) - -static NSDictionary *rkl_userInfoDictionary(NSString *regexString, RKLRegexOptions options, const UParseError *parseError, int32_t status, ...) { - va_list varArgsList; - va_start(varArgsList, status); - if(regexString == NULL) { va_end(varArgsList); return(NULL); } - - id objects[64], keys[64]; - NSUInteger count = 0UL; - - NSString *errorNameString = [NSString stringWithUTF8String:RKL_ICU_FUNCTION_APPEND(u_errorName)(status)]; - - addKeyAndObject(objects, keys, count, RKLICURegexRegexErrorKey, regexString); - addKeyAndObject(objects, keys, count, RKLICURegexRegexOptionsErrorKey, [NSNumber numberWithUnsignedInt:options]); - addKeyAndObject(objects, keys, count, RKLICURegexErrorCodeErrorKey, [NSNumber numberWithInt:status]); - addKeyAndObject(objects, keys, count, RKLICURegexErrorNameErrorKey, errorNameString); - - if((parseError != NULL) && (parseError->line != -1)) { - NSString *preContextString = [NSString stringWithCharacters:&parseError->preContext[0] length:(NSUInteger)RKL_ICU_FUNCTION_APPEND(u_strlen)(&parseError->preContext[0])]; - NSString *postContextString = [NSString stringWithCharacters:&parseError->postContext[0] length:(NSUInteger)RKL_ICU_FUNCTION_APPEND(u_strlen)(&parseError->postContext[0])]; - - addKeyAndObject(objects, keys, count, RKLICURegexLineErrorKey, [NSNumber numberWithInt:parseError->line]); - addKeyAndObject(objects, keys, count, RKLICURegexOffsetErrorKey, [NSNumber numberWithInt:parseError->offset]); - addKeyAndObject(objects, keys, count, RKLICURegexPreContextErrorKey, preContextString); - addKeyAndObject(objects, keys, count, RKLICURegexPostContextErrorKey, postContextString); - addKeyAndObject(objects, keys, count, @"NSLocalizedFailureReason", ([NSString stringWithFormat:@"The error %@ occurred at line %d, column %d: %@<>%@", errorNameString, parseError->line, parseError->offset, preContextString, postContextString])); - } else { - addKeyAndObject(objects, keys, count, @"NSLocalizedFailureReason", ([NSString stringWithFormat:@"The error %@ occurred.", errorNameString])); - } - - while(count < 62UL) { id obj = va_arg(varArgsList, id), key = va_arg(varArgsList, id); if((obj != NULL) && (key != NULL)) { addKeyAndObject(objects, keys, count, key, obj); } else { break; } } - va_end(varArgsList); - - return([NSDictionary dictionaryWithObjects:&objects[0] forKeys:&keys[0] count:count]); -} - -static NSError *rkl_NSErrorForRegex(NSString *regexString, RKLRegexOptions options, const UParseError *parseError, int32_t status) { - return([NSError errorWithDomain:RKLICURegexErrorDomain code:(NSInteger)status userInfo:rkl_userInfoDictionary(regexString, options, parseError, status, @"There was an error compiling the regular expression.", @"NSLocalizedDescription", NULL)]); -} - -static NSException *rkl_NSExceptionForRegex(NSString *regexString, RKLRegexOptions options, const UParseError *parseError, int32_t status) { - return([NSException exceptionWithName:RKLICURegexException reason:[NSString stringWithFormat:@"ICU regular expression error #%d, %s.", status, RKL_ICU_FUNCTION_APPEND(u_errorName)(status)] userInfo:rkl_userInfoDictionary(regexString, options, parseError, status, NULL)]); -} - -static NSDictionary *rkl_makeAssertDictionary(const char *function, const char *file, int line, NSString *format, ...) { - va_list varArgsList; - va_start(varArgsList, format); - NSString *formatString = [[[NSString alloc] initWithFormat:format arguments:varArgsList] autorelease]; - va_end(varArgsList); - NSString *functionString = [NSString stringWithUTF8String:function], *fileString = [NSString stringWithUTF8String:file]; - return([NSDictionary dictionaryWithObjectsAndKeys:formatString, @"description", functionString, @"function", fileString, @"file", [NSNumber numberWithInt:line], @"line", NSInternalInconsistencyException, @"exceptionName", NULL]); -} - -static NSString *rkl_stringFromClassAndMethod(id object, SEL selector, NSString *format, ...) { - va_list varArgsList; - va_start(varArgsList, format); - NSString *formatString = [[[NSString alloc] initWithFormat:format arguments:varArgsList] autorelease]; - va_end(varArgsList); - Class objectsClass = [object class]; - return([NSString stringWithFormat:@"*** %c[%@ %@]: %@", (object == objectsClass) ? '+' : '-', NSStringFromClass(objectsClass), NSStringFromSelector(selector), formatString]); -} - -#pragma mark - -#pragma mark Objective-C Public Interface -#pragma mark - - -@implementation NSString (RegexKitLiteAdditions) - -#pragma mark +clearStringCache - -+ (void)RKL_METHOD_PREPEND(clearStringCache) -{ - volatile NSUInteger RKL_CLEANUP(rkl_cleanup_cacheSpinLockStatus) cacheSpinLockStatus = 0UL; - OSSpinLockLock(&cacheSpinLock); - cacheSpinLockStatus |= RKLLockedCacheSpinLock; - rkl_clearStringCache(); - OSSpinLockUnlock(&cacheSpinLock); - cacheSpinLockStatus |= RKLUnlockedCacheSpinLock; // Warning about cacheSpinLockStatus never being read can be safely ignored. -} - -#pragma mark +captureCountForRegex: - -+ (NSInteger)RKL_METHOD_PREPEND(captureCountForRegex):(NSString *)regex -{ - NSInteger captureCount = -1L; - rkl_isRegexValid(self, _cmd, regex, RKLNoOptions, &captureCount, NULL); - return(captureCount); -} - -+ (NSInteger)RKL_METHOD_PREPEND(captureCountForRegex):(NSString *)regex options:(RKLRegexOptions)options error:(NSError **)error -{ - NSInteger captureCount = -1L; - rkl_isRegexValid(self, _cmd, regex, options, &captureCount, error); - return(captureCount); -} - -#pragma mark -captureCount: - -- (NSInteger)RKL_METHOD_PREPEND(captureCount) -{ - NSInteger captureCount = -1L; - rkl_isRegexValid(self, _cmd, self, RKLNoOptions, &captureCount, NULL); - return(captureCount); -} - -- (NSInteger)RKL_METHOD_PREPEND(captureCountWithOptions):(RKLRegexOptions)options error:(NSError **)error -{ - NSInteger captureCount = -1L; - rkl_isRegexValid(self, _cmd, self, options, &captureCount, error); - return(captureCount); -} - -#pragma mark -componentsSeparatedByRegex: - -- (NSArray *)RKL_METHOD_PREPEND(componentsSeparatedByRegex):(NSString *)regex -{ - NSRange range = NSMaxiumRange; - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLSplitOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(componentsSeparatedByRegex):(NSString *)regex range:(NSRange)range -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLSplitOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(componentsSeparatedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range error:(NSError **)error -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLSplitOp, regex, options, 0L, self, &range, NULL, error, NULL)); -} - -#pragma mark -isMatchedByRegex: - -- (BOOL)RKL_METHOD_PREPEND(isMatchedByRegex):(NSString *)regex -{ - NSRange result = NSNotFoundRange, range = NSMaxiumRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, &result); - return((result.location == (NSUInteger)NSNotFound) ? NO : YES); -} - -- (BOOL)RKL_METHOD_PREPEND(isMatchedByRegex):(NSString *)regex inRange:(NSRange)range -{ - NSRange result = NSNotFoundRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, &result); - return((result.location == (NSUInteger)NSNotFound) ? NO : YES); -} - -- (BOOL)RKL_METHOD_PREPEND(isMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options inRange:(NSRange)range error:(NSError **)error -{ - NSRange result = NSNotFoundRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, options, 0L, self, &range, NULL, error, &result); - return((result.location == (NSUInteger)NSNotFound) ? NO : YES); -} - -#pragma mark -isRegexValid - -- (BOOL)RKL_METHOD_PREPEND(isRegexValid) -{ - return(rkl_isRegexValid(self, _cmd, self, RKLNoOptions, NULL, NULL) == 1UL ? YES : NO); -} - -- (BOOL)RKL_METHOD_PREPEND(isRegexValidWithOptions):(RKLRegexOptions)options error:(NSError **)error -{ - return(rkl_isRegexValid(self, _cmd, self, options, NULL, error) == 1UL ? YES : NO); -} - -#pragma mark -flushCachedRegexData - -- (void)RKL_METHOD_PREPEND(flushCachedRegexData) -{ - volatile NSUInteger RKL_CLEANUP(rkl_cleanup_cacheSpinLockStatus) cacheSpinLockStatus = 0UL; - - CFIndex selfLength = CFStringGetLength((CFStringRef)self); - CFHashCode selfHash = CFHash((CFTypeRef)self); - - OSSpinLockLock(&cacheSpinLock); - cacheSpinLockStatus |= RKLLockedCacheSpinLock; - rkl_dtrace_incrementEventID(); - - NSUInteger slot; - for(slot = 0UL; slot < (NSUInteger)(RKL_CACHE_SIZE); slot++) { - RKLCacheSlot *cacheSlot = &rkl_cacheSlots[slot]; - if((cacheSlot->setToString != NULL) && ( (cacheSlot->setToString == (CFStringRef)self) || ((cacheSlot->setToLength == selfLength) && (cacheSlot->setToHash == selfHash)) ) ) { rkl_clearCacheSlotSetTo(cacheSlot); } - } - - RKLBuffer *buffer = (selfLength < (CFIndex)(RKL_FIXED_LENGTH)) ? &fixedBuffer : &dynamicBuffer; - if((buffer->string != NULL) && ((buffer->string == (CFStringRef)self) || ((buffer->length == selfLength) && (buffer->hash == selfHash)))) { rkl_clearBuffer(buffer, 0UL); } - - OSSpinLockUnlock(&cacheSpinLock); - cacheSpinLockStatus |= RKLUnlockedCacheSpinLock; // Warning about cacheSpinLockStatus never being read can be safely ignored. -} - -#pragma mark -rangeOfRegex: - -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex -{ - NSRange result = NSNotFoundRange, range = NSMaxiumRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, &result); - return(result); -} - -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex capture:(NSInteger)capture -{ - NSRange result = NSNotFoundRange, range = NSMaxiumRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, capture, self, &range, NULL, NULL, &result); - return(result); -} - -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex inRange:(NSRange)range -{ - NSRange result = NSNotFoundRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, &result); - return(result); -} - -- (NSRange)RKL_METHOD_PREPEND(rangeOfRegex):(NSString *)regex options:(RKLRegexOptions)options inRange:(NSRange)range capture:(NSInteger)capture error:(NSError **)error -{ - NSRange result = NSNotFoundRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, options, capture, self, &range, NULL, error, &result); - return(result); -} - -#pragma mark -stringByMatching: - -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex -{ - NSRange matchedRange = NSNotFoundRange, range = NSMaxiumRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, &matchedRange); - return((matchedRange.location == (NSUInteger)NSNotFound) ? NULL : rkl_CFAutorelease(CFStringCreateWithSubstring(NULL, (CFStringRef)self, CFMakeRange(matchedRange.location, matchedRange.length)))); -} // Warning about potential leak can be safely ignored. - -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex capture:(NSInteger)capture -{ - NSRange matchedRange = NSNotFoundRange, range = NSMaxiumRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, capture, self, &range, NULL, NULL, &matchedRange); - return((matchedRange.location == (NSUInteger)NSNotFound) ? NULL : rkl_CFAutorelease(CFStringCreateWithSubstring(NULL, (CFStringRef)self, CFMakeRange(matchedRange.location, matchedRange.length)))); -} // Warning about potential leak can be safely ignored. - -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex inRange:(NSRange)range -{ - NSRange matchedRange = NSNotFoundRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, &matchedRange); - return((matchedRange.location == (NSUInteger)NSNotFound) ? NULL : rkl_CFAutorelease(CFStringCreateWithSubstring(NULL, (CFStringRef)self, CFMakeRange(matchedRange.location, matchedRange.length)))); -} // Warning about potential leak can be safely ignored. - -- (NSString *)RKL_METHOD_PREPEND(stringByMatching):(NSString *)regex options:(RKLRegexOptions)options inRange:(NSRange)range capture:(NSInteger)capture error:(NSError **)error -{ - NSRange matchedRange = NSNotFoundRange; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLRangeOp, regex, options, capture, self, &range, NULL, error, &matchedRange); - return((matchedRange.location == (NSUInteger)NSNotFound) ? NULL : rkl_CFAutorelease(CFStringCreateWithSubstring(NULL, (CFStringRef)self, CFMakeRange(matchedRange.location, matchedRange.length)))); -} // Warning about potential leak can be safely ignored. - -#pragma mark -stringByReplacingOccurrencesOfRegex: - -- (NSString *)RKL_METHOD_PREPEND(stringByReplacingOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement -{ - NSRange searchRange = NSMaxiumRange; - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLReplaceOp, regex, RKLNoOptions, 0L, self, &searchRange, replacement, NULL, NULL)); -} - -- (NSString *)RKL_METHOD_PREPEND(stringByReplacingOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement range:(NSRange)searchRange -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLReplaceOp, regex, RKLNoOptions, 0L, self, &searchRange, replacement, NULL, NULL)); -} - -- (NSString *)RKL_METHOD_PREPEND(stringByReplacingOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement options:(RKLRegexOptions)options range:(NSRange)searchRange error:(NSError **)error -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLReplaceOp, regex, options, 0L, self, &searchRange, replacement, error, NULL)); -} - -#pragma mark -componentsMatchedByRegex: - -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex -{ - NSRange searchRange = NSMaxiumRange; - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLArrayOfStringsOp, regex, RKLNoOptions, 0L, self, &searchRange, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex capture:(NSInteger)capture -{ - NSRange searchRange = NSMaxiumRange; - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLArrayOfStringsOp, regex, RKLNoOptions, capture, self, &searchRange, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex range:(NSRange)range -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLArrayOfStringsOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(componentsMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range capture:(NSInteger)capture error:(NSError **)error -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLArrayOfStringsOp, regex, options, capture, self, &range, NULL, error, NULL)); -} - -#pragma mark -captureComponentsMatchedByRegex: - -- (NSArray *)RKL_METHOD_PREPEND(captureComponentsMatchedByRegex):(NSString *)regex -{ - NSRange searchRange = NSMaxiumRange; - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLCapturesArrayOp, regex, RKLNoOptions, 0L, self, &searchRange, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(captureComponentsMatchedByRegex):(NSString *)regex range:(NSRange)range -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLCapturesArrayOp, regex, RKLNoOptions, 0L, self, &range, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(captureComponentsMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range error:(NSError **)error -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)RKLCapturesArrayOp, regex, options, 0L, self, &range, NULL, error, NULL)); -} - -#pragma mark -arrayOfCaptureComponentsMatchedByRegex: - -- (NSArray *)RKL_METHOD_PREPEND(arrayOfCaptureComponentsMatchedByRegex):(NSString *)regex -{ - NSRange searchRange = NSMaxiumRange; - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)(RKLArrayOfCapturesOp | RKLSubcapturesArray), regex, RKLNoOptions, 0L, self, &searchRange, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(arrayOfCaptureComponentsMatchedByRegex):(NSString *)regex range:(NSRange)range -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)(RKLArrayOfCapturesOp | RKLSubcapturesArray), regex, RKLNoOptions, 0L, self, &range, NULL, NULL, NULL)); -} - -- (NSArray *)RKL_METHOD_PREPEND(arrayOfCaptureComponentsMatchedByRegex):(NSString *)regex options:(RKLRegexOptions)options range:(NSRange)range error:(NSError **)error -{ - return(rkl_performRegexOp(self, _cmd, (RKLRegexOp)(RKLArrayOfCapturesOp | RKLSubcapturesArray), regex, options, 0L, self, &range, NULL, error, NULL)); -} - -@end - - -@implementation NSMutableString (RegexKitLiteAdditions) - -#pragma mark -replaceOccurrencesOfRegex: - -- (NSUInteger)RKL_METHOD_PREPEND(replaceOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement -{ - NSRange searchRange = NSMaxiumRange; - NSUInteger replacedCount = 0UL; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)(RKLReplaceOp | RKLReplaceMutable), regex, RKLNoOptions, 0L, self, &searchRange, replacement, NULL, (void **)((void *)&replacedCount)); - return(replacedCount); -} - -- (NSUInteger)RKL_METHOD_PREPEND(replaceOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement range:(NSRange)searchRange -{ - NSUInteger replacedCount = 0UL; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)(RKLReplaceOp | RKLReplaceMutable), regex, RKLNoOptions, 0L, self, &searchRange, replacement, NULL, (void **)((void *)&replacedCount)); - return(replacedCount); -} - -- (NSUInteger)RKL_METHOD_PREPEND(replaceOccurrencesOfRegex):(NSString *)regex withString:(NSString *)replacement options:(RKLRegexOptions)options range:(NSRange)searchRange error:(NSError **)error -{ - NSUInteger replacedCount = 0UL; - rkl_performRegexOp(self, _cmd, (RKLRegexOp)(RKLReplaceOp | RKLReplaceMutable), regex, options, 0L, self, &searchRange, replacement, error, (void **)((void *)&replacedCount)); - return(replacedCount); -} - -@end diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj index fe533d1..f153669 100644 --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -55,7 +55,6 @@ 4BEE524A1339193600DA9881 /* NSAppleEventDescriptor+ToObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC006112FFFF800846DF6 /* NSAppleEventDescriptor+ToObject.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 4BEE524B1339193600DA9881 /* MCLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC008112FFFF800846DF6 /* MCLog.m */; }; 4BEE524E1339193600DA9881 /* CPFileReferenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC00F112FFFF800846DF6 /* CPFileReferenceCell.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE524F1339193600DA9881 /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC014112FFFF800846DF6 /* RegexKitLite.m */; }; 4BEE52501339193600DA9881 /* CPStatusLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B88D25511303885007250E5 /* CPStatusLabel.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 4BEE52511339193600DA9881 /* NSArray+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDCDAF5113142B40015BF7D /* NSArray+MiscExtensions.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 4BEE52521339193600DA9881 /* NSView+AllSubviews.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA45D2C11343FA9006351CC /* NSView+AllSubviews.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; @@ -191,8 +190,6 @@ 4B7FC009112FFFF800846DF6 /* MCLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = MCLog.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 4B7FC00F112FFFF800846DF6 /* CPFileReferenceCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CPFileReferenceCell.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 4B7FC010112FFFF800846DF6 /* CPFileReferenceCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPFileReferenceCell.h; sourceTree = ""; }; - 4B7FC014112FFFF800846DF6 /* RegexKitLite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = RegexKitLite.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 4B7FC015112FFFF800846DF6 /* RegexKitLite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegexKitLite.h; sourceTree = ""; }; 4B88D25411303885007250E5 /* CPStatusLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPStatusLabel.h; sourceTree = ""; }; 4B88D25511303885007250E5 /* CPStatusLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPStatusLabel.m; sourceTree = ""; }; 4B918211113C25AD00BF23B5 /* AMIndeterminateProgressIndicatorCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AMIndeterminateProgressIndicatorCell.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; @@ -482,15 +479,6 @@ name = Entities; sourceTree = ""; }; - 4B7FC0511130015A00846DF6 /* RegexKit Lite */ = { - isa = PBXGroup; - children = ( - 4B7FC015112FFFF800846DF6 /* RegexKitLite.h */, - 4B7FC014112FFFF800846DF6 /* RegexKitLite.m */, - ); - name = "RegexKit Lite"; - sourceTree = ""; - }; 4B918210113C258100BF23B5 /* AMIndeterminateProgressIndicatorCell */ = { isa = PBXGroup; children = ( @@ -526,7 +514,6 @@ children = ( 4B918210113C258100BF23B5 /* AMIndeterminateProgressIndicatorCell */, 4B24B6401139138E0000EF99 /* QSB */, - 4B7FC0511130015A00846DF6 /* RegexKit Lite */, ); name = "3rd party"; path = ../Classes; From 7b1e223d65c1c79d679d11c0da483d9cfa1847b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ka=C5=82uz=CC=87ny?= Date: Tue, 31 Mar 2015 16:05:44 +0200 Subject: [PATCH 12/33] Upgraded the project to use ARC --- .../AMIndeterminateProgressIndicatorCell.m | 10 +-- Classes/CPXcodeWrapper.m | 9 +- CodePilot.xcodeproj/project.pbxproj | 15 ++-- MCCommons/MCLog.m | 87 +++++++++---------- MCCommons/MCStringScoring.c | 8 +- 5 files changed, 58 insertions(+), 71 deletions(-) diff --git a/Classes/AMIndeterminateProgressIndicatorCell.m b/Classes/AMIndeterminateProgressIndicatorCell.m index 11567bc..90f4087 100644 --- a/Classes/AMIndeterminateProgressIndicatorCell.m +++ b/Classes/AMIndeterminateProgressIndicatorCell.m @@ -37,23 +37,17 @@ - (id)init return self; } -- (void)dealloc -{ - [NSColor release]; - [super dealloc]; -} - (NSColor *)color { - return [[color retain] autorelease]; + return color; } - (void)setColor:(NSColor *)value { CGFloat alphaComponent; if (color != value) { - [color release]; - color = [value retain]; + color = value; [[color colorUsingColorSpaceName:@"NSCalibratedRGBColorSpace"] getRed:&redComponent green:&greenComponent blue:&blueComponent alpha:&alphaComponent]; // NSAssert((alphaComponent > 0.999), @"color must be opaque"); // gives a warning in xcode4 } diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index 28ee54a..0ecff04 100644 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -247,11 +247,9 @@ - (NSArray *)filesAndSymbolsFromProjectForQuery:(NSString *)query { query = [self normalizedQueryForQuery:query]; - NSArray *resultArray = [NSArray array]; - NSArray *files = [NSArray array]; NSArray *symbols = [NSArray array]; - files = [self cpFileReferencesMatchingQuery:query]; + NSArray *files = [self cpFileReferencesMatchingQuery:query]; if ([files count] < MAX_OBJECT_COUNT_FOR_SORT_AND_FILTER) { symbols = [self topLevelCPSymbolsMatchingQuery:query]; @@ -259,7 +257,7 @@ - (NSArray *)filesAndSymbolsFromProjectForQuery:(NSString *)query USER_LOG(@"not adding symbols - we already have %d entries.", MAX_OBJECT_COUNT_FOR_SORT_AND_FILTER); } - resultArray = [symbols arrayByAddingObjectsFromArray:files]; + NSArray* resultArray = [symbols arrayByAddingObjectsFromArray:files]; // TODO/FIXME: We could add API search here resultArray = [self arrayByFilteringAndSortingArray:resultArray @@ -622,11 +620,10 @@ - (NSArray *)recursiveChildrenOfIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol - (NSArray *)allIDEIndexSymbolsFromCPFileReference:(CPFileReference *)fileReference { NSMutableArray *objects = [NSMutableArray array]; - NSArray *topLevelSymbols = [NSArray array]; PBXFileReference *pbxFileReference = [self pbxFileReferenceForCPFileReference:fileReference]; - topLevelSymbols = [[self currentIndex] topLevelSymbolsInFile:[pbxFileReference absolutePath]]; + NSArray * topLevelSymbols = [[self currentIndex] topLevelSymbolsInFile:[pbxFileReference absolutePath]]; for (IDEIndexSymbol *ideSymbol in topLevelSymbols) { [objects addObject:ideSymbol]; diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj index f153669..eeb8ef1 100644 --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -547,7 +547,7 @@ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0630; ORGANIZATIONNAME = Macoscope; }; buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "CodePilot" */; @@ -629,7 +629,6 @@ 4BEE524A1339193600DA9881 /* NSAppleEventDescriptor+ToObject.m in Sources */, 4BEE524B1339193600DA9881 /* MCLog.m in Sources */, 4BEE524E1339193600DA9881 /* CPFileReferenceCell.m in Sources */, - 4BEE524F1339193600DA9881 /* RegexKitLite.m in Sources */, 4BEE52501339193600DA9881 /* CPStatusLabel.m in Sources */, 4BEE52511339193600DA9881 /* NSArray+MiscExtensions.m in Sources */, 4BEE52521339193600DA9881 /* NSView+AllSubviews.m in Sources */, @@ -690,6 +689,7 @@ 1DEB913F08733D840010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_GC = supported; GCC_OPTIMIZATION_LEVEL = 0; @@ -704,6 +704,7 @@ 1DEB914008733D840010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_GC = supported; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -717,6 +718,7 @@ 4BE2963F12E60EBB0026BDAC /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_GC = unsupported; @@ -728,6 +730,7 @@ 4BE2964012E60EBB0026BDAC /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_OBJC_GC = unsupported; @@ -739,7 +742,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ENABLE_OBJC_ARC = NO; + CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEPLOYMENT_LOCATION = YES; @@ -747,7 +750,7 @@ DSTROOT = "$(HOME)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_GC = unsupproted; + GCC_ENABLE_OBJC_GC = unsupported; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -771,14 +774,14 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ENABLE_OBJC_ARC = NO; + CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_LOCATION = YES; DEPLOYMENT_POSTPROCESSING = YES; DSTROOT = "$(HOME)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - GCC_ENABLE_OBJC_GC = unsupproted; + GCC_ENABLE_OBJC_GC = unsupported; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Other Sources/CodePilot_Prefix.pch"; diff --git a/MCCommons/MCLog.m b/MCCommons/MCLog.m index 9879424..1df27a9 100644 --- a/MCCommons/MCLog.m +++ b/MCCommons/MCLog.m @@ -12,58 +12,53 @@ @implementation MCLog + (void)prefix:(NSString *)prefixString format:(NSString *)format, ... { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - va_list ap; - NSString *message; - va_start(ap,format); - - message = [[NSString alloc] initWithFormat:format arguments:ap]; - va_end(ap); - - NSLog(@"%@ %@", prefixString, message); - - [message release]; - [pool release]; + @autoreleasepool { + va_list ap; + NSString *message; + va_start(ap,format); + + message = [[NSString alloc] initWithFormat:format arguments:ap]; + va_end(ap); + + NSLog(@"%@ %@", prefixString, message); + + } } + (void)file:(char *)sourceFile function:(char *)functionName lineNumber:(int)lineNumber format:(NSString *)format, ... { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - va_list ap; - NSString *print, *file, *function; - va_start(ap,format); - - file = [[NSString alloc] initWithBytes:sourceFile length:strlen(sourceFile) encoding:NSUTF8StringEncoding]; - - - function = [NSString stringWithCString:functionName encoding:NSASCIIStringEncoding]; - print = [[NSString alloc] initWithFormat:format arguments:ap]; - va_end(ap); - + @autoreleasepool { + va_list ap; + NSString *print, *file, *function; + va_start(ap,format); + + file = [[NSString alloc] initWithBytes:sourceFile length:strlen(sourceFile) encoding:NSUTF8StringEncoding]; + + + function = [NSString stringWithCString:functionName encoding:NSASCIIStringEncoding]; + print = [[NSString alloc] initWithFormat:format arguments:ap]; + va_end(ap); + NSString *fileLocation = [file lastPathComponent]; - - NSLog(@"%@:%d %@; %@", fileLocation, lineNumber, function, print); - - [print release]; - [file release]; - [pool release]; + + NSLog(@"%@:%d %@; %@", fileLocation, lineNumber, function, print); + + } } + (NSString *)messageWithFile:(char *)sourceFile function:(char *)functionName lineNumber:(int)lineNumber format:(NSString *)format, ... { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - va_list ap; - NSString *print, *file, *function; - va_start(ap,format); - file = [[NSString alloc] initWithBytes:sourceFile length:strlen(sourceFile) encoding:NSUTF8StringEncoding]; - - function = [NSString stringWithCString:functionName encoding:NSASCIIStringEncoding]; - print = [[NSString alloc] initWithFormat:format arguments:ap]; - va_end(ap); - NSString * buffer = [NSString stringWithFormat:@"%@:%d %@; %@", [file lastPathComponent], lineNumber, function, print]; - [print release]; - [file release]; - [pool release]; - return buffer; + @autoreleasepool { + va_list ap; + NSString *print, *file, *function; + va_start(ap,format); + file = [[NSString alloc] initWithBytes:sourceFile length:strlen(sourceFile) encoding:NSUTF8StringEncoding]; + + function = [NSString stringWithCString:functionName encoding:NSASCIIStringEncoding]; + print = [[NSString alloc] initWithFormat:format arguments:ap]; + va_end(ap); + NSString * buffer = [NSString stringWithFormat:@"%@:%d %@; %@", [file lastPathComponent], lineNumber, function, print]; + return buffer; + } } NSString * MCToStringFromTypeAndValue(const char * typeCode, void * value) @@ -87,11 +82,9 @@ + (NSString *)messageWithFile:(char *)sourceFile function:(char *)functionName l return NSStringFromRange(*(NSRange *)value); } else if (strcmp(typeCode, @encode(id)) == 0) { - return MCNSStringWithFormat(@"%@", *(id *)value); - + return MCNSStringWithFormat(@"%@", (__bridge id)(value)); } else if (strcmp(typeCode, @encode(BOOL)) == 0) { return (*(BOOL *)value) ? @"YES" : @"NO"; - } else if (strcmp(typeCode, @encode(int)) == 0) { return MCNSStringWithFormat(@"%d", *(int *)value); diff --git a/MCCommons/MCStringScoring.c b/MCCommons/MCStringScoring.c index b877370..2251f32 100644 --- a/MCCommons/MCStringScoring.c +++ b/MCCommons/MCStringScoring.c @@ -187,8 +187,8 @@ float MCStringScoring_scoreStringForQuery(const char *scoredString, const char * queryCharMatchIndexes = malloc(sizeof(int *)*queryLength); for (index = 0; index < queryLength; index++) { - queryCharMatchIndexes[index] = malloc(sizeof(int *)*(valueLength+1)); - memset(queryCharMatchIndexes[index], -1, sizeof(int *)*(valueLength+1)); + queryCharMatchIndexes[index] = (int *)malloc(sizeof(int)*(valueLength+1)); + memset(queryCharMatchIndexes[index], -1, sizeof(int)*(valueLength+1)); } for (valueIndex = 0; valueIndex < valueLength; valueIndex++) { @@ -453,8 +453,8 @@ float MCStringScoring_scoreStringForQueryNEW(const char *scoredString, const cha queryCharMatchIndexes = malloc(sizeof(int *)*queryLength); for (index = 0; index < queryLength; index++) { - queryCharMatchIndexes[index] = malloc(sizeof(int *)*(valueLength+1)); - memset(queryCharMatchIndexes[index], -1, sizeof(int *)*(valueLength+1)); + queryCharMatchIndexes[index] = (int *)malloc(sizeof(int)*(valueLength+1)); + memset(queryCharMatchIndexes[index], -1, sizeof(int)*(valueLength+1)); } for (valueIndex = 0; valueIndex < valueLength; valueIndex++) { From 4a86d6fa65beb2683ef2306915f8e173c3e72df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ka=C5=82uz=CC=87ny?= Date: Tue, 31 Mar 2015 16:06:06 +0200 Subject: [PATCH 13/33] Added XCode 6.2 support --- Resources/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index 740a79a..9272da5 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -38,6 +38,8 @@ DVTPlugInCompatibilityUUIDs + 992275C1-432A-4CF7-B659-D84ED6D42D3F + A16FF353-8441-459E-A50C-B071F53F51B7 640F884E-CE55-4B40-87C0-8869546CAB7A 63FC1C47-140D-42B0-BB4D-A10B2D225574 37B30044-3B14-46BA-ABAA-F01000C27B63 From 7f133f8b0ef090c6a07f8e6e2d90a96bf36028be Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Thu, 2 Apr 2015 10:41:32 +0200 Subject: [PATCH 14/33] README update - note about installation via Alcatraz - info about Xcode 6 support --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d74259e..ae07ea0 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,26 @@ What is Code Pilot? Read the [full story](http://macoscope.com/blog/the-story-of-code-pilot/) of Code Pilot. -Code Pilot is a plugin for Xcode 5 that allows you to quickly find files, methods and symbols within your project without the need for your mouse. +Code Pilot is a plugin for Xcode 5 & 6 that allows you to quickly find files, methods and symbols within your project without the need for your mouse. It uses fuzzy query matching to compute a list of results sorted by their relevancy. With just a few keystrokes you can jump to the method you're looking for. ![CodePilot Window](https://github.com/macoscope/CodePilot/raw/master/Screenshots/CodePilot_01.png "CodePilot Window") More about original Code Pilot release [here](http://codepilot.cc/). -How to use Code Pilot? -====================== +How to install Code Pilot? +========================== + +##Alcatraz + +You can install Code Pilot using [Alcatraz](http://alcatraz.io) package manager + +##Manual To use Code Pilot you have to build the project and copy the resulting `CodePilot3.xcplugin` file to you plugin directory - `~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins`. Alternatively you can build the installer package and use it to install the plugin (it essentially just moves the xcplugin to the Plug-ins directory). -To load the plugin you have to restart Xcode 5. +To load the plugin you have to restart Xcode. NOTE: In order to build a package you may need to install PackageMaker.app included in "Auxiliary tools for Xcode" [PackageMaker](https://developer.apple.com/downloads/index.action?name=PackageMaker) From 0c07e628974b5b64a6aeadee01205db5a4d59877 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Thu, 2 Apr 2015 10:55:37 +0200 Subject: [PATCH 15/33] Removed not needed Build Package target --- CodePilot.xcodeproj/project.pbxproj | 82 ------------------- .../xcschemes/Build Package.xcscheme | 59 ------------- README.md | 6 +- 3 files changed, 1 insertion(+), 146 deletions(-) delete mode 100644 CodePilot.xcodeproj/xcshareddata/xcschemes/Build Package.xcscheme diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj index eeb8ef1..c5d4e71 100644 --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -6,21 +6,6 @@ objectVersion = 46; objects = { -/* Begin PBXAggregateTarget section */ - 4BE2963E12E60EBB0026BDAC /* Build Package */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 4BE2964412E60EC60026BDAC /* Build configuration list for PBXAggregateTarget "Build Package" */; - buildPhases = ( - 4BE2964812E60F120026BDAC /* ShellScript */, - ); - dependencies = ( - 4B2DF80B133927C200C0D8A9 /* PBXTargetDependency */, - ); - name = "Build Package"; - productName = "Build Package"; - }; -/* End PBXAggregateTarget section */ - /* Begin PBXBuildFile section */ 4B197DC113AF37A100DF2598 /* memlak.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B197DC013AF37A100DF2598 /* memlak.png */; }; 4B30A186133979A7008A4372 /* CPPluginInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B30A185133979A7008A4372 /* CPPluginInstaller.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; @@ -88,16 +73,6 @@ F9F596B417BBF78E0037BE7A /* CPResult.m in Sources */ = {isa = PBXBuildFile; fileRef = F9F596B317BBF78E0037BE7A /* CPResult.m */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 4B2DF80A133927C200C0D8A9 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 089C1669FE841209C02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4BEE52391339193600DA9881; - remoteInfo = "CodePilot for Xcode 4"; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXCopyFilesBuildPhase section */ 4B7A0F8B1356EF8C004CCC96 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -565,7 +540,6 @@ projectRoot = ""; targets = ( 4BEE52391339193600DA9881 /* CodePilot */, - 4BE2963E12E60EBB0026BDAC /* Build Package */, ); }; /* End PBXProject section */ @@ -594,22 +568,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 4BE2964812E60F120026BDAC /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "bash \"$PROJECT_DIR/Installer/build_installer_pkg.command\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 4BEE523E1339193600DA9881 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -666,14 +624,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 4B2DF80B133927C200C0D8A9 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4BEE52391339193600DA9881 /* CodePilot */; - targetProxy = 4B2DF80A133927C200C0D8A9 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin PBXVariantGroup section */ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; @@ -715,29 +665,6 @@ }; name = Release; }; - 4BE2963F12E60EBB0026BDAC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_GC = unsupported; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = "Build Package"; - }; - name = Debug; - }; - 4BE2964012E60EBB0026BDAC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_GC = unsupported; - PRODUCT_NAME = "Build Package"; - }; - name = Release; - }; 4BEE52791339193600DA9881 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -812,15 +739,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4BE2964412E60EC60026BDAC /* Build configuration list for PBXAggregateTarget "Build Package" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4BE2963F12E60EBB0026BDAC /* Debug */, - 4BE2964012E60EBB0026BDAC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 4BEE52781339193600DA9881 /* Build configuration list for PBXNativeTarget "CodePilot" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/CodePilot.xcodeproj/xcshareddata/xcschemes/Build Package.xcscheme b/CodePilot.xcodeproj/xcshareddata/xcschemes/Build Package.xcscheme deleted file mode 100644 index 93bdb6b..0000000 --- a/CodePilot.xcodeproj/xcshareddata/xcschemes/Build Package.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/README.md b/README.md index ae07ea0..e203764 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,9 @@ You can install Code Pilot using [Alcatraz](http://alcatraz.io) package manager ##Manual -To use Code Pilot you have to build the project and copy the resulting `CodePilot3.xcplugin` file to you plugin directory - `~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins`. - -Alternatively you can build the installer package and use it to install the plugin (it essentially just moves the xcplugin to the Plug-ins directory). +To use Code Pilot you have to build the project. It will automatically place `CodePilot3.xcplugin` file to your plugin directory - `~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins`. To load the plugin you have to restart Xcode. -NOTE: In order to build a package you may need to install PackageMaker.app included in "Auxiliary tools for Xcode" [PackageMaker](https://developer.apple.com/downloads/index.action?name=PackageMaker) - When the plugin is loaded you can open the CodePilot window with CMD + SHIFT + X, and then type your query. License From 8b71e9432dd914d5839f6663ce4dd681768f9b34 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Thu, 2 Apr 2015 11:09:52 +0200 Subject: [PATCH 16/33] Fixed a crash after typing space in the query --- Classes/CPXcodeWrapper.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index 0ecff04..7e3010f 100644 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -148,6 +148,9 @@ - (BOOL)hasOpenWorkspace - (NSString *)normalizedQueryForQuery:(NSString *)query { + if (!query) { + return nil; + } NSMutableString *mQuery = [query mutableCopy]; NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"[\\*\\ \\r\\n\\t]" options:NSRegularExpressionCaseInsensitive error:nil]; From b1300f79b96d15d6663cd13f8ce550b0259ed4b7 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Thu, 2 Apr 2015 11:14:22 +0200 Subject: [PATCH 17/33] Updated gitignore and added shareddata tracking --- .gitignore | 210 +++++++++++++++++- .../xcshareddata/CodePilot.xccheckout | 41 ++++ .../xcshareddata/xcschemes/CodePilot.xcscheme | 77 +++++++ 3 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 CodePilot.xcodeproj/project.xcworkspace/xcshareddata/CodePilot.xccheckout create mode 100644 CodePilot.xcodeproj/xcshareddata/xcschemes/CodePilot.xcscheme diff --git a/.gitignore b/.gitignore index 84c048a..49e63ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,209 @@ -/build/ +######################### +# .gitignore file for Xcode4 and Xcode5 Source projects +# +# Apple bugs, waiting for Apple to fix/respond: +# +# 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation? +# +# Version 2.3 +# For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects +# +# 2014 updates: +# - appended non-standard items DISABLED by default (uncomment if you use those tools) +# - removed the edit that an SO.com moderator made without bothering to ask me +# - researched CocoaPods .lock more carefully, thanks to Gokhan Celiker +# 2013 updates: +# - fixed the broken "save personal Schemes" +# - added line-by-line explanations for EVERYTHING (some were missing) +# +# NB: if you are storing "built" products, this WILL NOT WORK, +# and you should use a different .gitignore (or none at all) +# This file is for SOURCE projects, where there are many extra +# files that we want to exclude +# +######################### + +##### +# OS X temporary files that should never be committed +# +# c.f. http://www.westwind.com/reference/os-x/invisibles.html + +.DS_Store + +# c.f. http://www.westwind.com/reference/os-x/invisibles.html + +.Trashes + +# c.f. http://www.westwind.com/reference/os-x/invisibles.html + +*.swp + +# +# *.lock - this is used and abused by many editors for many different things. +# For the main ones I use (e.g. Eclipse), it should be excluded +# from source-control, but YMMV. +# (lock files are usually local-only file-synchronization on the local FS that should NOT go in git) +# c.f. the "OPTIONAL" section at bottom though, for tool-specific variations! + +*.lock + + +# +# profile - REMOVED temporarily (on double-checking, I can't find it in OS X docs?) +#profile + + +#### +# Xcode temporary files that should never be committed +# +# NB: NIB/XIB files still exist even on Storyboard projects, so we want this... + +*~.nib + + +#### +# Xcode build files - +# +# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" + +DerivedData/ + +# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" + +build/ + + +##### +# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) +# +# This is complicated: +# +# SOMETIMES you need to put this file in version control. +# Apple designed it poorly - if you use "custom executables", they are +# saved in this file. +# 99% of projects do NOT use those, so they do NOT want to version control this file. +# ..but if you're in the 1%, comment out the line "*.pbxuser" + +# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html + +*.pbxuser + +# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html + +*.mode1v3 + +# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html + +*.mode2v3 + +# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file + +*.perspectivev3 + +# NB: also, whitelist the default ones, some projects need to use these +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + + +#### +# Xcode 4 - semi-personal settings +# +# +# OPTION 1: --------------------------------- +# throw away ALL personal settings (including custom schemes! +# - unless they are "shared") +# +# NB: this is exclusive with OPTION 2 below +xcuserdata + +# OPTION 2: --------------------------------- +# get rid of ALL personal settings, but KEEP SOME OF THEM +# - NB: you must manually uncomment the bits you want to keep +# +# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, +# or manually install git over the top of the OS X version +# NB: this is exclusive with OPTION 1 above +# +#xcuserdata/**/* + +# (requires option 2 above): Personal Schemes +# +#!xcuserdata/**/xcschemes/* + +#### +# XCode 4 workspaces - more detailed +# +# Workspaces are important! They are a core feature of Xcode - don't exclude them :) +# +# Workspace layout is quite spammy. For reference: +# +# /(root)/ +# /(project-name).xcodeproj/ +# project.pbxproj +# /project.xcworkspace/ +# contents.xcworkspacedata +# /xcuserdata/ +# /(your name)/xcuserdatad/ +# UserInterfaceState.xcuserstate +# /xcsshareddata/ +# /xcschemes/ +# (shared scheme name).xcscheme +# /xcuserdata/ +# /(your name)/xcuserdatad/ +# (private scheme).xcscheme +# xcschememanagement.plist +# +# + +#### +# Xcode 4 - Deprecated classes +# +# Allegedly, if you manually "deprecate" your classes, they get moved here. +# +# We're using source-control, so this is a "feature" that we do not want! + +*.moved-aside + +#### +# OPTIONAL: Some well-known tools that people use side-by-side with Xcode / iOS development +# +# NB: I'd rather not include these here, but gitignore's design is weak and doesn't allow +# modular gitignore: you have to put EVERYTHING in one file. +# +# COCOAPODS: +# +# c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock +# c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +#!Podfile.lock +# +# RUBY: +# +# c.f. http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ +# +#!Gemfile.lock +# +# IDEA: +# +#.idea +# +# TEXTMATE: +# +# -- UNVERIFIED: c.f. http://stackoverflow.com/a/50283/153422 +# +#tm_build_errors + +#### +# UNKNOWN: recommended by others, but I can't discover what these files are +# +# Community suggestions (unverified, no evidence available - DISABLED by default) +# +# 1. Xcode 5 - VCS file +# +# "The data in this file not represent state of your project. +# If you'll leave this file in git - you will have merge conflicts during +# pull your cahnges to other's repo" +# +#*.xccheckout diff --git a/CodePilot.xcodeproj/project.xcworkspace/xcshareddata/CodePilot.xccheckout b/CodePilot.xcodeproj/project.xcworkspace/xcshareddata/CodePilot.xccheckout new file mode 100644 index 0000000..89435fa --- /dev/null +++ b/CodePilot.xcodeproj/project.xcworkspace/xcshareddata/CodePilot.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 0732B84C-C0E7-4A00-98C8-1AEFB507C593 + IDESourceControlProjectName + CodePilot + IDESourceControlProjectOriginsDictionary + + F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 + https://github.com/macoscope/CodePilot.git + + IDESourceControlProjectPath + CodePilot.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 + ../.. + + IDESourceControlProjectURL + https://github.com/macoscope/CodePilot.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 + IDESourceControlWCCName + CodePilot + + + + diff --git a/CodePilot.xcodeproj/xcshareddata/xcschemes/CodePilot.xcscheme b/CodePilot.xcodeproj/xcshareddata/xcschemes/CodePilot.xcscheme new file mode 100644 index 0000000..bdf46eb --- /dev/null +++ b/CodePilot.xcodeproj/xcshareddata/xcschemes/CodePilot.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From c2d9a8ce48d3a3ee2a81350f82a6fd77e8b60e49 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Thu, 2 Apr 2015 12:59:53 +0200 Subject: [PATCH 18/33] Fixed results without names not being removed --- Classes/CPXcodeWrapper.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index 0ecff04..dac6603 100644 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -630,7 +630,7 @@ - (NSArray *)allIDEIndexSymbolsFromCPFileReference:(CPFileReference *)fileRefere [objects addObjectsFromArray:[self recursiveChildrenOfIDEIndexSymbol:ideSymbol]]; } - [objects arrayWithoutElementsHavingNilOrEmptyValueForKey:@"name"]; + objects = [[objects arrayWithoutElementsHavingNilOrEmptyValueForKey:@"name"] mutableCopy]; NSArray *objectsWithRealOccurrences = [NSArray array]; From b921ce280f347659a1dcdf7bc5bc6ef8f6e9f15a Mon Sep 17 00:00:00 2001 From: Mark Struzinski Date: Tue, 14 Apr 2015 23:16:10 -0400 Subject: [PATCH 19/33] Adding Xcode 6.3 support --- Resources/Info.plist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index 9272da5..851741d 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -38,6 +38,9 @@ DVTPlugInCompatibilityUUIDs + FEC992CC-CA4A-4CFD-8881-77300FCB848A + AD68E85B-441B-4301-B564-A45E4919A6AD + 9F75337B-21B4-4ADC-B558-F9CADF7073A7 992275C1-432A-4CF7-B659-D84ED6D42D3F A16FF353-8441-459E-A50C-B071F53F51B7 640F884E-CE55-4B40-87C0-8869546CAB7A From 98b2d9714b5e04d92037c72226dfcebd8a6c1aa2 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Mon, 4 May 2015 09:05:20 +0200 Subject: [PATCH 20/33] Code style --- Classes/CPPreferencesView.h | 4 ++-- Classes/CPSearchController.m | 3 ++- Classes/CPXcodeWrapper.m | 6 ++++-- Classes/NSWorkspace+OpenFileOnLine.m | 20 +++++++++++++------- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Classes/CPPreferencesView.h b/Classes/CPPreferencesView.h index 2098067..eb4dd9e 100755 --- a/Classes/CPPreferencesView.h +++ b/Classes/CPPreferencesView.h @@ -10,8 +10,8 @@ @interface CPPreferencesView : NSView -@property (nonatomic, strong) NSButton *autocopyingSelectionCheckbox, - *externalEditorCheckbox; +@property (nonatomic, strong) NSButton *autocopyingSelectionCheckbox; +@property (nonatomic, strong) NSButton *externalEditorCheckbox; - (id)initWithPreferredFrame; diff --git a/Classes/CPSearchController.m b/Classes/CPSearchController.m index 6d67d9f..cfc5e60 100755 --- a/Classes/CPSearchController.m +++ b/Classes/CPSearchController.m @@ -472,8 +472,9 @@ - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBy [(CPCodePilotWindowDelegate *)[[self.searchField window] delegate] hideWindow]; BOOL external = [[[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_EXTERNAL_EDITOR_KEY] boolValue]; - if([NSEvent modifierFlags] & NSCommandKeyMask) + if ([NSEvent modifierFlags] & NSCommandKeyMask) { external = !external; + } [self.xcodeWrapper openFileOrSymbol:self.selectedElement inExternalEditor:external]; diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index deaa2e1..0144739 100755 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -410,8 +410,9 @@ - (void)openCPFileReference:(CPFileReference *)cpFileReference - (void)openCPFileReference:(CPFileReference *)cpFileReference inExternalEditor:(BOOL)aUseExternal { - if(aUseExternal && ![cpFileReference.fileURL cp_opensInXcode]) + if (aUseExternal && ![cpFileReference.fileURL cp_opensInXcode]) { [[NSWorkspace sharedWorkspace] openURL:cpFileReference.fileURL]; + } else { DVTDocumentLocation *documentLocation = [[DVTDocumentLocation alloc] initWithDocumentURL:[cpFileReference fileURL] timestamp:nil]; @@ -438,8 +439,9 @@ - (void)openCPSymbol:(CPSymbol *)symbol inExternalEditor:(BOOL)aUseExternal @try { IDEIndexSymbolOccurrence *occurrence = [symbol relatedSymbolOccurrence]; NSURL *url = occurrence.file.fileURL; - if (aUseExternal && ![url cp_opensInXcode]) + if (aUseExternal && ![url cp_opensInXcode]) { [[NSWorkspace sharedWorkspace] cp_openURL:url onLine:occurrence.lineNumber]; + } else { IDEEditorOpenSpecifier *openSpecifier = [IDEEditorOpenSpecifier structureEditorOpenSpecifierForDocumentLocation:[symbol relatedDocumentLocation] inWorkspace:[self currentWorkspace] diff --git a/Classes/NSWorkspace+OpenFileOnLine.m b/Classes/NSWorkspace+OpenFileOnLine.m index d114852..a11c0e3 100644 --- a/Classes/NSWorkspace+OpenFileOnLine.m +++ b/Classes/NSWorkspace+OpenFileOnLine.m @@ -21,16 +21,21 @@ @implementation NSWorkspace (OpenFileOnLine) + (NSString *)cp_schemeForEditor:(NSString *)editor { if ([editor isEqualToString:kSublimeText2Identifier] || - [editor isEqualToString:kSublimeText3Identifier]) + [editor isEqualToString:kSublimeText3Identifier]) { return @"subl"; - if ([editor isEqualToString:kMacVimIdentifier]) + } + if ([editor isEqualToString:kMacVimIdentifier]) { return @"mvim"; - if ([editor isEqualToString:kTextmateIdentifier]) + } + if ([editor isEqualToString:kTextmateIdentifier]) { return @"txmt"; - if ([editor isEqualToString:kBBEditIdentifier]) + } + if ([editor isEqualToString:kBBEditIdentifier]) { return @"txmt"; - else + } + else { return nil; + } } - (void)cp_openURL:(NSURL *)url onLine:(NSUInteger)line @@ -38,12 +43,13 @@ - (void)cp_openURL:(NSURL *)url onLine:(NSUInteger)line NSURL *editorURL = [self URLForApplicationToOpenURL:url]; NSString *editorIdentifier = [[NSBundle bundleWithURL:editorURL] bundleIdentifier]; NSString *scheme = [[self class] cp_schemeForEditor:editorIdentifier]; - - if (scheme) + + if (scheme) { url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://open?url=%@&line=%lu", scheme, [[url absoluteString] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], (unsigned long)line]]; + } [self openURL:url]; } From b5803e20fb140d05b979dcc60ad33c04d5171723 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Wed, 13 May 2015 10:42:29 +0200 Subject: [PATCH 21/33] Fixed a crash on regex invalid range --- Classes/CPXcodeWrapper.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index 62b6986..db942fa 100755 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -156,7 +156,7 @@ - (NSString *)normalizedQueryForQuery:(NSString *)query NSMutableString *mQuery = [query mutableCopy]; NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"[\\*\\ \\r\\n\\t]" options:NSRegularExpressionCaseInsensitive error:nil]; - [regex replaceMatchesInString:mQuery options:NSMatchingAnchored range:NSRangeFromString(mQuery) withTemplate:@""]; + [regex replaceMatchesInString:mQuery options:NSMatchingAnchored range:NSMakeRange(0, mQuery.length) withTemplate:@""]; return mQuery; } From dc77e09610fc2f59303c663abc6bf551b43ea5ad Mon Sep 17 00:00:00 2001 From: bartekchlebek Date: Wed, 20 May 2015 09:58:16 +0200 Subject: [PATCH 22/33] Added Xcode 6.3.2 and Xcode 6.4b3 compatibility --- Resources/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index 851741d..e18692b 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -48,6 +48,8 @@ 37B30044-3B14-46BA-ABAA-F01000C27B63 A2E4D43F-41F4-4FB9-BB94-7177011C9AED C4A681B0-4A26-480E-93EC-1218098B9AA0 + 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 + E969541F-E6F9-4D25-8158-72DC3545A6C6 NSPrincipalClass CPCodePilotPlugin From bd5820d1773ec8cf23a444050be957819b3b03b8 Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Wed, 20 May 2015 13:54:05 +0200 Subject: [PATCH 23/33] Fix for linking error with IDESourceCodeDocument private class Be careful with [IDESourceCodeDocument class], use NSClassFromString(@"IDESourceCodeDocument") instead. The reason is IDESourceCodeDocument is a private class residing in some dylib loaded after launching Xcode. However, since Xcode 6.3.2 plugins are loaded before loading the dylib with IDESourceCodeDocument, and so linker freaks out. NSClassFromString(@"IDESourceCodeDocument"), though not perfect, is safer because will return nil until appropriate dylib is loaded. --- Classes/CPSymbolCache.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Classes/CPSymbolCache.m b/Classes/CPSymbolCache.m index 3d37e63..ff88a02 100644 --- a/Classes/CPSymbolCache.m +++ b/Classes/CPSymbolCache.m @@ -40,7 +40,14 @@ - (id)init - (void)onFileChangeNotification:(NSNotification *)notification { - if (![[notification object] isKindOfClass:[IDESourceCodeDocument class]]) { + /* + Be careful with [IDESourceCodeDocument class], use NSClassFromString(@"IDESourceCodeDocument") instead. + The reason is IDESourceCodeDocument is a private class residing in some dylib loaded after launching Xcode. However, + since Xcode 6.3.2 plugins are loaded before loading the dylib with IDESourceCodeDocument, and so linker freaks out. + NSClassFromString(@"IDESourceCodeDocument"), though not perfect, is safer because will return nil until appropriate + dylib is loaded. + */ + if (![[notification object] isKindOfClass:NSClassFromString(@"IDESourceCodeDocument")]) { return; } From 79baa23d2a31e8bc901d6d0db0122c2faa5136bb Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Fri, 26 Jun 2015 10:33:41 +0200 Subject: [PATCH 24/33] Fixed a crash appearing in xcodebuild command kudos to Alexander --- Classes/CPCodePilotPlugin.m | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Classes/CPCodePilotPlugin.m b/Classes/CPCodePilotPlugin.m index a66d8b6..46ebcbb 100644 --- a/Classes/CPCodePilotPlugin.m +++ b/Classes/CPCodePilotPlugin.m @@ -20,10 +20,14 @@ + (void)pluginDidLoad:(id)arg1 + (void)load { - LOG(@"CODE PILOT: CURRENT_XCODE_VERSION: %@ CURRENT_XCODE_REVISION: %@", CURRENT_XCODE_VERSION, CURRENT_XCODE_REVISION); - - // just instantiate the singleton - (void)[CPCodePilotPlugin sharedInstance]; + // Avoid instantiating plugin if no Xcode is launched. + // Loading the plugin from xcodebuild command caused a crash because the plugin tries to load a window for itself + NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; + if ([currentApplicationName isEqual:@"Xcode"]) { + LOG(@"CODE PILOT: CURRENT_XCODE_VERSION: %@ CURRENT_XCODE_REVISION: %@", CURRENT_XCODE_VERSION, CURRENT_XCODE_REVISION); + // just instantiate the singleton + (void)[CPCodePilotPlugin sharedInstance]; + } } - (id)init From 07c82893f6c9ae338f9281b4389fb312e0ffc96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kwoska?= Date: Wed, 8 Jul 2015 09:54:18 +0200 Subject: [PATCH 25/33] Added Xcode 6.4 compatibility UUID. --- Resources/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index e18692b..df3b25a 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -50,6 +50,7 @@ C4A681B0-4A26-480E-93EC-1218098B9AA0 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 E969541F-E6F9-4D25-8158-72DC3545A6C6 + 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 NSPrincipalClass CPCodePilotPlugin From fa17f354f7209e27ef95f610a44bf90e8689cb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kwoska?= Date: Wed, 8 Jul 2015 10:27:01 +0200 Subject: [PATCH 26/33] Fixed recurring migration assistant prompt. --- CodePilot.xcodeproj/project.pbxproj | 88 ++++++++++++++--------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/CodePilot.xcodeproj/project.pbxproj b/CodePilot.xcodeproj/project.pbxproj index 5c44759..e1848d8 100755 --- a/CodePilot.xcodeproj/project.pbxproj +++ b/CodePilot.xcodeproj/project.pbxproj @@ -8,61 +8,61 @@ /* Begin PBXBuildFile section */ 4B197DC113AF37A100DF2598 /* memlak.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B197DC013AF37A100DF2598 /* memlak.png */; }; - 4B30A186133979A7008A4372 /* CPPluginInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B30A185133979A7008A4372 /* CPPluginInstaller.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4B30A186133979A7008A4372 /* CPPluginInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B30A185133979A7008A4372 /* CPPluginInstaller.m */; }; 4B30AEF5138D526F0008B1A9 /* UpperStatusBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B30AEF4138D526F0008B1A9 /* UpperStatusBackground.png */; }; 4B32ED40138E4B8B00D272E4 /* ATROX.TTF in Resources */ = {isa = PBXBuildFile; fileRef = 4B32ED3F138E4B8B00D272E4 /* ATROX.TTF */; }; 4B3A21011354CCF0004EAF8F /* InfoLabelBarTriangle.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B3A20FF1354CCF0004EAF8F /* InfoLabelBarTriangle.png */; }; 4B3A21021354CCF0004EAF8F /* InfoLabelBarRect.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B3A21001354CCF0004EAF8F /* InfoLabelBarRect.png */; }; 4B4D42C01354B8BF00ACA78B /* ResultSelection.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B4D42BE1354B8BF00ACA78B /* ResultSelection.png */; }; - 4B4DCEF21363543B0009304C /* CPPreferencesToolbarDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DCEF11363543B0009304C /* CPPreferencesToolbarDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4B4DCEF21363543B0009304C /* CPPreferencesToolbarDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DCEF11363543B0009304C /* CPPreferencesToolbarDelegate.m */; }; 4B61EB371354D52900ED0A40 /* HeaderWithInfo.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B61EB361354D52900ED0A40 /* HeaderWithInfo.png */; }; - 4BAC9BD51386B6310024658A /* CPWorkspaceSymbolCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAC9BD41386B6310024658A /* CPWorkspaceSymbolCache.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BC0BBF313AEBBB80093D04D /* NSURL+Anchors.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC0BBF213AEBBB80093D04D /* NSURL+Anchors.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4BAC9BD51386B6310024658A /* CPWorkspaceSymbolCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAC9BD41386B6310024658A /* CPWorkspaceSymbolCache.m */; }; + 4BC0BBF313AEBBB80093D04D /* NSURL+Anchors.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC0BBF213AEBBB80093D04D /* NSURL+Anchors.m */; }; 4BC46219135494830046C0A6 /* Header.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BC46217135494830046C0A6 /* Header.png */; }; 4BC4621A135494830046C0A6 /* Footer.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BC46218135494830046C0A6 /* Footer.png */; }; - 4BC6BE4F1366E49200C8B378 /* CPPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC6BE4E1366E49200C8B378 /* CPPreferencesViewController.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4BC6BE4F1366E49200C8B378 /* CPPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC6BE4E1366E49200C8B378 /* CPPreferencesViewController.m */; }; 4BEAF844138D67E8003DB3AB /* LightCell.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BEAF842138D67E8003DB3AB /* LightCell.png */; }; 4BEAF845138D67E8003DB3AB /* DarkCell.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BEAF843138D67E8003DB3AB /* DarkCell.png */; }; - 4BEB7735138E466D00D52605 /* CPResultScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BEB7734138E466D00D52605 /* CPResultScrollView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4BEB7735138E466D00D52605 /* CPResultScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BEB7734138E466D00D52605 /* CPResultScrollView.m */; }; 4BEE523B1339193600DA9881 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 4BEE523C1339193600DA9881 /* CodePilotPrefs.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B19163B1150FFBD00E073F8 /* CodePilotPrefs.png */; }; 4BEE523D1339193600DA9881 /* CodePilotIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4B19163C1150FFBD00E073F8 /* CodePilotIcon.icns */; }; - 4BEE523F1339193600DA9881 /* CPCodePilotPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B38FD31112DF476006C375F /* CPCodePilotPlugin.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52401339193600DA9881 /* CPCodePilotWindowDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFEE112FFFF700846DF6 /* CPCodePilotWindowDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52411339193600DA9881 /* CPXcodeWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFF0112FFFF700846DF6 /* CPXcodeWrapper.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52431339193600DA9881 /* CPSymbolCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFF6112FFFF800846DF6 /* CPSymbolCell.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52441339193600DA9881 /* CPSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFF7112FFFF800846DF6 /* CPSearchController.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52451339193600DA9881 /* CPSearchWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFFC112FFFF800846DF6 /* CPSearchWindowView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52461339193600DA9881 /* CPWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFFE112FFFF800846DF6 /* CPWindow.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52471339193600DA9881 /* CPResultTableViewColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC000112FFFF800846DF6 /* CPResultTableViewColumn.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52481339193600DA9881 /* CPResultTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC002112FFFF800846DF6 /* CPResultTableView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52491339193600DA9881 /* NSString+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC004112FFFF800846DF6 /* NSString+MiscExtensions.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE524A1339193600DA9881 /* NSAppleEventDescriptor+ToObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC006112FFFF800846DF6 /* NSAppleEventDescriptor+ToObject.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4BEE523F1339193600DA9881 /* CPCodePilotPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B38FD31112DF476006C375F /* CPCodePilotPlugin.m */; }; + 4BEE52401339193600DA9881 /* CPCodePilotWindowDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFEE112FFFF700846DF6 /* CPCodePilotWindowDelegate.m */; }; + 4BEE52411339193600DA9881 /* CPXcodeWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFF0112FFFF700846DF6 /* CPXcodeWrapper.m */; }; + 4BEE52431339193600DA9881 /* CPSymbolCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFF6112FFFF800846DF6 /* CPSymbolCell.m */; }; + 4BEE52441339193600DA9881 /* CPSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFF7112FFFF800846DF6 /* CPSearchController.m */; }; + 4BEE52451339193600DA9881 /* CPSearchWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFFC112FFFF800846DF6 /* CPSearchWindowView.m */; }; + 4BEE52461339193600DA9881 /* CPWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FBFFE112FFFF800846DF6 /* CPWindow.m */; }; + 4BEE52471339193600DA9881 /* CPResultTableViewColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC000112FFFF800846DF6 /* CPResultTableViewColumn.m */; }; + 4BEE52481339193600DA9881 /* CPResultTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC002112FFFF800846DF6 /* CPResultTableView.m */; }; + 4BEE52491339193600DA9881 /* NSString+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC004112FFFF800846DF6 /* NSString+MiscExtensions.m */; }; + 4BEE524A1339193600DA9881 /* NSAppleEventDescriptor+ToObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC006112FFFF800846DF6 /* NSAppleEventDescriptor+ToObject.m */; }; 4BEE524B1339193600DA9881 /* MCLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC008112FFFF800846DF6 /* MCLog.m */; }; - 4BEE524E1339193600DA9881 /* CPFileReferenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC00F112FFFF800846DF6 /* CPFileReferenceCell.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52501339193600DA9881 /* CPStatusLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B88D25511303885007250E5 /* CPStatusLabel.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52511339193600DA9881 /* NSArray+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDCDAF5113142B40015BF7D /* NSArray+MiscExtensions.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52521339193600DA9881 /* NSView+AllSubviews.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA45D2C11343FA9006351CC /* NSView+AllSubviews.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52531339193600DA9881 /* NSString+Abbreviation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B04640311347A1C00A27CC6 /* NSString+Abbreviation.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52541339193600DA9881 /* QSBSmallScroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B24B642113913B70000EF99 /* QSBSmallScroller.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52551339193600DA9881 /* CPSearchField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7E38CF1139898E00FDBC98 /* CPSearchField.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52561339193600DA9881 /* CPSearchFieldTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BBEE9401139B19F00C77C0C /* CPSearchFieldTextView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52571339193600DA9881 /* CPSelectedObjectCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE7C18113AF46A001F6CB1 /* CPSelectedObjectCell.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4BEE524E1339193600DA9881 /* CPFileReferenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FC00F112FFFF800846DF6 /* CPFileReferenceCell.m */; }; + 4BEE52501339193600DA9881 /* CPStatusLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B88D25511303885007250E5 /* CPStatusLabel.m */; }; + 4BEE52511339193600DA9881 /* NSArray+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDCDAF5113142B40015BF7D /* NSArray+MiscExtensions.m */; }; + 4BEE52521339193600DA9881 /* NSView+AllSubviews.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA45D2C11343FA9006351CC /* NSView+AllSubviews.m */; }; + 4BEE52531339193600DA9881 /* NSString+Abbreviation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B04640311347A1C00A27CC6 /* NSString+Abbreviation.m */; }; + 4BEE52541339193600DA9881 /* QSBSmallScroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B24B642113913B70000EF99 /* QSBSmallScroller.m */; }; + 4BEE52551339193600DA9881 /* CPSearchField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7E38CF1139898E00FDBC98 /* CPSearchField.m */; }; + 4BEE52561339193600DA9881 /* CPSearchFieldTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BBEE9401139B19F00C77C0C /* CPSearchFieldTextView.m */; }; + 4BEE52571339193600DA9881 /* CPSelectedObjectCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE7C18113AF46A001F6CB1 /* CPSelectedObjectCell.m */; }; 4BEE52581339193600DA9881 /* AMIndeterminateProgressIndicatorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B918211113C25AD00BF23B5 /* AMIndeterminateProgressIndicatorCell.m */; }; - 4BEE52591339193600DA9881 /* CPResultCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B5B0F113D08D700503FE7 /* CPResultCell.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE525A1339193600DA9881 /* CPFileReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EC540113D354D00126AE0 /* CPFileReference.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE525D1339193600DA9881 /* CPPreferencesView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B10F4851147B29B0081A264 /* CPPreferencesView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52611339193600DA9881 /* CPHUDViewWithRoundCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1171B011490EA70029BB44 /* CPHUDViewWithRoundCorners.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52631339193600DA9881 /* NSAttributedString+Hyperlink.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B53D0F911492AB200224F53 /* NSAttributedString+Hyperlink.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52641339193600DA9881 /* NSNumber+VersionComparison.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B69D3041153AA5E00541012 /* NSNumber+VersionComparison.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52651339193600DA9881 /* CPInfoWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B28A81F1153C3F300F077A5 /* CPInfoWindowView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52661339193600DA9881 /* CPNoProjectOpenWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B304E681153C9DF00240FF1 /* CPNoProjectOpenWindowView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52671339193600DA9881 /* CPXcodeVersionUnsupportedWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B304E6B1153CA3300240FF1 /* CPXcodeVersionUnsupportedWindowView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52681339193600DA9881 /* NSView+RoundedFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6C94121153F4D2003ED852 /* NSView+RoundedFrame.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE52691339193600DA9881 /* CPFirstRunWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE803001156C9F900F603A8 /* CPFirstRunWindowView.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE526A1339193600DA9881 /* NSMutableArray+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B38187B115CD37F0007D74B /* NSMutableArray+MiscExtensions.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE526C1339193600DA9881 /* MCStringScoring.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B63C9261190199500C0DB12 /* MCStringScoring.c */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - 4BEE526E1339193600DA9881 /* CPSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC547911D7757D00C63705 /* CPSymbol.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 4BEE52591339193600DA9881 /* CPResultCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B5B0F113D08D700503FE7 /* CPResultCell.m */; }; + 4BEE525A1339193600DA9881 /* CPFileReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6EC540113D354D00126AE0 /* CPFileReference.m */; }; + 4BEE525D1339193600DA9881 /* CPPreferencesView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B10F4851147B29B0081A264 /* CPPreferencesView.m */; }; + 4BEE52611339193600DA9881 /* CPHUDViewWithRoundCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1171B011490EA70029BB44 /* CPHUDViewWithRoundCorners.m */; }; + 4BEE52631339193600DA9881 /* NSAttributedString+Hyperlink.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B53D0F911492AB200224F53 /* NSAttributedString+Hyperlink.m */; }; + 4BEE52641339193600DA9881 /* NSNumber+VersionComparison.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B69D3041153AA5E00541012 /* NSNumber+VersionComparison.m */; }; + 4BEE52651339193600DA9881 /* CPInfoWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B28A81F1153C3F300F077A5 /* CPInfoWindowView.m */; }; + 4BEE52661339193600DA9881 /* CPNoProjectOpenWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B304E681153C9DF00240FF1 /* CPNoProjectOpenWindowView.m */; }; + 4BEE52671339193600DA9881 /* CPXcodeVersionUnsupportedWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B304E6B1153CA3300240FF1 /* CPXcodeVersionUnsupportedWindowView.m */; }; + 4BEE52681339193600DA9881 /* NSView+RoundedFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6C94121153F4D2003ED852 /* NSView+RoundedFrame.m */; }; + 4BEE52691339193600DA9881 /* CPFirstRunWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE803001156C9F900F603A8 /* CPFirstRunWindowView.m */; }; + 4BEE526A1339193600DA9881 /* NSMutableArray+MiscExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B38187B115CD37F0007D74B /* NSMutableArray+MiscExtensions.m */; }; + 4BEE526C1339193600DA9881 /* MCStringScoring.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B63C9261190199500C0DB12 /* MCStringScoring.c */; }; + 4BEE526E1339193600DA9881 /* CPSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC547911D7757D00C63705 /* CPSymbol.m */; }; 4BEE52741339193600DA9881 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; 4BEE52751339193600DA9881 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B71F65C11561A15005A8471 /* libssl.dylib */; }; 4BEE52761339193600DA9881 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B71F66011561A5E005A8471 /* libcrypto.dylib */; }; @@ -70,8 +70,8 @@ C79122D6189E3449001776A1 /* NSURL+Xcode.m in Sources */ = {isa = PBXBuildFile; fileRef = C79122D5189E3449001776A1 /* NSURL+Xcode.m */; }; C79122D9189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m in Sources */ = {isa = PBXBuildFile; fileRef = C79122D8189E391D001776A1 /* NSWorkspace+OpenFileOnLine.m */; }; F93F4FAD17B3FE550077B19E /* NSColor+ColorArithmetic.m in Sources */ = {isa = PBXBuildFile; fileRef = F93F4FAC17B3FE550077B19E /* NSColor+ColorArithmetic.m */; }; - F9979794155D52060023D04C /* CPSymbolCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F9979793155D52060023D04C /* CPSymbolCache.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; - F9EAED25179D945100701117 /* CPXcodeInterfaces.m in Sources */ = {isa = PBXBuildFile; fileRef = F9EAED24179D945100701117 /* CPXcodeInterfaces.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + F9979794155D52060023D04C /* CPSymbolCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F9979793155D52060023D04C /* CPSymbolCache.m */; }; + F9EAED25179D945100701117 /* CPXcodeInterfaces.m in Sources */ = {isa = PBXBuildFile; fileRef = F9EAED24179D945100701117 /* CPXcodeInterfaces.m */; }; F9F596B417BBF78E0037BE7A /* CPResult.m in Sources */ = {isa = PBXBuildFile; fileRef = F9F596B317BBF78E0037BE7A /* CPResult.m */; }; /* End PBXBuildFile section */ @@ -653,7 +653,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_GC = supported; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -668,7 +667,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_GC = supported; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; @@ -689,7 +687,6 @@ DSTROOT = "$(HOME)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_GC = unsupported; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -720,7 +717,6 @@ DEPLOYMENT_POSTPROCESSING = YES; DSTROOT = "$(HOME)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - GCC_ENABLE_OBJC_GC = unsupported; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Other Sources/CodePilot_Prefix.pch"; From 3815b1a20b1e07d9945c605de8d81cdf5bb2e71d Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Thu, 17 Sep 2015 22:07:15 +0800 Subject: [PATCH 27/33] add Xcode 7 UUID --- Resources/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index df3b25a..174b4a2 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -51,6 +51,7 @@ 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 E969541F-E6F9-4D25-8158-72DC3545A6C6 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 + 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 NSPrincipalClass CPCodePilotPlugin From d8e0f60ae8541175123af411644df127d641f7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ka=C5=82u=C5=BCny?= Date: Wed, 28 Oct 2015 12:45:08 +0100 Subject: [PATCH 28/33] Added support for missing Xcode versions --- Resources/Info.plist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index 174b4a2..22e9859 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -38,6 +38,9 @@ DVTPlugInCompatibilityUUIDs + AABB7188-E14E-4433-AD3B-5CD791EAD9A3 + CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 + 7265231C-39B4-402C-89E1-16167C4CC990 FEC992CC-CA4A-4CFD-8881-77300FCB848A AD68E85B-441B-4301-B564-A45E4919A6AD 9F75337B-21B4-4ADC-B558-F9CADF7073A7 From a6c06ce74e0d45473dc13d4dcaf46999051a13d5 Mon Sep 17 00:00:00 2001 From: waterjack Date: Tue, 15 Dec 2015 14:54:35 +0800 Subject: [PATCH 29/33] a little fix --- Classes/NSString+MiscExtensions.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Classes/NSString+MiscExtensions.m b/Classes/NSString+MiscExtensions.m index c20b965..4272e9f 100644 --- a/Classes/NSString+MiscExtensions.m +++ b/Classes/NSString+MiscExtensions.m @@ -7,7 +7,6 @@ // #import "NSString+MiscExtensions.h" -#import @implementation NSString (MiscExtensions) - (BOOL)isBlank @@ -40,7 +39,7 @@ + (NSString *)nounWithCount:(NSInteger)count forNoun:(NSString *)noun { NSString *format; - if (abs(count) != 1) { + if (ABS(count) != 1) { // s, z, x, sh, and ch if ([noun hasSuffix:@"s"] || [noun hasSuffix:@"z"] || From 22f18fc2bd149f1ac0f3690f27d49bdd7b91f5ce Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Sun, 7 Feb 2016 19:51:31 +0100 Subject: [PATCH 30/33] Xcode 7.2 DVTPlugInCompatibilityUUID added --- Resources/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Info.plist b/Resources/Info.plist index 22e9859..0832252 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -55,6 +55,7 @@ E969541F-E6F9-4D25-8158-72DC3545A6C6 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 + F41BD31E-2683-44B8-AE7F-5F09E919790E NSPrincipalClass CPCodePilotPlugin From 711eb4b95e7f0df01bf999af76b42ac8f5829404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kwoska?= Date: Wed, 8 Jul 2015 11:27:14 +0200 Subject: [PATCH 31/33] Optimized symbol caching. --- Classes/CPXcodeWrapper.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index db942fa..80123c3 100755 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -189,10 +189,11 @@ - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace withWor - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace { + CFTimeInterval startTime = CACurrentMediaTime(); @try { @synchronized (self.workspaceSymbolCaches) { self.symbolCachingInProgress = YES; - NSMutableArray *newSymbolCacheContents = [NSMutableArray array]; + NSMutableSet *newSymbolCacheContents = [NSMutableSet set]; NSArray *interestingSymbolKinds = [NSArray arrayWithObjects: [DVTSourceCodeSymbolKind containerSymbolKind], @@ -220,7 +221,7 @@ - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace } } - CPWorkspaceSymbolCache *newWorkspaceSymbolCache = [CPWorkspaceSymbolCache symbolCacheWithSymbols:newSymbolCacheContents + CPWorkspaceSymbolCache *newWorkspaceSymbolCache = [CPWorkspaceSymbolCache symbolCacheWithSymbols:newSymbolCacheContents.allObjects forWorkspace:workspace]; [self updateWorkspaceSymbolCacheForWorkspace:workspace withWorkspaceSymbolCache:newWorkspaceSymbolCache]; @@ -231,6 +232,8 @@ - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace @catch (NSException *exception) { LOG(@"EXCEPTION OCCURRED: %@", exception); } + CFTimeInterval endTime = CACurrentMediaTime(); + LOG(@"UPDATING SYMBOL CACHE TOOK %fs", endTime - startTime); } - (NSArray *)topLevelCPSymbolsMatchingQuery:(NSString *)query From a73c7f8af4fff7dc68a65e0d1ac7d2c9fb503aeb Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Sun, 7 Feb 2016 20:09:38 +0100 Subject: [PATCH 32/33] Benchmarking logs removed --- Classes/CPXcodeWrapper.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/Classes/CPXcodeWrapper.m b/Classes/CPXcodeWrapper.m index 80123c3..5b45ed7 100755 --- a/Classes/CPXcodeWrapper.m +++ b/Classes/CPXcodeWrapper.m @@ -189,7 +189,6 @@ - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace withWor - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace { - CFTimeInterval startTime = CACurrentMediaTime(); @try { @synchronized (self.workspaceSymbolCaches) { self.symbolCachingInProgress = YES; @@ -232,8 +231,6 @@ - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace @catch (NSException *exception) { LOG(@"EXCEPTION OCCURRED: %@", exception); } - CFTimeInterval endTime = CACurrentMediaTime(); - LOG(@"UPDATING SYMBOL CACHE TOOK %fs", endTime - startTime); } - (NSArray *)topLevelCPSymbolsMatchingQuery:(NSString *)query From 3a30999db0ce6d12505149bd9b1c3a071b0307bf Mon Sep 17 00:00:00 2001 From: Bartek Chlebek Date: Mon, 30 May 2016 13:09:05 +0200 Subject: [PATCH 33/33] Xcode 7.3/7.3.1 DVTPlugInCompatibilityUUID added --- Resources/Info.plist | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Resources/Info.plist b/Resources/Info.plist index 0832252..3afa574 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -38,24 +38,25 @@ DVTPlugInCompatibilityUUIDs + ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C + F41BD31E-2683-44B8-AE7F-5F09E919790E + 7265231C-39B4-402C-89E1-16167C4CC990 + 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 + 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 + E969541F-E6F9-4D25-8158-72DC3545A6C6 + 9F75337B-21B4-4ADC-B558-F9CADF7073A7 + A16FF353-8441-459E-A50C-B071F53F51B7 + C4A681B0-4A26-480E-93EC-1218098B9AA0 + A2E4D43F-41F4-4FB9-BB94-7177011C9AED AABB7188-E14E-4433-AD3B-5CD791EAD9A3 CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 - 7265231C-39B4-402C-89E1-16167C4CC990 FEC992CC-CA4A-4CFD-8881-77300FCB848A AD68E85B-441B-4301-B564-A45E4919A6AD - 9F75337B-21B4-4ADC-B558-F9CADF7073A7 992275C1-432A-4CF7-B659-D84ED6D42D3F - A16FF353-8441-459E-A50C-B071F53F51B7 640F884E-CE55-4B40-87C0-8869546CAB7A 63FC1C47-140D-42B0-BB4D-A10B2D225574 37B30044-3B14-46BA-ABAA-F01000C27B63 - A2E4D43F-41F4-4FB9-BB94-7177011C9AED - C4A681B0-4A26-480E-93EC-1218098B9AA0 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 - E969541F-E6F9-4D25-8158-72DC3545A6C6 - 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 - 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 - F41BD31E-2683-44B8-AE7F-5F09E919790E NSPrincipalClass CPCodePilotPlugin