From 6c2f14bc180418cfad42582be6ef1cc6a5413368 Mon Sep 17 00:00:00 2001 From: "gtm.daemon" Date: Fri, 4 Jun 2010 15:35:57 +0000 Subject: [Author: dmaclach] Turns on the undeclared-selector warning. This may cause builds to fail if they are using our configs. Also cleaned up some whitespace issues. R=thomasvl DELTA=94 (71 added, 22 deleted, 1 changed) --- AppKit/GTMHotKeyTextField.m | 211 +++++++-------- AppKit/GTMWindowSheetControllerTest.m | 6 + DebugUtils/GTMMethodCheckTest.m | 7 +- Foundation/GTMCalculatedRange.h | 17 +- Foundation/GTMExceptionalInlines.h | 9 +- Foundation/GTMGeometryUtils.h | 93 +++---- Foundation/GTMNSAppleEventDescriptor+Foundation.h | 16 +- Foundation/GTMNSAppleScript+Handler.m | 251 +++++++++-------- Foundation/GTMNSArray+MergeTest.m | 14 +- Foundation/GTMNSObject+KeyValueObserving.m | 315 ++++++++++++---------- Foundation/GTMNSObject+KeyValueObservingTest.m | 65 ++--- Foundation/GTMObjC2RuntimeTest.m | 41 +-- Foundation/GTMSignalHandlerTest.m | 23 +- Foundation/GTMTransientRootProxy.m | 11 +- GTMiPhone.xcodeproj/project.pbxproj | 41 ++- SnowLeopardGcov/GTM_fdopen2003.c | 28 ++ UnitTesting/GTMIPhoneUnitTestDelegate.m | 23 +- UnitTesting/GTMSenTestCase.m | 21 +- XcodeConfig/subconfig/General.xcconfig | 28 +- XcodeConfig/subconfig/SnowLeopardOrLater.xcconfig | 8 +- iPhone/GTMUIView+SubtreeDescription.h | 6 + iPhone/GTMUIView+SubtreeDescription.m | 8 +- 22 files changed, 676 insertions(+), 566 deletions(-) create mode 100644 SnowLeopardGcov/GTM_fdopen2003.c diff --git a/AppKit/GTMHotKeyTextField.m b/AppKit/GTMHotKeyTextField.m index aa7962b..afefeb4 100644 --- a/AppKit/GTMHotKeyTextField.m +++ b/AppKit/GTMHotKeyTextField.m @@ -5,9 +5,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -26,7 +26,7 @@ #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 typedef struct __TISInputSource* TISInputSourceRef; static TISInputSourceRef(*GTM_TISCopyCurrentKeyboardLayoutInputSource)(void) = NULL; -static void * (*GTM_TISGetInputSourceProperty)(TISInputSourceRef inputSource, +static void * (*GTM_TISGetInputSourceProperty)(TISInputSourceRef inputSource, CFStringRef propertyKey) = NULL; static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 @@ -35,6 +35,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; @interface GTMHotKeyTextField (PrivateMethods) - (void)setupBinding:(id)bound withPath:(NSString *)path; - (void)updateDisplayedPrettyString; +- (void)hotKeyValueChanged:(GTMKeyValueChangeNotification *)note; + (BOOL)isValidHotKey:(NSDictionary *)hotKey; + (NSString *)displayStringForHotKey:(NSDictionary *)hotKey; + (BOOL)doesKeyCodeRequireModifier:(UInt16)keycode; @@ -54,8 +55,8 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #if GTM_SUPPORT_GC - (void)finalize { if (boundObject_ && boundKeyPath_) { - [boundObject_ gtm_removeObserver:self - forKeyPath:boundKeyPath_ + [boundObject_ gtm_removeObserver:self + forKeyPath:boundKeyPath_ selector:@selector(hotKeyValueChanged:)]; } [super finalize]; @@ -64,8 +65,8 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; - (void)dealloc { if (boundObject_ && boundKeyPath_) { - [boundObject_ gtm_removeObserver:self - forKeyPath:boundKeyPath_ + [boundObject_ gtm_removeObserver:self + forKeyPath:boundKeyPath_ selector:@selector(hotKeyValueChanged:)]; } [boundObject_ release]; @@ -77,8 +78,8 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #pragma mark Bindings -- (void)bind:(NSString *)binding toObject:(id)observableController - withKeyPath:(NSString *)keyPath +- (void)bind:(NSString *)binding toObject:(id)observableController + withKeyPath:(NSString *)keyPath options:(NSDictionary *)options { if ([binding isEqualToString:NSValueBinding]) { // Update to our new binding @@ -96,7 +97,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; if ([binding isEqualToString:NSValueBinding]) { if (boundObject_ && boundKeyPath_) { [boundObject_ gtm_removeObserver:self - forKeyPath:boundKeyPath_ + forKeyPath:boundKeyPath_ selector:@selector(hotKeyValueChanged:)]; } [boundObject_ release]; @@ -122,7 +123,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; [hotKeyDict_ autorelease]; hotKeyDict_ = [changedValue copy]; [self updateDisplayedPrettyString]; -} +} // Private convenience method for attaching to a new binding @@ -130,7 +131,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; // Release previous if (boundObject_ && boundKeyPath_) { [boundObject_ gtm_removeObserver:self - forKeyPath:boundKeyPath_ + forKeyPath:boundKeyPath_ selector:@selector(hotKeyValueChanged:)]; } [boundObject_ release]; @@ -139,8 +140,8 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; boundObject_ = [bound retain]; boundKeyPath_ = [path copy]; // Make ourself an observer - [boundObject_ gtm_addObserver:self - forKeyPath:boundKeyPath_ + [boundObject_ gtm_addObserver:self + forKeyPath:boundKeyPath_ selector:@selector(hotKeyValueChanged:) userInfo:nil options:NSKeyValueObservingOptionNew]; @@ -174,7 +175,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; } - (float)floatValue { - return [self logBadValueAccess]; + return [self logBadValueAccess]; } - (void)setFloatValue:(float)value { @@ -182,7 +183,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; } - (int)intValue { - return [self logBadValueAccess]; + return [self logBadValueAccess]; } - (void)setIntValue:(int)value { @@ -192,11 +193,11 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - (NSInteger)integerValue { - return [self logBadValueAccess]; + return [self logBadValueAccess]; } - (void)setIntegerValue:(NSInteger)value { - [self logBadValueAccess]; + [self logBadValueAccess]; } #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 @@ -221,7 +222,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; NSAttributedString *attrString = nil; NSString *prettyString = [self stringValue]; if (prettyString) { - attrString = [[[NSAttributedString alloc] + attrString = [[[NSAttributedString alloc] initWithString:prettyString] autorelease]; } return attrString; @@ -280,7 +281,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; if (hotKey && ![[self class] isValidHotKey:hotKey]) { return; } - + // If we are bound we want to round trip through that interface if (boundObject_ && boundKeyPath_) { // If the change is accepted this will call us back as an observer @@ -305,21 +306,21 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; [super setStringValue:@""]; return; } - + // Pretty string NSString *prettyString = [[self class] displayStringForHotKey:hotKeyDict_]; if (!prettyString) { prettyString = @""; } [super setStringValue:prettyString]; - + } + (NSString *)displayStringForHotKey:(NSDictionary *)hotKeyDict { if (!hotKeyDict) return nil; - + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; - + // Modifiers unsigned int flags = [[hotKeyDict objectForKey:kGTMHotKeyModifierFlagsKey] unsignedIntValue]; @@ -338,11 +339,11 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; useGlyph:NO resourceBundle:bundle]; if (!keystroke || ![keystroke length]) return nil; - if ([[self class] doesKeyCodeRequireModifier:keycode] + if ([[self class] doesKeyCodeRequireModifier:keycode] && ![mods length]) { return nil; } - + return [NSString stringWithFormat:@"%@%@", mods, keystroke]; } @@ -355,7 +356,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; _GTMDevLog(@"Field editor not appropriate for field, check window delegate"); return NO; } - + // We don't call super from here, because we are defeating default behavior // as a result we have to call the delegate ourself. id myDelegate = [self delegate]; @@ -363,7 +364,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; if ([myDelegate respondsToSelector:selector]) { if (![myDelegate control:self textShouldBeginEditing:fieldEditor]) return NO; } - + // Update the field editor internal hotkey representation [fieldEditor setHotKeyDictionary:hotKeyDict_]; // OK if its nil return YES; @@ -371,17 +372,17 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; - (void)textDidChange:(NSNotification *)notification { // Sanity - GTMHotKeyFieldEditor *fieldEditor = GTM_STATIC_CAST(GTMHotKeyFieldEditor, + GTMHotKeyFieldEditor *fieldEditor = GTM_STATIC_CAST(GTMHotKeyFieldEditor, [notification object]); if (![fieldEditor isKindOfClass:[GTMHotKeyFieldEditor class]]) { _GTMDevLog(@"Field editor not appropriate for field, check window delegate"); return; } - + // When the field changes we want to read in the current hotkey value so // bindings can validate [self setHotKeyValue:[fieldEditor hotKeyDictionary]]; - + // Let super handle the notifications [super textDidChange:notification]; } @@ -392,7 +393,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; _GTMDevLog(@"Field editor not appropriate for field, check window delegate"); return NO; } - + // Again we are defeating default behavior so we have to do delegate handling // ourself. In this case our goal is simply to prevent the superclass from // doing its own KVO, but we can also skip [[self cell] isEntryAcceptable:]. @@ -403,10 +404,10 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; if ([myDelegate respondsToSelector:selector]) { [myDelegate control:self textShouldEndEditing:fieldEditor]; } - + // The end is always allowed, so set new value [self setHotKeyValue:[fieldEditor hotKeyDictionary]]; - + return YES; } @@ -414,33 +415,33 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + (void)initialize { - if (!GTM_TISCopyCurrentKeyboardLayoutInputSource + if (!GTM_TISCopyCurrentKeyboardLayoutInputSource && [GTMSystemVersion isLeopardOrGreater]) { - CFBundleRef hiToolbox + CFBundleRef hiToolbox = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox")); if (hiToolbox) { - kGTM_TISPropertyUnicodeKeyLayoutData - = *(CFStringRef*)CFBundleGetDataPointerForName(hiToolbox, + kGTM_TISPropertyUnicodeKeyLayoutData + = *(CFStringRef*)CFBundleGetDataPointerForName(hiToolbox, CFSTR("kTISPropertyUnicodeKeyLayoutData")); - GTM_TISCopyCurrentKeyboardLayoutInputSource - = CFBundleGetFunctionPointerForName(hiToolbox, + GTM_TISCopyCurrentKeyboardLayoutInputSource + = CFBundleGetFunctionPointerForName(hiToolbox, CFSTR("TISCopyCurrentKeyboardLayoutInputSource")); - GTM_TISGetInputSourceProperty - = CFBundleGetFunctionPointerForName(hiToolbox, + GTM_TISGetInputSourceProperty + = CFBundleGetFunctionPointerForName(hiToolbox, CFSTR("TISGetInputSourceProperty")); } } } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 #pragma mark Useful String Class Methods + (BOOL)doesKeyCodeRequireModifier:(UInt16)keycode { BOOL doesRequire = YES; switch(keycode) { - // These are the keycodes that map to the + // These are the keycodes that map to the //unichars in the associated comment. - case 122: // NSF1FunctionKey + case 122: // NSF1FunctionKey case 120: // NSF2FunctionKey case 99: // NSF3FunctionKey case 118: // NSF4FunctionKey @@ -484,36 +485,36 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; return [NSString stringWithCharacters:modChars length:charCount]; } -+ (NSString *)stringForKeycode:(UInt16)keycode ++ (NSString *)stringForKeycode:(UInt16)keycode useGlyph:(BOOL)useGlyph resourceBundle:(NSBundle *)bundle { // Some keys never move in any layout (to the best of our knowledge at least) // so we can hard map them. UniChar key = 0; NSString *localizedKey = nil; - + switch (keycode) { - + // Of the hard mapped keys some can be represented with pretty and obvioous // Unicode or simple strings without localization. - + // Arrow keys case 123: key = NSLeftArrowFunctionKey; break; case 124: key = NSRightArrowFunctionKey; break; case 125: key = NSDownArrowFunctionKey; break; case 126: key = NSUpArrowFunctionKey; break; - case 122: key = NSF1FunctionKey; localizedKey = @"F1"; break; + case 122: key = NSF1FunctionKey; localizedKey = @"F1"; break; case 120: key = NSF2FunctionKey; localizedKey = @"F2"; break; - case 99: key = NSF3FunctionKey; localizedKey = @"F3"; break; + case 99: key = NSF3FunctionKey; localizedKey = @"F3"; break; case 118: key = NSF4FunctionKey; localizedKey = @"F4"; break; case 96: key = NSF5FunctionKey; localizedKey = @"F5"; break; case 97: key = NSF6FunctionKey; localizedKey = @"F6"; break; - case 98: key = NSF7FunctionKey; localizedKey = @"F7"; break; - case 100: key = NSF8FunctionKey; localizedKey = @"F8"; break; + case 98: key = NSF7FunctionKey; localizedKey = @"F7"; break; + case 100: key = NSF8FunctionKey; localizedKey = @"F8"; break; case 101: key = NSF9FunctionKey; localizedKey = @"F9"; break; case 109: key = NSF10FunctionKey; localizedKey = @"F10"; break; case 103: key = NSF11FunctionKey; localizedKey = @"F11"; break; - case 111: key = NSF12FunctionKey; localizedKey = @"F12"; break; + case 111: key = NSF12FunctionKey; localizedKey = @"F12"; break; case 105: key = NSF13FunctionKey; localizedKey = @"F13"; break; case 107: key = NSF14FunctionKey; localizedKey = @"F14"; break; case 113: key = NSF15FunctionKey; localizedKey = @"F15"; break; @@ -521,7 +522,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; // Forward delete is a terrible name so we'll use the glyph Apple puts on // their current keyboards case 117: key = 0x2326; break; - + // Now we have keys that can be hard coded but don't have good glyph // representations. Sure, the Apple menu manager has glyphs for them, but // an informal poll of Google developers shows no one really knows what @@ -529,7 +530,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; // this also means localization (*sigh*). We'll use the real English // strings here as keys so that even if localization is missed we'll do OK // in output. - + // Whitespace case 36: key = '\r'; localizedKey = @"Return"; break; case 76: key = 0x3; localizedKey = @"Enter"; break; @@ -567,31 +568,31 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; case 89: key = '7'; localizedKey = @"Keypad 7"; break; case 91: key = '8'; localizedKey = @"Keypad 8"; break; case 92: key = '9'; localizedKey = @"Keypad 9"; break; - + } - + // If they asked for strings, and we have one return it. Otherwise, return // any key we've picked. if (!useGlyph && localizedKey) { - return NSLocalizedStringFromTableInBundle(localizedKey, - @"GTMHotKeyTextField", - bundle, + return NSLocalizedStringFromTableInBundle(localizedKey, + @"GTMHotKeyTextField", + bundle, @""); } else if (key != 0) { return [NSString stringWithFormat:@"%C", key]; } - + // Everything else should be printable so look it up in the current keyboard UCKeyboardLayout *uchrData = NULL; - + OSStatus err = noErr; #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 // layout - KeyboardLayoutRef currentLayout = NULL; + KeyboardLayoutRef currentLayout = NULL; // Get the layout kind SInt32 currentLayoutKind = -1; - if ([GTMSystemVersion isLeopardOrGreater] - && kGTM_TISPropertyUnicodeKeyLayoutData + if ([GTMSystemVersion isLeopardOrGreater] + && kGTM_TISPropertyUnicodeKeyLayoutData && GTM_TISGetInputSourceProperty && GTM_TISCopyCurrentKeyboardLayoutInputSource) { // On Leopard we use the new improved TIS interfaces which work for input @@ -599,7 +600,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; TISInputSourceRef inputSource = GTM_TISCopyCurrentKeyboardLayoutInputSource(); if (inputSource) { - CFDataRef uchrDataRef + CFDataRef uchrDataRef = GTM_TISGetInputSourceProperty(inputSource, kGTM_TISPropertyUnicodeKeyLayoutData); if(uchrDataRef) { @@ -614,19 +615,19 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; _GTMDevLog(@"failed to fetch the keyboard layout, err=%d", err); return nil; } // COV_NF_END - + err = KLGetKeyboardLayoutProperty(currentLayout, - kKLKind, + kKLKind, (const void **)¤tLayoutKind); if (err != noErr) { // COV_NF_START _GTMDevLog(@"failed to fetch the keyboard layout kind property, err=%d", err); return nil; } // COV_NF_END - + if (currentLayoutKind != kKLKCHRKind) { - err = KLGetKeyboardLayoutProperty(currentLayout, - kKLuchrData, + err = KLGetKeyboardLayoutProperty(currentLayout, + kKLuchrData, (const void **)&uchrData); if (err != noErr) { // COV_NF_START _GTMDevLog(@"failed to fetch the keyboard layout uchar data, err=%d", @@ -638,30 +639,30 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #else TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource(); if (inputSource) { - CFDataRef uchrDataRef + CFDataRef uchrDataRef = TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData); if(uchrDataRef) { uchrData = (UCKeyboardLayout*)CFDataGetBytePtr(uchrDataRef); } CFRelease(inputSource); - } + } #endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - + NSString *keystrokeString = nil; if (uchrData) { // uchr layout data is available, this is our preference UniCharCount uchrCharLength = 0; UniChar uchrChars[256] = { 0 }; UInt32 uchrDeadKeyState = 0; - err = UCKeyTranslate(uchrData, - keycode, - kUCKeyActionDisplay, + err = UCKeyTranslate(uchrData, + keycode, + kUCKeyActionDisplay, 0, // No modifiers - LMGetKbdType(), - kUCKeyTranslateNoDeadKeysMask, - &uchrDeadKeyState, + LMGetKbdType(), + kUCKeyTranslateNoDeadKeysMask, + &uchrDeadKeyState, sizeof(uchrChars) / sizeof(UniChar), - &uchrCharLength, + &uchrCharLength, uchrChars); if (err != noErr) { // COV_NF_START @@ -670,10 +671,10 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; // COV_NF_END } if (uchrCharLength < 1) return nil; - keystrokeString = [NSString stringWithCharacters:uchrChars + keystrokeString = [NSString stringWithCharacters:uchrChars length:uchrCharLength]; - } -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + } +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 else if (currentLayoutKind == kKLKCHRKind) { // Only KCHR layout data is available, go old school void *KCHRData = NULL; @@ -712,10 +713,10 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; } } #endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - + // Sanity we got a stroke if (!keystrokeString || ![keystrokeString length]) return nil; - + // Sanity check the keystroke string for unprintable characters NSMutableCharacterSet *validChars = [[[NSMutableCharacterSet alloc] init] autorelease]; @@ -728,13 +729,13 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; return nil; } } - + if (!useGlyph) { // menus want glyphs in the original lowercase forms, so we only upper this // if we aren't using it as a glyph. keystrokeString = [keystrokeString uppercaseString]; } - + return keystrokeString; } @@ -797,7 +798,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) // Lose our focus NSWindow *window = [self window]; [window makeFirstResponder:window]; - + } - (BOOL)shouldDrawInsertionPoint { @@ -806,7 +807,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) return YES; } -- (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange +- (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange granularity:(NSSelectionGranularity)granularity { // Always select everything return NSMakeRange(0, [[self textStorage] length]); @@ -818,7 +819,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) } else { // Try to eat the event [self processEventToHotKeyAndString:theEvent]; - } + } } - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { @@ -842,14 +843,14 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) // Ignore all events that the dock cares about // Just to be extra clear if the user is trying to use Dock hotkeys beep // at them - if ((modifierFlags == NSCommandKeyMask) || + if ((modifierFlags == NSCommandKeyMask) || (modifierFlags == (NSCommandKeyMask | NSShiftKeyMask))) { NSBeep(); bypass = YES; } } else if ((keyCode == 12) && (modifierFlags == NSCommandKeyMask)) { // Don't eat Cmd-Q. Users could have it as a hotkey, but its more likely - // they're trying to quit + // they're trying to quit bypass = YES; } else if ((keyCode == 13) && (modifierFlags == NSCommandKeyMask)) { // Same for Cmd-W, user is probably trying to close the window @@ -872,28 +873,28 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) NSBeep(); return; } - + // Replacement range NSRange replaceRange = NSMakeRange(0, [[self textStorage] length]); - + // Ask for permission to replace if (![self shouldChangeTextInRange:replaceRange replacementString:prettyString]) { // If replacement was disallowed, change nothing, including hotKeyDict_ NSBeep(); return; - } - + } + // Replacement was allowed, update [hotKeyDict_ autorelease]; hotKeyDict_ = [newHotKey retain]; - + // Set string on self, allowing super to handle attribute copying [self setString:prettyString]; - + // Finish the change [self didChangeText]; - + // Force editing to end. This sends focus off into space slightly, but // its better than constantly capturing user events. This is exactly // like the Apple editor in their Keyboard pref pane. @@ -923,7 +924,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) - (NSDictionary *)hotKeyDictionaryForEvent:(NSEvent *)event { if (!event) return nil; - + // Check event NSUInteger flags = [event modifierFlags]; UInt16 keycode = [event keyCode]; @@ -931,7 +932,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) NSUInteger allModifiers = (NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask | NSShiftKeyMask); - BOOL requiresModifiers + BOOL requiresModifiers = [GTMHotKeyTextField doesKeyCodeRequireModifier:keycode]; if (requiresModifiers) { // If we aren't a function key, and have no modifiers do nothing. @@ -939,14 +940,14 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor) // If the event has high bits in keycode do nothing if (keycode & 0xFF00) return nil; } - + // Clean the flags to only contain things we care about UInt32 cleanFlags = 0; if (flags & NSCommandKeyMask) cleanFlags |= NSCommandKeyMask; if (flags & NSAlternateKeyMask) cleanFlags |= NSAlternateKeyMask; if (flags & NSControlKeyMask) cleanFlags |= NSControlKeyMask; if (flags & NSShiftKeyMask) cleanFlags |= NSShiftKeyMask; - + return [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kGTMHotKeyDoubledModifierKey, diff --git a/AppKit/GTMWindowSheetControllerTest.m b/AppKit/GTMWindowSheetControllerTest.m index 62354e2..b2cb7b2 100644 --- a/AppKit/GTMWindowSheetControllerTest.m +++ b/AppKit/GTMWindowSheetControllerTest.m @@ -28,6 +28,12 @@ BOOL didAlertClose_; BOOL didSheetClose_; } +- (void)alertDidEnd:(NSAlert *)alert + returnCode:(NSInteger)returnCode + context:(void *)context; +- (void)sheetDidEnd:(NSWindow *)sheet + returnCode:(NSInteger)returnCode + context:(void *)context; @end @implementation GTMWindowSheetControllerTest diff --git a/DebugUtils/GTMMethodCheckTest.m b/DebugUtils/GTMMethodCheckTest.m index 974dfaf..1fba238 100644 --- a/DebugUtils/GTMMethodCheckTest.m +++ b/DebugUtils/GTMMethodCheckTest.m @@ -5,9 +5,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -22,6 +22,7 @@ static BOOL gTestCheckVar = NO; @interface GTMMethodCheckTest : GTMTestCase + (void)GTMMethodCheckTestClassMethod; +- (void)GTMMethodCheckTestMethod; @end @implementation GTMMethodCheckTest @@ -45,7 +46,7 @@ GTM_METHOD_CHECK(GTMMethodCheckTest, GTMMethodCheckTestClassMethod); // GTMMethodCheck only runs in debug STAssertTrue(gTestCheckVar, @"Should be true"); #endif - + // Next two calls just verify our code coverage [self GTMMethodCheckTestMethod]; [[self class] GTMMethodCheckTestClassMethod]; diff --git a/Foundation/GTMCalculatedRange.h b/Foundation/GTMCalculatedRange.h index 5710da6..7796f0b 100644 --- a/Foundation/GTMCalculatedRange.h +++ b/Foundation/GTMCalculatedRange.h @@ -9,9 +9,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -20,6 +20,7 @@ // #import +#import #import "GTMDefines.h" /// Allows you to calculate a value based on defined stops in a range. @@ -28,7 +29,7 @@ /// located at 0.0 is red and the stop located at 1.0 is blue, /// the value based on the position 0.5 would come out as purple assuming /// that the valueAtPosition function calculates a purely linear mapping between -/// the stops at 0.0 and 1.0. Stops have indices and are sorted from lowest to +/// the stops at 0.0 and 1.0. Stops have indices and are sorted from lowest to /// highest. The example above would have 2 stops. Stop 0 would be red and stop /// 1 would be blue. /// @@ -43,7 +44,7 @@ // Adds a stop to the range at |position|. If there is already a stop // at position |position| it is replaced. // -// Args: +// Args: // item: the object to place at |position|. // position: the position in the range to put |item|. // @@ -51,7 +52,7 @@ // Removes a stop from the range at |position|. // -// Args: +// Args: // position: the position in the range to remove |item|. // // Returns: @@ -63,7 +64,7 @@ // based on position where index of x < index of y if position // of x < position of y. // -// Args: +// Args: // item: the object to place at |position|. // position: the position in the range to put |item|. // @@ -81,7 +82,7 @@ // The default implementation returns a value if there happens to be // a stop for the given position. Otherwise it returns nil. // -// Args: +// Args: // position: the position to calculate a value for. // // Returns: @@ -91,7 +92,7 @@ // Returns the |index|'th stop and position in the set. // Throws an exception if out of range. // -// Args: +// Args: // index: the index of the stop // outPosition: a pointer to a value to be filled in with a position. // this can be NULL, in which case no position is returned. diff --git a/Foundation/GTMExceptionalInlines.h b/Foundation/GTMExceptionalInlines.h index ce30db9..ef6718a 100644 --- a/Foundation/GTMExceptionalInlines.h +++ b/Foundation/GTMExceptionalInlines.h @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -17,6 +17,7 @@ // #import +#import #import "GTMDefines.h" // This file exists because when you have full warnings on you can run into @@ -41,13 +42,13 @@ FOUNDATION_EXPORT CFRange GTMCFRangeMake(NSUInteger loc, NSUInteger len); FOUNDATION_EXPORT CGPoint GTMCGPointMake(CGFloat x, CGFloat y); FOUNDATION_EXPORT CGSize GTMCGSizeMake(CGFloat width, CGFloat height); -FOUNDATION_EXPORT CGRect GTMCGRectMake(CGFloat x, CGFloat y, +FOUNDATION_EXPORT CGRect GTMCGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height); #if !GTM_IPHONE_SDK // iPhone does not have NSTypes defined, only CGTypes. So no NSRect, NSPoint etc. FOUNDATION_EXPORT NSPoint GTMNSMakePoint(CGFloat x, CGFloat y); FOUNDATION_EXPORT NSSize GTMNSMakeSize(CGFloat w, CGFloat h); -FOUNDATION_EXPORT NSRect GTMNSMakeRect(CGFloat x, CGFloat y, +FOUNDATION_EXPORT NSRect GTMNSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h); #endif diff --git a/Foundation/GTMGeometryUtils.h b/Foundation/GTMGeometryUtils.h index 5c14303..867977d 100644 --- a/Foundation/GTMGeometryUtils.h +++ b/Foundation/GTMGeometryUtils.h @@ -9,9 +9,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -20,12 +20,13 @@ // #import +#import #import "GTMDefines.h" #ifdef __cplusplus extern "C" { #endif - + enum { GTMScaleProportionally = 0, // Fit proportionally GTMScaleToFit, // Forced fit (distort if necessary) @@ -53,7 +54,7 @@ typedef NSUInteger GTMRectAlignment; // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of min X side of rect GTM_INLINE CGPoint GTMCGMidMinX(CGRect rect) { @@ -64,7 +65,7 @@ GTM_INLINE CGPoint GTMCGMidMinX(CGRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of max X side of rect GTM_INLINE CGPoint GTMCGMidMaxX(CGRect rect) { @@ -75,7 +76,7 @@ GTM_INLINE CGPoint GTMCGMidMaxX(CGRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of max Y side of rect GTM_INLINE CGPoint GTMCGMidMaxY(CGRect rect) { @@ -86,7 +87,7 @@ GTM_INLINE CGPoint GTMCGMidMaxY(CGRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of min Y side of rect GTM_INLINE CGPoint GTMCGMidMinY(CGRect rect) { @@ -97,7 +98,7 @@ GTM_INLINE CGPoint GTMCGMidMinY(CGRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the center of rect GTM_INLINE CGPoint GTMCGCenter(CGRect rect) { @@ -111,7 +112,7 @@ GTM_INLINE CGPoint GTMCGCenter(CGRect rect) { // // Args: // rect - rectangle -// +// // Returns: // size of rectangle GTM_INLINE CGSize GTMCGRectSize(CGRect rect) { @@ -122,7 +123,7 @@ GTM_INLINE CGSize GTMCGRectSize(CGRect rect) { // // Args: // size - size -// +// // Returns: // rectangle of size (origin 0,0) GTM_INLINE CGRect GTMCGRectOfSize(CGSize size) { @@ -134,7 +135,7 @@ GTM_INLINE CGRect GTMCGRectOfSize(CGSize size) { /// Scales an CGRect // -// Args: +// Args: // inRect: Rect to scale // xScale: fraction to scale (1.0 is 100%) // yScale: fraction to scale (1.0 is 100%) @@ -142,7 +143,7 @@ GTM_INLINE CGRect GTMCGRectOfSize(CGSize size) { // Returns: // Converted Rect GTM_INLINE CGRect GTMCGRectScale(CGRect inRect, CGFloat xScale, CGFloat yScale) { - return CGRectMake(inRect.origin.x, inRect.origin.y, + return CGRectMake(inRect.origin.x, inRect.origin.y, inRect.size.width * xScale, inRect.size.height * yScale); } @@ -153,7 +154,7 @@ GTM_INLINE CGRect GTMCGRectScale(CGRect inRect, CGFloat xScale, CGFloat yScale) // alignee - rect to be aligned // aligner - rect to be aligned from // alignment - way to align the rectangles -CGRect GTMCGAlignRectangles(CGRect alignee, CGRect aligner, +CGRect GTMCGAlignRectangles(CGRect alignee, CGRect aligner, GTMRectAlignment alignment); /// Scale rectangle // @@ -161,7 +162,7 @@ CGRect GTMCGAlignRectangles(CGRect alignee, CGRect aligner, // scalee - rect to be scaled // size - size to scale to // scaling - way to scale the rectangle -CGRect GTMCGScaleRectangleToSize(CGRect scalee, CGSize size, +CGRect GTMCGScaleRectangleToSize(CGRect scalee, CGSize size, GTMScaling scaling); #pragma mark - @@ -172,13 +173,13 @@ CGRect GTMCGScaleRectangleToSize(CGRect scalee, CGSize size, // Args: // pt1 first point // pt2 second point -// +// // Returns: // Distance GTM_INLINE CGFloat GTMCGDistanceBetweenPoints(CGPoint pt1, CGPoint pt2) { CGFloat dX = pt1.x - pt2.x; CGFloat dY = pt1.y - pt2.y; -#if CGFLOAT_IS_DOUBLE +#if CGFLOAT_IS_DOUBLE return sqrt(dX * dX + dY * dY); #else return sqrtf(dX * dX + dY * dY); @@ -189,7 +190,7 @@ GTM_INLINE CGFloat GTMCGDistanceBetweenPoints(CGPoint pt1, CGPoint pt2) { // iPhone does not have NSTypes defined, only CGTypes. So no NSRect, NSPoint etc. #pragma mark - -// All of the conversion routines below are basically copied from the +// All of the conversion routines below are basically copied from the // NSGeometry header in the 10.5 sdk. #pragma mark NS <-> CG Point Conversion @@ -199,12 +200,12 @@ GTM_INLINE CGFloat GTMCGDistanceBetweenPoints(CGPoint pt1, CGPoint pt2) { /// CGPoints are relative to 0,0 in lower left; /// NSPoints are relative to 0,0 in lower left // -// Args: +// Args: // inPoint: CGPoint to convert // // Returns: // Converted NSPoint -GTM_INLINE NSPoint GTMCGPointToNSPoint(CGPoint inPoint) { +GTM_INLINE NSPoint GTMCGPointToNSPoint(CGPoint inPoint) { _GTMCompileAssert(sizeof(NSPoint) == sizeof(CGPoint), NSPoint_and_CGPoint_must_be_the_same_size); union convertUnion {NSPoint ns; CGPoint cg;}; return ((union convertUnion *)&inPoint)->ns; @@ -215,12 +216,12 @@ GTM_INLINE NSPoint GTMCGPointToNSPoint(CGPoint inPoint) { /// CGPoints are relative to 0,0 in lower left; /// NSPoints are relative to 0,0 in lower left // -// Args: +// Args: // inPoint: NSPoint to convert // // Returns: // Converted CGPoint -GTM_INLINE CGPoint GTMNSPointToCGPoint(NSPoint inPoint) { +GTM_INLINE CGPoint GTMNSPointToCGPoint(NSPoint inPoint) { _GTMCompileAssert(sizeof(NSPoint) == sizeof(CGPoint), NSPoint_and_CGPoint_must_be_the_same_size); union convertUnion {NSPoint ns; CGPoint cg;}; return ((union convertUnion *)&inPoint)->cg; @@ -234,7 +235,7 @@ GTM_INLINE CGPoint GTMNSPointToCGPoint(NSPoint inPoint) { /// NSRect are relative to 0,0 in lower left; /// CGRect are relative to 0,0 in lower left // -// Args: +// Args: // inRect: CGRect to convert // // Returns: @@ -250,7 +251,7 @@ GTM_INLINE NSRect GTMCGRectToNSRect(CGRect inRect) { /// NSRect are relative to 0,0 in lower left; /// CGRect are relative to 0,0 in lower left // -// Args: +// Args: // inRect: NSRect to convert // // Returns: @@ -267,7 +268,7 @@ GTM_INLINE CGRect GTMNSRectToCGRect(NSRect inRect) { /// Convert from a CGSize to an NSSize. // -// Args: +// Args: // inSize: CGSize to convert // // Returns: @@ -280,7 +281,7 @@ GTM_INLINE NSSize GTMCGSizeToNSSize(CGSize inSize) { /// Convert from a NSSize to a CGSize. // -// Args: +// Args: // inSize: NSSize to convert // // Returns: @@ -298,7 +299,7 @@ GTM_INLINE CGSize GTMNSSizeToCGSize(NSSize inSize) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of min X side of rect GTM_INLINE NSPoint GTMNSMidMinX(NSRect rect) { @@ -309,7 +310,7 @@ GTM_INLINE NSPoint GTMNSMidMinX(NSRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of max X side of rect GTM_INLINE NSPoint GTMNSMidMaxX(NSRect rect) { @@ -320,7 +321,7 @@ GTM_INLINE NSPoint GTMNSMidMaxX(NSRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of max Y side of rect GTM_INLINE NSPoint GTMNSMidMaxY(NSRect rect) { @@ -331,7 +332,7 @@ GTM_INLINE NSPoint GTMNSMidMaxY(NSRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the middle of min Y side of rect GTM_INLINE NSPoint GTMNSMidMinY(NSRect rect) { @@ -342,7 +343,7 @@ GTM_INLINE NSPoint GTMNSMidMinY(NSRect rect) { // // Args: // rect - rectangle -// +// // Returns: // point located in the center of rect GTM_INLINE NSPoint GTMNSCenter(NSRect rect) { @@ -356,7 +357,7 @@ GTM_INLINE NSPoint GTMNSCenter(NSRect rect) { // // Args: // rect - rectangle -// +// // Returns: // size of rectangle GTM_INLINE NSSize GTMNSRectSize(NSRect rect) { @@ -367,7 +368,7 @@ GTM_INLINE NSSize GTMNSRectSize(NSRect rect) { // // Args: // size - size -// +// // Returns: // rectangle of size (origin 0,0) GTM_INLINE NSRect GTMNSRectOfSize(NSSize size) { @@ -379,7 +380,7 @@ GTM_INLINE NSRect GTMNSRectOfSize(NSSize size) { /// Scales an NSRect // -// Args: +// Args: // inRect: Rect to scale // xScale: fraction to scale (1.0 is 100%) // yScale: fraction to scale (1.0 is 100%) @@ -387,7 +388,7 @@ GTM_INLINE NSRect GTMNSRectOfSize(NSSize size) { // Returns: // Converted Rect GTM_INLINE NSRect GTMNSRectScale(NSRect inRect, CGFloat xScale, CGFloat yScale) { - return NSMakeRect(inRect.origin.x, inRect.origin.y, + return NSMakeRect(inRect.origin.x, inRect.origin.y, inRect.size.width * xScale, inRect.size.height * yScale); } @@ -396,12 +397,12 @@ GTM_INLINE NSRect GTMNSRectScale(NSRect inRect, CGFloat xScale, CGFloat yScale) // Args: // alignee - rect to be aligned // aligner - rect to be aligned from -GTM_INLINE NSRect GTMNSAlignRectangles(NSRect alignee, NSRect aligner, +GTM_INLINE NSRect GTMNSAlignRectangles(NSRect alignee, NSRect aligner, GTMRectAlignment alignment) { return GTMCGRectToNSRect(GTMCGAlignRectangles(GTMNSRectToCGRect(alignee), GTMNSRectToCGRect(aligner), alignment)); -} +} /// Align a rectangle to another // @@ -410,27 +411,27 @@ GTM_INLINE NSRect GTMNSAlignRectangles(NSRect alignee, NSRect aligner, // scaler - rect to scale to // scaling - way to scale the rectangle // alignment - way to align the scaled rectangle -GTM_INLINE NSRect GTMNSScaleRectToRect(NSRect scalee, - NSRect scaler, +GTM_INLINE NSRect GTMNSScaleRectToRect(NSRect scalee, + NSRect scaler, GTMScaling scaling, GTMRectAlignment alignment) { - + return GTMCGRectToNSRect( GTMCGAlignRectangles( GTMCGScaleRectangleToSize(GTMNSRectToCGRect(scalee), GTMNSSizeToCGSize(scaler.size), - scaling), + scaling), GTMNSRectToCGRect(scaler), alignment)); -} - +} + /// Scale rectangle // // Args: // scalee - rect to be scaled // size - size to scale to // scaling - way to scale the rectangle -GTM_INLINE NSRect GTMNSScaleRectangleToSize(NSRect scalee, NSSize size, +GTM_INLINE NSRect GTMNSScaleRectangleToSize(NSRect scalee, NSSize size, GTMScaling scaling) { return GTMCGRectToNSRect(GTMCGScaleRectangleToSize(GTMNSRectToCGRect(scalee), GTMNSSizeToCGSize(size), @@ -445,16 +446,16 @@ GTM_INLINE NSRect GTMNSScaleRectangleToSize(NSRect scalee, NSSize size, // Args: // pt1 first point // pt2 second point -// +// // Returns: // Distance GTM_INLINE CGFloat GTMNSDistanceBetweenPoints(NSPoint pt1, NSPoint pt2) { - return GTMCGDistanceBetweenPoints(GTMNSPointToCGPoint(pt1), + return GTMCGDistanceBetweenPoints(GTMNSPointToCGPoint(pt1), GTMNSPointToCGPoint(pt2)); } #endif // !GTM_IPHONE_SDK - + #ifdef __cplusplus } #endif diff --git a/Foundation/GTMNSAppleEventDescriptor+Foundation.h b/Foundation/GTMNSAppleEventDescriptor+Foundation.h index fe3e1f0..8e62bcc 100644 --- a/Foundation/GTMNSAppleEventDescriptor+Foundation.h +++ b/Foundation/GTMNSAppleEventDescriptor+Foundation.h @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -22,7 +22,7 @@ // A category for dealing with NSAppleEventDescriptors and NSArrays. @interface NSAppleEventDescriptor (GTMAppleEventDescriptorArrayAdditions) -// Used to register the types you know how to convert into +// Used to register the types you know how to convert into // NSAppleEventDescriptors. // See examples in GTMNSAppleEventDescriptor+Foundation. // Args: @@ -30,8 +30,8 @@ // -(NSAppleEventDesc *)selector_name; // types - an std c array of types of length |count| // count - number of types in |types| -+ (void)gtm_registerSelector:(SEL)selector - forTypes:(DescType*)types ++ (void)gtm_registerSelector:(SEL)selector + forTypes:(DescType*)types count:(NSUInteger)count; // Returns an NSObject for any NSAppleEventDescriptor @@ -73,6 +73,8 @@ // Attempt to extract a NSNumber. Returns nil on error. - (NSNumber*)gtm_numberValue; +// Attempt to return a GTMFourCharCode. Returns nil on error. +- (GTMFourCharCode*)gtm_fourCharCodeValue; @end @interface NSObject (GTMAppleEventDescriptorObjectAdditions) @@ -86,10 +88,10 @@ @interface NSAppleEventDescriptor (GTMAppleEventDescriptorAdditions) // Allows you to send events. // Returns YES if send was successful. -- (BOOL)gtm_sendEventWithMode:(AESendMode)mode +- (BOOL)gtm_sendEventWithMode:(AESendMode)mode timeOut:(NSTimeInterval)timeout reply:(NSAppleEventDescriptor**)reply; -@end +@end @interface GTMFourCharCode (GTMAppleEventDescriptorObjectAdditions) diff --git a/Foundation/GTMNSAppleScript+Handler.m b/Foundation/GTMNSAppleScript+Handler.m index 01e15e1..e4ace96 100644 --- a/Foundation/GTMNSAppleScript+Handler.m +++ b/Foundation/GTMNSAppleScript+Handler.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -32,9 +32,9 @@ static NSString *const GTMNSAppleScriptErrorKey = @"GTMNSAppleScriptError"; // Error keys that we may return in the error dictionary on top of the standard // NSAppleScriptError* keys. -NSString const* GTMNSAppleScriptErrorPartialResult +NSString const* GTMNSAppleScriptErrorPartialResult = @"GTMNSAppleScriptErrorPartialResult"; -NSString const* GTMNSAppleScriptErrorOffendingObject +NSString const* GTMNSAppleScriptErrorOffendingObject = @"GTMNSAppleScriptErrorOffendingObject"; NSString const* GTMNSAppleScriptErrorExpectedType = @"GTMNSAppleScriptErrorExpectedType"; @@ -76,7 +76,7 @@ NSString const* GTMNSAppleScriptErrorExpectedType - (NSSet*)gtm_scriptProperties; // Handles creating an NSAppleEventDescriptor from an OSAID -- (NSAppleEventDescriptor*)descForScriptID:(OSAID)scriptID +- (NSAppleEventDescriptor*)descForScriptID:(OSAID)scriptID component:(ComponentInstance)component; // Utility methods for converting between real and generic OSAIDs. @@ -89,45 +89,63 @@ NSString const* GTMNSAppleScriptErrorExpectedType component:(ComponentInstance)component; @end +// Private methods for dealing with Scripts/Events and NSAppleEventDescriptors +@interface NSAppleEventDescriptor (GTMAppleEventDescriptorScriptAdditions) + +// Return an NSAppleScript for a desc of typeScript. This will create a new +// Applescript that is a copy of the script that you want. +// Returns nil on failure. +- (NSAppleScript*)gtm_scriptValue; + +// Return an NSAppleScript for a desc of typeGTMOSAID. This will not copy the +// script, but will create an NSAppleScript wrapping the script represented +// by the OSAID. +// Returns nil on failure. +- (NSAppleScript*)gtm_osaIDValue; + +// Return a NSString with [eventClass][eventID] for typeEvent 'evnt' +- (NSString*)gtm_eventValue; +@end + @implementation NSAppleScript(GTMAppleScriptHandlerAdditions) GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_descriptorWithPositionalHandler:parametersArray:); GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_descriptorWithLabeledHandler:labels:parameters:count:); GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); + (void)load { - DescType types[] = { + DescType types[] = { typeScript }; - + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_scriptValue) forTypes:types count:sizeof(types)/sizeof(DescType)]; - - DescType types2[] = { + + DescType types2[] = { 'evnt' // No type code for this one }; - + [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_eventValue) forTypes:types2 count:sizeof(types2)/sizeof(DescType)]; - + DescType types3[] = { typeGTMOSAID }; - + [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_osaIDValue) forTypes:types3 count:sizeof(types3)/sizeof(DescType)]; [pool drain]; } -- (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event +- (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event error:(NSDictionary **)error { NSMutableDictionary *data = [NSMutableDictionary dictionaryWithObjectsAndKeys: event, GTMNSAppleScriptEventKey, nil]; [self performSelectorOnMainThread:@selector(gtm_internalExecuteAppleEvent:) - withObject:data + withObject:data waitUntilDone:YES]; if (error) { *error = [data objectForKey:GTMNSAppleScriptErrorKey]; @@ -135,51 +153,51 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); return [data objectForKey:GTMNSAppleScriptResultKey]; } -- (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler - parameters:(NSArray*)params +- (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler + parameters:(NSArray*)params error:(NSDictionary**)error { - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:handler + NSAppleEventDescriptor *event + = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:handler parametersArray:params]; return [self gtm_executeAppleEvent:event error:error]; -} +} - (NSAppleEventDescriptor*)gtm_executeLabeledHandler:(NSString*)handler labels:(AEKeyword*)labels parameters:(id*)params count:(NSUInteger)count error:(NSDictionary **)error { - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:handler + NSAppleEventDescriptor *event + = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:handler labels:labels parameters:params count:count]; return [self gtm_executeAppleEvent:event error:error]; -} +} - (NSSet*)gtm_handlers { return [self gtm_allValuesUsingSelector:@selector(gtm_scriptHandlers)]; } - + - (NSSet*)gtm_properties { return [self gtm_allValuesUsingSelector:@selector(gtm_scriptProperties)]; } // Set a value for a property by type (eg pASTopLevelScript) -- (BOOL)gtm_setValue:(id)value +- (BOOL)gtm_setValue:(id)value forPropertyEnum:(DescType)property addingDefinition:(BOOL)adding { - GTMFourCharCode *fcc + GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:property]; return [self gtm_setValue:value forProperty:fcc addingDefinition:adding]; } -- (BOOL)gtm_setValue:(id)value - forProperty:(id)property +- (BOOL)gtm_setValue:(id)value + forProperty:(id)property addingDefinition:(BOOL)adding{ OSAError error = paramErr; BOOL wasGood = NO; - NSAppleEventDescriptor *propertyName + NSAppleEventDescriptor *propertyName = [self gtm_descriptorForPropertyValue:property]; NSAppleEventDescriptor *desc = [value gtm_appleEventDescriptor]; if (propertyName && desc) { @@ -188,22 +206,22 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); ComponentInstance component; OSAID scriptID = [script gtm_realIDAndComponent:&component]; error = OSACoerceFromDesc(component, - [desc aeDesc], - kOSAModeNull, + [desc aeDesc], + kOSAModeNull, &valueID); if (error == noErr) { - error = OSASetProperty(component, - adding ? kOSAModeNull : kOSAModeDontDefine, - scriptID, - [propertyName aeDesc], - valueID); + error = OSASetProperty(component, + adding ? kOSAModeNull : kOSAModeDontDefine, + scriptID, + [propertyName aeDesc], + valueID); if (error == noErr) { wasGood = YES; } } } if (!wasGood) { - _GTMDevLog(@"Unable to setValue:%@ forProperty:%@ from %@ (%d)", + _GTMDevLog(@"Unable to setValue:%@ forProperty:%@ from %@ (%d)", value, property, self, error); } return wasGood; @@ -223,13 +241,13 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSAID osaID = [self gtm_realIDAndComponent:&component]; AEDesc result = { typeNull, NULL }; NSAppleEventDescriptor *desc = nil; - OSAError error = OSACoerceToDesc(component, - osaID, + OSAError error = OSACoerceToDesc(component, + osaID, typeScript, kOSAModeNull, &result); if (error == noErr) { - desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&result] + desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&result] autorelease]; } else { _GTMDevLog(@"Unable to coerce script %d", error); @@ -262,17 +280,17 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); for (NSUInteger i = 1; i < count; i++) { [types appendString:@"@"]; } - signature = [NSMethodSignature signatureWithObjCTypes:[types UTF8String]]; + signature = [NSMethodSignature signatureWithObjCTypes:[types UTF8String]]; } return signature; } - (void)forwardInvocation:(NSInvocation *)invocation { SEL sel = [invocation selector]; - NSMutableString *handlerName + NSMutableString *handlerName = [NSMutableString stringWithString:NSStringFromSelector(sel)]; NSUInteger handlerOrigLength = [handlerName length]; - [handlerName replaceOccurrencesOfString:@":" + [handlerName replaceOccurrencesOfString:@":" withString:@"" options:0 range:NSMakeRange(0,handlerOrigLength)]; @@ -285,9 +303,9 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); [args addObject:arg]; } NSDictionary *error = nil; - NSAppleEventDescriptor *desc = [self gtm_executePositionalHandler:handlerName - parameters:args - error:&error]; + NSAppleEventDescriptor *desc = [self gtm_executePositionalHandler:handlerName + parameters:args + error:&error]; if ([[invocation methodSignature] methodReturnLength] > 0) { id returnValue = [desc gtm_objectValue]; [invocation setReturnValue:&returnValue]; @@ -303,7 +321,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); propDesc = [property gtm_appleEventDescriptorOfType:typeProperty]; } else if ([property isKindOfClass:[NSString class]]) { propDesc = [property gtm_appleEventDescriptor]; - } + } return propDesc; } @@ -311,23 +329,23 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); GTMAssertRunningOnMainThread(); OSAError error = paramErr; NSAppleEventDescriptor *desc = nil; - NSAppleEventDescriptor *propertyName + NSAppleEventDescriptor *propertyName = [self gtm_descriptorForPropertyValue:property]; if (propertyName) { ComponentInstance component; OSAID scriptID = [self gtm_realIDAndComponent:&component]; OSAID valueID = kOSANullScript; - error = OSAGetProperty(component, - kOSAModeNull, - scriptID, - [propertyName aeDesc], + error = OSAGetProperty(component, + kOSAModeNull, + scriptID, + [propertyName aeDesc], &valueID); if (error == noErr) { desc = [self descForScriptID:valueID component:component]; } } if (error) { - _GTMDevLog(@"Unable to get valueForProperty:%@ from %@ (%d)", + _GTMDevLog(@"Unable to get valueForProperty:%@ from %@ (%d)", property, self, error); } return desc; @@ -366,8 +384,8 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSAID osaID = [self gtm_realIDAndComponent:&component]; OSAError error = OSAGetHandlerNames(component, kOSAModeNull, osaID, &names); if (error == noErr) { - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] + NSAppleEventDescriptor *desc + = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] autorelease]; array = [desc gtm_objectValue]; } @@ -385,8 +403,8 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSAID osaID = [self gtm_realIDAndComponent:&component]; OSAError error = OSAGetPropertyNames(component, kOSAModeNull, osaID, &names); if (error == noErr) { - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] + NSAppleEventDescriptor *desc + = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] autorelease]; array = [desc gtm_objectValue]; } @@ -408,7 +426,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); return exactID; } -- (NSAppleEventDescriptor*)descForScriptID:(OSAID)osaID +- (NSAppleEventDescriptor*)descForScriptID:(OSAID)osaID component:(ComponentInstance)component { GTMAssertRunningOnMainThread(); NSAppleEventDescriptor *desc = nil; @@ -427,17 +445,17 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); if (value == typeScript) { osaID = [self gtm_genericID:osaID forComponent:component]; desc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeGTMOSAID - bytes:&osaID + bytes:&osaID length:sizeof(osaID)]; } else { AEDesc aeDesc; - err = OSACoerceToDesc(component, - osaID, - typeWildCard, - kOSAModeNull, + err = OSACoerceToDesc(component, + osaID, + typeWildCard, + kOSAModeNull, &aeDesc); if (err == noErr) { - desc = [[[NSAppleEventDescriptor alloc] + desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&aeDesc] autorelease]; } } @@ -480,12 +498,12 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); ComponentInstance component; OSAID scriptID = [self gtm_realIDAndComponent:&component]; OSAID valueID; - OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, + OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, kOSAModeNull, &valueID); if (err == noErr) { // descForScriptID:component: is what sets this apart from the // standard executeAppleEvent:error: in that it handles - // taking script results and turning them into AEDescs of typeGTMOSAID + // taking script results and turning them into AEDescs of typeGTMOSAID // instead of typeScript. desc = [self descForScriptID:valueID component:component]; if (desc) { @@ -511,51 +529,51 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); SEL extractor; id key; } errMap[] = { - { - kOSAErrorNumber, - typeSInt16, - @selector(gtm_numberValue), - NSAppleScriptErrorNumber + { + kOSAErrorNumber, + typeSInt16, + @selector(gtm_numberValue), + NSAppleScriptErrorNumber }, { - kOSAErrorMessage, - typeText, - @selector(stringValue), + kOSAErrorMessage, + typeText, + @selector(stringValue), NSAppleScriptErrorMessage }, - { - kOSAErrorBriefMessage, - typeText, - @selector(stringValue), + { + kOSAErrorBriefMessage, + typeText, + @selector(stringValue), NSAppleScriptErrorBriefMessage }, - { kOSAErrorApp, - typeText, - @selector(stringValue), - NSAppleScriptErrorAppName + { kOSAErrorApp, + typeText, + @selector(stringValue), + NSAppleScriptErrorAppName }, - { kOSAErrorRange, - typeOSAErrorRange, - @selector(gtm_OSAErrorRangeValue), + { kOSAErrorRange, + typeOSAErrorRange, + @selector(gtm_OSAErrorRangeValue), NSAppleScriptErrorRange }, - { - kOSAErrorPartialResult, - typeBest, - @selector(gtm_objectValue), - GTMNSAppleScriptErrorPartialResult + { + kOSAErrorPartialResult, + typeBest, + @selector(gtm_objectValue), + GTMNSAppleScriptErrorPartialResult }, - { - kOSAErrorOffendingObject, - typeBest, - @selector(gtm_objectValue), - GTMNSAppleScriptErrorOffendingObject + { + kOSAErrorOffendingObject, + typeBest, + @selector(gtm_objectValue), + GTMNSAppleScriptErrorOffendingObject }, - { - kOSAErrorExpectedType, - typeType, - @selector(gtm_fourCharCodeValue), - GTMNSAppleScriptErrorExpectedType + { + kOSAErrorExpectedType, + typeType, + @selector(gtm_fourCharCodeValue), + GTMNSAppleScriptErrorExpectedType }, }; for (size_t i = 0; i < sizeof(errMap) / sizeof(errMap[0]); ++i) { @@ -563,9 +581,9 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); OSStatus err = OSAScriptError(component, errMap[i].selector, errMap[i].desiredType, - &errorResult); + &errorResult); if (err == noErr) { - NSAppleEventDescriptor *desc = [[[NSAppleEventDescriptor alloc] + NSAppleEventDescriptor *desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&errorResult] autorelease]; id value = [desc performSelector:errMap[i].extractor]; if (value) { @@ -576,10 +594,10 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); } else if (status != noErr) { // Unknown error. Do our best to give the user something good. NSNumber *errNum = [NSNumber numberWithInt:status]; - error - = [NSMutableDictionary dictionaryWithObject:errNum + error + = [NSMutableDictionary dictionaryWithObject:errNum forKey:NSAppleScriptErrorNumber]; - NSString *briefMessage + NSString *briefMessage = [NSString stringWithUTF8String:GetMacOSStatusErrorString(status)]; if (briefMessage) { [error setValue:briefMessage forKey:NSAppleScriptErrorBriefMessage]; @@ -594,30 +612,11 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); } @end -// Private methods for dealing with Scripts/Events and NSAppleEventDescriptors -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorScriptAdditions) - -// Return an NSAppleScript for a desc of typeScript. This will create a new -// Applescript that is a copy of the script that you want. -// Returns nil on failure. -- (NSAppleScript*)gtm_scriptValue; - -// Return an NSAppleScript for a desc of typeGTMOSAID. This will not copy the -// script, but will create an NSAppleScript wrapping the script represented -// by the OSAID. -// Returns nil on failure. -- (NSAppleScript*)gtm_osaIDValue; - -// Return a NSString with [eventClass][eventID] for typeEvent 'evnt' -- (NSString*)gtm_eventValue; -@end - - @implementation NSAppleEventDescriptor (GMAppleEventDescriptorScriptAdditions) - (NSAppleScript*)gtm_scriptValue { NSDictionary *error; - NSAppleScript *script = [[[NSAppleScript alloc] _initWithData:[self data] + NSAppleScript *script = [[[NSAppleScript alloc] _initWithData:[self data] error:&error] autorelease]; if (!script) { _GTMDevLog(@"Unable to create script: %@", error); // COV_NF_LINE @@ -637,7 +636,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); AEEventID eventID; }; NSData *data = [self data]; - const struct AEEventRecordStruct *record + const struct AEEventRecordStruct *record = (const struct AEEventRecordStruct*)[data bytes]; NSString *eClass = [GTMFourCharCode stringWithFourCharCode:record->eventClass]; NSString *eID = [GTMFourCharCode stringWithFourCharCode:record->eventID]; @@ -661,4 +660,4 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); } @end - + diff --git a/Foundation/GTMNSArray+MergeTest.m b/Foundation/GTMNSArray+MergeTest.m index 0d8eb81..9148ba7 100644 --- a/Foundation/GTMNSArray+MergeTest.m +++ b/Foundation/GTMNSArray+MergeTest.m @@ -6,13 +6,13 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations +// License for the specific language governing permissions and limitations // under the License. // @@ -65,7 +65,7 @@ NSArray *nilArrayB = nil; NSArray *mergedArray = [emptyArrayA gtm_mergeArray:nilArrayB - mergeSelector:@selector(mergeObject:)]; + mergeSelector:@selector(mergeString:)]; STAssertNil(mergedArray, @"merge of empty with nil array with merger should render nil"); } @@ -179,7 +179,7 @@ STAssertNotNil(arrayB, nil); STAssertNotNil(expected, nil); NSArray *mergedArray; - + // no merger mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:nil]; @@ -197,13 +197,13 @@ mergeSelector:nil]; STAssertNotNil(mergedArray, nil); STAssertEqualObjects(mergedArray, expected, nil); - + // w/ merger and array args reversed mergedArray = [arrayB gtm_mergeArray:arrayA mergeSelector:@selector(mergeString:)]; STAssertNotNil(mergedArray, nil); STAssertEqualObjects(mergedArray, expected, nil); - + } @end diff --git a/Foundation/GTMNSObject+KeyValueObserving.m b/Foundation/GTMNSObject+KeyValueObserving.m index 9b9acce..3fdc24e 100644 --- a/Foundation/GTMNSObject+KeyValueObserving.m +++ b/Foundation/GTMNSObject+KeyValueObserving.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -23,7 +23,7 @@ // Created by Michael Ash on 10/15/08. // -// This code is based on code by Michael Ash. +// This code is based on code by Michael Ash. // See comment in header. #import "GTMDefines.h" #import "GTMNSObject+KeyValueObserving.h" @@ -32,9 +32,9 @@ #import "GTMObjC2Runtime.h" #import "GTMMethodCheck.h" -// A singleton that works as a dispatch center for KVO +// A singleton that works as a dispatch center for KVO // -[NSObject observeValueForKeyPath:ofObject:change:context:] and turns them -// into selector dispatches. It stores a collection of +// into selector dispatches. It stores a collection of // GTMKeyValueObservingHelpers, and keys them via the key generated by // -dictionaryKeyForObserver:ofObject:forKeyPath:selector. @interface GTMKeyValueObservingCenter : NSObject { @@ -44,19 +44,19 @@ + (id)defaultCenter; -- (void)addObserver:(id)observer - ofObject:(id)target - forKeyPath:(NSString *)keyPath - selector:(SEL)selector - userInfo:(id)userInfo +- (void)addObserver:(id)observer + ofObject:(id)target + forKeyPath:(NSString *)keyPath + selector:(SEL)selector + userInfo:(id)userInfo options:(NSKeyValueObservingOptions)options; -- (void)removeObserver:(id)observer - ofObject:(id)target - forKeyPath:(NSString *)keyPath +- (void)removeObserver:(id)observer + ofObject:(id)target + forKeyPath:(NSString *)keyPath selector:(SEL)selector; -- (id)dictionaryKeyForObserver:(id)observer - ofObject:(id)target - forKeyPath:(NSString *)keyPath +- (id)dictionaryKeyForObserver:(id)observer + ofObject:(id)target + forKeyPath:(NSString *)keyPath selector:(SEL)selector; @end @@ -69,43 +69,43 @@ NSString* keyPath_; } -- (id)initWithObserver:(id)observer - object:(id)target - keyPath:(NSString *)keyPath - selector:(SEL)selector - userInfo:(id)userInfo +- (id)initWithObserver:(id)observer + object:(id)target + keyPath:(NSString *)keyPath + selector:(SEL)selector + userInfo:(id)userInfo options:(NSKeyValueObservingOptions)options; - (void)deregister; @end @interface GTMKeyValueChangeNotification () -- (id)initWithKeyPath:(NSString *)keyPath ofObject:(id)object +- (id)initWithKeyPath:(NSString *)keyPath ofObject:(id)object userInfo:(id)userInfo change:(NSDictionary *)change; @end @implementation GTMKeyValueObservingHelper -// For info how and why we use these statics: +// For info how and why we use these statics: // http://lists.apple.com/archives/cocoa-dev/2006/Jul/msg01038.html static char GTMKeyValueObservingHelperContextData; -static char* GTMKeyValueObservingHelperContext +static char* GTMKeyValueObservingHelperContext = >MKeyValueObservingHelperContextData; -- (id)initWithObserver:(id)observer - object:(id)target - keyPath:(NSString *)keyPath - selector:(SEL)selector +- (id)initWithObserver:(id)observer + object:(id)target + keyPath:(NSString *)keyPath + selector:(SEL)selector userInfo:(id)userInfo options:(NSKeyValueObservingOptions)options { if((self = [super init])) { observer_ = observer; selector_ = selector; userInfo_ = [userInfo retain]; - + target_ = target; keyPath_ = [keyPath retain]; - + [target addObserver:self forKeyPath:keyPath options:options @@ -116,8 +116,8 @@ static char* GTMKeyValueObservingHelperContext - (NSString *)description { return [NSString stringWithFormat: - @"%@ ", - [self class], observer_, keyPath_, target_, + @"%@ ", + [self class], observer_, keyPath_, target_, NSStringFromSelector(selector_)]; } @@ -143,15 +143,15 @@ static char* GTMKeyValueObservingHelperContext [super dealloc]; } -- (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change context:(void *)context { if(context == GTMKeyValueObservingHelperContext) { - GTMKeyValueChangeNotification *notification + GTMKeyValueChangeNotification *notification = [[GTMKeyValueChangeNotification alloc] initWithKeyPath:keyPath - ofObject:object - userInfo:userInfo_ + ofObject:object + userInfo:userInfo_ change:change]; [observer_ performSelector:selector_ withObject:notification]; [notification release]; @@ -159,9 +159,9 @@ static char* GTMKeyValueObservingHelperContext // COV_NF_START // There's no way this should ever be called. // If it is, the call will go up to NSObject which will assert. - [super observeValueForKeyPath:keyPath - ofObject:object - change:change + [super observeValueForKeyPath:keyPath + ofObject:object + change:change context:context]; // COV_NF_END } @@ -184,8 +184,8 @@ static char* GTMKeyValueObservingHelperContext // and the other will set things up so that the failing thread // gets the shared center GTMKeyValueObservingCenter *newCenter = [[self alloc] init]; - if(!objc_atomicCompareAndSwapGlobalBarrier(nil, - newCenter, + if(!objc_atomicCompareAndSwapGlobalBarrier(nil, + newCenter, (void *)¢er)) { [newCenter release]; // COV_NF_LINE no guarantee we'll hit this line } @@ -208,41 +208,41 @@ static char* GTMKeyValueObservingHelperContext } // COV_NF_END -- (id)dictionaryKeyForObserver:(id)observer - ofObject:(id)target - forKeyPath:(NSString *)keyPath +- (id)dictionaryKeyForObserver:(id)observer + ofObject:(id)target + forKeyPath:(NSString *)keyPath selector:(SEL)selector { NSString *key = nil; if (!target && !keyPath && !selector) { key = [NSString stringWithFormat:@"%p:", observer]; } else { - key = [NSString stringWithFormat:@"%p:%@:%p:%p", + key = [NSString stringWithFormat:@"%p:%@:%p:%p", observer, keyPath, selector, target]; } return key; } -- (void)addObserver:(id)observer - ofObject:(id)target - forKeyPath:(NSString *)keyPath +- (void)addObserver:(id)observer + ofObject:(id)target + forKeyPath:(NSString *)keyPath selector:(SEL)selector - userInfo:(id)userInfo + userInfo:(id)userInfo options:(NSKeyValueObservingOptions)options { - GTMKeyValueObservingHelper *helper - = [[GTMKeyValueObservingHelper alloc] initWithObserver:observer - object:target - keyPath:keyPath - selector:selector - userInfo:userInfo + GTMKeyValueObservingHelper *helper + = [[GTMKeyValueObservingHelper alloc] initWithObserver:observer + object:target + keyPath:keyPath + selector:selector + userInfo:userInfo options:options]; - id key = [self dictionaryKeyForObserver:observer - ofObject:target - forKeyPath:keyPath + id key = [self dictionaryKeyForObserver:observer + ofObject:target + forKeyPath:keyPath selector:selector]; @synchronized(self) { GTMKeyValueObservingHelper *oldHelper = [observerHelpers_ objectForKey:key]; if (oldHelper) { - _GTMDevLog(@"%@ already observing %@ forKeyPath %@", + _GTMDevLog(@"%@ already observing %@ forKeyPath %@", observer, target, keyPath); [oldHelper deregister]; } @@ -251,18 +251,18 @@ static char* GTMKeyValueObservingHelperContext [helper release]; } -- (void)removeObserver:(id)observer - ofObject:(id)target - forKeyPath:(NSString *)keyPath +- (void)removeObserver:(id)observer + ofObject:(id)target + forKeyPath:(NSString *)keyPath selector:(SEL)selector { - id key = [self dictionaryKeyForObserver:observer + id key = [self dictionaryKeyForObserver:observer ofObject:target - forKeyPath:keyPath + forKeyPath:keyPath selector:selector]; NSMutableArray *allValidHelperKeys = [NSMutableArray array]; NSArray *allValidHelpers = nil; @synchronized(self) { - + NSString *helperKey; GTM_FOREACH_OBJECT(helperKey, [observerHelpers_ allKeys]) { if ([helperKey hasPrefix:key]) { @@ -271,11 +271,11 @@ static char* GTMKeyValueObservingHelperContext } #if DEBUG if ([allValidHelperKeys count] == 0) { - _GTMDevLog(@"%@ was not observing %@ with keypath %@", + _GTMDevLog(@"%@ was not observing %@ with keypath %@", observer, target, keyPath); } #endif // DEBUG - allValidHelpers = [observerHelpers_ objectsForKeys:allValidHelperKeys + allValidHelpers = [observerHelpers_ objectsForKeys:allValidHelperKeys notFoundMarker:[NSNull null]]; [observerHelpers_ removeObjectsForKeys:allValidHelperKeys]; } @@ -286,61 +286,61 @@ static char* GTMKeyValueObservingHelperContext @implementation NSObject (GTMKeyValueObservingAdditions) -- (void)gtm_addObserver:(id)observer - forKeyPath:(NSString *)keyPath - selector:(SEL)selector - userInfo:(id)userInfo +- (void)gtm_addObserver:(id)observer + forKeyPath:(NSString *)keyPath + selector:(SEL)selector + userInfo:(id)userInfo options:(NSKeyValueObservingOptions)options { - _GTMDevAssert(observer && [keyPath length] && selector, + _GTMDevAssert(observer && [keyPath length] && selector, @"Missing observer, keyPath, or selector"); - GTMKeyValueObservingCenter *center + GTMKeyValueObservingCenter *center = [GTMKeyValueObservingCenter defaultCenter]; GTMAssertSelectorNilOrImplementedWithArguments( observer, - selector, - @encode(GTMKeyValueChangeNotification *), + selector, + @encode(GTMKeyValueChangeNotification *), NULL); - [center addObserver:observer - ofObject:self - forKeyPath:keyPath - selector:selector - userInfo:userInfo + [center addObserver:observer + ofObject:self + forKeyPath:keyPath + selector:selector + userInfo:userInfo options:options]; } -- (void)gtm_removeObserver:(id)observer - forKeyPath:(NSString *)keyPath +- (void)gtm_removeObserver:(id)observer + forKeyPath:(NSString *)keyPath selector:(SEL)selector { - _GTMDevAssert(observer && [keyPath length] && selector, + _GTMDevAssert(observer && [keyPath length] && selector, @"Missing observer, keyPath, or selector"); - GTMKeyValueObservingCenter *center + GTMKeyValueObservingCenter *center = [GTMKeyValueObservingCenter defaultCenter]; GTMAssertSelectorNilOrImplementedWithArguments( observer, - selector, - @encode(GTMKeyValueChangeNotification *), - NULL); - [center removeObserver:observer - ofObject:self - forKeyPath:keyPath + selector, + @encode(GTMKeyValueChangeNotification *), + NULL); + [center removeObserver:observer + ofObject:self + forKeyPath:keyPath selector:selector]; } - (void)gtm_stopObservingAllKeyPaths { - GTMKeyValueObservingCenter *center + GTMKeyValueObservingCenter *center = [GTMKeyValueObservingCenter defaultCenter]; - [center removeObserver:self - ofObject:nil - forKeyPath:nil + [center removeObserver:self + ofObject:nil + forKeyPath:nil selector:Nil]; -} +} @end @implementation GTMKeyValueChangeNotification -- (id)initWithKeyPath:(NSString *)keyPath ofObject:(id)object +- (id)initWithKeyPath:(NSString *)keyPath ofObject:(id)object userInfo:(id)userInfo change:(NSDictionary *)change { if ((self = [super init])) { keyPath_ = [keyPath copy]; @@ -360,9 +360,9 @@ static char* GTMKeyValueObservingHelperContext } - (id)copyWithZone:(NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithKeyPath:keyPath_ + return [[[self class] allocWithZone:zone] initWithKeyPath:keyPath_ ofObject:object_ - userInfo:userInfo_ + userInfo:userInfo_ change:change_]; } @@ -375,7 +375,7 @@ static char* GTMKeyValueObservingHelperContext - (NSString *)description { return [NSString stringWithFormat: - @"%@ ", + @"%@ ", [self class], object_, keyPath_, userInfo_, change_]; } @@ -432,8 +432,8 @@ static void SwizzleClassMethodsInClass(Class cls, SEL sel1, SEL sel2) { // // Debugs // Debugs are mainly for logging all the KVO/KVC that is occurring in your -// application. To enable our KVO debugging, set the GTMDebugKVO environment -// variable to 1 and you will get a whole pile of KVO logging that may help you +// application. To enable our KVO debugging, set the GTMDebugKVO environment +// variable to 1 and you will get a whole pile of KVO logging that may help you // track down problems. // bash - export GTMDebugKVO=1 // csh/tcsh - setenv GTMDebugKVO 1 @@ -452,20 +452,51 @@ static void SwizzleClassMethodsInClass(Class cls, SEL sel1, SEL sel2) { // may never see the bug until it's too late. We try to force KVO issues to // rear their head at the time of the observing if at all possible. // Checks are on by default in debug builds. They can be turned off by defining -// the compile flag GTM_PERFORM_KVO_CHECKS to 0 -// i.e. #define GTM_PERFORM_KVO_CHECKS 0, or set it +// the compile flag GTM_PERFORM_KVO_CHECKS to 0 +// i.e. #define GTM_PERFORM_KVO_CHECKS 0, or set it // in GCC_PREPROCESSOR_DEFINITIONS. // // Checks work at a couple of different levels. -// The most restrictive of the checks is that we set +// The most restrictive of the checks is that we set // |accessInstanceVariablesDirectly| to NO by default. This means that if you // attempt to perform KVO on an instance variable, you will get an exception // thrown. -// Also, when adding an observer, we check to see if any member of the path -// starts or ends with _ which by convention denotes an instance variable. If so +// Also, when adding an observer, we check to see if any member of the path +// starts or ends with _ which by convention denotes an instance variable. If so // we warn you about attempting to access a ivar directly. @interface NSObject (GTMDebugKeyValueObserving) +- (void)_gtmDebugAddObserver:(NSObject *)observer + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context; +- (void)_gtmDebugArrayAddObserver:(NSObject *)observer + toObjectsAtIndexes:(NSIndexSet *)indexes + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context; +- (void)_gtmDebugRemoveObserver:(NSObject *)observer + forKeyPath:(NSString *)keyPath; +- (void)_gtmDebugArrayRemoveObserver:(NSObject *)observer + fromObjectsAtIndexes:(NSIndexSet *)indexes + forKeyPath:(NSString *)keyPath; +- (void)_gtmDebugWillChangeValueForKey:(NSString*)key; +- (void)_gtmDebugDidChangeValueForKey:(NSString*)key; + +#if GTM_PERFORM_KVO_CHECKS + +- (void)_gtmCheckAddObserver:(NSObject *)observer + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context; +- (void)_gtmCheckAddObserver:(NSObject *)observer + toObjectsAtIndexes:(NSIndexSet *)indexes + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context; ++ (BOOL)_gtmAccessInstanceVariablesDirectly; + +#endif // GTM_PERFORM_KVO_CHECKS @end @implementation NSObject (GTMDebugKeyValueObserving) @@ -473,18 +504,18 @@ GTM_METHOD_CHECK(NSObject, _gtmDebugAddObserver:forKeyPath:options:context:); GTM_METHOD_CHECK(NSObject, _gtmDebugRemoveObserver:forKeyPath:); GTM_METHOD_CHECK(NSObject, _gtmDebugWillChangeValueForKey:); GTM_METHOD_CHECK(NSObject, _gtmDebugDidChangeValueForKey:); -GTM_METHOD_CHECK(NSArray, +GTM_METHOD_CHECK(NSArray, _gtmDebugArrayAddObserver:toObjectsAtIndexes:forKeyPath:options:context:); -GTM_METHOD_CHECK(NSArray, +GTM_METHOD_CHECK(NSArray, _gtmDebugArrayRemoveObserver:fromObjectsAtIndexes:forKeyPath:); #if GTM_PERFORM_KVO_CHECKS -GTM_METHOD_CHECK(NSObject, +GTM_METHOD_CHECK(NSObject, _gtmCheckAddObserver:forKeyPath:options:context:); -GTM_METHOD_CHECK(NSArray, +GTM_METHOD_CHECK(NSArray, _gtmCheckAddObserver:toObjectsAtIndexes:forKeyPath:options:context:); -GTM_METHOD_CHECK(NSObject, +GTM_METHOD_CHECK(NSObject, _gtmAccessInstanceVariablesDirectly); #endif // GTM_PERFORM_KVO_CHECKS @@ -503,23 +534,23 @@ GTM_METHOD_CHECK(NSObject, Class cls = Nil; if (debug) { cls = [NSObject class]; - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(addObserver:forKeyPath:options:context:), @selector(_gtmDebugAddObserver:forKeyPath:options:context:)); - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(removeObserver:forKeyPath:), @selector(_gtmDebugRemoveObserver:forKeyPath:)); - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(willChangeValueForKey:), @selector(_gtmDebugWillChangeValueForKey:)); - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(didChangeValueForKey:), @selector(_gtmDebugDidChangeValueForKey:)); cls = [NSArray class]; - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(addObserver:toObjectsAtIndexes:forKeyPath:options:context:), @selector(_gtmDebugArrayAddObserver:toObjectsAtIndexes:forKeyPath:options:context:)); - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(removeObserver:fromObjectsAtIndexes:forKeyPath:), @selector(_gtmDebugArrayRemoveObserver:fromObjectsAtIndexes:forKeyPath:)); } @@ -527,55 +558,55 @@ GTM_METHOD_CHECK(NSObject, cls = [NSObject class]; SwizzleMethodsInClass(cls, @selector(addObserver:forKeyPath:options:context:), - @selector(_gtmCheckAddObserver:forKeyPath:options:context:)); - SwizzleClassMethodsInClass(cls, - @selector(accessInstanceVariablesDirectly), + @selector(_gtmCheckAddObserver:forKeyPath:options:context:)); + SwizzleClassMethodsInClass(cls, + @selector(accessInstanceVariablesDirectly), @selector(_gtmAccessInstanceVariablesDirectly)); cls = [NSArray class]; - SwizzleMethodsInClass(cls, + SwizzleMethodsInClass(cls, @selector(addObserver:toObjectsAtIndexes:forKeyPath:options:context:), @selector(_gtmCheckAddObserver:toObjectsAtIndexes:forKeyPath:options:context:)); - + #endif // GTM_PERFORM_KVO_CHECKS [pool release]; } -- (void)_gtmDebugAddObserver:(NSObject *)observer - forKeyPath:(NSString *)keyPath +- (void)_gtmDebugAddObserver:(NSObject *)observer + forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context { _GTMDevLog(@"Adding observer %@ to %@ keypath '%@'", observer, self, keyPath); - [self _gtmDebugAddObserver:observer forKeyPath:keyPath + [self _gtmDebugAddObserver:observer forKeyPath:keyPath options:options context:context]; } - (void)_gtmDebugArrayAddObserver:(NSObject *)observer toObjectsAtIndexes:(NSIndexSet *)indexes - forKeyPath:(NSString *)keyPath + forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context { - _GTMDevLog(@"Array adding observer %@ to indexes %@ of %@ keypath '%@'", + _GTMDevLog(@"Array adding observer %@ to indexes %@ of %@ keypath '%@'", observer, indexes, self, keyPath); - [self _gtmDebugArrayAddObserver:observer + [self _gtmDebugArrayAddObserver:observer toObjectsAtIndexes:indexes - forKeyPath:keyPath + forKeyPath:keyPath options:options context:context]; } - (void)_gtmDebugRemoveObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath { - _GTMDevLog(@"Removing observer %@ from %@ keypath '%@'", + _GTMDevLog(@"Removing observer %@ from %@ keypath '%@'", observer, self, keyPath); [self _gtmDebugRemoveObserver:observer forKeyPath:keyPath]; } -- (void)_gtmDebugArrayRemoveObserver:(NSObject *)observer +- (void)_gtmDebugArrayRemoveObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath { - _GTMDevLog(@"Array removing observer %@ from indexes %@ of %@ keypath '%@'", + _GTMDevLog(@"Array removing observer %@ from indexes %@ of %@ keypath '%@'", indexes, observer, self, keyPath); - [self _gtmDebugArrayRemoveObserver:observer - fromObjectsAtIndexes:indexes + [self _gtmDebugArrayRemoveObserver:observer + fromObjectsAtIndexes:indexes forKeyPath:keyPath]; } @@ -605,9 +636,9 @@ GTM_METHOD_CHECK(NSObject, keyPath); } } - [self _gtmCheckAddObserver:observer - forKeyPath:keyPath - options:options + [self _gtmCheckAddObserver:observer + forKeyPath:keyPath + options:options context:context]; } @@ -628,8 +659,8 @@ GTM_METHOD_CHECK(NSObject, } [self _gtmCheckAddObserver:observer toObjectsAtIndexes:indexes - forKeyPath:keyPath - options:options + forKeyPath:keyPath + options:options context:context]; } @@ -637,7 +668,7 @@ GTM_METHOD_CHECK(NSObject, + (BOOL)_gtmAccessInstanceVariablesDirectly { // Apple has lots of "bad" direct instance variable accesses, so we // only want to check our code, as opposed to library code. - + // If this turns out to be slow, we may want to consider a cache to speed // things up. NSBundle *bundle = [NSBundle bundleForClass:self]; diff --git a/Foundation/GTMNSObject+KeyValueObservingTest.m b/Foundation/GTMNSObject+KeyValueObservingTest.m index d49118a..f37f1b4 100644 --- a/Foundation/GTMNSObject+KeyValueObservingTest.m +++ b/Foundation/GTMNSObject+KeyValueObservingTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -23,7 +23,7 @@ // Created by Michael Ash on 10/15/08. // -// This code is based on code by Michael Ash. +// This code is based on code by Michael Ash. // See comment in header. #import "GTMSenTestCase.h" @@ -36,6 +36,9 @@ NSMutableDictionary *dict_; __weak NSString *expectedValue_; } + +- (void)observeValueChange:(GTMKeyValueChangeNotification *)notification; + @end @implementation GTMNSObject_KeyValueObservingTest @@ -51,16 +54,16 @@ - (void)testSingleChange { count_ = 0; - [dict_ gtm_addObserver:self - forKeyPath:@"key" - selector:@selector(observeValueChange:) - userInfo:@"userInfo" + [dict_ gtm_addObserver:self + forKeyPath:@"key" + selector:@selector(observeValueChange:) + userInfo:@"userInfo" options:NSKeyValueObservingOptionNew]; expectedValue_ = @"bar"; [dict_ setObject:expectedValue_ forKey:@"key"]; STAssertEquals(count_, (int32_t)1, nil); - [dict_ gtm_removeObserver:self - forKeyPath:@"key" + [dict_ gtm_removeObserver:self + forKeyPath:@"key" selector:@selector(observeValueChange:)]; [dict_ setObject:@"foo" forKey:@"key"]; STAssertEquals(count_, (int32_t)1, nil); @@ -68,10 +71,10 @@ - (void)testStopObservingAllKeyPaths { count_ = 0; - [dict_ gtm_addObserver:self - forKeyPath:@"key" - selector:@selector(observeValueChange:) - userInfo:@"userInfo" + [dict_ gtm_addObserver:self + forKeyPath:@"key" + selector:@selector(observeValueChange:) + userInfo:@"userInfo" options:NSKeyValueObservingOptionNew]; expectedValue_ = @"bar"; [dict_ setObject:expectedValue_ forKey:@"key"]; @@ -85,28 +88,28 @@ - (void)testRemoving { [GTMUnitTestDevLogDebug expectPattern:@"-\\[GTMNSObject_KeyValueObservingTest" @" testRemoving\\] was not observing.*"]; - - [dict_ gtm_removeObserver:self - forKeyPath:@"key" + + [dict_ gtm_removeObserver:self + forKeyPath:@"key" selector:@selector(observeValueChange:)]; } - (void)testAdding { - [dict_ gtm_addObserver:self - forKeyPath:@"key" - selector:@selector(observeValueChange:) - userInfo:@"userInfo" + [dict_ gtm_addObserver:self + forKeyPath:@"key" + selector:@selector(observeValueChange:) + userInfo:@"userInfo" options:NSKeyValueObservingOptionNew]; [GTMUnitTestDevLog expectPattern:@"-\\[GTMNSObject_KeyValueObservingTest" @" testAdding\\] already observing.*"]; - [dict_ gtm_addObserver:self - forKeyPath:@"key" - selector:@selector(observeValueChange:) - userInfo:@"userInfo" + [dict_ gtm_addObserver:self + forKeyPath:@"key" + selector:@selector(observeValueChange:) + userInfo:@"userInfo" options:NSKeyValueObservingOptionNew]; - [dict_ gtm_removeObserver:self - forKeyPath:@"key" - selector:@selector(observeValueChange:)]; + [dict_ gtm_removeObserver:self + forKeyPath:@"key" + selector:@selector(observeValueChange:)]; } - (void)observeValueChange:(GTMKeyValueChangeNotification *)notification { @@ -117,7 +120,7 @@ NSString *value = [change objectForKey:NSKeyValueChangeNewKey]; STAssertEqualObjects(value, expectedValue_, nil); ++count_; - + GTMKeyValueChangeNotification *copy = [[notification copy] autorelease]; STAssertEqualObjects(notification, copy, nil); STAssertEquals([notification hash], [copy hash], nil); @@ -146,15 +149,15 @@ value3_ = [NSArray arrayWithObject:@"foo"]; NSIndexSet *set = [NSIndexSet indexSetWithIndex:0]; [GTMUnitTestDevLogDebug expectPattern:@"warning:.*"]; - [value3_ addObserver:self toObjectsAtIndexes:set forKeyPath:@"_fronttest" + [value3_ addObserver:self toObjectsAtIndexes:set forKeyPath:@"_fronttest" options:0 context:NULL]; [GTMUnitTestDevLogDebug expectPattern:@"warning:.*"]; - [value3_ addObserver:self toObjectsAtIndexes:set forKeyPath:@"backtest_" + [value3_ addObserver:self toObjectsAtIndexes:set forKeyPath:@"backtest_" options:0 context:NULL]; #if DEBUG // Should only throw in debug STAssertThrows([self valueForKey:@"value_"], nil); -#else +#else STAssertNoThrow([self valueForKey:@"value_"], nil); #endif value4 = @"Hello"; diff --git a/Foundation/GTMObjC2RuntimeTest.m b/Foundation/GTMObjC2RuntimeTest.m index 360f931..27a9aa1 100644 --- a/Foundation/GTMObjC2RuntimeTest.m +++ b/Foundation/GTMObjC2RuntimeTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -74,6 +74,7 @@ AT_REQUIRED @end @interface GTMObjC2NotificationWatcher : NSObject +- (void)startedTest:(NSNotification *)notification; @end @implementation GTMObjC2NotificationWatcher @@ -82,18 +83,18 @@ AT_REQUIRED NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; // We release ourselves when we are notified. [self retain]; - [nc addObserver:self - selector:@selector(startedTest:) - name:SenTestSuiteDidStartNotification + [nc addObserver:self + selector:@selector(startedTest:) + name:SenTestSuiteDidStartNotification object:nil]; - + } return self; } - (void)startedTest:(NSNotification *)notification { // Logs if we are testing on Tiger or Leopard runtime. - SenTestSuiteRun *suiteRun = GTM_STATIC_CAST(SenTestSuiteRun, + SenTestSuiteRun *suiteRun = GTM_STATIC_CAST(SenTestSuiteRun, [notification object]); NSString *testName = [[suiteRun test] name]; NSString *className = NSStringFromClass([GTMObjC2RuntimeTest class]); @@ -156,8 +157,8 @@ AT_REQUIRED // STAssertFalse(class_conformsToProtocol(nil, nil), nil); // Standard use check - STAssertTrue(class_conformsToProtocol(cls_, - @protocol(GTMObjC2Runtime_TestProtocol)), + STAssertTrue(class_conformsToProtocol(cls_, + @protocol(GTMObjC2Runtime_TestProtocol)), nil); } @@ -165,9 +166,9 @@ AT_REQUIRED // Nil Checks STAssertFalse(class_respondsToSelector(cls_, @selector(setUp)), nil); STAssertFalse(class_respondsToSelector(cls_, nil), nil); - + // Standard use check - STAssertTrue(class_respondsToSelector(cls_, @selector(kwyjibo)), nil); + STAssertTrue(class_respondsToSelector(cls_, @selector(kwyjibo)), nil); } - (void)test_class_getSuperclass { @@ -193,10 +194,10 @@ AT_REQUIRED STAssertEquals(count, 2U, nil); STAssertNULL(list[count], nil); free(list); - + // Now test meta class count = 0; - list = class_copyMethodList((Class)objc_getMetaClass(class_getName(cls_)), + list = class_copyMethodList((Class)objc_getMetaClass(class_getName(cls_)), &count); STAssertNotNULL(list, nil); STAssertEquals(count, 2U, nil); @@ -236,7 +237,7 @@ AT_REQUIRED STAssertNotNil(val3, nil); NSString *val4 = [GTMObjC2Runtime_TestClass brokeHisBrain]; STAssertNotNil(val4, nil); - + // exchange the imps Method *list = class_copyMethodList(cls_, nil); STAssertNotNULL(list, nil); @@ -253,7 +254,7 @@ AT_REQUIRED // Check that other methods not affected STAssertEqualStrings([GTMObjC2Runtime_TestClass dontHaveACow], val3, nil); STAssertEqualStrings([GTMObjC2Runtime_TestClass brokeHisBrain], val4, nil); - + // exchange the imps back method_exchangeImplementations(list[0], list[1]); @@ -323,7 +324,7 @@ AT_REQUIRED STAssertNULL(nullImp, nil); IMP testImp = method_setImplementation(list[0], newImp); STAssertEquals(testImp, oldImp, nil); -#else +#else // Built for leopard or later means we get the os runtime behavior... if ([GTMSystemVersion isLeopard]) { // (takes nil) @@ -339,10 +340,10 @@ AT_REQUIRED STAssertEquals(testImp, oldImp, nil); } #endif - + // This case intentionally not tested. Passing nil to method_setImplementation // on Leopard crashes. It does on Tiger as well. Half works on SnowLeopard. - // We made our Tiger implementation the same as the SnowLeopard + // We made our Tiger implementation the same as the SnowLeopard // implementation. // Logged as radar 5572981. if (![GTMSystemVersion isLeopardOrGreater]) { @@ -353,14 +354,14 @@ AT_REQUIRED STAssertNULL(method_setImplementation(nil, newImp), nil); } #endif - + [test release]; free(list); } - (void)test_protocol_getMethodDescription { // Check nil cases - struct objc_method_description desc = protocol_getMethodDescription(nil, nil, + struct objc_method_description desc = protocol_getMethodDescription(nil, nil, YES, YES); STAssertNULL(desc.name, nil); desc = protocol_getMethodDescription(nil, @selector(optional), YES, YES); diff --git a/Foundation/GTMSignalHandlerTest.m b/Foundation/GTMSignalHandlerTest.m index 191d67f..f284860 100644 --- a/Foundation/GTMSignalHandlerTest.m +++ b/Foundation/GTMSignalHandlerTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -65,6 +65,9 @@ @end @implementation GTMSignalHandlerTest +- (void)nomnomnom:(int)blah { + STFail(@"Should never be called!"); +} - (void)testNillage { GTMSignalHandler *handler; @@ -76,7 +79,7 @@ STAssertNil(handler, nil); // Zero signal should return nil as well. - handler = [[[GTMSignalHandler alloc] + handler = [[[GTMSignalHandler alloc] initWithSignal:0 target:self action:@selector(nomnomnom:)] autorelease]; @@ -87,7 +90,7 @@ - (void)testSingleHandler { SignalCounter *counter = [SignalCounter signalCounter]; STAssertNotNil(counter, nil); - + GTMSignalHandler *handler = [[[GTMSignalHandler alloc] initWithSignal:SIGWINCH target:counter @@ -95,31 +98,31 @@ autorelease]; STAssertNotNil(handler, nil); raise(SIGWINCH); - + NSRunLoop *rl = [NSRunLoop currentRunLoop]; [rl gtm_runUpToSixtySecondsWithContext:counter]; STAssertEquals([counter count], 1, nil); STAssertEquals([counter lastSeen], SIGWINCH, nil); [counter resetShouldStop]; - + raise(SIGWINCH); [rl gtm_runUpToSixtySecondsWithContext:counter]; STAssertEquals([counter count], 2, nil); STAssertEquals([counter lastSeen], SIGWINCH, nil); [counter resetShouldStop]; - + // create a second one to make sure we're seding data where we want SignalCounter *counter2 = [SignalCounter signalCounter]; STAssertNotNil(counter2, nil); [[[GTMSignalHandler alloc] initWithSignal:SIGUSR1 target:counter2 action:@selector(countSignal:)] autorelease]; - + raise(SIGUSR1); [rl gtm_runUpToSixtySecondsWithContext:counter2]; - + STAssertEquals([counter count], 2, nil); STAssertEquals([counter lastSeen], SIGWINCH, nil); STAssertEquals([counter2 count], 1, nil); @@ -131,7 +134,7 @@ // the handler method should not get called. raise(SIGWINCH); [rl runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.2]]; - + STAssertEquals([counter count], 2, nil); STAssertEquals([counter lastSeen], SIGWINCH, nil); STAssertEquals([counter2 count], 1, nil); diff --git a/Foundation/GTMTransientRootProxy.m b/Foundation/GTMTransientRootProxy.m index 3d34bda..2f7dfec 100644 --- a/Foundation/GTMTransientRootProxy.m +++ b/Foundation/GTMTransientRootProxy.m @@ -29,7 +29,7 @@ @interface GTMTransientRootProxy (PrivateMethods) // Returns an NSConnection for NSMacPorts. This method is broken out to allow -// subclasses to override it to generate different types of NSConnections. +// subclasses to override it to generate different types of NSConnections. - (NSConnection *)makeConnection; // Returns the "real" proxy (stored in the realProxy_ ivar) associated with this @@ -42,6 +42,9 @@ // the NSNotificationCenter. // - (void)releaseRealProxy; + +// Notification that a connection has died. +- (void)connectionDidDie:(NSNotification *)notification; @end @implementation GTMTransientRootProxy @@ -124,12 +127,12 @@ // We need to catch NSException* here rather than "id" because we need to // treat |ex| as an NSException when using the -name method. Also, we're - // only looking to catch a few types of exception here, all of which are + // only looking to catch a few types of exception here, all of which are // NSException types; the rest we just rethrow. } @catch (NSException *ex) { NSString *exName = [ex name]; // If we catch an exception who's name matches any of the following types, - // it's because the DO connection probably went down. So, we'll just + // it's because the DO connection probably went down. So, we'll just // release our realProxy_, and attempt to reconnect on the next call. if ([exName isEqualToString:NSPortTimeoutException] || [exName isEqualToString:NSInvalidSendPortException] @@ -168,7 +171,7 @@ // Try to get the root proxy for this connection's vended object. realProxy_ = [conn rootProxy]; } @catch (id ex) { - // We may fail here if we can't get the root proxy in the amount of time + // We may fail here if we can't get the root proxy in the amount of time // specified by the timeout above. This may happen, for example, if the // server process is stopped (via SIGSTOP). We'll just ignore this, and // try again at the next message. diff --git a/GTMiPhone.xcodeproj/project.pbxproj b/GTMiPhone.xcodeproj/project.pbxproj index 42e0ec4..b8af71c 100644 --- a/GTMiPhone.xcodeproj/project.pbxproj +++ b/GTMiPhone.xcodeproj/project.pbxproj @@ -72,6 +72,8 @@ 8B6C18750F3769D200E51E5D /* GTMNSObject+KeyValueObservingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B6C18730F3769D200E51E5D /* GTMNSObject+KeyValueObservingTest.m */; }; 8B7DCEAA0DFF4C760017E983 /* GTMDevLogUnitTestingBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7DCEA90DFF4C760017E983 /* GTMDevLogUnitTestingBridge.m */; }; 8B7DCEAD0DFF4CA60017E983 /* GTMUnitTestDevLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7DCEAC0DFF4CA60017E983 /* GTMUnitTestDevLog.m */; }; + 8BB78FA911B94D9500AB31AF /* GTMGoogleSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BB78FA711B94D9500AB31AF /* GTMGoogleSearch.m */; }; + 8BB78FAA11B94D9500AB31AF /* GTMGoogleSearchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BB78FA811B94D9500AB31AF /* GTMGoogleSearchTest.m */; }; 8BC0480F0DAE928A00C2D1CA /* GTMCalculatedRange.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BC047780DAE928A00C2D1CA /* GTMCalculatedRange.m */; }; 8BC048100DAE928A00C2D1CA /* GTMCalculatedRangeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BC047790DAE928A00C2D1CA /* GTMCalculatedRangeTest.m */; }; 8BC048130DAE928A00C2D1CA /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BC0477F0DAE928A00C2D1CA /* GTMNSData+zlib.m */; }; @@ -103,8 +105,6 @@ 8BDA25140E759A6500C9769D /* GTMNSData+zlibTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BC047800DAE928A00C2D1CA /* GTMNSData+zlibTest.m */; }; 8BE839890E89C74B00C611B0 /* GTMDebugThreadValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BE839870E89C74A00C611B0 /* GTMDebugThreadValidation.m */; }; 8BE83A660E8B059A00C611B0 /* GTMDebugThreadValidationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BE83A650E8B059A00C611B0 /* GTMDebugThreadValidationTest.m */; }; - 8BF4D4180FC74998009ABC3F /* GTMGoogleSearchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF4D3E20FC72A46009ABC3F /* GTMGoogleSearchTest.m */; }; - 8BF4D4190FC7499D009ABC3F /* GTMGoogleSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF4D3E10FC72A46009ABC3F /* GTMGoogleSearch.m */; }; 8BFE15C60FB0F764001BE894 /* GTMABAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BFE15C10FB0F764001BE894 /* GTMABAddressBook.m */; }; 8BFE15C70FB0F764001BE894 /* GTMABAddressBook.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8BFE15C20FB0F764001BE894 /* GTMABAddressBook.strings */; }; 8BFE15C80FB0F764001BE894 /* GTMABAddressBookTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BFE15C30FB0F764001BE894 /* GTMABAddressBookTest.m */; }; @@ -213,6 +213,9 @@ 8B7DCEA90DFF4C760017E983 /* GTMDevLogUnitTestingBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMDevLogUnitTestingBridge.m; sourceTree = ""; }; 8B7DCEAB0DFF4CA60017E983 /* GTMUnitTestDevLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMUnitTestDevLog.h; sourceTree = ""; }; 8B7DCEAC0DFF4CA60017E983 /* GTMUnitTestDevLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMUnitTestDevLog.m; sourceTree = ""; }; + 8BB78FA611B94D9500AB31AF /* GTMGoogleSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGoogleSearch.h; sourceTree = ""; }; + 8BB78FA711B94D9500AB31AF /* GTMGoogleSearch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMGoogleSearch.m; sourceTree = ""; }; + 8BB78FA811B94D9500AB31AF /* GTMGoogleSearchTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMGoogleSearchTest.m; sourceTree = ""; }; 8BC047750DAE926E00C2D1CA /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; 8BC047770DAE928A00C2D1CA /* GTMCalculatedRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMCalculatedRange.h; sourceTree = ""; }; 8BC047780DAE928A00C2D1CA /* GTMCalculatedRange.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMCalculatedRange.m; sourceTree = ""; }; @@ -267,9 +270,6 @@ 8BE839880E89C74A00C611B0 /* GTMDebugThreadValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDebugThreadValidation.h; sourceTree = ""; }; 8BE83A650E8B059A00C611B0 /* GTMDebugThreadValidationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMDebugThreadValidationTest.m; sourceTree = ""; }; 8BF2568E10F673D1000490C8 /* GTMTypeCasting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMTypeCasting.h; sourceTree = ""; }; - 8BF4D3E00FC72A46009ABC3F /* GTMGoogleSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGoogleSearch.h; sourceTree = ""; }; - 8BF4D3E10FC72A46009ABC3F /* GTMGoogleSearch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMGoogleSearch.m; sourceTree = ""; }; - 8BF4D3E20FC72A46009ABC3F /* GTMGoogleSearchTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMGoogleSearchTest.m; sourceTree = ""; }; 8BFE15C00FB0F764001BE894 /* GTMABAddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMABAddressBook.h; sourceTree = ""; }; 8BFE15C10FB0F764001BE894 /* GTMABAddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMABAddressBook.m; sourceTree = ""; }; 8BFE15C20FB0F764001BE894 /* GTMABAddressBook.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; path = GTMABAddressBook.strings; sourceTree = ""; }; @@ -357,9 +357,10 @@ 8BC04DE70DB023D400C2D1CA /* ReleaseNotes.txt */, 8BC047750DAE926E00C2D1CA /* GTMDefines.h */, 8BFE15BF0FB0F764001BE894 /* AddressBook */, - 8BA5F4060E75669000798036 /* iPhone */, - 8BC047760DAE928A00C2D1CA /* Foundation */, + 8BB78FA011B94D6C00AB31AF /* AppKit */, 8BC0479A0DAE928A00C2D1CA /* DebugUtils */, + 8BC047760DAE928A00C2D1CA /* Foundation */, + 8BA5F4060E75669000798036 /* iPhone */, 8BC0479F0DAE928A00C2D1CA /* UnitTesting */, 8BC049840DAEC59100C2D1CA /* XcodeConfig */, 29B97323FDCFA39411CA2CEA /* Frameworks */, @@ -428,6 +429,16 @@ path = iPhone; sourceTree = ""; }; + 8BB78FA011B94D6C00AB31AF /* AppKit */ = { + isa = PBXGroup; + children = ( + 8BB78FA611B94D9500AB31AF /* GTMGoogleSearch.h */, + 8BB78FA711B94D9500AB31AF /* GTMGoogleSearch.m */, + 8BB78FA811B94D9500AB31AF /* GTMGoogleSearchTest.m */, + ); + path = AppKit; + sourceTree = ""; + }; 8BC047760DAE928A00C2D1CA /* Foundation */ = { isa = PBXGroup; children = ( @@ -453,9 +464,6 @@ F439ADED0DBD3C4000BE9B91 /* GTMGeometryUtils.h */, F439ADEE0DBD3C4000BE9B91 /* GTMGeometryUtils.m */, F439ADEF0DBD3C4000BE9B91 /* GTMGeometryUtilsTest.m */, - 8BF4D3E00FC72A46009ABC3F /* GTMGoogleSearch.h */, - 8BF4D3E10FC72A46009ABC3F /* GTMGoogleSearch.m */, - 8BF4D3E20FC72A46009ABC3F /* GTMGoogleSearchTest.m */, 8B3AA91F0E033624007E31B5 /* GTMHTTPServer.h */, 8B3AA9200E033624007E31B5 /* GTMHTTPServer.m */, 8B3AA9210E033624007E31B5 /* GTMHTTPServerTest.m */, @@ -812,8 +820,6 @@ 8BFE15C80FB0F764001BE894 /* GTMABAddressBookTest.m in Sources */, 8BD35C920FB234E1009058F5 /* GTMNSScanner+JSON.m in Sources */, 8BD35C930FB234E1009058F5 /* GTMNSScanner+JSONTest.m in Sources */, - 8BF4D4180FC74998009ABC3F /* GTMGoogleSearchTest.m in Sources */, - 8BF4D4190FC7499D009ABC3F /* GTMGoogleSearch.m in Sources */, 64D0F5C80FD3E65C00506CC7 /* GTMUIImage+ResizeTest.m in Sources */, 64D0F5C90FD3E65C00506CC7 /* GTMUIImage+Resize.m in Sources */, 13C1ED4F104896C900907CD8 /* GTMUIView+SubtreeDescription.m in Sources */, @@ -824,6 +830,8 @@ 0B859DA2104D08160064FE46 /* GTMNSDictionary+CaseInsensitiveTest.m in Sources */, 0BBC768B10FEF62C0006FABE /* GTMStringEncoding.m in Sources */, 0BBC768C10FEF62C0006FABE /* GTMStringEncodingTest.m in Sources */, + 8BB78FA911B94D9500AB31AF /* GTMGoogleSearch.m in Sources */, + 8BB78FAA11B94D9500AB31AF /* GTMGoogleSearchTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -857,6 +865,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone3.1.3-Debug-gcov"; }; @@ -960,6 +969,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone3.2-Debug-gcov"; }; @@ -1063,6 +1073,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone2.0-Debug-gcov"; }; @@ -1166,6 +1177,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone2.1-Debug-gcov"; }; @@ -1258,6 +1270,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone2.2-Debug-gcov"; }; @@ -1372,6 +1385,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone2.2.1-Debug-gcov"; }; @@ -1475,6 +1489,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone3.0-Debug-gcov"; }; @@ -1578,6 +1593,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone3.1-Debug-gcov"; }; @@ -1681,6 +1697,7 @@ GCC_PREFIX_HEADER = GTM_Prefix.pch; GCC_WARN_SHADOW = YES; GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = "-Wno-unused-parameter"; + LIBRARY_SEARCH_PATHS = SnowLeopardGcov; }; name = "iPhone3.1.2-Debug-gcov"; }; diff --git a/SnowLeopardGcov/GTM_fdopen2003.c b/SnowLeopardGcov/GTM_fdopen2003.c new file mode 100644 index 0000000..6c21b25 --- /dev/null +++ b/SnowLeopardGcov/GTM_fdopen2003.c @@ -0,0 +1,28 @@ +// +// GTM_fdopen2003.c +// +// Copyright 2010 Google Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// + +// This file exists because when you build with your SDK set to 10.5 and +// and compiler version set to gcc 4.0 on using Xcode 3.2.2 on Snow Leopard +// you will receive a link error for missing the _fdopen$UNIX2003 symbol. +// See http://code.google.com/p/coverstory/wiki/SnowLeopardGCov +// for more details. + +#include + +FILE *fdopen$UNIX2003(int fildes, const char *mode) { + return fdopen(fildes, mode); +} diff --git a/UnitTesting/GTMIPhoneUnitTestDelegate.m b/UnitTesting/GTMIPhoneUnitTestDelegate.m index 9f2457d..dc4b182 100644 --- a/UnitTesting/GTMIPhoneUnitTestDelegate.m +++ b/UnitTesting/GTMIPhoneUnitTestDelegate.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -27,6 +27,13 @@ #import #import "GTMSenTestCase.h" +@interface UIApplication (GTMIPhoneUnitTestDelegate) + +// SPI that we need to exti cleanly with a value. +- (void)_terminateWithStatus:(int)status; + +@end + @implementation GTMIPhoneUnitTestDelegate // Run through all the registered classes and run test methods on any @@ -34,7 +41,7 @@ // test completion. - (void)applicationDidFinishLaunching:(UIApplication *)application { [self runTests]; - + if (!getenv("GTM_DISABLE_TERMINATION")) { // To help using xcodebuild, make the exit status 0/1 to signal the tests // success/failure. @@ -87,7 +94,7 @@ if ([invocations count]) { NSInvocation *invocation; GTM_FOREACH_OBJECT(invocation, invocations) { - GTMTestCase *testCase + GTMTestCase *testCase = [[currClass alloc] initWithInvocation:invocation]; BOOL failed = NO; NSDate *caseStartDate = [NSDate date]; @@ -128,14 +135,14 @@ @"Executed %d tests, with %d failures (%d " @"unexpected) in %0.3f (%0.3f) seconds\n\n", fixtureName, fixtureEndDate, - fixtureSuccesses + fixtureFailures, + fixtureSuccesses + fixtureFailures, fixtureFailures, fixtureFailures, fixtureEndTime, fixtureEndTime]; - + fputs([fixtureEndString UTF8String], stderr); fflush(stderr); totalSuccesses_ += fixtureSuccesses; - totalFailures_ += fixtureFailures; + totalFailures_ += fixtureFailures; } [pool release]; } @@ -147,7 +154,7 @@ @"Executed %d tests, with %d failures (%d " @"unexpected) in %0.3f (%0.3f) seconds\n\n", suiteName, suiteEndDate, - totalSuccesses_ + totalFailures_, + totalSuccesses_ + totalFailures_, totalFailures_, totalFailures_, suiteEndTime, suiteEndTime]; fputs([suiteEndString UTF8String], stderr); diff --git a/UnitTesting/GTMSenTestCase.m b/UnitTesting/GTMSenTestCase.m index e909294..a766717 100644 --- a/UnitTesting/GTMSenTestCase.m +++ b/UnitTesting/GTMSenTestCase.m @@ -19,6 +19,7 @@ #import "GTMSenTestCase.h" #import #import "GTMObjC2Runtime.h" +#import "GTMUnitTestDevLog.h" #if !GTM_IPHONE_SDK #import "GTMGarbageCollection.h" @@ -310,7 +311,7 @@ NSString *const SenTestLineNumberKey = @"SenTestLineNumberKey"; - (NSString *)description { // This matches the description OCUnit would return to you - return [NSString stringWithFormat:@"-[%@ %@]", [self class], + return [NSString stringWithFormat:@"-[%@ %@]", [self class], NSStringFromSelector([self selector])]; } @@ -355,7 +356,7 @@ static int MethodSort(const void *a, const void *b) { && strcmp(returnType, @encode(void)) == 0 && method_getNumberOfArguments(currMethod) == 2) { NSMethodSignature *sig = [self instanceMethodSignatureForSelector:sel]; - NSInvocation *invocation + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; [invocation setSelector:sel]; [invocations addObject:invocation]; @@ -407,8 +408,8 @@ static int MethodSort(const void *a, const void *b) { // COV_NF_START // We don't have leak checking on by default, so this won't be hit. static void _GTMRunLeaks(void) { - // This is an atexit handler. It runs leaks for us to check if we are - // leaking anything in our tests. + // This is an atexit handler. It runs leaks for us to check if we are + // leaking anything in our tests. const char* cExclusionsEnv = getenv("GTM_LEAKS_SYMBOLS_TO_IGNORE"); NSMutableString *exclusions = [NSMutableString string]; if (cExclusionsEnv) { @@ -421,13 +422,13 @@ static void _GTMRunLeaks(void) { [exclusions appendFormat:@"-exclude \"%@\" ", exclusion]; } } - NSString *string + NSString *string = [NSString stringWithFormat:@"/usr/bin/leaks %@%d" - @"| /usr/bin/sed -e 's/Leak: /Leaks:0: warning: Leak /'", + @"| /usr/bin/sed -e 's/Leak: /Leaks:0: warning: Leak /'", exclusions, getpid()]; int ret = system([string UTF8String]); if (ret) { - fprintf(stderr, "%s:%d: Error: Unable to run leaks. 'system' returned: %d", + fprintf(stderr, "%s:%d: Error: Unable to run leaks. 'system' returned: %d", __FILE__, __LINE__, ret); fflush(stderr); } @@ -447,11 +448,11 @@ static __attribute__((constructor)) void _GTMInstallLeaks(void) { fprintf(stderr, "Leak Checking Enabled\n"); fflush(stderr); int ret = atexit(&_GTMRunLeaks); - _GTMDevAssert(ret == 0, - @"Unable to install _GTMRunLeaks as an atexit handler (%d)", + _GTMDevAssert(ret == 0, + @"Unable to install _GTMRunLeaks as an atexit handler (%d)", errno); // COV_NF_END - } + } } } diff --git a/XcodeConfig/subconfig/General.xcconfig b/XcodeConfig/subconfig/General.xcconfig index 553b3a5..ffe3454 100644 --- a/XcodeConfig/subconfig/General.xcconfig +++ b/XcodeConfig/subconfig/General.xcconfig @@ -9,9 +9,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -92,16 +92,16 @@ GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64*] = YES // -Wpadded - lots of structures will get padded, so although this warning may // be useful to show us badly padded structures, it causes to many // warnings to be on generally. -// -Wunreachable-code - several macros use the do {} while (0) which always +// -Wunreachable-code - several macros use the do {} while (0) which always // flags this. e.g. all the ST... macros for unittesting // -Wredundant-decls - we sometimes use redundant decls to add an attribute -// to a function/method (i.e. +// to a function/method (i.e. // -Waggregate-return - NSPoint, NSRect etc are often returned as aggregates // -Wshorten-64-to-32 - this is defined in the 64 bit build settings // -Wcast-qual - Would love to turn this on, but causes issues when converting // CFTypes to NSTypes and also has issues with some external // libraries (notably zlib) -// -Wundef - we conditionalize on TARGET_OS_IPHONE which is only defined +// -Wundef - we conditionalize on TARGET_OS_IPHONE which is only defined // in the iPhoneSDK making us unable to turn this warning on. // -Wstrict-prototypes - breaks the GTM_METHOD_CHECK macro // -Wcast-align - causes a whole pile of problems buildng with iPhoneSDK @@ -111,10 +111,8 @@ GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64*] = YES // -Wassign-intercept - this really is more informational than a warning. // -Wselector - the system headers define lots of methods with the same selector // rendering this mostly useless to us -// -Wstrict-selector-match - the system headers define lots of methods with the +// -Wstrict-selector-match - the system headers define lots of methods with the // same selector rendering this mostly useless to us -// Not being used currently because of Radar 5978978 -// GTM_GENERAL_WARNING_OBJC_ONLY_FLAGS=-Wundeclared-selector // C Only Warnings GTM_GENERAL_OTHER_CFLAGS = -Wdiv-by-zero -Wbad-function-cast -Wnested-externs -Wold-style-definition @@ -127,16 +125,16 @@ GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = YES GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES // General C/C++/ObjC/ObjC++ warnings -// These are generally ordered in easiest to hardest to support. -// If you are transitioning, you can turn on the levels one level at a time -// in your project file by editing GTM_GENERAL_WARNING_CFLAGS and only -// including the warning levels that you currently are compiling against. +// These are generally ordered in easiest to hardest to support. +// If you are transitioning, you can turn on the levels one level at a time +// in your project file by editing GTM_GENERAL_WARNING_CFLAGS and only +// including the warning levels that you currently are compiling against. // GTM should always compile with full warnings. GTM_GENERAL_WARNING_CFLAGS1 = -Wall -Wendif-labels -Winvalid-pch -Wformat=2 -Wmissing-format-attribute -Wwrite-strings -Wstack-protector -Wstrict-aliasing=2 GTM_GENERAL_WARNING_CFLAGS2 = -Wpacked -Wmissing-field-initializers GTM_EXTRA_WARNING_OVERRIDE_CFLAGS = -Wno-unused-parameter -Wno-sign-compare GTM_GENERAL_WARNING_CFLAGS3 = -Wextra $(GTM_EXTRA_WARNING_OVERRIDE_CFLAGS) -Wpointer-arith -Wdisabled-optimization -Wfloat-equal -GTM_GENERAL_WARNING_CFLAGS = $(GTM_GENERAL_WARNING_CFLAGS1) $(GTM_GENERAL_WARNING_CFLAGS2) $(GTM_GENERAL_WARNING_CFLAGS3) +GTM_GENERAL_WARNING_CFLAGS = $(GTM_GENERAL_WARNING_CFLAGS1) $(GTM_GENERAL_WARNING_CFLAGS2) $(GTM_GENERAL_WARNING_CFLAGS3) // GCC_WARN_UNINITIALIZED_AUTOS is defined in the release/debug xcconfigs. GCC_WARN_CHECK_SWITCH_STATEMENTS = YES @@ -154,6 +152,7 @@ GCC_WARN_UNUSED_FUNCTION = YES GCC_WARN_UNUSED_VALUE = YES GCC_WARN_UNUSED_VARIABLE = YES GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES +GCC_WARN_UNDECLARED_SELECTOR = YES // We don't turn on shadow and sign comparisons because too many 3rd party // libaries don't compile with them turned on (sign compare rarely catches // errors, but shadow is very useful). @@ -168,5 +167,4 @@ GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = NO GCC_WARN_UNUSED_PARAMETER = NO // Use of Gestalt requires 4 char constants (amongst other things) -GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO - +GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO diff --git a/XcodeConfig/subconfig/SnowLeopardOrLater.xcconfig b/XcodeConfig/subconfig/SnowLeopardOrLater.xcconfig index 666dbdc..f0a3b50 100644 --- a/XcodeConfig/subconfig/SnowLeopardOrLater.xcconfig +++ b/XcodeConfig/subconfig/SnowLeopardOrLater.xcconfig @@ -1,8 +1,8 @@ // // SnowLeopardOrLater.xcconfig // -// Xcode configuration file for projects targeting 10.6 SnowLeopard or later. -// These settings produce a Universal binary compatible with 10.6 for +// Xcode configuration file for projects targeting 10.6 SnowLeopard or later. +// These settings produce a Universal binary compatible with 10.6 for // PPC and Intel. // // Copyright 2008 Google Inc. @@ -10,9 +10,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the diff --git a/iPhone/GTMUIView+SubtreeDescription.h b/iPhone/GTMUIView+SubtreeDescription.h index 1e714ed..627298a 100644 --- a/iPhone/GTMUIView+SubtreeDescription.h +++ b/iPhone/GTMUIView+SubtreeDescription.h @@ -44,4 +44,10 @@ @end +@protocol GTMUIViewSubtreeDescription +// A UIView can implement this and it can add it's own custom description +// in gtm_subtreeDescriptionLine. +- (NSString *)myViewDescriptionLine; +@end + #endif // DEBUG diff --git a/iPhone/GTMUIView+SubtreeDescription.m b/iPhone/GTMUIView+SubtreeDescription.m index bae0e2f..519aed0 100644 --- a/iPhone/GTMUIView+SubtreeDescription.m +++ b/iPhone/GTMUIView+SubtreeDescription.m @@ -31,7 +31,6 @@ static void AppendLabelFloat(NSMutableString *s, NSString *label, float f) { } } - static NSMutableString *SublayerDescriptionLine(CALayer *layer) { NSMutableString *result = [NSMutableString string]; [result appendFormat:@"%@ %p {", [layer class], layer]; @@ -60,7 +59,7 @@ static NSMutableString *SublayerDescriptionAtLevel(CALayer *layer, int level) { [result appendString:SublayerDescriptionLine(layer)]; // |sublayers| is defined in the QuartzCore framework, which isn't guaranteed // to be linked to this program. (So we don't include the header.) - NSArray *layers = [layer performSelector:@selector(sublayers)]; + NSArray *layers = [layer performSelector:NSSelectorFromString(@"sublayers")]; for (CALayer *l in layers) { [result appendString:SublayerDescriptionAtLevel(l, level+1)]; } @@ -127,11 +126,12 @@ static NSMutableString *SublayerDescriptionAtLevel(CALayer *layer, int level) { // for debugging dump the layer hierarchy, frames and isHidden. - (NSString *)sublayersDescription { CALayer *layer = [self layer]; - if (![layer respondsToSelector:@selector(sublayers)]) { + SEL sublayers = NSSelectorFromString(@"sublayers"); + if (![layer respondsToSelector:sublayers]) { return @"*** Sorry: This app is not linked with the QuartzCore framework."; } NSMutableString *result = SublayerDescriptionLine(layer); - NSArray *layers = [layer performSelector:@selector(sublayers)]; + NSArray *layers = [layer performSelector:sublayers]; for (CALayer *l in layers) { [result appendString:SublayerDescriptionAtLevel(l, 1)]; } -- cgit v1.2.3