diff --git a/.gitignore b/.gitignore index d46c2dc..a2fed1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,16 @@ -distribution/build -distribution/artifacts +# General +.DS_Store -app_unexpectedly/app_unexpectedly.xcodeproj/project.xcworkspace/xcuserdata/stephane.xcuserdatad/UserInterfaceState.xcuserstate +# Build -app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist - -app_unexpectedly/app_unexpectedly/Extemal/Line View Test/Line View Test.xcodeproj/xcuserdata/stephane.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +distribution/build +distribution/artifacts +distribution/Template/Template_rw.dmg -app_unexpectedly/app_unexpectedly/Extemal/Line View Test/Line View Test.xcodeproj/project.xcworkspace/xcuserdata/stephane.xcuserdatad/UserInterfaceState.xcuserstate +# Xcode project -app_unexpectedly/app_unexpectedly/Extemal/Line View Test/Line View Test.xcodeproj/xcuserdata/stephane.xcuserdatad/xcschemes/xcschememanagement.plist +project.xcworkspace/xcuserdata/ -distribution/Template/Template_rw.dmg +*.xcodeproj/xcuserdata/ +*.xcuserdata +*.xcuserstate diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..67a3a02 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "submodules/ips2crash"] + path = submodules/ips2crash + url = https://github.com/packagesdev/ips2crash diff --git a/Configs/SharedConfigurationSettings.xcconfig b/Configs/SharedConfigurationSettings.xcconfig index 6bb8832..412839c 100644 --- a/Configs/SharedConfigurationSettings.xcconfig +++ b/Configs/SharedConfigurationSettings.xcconfig @@ -20,4 +20,6 @@ MACOSX_DEPLOYMENT_TARGET[arch=arm64] = 11.0 COPY_PHASE_STRIP[config=Debug] = NO COPY_PHASE_STRIP = YES +// Codesigning +OTHER_CODE_SIGN_FLAGS = --timestamp diff --git a/Documents Pages/Unexpectedly_Acknowledgements.pages b/Documents Pages/Unexpectedly_Acknowledgements.pages index 257f654..32b38ba 100644 Binary files a/Documents Pages/Unexpectedly_Acknowledgements.pages and b/Documents Pages/Unexpectedly_Acknowledgements.pages differ diff --git a/Documents Pages/Unexpectedly_Acknowledgements.pdf b/Documents Pages/Unexpectedly_Acknowledgements.pdf index 47deb08..8c2aaf0 100644 Binary files a/Documents Pages/Unexpectedly_Acknowledgements.pdf and b/Documents Pages/Unexpectedly_Acknowledgements.pdf differ diff --git a/Documents Pages/Unexpectedly_License.pages b/Documents Pages/Unexpectedly_License.pages index 64ffc9b..54e896b 100644 Binary files a/Documents Pages/Unexpectedly_License.pages and b/Documents Pages/Unexpectedly_License.pages differ diff --git a/Documents Pages/Unexpectedly_License.pdf b/Documents Pages/Unexpectedly_License.pdf index 2b370d0..b22adb6 100644 Binary files a/Documents Pages/Unexpectedly_License.pdf and b/Documents Pages/Unexpectedly_License.pdf differ diff --git a/LICENSE.txt b/LICENSE.txt index e321071..d335ce4 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright © 2021, Stéphane Sudre. All rights reserved. +Copyright © 2021-2025, Stéphane Sudre. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 9d8e0cb..3700f56 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Unexpectedly is a macOS utility to browse and inspect crash reports of Mac appli ## Screenshot -[Alt text](http://s.sudre.free.fr/Software/Unexpectedly/images/about_top.png "Unexpectedly text mode") +![Alt text](http://s.sudre.free.fr/Software/Unexpectedly/images/about_top.png "Unexpectedly text mode") ## Motivation @@ -21,7 +21,7 @@ Minimum OS requirement is macOS 10.13 at this time. ## License - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/app_unexpectedly/AppKit + Extensions/NSColor+String.m b/app_unexpectedly/AppKit + Extensions/NSColor+String.m index 4a206cd..8adcc1e 100644 --- a/app_unexpectedly/AppKit + Extensions/NSColor+String.m +++ b/app_unexpectedly/AppKit + Extensions/NSColor+String.m @@ -21,9 +21,9 @@ + (NSColor *)colorFromString:(NSString *)inString if (inString!=nil) { - NSArray * tComponents=[inString componentsSeparatedByString:@"|"]; + NSArray * tComponents=[inString componentsSeparatedByString:@"|"]; - if ([tComponents count]==3) + if (tComponents.count==3) { tColor=[NSColor colorWithCalibratedRed:[tComponents[0] floatValue] green:[tComponents[1] floatValue] @@ -39,7 +39,8 @@ + (NSColor *)colorFromString:(NSString *)inString - (NSString *)stringValue { - NSColor *tColor = [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + NSColorSpace * tColorSpace = [NSColorSpace genericRGBColorSpace]; + NSColor * tColor = [self colorUsingColorSpace:tColorSpace]; return([NSString stringWithFormat:@"%f|%f|%f",(float)[tColor redComponent],(float)[tColor greenComponent],(float)[tColor blueComponent]]); } diff --git a/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.h b/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.h index b41c167..ac27f7c 100644 --- a/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.h +++ b/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.h @@ -1,3 +1,15 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #import diff --git a/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.m b/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.m index b2871bf..70e5646 100644 --- a/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.m +++ b/app_unexpectedly/AppKit + Extensions/NSTableView+Selection.m @@ -1,3 +1,15 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #import "NSTableView+Selection.h" diff --git a/plugin_quicklook/crashreport/CUIThemesManager+QuickLookGenerator.h b/app_unexpectedly/Foundation + Extensions/NSString+CPU.h similarity index 94% rename from plugin_quicklook/crashreport/CUIThemesManager+QuickLookGenerator.h rename to app_unexpectedly/Foundation + Extensions/NSString+CPU.h index 2c4abb7..0a6aa44 100644 --- a/plugin_quicklook/crashreport/CUIThemesManager+QuickLookGenerator.h +++ b/app_unexpectedly/Foundation + Extensions/NSString+CPU.h @@ -11,8 +11,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "CUIThemesManager.h" +#import -@interface CUIThemesManager (QuickLookGenerator) +@interface NSString (CPU) + +- (cpu_type_t)CUI_CPUType; @end + diff --git a/app_unexpectedly/Foundation + Extensions/NSString+CPU.m b/app_unexpectedly/Foundation + Extensions/NSString+CPU.m new file mode 100644 index 0000000..69b3b5a --- /dev/null +++ b/app_unexpectedly/Foundation + Extensions/NSString+CPU.m @@ -0,0 +1,39 @@ +/* + Copyright (c) 2021-2024, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "NSString+CPU.h" + +@implementation NSString (CPU) + +- (cpu_type_t)CUI_CPUType +{ + static NSDictionary * sCPUFamiliesRegistry=nil; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + + sCPUFamiliesRegistry=@{ + @"X86-64":@(CPU_TYPE_X86_64), + @"x86_64":@(CPU_TYPE_X86_64), + @"ARM-64":@(CPU_TYPE_ARM64), + @"arm64":@(CPU_TYPE_ARM64), + }; + + }); + + NSNumber * tCPUFamily=sCPUFamiliesRegistry[self]; + + return (tCPUFamily!=nil) ? [tCPUFamily intValue] : CPU_TYPE_X86; +} + +@end diff --git a/app_unexpectedly/RSCore/LICENSE.txt b/app_unexpectedly/RSCore/LICENSE.txt new file mode 100644 index 0000000..ea433ea --- /dev/null +++ b/app_unexpectedly/RSCore/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2002-2025 Brent Simmons + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app_unexpectedly/RSCore/NSMenuItem+RSCore.h b/app_unexpectedly/RSCore/NSMenuItem+RSCore.h new file mode 100644 index 0000000..d672f49 --- /dev/null +++ b/app_unexpectedly/RSCore/NSMenuItem+RSCore.h @@ -0,0 +1,26 @@ +// +// NSMenuItem+RSCore.h +// RSCore +// +// Created by Brent Simmons on 1/5/26. +// + +#if TARGET_OS_MAC && !TARGET_OS_IPHONE + +@import AppKit; + +@interface NSMenuItem (RSCore) + +/// When YES, the menu item’s image will be shown (if it exists) despite icon disabling. +/// Defaults to NO. +@property (nonatomic, assign) BOOL rs_shouldShowImage; + +/// Disables icons in all menu items (except where `rs_shouldShowImage == YES`) +/// and those that are likely toolbar item representations. +/// +/// Call +[NSMenuItem rs_disableIcons] early (from AppDelegate init is good). ++ (void)rs_disableIcons; + +@end + +#endif diff --git a/app_unexpectedly/RSCore/NSMenuItem+RSCore.m b/app_unexpectedly/RSCore/NSMenuItem+RSCore.m new file mode 100644 index 0000000..8d52287 --- /dev/null +++ b/app_unexpectedly/RSCore/NSMenuItem+RSCore.m @@ -0,0 +1,63 @@ +// +// NSMenuItem+RSCore.m +// RSCore +// +// Created by Brent Simmons on 1/7/26. +// + +#if TARGET_OS_MAC && !TARGET_OS_IPHONE + +#import "NSMenuItem+RSCore.h" +#import + +static void *kShouldShowImageKey = &kShouldShowImageKey; + +@implementation NSMenuItem (RSCore) + ++ (void)rs_disableIcons { + + Method originalMethod = class_getInstanceMethod(self, @selector(image)); + Method swizzledMethod = class_getInstanceMethod(self, @selector(rs_swizzledImage)); + + if (originalMethod && swizzledMethod) { + method_exchangeImplementations(originalMethod, swizzledMethod); + } +} + +- (NSImage *)rs_swizzledImage { + + if (self.rs_shouldShowImage || [self rs_isToolbarItemRepresentation] || ![self rs_isMainMenuItem] || self.title.length < 1) { + // Call the original getter (now swapped to rs_swizzledImage) + return [self rs_swizzledImage]; + } + return nil; +} + +- (BOOL)rs_isToolbarItemRepresentation { + + // Menu items not attached to any menu are likely toolbar button representations + return self.menu == nil; +} + +- (BOOL)rs_isMainMenuItem { + + // Return true if the parent menu is the main menu. + // This allows images to show for (for instance) the traffic light menus + // and for menu items in submenus such as Move & Resize and Full Screen Tile. + return self.menu.supermenu == NSApplication.sharedApplication.mainMenu; +} + +- (BOOL)rs_shouldShowImage { + + NSNumber *value = objc_getAssociatedObject(self, kShouldShowImageKey); + return value.boolValue; +} + +- (void)setRs_shouldShowImage:(BOOL)shouldShowImage { + + objc_setAssociatedObject(self, kShouldShowImageKey, @(shouldShowImage), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +#endif diff --git a/app_unexpectedly/app_unexpectedly.xcodeproj/project.pbxproj b/app_unexpectedly/app_unexpectedly.xcodeproj/project.pbxproj index 1d4c4ee..61035d2 100644 --- a/app_unexpectedly/app_unexpectedly.xcodeproj/project.pbxproj +++ b/app_unexpectedly/app_unexpectedly.xcodeproj/project.pbxproj @@ -7,11 +7,16 @@ objects = { /* Begin PBXBuildFile section */ + D06294382E1DD8150008895D /* CUICodeSigningInformationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D06294362E1DD8150008895D /* CUICodeSigningInformationViewController.m */; }; + D0790DBD2E00BACF00CD6A72 /* CUIThreadImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D0790DBC2E00BACF00CD6A72 /* CUIThreadImageView.m */; }; + D0BA6A462E09FEB50010D630 /* EXC_GUARD.html in Resources */ = {isa = PBXBuildFile; fileRef = D0BA6A442E09FEB50010D630 /* EXC_GUARD.html */; }; + D0BD223B2F3FC6810052AD8E /* NSMenuItem+RSCore.m in Sources */ = {isa = PBXBuildFile; fileRef = D0BD223A2F3FC6810052AD8E /* NSMenuItem+RSCore.m */; }; F4040A7624F5B9CE0072BF65 /* CUINavigationChevronView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4040A7524F5B9CE0072BF65 /* CUINavigationChevronView.m */; }; F4040A7924F5BC230072BF65 /* CUINavigationView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4040A7824F5BC230072BF65 /* CUINavigationView.m */; }; F4055C8125EEE37400DC6CCA /* CUIMainWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4055C8325EEE37400DC6CCA /* CUIMainWindowController.xib */; }; F405A96D255015D800AD2F24 /* CUICXXDemangler.mm in Sources */ = {isa = PBXBuildFile; fileRef = F405A96C255015D800AD2F24 /* CUICXXDemangler.mm */; }; F405A97025501A5F00AD2F24 /* CUIParsingErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = F405A96F25501A5F00AD2F24 /* CUIParsingErrors.m */; }; + F406B4992687AB1400B90C7B /* CUIPreferencePaneAdvancedViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F406B49B2687AB1400B90C7B /* CUIPreferencePaneAdvancedViewController.xib */; }; F40ACE2D255697A3006855E5 /* CUICrashLogBrowsingState.m in Sources */ = {isa = PBXBuildFile; fileRef = F40ACE2C255697A3006855E5 /* CUICrashLogBrowsingState.m */; }; F40ACE30255697CE006855E5 /* CUICrashLogBrowsingStateRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40ACE2F255697CE006855E5 /* CUICrashLogBrowsingStateRegistry.m */; }; F40B0D7E24D3558800663282 /* CUIPreferencesTabBox.m in Sources */ = {isa = PBXBuildFile; fileRef = F40B0D7824D3558700663282 /* CUIPreferencesTabBox.m */; }; @@ -58,17 +63,42 @@ F420C9C4254F5F4C00D24249 /* CUIdSYMHunter.m in Sources */ = {isa = PBXBuildFile; fileRef = F420C9C3254F5F4C00D24249 /* CUIdSYMHunter.m */; }; F420F35224E95E5F006C82CD /* CUITheme.m in Sources */ = {isa = PBXBuildFile; fileRef = F420F35124E95E5F006C82CD /* CUITheme.m */; }; F4214CB524B6534400852DDE /* CUICrashLogsSourcesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F4214CB424B6534400852DDE /* CUICrashLogsSourcesManager.m */; }; + F423818C267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F423818A267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.m */; }; + F4238191267D3522003837AC /* WBRemoteVersionChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = F4238190267D3522003837AC /* WBRemoteVersionChecker.m */; }; + F428C0702724592D00FB8CAC /* IPSImage.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0412724592900FB8CAC /* IPSImage.m */; }; + F428C0712724592D00FB8CAC /* IPSIncidentHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0422724592900FB8CAC /* IPSIncidentHeader.m */; }; + F428C0722724592D00FB8CAC /* IPSIncidentExceptionInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0432724592900FB8CAC /* IPSIncidentExceptionInformation.m */; }; + F428C0732724592D00FB8CAC /* IPSIncidentDiagnosticMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0442724592900FB8CAC /* IPSIncidentDiagnosticMessage.m */; }; + F428C0742724592D00FB8CAC /* IPSReport.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0452724592900FB8CAC /* IPSReport.m */; }; + F428C0752724592D00FB8CAC /* IPSThreadInstructionState.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0462724592900FB8CAC /* IPSThreadInstructionState.m */; }; + F428C0762724592D00FB8CAC /* IPSThreadInstructionStream.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0472724592900FB8CAC /* IPSThreadInstructionStream.m */; }; + F428C0772724592D00FB8CAC /* IPSRegisterState.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0492724592900FB8CAC /* IPSRegisterState.m */; }; + F428C0782724592D00FB8CAC /* IPSDateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C04A2724592A00FB8CAC /* IPSDateFormatter.m */; }; + F428C0792724592D00FB8CAC /* IPSApplicationSpecificInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C04B2724592A00FB8CAC /* IPSApplicationSpecificInformation.m */; }; + F428C07A2724592D00FB8CAC /* IPSSummary.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C04C2724592A00FB8CAC /* IPSSummary.m */; }; + F428C07B2724592D00FB8CAC /* IPSTermination.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C04D2724592A00FB8CAC /* IPSTermination.m */; }; + F428C07C2724592D00FB8CAC /* IPSExternalModificationSummary.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C04E2724592A00FB8CAC /* IPSExternalModificationSummary.m */; }; + F428C07D2724592D00FB8CAC /* IPSExternalModificationStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0502724592A00FB8CAC /* IPSExternalModificationStatistics.m */; }; + F428C07E2724592D00FB8CAC /* IPSBundleInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0532724592A00FB8CAC /* IPSBundleInfo.m */; }; + F428C07F2724592D00FB8CAC /* IPSException.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0542724592A00FB8CAC /* IPSException.m */; }; + F428C0802724592D00FB8CAC /* IPSThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0572724592A00FB8CAC /* IPSThread.m */; }; + F428C0812724592D00FB8CAC /* IPSThreadFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0592724592B00FB8CAC /* IPSThreadFrame.m */; }; + F428C0822724592D00FB8CAC /* IPSError.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C05B2724592B00FB8CAC /* IPSError.m */; }; + F428C0832724592D00FB8CAC /* IPSOperatingSystemVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C05E2724592B00FB8CAC /* IPSOperatingSystemVersion.m */; }; + F428C0842724592D00FB8CAC /* IPSThreadState.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0622724592B00FB8CAC /* IPSThreadState.m */; }; + F428C0852724592D00FB8CAC /* IPSLegacyInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C0682724592C00FB8CAC /* IPSLegacyInfo.m */; }; + F428C0862724592D00FB8CAC /* IPSIncident.m in Sources */ = {isa = PBXBuildFile; fileRef = F428C06A2724592C00FB8CAC /* IPSIncident.m */; }; F42B57E224ABEF6E00F77ED5 /* CUICallsSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = F42B57E124ABEF6E00F77ED5 /* CUICallsSelection.m */; }; F42D0BC425514B670021A551 /* template.source in Resources */ = {isa = PBXBuildFile; fileRef = F42D0BC225514B2E0021A551 /* template.source */; }; + F42E50012724B7550092181A /* CUICrashDataTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = F42E50002724B7550092181A /* CUICrashDataTransform.m */; }; F4301A6825EF0DE000ACDA3F /* CUIPreferencePanePresentationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4301A6A25EF0DE000ACDA3F /* CUIPreferencePanePresentationViewController.xib */; }; F4306D592577E168007E667F /* CUICrashLogThreadState+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F4306D582577E168007E667F /* CUICrashLogThreadState+UI.m */; }; F432ACC824A95014000A3E7A /* CUIThreadsListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F432ACC624A95014000A3E7A /* CUIThreadsListViewController.m */; }; - F432ACC924A95014000A3E7A /* CUIThreadsListViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F432ACC724A95014000A3E7A /* CUIThreadsListViewController.xib */; }; F432ACCC24A9502A000A3E7A /* CUIThreadsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F432ACCB24A9502A000A3E7A /* CUIThreadsViewController.m */; }; F432ACD024A95042000A3E7A /* CUIThreadsColumnViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F432ACCE24A95042000A3E7A /* CUIThreadsColumnViewController.m */; }; - F432ACD124A95042000A3E7A /* CUIThreadsColumnViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F432ACCF24A95042000A3E7A /* CUIThreadsColumnViewController.xib */; }; F43362FE25FCEFBA006E7894 /* CUIRawCrashLog+Path.m in Sources */ = {isa = PBXBuildFile; fileRef = F43362FD25FCEFBA006E7894 /* CUIRawCrashLog+Path.m */; }; F4341C6B258EB8FE001A5605 /* CUICrashReporterDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = F4341C6A258EB8FE001A5605 /* CUICrashReporterDefaults.m */; }; + F4386B0F2849541C00B83525 /* CUICrashLogExceptionInformation+QuickHelp.m in Sources */ = {isa = PBXBuildFile; fileRef = F4386B0D2849541B00B83525 /* CUICrashLogExceptionInformation+QuickHelp.m */; }; F43A9A832591260C005AB2AA /* CUIOutlineModeDisplaySettings.m in Sources */ = {isa = PBXBuildFile; fileRef = F43A9A822591260C005AB2AA /* CUIOutlineModeDisplaySettings.m */; }; F43AF0D1256FE2AE0066CA1B /* DWRFSection_debug_addr.m in Sources */ = {isa = PBXBuildFile; fileRef = F43AF0D0256FE2AE0066CA1B /* DWRFSection_debug_addr.m */; }; F43C828824D892620096F27B /* CUIPreferencePanePresentationTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F43C828624D892620096F27B /* CUIPreferencePanePresentationTextViewController.m */; }; @@ -79,9 +109,11 @@ F440A3E924AA35AC00C23DA1 /* CUICrashLogsSourceDirectory.m in Sources */ = {isa = PBXBuildFile; fileRef = F440A3E824AA35AC00C23DA1 /* CUICrashLogsSourceDirectory.m */; }; F440A3EC24AA38E600C23DA1 /* CUICrashLogsSourceAll.m in Sources */ = {isa = PBXBuildFile; fileRef = F440A3EB24AA38E600C23DA1 /* CUICrashLogsSourceAll.m */; }; F442FCED24AB855C00E87B69 /* CUIBinaryImagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F442FCEB24AB855C00E87B69 /* CUIBinaryImagesViewController.m */; }; - F442FCF124AB8A8B00E87B69 /* CUIBinaryImage+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F442FCF024AB8A8B00E87B69 /* CUIBinaryImage+UI.m */; }; + F442FCF124AB8A8B00E87B69 /* CUIBinaryImageUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F442FCF024AB8A8B00E87B69 /* CUIBinaryImageUtility.m */; }; F44356F324A8A113001D3D35 /* CUICrashLogPresentationOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F44356F124A8A113001D3D35 /* CUICrashLogPresentationOutlineViewController.m */; }; F44356FF24A8A8B5001D3D35 /* CUIThreadNamedTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = F44356FE24A8A8B5001D3D35 /* CUIThreadNamedTableCellView.m */; }; + F4440FE0282C4104003C810B /* IPSSummarySerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = F4440FDC282C4103003C810B /* IPSSummarySerialization.m */; }; + F4440FE1282C4104003C810B /* IPSCrashSummary.m in Sources */ = {isa = PBXBuildFile; fileRef = F4440FDD282C4103003C810B /* IPSCrashSummary.m */; }; F44E7B7F255C83D500025C04 /* NoodleLineNumberView.m in Sources */ = {isa = PBXBuildFile; fileRef = F44E7B7C255C83D500025C04 /* NoodleLineNumberView.m */; }; F44E7B80255C83D500025C04 /* NoodleLineNumberMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = F44E7B7D255C83D500025C04 /* NoodleLineNumberMarker.m */; }; F45015C625FABCAC000C4B8D /* EXC_BAD_ACCESS_SIGSEGV.html in Resources */ = {isa = PBXBuildFile; fileRef = F45015C825FABCAC000C4B8D /* EXC_BAD_ACCESS_SIGSEGV.html */; }; @@ -104,6 +136,8 @@ F45A2D6D25EC60920007D50E /* CUICrashLogsSourcesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F45A2D6F25EC60920007D50E /* CUICrashLogsSourcesViewController.xib */; }; F45A2D7125EC60D90007D50E /* CUICrashLogsListViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F45A2D7325EC60D90007D50E /* CUICrashLogsListViewController.xib */; }; F45B518C24AFA04000E97B87 /* CUICrashLogsSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = F45B518B24AFA04000E97B87 /* CUICrashLogsSelection.m */; }; + F45DED692E350F07008F4CE8 /* CUICodeSigningInformationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F45DED6B2E350F07008F4CE8 /* CUICodeSigningInformationViewController.xib */; }; + F45DED6F2E3510D9008F4CE8 /* CodeSigning.strings in Resources */ = {isa = PBXBuildFile; fileRef = F45DED6D2E3510D9008F4CE8 /* CodeSigning.strings */; }; F45F2F5B2538EF3F0030A402 /* NSFileManager+ExtendedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = F45F2F5A2538EF3F0030A402 /* NSFileManager+ExtendedAttributes.m */; }; F45F84DC266ABB7600F354F3 /* crashreport.qlgenerator in CopyFiles */ = {isa = PBXBuildFile; fileRef = F45F84D8266ABB5800F354F3 /* crashreport.qlgenerator */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; F46198E924CA390700FA9717 /* CUICrashLogBacktraces+Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = F46198E824CA390700FA9717 /* CUICrashLogBacktraces+Utilities.m */; }; @@ -126,10 +160,15 @@ F46D77AB25ED9EAE00039663 /* CUICollectionViewRegisterItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = F46D77AD25ED9EAE00039663 /* CUICollectionViewRegisterItem.xib */; }; F472CC972550631A003F6338 /* CUISwiftDemangler.m in Sources */ = {isa = PBXBuildFile; fileRef = F472CC962550631A003F6338 /* CUISwiftDemangler.m */; }; F4754D7125F5678700B0D48F /* CUICrashLogPresentationOutlineViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4754D7325F5678700B0D48F /* CUICrashLogPresentationOutlineViewController.xib */; }; + F475FB4026DBAC8200A113D8 /* CUITableViewNoSpace.m in Sources */ = {isa = PBXBuildFile; fileRef = F475FB3F26DBAC8200A113D8 /* CUITableViewNoSpace.m */; }; F476EEBE25686DEF00F40F87 /* CUIAboutBoxFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = F476EEBD25686DEF00F40F87 /* CUIAboutBoxFooterView.m */; }; F476EEC125686EC000F40F87 /* CUIContentBox.m in Sources */ = {isa = PBXBuildFile; fileRef = F476EEBF25686EC000F40F87 /* CUIContentBox.m */; }; F4775479255B0054006BA662 /* CUIThemesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4775478255B0054006BA662 /* CUIThemesTableView.m */; }; F47AF8C0255DE61E0037E2D8 /* NSCrashLogTextScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = F47AF8BF255DE61E0037E2D8 /* NSCrashLogTextScrollView.m */; }; + F47C381E2A422E880020D88F /* CUIThreadsListViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F47C381C2A422E880020D88F /* CUIThreadsListViewController.xib */; }; + F47C381F2A422E880020D88F /* CUIThreadsListViewController_RTL.xib in Resources */ = {isa = PBXBuildFile; fileRef = F47C381D2A422E880020D88F /* CUIThreadsListViewController_RTL.xib */; }; + F47C38222A4230370020D88F /* CUIThreadsColumnViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F47C38202A4230370020D88F /* CUIThreadsColumnViewController.xib */; }; + F47C38232A4230370020D88F /* CUIThreadsColumnViewController_RTL.xib in Resources */ = {isa = PBXBuildFile; fileRef = F47C38212A4230370020D88F /* CUIThreadsColumnViewController_RTL.xib */; }; F47F76622673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F47F76612673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.m */; }; F47F76652673548600A74905 /* CUICrashLogsOpenErrorRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = F47F76642673548600A74905 /* CUICrashLogsOpenErrorRecord.m */; }; F47F7668267355EA00A74905 /* CUICrashLogErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = F47F7667267355EA00A74905 /* CUICrashLogErrors.m */; }; @@ -151,6 +190,7 @@ F4871E10254384E100580562 /* CUIdSYMBundlesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F4871E0F254384E100580562 /* CUIdSYMBundlesManager.m */; }; F48906AE25D2BA0C002D79A9 /* CUISelectedWhiteTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F48906AD25D2BA0C002D79A9 /* CUISelectedWhiteTextFieldCell.m */; }; F48944222545836F00E3E360 /* CUISymbolsFilesLibraryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F48944202545836F00E3E360 /* CUISymbolsFilesLibraryViewController.m */; }; + F4895F5727A72D1000D75369 /* CUILineJumperWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4895F5927A72D1000D75369 /* CUILineJumperWindowController.xib */; }; F48BAB3625D9D4140005F3E5 /* CUIThreadImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F48BAB3525D9D4140005F3E5 /* CUIThreadImageCell.m */; }; F48CF5FF24A96992002AD214 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4CC570B24A79EDA00150EC4 /* MainMenu.xib */; }; F49227C824A8D45000772411 /* CUIStackFrame+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F49227C724A8D45000772411 /* CUIStackFrame+UI.m */; }; @@ -197,6 +237,8 @@ F4B52E212548B8B4007593FD /* CUIdSYMBundle+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B52E202548B8B4007593FD /* CUIdSYMBundle+UI.m */; }; F4B57C0C24AF5607000851FF /* CUICrashLogsSourceToday.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B57C0B24AF5607000851FF /* CUICrashLogsSourceToday.m */; }; F4B57C0F24AF5655000851FF /* CUICrashLogsSourceToday+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B57C0E24AF5655000851FF /* CUICrashLogsSourceToday+UI.m */; }; + F4B5BE6E2848277400C33F6F /* CUIExceptionTypePopUpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B5BE6D2848277400C33F6F /* CUIExceptionTypePopUpViewController.m */; }; + F4B5BE7128482A4300C33F6F /* CUITerminationReasonPopUpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B5BE7028482A4300C33F6F /* CUITerminationReasonPopUpViewController.m */; }; F4B649D324EDCD2300008C47 /* CUIInspectorExecutableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B649D124EDCD2300008C47 /* CUIInspectorExecutableViewController.m */; }; F4B649D724EDD09A00008C47 /* CUIInspectorStackableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B649D624EDD09A00008C47 /* CUIInspectorStackableViewController.m */; }; F4B649DB24EDD64900008C47 /* CUIInspectorProcessesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4B649D924EDD64900008C47 /* CUIInspectorProcessesViewController.m */; }; @@ -214,10 +256,11 @@ F4BBAC5D24AA7D37000511BE /* CUIBinaryImage.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BBAC5C24AA7D37000511BE /* CUIBinaryImage.m */; }; F4BC577124DF426200063545 /* CUIAATextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BC577024DF426200063545 /* CUIAATextFieldCell.m */; }; F4BD6A0025553E9000F98F3E /* CUICrashLogSectionsDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BD69FF25553E9000F98F3E /* CUICrashLogSectionsDetector.m */; }; + F4BD8C6A2DF4DDCB00BD61A8 /* IPSExceptionReason.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BD8C692DF4DDCA00BD61A8 /* IPSExceptionReason.m */; }; F4C269CD2503BCC100C8F3B3 /* CUISymbolicationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C269CC2503BCC100C8F3B3 /* CUISymbolicationManager.m */; }; F4C269D02503BE6500C8F3B3 /* CUISymbolicationData.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C269CF2503BE6500C8F3B3 /* CUISymbolicationData.m */; }; - F4C7498E24F84689004F38C0 /* CUIExceptionTypePopUpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C7498C24F84689004F38C0 /* CUIExceptionTypePopUpViewController.m */; }; - F4C7498F24F84689004F38C0 /* CUIExceptionTypePopUpViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4C7498D24F84689004F38C0 /* CUIExceptionTypePopUpViewController.xib */; }; + F4C7498E24F84689004F38C0 /* CUIQuickHelpPopUpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C7498C24F84689004F38C0 /* CUIQuickHelpPopUpViewController.m */; }; + F4C7498F24F84689004F38C0 /* CUIQuickHelpPopUpViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4C7498D24F84689004F38C0 /* CUIQuickHelpPopUpViewController.xib */; }; F4CC570624A79EDA00150EC4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F4CC570524A79EDA00150EC4 /* AppDelegate.m */; }; F4CC570824A79EDA00150EC4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F4CC570724A79EDA00150EC4 /* main.m */; }; F4CC570A24A79EDA00150EC4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4CC570924A79EDA00150EC4 /* Images.xcassets */; }; @@ -232,10 +275,37 @@ F4CCCC6E24AE9EDA0031BC27 /* CUICrashLogsSource+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F4CCCC6D24AE9EDA0031BC27 /* CUICrashLogsSource+UI.m */; }; F4CD32B6257D17B3008C71AA /* CUIPreferencePaneSymbolicationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4CD32B4257D17B3008C71AA /* CUIPreferencePaneSymbolicationViewController.m */; }; F4CE83DE2554B97400A8BD87 /* CUICenteredLabelViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4CE83DD2554B97300A8BD87 /* CUICenteredLabelViewController.xib */; }; + F4CF6CF62DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = F4CF6CF42DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.m */; }; + F4D0EE95273DB8CD00CC9737 /* IPSThreadState+RegisterDisplayName.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D0EE93273DB8CC00CC9737 /* IPSThreadState+RegisterDisplayName.m */; }; + F4D14D682745C0A9003698AD /* IPSImage+UserCode.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D14D662745C0A9003698AD /* IPSImage+UserCode.m */; }; F4D5C77C2571AF900029B051 /* CUIRegisterLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5C77B2571AF900029B051 /* CUIRegisterLabel.m */; }; + F4D6C56D2680028A00B78B3D /* RemoteCheck.strings in Resources */ = {isa = PBXBuildFile; fileRef = F4D6C56B2680028A00B78B3D /* RemoteCheck.strings */; }; F4D7F15B25F04A620024E9A5 /* CUISymbolsFilesLibraryViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4D7F15D25F04A620024E9A5 /* CUISymbolsFilesLibraryViewController.xib */; }; F4D7F15F25F04A9D0024E9A5 /* CUIPreferencePaneSymbolicationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4D7F16125F04A9D0024E9A5 /* CUIPreferencePaneSymbolicationViewController.xib */; }; + F4DAF0B327C44AA800256EA4 /* IPSImage+Offset.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DAF0B227C44AA700256EA4 /* IPSImage+Offset.m */; }; + F4DAFBEE2736B7B200FB50A6 /* CUIIPSTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DAFBED2736B7B200FB50A6 /* CUIIPSTransform.m */; }; + F4DAFBF12736B7D500FB50A6 /* CUIDataTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DAFBF02736B7D500FB50A6 /* CUIDataTransform.m */; }; + F4DF815A2893463E008EF1B3 /* IPSThreadState+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF813C2893463B008EF1B3 /* IPSThreadState+Obfuscating.m */; }; + F4DF815B2893463E008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF813D2893463B008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.m */; }; + F4DF815C2893463E008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81402893463B008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.m */; }; + F4DF815D2893463E008EF1B3 /* IPSIncidentHeader+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81432893463C008EF1B3 /* IPSIncidentHeader+Obfuscating.m */; }; + F4DF815E2893463E008EF1B3 /* IPSObfuscator.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81462893463C008EF1B3 /* IPSObfuscator.m */; }; + F4DF815F2893463E008EF1B3 /* IPSCrashSummary+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81472893463C008EF1B3 /* IPSCrashSummary+Obfuscating.m */; }; + F4DF81602893463E008EF1B3 /* IPSThread+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81492893463C008EF1B3 /* IPSThread+Obfuscating.m */; }; + F4DF81612893463E008EF1B3 /* IPSThreadFrame+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF814A2893463C008EF1B3 /* IPSThreadFrame+Obfuscating.m */; }; + F4DF81622893463E008EF1B3 /* IPSRegisterState+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF814B2893463C008EF1B3 /* IPSRegisterState+Obfuscating.m */; }; + F4DF81632893463E008EF1B3 /* IPSImage+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF814F2893463D008EF1B3 /* IPSImage+Obfuscating.m */; }; + F4DF81642893463E008EF1B3 /* IPSLegacyInfo+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81502893463D008EF1B3 /* IPSLegacyInfo+Obfuscating.m */; }; + F4DF81652893463E008EF1B3 /* IPSReport+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81522893463D008EF1B3 /* IPSReport+Obfuscating.m */; }; + F4DF81662893463E008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81552893463D008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.m */; }; + F4DF81672893463E008EF1B3 /* IPSBundleInfo+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81562893463D008EF1B3 /* IPSBundleInfo+Obfuscating.m */; }; + F4DF81682893463E008EF1B3 /* IPSIncident+Obfuscating.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DF81572893463D008EF1B3 /* IPSIncident+Obfuscating.m */; }; F4E0BD25262078220048647C /* CUIAboutBoxWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E0BD24262078220048647C /* CUIAboutBoxWindow.m */; }; + F4E671922E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E671912E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.m */; }; + F4E671952E2C405F00E5A064 /* CodeSigningFlags.plist in Resources */ = {isa = PBXBuildFile; fileRef = F4E671942E2C405F00E5A064 /* CodeSigningFlags.plist */; }; + F4E6ED9C2849695200766F9A /* unknown_termination_reason.html in Resources */ = {isa = PBXBuildFile; fileRef = F4E6ED9A2849695100766F9A /* unknown_termination_reason.html */; }; + F4E6EDA1284969DD00766F9A /* known_termination_reasons.css in Resources */ = {isa = PBXBuildFile; fileRef = F4E6EDA0284969DD00766F9A /* known_termination_reasons.css */; }; + F4E6EDA4284969E500766F9A /* ENDPOINTSECURITY_2.html in Resources */ = {isa = PBXBuildFile; fileRef = F4E6EDA2284969E500766F9A /* ENDPOINTSECURITY_2.html */; }; F4E861BA255496310061E203 /* CUIRawCrashLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E861B9255496310061E203 /* CUIRawCrashLog.m */; }; F4E91ADD256A98050017C3EE /* CUIFontBoxView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E91ADC256A98050017C3EE /* CUIFontBoxView.m */; }; F4EAFA2C24FA6CD100C0B729 /* CUICrashLogTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EAFA2B24FA6CD100C0B729 /* CUICrashLogTextView.m */; }; @@ -257,8 +327,8 @@ F4F9BAF224EF060E00D08FBD /* CUIInspectorUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F9BAF024EF060E00D08FBD /* CUIInspectorUserViewController.m */; }; F4F9BAF724EF06BC00D08FBD /* CUIInspectorGeneralViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F9BAF524EF06BC00D08FBD /* CUIInspectorGeneralViewController.m */; }; F4F9D3362556C7DB00D28E6E /* CUILineJumperWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F9D3342556C7DB00D28E6E /* CUILineJumperWindowController.m */; }; - F4FB9EA62579BAF700692B2A /* CUILineJumperWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4FB9EA52579BAF700692B2A /* CUILineJumperWindowController.xib */; }; - F4FC77A924E1F6AB001F82CA /* CUIRawTextTransformation.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FC77A824E1F6AA001F82CA /* CUIRawTextTransformation.m */; }; + F4FA4323273EF2F30068EDB8 /* NSString+CPU.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FA4322273EF2F30068EDB8 /* NSString+CPU.m */; }; + F4FC8EA727C1A6EE00291875 /* CUIReportThemedTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FC8EA627C1A6EE00291875 /* CUIReportThemedTransform.m */; }; F4FE2DEA25615CA800C1774A /* CUICrashLogExceptionInformation+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE2DE925615CA800C1774A /* CUICrashLogExceptionInformation+UI.m */; }; /* End PBXBuildFile section */ @@ -293,6 +363,17 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + D000743B2E11F30900CC5121 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = Help/ja.lproj/EXC_GUARD.html; sourceTree = ""; }; + D000743C2E11F30B00CC5121 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = es; path = Help/es.lproj/EXC_GUARD.html; sourceTree = ""; }; + D00B152C2E0B52740098456B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = fr; path = Help/fr.lproj/EXC_GUARD.html; sourceTree = ""; }; + D06294352E1DD8150008895D /* CUICodeSigningInformationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICodeSigningInformationViewController.h; sourceTree = ""; }; + D06294362E1DD8150008895D /* CUICodeSigningInformationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICodeSigningInformationViewController.m; sourceTree = ""; }; + D0790DBB2E00BACF00CD6A72 /* CUIThreadImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIThreadImageView.h; sourceTree = ""; }; + D0790DBC2E00BACF00CD6A72 /* CUIThreadImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIThreadImageView.m; sourceTree = ""; }; + D0AECAE42E0F34830028246E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = Help/he.lproj/EXC_GUARD.html; sourceTree = ""; }; + D0BA6A452E09FEB50010D630 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = en; path = Help/en.lproj/EXC_GUARD.html; sourceTree = ""; }; + D0BD22392F3FC6810052AD8E /* NSMenuItem+RSCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSMenuItem+RSCore.h"; path = "RSCore/NSMenuItem+RSCore.h"; sourceTree = ""; }; + D0BD223A2F3FC6810052AD8E /* NSMenuItem+RSCore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "NSMenuItem+RSCore.m"; path = "RSCore/NSMenuItem+RSCore.m"; sourceTree = ""; }; F4040A7424F5B9CE0072BF65 /* CUINavigationChevronView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUINavigationChevronView.h; sourceTree = ""; }; F4040A7524F5B9CE0072BF65 /* CUINavigationChevronView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUINavigationChevronView.m; sourceTree = ""; }; F4040A7724F5BC230072BF65 /* CUINavigationView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUINavigationView.h; sourceTree = ""; }; @@ -303,6 +384,9 @@ F405A96C255015D800AD2F24 /* CUICXXDemangler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = CUICXXDemangler.mm; path = app_unexpectedly/Demangling/CUICXXDemangler.mm; sourceTree = ""; }; F405A96E25501A5F00AD2F24 /* CUIParsingErrors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIParsingErrors.h; sourceTree = ""; }; F405A96F25501A5F00AD2F24 /* CUIParsingErrors.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIParsingErrors.m; sourceTree = ""; }; + F406B49A2687AB1400B90C7B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUIPreferencePaneAdvancedViewController.xib; sourceTree = ""; }; + F406B49C2687AB1800B90C7B /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUIPreferencePaneAdvancedViewController.xib; sourceTree = ""; }; + F406B49D2687AC1900B90C7B /* es */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = es; path = es.lproj/CUIPreferencePaneAdvancedViewController.xib; sourceTree = ""; }; F40ACE2B255697A3006855E5 /* CUICrashLogBrowsingState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashLogBrowsingState.h; sourceTree = ""; }; F40ACE2C255697A3006855E5 /* CUICrashLogBrowsingState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogBrowsingState.m; sourceTree = ""; }; F40ACE2E255697CE006855E5 /* CUICrashLogBrowsingStateRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashLogBrowsingStateRegistry.h; sourceTree = ""; }; @@ -428,25 +512,120 @@ F420F35124E95E5F006C82CD /* CUITheme.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUITheme.m; sourceTree = ""; }; F4214CB324B6534400852DDE /* CUICrashLogsSourcesManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashLogsSourcesManager.h; sourceTree = ""; }; F4214CB424B6534400852DDE /* CUICrashLogsSourcesManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogsSourcesManager.m; sourceTree = ""; }; + F4238189267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIPreferencePaneAdvancedViewController.h; sourceTree = ""; }; + F423818A267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIPreferencePaneAdvancedViewController.m; sourceTree = ""; }; + F423818F267D3521003837AC /* WBRemoteVersionChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBRemoteVersionChecker.h; sourceTree = ""; }; + F4238190267D3522003837AC /* WBRemoteVersionChecker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WBRemoteVersionChecker.m; sourceTree = ""; }; + F428C0412724592900FB8CAC /* IPSImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSImage.m; path = ../submodules/ips2crash/Model/IPSImage.m; sourceTree = ""; }; + F428C0422724592900FB8CAC /* IPSIncidentHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSIncidentHeader.m; path = ../submodules/ips2crash/Model/IPSIncidentHeader.m; sourceTree = ""; }; + F428C0432724592900FB8CAC /* IPSIncidentExceptionInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSIncidentExceptionInformation.m; path = ../submodules/ips2crash/Model/IPSIncidentExceptionInformation.m; sourceTree = ""; }; + F428C0442724592900FB8CAC /* IPSIncidentDiagnosticMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSIncidentDiagnosticMessage.m; path = ../submodules/ips2crash/Model/IPSIncidentDiagnosticMessage.m; sourceTree = ""; }; + F428C0452724592900FB8CAC /* IPSReport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSReport.m; path = ../submodules/ips2crash/Model/IPSReport.m; sourceTree = ""; }; + F428C0462724592900FB8CAC /* IPSThreadInstructionState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSThreadInstructionState.m; path = ../submodules/ips2crash/Model/IPSThreadInstructionState.m; sourceTree = ""; }; + F428C0472724592900FB8CAC /* IPSThreadInstructionStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSThreadInstructionStream.m; path = ../submodules/ips2crash/Model/IPSThreadInstructionStream.m; sourceTree = ""; }; + F428C0482724592900FB8CAC /* IPSIncident.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSIncident.h; path = ../submodules/ips2crash/Model/IPSIncident.h; sourceTree = ""; }; + F428C0492724592900FB8CAC /* IPSRegisterState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSRegisterState.m; path = ../submodules/ips2crash/Model/IPSRegisterState.m; sourceTree = ""; }; + F428C04A2724592A00FB8CAC /* IPSDateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSDateFormatter.m; path = ../submodules/ips2crash/Model/IPSDateFormatter.m; sourceTree = ""; }; + F428C04B2724592A00FB8CAC /* IPSApplicationSpecificInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSApplicationSpecificInformation.m; path = ../submodules/ips2crash/Model/IPSApplicationSpecificInformation.m; sourceTree = ""; }; + F428C04C2724592A00FB8CAC /* IPSSummary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSSummary.m; path = ../submodules/ips2crash/Model/IPSSummary.m; sourceTree = ""; }; + F428C04D2724592A00FB8CAC /* IPSTermination.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSTermination.m; path = ../submodules/ips2crash/Model/IPSTermination.m; sourceTree = ""; }; + F428C04E2724592A00FB8CAC /* IPSExternalModificationSummary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSExternalModificationSummary.m; path = ../submodules/ips2crash/Model/IPSExternalModificationSummary.m; sourceTree = ""; }; + F428C04F2724592A00FB8CAC /* IPSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSError.h; path = ../submodules/ips2crash/Model/IPSError.h; sourceTree = ""; }; + F428C0502724592A00FB8CAC /* IPSExternalModificationStatistics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSExternalModificationStatistics.m; path = ../submodules/ips2crash/Model/IPSExternalModificationStatistics.m; sourceTree = ""; }; + F428C0512724592A00FB8CAC /* IPSReport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSReport.h; path = ../submodules/ips2crash/Model/IPSReport.h; sourceTree = ""; }; + F428C0522724592A00FB8CAC /* IPSTermination.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSTermination.h; path = ../submodules/ips2crash/Model/IPSTermination.h; sourceTree = ""; }; + F428C0532724592A00FB8CAC /* IPSBundleInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSBundleInfo.m; path = ../submodules/ips2crash/Model/IPSBundleInfo.m; sourceTree = ""; }; + F428C0542724592A00FB8CAC /* IPSException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSException.m; path = ../submodules/ips2crash/Model/IPSException.m; sourceTree = ""; }; + F428C0552724592A00FB8CAC /* IPSObjectProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSObjectProtocol.h; path = ../submodules/ips2crash/Model/IPSObjectProtocol.h; sourceTree = ""; }; + F428C0562724592A00FB8CAC /* IPSSummary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSSummary.h; path = ../submodules/ips2crash/Model/IPSSummary.h; sourceTree = ""; }; + F428C0572724592A00FB8CAC /* IPSThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSThread.m; path = ../submodules/ips2crash/Model/IPSThread.m; sourceTree = ""; }; + F428C0582724592B00FB8CAC /* IPSIncidentExceptionInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSIncidentExceptionInformation.h; path = ../submodules/ips2crash/Model/IPSIncidentExceptionInformation.h; sourceTree = ""; }; + F428C0592724592B00FB8CAC /* IPSThreadFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSThreadFrame.m; path = ../submodules/ips2crash/Model/IPSThreadFrame.m; sourceTree = ""; }; + F428C05A2724592B00FB8CAC /* IPSExternalModificationSummary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSExternalModificationSummary.h; path = ../submodules/ips2crash/Model/IPSExternalModificationSummary.h; sourceTree = ""; }; + F428C05B2724592B00FB8CAC /* IPSError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSError.m; path = ../submodules/ips2crash/Model/IPSError.m; sourceTree = ""; }; + F428C05C2724592B00FB8CAC /* IPSDateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSDateFormatter.h; path = ../submodules/ips2crash/Model/IPSDateFormatter.h; sourceTree = ""; }; + F428C05D2724592B00FB8CAC /* IPSThreadFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSThreadFrame.h; path = ../submodules/ips2crash/Model/IPSThreadFrame.h; sourceTree = ""; }; + F428C05E2724592B00FB8CAC /* IPSOperatingSystemVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSOperatingSystemVersion.m; path = ../submodules/ips2crash/Model/IPSOperatingSystemVersion.m; sourceTree = ""; }; + F428C05F2724592B00FB8CAC /* IPSThreadInstructionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSThreadInstructionState.h; path = ../submodules/ips2crash/Model/IPSThreadInstructionState.h; sourceTree = ""; }; + F428C0602724592B00FB8CAC /* IPSThreadInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSThreadInstructionStream.h; path = ../submodules/ips2crash/Model/IPSThreadInstructionStream.h; sourceTree = ""; }; + F428C0612724592B00FB8CAC /* IPSThreadState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSThreadState.h; path = ../submodules/ips2crash/Model/IPSThreadState.h; sourceTree = ""; }; + F428C0622724592B00FB8CAC /* IPSThreadState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSThreadState.m; path = ../submodules/ips2crash/Model/IPSThreadState.m; sourceTree = ""; }; + F428C0632724592B00FB8CAC /* IPSImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSImage.h; path = ../submodules/ips2crash/Model/IPSImage.h; sourceTree = ""; }; + F428C0642724592C00FB8CAC /* IPSExternalModificationStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSExternalModificationStatistics.h; path = ../submodules/ips2crash/Model/IPSExternalModificationStatistics.h; sourceTree = ""; }; + F428C0652724592C00FB8CAC /* IPSApplicationSpecificInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSApplicationSpecificInformation.h; path = ../submodules/ips2crash/Model/IPSApplicationSpecificInformation.h; sourceTree = ""; }; + F428C0662724592C00FB8CAC /* IPSLegacyInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSLegacyInfo.h; path = ../submodules/ips2crash/Model/IPSLegacyInfo.h; sourceTree = ""; }; + F428C0672724592C00FB8CAC /* IPSBundleInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSBundleInfo.h; path = ../submodules/ips2crash/Model/IPSBundleInfo.h; sourceTree = ""; }; + F428C0682724592C00FB8CAC /* IPSLegacyInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSLegacyInfo.m; path = ../submodules/ips2crash/Model/IPSLegacyInfo.m; sourceTree = ""; }; + F428C0692724592C00FB8CAC /* IPSThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSThread.h; path = ../submodules/ips2crash/Model/IPSThread.h; sourceTree = ""; }; + F428C06A2724592C00FB8CAC /* IPSIncident.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSIncident.m; path = ../submodules/ips2crash/Model/IPSIncident.m; sourceTree = ""; }; + F428C06B2724592C00FB8CAC /* IPSIncidentDiagnosticMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSIncidentDiagnosticMessage.h; path = ../submodules/ips2crash/Model/IPSIncidentDiagnosticMessage.h; sourceTree = ""; }; + F428C06C2724592C00FB8CAC /* IPSRegisterState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSRegisterState.h; path = ../submodules/ips2crash/Model/IPSRegisterState.h; sourceTree = ""; }; + F428C06D2724592C00FB8CAC /* IPSIncidentHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSIncidentHeader.h; path = ../submodules/ips2crash/Model/IPSIncidentHeader.h; sourceTree = ""; }; + F428C06E2724592D00FB8CAC /* IPSOperatingSystemVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSOperatingSystemVersion.h; path = ../submodules/ips2crash/Model/IPSOperatingSystemVersion.h; sourceTree = ""; }; + F428C06F2724592D00FB8CAC /* IPSException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSException.h; path = ../submodules/ips2crash/Model/IPSException.h; sourceTree = ""; }; F42B57E024ABEF6E00F77ED5 /* CUICallsSelection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICallsSelection.h; sourceTree = ""; }; F42B57E124ABEF6E00F77ED5 /* CUICallsSelection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICallsSelection.m; sourceTree = ""; }; F42D0BC225514B2E0021A551 /* template.source */ = {isa = PBXFileReference; lastKnownFileType = text; path = template.source; sourceTree = ""; }; + F42E4FFF2724B7550092181A /* CUICrashDataTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashDataTransform.h; sourceTree = ""; }; + F42E50002724B7550092181A /* CUICrashDataTransform.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashDataTransform.m; sourceTree = ""; }; F4301A6925EF0DE000ACDA3F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUIPreferencePanePresentationViewController.xib; sourceTree = ""; }; F4301A6B25EF0DE200ACDA3F /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUIPreferencePanePresentationViewController.xib; sourceTree = ""; }; + F43066C52A12EDE4002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/RemoteCheck.strings; sourceTree = ""; }; + F43066C62A12EDE4002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIAboutBoxWindowController.xib; sourceTree = ""; }; + F43066C72A12EDE5002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePaneGeneralViewController.xib; sourceTree = ""; }; + F43066C82A12EDE5002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePanePresentationTextViewController.xib; sourceTree = ""; }; + F43066C92A12EDE5002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePanePresentationOutlineViewController.xib; sourceTree = ""; }; + F43066CA2A12EDE5002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePanePresentationViewController.xib; sourceTree = ""; }; + F43066CB2A12EDE5002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePaneFontscolorsViewController.xib; sourceTree = ""; }; + F43066CC2A12EDE5002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUISymbolsFilesLibraryViewController.xib; sourceTree = ""; }; + F43066CD2A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePaneSymbolicationViewController.xib; sourceTree = ""; }; + F43066CE2A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePaneCrashreporterViewController.xib; sourceTree = ""; }; + F43066CF2A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencePaneAdvancedViewController.xib; sourceTree = ""; }; + F43066D02A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIPreferencesWindowController.xib; sourceTree = ""; }; + F43066D12A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICrashLogsSourceSmartEditorWindowController.xib; sourceTree = ""; }; + F43066D22A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICrashLogsSourcesViewController.xib; sourceTree = ""; }; + F43066D32A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICrashLogsListViewController.xib; sourceTree = ""; }; + F43066D42A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIInspectorGeneralViewController.xib; sourceTree = ""; }; + F43066D52A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIInspectorUserViewController.xib; sourceTree = ""; }; + F43066D62A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIInspectorExecutableViewController.xib; sourceTree = ""; }; + F43066D72A12EDE6002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIInspectorProcessesViewController.xib; sourceTree = ""; }; + F43066D82A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/unknown_exception_type.html; sourceTree = ""; }; + F43066D92A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_BAD_ACCESS_SIGBUS.html; sourceTree = ""; }; + F43066DA2A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_BAD_ACCESS_SIGSEGV.html; sourceTree = ""; }; + F43066DB2A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_BAD_INSTRUCTION_SIGILL.html; sourceTree = ""; }; + F43066DC2A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_BREAKPOINT_SIGTRAP.html; sourceTree = ""; }; + F43066DD2A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_CRASH_SIGABRT.html; sourceTree = ""; }; + F43066DE2A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_CRASH_SIGKILL.html; sourceTree = ""; }; + F43066DF2A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_CRASH_SIGQUIT.html; sourceTree = ""; }; + F43066E02A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = he.lproj/EXC_CRASH_SIGSEGV.html; sourceTree = ""; }; + F43066E12A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = "he.lproj/EXC_CRASH_Code Signature Invalid.html"; sourceTree = ""; }; + F43066E22A12EDE7002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = Help/he.lproj/unknown_termination_reason.html; sourceTree = ""; }; + F43066E32A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = he; path = Help/he.lproj/ENDPOINTSECURITY_2.html; sourceTree = ""; }; + F43066E42A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUILineJumperWindowController.xib; sourceTree = ""; }; + F43066E52A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIExportAccessoryViewController.xib; sourceTree = ""; }; + F43066E62A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICrashLogPresentationTextViewController.xib; sourceTree = ""; }; + F43066E72A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICrashLogPresentationOutlineViewController.xib; sourceTree = ""; }; + F43066E82A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICollectionViewRegisterItem.xib; sourceTree = ""; }; + F43066E92A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIBinaryImagesViewController.xib; sourceTree = ""; }; + F43066EA2A12EDE8002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUIMainWindowController.xib; sourceTree = ""; }; + F43066EB2A12EDE8002AB430 /* he */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = ""; }; + F43066EC2A12EDE9002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Predicates.strings; sourceTree = ""; }; + F43066ED2A12EDE9002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/MainMenu.xib; sourceTree = ""; }; + F43066EE2A12EDE9002AB430 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/InfoPlist.strings; sourceTree = ""; }; F4306D572577E168007E667F /* CUICrashLogThreadState+UI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CUICrashLogThreadState+UI.h"; sourceTree = ""; }; F4306D582577E168007E667F /* CUICrashLogThreadState+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUICrashLogThreadState+UI.m"; sourceTree = ""; }; F432ACC524A95014000A3E7A /* CUIThreadsListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUIThreadsListViewController.h; sourceTree = ""; }; F432ACC624A95014000A3E7A /* CUIThreadsListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUIThreadsListViewController.m; sourceTree = ""; }; - F432ACC724A95014000A3E7A /* CUIThreadsListViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUIThreadsListViewController.xib; sourceTree = ""; }; F432ACCA24A9502A000A3E7A /* CUIThreadsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUIThreadsViewController.h; sourceTree = ""; }; F432ACCB24A9502A000A3E7A /* CUIThreadsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUIThreadsViewController.m; sourceTree = ""; }; F432ACCD24A95042000A3E7A /* CUIThreadsColumnViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUIThreadsColumnViewController.h; sourceTree = ""; }; F432ACCE24A95042000A3E7A /* CUIThreadsColumnViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUIThreadsColumnViewController.m; sourceTree = ""; }; - F432ACCF24A95042000A3E7A /* CUIThreadsColumnViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUIThreadsColumnViewController.xib; sourceTree = ""; }; F43362FC25FCEFBA006E7894 /* CUIRawCrashLog+Path.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CUIRawCrashLog+Path.h"; sourceTree = ""; }; F43362FD25FCEFBA006E7894 /* CUIRawCrashLog+Path.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUIRawCrashLog+Path.m"; sourceTree = ""; }; F4341C69258EB8FE001A5605 /* CUICrashReporterDefaults.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashReporterDefaults.h; sourceTree = ""; }; F4341C6A258EB8FE001A5605 /* CUICrashReporterDefaults.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashReporterDefaults.m; sourceTree = ""; }; + F4386B0D2849541B00B83525 /* CUICrashLogExceptionInformation+QuickHelp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CUICrashLogExceptionInformation+QuickHelp.m"; sourceTree = ""; }; + F4386B0E2849541B00B83525 /* CUICrashLogExceptionInformation+QuickHelp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CUICrashLogExceptionInformation+QuickHelp.h"; sourceTree = ""; }; F43A9A812591260C005AB2AA /* CUIOutlineModeDisplaySettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIOutlineModeDisplaySettings.h; sourceTree = ""; }; F43A9A822591260C005AB2AA /* CUIOutlineModeDisplaySettings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIOutlineModeDisplaySettings.m; sourceTree = ""; }; F43AF0CF256FE2AE0066CA1B /* DWRFSection_debug_addr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DWRFSection_debug_addr.h; path = app_unexpectedly/DWARF/DWRFSection_debug_addr.h; sourceTree = ""; }; @@ -469,12 +648,16 @@ F440A3EB24AA38E600C23DA1 /* CUICrashLogsSourceAll.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogsSourceAll.m; sourceTree = ""; }; F442FCEA24AB855C00E87B69 /* CUIBinaryImagesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIBinaryImagesViewController.h; sourceTree = ""; }; F442FCEB24AB855C00E87B69 /* CUIBinaryImagesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIBinaryImagesViewController.m; sourceTree = ""; }; - F442FCEF24AB8A8B00E87B69 /* CUIBinaryImage+UI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CUIBinaryImage+UI.h"; sourceTree = ""; }; - F442FCF024AB8A8B00E87B69 /* CUIBinaryImage+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUIBinaryImage+UI.m"; sourceTree = ""; }; + F442FCEF24AB8A8B00E87B69 /* CUIBinaryImageUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIBinaryImageUtility.h; sourceTree = ""; }; + F442FCF024AB8A8B00E87B69 /* CUIBinaryImageUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIBinaryImageUtility.m; sourceTree = ""; }; F44356F024A8A113001D3D35 /* CUICrashLogPresentationOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUICrashLogPresentationOutlineViewController.h; sourceTree = ""; }; F44356F124A8A113001D3D35 /* CUICrashLogPresentationOutlineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogPresentationOutlineViewController.m; sourceTree = ""; }; F44356FD24A8A8B5001D3D35 /* CUIThreadNamedTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUIThreadNamedTableCellView.h; sourceTree = ""; }; F44356FE24A8A8B5001D3D35 /* CUIThreadNamedTableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUIThreadNamedTableCellView.m; sourceTree = ""; }; + F4440FDC282C4103003C810B /* IPSSummarySerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSSummarySerialization.m; path = ../submodules/ips2crash/Model/IPSSummarySerialization.m; sourceTree = ""; }; + F4440FDD282C4103003C810B /* IPSCrashSummary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSCrashSummary.m; path = ../submodules/ips2crash/Model/IPSCrashSummary.m; sourceTree = ""; }; + F4440FDE282C4103003C810B /* IPSSummarySerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSSummarySerialization.h; path = ../submodules/ips2crash/Model/IPSSummarySerialization.h; sourceTree = ""; }; + F4440FDF282C4103003C810B /* IPSCrashSummary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSCrashSummary.h; path = ../submodules/ips2crash/Model/IPSCrashSummary.h; sourceTree = ""; }; F44A5F2D24CCDCB1006B59B8 /* CUICollectionViewDockedThreadItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICollectionViewDockedThreadItem.h; sourceTree = ""; }; F44A5F2E24CCDCB1006B59B8 /* CUICollectionViewDockedThreadItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICollectionViewDockedThreadItem.m; sourceTree = ""; }; F44A5F2F24CCDCB1006B59B8 /* CUICollectionViewDockedThreadItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CUICollectionViewDockedThreadItem.xib; sourceTree = ""; }; @@ -530,6 +713,16 @@ F45A2D7425EC60DB0007D50E /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUICrashLogsListViewController.xib; sourceTree = ""; }; F45B518A24AFA04000E97B87 /* CUICrashLogsSelection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashLogsSelection.h; sourceTree = ""; }; F45B518B24AFA04000E97B87 /* CUICrashLogsSelection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogsSelection.m; sourceTree = ""; }; + F45DED6A2E350F07008F4CE8 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUICodeSigningInformationViewController.xib; sourceTree = ""; }; + F45DED6C2E350F0D008F4CE8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUICodeSigningInformationViewController.xib; sourceTree = ""; }; + F45DED6E2E3510D9008F4CE8 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/CodeSigning.strings; sourceTree = ""; }; + F45DED702E351134008F4CE8 /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/CodeSigning.strings; sourceTree = ""; }; + F45DED712E3511B8008F4CE8 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/CodeSigning.strings; sourceTree = ""; }; + F45DED722E3511BB008F4CE8 /* ja */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/CodeSigning.strings; sourceTree = ""; }; + F45DED732E3511BC008F4CE8 /* he */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/CodeSigning.strings; sourceTree = ""; }; + F45DED742E351277008F4CE8 /* es */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = es; path = es.lproj/CUICodeSigningInformationViewController.xib; sourceTree = ""; }; + F45DED752E351279008F4CE8 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICodeSigningInformationViewController.xib; sourceTree = ""; }; + F45DED762E35127A008F4CE8 /* he */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = he; path = he.lproj/CUICodeSigningInformationViewController.xib; sourceTree = ""; }; F45F2F592538EF3F0030A402 /* NSFileManager+ExtendedAttributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSFileManager+ExtendedAttributes.h"; path = "app_unexpectedly/NSFileManager+ExtendedAttributes.h"; sourceTree = ""; }; F45F2F5A2538EF3F0030A402 /* NSFileManager+ExtendedAttributes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "NSFileManager+ExtendedAttributes.m"; path = "app_unexpectedly/NSFileManager+ExtendedAttributes.m"; sourceTree = ""; }; F45F84D3266ABB5800F354F3 /* crashreport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = crashreport.xcodeproj; path = ../plugin_quicklook/crashreport.xcodeproj; sourceTree = ""; }; @@ -571,6 +764,8 @@ F472CC962550631A003F6338 /* CUISwiftDemangler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CUISwiftDemangler.m; path = app_unexpectedly/Demangling/CUISwiftDemangler.m; sourceTree = ""; }; F4754D7225F5678700B0D48F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUICrashLogPresentationOutlineViewController.xib; sourceTree = ""; }; F4754D7425F5678A00B0D48F /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUICrashLogPresentationOutlineViewController.xib; sourceTree = ""; }; + F475FB3E26DBAC8200A113D8 /* CUITableViewNoSpace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUITableViewNoSpace.h; sourceTree = ""; }; + F475FB3F26DBAC8200A113D8 /* CUITableViewNoSpace.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUITableViewNoSpace.m; sourceTree = ""; }; F476EEBC25686DEF00F40F87 /* CUIAboutBoxFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUIAboutBoxFooterView.h; sourceTree = ""; }; F476EEBD25686DEF00F40F87 /* CUIAboutBoxFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUIAboutBoxFooterView.m; sourceTree = ""; }; F476EEBF25686EC000F40F87 /* CUIContentBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUIContentBox.m; sourceTree = ""; }; @@ -579,6 +774,10 @@ F4775478255B0054006BA662 /* CUIThemesTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIThemesTableView.m; sourceTree = ""; }; F47AF8BE255DE61E0037E2D8 /* NSCrashLogTextScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSCrashLogTextScrollView.h; sourceTree = ""; }; F47AF8BF255DE61E0037E2D8 /* NSCrashLogTextScrollView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSCrashLogTextScrollView.m; sourceTree = ""; }; + F47C381C2A422E880020D88F /* CUIThreadsListViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUIThreadsListViewController.xib; sourceTree = ""; }; + F47C381D2A422E880020D88F /* CUIThreadsListViewController_RTL.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUIThreadsListViewController_RTL.xib; sourceTree = ""; }; + F47C38202A4230370020D88F /* CUIThreadsColumnViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUIThreadsColumnViewController.xib; sourceTree = ""; }; + F47C38212A4230370020D88F /* CUIThreadsColumnViewController_RTL.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUIThreadsColumnViewController_RTL.xib; sourceTree = ""; }; F47F76602673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CUICrashLogsOpenErrorRecord+UI.h"; sourceTree = ""; }; F47F76612673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUICrashLogsOpenErrorRecord+UI.m"; sourceTree = ""; }; F47F76632673548600A74905 /* CUICrashLogsOpenErrorRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashLogsOpenErrorRecord.h; sourceTree = ""; }; @@ -621,6 +820,10 @@ F48906AD25D2BA0C002D79A9 /* CUISelectedWhiteTextFieldCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUISelectedWhiteTextFieldCell.m; sourceTree = ""; }; F489441F2545836F00E3E360 /* CUISymbolsFilesLibraryViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUISymbolsFilesLibraryViewController.h; sourceTree = ""; }; F48944202545836F00E3E360 /* CUISymbolsFilesLibraryViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUISymbolsFilesLibraryViewController.m; sourceTree = ""; }; + F4895F5827A72D1000D75369 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUILineJumperWindowController.xib; sourceTree = ""; }; + F4895F5A27A72D1300D75369 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUILineJumperWindowController.xib; sourceTree = ""; }; + F4895F5B27A72D3300D75369 /* es */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = es; path = es.lproj/CUILineJumperWindowController.xib; sourceTree = ""; }; + F4895F5C27A72D6300D75369 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUILineJumperWindowController.xib; sourceTree = ""; }; F48BAB3425D9D4140005F3E5 /* CUIThreadImageCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIThreadImageCell.h; sourceTree = ""; }; F48BAB3525D9D4140005F3E5 /* CUIThreadImageCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIThreadImageCell.m; sourceTree = ""; }; F48CF60024A969B5002AD214 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; @@ -711,6 +914,10 @@ F4B57C0B24AF5607000851FF /* CUICrashLogsSourceToday.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogsSourceToday.m; sourceTree = ""; }; F4B57C0D24AF5655000851FF /* CUICrashLogsSourceToday+UI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CUICrashLogsSourceToday+UI.h"; sourceTree = ""; }; F4B57C0E24AF5655000851FF /* CUICrashLogsSourceToday+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUICrashLogsSourceToday+UI.m"; sourceTree = ""; }; + F4B5BE6C2848277400C33F6F /* CUIExceptionTypePopUpViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIExceptionTypePopUpViewController.h; sourceTree = ""; }; + F4B5BE6D2848277400C33F6F /* CUIExceptionTypePopUpViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIExceptionTypePopUpViewController.m; sourceTree = ""; }; + F4B5BE6F28482A4300C33F6F /* CUITerminationReasonPopUpViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUITerminationReasonPopUpViewController.h; sourceTree = ""; }; + F4B5BE7028482A4300C33F6F /* CUITerminationReasonPopUpViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUITerminationReasonPopUpViewController.m; sourceTree = ""; }; F4B649D024EDCD2300008C47 /* CUIInspectorExecutableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIInspectorExecutableViewController.h; sourceTree = ""; }; F4B649D124EDCD2300008C47 /* CUIInspectorExecutableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIInspectorExecutableViewController.m; sourceTree = ""; }; F4B649D524EDD09A00008C47 /* CUIInspectorStackableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIInspectorStackableViewController.h; sourceTree = ""; }; @@ -744,13 +951,15 @@ F4BC577024DF426200063545 /* CUIAATextFieldCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIAATextFieldCell.m; sourceTree = ""; }; F4BD69FE25553E8F00F98F3E /* CUICrashLogSectionsDetector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICrashLogSectionsDetector.h; sourceTree = ""; }; F4BD69FF25553E9000F98F3E /* CUICrashLogSectionsDetector.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICrashLogSectionsDetector.m; sourceTree = ""; }; + F4BD8C682DF4DDCA00BD61A8 /* IPSExceptionReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSExceptionReason.h; path = ../submodules/ips2crash/Model/IPSExceptionReason.h; sourceTree = ""; }; + F4BD8C692DF4DDCA00BD61A8 /* IPSExceptionReason.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSExceptionReason.m; path = ../submodules/ips2crash/Model/IPSExceptionReason.m; sourceTree = ""; }; F4C269CB2503BCC100C8F3B3 /* CUISymbolicationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUISymbolicationManager.h; sourceTree = ""; }; F4C269CC2503BCC100C8F3B3 /* CUISymbolicationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUISymbolicationManager.m; sourceTree = ""; }; F4C269CE2503BE6500C8F3B3 /* CUISymbolicationData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUISymbolicationData.h; sourceTree = ""; }; F4C269CF2503BE6500C8F3B3 /* CUISymbolicationData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUISymbolicationData.m; sourceTree = ""; }; - F4C7498B24F84689004F38C0 /* CUIExceptionTypePopUpViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIExceptionTypePopUpViewController.h; sourceTree = ""; }; - F4C7498C24F84689004F38C0 /* CUIExceptionTypePopUpViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIExceptionTypePopUpViewController.m; sourceTree = ""; }; - F4C7498D24F84689004F38C0 /* CUIExceptionTypePopUpViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CUIExceptionTypePopUpViewController.xib; sourceTree = ""; }; + F4C7498B24F84689004F38C0 /* CUIQuickHelpPopUpViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIQuickHelpPopUpViewController.h; sourceTree = ""; }; + F4C7498C24F84689004F38C0 /* CUIQuickHelpPopUpViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIQuickHelpPopUpViewController.m; sourceTree = ""; }; + F4C7498D24F84689004F38C0 /* CUIQuickHelpPopUpViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CUIQuickHelpPopUpViewController.xib; sourceTree = ""; }; F4CC56FF24A79EDA00150EC4 /* Unexpectedly.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Unexpectedly.app; sourceTree = BUILT_PRODUCTS_DIR; }; F4CC570324A79EDA00150EC4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F4CC570424A79EDA00150EC4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -777,13 +986,61 @@ F4CCCC6D24AE9EDA0031BC27 /* CUICrashLogsSource+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUICrashLogsSource+UI.m"; sourceTree = ""; }; F4CD32B3257D17B3008C71AA /* CUIPreferencePaneSymbolicationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIPreferencePaneSymbolicationViewController.h; sourceTree = ""; }; F4CD32B4257D17B3008C71AA /* CUIPreferencePaneSymbolicationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIPreferencePaneSymbolicationViewController.m; sourceTree = ""; }; + F4CE09A42A76E43300BACB71 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = es; path = Help/es.lproj/ENDPOINTSECURITY_2.html; sourceTree = ""; }; + F4CE09A52A76E44D00BACB71 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = Help/ja.lproj/ENDPOINTSECURITY_2.html; sourceTree = ""; }; F4CE83DD2554B97300A8BD87 /* CUICenteredLabelViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CUICenteredLabelViewController.xib; sourceTree = ""; }; + F4CF6CF42DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSIncident+ApplicationSpecificInformation.m"; path = "../submodules/ips2crash/tool_ips2crash/ips2crash/IPSIncident+ApplicationSpecificInformation.m"; sourceTree = ""; }; + F4CF6CF52DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSIncident+ApplicationSpecificInformation.h"; path = "../submodules/ips2crash/tool_ips2crash/ips2crash/IPSIncident+ApplicationSpecificInformation.h"; sourceTree = ""; }; + F4D0EE93273DB8CC00CC9737 /* IPSThreadState+RegisterDisplayName.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSThreadState+RegisterDisplayName.m"; path = "../submodules/ips2crash/tool_ips2crash/ips2crash/IPSThreadState+RegisterDisplayName.m"; sourceTree = ""; }; + F4D0EE94273DB8CC00CC9737 /* IPSThreadState+RegisterDisplayName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSThreadState+RegisterDisplayName.h"; path = "../submodules/ips2crash/tool_ips2crash/ips2crash/IPSThreadState+RegisterDisplayName.h"; sourceTree = ""; }; + F4D14D662745C0A9003698AD /* IPSImage+UserCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSImage+UserCode.m"; path = "../submodules/ips2crash/tool_ips2crash/ips2crash/IPSImage+UserCode.m"; sourceTree = ""; }; + F4D14D672745C0A9003698AD /* IPSImage+UserCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSImage+UserCode.h"; path = "../submodules/ips2crash/tool_ips2crash/ips2crash/IPSImage+UserCode.h"; sourceTree = ""; }; F4D5C77A2571AF900029B051 /* CUIRegisterLabel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIRegisterLabel.h; sourceTree = ""; }; F4D5C77B2571AF900029B051 /* CUIRegisterLabel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIRegisterLabel.m; sourceTree = ""; }; + F4D6C56C2680028A00B78B3D /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/RemoteCheck.strings; sourceTree = ""; }; + F4D6C56E268002DE00B78B3D /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/RemoteCheck.strings; sourceTree = ""; }; + F4D6C56F2680031E00B78B3D /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/RemoteCheck.strings; sourceTree = ""; }; F4D7F15C25F04A620024E9A5 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUISymbolsFilesLibraryViewController.xib; sourceTree = ""; }; F4D7F15E25F04A630024E9A5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUISymbolsFilesLibraryViewController.xib; sourceTree = ""; }; F4D7F16025F04A9D0024E9A5 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CUIPreferencePaneSymbolicationViewController.xib; sourceTree = ""; }; F4D7F16225F04A9E0024E9A5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CUIPreferencePaneSymbolicationViewController.xib; sourceTree = ""; }; + F4DAF0B127C44AA700256EA4 /* IPSImage+Offset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSImage+Offset.h"; path = "app_unexpectedly/ips + Extensions/IPSImage+Offset.h"; sourceTree = ""; }; + F4DAF0B227C44AA700256EA4 /* IPSImage+Offset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSImage+Offset.m"; path = "app_unexpectedly/ips + Extensions/IPSImage+Offset.m"; sourceTree = ""; }; + F4DAFBEC2736B7B200FB50A6 /* CUIIPSTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIIPSTransform.h; sourceTree = ""; }; + F4DAFBED2736B7B200FB50A6 /* CUIIPSTransform.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIIPSTransform.m; sourceTree = ""; }; + F4DAFBEF2736B7D500FB50A6 /* CUIDataTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIDataTransform.h; sourceTree = ""; }; + F4DAFBF02736B7D500FB50A6 /* CUIDataTransform.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIDataTransform.m; sourceTree = ""; }; + F4DF813B2893463B008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSIncidentDiagnosticMessage+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncidentDiagnosticMessage+Obfuscating.h"; sourceTree = ""; }; + F4DF813C2893463B008EF1B3 /* IPSThreadState+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSThreadState+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSThreadState+Obfuscating.m"; sourceTree = ""; }; + F4DF813D2893463B008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSIncidentDiagnosticMessage+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncidentDiagnosticMessage+Obfuscating.m"; sourceTree = ""; }; + F4DF813E2893463B008EF1B3 /* IPSObfuscator+Extended.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSObfuscator+Extended.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSObfuscator+Extended.h"; sourceTree = ""; }; + F4DF813F2893463B008EF1B3 /* IPSThreadState+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSThreadState+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSThreadState+Obfuscating.h"; sourceTree = ""; }; + F4DF81402893463B008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSApplicationSpecificInformation+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSApplicationSpecificInformation+Obfuscating.m"; sourceTree = ""; }; + F4DF81412893463B008EF1B3 /* IPSObfuscator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPSObfuscator.h; path = "../submodules/ips2crash/Model + Obfuscating/IPSObfuscator.h"; sourceTree = ""; }; + F4DF81422893463C008EF1B3 /* IPSBundleInfo+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSBundleInfo+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSBundleInfo+Obfuscating.h"; sourceTree = ""; }; + F4DF81432893463C008EF1B3 /* IPSIncidentHeader+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSIncidentHeader+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncidentHeader+Obfuscating.m"; sourceTree = ""; }; + F4DF81442893463C008EF1B3 /* IPSLegacyInfo+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSLegacyInfo+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSLegacyInfo+Obfuscating.h"; sourceTree = ""; }; + F4DF81452893463C008EF1B3 /* IPSIncident+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSIncident+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncident+Obfuscating.h"; sourceTree = ""; }; + F4DF81462893463C008EF1B3 /* IPSObfuscator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IPSObfuscator.m; path = "../submodules/ips2crash/Model + Obfuscating/IPSObfuscator.m"; sourceTree = ""; }; + F4DF81472893463C008EF1B3 /* IPSCrashSummary+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSCrashSummary+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSCrashSummary+Obfuscating.m"; sourceTree = ""; }; + F4DF81482893463C008EF1B3 /* IPSImage+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSImage+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSImage+Obfuscating.h"; sourceTree = ""; }; + F4DF81492893463C008EF1B3 /* IPSThread+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSThread+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSThread+Obfuscating.m"; sourceTree = ""; }; + F4DF814A2893463C008EF1B3 /* IPSThreadFrame+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSThreadFrame+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSThreadFrame+Obfuscating.m"; sourceTree = ""; }; + F4DF814B2893463C008EF1B3 /* IPSRegisterState+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSRegisterState+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSRegisterState+Obfuscating.m"; sourceTree = ""; }; + F4DF814C2893463C008EF1B3 /* IPSReport+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSReport+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSReport+Obfuscating.h"; sourceTree = ""; }; + F4DF814D2893463C008EF1B3 /* IPSIncidentHeader+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSIncidentHeader+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncidentHeader+Obfuscating.h"; sourceTree = ""; }; + F4DF814E2893463D008EF1B3 /* IPSCrashSummary+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSCrashSummary+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSCrashSummary+Obfuscating.h"; sourceTree = ""; }; + F4DF814F2893463D008EF1B3 /* IPSImage+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSImage+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSImage+Obfuscating.m"; sourceTree = ""; }; + F4DF81502893463D008EF1B3 /* IPSLegacyInfo+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSLegacyInfo+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSLegacyInfo+Obfuscating.m"; sourceTree = ""; }; + F4DF81512893463D008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSApplicationSpecificInformation+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSApplicationSpecificInformation+Obfuscating.h"; sourceTree = ""; }; + F4DF81522893463D008EF1B3 /* IPSReport+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSReport+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSReport+Obfuscating.m"; sourceTree = ""; }; + F4DF81532893463D008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSIncidentExceptionInformation+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncidentExceptionInformation+Obfuscating.h"; sourceTree = ""; }; + F4DF81542893463D008EF1B3 /* IPSThreadFrame+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSThreadFrame+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSThreadFrame+Obfuscating.h"; sourceTree = ""; }; + F4DF81552893463D008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSIncidentExceptionInformation+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncidentExceptionInformation+Obfuscating.m"; sourceTree = ""; }; + F4DF81562893463D008EF1B3 /* IPSBundleInfo+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSBundleInfo+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSBundleInfo+Obfuscating.m"; sourceTree = ""; }; + F4DF81572893463D008EF1B3 /* IPSIncident+Obfuscating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IPSIncident+Obfuscating.m"; path = "../submodules/ips2crash/Model + Obfuscating/IPSIncident+Obfuscating.m"; sourceTree = ""; }; + F4DF81582893463D008EF1B3 /* IPSThread+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSThread+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSThread+Obfuscating.h"; sourceTree = ""; }; + F4DF81592893463E008EF1B3 /* IPSRegisterState+Obfuscating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IPSRegisterState+Obfuscating.h"; path = "../submodules/ips2crash/Model + Obfuscating/IPSRegisterState+Obfuscating.h"; sourceTree = ""; }; F4E0BD23262078220048647C /* CUIAboutBoxWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIAboutBoxWindow.h; sourceTree = ""; }; F4E0BD24262078220048647C /* CUIAboutBoxWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIAboutBoxWindow.m; sourceTree = ""; }; F4E1C11124C22CF5000F5C0F /* CUILightTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUILightTableViewController.h; sourceTree = ""; }; @@ -798,6 +1055,16 @@ F4E1C11F24C22FB5000F5C0F /* CUILightTableVisibleThreadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUILightTableVisibleThreadView.m; sourceTree = ""; }; F4E1C12124C22FEE000F5C0F /* CUILightTableVisibleInterGapView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUILightTableVisibleInterGapView.h; sourceTree = ""; }; F4E1C12224C22FEE000F5C0F /* CUILightTableVisibleInterGapView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUILightTableVisibleInterGapView.m; sourceTree = ""; }; + F4E671902E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUICodeSigningFlagsTableView.h; sourceTree = ""; }; + F4E671912E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUICodeSigningFlagsTableView.m; sourceTree = ""; }; + F4E671942E2C405F00E5A064 /* CodeSigningFlags.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = CodeSigningFlags.plist; sourceTree = ""; }; + F4E6ED9B2849695100766F9A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = en; path = Help/en.lproj/unknown_termination_reason.html; sourceTree = ""; }; + F4E6ED9D2849696000766F9A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = es; path = Help/es.lproj/unknown_termination_reason.html; sourceTree = ""; }; + F4E6ED9E2849696600766F9A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = fr; path = Help/fr.lproj/unknown_termination_reason.html; sourceTree = ""; }; + F4E6ED9F2849696C00766F9A /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = Help/ja.lproj/unknown_termination_reason.html; sourceTree = ""; }; + F4E6EDA0284969DD00766F9A /* known_termination_reasons.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = known_termination_reasons.css; path = Help/known_termination_reasons.css; sourceTree = ""; }; + F4E6EDA3284969E500766F9A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = en; path = Help/en.lproj/ENDPOINTSECURITY_2.html; sourceTree = ""; }; + F4E6EDA528496E2A00766F9A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = fr; path = Help/fr.lproj/ENDPOINTSECURITY_2.html; sourceTree = ""; }; F4E861B8255496310061E203 /* CUIRawCrashLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIRawCrashLog.h; sourceTree = ""; }; F4E861B9255496310061E203 /* CUIRawCrashLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIRawCrashLog.m; sourceTree = ""; }; F4E91ADB256A98050017C3EE /* CUIFontBoxView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIFontBoxView.h; sourceTree = ""; }; @@ -837,9 +1104,49 @@ F4F9BAF524EF06BC00D08FBD /* CUIInspectorGeneralViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIInspectorGeneralViewController.m; sourceTree = ""; }; F4F9D3332556C7DB00D28E6E /* CUILineJumperWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUILineJumperWindowController.h; sourceTree = ""; }; F4F9D3342556C7DB00D28E6E /* CUILineJumperWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUILineJumperWindowController.m; sourceTree = ""; }; - F4FB9EA52579BAF700692B2A /* CUILineJumperWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CUILineJumperWindowController.xib; sourceTree = ""; }; - F4FC77A724E1F6AA001F82CA /* CUIRawTextTransformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIRawTextTransformation.h; sourceTree = ""; }; - F4FC77A824E1F6AA001F82CA /* CUIRawTextTransformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIRawTextTransformation.m; sourceTree = ""; }; + F4FA4321273EF2F30068EDB8 /* NSString+CPU.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSString+CPU.h"; path = "Foundation + Extensions/NSString+CPU.h"; sourceTree = ""; }; + F4FA4322273EF2F30068EDB8 /* NSString+CPU.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "NSString+CPU.m"; path = "Foundation + Extensions/NSString+CPU.m"; sourceTree = ""; }; + F4FC3629278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/RemoteCheck.strings; sourceTree = ""; }; + F4FC362A278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIAboutBoxWindowController.xib; sourceTree = ""; }; + F4FC362B278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePaneGeneralViewController.xib; sourceTree = ""; }; + F4FC362C278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePanePresentationTextViewController.xib; sourceTree = ""; }; + F4FC362D278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePanePresentationOutlineViewController.xib; sourceTree = ""; }; + F4FC362E278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePanePresentationViewController.xib; sourceTree = ""; }; + F4FC362F278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePaneFontscolorsViewController.xib; sourceTree = ""; }; + F4FC3630278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUISymbolsFilesLibraryViewController.xib; sourceTree = ""; }; + F4FC3631278F914200669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePaneSymbolicationViewController.xib; sourceTree = ""; }; + F4FC3632278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePaneCrashreporterViewController.xib; sourceTree = ""; }; + F4FC3633278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencePaneAdvancedViewController.xib; sourceTree = ""; }; + F4FC3634278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIPreferencesWindowController.xib; sourceTree = ""; }; + F4FC3635278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICrashLogsSourceSmartEditorWindowController.xib; sourceTree = ""; }; + F4FC3636278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICrashLogsSourcesViewController.xib; sourceTree = ""; }; + F4FC3637278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICrashLogsListViewController.xib; sourceTree = ""; }; + F4FC3638278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIInspectorGeneralViewController.xib; sourceTree = ""; }; + F4FC3639278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIInspectorUserViewController.xib; sourceTree = ""; }; + F4FC363A278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIInspectorExecutableViewController.xib; sourceTree = ""; }; + F4FC363B278F914300669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIInspectorProcessesViewController.xib; sourceTree = ""; }; + F4FC363C278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/unknown_exception_type.html; sourceTree = ""; }; + F4FC363D278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_BAD_ACCESS_SIGBUS.html; sourceTree = ""; }; + F4FC363E278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_BAD_ACCESS_SIGSEGV.html; sourceTree = ""; }; + F4FC363F278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_BAD_INSTRUCTION_SIGILL.html; sourceTree = ""; }; + F4FC3640278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_BREAKPOINT_SIGTRAP.html; sourceTree = ""; }; + F4FC3641278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_CRASH_SIGABRT.html; sourceTree = ""; }; + F4FC3642278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_CRASH_SIGKILL.html; sourceTree = ""; }; + F4FC3643278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_CRASH_SIGQUIT.html; sourceTree = ""; }; + F4FC3644278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = ja.lproj/EXC_CRASH_SIGSEGV.html; sourceTree = ""; }; + F4FC3645278F914400669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ja; path = "ja.lproj/EXC_CRASH_Code Signature Invalid.html"; sourceTree = ""; }; + F4FC3646278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIExportAccessoryViewController.xib; sourceTree = ""; }; + F4FC3647278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICrashLogPresentationTextViewController.xib; sourceTree = ""; }; + F4FC3648278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICrashLogPresentationOutlineViewController.xib; sourceTree = ""; }; + F4FC3649278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUICollectionViewRegisterItem.xib; sourceTree = ""; }; + F4FC364A278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIBinaryImagesViewController.xib; sourceTree = ""; }; + F4FC364B278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/CUIMainWindowController.xib; sourceTree = ""; }; + F4FC364C278F914500669B32 /* ja */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; + F4FC364D278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Predicates.strings; sourceTree = ""; }; + F4FC364E278F914500669B32 /* ja */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ja; path = ja.lproj/MainMenu.xib; sourceTree = ""; }; + F4FC364F278F914500669B32 /* ja */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; + F4FC8EA527C1A6EE00291875 /* CUIReportThemedTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIReportThemedTransform.h; sourceTree = ""; }; + F4FC8EA627C1A6EE00291875 /* CUIReportThemedTransform.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CUIReportThemedTransform.m; sourceTree = ""; }; F4FE2DE525613B5400C1774A /* CUIKeyViews.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUIKeyViews.h; sourceTree = ""; }; F4FE2DE825615CA800C1774A /* CUICrashLogExceptionInformation+UI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CUICrashLogExceptionInformation+UI.h"; sourceTree = ""; }; F4FE2DE925615CA800C1774A /* CUICrashLogExceptionInformation+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CUICrashLogExceptionInformation+UI.m"; sourceTree = ""; }; @@ -856,6 +1163,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D0BD22382F3FC6430052AD8E /* RSCore */ = { + isa = PBXGroup; + children = ( + D0BD22392F3FC6810052AD8E /* NSMenuItem+RSCore.h */, + D0BD223A2F3FC6810052AD8E /* NSMenuItem+RSCore.m */, + ); + name = RSCore; + sourceTree = ""; + }; F4040A7324F5B9B40072BF65 /* Views */ = { isa = PBXGroup; children = ( @@ -928,6 +1244,8 @@ F45F2F5A2538EF3F0030A402 /* NSFileManager+ExtendedAttributes.m */, F464FA1325D2DA2A00E024A3 /* NSSet+WBExtensions.h */, F464FA1425D2DA2A00E024A3 /* NSSet+WBExtensions.m */, + F4FA4321273EF2F30068EDB8 /* NSString+CPU.h */, + F4FA4322273EF2F30068EDB8 /* NSString+CPU.m */, ); name = "Foundation + Extensions"; sourceTree = ""; @@ -960,6 +1278,16 @@ name = Views; sourceTree = ""; }; + F423818E267D3511003837AC /* RemoteVersionChecker */ = { + isa = PBXGroup; + children = ( + F423818F267D3521003837AC /* WBRemoteVersionChecker.h */, + F4238190267D3522003837AC /* WBRemoteVersionChecker.m */, + F4D6C56A2680028200B78B3D /* Resources */, + ); + name = RemoteVersionChecker; + sourceTree = ""; + }; F423D8CA2673F5F200E2D31D /* Panels */ = { isa = PBXGroup; children = ( @@ -970,6 +1298,81 @@ name = Panels; sourceTree = ""; }; + F428C0402724591300FB8CAC /* ips model */ = { + isa = PBXGroup; + children = ( + F428C0652724592C00FB8CAC /* IPSApplicationSpecificInformation.h */, + F428C04B2724592A00FB8CAC /* IPSApplicationSpecificInformation.m */, + F428C0672724592C00FB8CAC /* IPSBundleInfo.h */, + F428C0532724592A00FB8CAC /* IPSBundleInfo.m */, + F428C05C2724592B00FB8CAC /* IPSDateFormatter.h */, + F428C04A2724592A00FB8CAC /* IPSDateFormatter.m */, + F428C04F2724592A00FB8CAC /* IPSError.h */, + F428C05B2724592B00FB8CAC /* IPSError.m */, + F428C06F2724592D00FB8CAC /* IPSException.h */, + F428C0542724592A00FB8CAC /* IPSException.m */, + F4BD8C682DF4DDCA00BD61A8 /* IPSExceptionReason.h */, + F4BD8C692DF4DDCA00BD61A8 /* IPSExceptionReason.m */, + F428C0642724592C00FB8CAC /* IPSExternalModificationStatistics.h */, + F428C0502724592A00FB8CAC /* IPSExternalModificationStatistics.m */, + F428C05A2724592B00FB8CAC /* IPSExternalModificationSummary.h */, + F428C04E2724592A00FB8CAC /* IPSExternalModificationSummary.m */, + F428C0632724592B00FB8CAC /* IPSImage.h */, + F428C0412724592900FB8CAC /* IPSImage.m */, + F428C0482724592900FB8CAC /* IPSIncident.h */, + F428C06A2724592C00FB8CAC /* IPSIncident.m */, + F428C06B2724592C00FB8CAC /* IPSIncidentDiagnosticMessage.h */, + F428C0442724592900FB8CAC /* IPSIncidentDiagnosticMessage.m */, + F428C0582724592B00FB8CAC /* IPSIncidentExceptionInformation.h */, + F428C0432724592900FB8CAC /* IPSIncidentExceptionInformation.m */, + F428C06D2724592C00FB8CAC /* IPSIncidentHeader.h */, + F428C0422724592900FB8CAC /* IPSIncidentHeader.m */, + F428C0662724592C00FB8CAC /* IPSLegacyInfo.h */, + F428C0682724592C00FB8CAC /* IPSLegacyInfo.m */, + F428C0552724592A00FB8CAC /* IPSObjectProtocol.h */, + F428C06E2724592D00FB8CAC /* IPSOperatingSystemVersion.h */, + F428C05E2724592B00FB8CAC /* IPSOperatingSystemVersion.m */, + F428C06C2724592C00FB8CAC /* IPSRegisterState.h */, + F428C0492724592900FB8CAC /* IPSRegisterState.m */, + F428C0512724592A00FB8CAC /* IPSReport.h */, + F428C0452724592900FB8CAC /* IPSReport.m */, + F428C0562724592A00FB8CAC /* IPSSummary.h */, + F428C04C2724592A00FB8CAC /* IPSSummary.m */, + F4440FDF282C4103003C810B /* IPSCrashSummary.h */, + F4440FDD282C4103003C810B /* IPSCrashSummary.m */, + F4440FDE282C4103003C810B /* IPSSummarySerialization.h */, + F4440FDC282C4103003C810B /* IPSSummarySerialization.m */, + F428C0522724592A00FB8CAC /* IPSTermination.h */, + F428C04D2724592A00FB8CAC /* IPSTermination.m */, + F428C0692724592C00FB8CAC /* IPSThread.h */, + F428C0572724592A00FB8CAC /* IPSThread.m */, + F428C05D2724592B00FB8CAC /* IPSThreadFrame.h */, + F428C0592724592B00FB8CAC /* IPSThreadFrame.m */, + F428C05F2724592B00FB8CAC /* IPSThreadInstructionState.h */, + F428C0462724592900FB8CAC /* IPSThreadInstructionState.m */, + F428C0602724592B00FB8CAC /* IPSThreadInstructionStream.h */, + F428C0472724592900FB8CAC /* IPSThreadInstructionStream.m */, + F428C0612724592B00FB8CAC /* IPSThreadState.h */, + F428C0622724592B00FB8CAC /* IPSThreadState.m */, + ); + name = "ips model"; + sourceTree = ""; + }; + F428C08727245BBF00FB8CAC /* ips model + Extensions */ = { + isa = PBXGroup; + children = ( + F4DAF0B127C44AA700256EA4 /* IPSImage+Offset.h */, + F4DAF0B227C44AA700256EA4 /* IPSImage+Offset.m */, + F4D14D672745C0A9003698AD /* IPSImage+UserCode.h */, + F4D14D662745C0A9003698AD /* IPSImage+UserCode.m */, + F4CF6CF52DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.h */, + F4CF6CF42DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.m */, + F4D0EE94273DB8CC00CC9737 /* IPSThreadState+RegisterDisplayName.h */, + F4D0EE93273DB8CC00CC9737 /* IPSThreadState+RegisterDisplayName.m */, + ); + name = "ips model + Extensions"; + sourceTree = ""; + }; F4341C68258EB8B8001A5605 /* CrashReporterPreferences */ = { isa = PBXGroup; children = ( @@ -1004,6 +1407,8 @@ F4545C38256C1ADB00F62A39 /* Registers Palette */, F48BAB3425D9D4140005F3E5 /* CUIThreadImageCell.h */, F48BAB3525D9D4140005F3E5 /* CUIThreadImageCell.m */, + D0790DBB2E00BACF00CD6A72 /* CUIThreadImageView.h */, + D0790DBC2E00BACF00CD6A72 /* CUIThreadImageView.m */, F48906AC25D2BA0C002D79A9 /* CUISelectedWhiteTextFieldCell.h */, F48906AD25D2BA0C002D79A9 /* CUISelectedWhiteTextFieldCell.m */, F442FCEA24AB855C00E87B69 /* CUIBinaryImagesViewController.h */, @@ -1071,8 +1476,6 @@ F464F20F24ACFBA1007A3A96 /* CUIRegister.m */, F4BBAC5B24AA7D37000511BE /* CUIBinaryImage.h */, F4BBAC5C24AA7D37000511BE /* CUIBinaryImage.m */, - F442FCEF24AB8A8B00E87B69 /* CUIBinaryImage+UI.h */, - F442FCF024AB8A8B00E87B69 /* CUIBinaryImage+UI.m */, F4ED75882501A29700316E73 /* CUIStackFrame.h */, F4ED75892501A29700316E73 /* CUIStackFrame.m */, F4CC573124A7ABAF00150EC4 /* CUICallStackBacktrace.h */, @@ -1104,6 +1507,8 @@ F47F76642673548600A74905 /* CUICrashLogsOpenErrorRecord.m */, F47F76602673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.h */, F47F76612673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.m */, + F4386B0E2849541B00B83525 /* CUICrashLogExceptionInformation+QuickHelp.h */, + F4386B0D2849541B00B83525 /* CUICrashLogExceptionInformation+QuickHelp.m */, ); name = Model; sourceTree = ""; @@ -1169,6 +1574,8 @@ F46198EB24CA457E00FA9717 /* Views */ = { isa = PBXGroup; children = ( + F4E671902E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.h */, + F4E671912E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.m */, F46198EC24CA459700FA9717 /* CUIInspectorAlternateBackgroundView.h */, F46198ED24CA459700FA9717 /* CUIInspectorAlternateBackgroundView.m */, ); @@ -1236,6 +1643,10 @@ F4B649D024EDCD2300008C47 /* CUIInspectorExecutableViewController.h */, F4B649D124EDCD2300008C47 /* CUIInspectorExecutableViewController.m */, F46D77A525ED8D5700039663 /* CUIInspectorExecutableViewController.xib */, + D06294352E1DD8150008895D /* CUICodeSigningInformationViewController.h */, + D06294362E1DD8150008895D /* CUICodeSigningInformationViewController.m */, + F4E671942E2C405F00E5A064 /* CodeSigningFlags.plist */, + F45DED6B2E350F07008F4CE8 /* CUICodeSigningInformationViewController.xib */, F4B649D824EDD64900008C47 /* CUIInspectorProcessesViewController.h */, F4B649D924EDD64900008C47 /* CUIInspectorProcessesViewController.m */, F46D77A925ED8E3B00039663 /* CUIInspectorProcessesViewController.xib */, @@ -1286,6 +1697,9 @@ F4B67835258F702E0047369E /* CUIPreferencePaneCrashreporterViewController.h */, F4B67836258F702E0047369E /* CUIPreferencePaneCrashreporterViewController.m */, F4A3A6E925ED817E0018053E /* CUIPreferencePaneCrashreporterViewController.xib */, + F4238189267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.h */, + F423818A267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.m */, + F406B49B2687AB1400B90C7B /* CUIPreferencePaneAdvancedViewController.xib */, ); name = Controllers; sourceTree = ""; @@ -1424,11 +1838,15 @@ F45F84D3266ABB5800F354F3 /* crashreport.xcodeproj */, F43BA4E425F2674100D8D68A /* SharedConfigurationSettings.xcconfig */, F43C828D24D8AD850096F27B /* CUIStackFrameComponents.h */, + F428C0402724591300FB8CAC /* ips model */, + F428C08727245BBF00FB8CAC /* ips model + Extensions */, + F4DF813A2893460E008EF1B3 /* ips model + Obfuscating */, F4B9AD23253199EE0083FA6C /* Mach-o */, F405A96A255015B500AD2F24 /* Demangling */, F4871DF125435AE500580562 /* DWARF */, F40B0D8124D3568000663282 /* Foundation + Extensions */, F40B0D8224D3568A00663282 /* AppKit + Extensions */, + D0BD22382F3FC6430052AD8E /* RSCore */, F4CC570124A79EDA00150EC4 /* app_unexpectedly */, F4CC570024A79EDA00150EC4 /* Products */, ); @@ -1445,6 +1863,7 @@ F4CC570124A79EDA00150EC4 /* app_unexpectedly */ = { isa = PBXGroup; children = ( + F423818E267D3511003837AC /* RemoteVersionChecker */, F4341C68258EB8B8001A5605 /* CrashReporterPreferences */, F4CDFB50257EE1BC002A73D0 /* Views */, F4B138542522945E00D9DE2F /* dSYM */, @@ -1471,6 +1890,8 @@ F420F35124E95E5F006C82CD /* CUITheme.m */, F49C47C824E9B48B003FC65C /* CUIThemesManager.h */, F49C47C924E9B48B003FC65C /* CUIThemesManager.m */, + F442FCEF24AB8A8B00E87B69 /* CUIBinaryImageUtility.h */, + F442FCF024AB8A8B00E87B69 /* CUIBinaryImageUtility.m */, F496740C24D0D74A00716289 /* CUIApplicationPreferences.h */, F496740D24D0D74A00716289 /* CUIApplicationPreferences.m */, F483845424EB1BEB00FAEF5D /* CUIApplicationPreferences+Themes.h */, @@ -1494,6 +1915,7 @@ children = ( F493DB1A24F1CF2F001AA8C0 /* Localizable.strings */, F46D2A2824C33FA200652D50 /* Predicates.strings */, + F45DED6D2E3510D9008F4CE8 /* CodeSigning.strings */, F4CC570B24A79EDA00150EC4 /* MainMenu.xib */, F483845224EB11F700FAEF5D /* default_themes.plist */, F4CC570324A79EDA00150EC4 /* Info.plist */, @@ -1574,6 +1996,8 @@ children = ( F49A6D7C25474F6E00466D15 /* CUIInactiveButton.h */, F49A6D7D25474F6E00466D15 /* CUIInactiveButton.m */, + F475FB3E26DBAC8200A113D8 /* CUITableViewNoSpace.h */, + F475FB3F26DBAC8200A113D8 /* CUITableViewNoSpace.m */, ); name = Views; sourceTree = ""; @@ -1587,15 +2011,67 @@ name = Views; sourceTree = ""; }; + F4D6C56A2680028200B78B3D /* Resources */ = { + isa = PBXGroup; + children = ( + F4D6C56B2680028A00B78B3D /* RemoteCheck.strings */, + ); + name = Resources; + sourceTree = ""; + }; + F4DF813A2893460E008EF1B3 /* ips model + Obfuscating */ = { + isa = PBXGroup; + children = ( + F4DF81412893463B008EF1B3 /* IPSObfuscator.h */, + F4DF81462893463C008EF1B3 /* IPSObfuscator.m */, + F4DF81512893463D008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.h */, + F4DF81402893463B008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.m */, + F4DF81422893463C008EF1B3 /* IPSBundleInfo+Obfuscating.h */, + F4DF81562893463D008EF1B3 /* IPSBundleInfo+Obfuscating.m */, + F4DF814E2893463D008EF1B3 /* IPSCrashSummary+Obfuscating.h */, + F4DF81472893463C008EF1B3 /* IPSCrashSummary+Obfuscating.m */, + F4DF81482893463C008EF1B3 /* IPSImage+Obfuscating.h */, + F4DF814F2893463D008EF1B3 /* IPSImage+Obfuscating.m */, + F4DF81452893463C008EF1B3 /* IPSIncident+Obfuscating.h */, + F4DF81572893463D008EF1B3 /* IPSIncident+Obfuscating.m */, + F4DF813B2893463B008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.h */, + F4DF813D2893463B008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.m */, + F4DF81532893463D008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.h */, + F4DF81552893463D008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.m */, + F4DF814D2893463C008EF1B3 /* IPSIncidentHeader+Obfuscating.h */, + F4DF81432893463C008EF1B3 /* IPSIncidentHeader+Obfuscating.m */, + F4DF81442893463C008EF1B3 /* IPSLegacyInfo+Obfuscating.h */, + F4DF81502893463D008EF1B3 /* IPSLegacyInfo+Obfuscating.m */, + F4DF813E2893463B008EF1B3 /* IPSObfuscator+Extended.h */, + F4DF81592893463E008EF1B3 /* IPSRegisterState+Obfuscating.h */, + F4DF814B2893463C008EF1B3 /* IPSRegisterState+Obfuscating.m */, + F4DF814C2893463C008EF1B3 /* IPSReport+Obfuscating.h */, + F4DF81522893463D008EF1B3 /* IPSReport+Obfuscating.m */, + F4DF81582893463D008EF1B3 /* IPSThread+Obfuscating.h */, + F4DF81492893463C008EF1B3 /* IPSThread+Obfuscating.m */, + F4DF81542893463D008EF1B3 /* IPSThreadFrame+Obfuscating.h */, + F4DF814A2893463C008EF1B3 /* IPSThreadFrame+Obfuscating.m */, + F4DF813F2893463B008EF1B3 /* IPSThreadState+Obfuscating.h */, + F4DF813C2893463B008EF1B3 /* IPSThreadState+Obfuscating.m */, + ); + name = "ips model + Obfuscating"; + sourceTree = ""; + }; F4E1C10E24C22CA0000F5C0F /* Presentation Text */ = { isa = PBXGroup; children = ( F4BC576E24DF423C00063545 /* Views */, - F4FC77A724E1F6AA001F82CA /* CUIRawTextTransformation.h */, - F4FC77A824E1F6AA001F82CA /* CUIRawTextTransformation.m */, + F4DAFBEF2736B7D500FB50A6 /* CUIDataTransform.h */, + F4DAFBF02736B7D500FB50A6 /* CUIDataTransform.m */, + F4FC8EA527C1A6EE00291875 /* CUIReportThemedTransform.h */, + F4FC8EA627C1A6EE00291875 /* CUIReportThemedTransform.m */, + F42E4FFF2724B7550092181A /* CUICrashDataTransform.h */, + F42E50002724B7550092181A /* CUICrashDataTransform.m */, + F4DAFBEC2736B7B200FB50A6 /* CUIIPSTransform.h */, + F4DAFBED2736B7B200FB50A6 /* CUIIPSTransform.m */, F4F9D3332556C7DB00D28E6E /* CUILineJumperWindowController.h */, F4F9D3342556C7DB00D28E6E /* CUILineJumperWindowController.m */, - F4FB9EA52579BAF700692B2A /* CUILineJumperWindowController.xib */, + F4895F5927A72D1000D75369 /* CUILineJumperWindowController.xib */, F4AC86472558A03B004F2637 /* CUIExportAccessoryViewController.h */, F4AC86482558A03B004F2637 /* CUIExportAccessoryViewController.m */, F453AE4B25EE706F00B7BEF0 /* CUIExportAccessoryViewController.xib */, @@ -1662,9 +2138,13 @@ F4F1C31624F950FC00D1A7A0 /* Exception Info Controller */ = { isa = PBXGroup; children = ( - F4C7498B24F84689004F38C0 /* CUIExceptionTypePopUpViewController.h */, - F4C7498C24F84689004F38C0 /* CUIExceptionTypePopUpViewController.m */, - F4C7498D24F84689004F38C0 /* CUIExceptionTypePopUpViewController.xib */, + F4C7498B24F84689004F38C0 /* CUIQuickHelpPopUpViewController.h */, + F4C7498C24F84689004F38C0 /* CUIQuickHelpPopUpViewController.m */, + F4C7498D24F84689004F38C0 /* CUIQuickHelpPopUpViewController.xib */, + F4B5BE6C2848277400C33F6F /* CUIExceptionTypePopUpViewController.h */, + F4B5BE6D2848277400C33F6F /* CUIExceptionTypePopUpViewController.m */, + F4B5BE6F28482A4300C33F6F /* CUITerminationReasonPopUpViewController.h */, + F4B5BE7028482A4300C33F6F /* CUITerminationReasonPopUpViewController.m */, F4F1C31724F9510E00D1A7A0 /* Resources */, ); name = "Exception Info Controller"; @@ -1684,6 +2164,10 @@ F45015D025FAD279000C4B8D /* EXC_CRASH_SIGQUIT.html */, F40B832825FC0AEC0091D886 /* EXC_CRASH_SIGSEGV.html */, F495AED625F03820000D92E1 /* EXC_CRASH_Code Signature Invalid.html */, + D0BA6A442E09FEB50010D630 /* EXC_GUARD.html */, + F4E6EDA0284969DD00766F9A /* known_termination_reasons.css */, + F4E6ED9A2849695100766F9A /* unknown_termination_reason.html */, + F4E6EDA2284969E500766F9A /* ENDPOINTSECURITY_2.html */, ); name = Resources; sourceTree = ""; @@ -1694,7 +2178,8 @@ F4F5395524D2066300D537BC /* Views */, F432ACC524A95014000A3E7A /* CUIThreadsListViewController.h */, F432ACC624A95014000A3E7A /* CUIThreadsListViewController.m */, - F432ACC724A95014000A3E7A /* CUIThreadsListViewController.xib */, + F47C381C2A422E880020D88F /* CUIThreadsListViewController.xib */, + F47C381D2A422E880020D88F /* CUIThreadsListViewController_RTL.xib */, ); name = "View Mode - List"; sourceTree = ""; @@ -1704,7 +2189,8 @@ children = ( F432ACCD24A95042000A3E7A /* CUIThreadsColumnViewController.h */, F432ACCE24A95042000A3E7A /* CUIThreadsColumnViewController.m */, - F432ACCF24A95042000A3E7A /* CUIThreadsColumnViewController.xib */, + F47C38202A4230370020D88F /* CUIThreadsColumnViewController.xib */, + F47C38212A4230370020D88F /* CUIThreadsColumnViewController_RTL.xib */, ); name = "View Mode - Columns"; sourceTree = ""; @@ -1783,6 +2269,8 @@ en, fr, es, + ja, + he, ); mainGroup = F4CC56F624A79EDA00150EC4; productRefGroup = F4CC570024A79EDA00150EC4 /* Products */; @@ -1821,11 +2309,14 @@ F416687024B0AEE800C2AB89 /* CUIContentsViewController.xib in Resources */, F495AED025F034C0000D92E1 /* EXC_BREAKPOINT_SIGTRAP.html in Resources */, F45015CE25FAD279000C4B8D /* EXC_CRASH_SIGQUIT.html in Resources */, + F45DED6F2E3510D9008F4CE8 /* CodeSigning.strings in Resources */, F45A2D6D25EC60920007D50E /* CUICrashLogsSourcesViewController.xib in Resources */, + F47C38232A4230370020D88F /* CUIThreadsColumnViewController_RTL.xib in Resources */, F48CF5FF24A96992002AD214 /* MainMenu.xib in Resources */, F483845324EB11F700FAEF5D /* default_themes.plist in Resources */, F4CE83DE2554B97400A8BD87 /* CUICenteredLabelViewController.xib in Resources */, - F4C7498F24F84689004F38C0 /* CUIExceptionTypePopUpViewController.xib in Resources */, + F4E6ED9C2849695200766F9A /* unknown_termination_reason.html in Resources */, + F4C7498F24F84689004F38C0 /* CUIQuickHelpPopUpViewController.xib in Resources */, F4F8D26A24F29624007661D6 /* CUIPresentationTextNavigationViewController.xib in Resources */, F45854FB25C76591007A3A79 /* Unexpectedly_Acknowledgements.pdf in Resources */, F495AED425F03820000D92E1 /* EXC_CRASH_Code Signature Invalid.html in Resources */, @@ -1833,23 +2324,24 @@ F495AEC425F03141000D92E1 /* unknown_exception_type.html in Resources */, F4A3A6DF25ED7F450018053E /* CUICrashLogsSourceSmartEditorWindowController.xib in Resources */, F453AE4925EE706F00B7BEF0 /* CUIExportAccessoryViewController.xib in Resources */, - F432ACC924A95014000A3E7A /* CUIThreadsListViewController.xib in Resources */, F41ECA5424AB689B00CE56C7 /* CUIInspectorViewController.xib in Resources */, F4A3A6EB25ED82F10018053E /* EXC_BAD_ACCESS_SIGBUS.html in Resources */, F4A9967C2675078B0001B40E /* CUICrashLogsOpenErrorWindowController.xib in Resources */, - F4FB9EA62579BAF700692B2A /* CUILineJumperWindowController.xib in Resources */, + F4895F5727A72D1000D75369 /* CUILineJumperWindowController.xib in Resources */, F416688724B0BF2000C2AB89 /* CUISidebarViewController.xib in Resources */, F453AE4D25EE70E800B7BEF0 /* CUICrashLogPresentationTextViewController.xib in Resources */, F4545C3D256C1AF900F62A39 /* CUIRegistersWindowController.xib in Resources */, F4055C8125EEE37400DC6CCA /* CUIMainWindowController.xib in Resources */, F4B74C1A24B233C900CD1E60 /* CUIRightViewController.xib in Resources */, + F47C38222A4230370020D88F /* CUIThreadsColumnViewController.xib in Resources */, F45A2D7125EC60D90007D50E /* CUICrashLogsListViewController.xib in Resources */, F495AEC025F02F74000D92E1 /* CUIPreferencePanePresentationOutlineViewController.xib in Resources */, F45854FA25C76591007A3A79 /* Unexpectedly_License.pdf in Resources */, F4301A6825EF0DE000ACDA3F /* CUIPreferencePanePresentationViewController.xib in Resources */, - F432ACD124A95042000A3E7A /* CUIThreadsColumnViewController.xib in Resources */, F4CC570A24A79EDA00150EC4 /* Images.xcassets in Resources */, + F47C381E2A422E880020D88F /* CUIThreadsListViewController.xib in Resources */, F40B832625FC0AEC0091D886 /* EXC_CRASH_SIGSEGV.html in Resources */, + F4E6EDA1284969DD00766F9A /* known_termination_reasons.css in Resources */, F493DB1C24F1CF30001AA8C0 /* Localizable.strings in Resources */, F45015C625FABCAC000C4B8D /* EXC_BAD_ACCESS_SIGSEGV.html in Resources */, F45015CA25FABE00000C4B8D /* EXC_BAD_INSTRUCTION_SIGILL.html in Resources */, @@ -1857,11 +2349,16 @@ F495AECC25F033CC000D92E1 /* EXC_CRASH_SIGKILL.html in Resources */, F4A0BEF3261BC39700BADEED /* brushed-alum.png in Resources */, F46D2A2624C33FA200652D50 /* Predicates.strings in Resources */, + F4E671952E2C405F00E5A064 /* CodeSigningFlags.plist in Resources */, + F4E6EDA4284969E500766F9A /* ENDPOINTSECURITY_2.html in Resources */, F45A2D6525EC5F850007D50E /* CUIAboutBoxWindowController.xib in Resources */, + D0BA6A462E09FEB50010D630 /* EXC_GUARD.html in Resources */, + F45DED692E350F07008F4CE8 /* CUICodeSigningInformationViewController.xib in Resources */, F49282C325696BF900D255D8 /* known_exceptions.css in Resources */, F4D7F15F25F04A9D0024E9A5 /* CUIPreferencePaneSymbolicationViewController.xib in Resources */, F4754D7125F5678700B0D48F /* CUICrashLogPresentationOutlineViewController.xib in Resources */, F4F892F92575A6DC00BE4CE0 /* CUIRegistersViewController.xib in Resources */, + F4D6C56D2680028A00B78B3D /* RemoteCheck.strings in Resources */, F46D779F25ED8D3600039663 /* CUIInspectorUserViewController.xib in Resources */, F464F20D24ACF9CF007A3A96 /* CUICrashLogsMainViewController.xib in Resources */, F46D77AB25ED9EAE00039663 /* CUICollectionViewRegisterItem.xib in Resources */, @@ -1870,7 +2367,9 @@ F4A3A6E325ED81260018053E /* CUIPreferencePaneGeneralViewController.xib in Resources */, F4D7F15B25F04A620024E9A5 /* CUISymbolsFilesLibraryViewController.xib in Resources */, F4F892FE2575A70800BE4CE0 /* CUIRegistersMainViewController.xib in Resources */, + F406B4992687AB1400B90C7B /* CUIPreferencePaneAdvancedViewController.xib in Resources */, F45A2D6925EC602B0007D50E /* CUIBinaryImagesViewController.xib in Resources */, + F47C381F2A422E880020D88F /* CUIThreadsListViewController_RTL.xib in Resources */, F4A3A6E725ED817E0018053E /* CUIPreferencePaneCrashreporterViewController.xib in Resources */, F416687A24B0BA5000C2AB89 /* CUICrashLogContentsViewController.xib in Resources */, F495AEC825F0320D000D92E1 /* EXC_CRASH_SIGABRT.html in Resources */, @@ -1906,19 +2405,23 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F428C07F2724592D00FB8CAC /* IPSException.m in Sources */, F483845924EB26DF00FAEF5D /* CUIThemeItemsGroup+UI.m in Sources */, + F4DF81622893463E008EF1B3 /* IPSRegisterState+Obfuscating.m in Sources */, + F4D14D682745C0A9003698AD /* IPSImage+UserCode.m in Sources */, F4871E0625435AF400580562 /* DWRFSection_debug_abbrev.m in Sources */, F43C828824D892620096F27B /* CUIPreferencePanePresentationTextViewController.m in Sources */, F40B0D9724D3572E00663282 /* NSColor+String.m in Sources */, F44E7B80255C83D500025C04 /* NoodleLineNumberMarker.m in Sources */, - F442FCF124AB8A8B00E87B69 /* CUIBinaryImage+UI.m in Sources */, + F4DF815E2893463E008EF1B3 /* IPSObfuscator.m in Sources */, + F442FCF124AB8A8B00E87B69 /* CUIBinaryImageUtility.m in Sources */, F4651F8624B297420090DF10 /* CUIOperatingSystemVersion.m in Sources */, F48944222545836F00E3E360 /* CUISymbolsFilesLibraryViewController.m in Sources */, F4B9AD3325319A410083FA6C /* MCHSegment.m in Sources */, + F4DF81642893463E008EF1B3 /* IPSLegacyInfo+Obfuscating.m in Sources */, F43362FE25FCEFBA006E7894 /* CUIRawCrashLog+Path.m in Sources */, F4FE2DEA25615CA800C1774A /* CUICrashLogExceptionInformation+UI.m in Sources */, F405A96D255015D800AD2F24 /* CUICXXDemangler.mm in Sources */, - F4FC77A924E1F6AB001F82CA /* CUIRawTextTransformation.m in Sources */, F497AD5524B8FE88008517B7 /* CUICrashLogsSourceSmartEditorPanel.m in Sources */, F4A0BEF8261BC39700BADEED /* CUIWatchScrew.m in Sources */, F416686F24B0AEE800C2AB89 /* CUIContentsViewController.m in Sources */, @@ -1926,23 +2429,32 @@ F4B9AD3825319A410083FA6C /* MCHMachBinary.m in Sources */, F4AA22B72561A233001A1315 /* CUIAboutBoxWindowController.m in Sources */, F40ACE30255697CE006855E5 /* CUICrashLogBrowsingStateRegistry.m in Sources */, + F428C0792724592D00FB8CAC /* IPSApplicationSpecificInformation.m in Sources */, + F4D0EE95273DB8CD00CC9737 /* IPSThreadState+RegisterDisplayName.m in Sources */, F49C47CA24E9B48B003FC65C /* CUIThemesManager.m in Sources */, + D0BD223B2F3FC6810052AD8E /* NSMenuItem+RSCore.m in Sources */, F416688224B0BBFC00C2AB89 /* CUICrashLogPresentationViewController.m in Sources */, + F428C0802724592D00FB8CAC /* IPSThread.m in Sources */, F4A0BEF4261BC39700BADEED /* CUIWatchAxis.m in Sources */, F4EFE75224BA48F500DB97AC /* CUIMainWindow.m in Sources */, F43C828C24D8A39B0096F27B /* CUITextModeDisplaySettings.m in Sources */, F414D08E24BFB57700A7095C /* CUICrashLogDianosticMessages.m in Sources */, F4871E0325435AF400580562 /* DWRFSection_debug_info.m in Sources */, F4CC573024A7A95A00150EC4 /* CUIThread.m in Sources */, + F428C0732724592D00FB8CAC /* IPSIncidentDiagnosticMessage.m in Sources */, F4BD6A0025553E9000F98F3E /* CUICrashLogSectionsDetector.m in Sources */, F4F8D26924F29624007661D6 /* CUIPresentationTextNavigationViewController.m in Sources */, F469AB2524B3DDEA0053C824 /* CUICrashLogExceptionInformation.m in Sources */, F419376F2672B2BE00B796EB /* CUICrashLogsOpenErrorPanel.m in Sources */, + D06294382E1DD8150008895D /* CUICodeSigningInformationViewController.m in Sources */, F4F5395924D21DB800D537BC /* CUIPreferencePaneGeneralViewController.m in Sources */, F4B9AD3425319A410083FA6C /* MCHObjectFile.m in Sources */, F4B649D324EDCD2300008C47 /* CUIInspectorExecutableViewController.m in Sources */, + F428C0812724592D00FB8CAC /* IPSThreadFrame.m in Sources */, F476EEC125686EC000F40F87 /* CUIContentBox.m in Sources */, F4CC572724A7A2B200150EC4 /* CUICrashLog.m in Sources */, + F4DF815D2893463E008EF1B3 /* IPSIncidentHeader+Obfuscating.m in Sources */, + F4FA4323273EF2F30068EDB8 /* NSString+CPU.m in Sources */, F476EEBE25686DEF00F40F87 /* CUIAboutBoxFooterView.m in Sources */, F420C9C4254F5F4C00D24249 /* CUIdSYMHunter.m in Sources */, F4A0BEF1261BC39700BADEED /* CUIWatchGear.m in Sources */, @@ -1950,8 +2462,10 @@ F4B9AD3B25319D7C0083FA6C /* MCHSegmentLoadCommand.m in Sources */, F4F5821C256FC7B90032FC53 /* DWRFSection_debug_str_offsets.m in Sources */, F4559F3724AF232800B8EF41 /* CUICrashLogHeader.m in Sources */, + F428C0762724592D00FB8CAC /* IPSThreadInstructionStream.m in Sources */, F4545C3C256C1AF900F62A39 /* CUIRegistersWindowController.m in Sources */, F4A0BEF6261BC39700BADEED /* CUIWatchPart.m in Sources */, + F428C07C2724592D00FB8CAC /* IPSExternalModificationSummary.m in Sources */, F4B649D724EDD09A00008C47 /* CUIInspectorStackableViewController.m in Sources */, F4CC572D24A7A5F000150EC4 /* CUICrashLog+Transform.m in Sources */, F4627F1225704557007E5CD0 /* CUICollectionViewRegisterItem.m in Sources */, @@ -1963,10 +2477,16 @@ F41ECA5324AB689B00CE56C7 /* CUIInspectorViewController.m in Sources */, F440A3E624AA31B500C23DA1 /* CUICrashLogsSourceFile.m in Sources */, F472CC972550631A003F6338 /* CUISwiftDemangler.m in Sources */, + F428C07A2724592D00FB8CAC /* IPSSummary.m in Sources */, + F428C0782724592D00FB8CAC /* IPSDateFormatter.m in Sources */, + F4CF6CF62DF6111B0078458E /* IPSIncident+ApplicationSpecificInformation.m in Sources */, F4040A7924F5BC230072BF65 /* CUINavigationView.m in Sources */, F4B018372620FEC7009727F1 /* CUIApplicationIconView.m in Sources */, F4BC577124DF426200063545 /* CUIAATextFieldCell.m in Sources */, F47F76652673548600A74905 /* CUICrashLogsOpenErrorRecord.m in Sources */, + F428C07E2724592D00FB8CAC /* IPSBundleInfo.m in Sources */, + F428C07D2724592D00FB8CAC /* IPSExternalModificationStatistics.m in Sources */, + F428C0752724592D00FB8CAC /* IPSThreadInstructionState.m in Sources */, F40B0D8824D3569800663282 /* NSResponder+Appearance.m in Sources */, F43A9A832591260C005AB2AA /* CUIOutlineModeDisplaySettings.m in Sources */, F4AC864A2558A03B004F2637 /* CUIExportAccessoryViewController.m in Sources */, @@ -1980,15 +2500,22 @@ F4871E0925435AF400580562 /* DWRFObject.m in Sources */, F4214CB524B6534400852DDE /* CUICrashLogsSourcesManager.m in Sources */, F4871E0D25437A6A00580562 /* CUISymbolicationDataCache.m in Sources */, + F4440FE0282C4104003C810B /* IPSSummarySerialization.m in Sources */, + F428C07B2724592D00FB8CAC /* IPSTermination.m in Sources */, F440A3E924AA35AC00C23DA1 /* CUICrashLogsSourceDirectory.m in Sources */, F414D09124BFBC3A00A7095C /* CUICrashLogBacktraces.m in Sources */, F4A0BEF7261BC39700BADEED /* CUIWatchBridge.m in Sources */, + F4DF81682893463E008EF1B3 /* IPSIncident+Obfuscating.m in Sources */, F440A3E324AA315800C23DA1 /* CUICrashLogsSourceStandardDirectory.m in Sources */, F43AF0D1256FE2AE0066CA1B /* DWRFSection_debug_addr.m in Sources */, F4871E0525435AF400580562 /* DWRFSection_debug_line.m in Sources */, + F4DF81672893463E008EF1B3 /* IPSBundleInfo+Obfuscating.m in Sources */, F40BEAF124E9F754007A3F60 /* CUIThemeItemAttributes.m in Sources */, F4B138572522948700D9DE2F /* NSBundle+dSYM.m in Sources */, + F428C0742724592D00FB8CAC /* IPSReport.m in Sources */, F49A6D8125476F7B00466D15 /* CUISymbolicationDataFormatter.m in Sources */, + F4DF81612893463E008EF1B3 /* IPSThreadFrame+Obfuscating.m in Sources */, + F4DF815C2893463E008EF1B3 /* IPSApplicationSpecificInformation+Obfuscating.m in Sources */, F416687E24B0BBA300C2AB89 /* CUICrashLogPresentationTextViewController.m in Sources */, F4EBADB724A8F10000DF4271 /* CUICrashLogTableCellView.m in Sources */, F45B518C24AFA04000E97B87 /* CUICrashLogsSelection.m in Sources */, @@ -2001,8 +2528,14 @@ F4B9AD3625319A410083FA6C /* MCHLoadCommand.m in Sources */, F480692E24AF7D83009665F2 /* CUICrashLogsListViewController.m in Sources */, F4ED18A324EC77A300ED7EF2 /* NSArray+UniqueName.m in Sources */, + F42E50012724B7550092181A /* CUICrashDataTransform.m in Sources */, + F428C0822724592D00FB8CAC /* IPSError.m in Sources */, F4E0BD25262078220048647C /* CUIAboutBoxWindow.m in Sources */, + F4DF81662893463E008EF1B3 /* IPSIncidentExceptionInformation+Obfuscating.m in Sources */, F4C269CD2503BCC100C8F3B3 /* CUISymbolicationManager.m in Sources */, + F4DF815F2893463E008EF1B3 /* IPSCrashSummary+Obfuscating.m in Sources */, + F4E671922E2C3B1600E5A064 /* CUICodeSigningFlagsTableView.m in Sources */, + F4DAFBEE2736B7B200FB50A6 /* CUIIPSTransform.m in Sources */, F47F76622673542600A74905 /* CUICrashLogsOpenErrorRecord+UI.m in Sources */, F462DD3124ADC5F900044AB1 /* CUICrashLogsSourceSmart.m in Sources */, F483845624EB1BEB00FAEF5D /* CUIApplicationPreferences+Themes.m in Sources */, @@ -2011,24 +2544,30 @@ F414D09724BFBC6300A7095C /* CUICrashLogBinaryImages.m in Sources */, F47AF8C0255DE61E0037E2D8 /* NSCrashLogTextScrollView.m in Sources */, F40B0D8724D3569800663282 /* NSColor+LabelColor.m in Sources */, + F4238191267D3522003837AC /* WBRemoteVersionChecker.m in Sources */, F48BAB3625D9D4140005F3E5 /* CUIThreadImageCell.m in Sources */, F416687924B0BA5000C2AB89 /* CUICrashLogContentsViewController.m in Sources */, + F428C0842724592D00FB8CAC /* IPSThreadState.m in Sources */, F49673FE24D0CF6400716289 /* CUIPreferencesWindowController.m in Sources */, F4040A7624F5B9CE0072BF65 /* CUINavigationChevronView.m in Sources */, F4EAFA2C24FA6CD100C0B729 /* CUICrashLogTextView.m in Sources */, F4341C6B258EB8FE001A5605 /* CUICrashReporterDefaults.m in Sources */, + F428C0722724592D00FB8CAC /* IPSIncidentExceptionInformation.m in Sources */, F496740E24D0D74A00716289 /* CUIApplicationPreferences.m in Sources */, F40B0D9D24D370A200663282 /* NSDictionary+MutableDeepCopy.m in Sources */, F40B0D9424D3571B00663282 /* NSTableView+Selection.m in Sources */, F40B0D7E24D3558800663282 /* CUIPreferencesTabBox.m in Sources */, F4CCCC6E24AE9EDA0031BC27 /* CUICrashLogsSource+UI.m in Sources */, - F4C7498E24F84689004F38C0 /* CUIExceptionTypePopUpViewController.m in Sources */, + F4C7498E24F84689004F38C0 /* CUIQuickHelpPopUpViewController.m in Sources */, F4A58D1E24CA4CDA00D98FDB /* CUICrashedThreadCallRowView.m in Sources */, F4545C41256C1B2400F62A39 /* CUIRegistersViewController.m in Sources */, + F4386B0F2849541C00B83525 /* CUICrashLogExceptionInformation+QuickHelp.m in Sources */, F440A3EC24AA38E600C23DA1 /* CUICrashLogsSourceAll.m in Sources */, F4871E0725435AF400580562 /* DWRFFileObject.m in Sources */, F4871E10254384E100580562 /* CUIdSYMBundlesManager.m in Sources */, F4B74C1924B233C900CD1E60 /* CUIRightViewController.m in Sources */, + F428C0712724592D00FB8CAC /* IPSIncidentHeader.m in Sources */, + F428C0772724592D00FB8CAC /* IPSRegisterState.m in Sources */, F4CD32B6257D17B3008C71AA /* CUIPreferencePaneSymbolicationViewController.m in Sources */, F41D66B025921F3400C0D491 /* CUIPreferencePanePresentationViewController.m in Sources */, F49A55DE24C7A7F900D249DE /* CUICallTableCellView.m in Sources */, @@ -2036,43 +2575,57 @@ F40B0D9124D356F900663282 /* NSToolbar+Packages.m in Sources */, F46198E924CA390700FA9717 /* CUICrashLogBacktraces+Utilities.m in Sources */, F49227C824A8D45000772411 /* CUIStackFrame+UI.m in Sources */, + F428C0832724592D00FB8CAC /* IPSOperatingSystemVersion.m in Sources */, F432ACD024A95042000A3E7A /* CUIThreadsColumnViewController.m in Sources */, F416688624B0BF2000C2AB89 /* CUISidebarViewController.m in Sources */, F4B57C0C24AF5607000851FF /* CUICrashLogsSourceToday.m in Sources */, F420C9C1254F335000D24249 /* CUIdSYMDropView.m in Sources */, F44356F324A8A113001D3D35 /* CUICrashLogPresentationOutlineViewController.m in Sources */, F40B0D8D24D356A200663282 /* NSArray+WBExtensions.m in Sources */, + D0790DBD2E00BACF00CD6A72 /* CUIThreadImageView.m in Sources */, F4A58D1B24CA4B1500D98FDB /* CUICrashedThreadRowView.m in Sources */, F4871E0825435AF400580562 /* LEB128.c in Sources */, F4EBD24B24E01556007F0252 /* CUITableCustomSelectionColorRowView.m in Sources */, + F4BD8C6A2DF4DDCB00BD61A8 /* IPSExceptionReason.m in Sources */, F442FCED24AB855C00E87B69 /* CUIBinaryImagesViewController.m in Sources */, F496740A24D0D2A300716289 /* CUIPreferencePaneFontscolorsViewController.m in Sources */, + F4DF815A2893463E008EF1B3 /* IPSThreadState+Obfuscating.m in Sources */, F416687424B0AF4D00C2AB89 /* CUICenteredLabelViewController.m in Sources */, + F4DF81632893463E008EF1B3 /* IPSImage+Obfuscating.m in Sources */, F40B77D724AF0F5C001A8131 /* CUICrashLogsSourceStandardDirectory+UI.m in Sources */, + F4B5BE7128482A4300C33F6F /* CUITerminationReasonPopUpViewController.m in Sources */, F45442A924AF355700EE79E4 /* CUICaptionView.m in Sources */, + F4DF81602893463E008EF1B3 /* IPSThread+Obfuscating.m in Sources */, F40FC81625EAF7B000DB4B27 /* CUISourceFileTableCellView.m in Sources */, F414D09424BFBC4A00A7095C /* CUICrashLogThreadState.m in Sources */, F4B57C0F24AF5655000851FF /* CUICrashLogsSourceToday+UI.m in Sources */, F4F9BAF724EF06BC00D08FBD /* CUIInspectorGeneralViewController.m in Sources */, + F4440FE1282C4104003C810B /* IPSCrashSummary.m in Sources */, F414068B24D6014D0059FF21 /* CUIFontAndColorsFramedView.m in Sources */, F40B124924E89BBE005E82DD /* CUIPreferencesWindowController+Convenience.m in Sources */, F4132C8F24AA19F70086B99C /* CUICrashLogsSource.m in Sources */, + F4DAF0B327C44AA800256EA4 /* IPSImage+Offset.m in Sources */, F4CCCC6524AE810E0031BC27 /* CUICrashLogsSourcesSelection.m in Sources */, F432ACCC24A9502A000A3E7A /* CUIThreadsViewController.m in Sources */, F40B0D8E24D356A200663282 /* NSIndexSet+Analysis.m in Sources */, + F4FC8EA727C1A6EE00291875 /* CUIReportThemedTransform.m in Sources */, + F4DAFBF12736B7D500FB50A6 /* CUIDataTransform.m in Sources */, F4B9AD3225319A410083FA6C /* MCHMemoryBufferWrapper.m in Sources */, F40B0D8024D3558800663282 /* CUIPreferencesTabButton.m in Sources */, F464F21024ACFBA1007A3A96 /* CUIRegister.m in Sources */, F4EBADB424A8F04F00DF4271 /* CUICrashLog+UI.m in Sources */, F46198EE24CA459700FA9717 /* CUIInspectorAlternateBackgroundView.m in Sources */, + F475FB4026DBAC8200A113D8 /* CUITableViewNoSpace.m in Sources */, F47F7668267355EA00A74905 /* CUICrashLogErrors.m in Sources */, F4F9BAF224EF060E00D08FBD /* CUIInspectorUserViewController.m in Sources */, F4CC570824A79EDA00150EC4 /* main.m in Sources */, F420C9B9254F30A100D24249 /* CUIFileDeadDropView.m in Sources */, F42B57E224ABEF6E00F77ED5 /* CUICallsSelection.m in Sources */, F44E7B7F255C83D500025C04 /* NoodleLineNumberView.m in Sources */, + F4DF81652893463E008EF1B3 /* IPSReport+Obfuscating.m in Sources */, F483845124EB041B00FAEF5D /* CUIThemeItemsGroup.m in Sources */, F4F2A9D024BB7E3600F912D4 /* CUICrashLogsSourceSeparator.m in Sources */, + F4DF815B2893463E008EF1B3 /* IPSIncidentDiagnosticMessage+Obfuscating.m in Sources */, F4D5C77C2571AF900029B051 /* CUIRegisterLabel.m in Sources */, F45F2F5B2538EF3F0030A402 /* NSFileManager+ExtendedAttributes.m in Sources */, F4B67838258F702E0047369E /* CUIPreferencePaneCrashreporterViewController.m in Sources */, @@ -2085,19 +2638,24 @@ F4B52E212548B8B4007593FD /* CUIdSYMBundle+UI.m in Sources */, F496740324D0D05800716289 /* CUIPreferencePaneViewController.m in Sources */, F4ED758A2501A29700316E73 /* CUIStackFrame.m in Sources */, + F428C0702724592D00FB8CAC /* IPSImage.m in Sources */, F4871DC02543566E00580562 /* CUIdSYMBundle.m in Sources */, F4A7696A2555D9DE00F9D9D3 /* CUIRawCrashLog+UI.m in Sources */, F4871E0425435AF400580562 /* DWRFSection_debug_str.m in Sources */, + F4B5BE6E2848277400C33F6F /* CUIExceptionTypePopUpViewController.m in Sources */, F48906AE25D2BA0C002D79A9 /* CUISelectedWhiteTextFieldCell.m in Sources */, F43D8FF724A7FAD2008147F9 /* CUIMainWindowController.m in Sources */, F40B77DA24AF1426001A8131 /* CUICrashLogsSourceAll+UI.m in Sources */, F4A0BEF2261BC39700BADEED /* CUIWatchJewel.m in Sources */, F46BAF59250162C900991970 /* CUIPreferencesWindow.m in Sources */, + F428C0862724592D00FB8CAC /* IPSIncident.m in Sources */, F4871E0A25435AF400580562 /* DWRFSection_debug_aranges.m in Sources */, F40BEAFC24E9FEF8007A3F60 /* NSDictionary+WBExtensions.m in Sources */, + F423818C267D1D4A003837AC /* CUIPreferencePaneAdvancedViewController.m in Sources */, F497303A25F796E6001D01FE /* CUIHopperDisassemblerManager.m in Sources */, F4CC570624A79EDA00150EC4 /* AppDelegate.m in Sources */, F4CC572424A7A1D100150EC4 /* CUICrashLogsProvider.m in Sources */, + F428C0852724592D00FB8CAC /* IPSLegacyInfo.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2112,22 +2670,50 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + D0BA6A442E09FEB50010D630 /* EXC_GUARD.html */ = { + isa = PBXVariantGroup; + children = ( + D0BA6A452E09FEB50010D630 /* en */, + D00B152C2E0B52740098456B /* fr */, + D0AECAE42E0F34830028246E /* he */, + D000743B2E11F30900CC5121 /* ja */, + D000743C2E11F30B00CC5121 /* es */, + ); + name = EXC_GUARD.html; + sourceTree = ""; + }; F4055C8325EEE37400DC6CCA /* CUIMainWindowController.xib */ = { isa = PBXVariantGroup; children = ( F4055C8225EEE37400DC6CCA /* en */, F4055C8425EEE37600DC6CCA /* fr */, F4111AE4265EE92600FD8950 /* es */, + F4FC364B278F914500669B32 /* ja */, + F43066EA2A12EDE8002AB430 /* he */, ); name = CUIMainWindowController.xib; sourceTree = ""; }; + F406B49B2687AB1400B90C7B /* CUIPreferencePaneAdvancedViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + F406B49A2687AB1400B90C7B /* en */, + F406B49C2687AB1800B90C7B /* fr */, + F406B49D2687AC1900B90C7B /* es */, + F4FC3633278F914300669B32 /* ja */, + F43066CF2A12EDE6002AB430 /* he */, + ); + name = CUIPreferencePaneAdvancedViewController.xib; + sourceTree = ""; + }; F40B832825FC0AEC0091D886 /* EXC_CRASH_SIGSEGV.html */ = { isa = PBXVariantGroup; children = ( F40B832725FC0AEC0091D886 /* en */, F40B832925FC0AEE0091D886 /* fr */, F4111ADD265EE92500FD8950 /* es */, + F4FC3644278F914400669B32 /* ja */, + F43066E02A12EDE7002AB430 /* he */, ); name = EXC_CRASH_SIGSEGV.html; path = Help; @@ -2139,6 +2725,8 @@ F4301A6925EF0DE000ACDA3F /* en */, F4301A6B25EF0DE200ACDA3F /* fr */, F4111AC8265EE92200FD8950 /* es */, + F4FC362E278F914200669B32 /* ja */, + F43066CA2A12EDE5002AB430 /* he */, ); name = CUIPreferencePanePresentationViewController.xib; sourceTree = ""; @@ -2149,6 +2737,8 @@ F45015C725FABCAC000C4B8D /* en */, F45015C925FABCAF000C4B8D /* fr */, F4111AD7265EE92400FD8950 /* es */, + F4FC363E278F914400669B32 /* ja */, + F43066DA2A12EDE7002AB430 /* he */, ); name = EXC_BAD_ACCESS_SIGSEGV.html; path = Help; @@ -2160,6 +2750,8 @@ F45015CB25FABE00000C4B8D /* en */, F45015CD25FABE02000C4B8D /* fr */, F4111AD8265EE92400FD8950 /* es */, + F4FC363F278F914400669B32 /* ja */, + F43066DB2A12EDE7002AB430 /* he */, ); name = EXC_BAD_INSTRUCTION_SIGILL.html; path = Help; @@ -2171,6 +2763,8 @@ F45015CF25FAD279000C4B8D /* en */, F45015D125FAD27B000C4B8D /* fr */, F4111ADC265EE92500FD8950 /* es */, + F4FC3643278F914400669B32 /* ja */, + F43066DF2A12EDE7002AB430 /* he */, ); name = EXC_CRASH_SIGQUIT.html; path = Help; @@ -2182,6 +2776,8 @@ F453AE4A25EE706F00B7BEF0 /* en */, F453AE4C25EE707000B7BEF0 /* fr */, F4111ADF265EE92500FD8950 /* es */, + F4FC3646278F914500669B32 /* ja */, + F43066E52A12EDE8002AB430 /* he */, ); name = CUIExportAccessoryViewController.xib; sourceTree = ""; @@ -2192,6 +2788,8 @@ F453AE4E25EE70E800B7BEF0 /* en */, F453AE5025EE70E900B7BEF0 /* fr */, F4111AE0265EE92500FD8950 /* es */, + F4FC3647278F914500669B32 /* ja */, + F43066E62A12EDE8002AB430 /* he */, ); name = CUICrashLogPresentationTextViewController.xib; sourceTree = ""; @@ -2202,6 +2800,8 @@ F45A2D5E25EC5CA00007D50E /* en */, F45A2D6025EC5CA30007D50E /* fr */, F4111ACD265EE92300FD8950 /* es */, + F4FC3634278F914300669B32 /* ja */, + F43066D02A12EDE6002AB430 /* he */, ); name = CUIPreferencesWindowController.xib; sourceTree = ""; @@ -2212,6 +2812,8 @@ F45A2D6225EC5D130007D50E /* en */, F45A2D6425EC5D140007D50E /* fr */, F4111AC9265EE92200FD8950 /* es */, + F4FC362F278F914200669B32 /* ja */, + F43066CB2A12EDE5002AB430 /* he */, ); name = CUIPreferencePaneFontscolorsViewController.xib; sourceTree = ""; @@ -2222,6 +2824,8 @@ F45A2D6625EC5F850007D50E /* en */, F45A2D6825EC5F870007D50E /* fr */, F4111AC4265EE92200FD8950 /* es */, + F4FC362A278F914200669B32 /* ja */, + F43066C62A12EDE4002AB430 /* he */, ); name = CUIAboutBoxWindowController.xib; sourceTree = ""; @@ -2232,6 +2836,8 @@ F45A2D6A25EC602B0007D50E /* en */, F45A2D6C25EC60310007D50E /* fr */, F4111AE3265EE92600FD8950 /* es */, + F4FC364A278F914500669B32 /* ja */, + F43066E92A12EDE8002AB430 /* he */, ); name = CUIBinaryImagesViewController.xib; sourceTree = ""; @@ -2242,6 +2848,8 @@ F45A2D6E25EC60920007D50E /* en */, F45A2D7025EC60930007D50E /* fr */, F4111ACF265EE92300FD8950 /* es */, + F4FC3636278F914300669B32 /* ja */, + F43066D22A12EDE6002AB430 /* he */, ); name = CUICrashLogsSourcesViewController.xib; sourceTree = ""; @@ -2252,16 +2860,44 @@ F45A2D7225EC60D90007D50E /* en */, F45A2D7425EC60DB0007D50E /* fr */, F4111AD0265EE92300FD8950 /* es */, + F4FC3637278F914300669B32 /* ja */, + F43066D32A12EDE6002AB430 /* he */, ); name = CUICrashLogsListViewController.xib; sourceTree = ""; }; + F45DED6B2E350F07008F4CE8 /* CUICodeSigningInformationViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + F45DED6A2E350F07008F4CE8 /* en */, + F45DED6C2E350F0D008F4CE8 /* fr */, + F45DED742E351277008F4CE8 /* es */, + F45DED752E351279008F4CE8 /* ja */, + F45DED762E35127A008F4CE8 /* he */, + ); + name = CUICodeSigningInformationViewController.xib; + sourceTree = ""; + }; + F45DED6D2E3510D9008F4CE8 /* CodeSigning.strings */ = { + isa = PBXVariantGroup; + children = ( + F45DED6E2E3510D9008F4CE8 /* en */, + F45DED702E351134008F4CE8 /* fr */, + F45DED712E3511B8008F4CE8 /* es */, + F45DED722E3511BB008F4CE8 /* ja */, + F45DED732E3511BC008F4CE8 /* he */, + ); + name = CodeSigning.strings; + sourceTree = ""; + }; F46D2A2824C33FA200652D50 /* Predicates.strings */ = { isa = PBXVariantGroup; children = ( F46D2A2724C33FA200652D50 /* en */, F45A2D5625EC50960007D50E /* fr */, F4111AE6265EE92600FD8950 /* es */, + F4FC364D278F914500669B32 /* ja */, + F43066EC2A12EDE9002AB430 /* he */, ); name = Predicates.strings; sourceTree = ""; @@ -2272,6 +2908,8 @@ F46D779C25ED8D1800039663 /* en */, F46D779E25ED8D1900039663 /* fr */, F4111AD1265EE92300FD8950 /* es */, + F4FC3638278F914300669B32 /* ja */, + F43066D42A12EDE6002AB430 /* he */, ); name = CUIInspectorGeneralViewController.xib; sourceTree = ""; @@ -2282,6 +2920,8 @@ F46D77A025ED8D3600039663 /* en */, F46D77A225ED8D3900039663 /* fr */, F4111AD2265EE92300FD8950 /* es */, + F4FC3639278F914300669B32 /* ja */, + F43066D52A12EDE6002AB430 /* he */, ); name = CUIInspectorUserViewController.xib; sourceTree = ""; @@ -2292,6 +2932,8 @@ F46D77A425ED8D5700039663 /* en */, F46D77A625ED8D5900039663 /* fr */, F4111AD3265EE92400FD8950 /* es */, + F4FC363A278F914300669B32 /* ja */, + F43066D62A12EDE6002AB430 /* he */, ); name = CUIInspectorExecutableViewController.xib; sourceTree = ""; @@ -2302,6 +2944,8 @@ F46D77A825ED8E3B00039663 /* en */, F46D77AA25ED8E3E00039663 /* fr */, F4111AD4265EE92400FD8950 /* es */, + F4FC363B278F914300669B32 /* ja */, + F43066D72A12EDE6002AB430 /* he */, ); name = CUIInspectorProcessesViewController.xib; sourceTree = ""; @@ -2312,6 +2956,8 @@ F46D77AC25ED9EAE00039663 /* en */, F46D77AE25ED9EAF00039663 /* fr */, F4111AE2265EE92500FD8950 /* es */, + F4FC3649278F914500669B32 /* ja */, + F43066E82A12EDE8002AB430 /* he */, ); name = CUICollectionViewRegisterItem.xib; sourceTree = ""; @@ -2322,16 +2968,32 @@ F4754D7225F5678700B0D48F /* en */, F4754D7425F5678A00B0D48F /* fr */, F4111AE1265EE92500FD8950 /* es */, + F4FC3648278F914500669B32 /* ja */, + F43066E72A12EDE8002AB430 /* he */, ); name = CUICrashLogPresentationOutlineViewController.xib; sourceTree = ""; }; + F4895F5927A72D1000D75369 /* CUILineJumperWindowController.xib */ = { + isa = PBXVariantGroup; + children = ( + F4895F5827A72D1000D75369 /* en */, + F4895F5A27A72D1300D75369 /* fr */, + F4895F5B27A72D3300D75369 /* es */, + F4895F5C27A72D6300D75369 /* ja */, + F43066E42A12EDE8002AB430 /* he */, + ); + name = CUILineJumperWindowController.xib; + sourceTree = ""; + }; F493DB1A24F1CF2F001AA8C0 /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( F493DB1B24F1CF2F001AA8C0 /* en */, F45A2D5525EC50960007D50E /* fr */, F4111AE5265EE92600FD8950 /* es */, + F4FC364C278F914500669B32 /* ja */, + F43066EB2A12EDE8002AB430 /* he */, ); name = Localizable.strings; sourceTree = ""; @@ -2342,6 +3004,8 @@ F495AEBD25F029C2000D92E1 /* en */, F495AEBF25F029CD000D92E1 /* fr */, F4111AC6265EE92200FD8950 /* es */, + F4FC362C278F914200669B32 /* ja */, + F43066C82A12EDE5002AB430 /* he */, ); name = CUIPreferencePanePresentationTextViewController.xib; sourceTree = ""; @@ -2352,6 +3016,8 @@ F495AEC125F02F74000D92E1 /* en */, F495AEC325F02F76000D92E1 /* fr */, F4111AC7265EE92200FD8950 /* es */, + F4FC362D278F914200669B32 /* ja */, + F43066C92A12EDE5002AB430 /* he */, ); name = CUIPreferencePanePresentationOutlineViewController.xib; sourceTree = ""; @@ -2362,6 +3028,8 @@ F495AEC525F03141000D92E1 /* en */, F495AEC725F0314A000D92E1 /* fr */, F4111AD5265EE92400FD8950 /* es */, + F4FC363C278F914400669B32 /* ja */, + F43066D82A12EDE7002AB430 /* he */, ); name = unknown_exception_type.html; path = Help; @@ -2373,6 +3041,8 @@ F495AEC925F0320D000D92E1 /* en */, F495AECB25F03213000D92E1 /* fr */, F4111ADA265EE92500FD8950 /* es */, + F4FC3641278F914400669B32 /* ja */, + F43066DD2A12EDE7002AB430 /* he */, ); name = EXC_CRASH_SIGABRT.html; path = Help; @@ -2384,6 +3054,8 @@ F495AECD25F033CC000D92E1 /* en */, F495AECF25F033D0000D92E1 /* fr */, F4111ADB265EE92500FD8950 /* es */, + F4FC3642278F914400669B32 /* ja */, + F43066DE2A12EDE7002AB430 /* he */, ); name = EXC_CRASH_SIGKILL.html; path = Help; @@ -2395,6 +3067,8 @@ F495AED125F034C0000D92E1 /* en */, F495AED325F034C4000D92E1 /* fr */, F4111AD9265EE92400FD8950 /* es */, + F4FC3640278F914400669B32 /* ja */, + F43066DC2A12EDE7002AB430 /* he */, ); name = EXC_BREAKPOINT_SIGTRAP.html; path = Help; @@ -2406,6 +3080,8 @@ F495AED525F03820000D92E1 /* en */, F495AED725F03825000D92E1 /* fr */, F4111ADE265EE92500FD8950 /* es */, + F4FC3645278F914400669B32 /* ja */, + F43066E12A12EDE7002AB430 /* he */, ); name = "EXC_CRASH_Code Signature Invalid.html"; path = Help; @@ -2417,6 +3093,8 @@ F497303D25F7F74B001D01FE /* en */, F497303F25F7F7A6001D01FE /* fr */, F4111AE8265EE92600FD8950 /* es */, + F4FC364F278F914500669B32 /* ja */, + F43066EE2A12EDE9002AB430 /* he */, ); name = InfoPlist.strings; sourceTree = ""; @@ -2427,6 +3105,8 @@ F4A3A6E025ED7F450018053E /* en */, F4A3A6E225ED7F460018053E /* fr */, F4111ACE265EE92300FD8950 /* es */, + F4FC3635278F914300669B32 /* ja */, + F43066D12A12EDE6002AB430 /* he */, ); name = CUICrashLogsSourceSmartEditorWindowController.xib; sourceTree = ""; @@ -2437,6 +3117,8 @@ F4A3A6E425ED81260018053E /* en */, F4A3A6E625ED81290018053E /* fr */, F4111AC5265EE92200FD8950 /* es */, + F4FC362B278F914200669B32 /* ja */, + F43066C72A12EDE5002AB430 /* he */, ); name = CUIPreferencePaneGeneralViewController.xib; sourceTree = ""; @@ -2447,6 +3129,8 @@ F4A3A6E825ED817E0018053E /* en */, F4A3A6EA25ED81800018053E /* fr */, F4111ACC265EE92300FD8950 /* es */, + F4FC3632278F914300669B32 /* ja */, + F43066CE2A12EDE6002AB430 /* he */, ); name = CUIPreferencePaneCrashreporterViewController.xib; sourceTree = ""; @@ -2457,6 +3141,8 @@ F4A3A6EC25ED82F10018053E /* en */, F4A3A6EE25ED82F20018053E /* fr */, F4111AD6265EE92400FD8950 /* es */, + F4FC363D278F914400669B32 /* ja */, + F43066D92A12EDE7002AB430 /* he */, ); name = EXC_BAD_ACCESS_SIGBUS.html; path = Help; @@ -2468,16 +3154,32 @@ F48CF60024A969B5002AD214 /* en */, F45A2D5725EC50960007D50E /* fr */, F4111AE7265EE92600FD8950 /* es */, + F4FC364E278F914500669B32 /* ja */, + F43066ED2A12EDE9002AB430 /* he */, ); name = MainMenu.xib; sourceTree = ""; }; + F4D6C56B2680028A00B78B3D /* RemoteCheck.strings */ = { + isa = PBXVariantGroup; + children = ( + F4D6C56C2680028A00B78B3D /* en */, + F4D6C56E268002DE00B78B3D /* fr */, + F4D6C56F2680031E00B78B3D /* es */, + F4FC3629278F914200669B32 /* ja */, + F43066C52A12EDE4002AB430 /* he */, + ); + name = RemoteCheck.strings; + sourceTree = ""; + }; F4D7F15D25F04A620024E9A5 /* CUISymbolsFilesLibraryViewController.xib */ = { isa = PBXVariantGroup; children = ( F4D7F15C25F04A620024E9A5 /* en */, F4D7F15E25F04A630024E9A5 /* fr */, F4111ACA265EE92200FD8950 /* es */, + F4FC3630278F914200669B32 /* ja */, + F43066CC2A12EDE5002AB430 /* he */, ); name = CUISymbolsFilesLibraryViewController.xib; sourceTree = ""; @@ -2488,10 +3190,36 @@ F4D7F16025F04A9D0024E9A5 /* en */, F4D7F16225F04A9E0024E9A5 /* fr */, F4111ACB265EE92300FD8950 /* es */, + F4FC3631278F914200669B32 /* ja */, + F43066CD2A12EDE6002AB430 /* he */, ); name = CUIPreferencePaneSymbolicationViewController.xib; sourceTree = ""; }; + F4E6ED9A2849695100766F9A /* unknown_termination_reason.html */ = { + isa = PBXVariantGroup; + children = ( + F4E6ED9B2849695100766F9A /* en */, + F4E6ED9D2849696000766F9A /* es */, + F4E6ED9E2849696600766F9A /* fr */, + F4E6ED9F2849696C00766F9A /* ja */, + F43066E22A12EDE7002AB430 /* he */, + ); + name = unknown_termination_reason.html; + sourceTree = ""; + }; + F4E6EDA2284969E500766F9A /* ENDPOINTSECURITY_2.html */ = { + isa = PBXVariantGroup; + children = ( + F4E6EDA3284969E500766F9A /* en */, + F4E6EDA528496E2A00766F9A /* fr */, + F43066E32A12EDE8002AB430 /* he */, + F4CE09A42A76E43300BACB71 /* es */, + F4CE09A52A76E44D00BACB71 /* ja */, + ); + name = ENDPOINTSECURITY_2.html; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -2598,7 +3326,7 @@ CLANG_WARN_BOOL_CONVERSION = YES_ERROR; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 78; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -2619,7 +3347,7 @@ CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 78; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = app_unexpectedly/app_unexpectedly_Prefix.pch; diff --git a/app_unexpectedly/app_unexpectedly.xcodeproj/xcshareddata/xcschemes/app_unexpectedly.xcscheme b/app_unexpectedly/app_unexpectedly.xcodeproj/xcshareddata/xcschemes/app_unexpectedly.xcscheme index c4926b8..64b34e7 100644 --- a/app_unexpectedly/app_unexpectedly.xcodeproj/xcshareddata/xcschemes/app_unexpectedly.xcscheme +++ b/app_unexpectedly/app_unexpectedly.xcodeproj/xcshareddata/xcschemes/app_unexpectedly.xcscheme @@ -61,6 +61,16 @@ ReferencedContainer = "container:app_unexpectedly.xcodeproj"> + + + + + + diff --git a/app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fe2b454 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcschemes/xcschememanagement.plist b/app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..2586a3a --- /dev/null +++ b/app_unexpectedly/app_unexpectedly.xcodeproj/xcuserdata/stephane.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + app_unexpectedly.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/app_unexpectedly/app_unexpectedly/AppDelegate.m b/app_unexpectedly/app_unexpectedly/AppDelegate.m index ad54512..45f8222 100644 --- a/app_unexpectedly/app_unexpectedly/AppDelegate.m +++ b/app_unexpectedly/app_unexpectedly/AppDelegate.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -48,9 +48,16 @@ #import "CUICrashLogsOpenErrorPanel.h" +#import "WBRemoteVersionChecker.h" + +#import "NSMenuItem+RSCore.h" + + NSString * const CUIApplicationShowDebugMenuKey=@"ui.menu.debug.show"; -@interface AppDelegate () +NSString * const CUIApplicationShowDebugDidChangeNotification=@"CUIApplicationShowDebugDidChangeNotification"; + +@interface AppDelegate () { IBOutlet NSMenu * _themesMenu; @@ -77,6 +84,8 @@ - (IBAction)showUnexpectedlyWebSite:(id)sender; - (void)themesListDidChange:(NSNotification *)inNotification; +- (void)showDebugMenuDidChange:(NSNotification *)inNotification; + @end @implementation AppDelegate @@ -84,8 +93,11 @@ @implementation AppDelegate + (void)initialize { [[NSUserDefaults standardUserDefaults] registerDefaults:@{ - CUIApplicationShowDebugMenuKey:@(NO) + CUIApplicationShowDebugMenuKey:@(NO), + @"NSScrollViewShouldFlipRulerForRTL":@(NO) }]; + + [NSMenuItem rs_disableIcons]; } - (void)awakeFromNib @@ -99,9 +111,11 @@ - (void)awakeFromNib // Register for notifications - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; + + [tNotificationCenter addObserver:self selector:@selector(showDebugMenuDidChange:) name:CUIApplicationShowDebugDidChangeNotification object:nil]; } #pragma mark - @@ -126,9 +140,11 @@ - (void)refreshThemesMenu NSArray * tThemes=[tThemesManager allThemes]; + SEL selector=NSSelectorFromString(@"CUI_MENUACTION_switchTheme:"); + [tThemes enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(CUITheme * bTheme, NSUInteger bIndex, BOOL * bOutStop) { - NSMenuItem * tMenuItem=[[NSMenuItem alloc] initWithTitle:bTheme.name action:@selector(CUI_MENUACTION_switchTheme:) keyEquivalent:@""]; + NSMenuItem * tMenuItem=[[NSMenuItem alloc] initWithTitle:bTheme.name action:selector keyEquivalent:@""]; tMenuItem.representedObject=bTheme.UUID; @@ -149,7 +165,7 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem { CUICrashReporterDefaults * tDefaults=[CUICrashReporterDefaults standardCrashReporterDefaults]; - inMenuItem.state=(tDefaults.dialogType==inMenuItem.tag) ? NSOnState : NSOffState; + inMenuItem.state=(tDefaults.dialogType==inMenuItem.tag) ? NSControlStateValueOn : NSControlStateValueOff; return YES; } @@ -158,7 +174,7 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem { CUICrashReporterDefaults * tDefaults=[CUICrashReporterDefaults standardCrashReporterDefaults]; - inMenuItem.state=(tDefaults.notificationMode==inMenuItem.tag) ? NSOnState : NSOffState; + inMenuItem.state=(tDefaults.notificationMode==inMenuItem.tag) ? NSControlStateValueOn : NSControlStateValueOff; return YES; } @@ -167,10 +183,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem { CUICrashReporterDefaults * tDefaults=[CUICrashReporterDefaults standardCrashReporterDefaults]; - inMenuItem.state=(tDefaults.reportUncaughtExceptions==YES) ? NSOnState : NSOffState; + inMenuItem.state=(tDefaults.reportUncaughtExceptions==YES) ? NSControlStateValueOn : NSControlStateValueOff; } - return YES; } @@ -299,6 +314,26 @@ - (void)application:(NSApplication *)sender openFiles:(NSArray *)inF if (tSource==nil) { + if (tError!=nil) + { + if ([tError.domain isEqualToString:IPSErrorDomain]==YES) + { + switch(tError.code) + { + case IPSUnsupportedBugTypeError: + + // Open file in Console.app + + if ([[NSWorkspace sharedWorkspace] openFile:tFilePath withApplication:@"/Applications/Utilities/Console.app"]==YES) + { + return; + } + + break; + } + } + } + CUICrashLogsOpenErrorRecord * tRecord=[CUICrashLogsOpenErrorRecord new]; tRecord.sourceURL=[NSURL fileURLWithPath:tFilePath]; tRecord.openError=tError; @@ -333,7 +368,8 @@ - (void)application:(NSApplication *)sender openFiles:(NSArray *)inF [tErrorPanel runModal]; } - + + [NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; } - (BOOL)application:(NSApplication *)sender openFile:(NSString *)inFilePath @@ -404,6 +440,8 @@ - (BOOL)application:(NSApplication *)sender openFile:(NSString *)inFilePath - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + [WBRemoteVersionChecker sharedChecker]; + _mainWindowController=[CUIMainWindowController new]; //NSLog(@"%@",_mainWindowController.window.frameAutosaveName); @@ -423,4 +461,11 @@ - (void)themesListDidChange:(NSNotification *)inNotification [self refreshThemesMenu]; } +- (void)showDebugMenuDidChange:(NSNotification *)inNotification +{ + NSUserDefaults * tUserDefaults=[NSUserDefaults standardUserDefaults]; + + _debugMenuBarItem.hidden=([tUserDefaults boolForKey:CUIApplicationShowDebugMenuKey]==NO); +} + @end diff --git a/app_unexpectedly/app_unexpectedly/CUIAboutBoxFooterView.m b/app_unexpectedly/app_unexpectedly/CUIAboutBoxFooterView.m index a2e10c5..6deae4a 100755 --- a/app_unexpectedly/app_unexpectedly/CUIAboutBoxFooterView.m +++ b/app_unexpectedly/app_unexpectedly/CUIAboutBoxFooterView.m @@ -15,8 +15,10 @@ @implementation CUIAboutBoxFooterView -- (void)drawRect:(NSRect) inRect +- (void)drawRect:(NSRect)inRect { + NSRect tRefreshRect=NSIntersectionRect(self.bounds, inRect); + // Draw background BOOL tIsDarkMode=[self WB_isEffectiveAppearanceDarkAqua]; @@ -26,12 +28,10 @@ - (void)drawRect:(NSRect) inRect else [[NSColor colorWithDeviceWhite:0.0 alpha:0.18] set]; - NSRectFillUsingOperation(inRect,NSCompositingOperationSourceOver); + NSRectFillUsingOperation(tRefreshRect,NSCompositingOperationSourceOver); // Draw top line - NSRect tBounds=[self bounds]; - if (tIsDarkMode==NO) [[NSColor colorWithDeviceWhite:0.698 alpha:1.0] set]; else @@ -40,9 +40,9 @@ - (void)drawRect:(NSRect) inRect NSRect tLineRect; if (tIsDarkMode==NO) - tLineRect=NSMakeRect(NSMinX(inRect),NSMaxY(tBounds)-1.0,NSWidth(tBounds),1.0); + tLineRect=NSMakeRect(NSMinX(tRefreshRect),NSMaxY(tRefreshRect)-1.0,NSWidth(tRefreshRect),1.0); else - tLineRect=NSMakeRect(NSMinX(inRect)+1.0,NSMaxY(tBounds)-1.0,NSWidth(tBounds)-3.0,1.0); + tLineRect=NSMakeRect(NSMinX(tRefreshRect)+1.0,NSMaxY(tRefreshRect)-1.0,NSWidth(tRefreshRect)-3.0,1.0); NSRectFillUsingOperation(tLineRect,NSCompositingOperationSourceOver); } diff --git a/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindow.m b/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindow.m index 1a4b92d..a2b236f 100644 --- a/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindow.m +++ b/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindow.m @@ -27,7 +27,7 @@ - (void)becomeKeyWindow if (tEvent!=nil) { - NSUInteger tModifierFlags=[tEvent modifierFlags]; + NSUInteger tModifierFlags=tEvent.modifierFlags; BOOL isDown=((tModifierFlags & NSEventModifierFlagOption) == NSEventModifierFlagOption); @@ -35,9 +35,9 @@ - (void)becomeKeyWindow { _optionKeyDown=isDown; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIOptionKeyStateDidChangeNotification - object:self - userInfo:@{CUIOptionKeyState:@(_optionKeyDown)}]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIOptionKeyStateDidChangeNotification + object:self + userInfo:@{CUIOptionKeyState:@(_optionKeyDown)}]; } } @@ -52,9 +52,9 @@ - (void)resignKeyWindow // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIOptionKeyStateDidChangeNotification - object:self - userInfo:@{CUIOptionKeyState:@(_optionKeyDown)}]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIOptionKeyStateDidChangeNotification + object:self + userInfo:@{CUIOptionKeyState:@(_optionKeyDown)}]; } [super resignKeyWindow]; @@ -65,7 +65,7 @@ - (void)flagsChanged:(NSEvent *)inEvent if (inEvent==nil) return; - NSUInteger tModifierFlags=[inEvent modifierFlags]; + NSUInteger tModifierFlags=inEvent.modifierFlags; BOOL isDown=((tModifierFlags & NSEventModifierFlagOption) == NSEventModifierFlagOption); @@ -75,9 +75,9 @@ - (void)flagsChanged:(NSEvent *)inEvent // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIOptionKeyStateDidChangeNotification - object:self - userInfo:@{CUIOptionKeyState:@(_optionKeyDown)}]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIOptionKeyStateDidChangeNotification + object:self + userInfo:@{CUIOptionKeyState:@(_optionKeyDown)}]; } } diff --git a/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindowController.m b/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindowController.m index 4104975..94e8377 100644 --- a/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindowController.m +++ b/app_unexpectedly/app_unexpectedly/CUIAboutBoxWindowController.m @@ -45,7 +45,7 @@ + (void)showAbouxBox - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -65,7 +65,7 @@ - (void)windowDidLoad // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(optionKeyStateDidChange:) name:CUIOptionKeyStateDidChangeNotification object:self.window]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(optionKeyStateDidChange:) name:CUIOptionKeyStateDidChangeNotification object:self.window]; [self.window center]; } @@ -82,7 +82,7 @@ - (IBAction)showLicenseAgreement:(id)sender return; } - [[NSWorkspace sharedWorkspace] openFile:tPath]; + [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:tPath]]; } - (IBAction)showAcknowledgments:(id)sender @@ -95,7 +95,7 @@ - (IBAction)showAcknowledgments:(id)sender return; } - [[NSWorkspace sharedWorkspace] openFile:tPath]; + [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:tPath]]; } #pragma mark - Notifications diff --git a/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.h b/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.h index c769b2f..cd03e6e 100644 --- a/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.h +++ b/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.h @@ -65,6 +65,8 @@ typedef NS_ENUM(NSUInteger, CUICrashLogsSortType) @property (nonatomic) CUICrashLogsSortType crashLogsSortType; + @property (nonatomic) BOOL crashLogsShowFileNames; + + (CUIApplicationPreferences *)sharedPreferences; @@ -79,3 +81,5 @@ extern NSString * const CUIPreferencesTextModeLineWrappingDidChangeNotification; extern NSString * const CUIPreferencesSymbolicationSymbolicateAutomaticallyDidChangeNotification; extern NSString * const CUIPreferencesCrashLogsSortTypeDidChangeNotification; + +extern NSString * const CUIPreferencesCrashLogsShowFileNamesDidChangeNotification; diff --git a/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.m b/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.m index 65f5364..75cc0fd 100644 --- a/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.m +++ b/app_unexpectedly/app_unexpectedly/CUIApplicationPreferences.m @@ -59,6 +59,8 @@ // Crash Logs List +NSString * const CUIPreferencesCrashLogsShowFileNamesKey=@"showFileNames"; + NSString * const CUIPreferencesCrashLogsSortTypeKey=@"crashLogs.list.sort"; // Notifications @@ -74,7 +76,7 @@ NSString * const CUIPreferencesCrashLogsSortTypeDidChangeNotification=@"CUIPreferencesCrashLogsSortTypeDidChangeNotification"; - +NSString * const CUIPreferencesCrashLogsShowFileNamesDidChangeNotification=@"CUIPreferencesCrashLogsShowFileNamesDidChangeNotification"; @interface CUIApplicationPreferences () { @@ -144,7 +146,8 @@ - (instancetype)init // Crash Logs - CUIPreferencesCrashLogsSortTypeKey:@(CUICrashLogsSortDateDescending) + CUIPreferencesCrashLogsSortTypeKey:@(CUICrashLogsSortDateDescending), + CUIPreferencesCrashLogsSortTypeKey:@(NO) }]; @@ -192,6 +195,8 @@ - (instancetype)init _crashLogsSortType=[_defaults integerForKey:CUIPreferencesCrashLogsSortTypeKey]; + _crashLogsShowFileNames=[_defaults boolForKey:CUIPreferencesCrashLogsShowFileNamesKey]; + } return self; @@ -226,7 +231,7 @@ - (void)setSymbolicateAutomatically:(BOOL)inSymbolicateAutomatically [_defaults setBool:inSymbolicateAutomatically forKey:CUIPreferencesSymbolicationSymbolicateAutomaticallyKey]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIPreferencesSymbolicationSymbolicateAutomaticallyDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIPreferencesSymbolicationSymbolicateAutomaticallyDidChangeNotification object:nil]; } - (void)setPreferedSourceCodeEditorURL:(NSURL *)inURL @@ -247,7 +252,7 @@ - (void)setShowsLineNumbers:(BOOL)inShowsLineNumber [_defaults setBool:inShowsLineNumber forKey:CUIPreferencesTextModeShowsLineNumbersKey]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIPreferencesTextModeShowsLineNumbersDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIPreferencesTextModeShowsLineNumbersDidChangeNotification object:nil]; } - (void)setLineWrapping:(BOOL)inLineWrapping @@ -256,7 +261,7 @@ - (void)setLineWrapping:(BOOL)inLineWrapping [_defaults setBool:inLineWrapping forKey:CUIPreferencesTextModeLineWrappingKey]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIPreferencesTextModeLineWrappingDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIPreferencesTextModeLineWrappingDidChangeNotification object:nil]; } - (void)setDefaultTextModeDisplaySettings:(CUITextModeDisplaySettings *)inDisplaySettings @@ -284,7 +289,19 @@ - (void)setCrashLogsSortType:(CUICrashLogsSortType)inCrashLogsSortType [_defaults setObject:@(_crashLogsSortType) forKey:CUIPreferencesCrashLogsSortTypeKey]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIPreferencesCrashLogsSortTypeDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIPreferencesCrashLogsSortTypeDidChangeNotification object:nil]; +} + +- (void)setCrashLogsShowFileNames:(BOOL)inCrashLogsShowFileNames +{ + if (_crashLogsShowFileNames==inCrashLogsShowFileNames) + return; + + _crashLogsShowFileNames=inCrashLogsShowFileNames; + + [_defaults setObject:@(_crashLogsShowFileNames) forKey:CUIPreferencesCrashLogsShowFileNamesKey]; + + [NSNotificationCenter.defaultCenter postNotificationName:CUIPreferencesCrashLogsShowFileNamesDidChangeNotification object:nil]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIBinaryImage.h b/app_unexpectedly/app_unexpectedly/CUIBinaryImage.h index 274b9fd..43e107f 100644 --- a/app_unexpectedly/app_unexpectedly/CUIBinaryImage.h +++ b/app_unexpectedly/app_unexpectedly/CUIBinaryImage.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,6 +13,8 @@ #import +#import "IPSImage.h" + @interface CUIAddressesRange : NSObject @property NSUInteger loadAddress; @@ -30,8 +32,6 @@ @interface CUIBinaryImage : NSObject - @property (getter=isMainImage) BOOL mainImage; - @property (readonly,getter=isUserCode) BOOL userCode; @property (readonly,copy) NSString * identifier; @@ -52,4 +52,6 @@ - (instancetype)initWithString:(NSString *)inString reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; +- (instancetype)initWithImage:(IPSImage *)inImage error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUIBinaryImage.m b/app_unexpectedly/app_unexpectedly/CUIBinaryImage.m index 3c09114..02010b5 100644 --- a/app_unexpectedly/app_unexpectedly/CUIBinaryImage.m +++ b/app_unexpectedly/app_unexpectedly/CUIBinaryImage.m @@ -13,6 +13,10 @@ #import "CUIBinaryImage.h" +#import "NSString+CPU.h" + +#import "IPSImage+UserCode.h" + @interface CUIAddressesRange () + (CUIAddressesRange *)addressesRangeWithLocation:(NSUInteger)inLocation length:(NSUInteger)inLength; @@ -97,6 +101,8 @@ @interface CUIBinaryImage () @property CUIAddressesRange * addressesRange; +- (BOOL)_isUserCode; + @end // Line example: @@ -106,7 +112,7 @@ @implementation CUIBinaryImage - (instancetype)initWithString:(NSString *)inString reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError { - if ([inString isKindOfClass:[NSString class]]==NO) + if ([inString isKindOfClass:NSString.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -141,8 +147,28 @@ - (instancetype)initWithString:(NSString *)inString reportVersion:(NSUInteger)in NSString * tString; NSString * tOriginalString; + BOOL tIsMissingVersion=NO; + + NSUInteger tSavedScannerScanLocation=tScanner.scanLocation; + if ([tScanner scanUpToString:@"(" intoString:&tOriginalString]==NO) + { return nil; + } + else + { + // Maybe only the version is missing + + if (tScanner.scanLocation==inString.length) + { + tScanner.scanLocation=tSavedScannerScanLocation; + + if ([tScanner scanUpToString:@"<" intoString:&tOriginalString]==NO) + return nil; + + tIsMissingVersion=YES; + } + } if (inReportVersion==6) { @@ -166,7 +192,7 @@ - (instancetype)initWithString:(NSString *)inString reportVersion:(NSUInteger)in tString=tOriginalString; } - if ([tString hasPrefix:@"+"]==YES && tString.length>1) + if ([tString hasPrefix:@"+"]==YES && tString.length>1) // Cheap way to find that a binary image is user code. { _userCode=YES; @@ -180,48 +206,57 @@ - (instancetype)initWithString:(NSString *)inString reportVersion:(NSUInteger)in if (tScanner.scanLocation>=inString.length) return nil; - if (inReportVersion==6) + if (tIsMissingVersion==NO) { - NSUInteger tLength=tOriginalString.length; - - NSRange tRange=[tOriginalString rangeOfCharacterFromSet:tWhitespaceCharacterSet options:NSBackwardsSearch range:NSMakeRange(0,tLength-1)]; - - _version=[[tOriginalString substringFromIndex:tRange.location] stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; - - tScanner.scanLocation+=1; - - if ([tScanner scanUpToString:@")" intoString:&tString]==NO) - return nil; + + if (inReportVersion==6) + { + NSUInteger tLength=tOriginalString.length; + + NSRange tRange=[tOriginalString rangeOfCharacterFromSet:tWhitespaceCharacterSet options:NSBackwardsSearch range:NSMakeRange(0,tLength-1)]; + + _version=[[tOriginalString substringFromIndex:tRange.location] stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + + tScanner.scanLocation+=1; + + if ([tScanner scanUpToString:@")" intoString:&tString]==NO) + return nil; + + _buildNumber=[tString stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + } + else + { + tScanner.scanLocation+=1; + + if ([tScanner scanUpToString:@")" intoString:&tString]==NO) + return nil; + + NSArray * tVersions=[tString componentsSeparatedByString:@" - "]; + + switch(tVersions.count) + { + case 2: + + _buildNumber=[tVersions[1] stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + + case 1: + + _version=[tVersions.firstObject stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + + break; + } + } - _buildNumber=[tString stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + tScanner.scanLocation+=2; } else { - tScanner.scanLocation+=1; - - if ([tScanner scanUpToString:@")" intoString:&tString]==NO) - return nil; - - NSArray * tVersions=[tString componentsSeparatedByString:@" - "]; - - switch(tVersions.count) - { - case 2: - - _buildNumber=[tVersions[1] stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; - - case 1: - - _version=[tVersions.firstObject stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; - - break; - } + _version=@"???"; + _buildNumber=@"???"; } // UUID - tScanner.scanLocation+=2; - if ([inString characterAtIndex:tScanner.scanLocation]=='<') { if ([tScanner scanUpToString:@">" intoString:&tString]==NO) @@ -238,6 +273,46 @@ - (instancetype)initWithString:(NSString *)inString reportVersion:(NSUInteger)in return nil; _path=[[inString substringFromIndex:tScanner.scanLocation] stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + + // User Code + + _userCode = (_userCode == YES) ? YES : [self _isUserCode]; + } + + return self; +} + +- (instancetype)initWithImage:(IPSImage *)inImage error:(NSError **)outError +{ + if ([inImage isKindOfClass:IPSImage.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + _userCode=inImage.isUserCode; + + _identifier=[((inImage.bundleIdentifier!=nil) ? inImage.bundleIdentifier : inImage.name) copy]; + + _architecture=[inImage.architecture CUI_CPUType]; + + _version=[inImage.bundleShortVersionString copy]; + + _buildNumber=[inImage.bundleVersion copy]; + + _UUID=[inImage.UUID.UUIDString copy]; + + _path=[inImage.path copy]; + + _addressesRange=[CUIAddressesRange new]; + _addressesRange.loadAddress=inImage.loadAddress; + _addressesRange.length=inImage.size; } return self; @@ -249,10 +324,61 @@ - (NSUInteger)binaryImageOffset { NSUInteger tLoadAddress=self.addressesRange.loadAddress; - if (tLoadAddress>0x7fff00000000 || self.mainImage==NO) + if (tLoadAddress>0x7fff00000000) // Won't happen with ARM-64. return tLoadAddress; - return (tLoadAddress-0x100000000); + if (tLoadAddress>=0x100000000) + return (tLoadAddress-0x100000000); + + return tLoadAddress; // 32-bit +} + +- (BOOL)_isUserCode +{ + NSString * tIdentifier=self.identifier; + + if (tIdentifier!=nil) + { + if ([tIdentifier hasPrefix:@"com.apple."]==YES) + return NO; + } + + NSString * tPath=self.path; + + if (tPath!=nil) + { + if ([tPath hasPrefix:@"/System/"]==YES) + return NO; + + if ([tPath hasPrefix:@"/usr/"]==YES) + { + if ([tPath hasPrefix:@"/usr/bin"]==YES) + return NO; + + if ([tPath hasPrefix:@"/usr/sbin"]==YES) + return NO; + + if ([tPath hasPrefix:@"/usr/lib"]==YES) + return NO; + + if ([tPath hasPrefix:@"/usr/libexec"]==YES) + return NO; + + if ([tPath hasPrefix:@"/usr/share"]==YES) + return NO; + } + + if ([tPath hasPrefix:@"/bin/"]==YES) + return NO; + + if ([tPath hasPrefix:@"/sbin/"]==YES) + return NO; + + if ([tPath hasPrefix:@"/Library/Apple"]==YES) + return NO; + } + + return YES; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIBinaryImage+UI.h b/app_unexpectedly/app_unexpectedly/CUIBinaryImageUtility.h similarity index 97% rename from app_unexpectedly/app_unexpectedly/CUIBinaryImage+UI.h rename to app_unexpectedly/app_unexpectedly/CUIBinaryImageUtility.h index 097d603..737d673 100644 --- a/app_unexpectedly/app_unexpectedly/CUIBinaryImage+UI.h +++ b/app_unexpectedly/app_unexpectedly/CUIBinaryImageUtility.h @@ -11,8 +11,6 @@ Redistribution and use in source and binary forms, with or without modification, THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "CUIBinaryImage.h" - #import extern NSString * const CUIBinaryImageGroupAppKitUIKit; @@ -29,7 +27,7 @@ extern NSString * const CUIBinaryImageGroupSystem; extern NSString * const CUIBinaryImageGroupUserCode; extern NSString * const CUIBinaryImageGroupWebInternet; -@interface CUIBinaryImage (UI) +@interface CUIBinaryImageUtility : NSObject + (NSString *)binaryImageGroupForIdentifier:(NSString *)inIdentifier; diff --git a/app_unexpectedly/app_unexpectedly/CUIBinaryImage+UI.m b/app_unexpectedly/app_unexpectedly/CUIBinaryImageUtility.m similarity index 97% rename from app_unexpectedly/app_unexpectedly/CUIBinaryImage+UI.m rename to app_unexpectedly/app_unexpectedly/CUIBinaryImageUtility.m index 0b75966..8aa0bf9 100644 --- a/app_unexpectedly/app_unexpectedly/CUIBinaryImage+UI.m +++ b/app_unexpectedly/app_unexpectedly/CUIBinaryImageUtility.m @@ -11,7 +11,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "CUIBinaryImage+UI.h" +#import "CUIBinaryImageUtility.h" NSString * const CUIBinaryImageGroupAppKitUIKit=@"AppKit/UIKit"; NSString * const CUIBinaryImageGroupAudioSpeech=@"Audio/Speech"; @@ -28,7 +28,7 @@ NSString * const CUIBinaryImageGroupWebInternet=@"Web/Internet"; -@implementation CUIBinaryImage (UI) +@implementation CUIBinaryImageUtility + (NSString *)binaryImageGroupForIdentifier:(NSString *)inIdentifier { @@ -273,9 +273,9 @@ + (NSColor *)colorForBinaryImageGroup:(NSString *)inBinaryImageGroup + (NSImage *)iconForIdentifier:(NSString *)inIdentifier { - NSString * tBinaryImageGroup=[CUIBinaryImage binaryImageGroupForIdentifier:inIdentifier]; + NSString * tBinaryImageGroup=[CUIBinaryImageUtility binaryImageGroupForIdentifier:inIdentifier]; - return [CUIBinaryImage iconForBinaryImageGroup:tBinaryImageGroup]; + return [CUIBinaryImageUtility iconForBinaryImageGroup:tBinaryImageGroup]; } + (NSImage *)iconForPath:(NSString *)inPath @@ -298,9 +298,9 @@ + (NSColor *)colorForUserCode + (NSColor *)colorForIdentifier:(NSString *)inIdentifier { - NSString * tBinaryImageGroup=[CUIBinaryImage binaryImageGroupForIdentifier:inIdentifier]; + NSString * tBinaryImageGroup=[CUIBinaryImageUtility binaryImageGroupForIdentifier:inIdentifier]; - return [CUIBinaryImage colorForBinaryImageGroup:tBinaryImageGroup]; + return [CUIBinaryImageUtility colorForBinaryImageGroup:tBinaryImageGroup]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIBinaryImagesViewController.m b/app_unexpectedly/app_unexpectedly/CUIBinaryImagesViewController.m index d28942b..393b4eb 100644 --- a/app_unexpectedly/app_unexpectedly/CUIBinaryImagesViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIBinaryImagesViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,7 +15,7 @@ #import "CUIBinaryImage.h" -#import "CUIBinaryImage+UI.h" +#import "CUIBinaryImageUtility.h" #import "CUICallsSelection.h" @@ -31,7 +31,7 @@ #import "CUIHopperDisassemblerManager.h" -@interface CUIBinaryImagesViewController () +@interface CUIBinaryImagesViewController () { IBOutlet NSTableView * _tableView; @@ -112,7 +112,7 @@ - (void)viewDidLoad // Notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callsSelectionDidChange:) name:CUICallsSelectionDidChangeNotification object:[CUICallsSelection sharedCallsSelection]]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(callsSelectionDidChange:) name:CUICallsSelectionDidChangeNotification object:[CUICallsSelection sharedCallsSelection]]; } #pragma mark - @@ -304,26 +304,16 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu tTableCellView.textField.stringValue=tBinaryImage.identifier; if (tBinaryImage.isUserCode==YES) - { tTableCellView.imageView.image=[NSImage imageNamed:@"call-usercode"]; - } else - { - tTableCellView.imageView.image=[CUIBinaryImage iconForIdentifier:tBinaryImage.identifier]; - } - - + tTableCellView.imageView.image=[CUIBinaryImageUtility iconForIdentifier:tBinaryImage.identifier]; } else if ([tTableColumnIdentifier isEqualToString:@"version"]==YES) { if (tBinaryImage.buildNumber==nil) - { - tTableCellView.textField.stringValue=tBinaryImage.version; - } + tTableCellView.textField.stringValue=(tBinaryImage.version!=nil) ? tBinaryImage.version : @"-"; else - { - tTableCellView.textField.stringValue=[NSString stringWithFormat:@"%@ (%@)",tBinaryImage.version,tBinaryImage.buildNumber]; - } + tTableCellView.textField.stringValue=[NSString stringWithFormat:NSLocalizedString(@"%@ (%@)",@""),tBinaryImage.version,tBinaryImage.buildNumber]; } else if ([tTableColumnIdentifier isEqualToString:@"addresses"]==YES) { diff --git a/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.h b/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.h index a84f4e6..5a25d55 100644 --- a/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.h +++ b/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.h @@ -15,10 +15,15 @@ #import "CUIStackFrame.h" +#import "IPSThreadFrame.h" +#import "IPSImage.h" + @interface CUICallStackBacktrace : NSObject @property (readonly) NSArray * stackFrames; - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError; +- (instancetype)initWithFrames:(NSArray *)inFrames binaryImages:(NSArray *)inImages error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.m b/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.m index 2c90893..ceb5c84 100644 --- a/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.m +++ b/app_unexpectedly/app_unexpectedly/CUICallStackBacktrace.m @@ -65,6 +65,40 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError return self; } +- (instancetype)initWithFrames:(NSArray *)inFrames binaryImages:(NSArray *)inImages error:(NSError **)outError +{ + if ([inFrames isKindOfClass:[NSArray class]]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + _stackFrames=[inFrames WB_arrayByMappingObjectsUsingBlock:^CUIStackFrame *(IPSThreadFrame * bFrame, NSUInteger bIndex) { + + CUIStackFrame * tStackFrame=[[CUIStackFrame alloc] initWithThreadFrame:bFrame + atIndex:bIndex + image:inImages[bFrame.imageIndex] + error:NULL]; + + if (tStackFrame==nil) + { + return nil; + } + + return tStackFrame; + + }]; + } + + return self; +} + #pragma mark - - (NSString *)description diff --git a/app_unexpectedly/app_unexpectedly/CUICallsSelection.m b/app_unexpectedly/app_unexpectedly/CUICallsSelection.m index d9c8b33..528a1f3 100644 --- a/app_unexpectedly/app_unexpectedly/CUICallsSelection.m +++ b/app_unexpectedly/app_unexpectedly/CUICallsSelection.m @@ -39,7 +39,7 @@ - (void)setCalls:(NSSet *)inCalls { _calls=inCalls; - [[NSNotificationCenter defaultCenter] postNotificationName:CUICallsSelectionDidChangeNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICallsSelectionDidChangeNotification object:self]; } - (NSSet *)binaryImageIdentifiers diff --git a/app_unexpectedly/app_unexpectedly/CUICenteredLabelViewController.m b/app_unexpectedly/app_unexpectedly/CUICenteredLabelViewController.m index 018fc88..aa63524 100644 --- a/app_unexpectedly/app_unexpectedly/CUICenteredLabelViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICenteredLabelViewController.m @@ -36,7 +36,7 @@ @implementation CUICenteredLabelViewController - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } - (NSString *)nibName @@ -66,13 +66,13 @@ - (void)viewWillAppear // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; } - (void)viewWillDisappear { - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewFrameDidChangeNotification object:self.view]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSViewFrameDidChangeNotification object:self.view]; } #pragma mark - diff --git a/app_unexpectedly/app_unexpectedly/CUICodeSigningFlagsTableView.h b/app_unexpectedly/app_unexpectedly/CUICodeSigningFlagsTableView.h new file mode 100644 index 0000000..fc7c435 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICodeSigningFlagsTableView.h @@ -0,0 +1,22 @@ +/* + Copyright (c) 2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CUICodeSigningFlagsTableView : NSTableView + +@end + +NS_ASSUME_NONNULL_END diff --git a/app_unexpectedly/app_unexpectedly/CUICodeSigningFlagsTableView.m b/app_unexpectedly/app_unexpectedly/CUICodeSigningFlagsTableView.m new file mode 100644 index 0000000..96a105b --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICodeSigningFlagsTableView.m @@ -0,0 +1,40 @@ +/* + Copyright (c) 2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUICodeSigningFlagsTableView.h" + +@implementation CUICodeSigningFlagsTableView + +- (BOOL)isOpaque +{ + return NO; +} + +- (NSColor *)backgroundColor +{ + return [NSColor clearColor]; +} + +#pragma mark - + +- (BOOL)acceptsFirstResponder +{ + return NO; +} + +- (NSView *)hitTest:(NSPoint)point +{ + return nil; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUICodeSigningInformationViewController.h b/app_unexpectedly/app_unexpectedly/CUICodeSigningInformationViewController.h new file mode 100644 index 0000000..12a8d22 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICodeSigningInformationViewController.h @@ -0,0 +1,23 @@ +/* + Copyright (c) 2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "IPSIncidentHeader.h" + +@interface CUICodeSigningInformationViewController : NSViewController + +- (instancetype)initWithCodeSigningInfo:(IPSCodeSigningInfo *)inCodeSigningInfo; + +@end + diff --git a/app_unexpectedly/app_unexpectedly/CUICodeSigningInformationViewController.m b/app_unexpectedly/app_unexpectedly/CUICodeSigningInformationViewController.m new file mode 100644 index 0000000..94334fc --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICodeSigningInformationViewController.m @@ -0,0 +1,180 @@ +/* + Copyright (c) 2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUICodeSigningInformationViewController.h" +#import "NSDictionary+WBExtensions.h" + +@interface IPSCodeSigningInfo (UI) + +@property (nonatomic, readonly) NSString *validationCategoryDisplayString; + +@end + + +@implementation IPSCodeSigningInfo (UI) + +- (NSString *)validationCategoryDisplayString +{ + switch(self.validationCategory) + { + case IPSCodeSigningValidationCategoryPlatform: + return NSLocalizedStringFromTable(@"",@"CodeSigning",@""); + + case IPSCodeSigningValidationCategoryTestFlight: + return NSLocalizedStringFromTable(@"TestFlight",@"CodeSigning",@""); + + case IPSCodeSigningValidationCategoryDevelopment: + return NSLocalizedStringFromTable(@"Development",@"CodeSigning",@""); + + case IPSCodeSigningValidationCategoryAppStore: + return NSLocalizedStringFromTable(@"AppStore",@"CodeSigning",@""); + + case IPSCodeSigningValidationCategoryEnterprise: + return NSLocalizedStringFromTable(@"Enterprise",@"CodeSigning",@""); + + case IPSCodeSigningValidationCategoryDeveloperID: + return NSLocalizedStringFromTable(@"Developer ID",@"CodeSigning",@""); + + case IPSCodeSigningValidationCategoryNone: + return NSLocalizedStringFromTable(@"None",@"CodeSigning",@""); + } + + return @"-"; +} + +@end + +@interface CUICodeSigningInformationViewController () +{ + IPSCodeSigningInfo * _info; + + IBOutlet NSTextField * _identifierTextField; + IBOutlet NSTextField * _teamIdentifierTextField; + + IBOutlet NSTextField * _validationCategoryTextField; + + IBOutlet NSTextField * _flagsRichTextField; + + IBOutlet NSTextField * _trustLevelTextField; +} + +@end + +@implementation CUICodeSigningInformationViewController + ++ (NSDictionary *)flagsToLocalizedNameDictionary +{ + static dispatch_once_t onceToken; + static NSDictionary * sConversionDictionary=nil; + + dispatch_once(&onceToken, ^{ + + NSURL * tResourceURL=[[NSBundle bundleForClass:self] URLForResource:@"CodeSigningFlags" withExtension:@"plist"]; + NSError * tError; + + sConversionDictionary=[[NSDictionary alloc] initWithContentsOfURL:tResourceURL error:&tError]; + + if (sConversionDictionary==nil) + NSLog(@"Could not get the list of codesigning flags: %@",tError); + }); + + return sConversionDictionary; +} + +- (instancetype)initWithCodeSigningInfo:(IPSCodeSigningInfo *)inCodeSigningInfo +{ + self=[super init]; + + if (self!=nil) + { + _info=[inCodeSigningInfo copy]; + } + + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + _identifierTextField.stringValue=_info.identifier ?: @"-"; + _teamIdentifierTextField.stringValue=_info.teamIdentifier ?: @"-"; + _validationCategoryTextField.stringValue=_info.validationCategoryDisplayString; + _flagsRichTextField.attributedStringValue=[self codeSigningFlagsDisplayString]; + _trustLevelTextField.stringValue=[NSString stringWithFormat:@"0x%x",_info.trustLevel]; +} + +#pragma mark - + +- (NSAttributedString *)codeSigningFlagsDisplayString +{ + NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:@""]; + + NSDictionary *tFlagsToLocalizedNameDictionary = [CUICodeSigningInformationViewController flagsToLocalizedNameDictionary]; + static dispatch_once_t onceToken; + static NSArray * sAllFlags=nil; + + dispatch_once(&onceToken, ^{ + sAllFlags=[tFlagsToLocalizedNameDictionary.allKeys sortedArrayUsingSelector:@selector(compare:)]; + }); + + BOOL tFirstLine=YES; + NSAttributedString * tNewLine=[[NSAttributedString alloc] initWithString:@"\n" + attributes:nil]; + BOOL tShouldIncreaseContrast=NSWorkspace.sharedWorkspace.accessibilityDisplayShouldIncreaseContrast; + NSFont * tSystemFont=[NSFont systemFontOfSize:NSFont.systemFontSize];; + NSFont * tBoldSystemFont=[NSFont boldSystemFontOfSize:NSFont.systemFontSize]; + + for(NSString * tKey in sAllFlags) + { + if (tFirstLine==NO) + [tMutableAttributedString appendAttributedString:tNewLine]; + else + tFirstLine=NO; + + NSNumber * tFlagNumber=tFlagsToLocalizedNameDictionary[tKey]; + BOOL tIsFlagSet=((tFlagNumber.unsignedIntValue & _info.flags)!=0); + NSDictionary * tAttributes; + + if (tIsFlagSet==YES) + { + NSFont * tFont; + + if (tShouldIncreaseContrast==YES) + tFont = tBoldSystemFont; + else + tFont = tSystemFont; + + tAttributes = @{ + NSForegroundColorAttributeName : NSColor.labelColor, + NSFontAttributeName : tFont + }; + } + else + { + tAttributes = @{ + NSForegroundColorAttributeName : NSColor.tertiaryLabelColor, + NSFontAttributeName : tSystemFont + }; + } + + NSAttributedString * tAttributedLine=[[NSAttributedString alloc] initWithString:tKey + attributes:tAttributes]; + + [tMutableAttributedString appendAttributedString:tAttributedLine]; + } + + return tMutableAttributedString; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUICollectionViewRegisterItem.m b/app_unexpectedly/app_unexpectedly/CUICollectionViewRegisterItem.m index 2c495f3..798aa39 100644 --- a/app_unexpectedly/app_unexpectedly/CUICollectionViewRegisterItem.m +++ b/app_unexpectedly/app_unexpectedly/CUICollectionViewRegisterItem.m @@ -17,6 +17,8 @@ #import "CUIRegisterLabel.h" +#define MACOS_BIGSUR_WIDTH_INSET 3.0 + NSString * const CUIRegisterItemViewAsValueDidChangeNotification=@"CUIRegisterItemViewAsValueDidChangeNotification"; @interface CUICollectionViewRegisterItem () @@ -24,6 +26,8 @@ @interface CUICollectionViewRegisterItem () IBOutlet NSTextField * _registerNameLabel; IBOutlet CUIRegisterLabel * _registerValueLabel; + + IBOutlet NSPopUpButton* _registerValueDisplayFormatPopUpButton; } @end @@ -32,6 +36,18 @@ @implementation CUICollectionViewRegisterItem - (void)viewDidLoad { [super viewDidLoad]; + + if (NSAppKitVersionNumber>0/*2022.00*/) // A VERIFIER + { + // Deal with macOS Big Sur different UI metrics + + NSRect tFrame=_registerValueDisplayFormatPopUpButton.frame; + + tFrame.origin.x+=MACOS_BIGSUR_WIDTH_INSET; + tFrame.size.width-=MACOS_BIGSUR_WIDTH_INSET; + + _registerValueDisplayFormatPopUpButton.frame=tFrame; + } } #pragma mark - @@ -113,11 +129,11 @@ - (void)registerLabel:(CUIRegisterLabel *)inRegisterLabel viewValueAsDidChange:( // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIRegisterItemViewAsValueDidChangeNotification - object:tRegister - userInfo:@{ - @"viewAs":@(inType) - }]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIRegisterItemViewAsValueDidChangeNotification + object:tRegister + userInfo:@{ + @"viewAs":@(inType) + }]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIContentsViewController.m b/app_unexpectedly/app_unexpectedly/CUIContentsViewController.m index c8e08f6..ddb25f8 100644 --- a/app_unexpectedly/app_unexpectedly/CUIContentsViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIContentsViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,7 +21,7 @@ #import "CUICrashLogsSelection.h" -@interface CUIContentsViewController () +@interface CUIContentsViewController () { IBOutlet NSView * _topView; @@ -56,7 +56,7 @@ - (instancetype)init // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; } @@ -65,7 +65,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -172,11 +172,13 @@ - (void)setSelection:(CUICrashLogsSelection *)inSelection } if (_currentController!=tNewController) + { [_currentController.view removeFromSuperview]; - tNewController.view.frame=_contentsView.bounds; + tNewController.view.frame=_contentsView.bounds; - [_contentsView addSubview:tNewController.view]; + [_contentsView addSubview:tNewController.view]; + } _currentController=tNewController; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashDataTransform.h b/app_unexpectedly/app_unexpectedly/CUICrashDataTransform.h new file mode 100644 index 0000000..212b304 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICrashDataTransform.h @@ -0,0 +1,18 @@ +/* + Copyright (c) 2020-2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIReportThemedTransform.h" + +@interface CUICrashDataTransform : CUIReportThemedTransform + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashDataTransform.m b/app_unexpectedly/app_unexpectedly/CUICrashDataTransform.m new file mode 100644 index 0000000..3f14859 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICrashDataTransform.m @@ -0,0 +1,1197 @@ +/* + Copyright (c) 2020-2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUICrashDataTransform.h" + +#import "CUIApplicationPreferences.h" +#import "CUIApplicationPreferences+Themes.h" + +#import "CUICrashLogBinaryImages.h" + +#import "CUIBinaryImageUtility.h" + +#import "CUIThemesManager.h" +#import "CUIThemeItemsGroup+UI.h" + +#ifndef __DISABLE_SYMBOLICATION_ +#import "CUIdSYMBundlesManager.h" + +#import "CUISymbolicationManager.h" + +#import "CUISymbolicationDataFormatter.h" +#endif + +#import "CUICrashLogExceptionInformation+QuickHelp.h" + +@interface CUICrashLog (Private) + + // Sections ranges + + @property (readonly) NSRange headerRange; + + @property (readonly) NSRange exceptionInformationRange; + @property (readonly) NSRange diagnosticMessagesRange; + + @property (readonly) NSRange backtracesRange; + + @property (readonly) NSRange threadStateRange; + + @property (readonly) NSRange binaryImagesRange; + +@end + +@interface CUIDataTransform (Private) + +- (void)setOutput:(NSAttributedString *)inOutput; + +@end + +@implementation CUICrashDataTransform + +- (CUICrashLog *)crashlog +{ + return self.input; +} + +#pragma mark - + +- (BOOL)transform +{ + if ([super transform]==NO) + return NO; + + CUICrashLog * tCrashLog=self.input; + + if ([tCrashLog isKindOfClass:CUIRawCrashLog.class]==NO) + { + // A COMPLETER + + return NO; + } + + [self updatesCachedAttributes]; + + if ([tCrashLog isMemberOfClass:CUIRawCrashLog.class]==YES) + { + NSAttributedString * tAttributedString=[[NSAttributedString alloc] initWithString:tCrashLog.rawText + attributes:self.plainTextAttributes]; + + self.output=tAttributedString; + + return YES; + } + + if ([tCrashLog isMemberOfClass:CUICrashLog.class]==NO) + { + // A COMPLETER + + return NO; + } + + self.processPath=tCrashLog.header.executablePath; + + NSMutableArray * tLines=[NSMutableArray array]; + + [tCrashLog.rawText enumerateLinesUsingBlock:^(NSString * bLine, BOOL * bOutStop) { + + [tLines addObject:bLine]; + }]; + + NSMutableArray * tMutableArray=[tLines mutableCopy]; + + + if (tCrashLog.binaryImagesRange.location!=NSNotFound) + { + if ((self.displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==0) + { + [tMutableArray removeObjectsInRange:tCrashLog.binaryImagesRange]; + } + else + { + NSArray * tBacktracesLines=[tLines subarrayWithRange:tCrashLog.binaryImagesRange]; + + NSArray * tFilteredLines=[self processedBinaryImagesSectionLines:tBacktracesLines reportVersion:tCrashLog.reportVersion error:NULL]; + + [tMutableArray removeObjectsInRange:tCrashLog.binaryImagesRange]; + + [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tCrashLog.binaryImagesRange.location,tFilteredLines.count)]]; + } + } + + if (tCrashLog.threadStateRange.location!=NSNotFound) + { + if ((self.displaySettings.visibleSections & CUIDocumentThreadStateSection)==0) + { + [tMutableArray removeObjectsInRange:tCrashLog.threadStateRange]; + } + else + { + NSArray * tThreadStateLines=[tLines subarrayWithRange:tCrashLog.threadStateRange]; + + NSArray * tFilteredLines=[self processedThreadStateSectionLines:tThreadStateLines error:NULL]; + + [tMutableArray removeObjectsInRange:tCrashLog.threadStateRange]; + + [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tCrashLog.threadStateRange.location,tFilteredLines.count)]]; + } + } + + if (tCrashLog.backtracesRange.location!=NSNotFound) + { + if ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==0) + { + [tMutableArray removeObjectsInRange:tCrashLog.backtracesRange]; + } + else + { + NSArray * tBacktracesLines=[tLines subarrayWithRange:tCrashLog.backtracesRange]; + + NSArray * tFilteredLines=[self processedBacktracesSectionLines:tBacktracesLines error:NULL]; + + [tMutableArray removeObjectsInRange:tCrashLog.backtracesRange]; + + [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tCrashLog.backtracesRange.location,tFilteredLines.count)]]; + } + } + + + if (tCrashLog.diagnosticMessagesRange.location!=NSNotFound) + { + if ((self.displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)==0) + { + [tMutableArray removeObjectsInRange:tCrashLog.diagnosticMessagesRange]; + } + else + { + NSArray * tDiagnosticMessagesLines=[tLines subarrayWithRange:tCrashLog.diagnosticMessagesRange]; + + NSArray * tFilteredLines=[self processedDiagnosticMessagesSectionLines:tDiagnosticMessagesLines error:NULL]; + + [tMutableArray removeObjectsInRange:tCrashLog.diagnosticMessagesRange]; + + [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tCrashLog.diagnosticMessagesRange.location,tFilteredLines.count)]]; + } + } + + + if (tCrashLog.exceptionInformationRange.location!=NSNotFound) + { + if ((self.displaySettings.visibleSections & CUIDocumentExceptionInformationSection)==0) + { + [tMutableArray removeObjectsInRange:tCrashLog.exceptionInformationRange]; + } + else + { + NSArray * tExceptionInformationLines=[tLines subarrayWithRange:tCrashLog.exceptionInformationRange]; + + NSArray * tFilteredLines=[self processedExceptionInformationSectionLines:tExceptionInformationLines error:NULL]; + + [tMutableArray removeObjectsInRange:tCrashLog.exceptionInformationRange]; + + [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tCrashLog.exceptionInformationRange.location,tFilteredLines.count)]]; + } + } + + + if (tCrashLog.isHeaderAvailable==YES) + { + if ((self.displaySettings.visibleSections & CUIDocumentHeaderSection)==0) + { + [tMutableArray removeObjectsInRange:tCrashLog.headerRange]; + } + else + { + NSArray * HeaderLines=[tLines subarrayWithRange:tCrashLog.headerRange]; + + NSArray * tFilteredLines=[self processedHeaderSectionLines:HeaderLines error:NULL]; + + [tMutableArray removeObjectsInRange:tCrashLog.headerRange]; + + [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tCrashLog.headerRange.location,tFilteredLines.count)]]; + } + } + + self.output=[self joinLines:tMutableArray withString:@"\n"]; + + return YES; +} + +#pragma mark - Header + +- (NSArray *)processedHeaderSectionLines:(NSArray *)inLines error:(NSError **)outError +{ + if (inLines.count==0) + return inLines; + + NSMutableArray * tProcessedLines=[NSMutableArray array]; + + [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + NSUInteger tLineLength=bLine.length; + + // Skip Blank lines + + if (tLineLength==0) + { + [tProcessedLines addObject:bLine]; + return; + } + + // Find Key and Value + + NSScanner * tScanner=[NSScanner scannerWithString:bLine]; + + NSString * tKey; + + if ([tScanner scanUpToString:@":" intoString:&tKey]==NO) + { + [tProcessedLines addObject:bLine]; + + *bOutStop=YES; + return; + } + + NSRange tKeyRange=NSMakeRange(0,tScanner.scanLocation+1); + + tScanner.scanLocation=tScanner.scanLocation+1; + + tScanner.charactersToBeSkipped=nil; + + [tScanner scanCharactersFromSet:self.whitespaceCharacterSet intoString:NULL]; + + NSRange tValueRange=NSMakeRange(tScanner.scanLocation,bLine.length-1-tScanner.scanLocation+1); + + + NSMutableAttributedString * tProcessedLine=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self.plainTextAttributes]; + + if (bLineNumber==0) + { + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Header" + }; + + [tProcessedLine addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,bLine.length)]; + } + + + [tProcessedLine addAttributes:self.keyAttributes range:tKeyRange]; + + + if ([tKey isEqualToString:@"Path"]==YES) + { + [tProcessedLine addAttributes:self.pathAttributes range:tValueRange]; + } + else if ([tKey isEqualToString:@"Version"]==YES || + [tKey isEqualToString:@"OS Version"]==YES) + { + [tProcessedLine addAttributes:self.versionAttributes range:tValueRange]; + } + else if ([tKey isEqualToString:@"Anonymous UUID"]==YES || + [tKey isEqualToString:@"Sleep/Wake UUID"]==YES) + { + [tProcessedLine addAttributes:self.UUIDAttributes range:tValueRange]; + } + + [tProcessedLines addObject:tProcessedLine]; + }]; + + return [tProcessedLines copy]; +} + +#pragma mark - Exception Information + +- (NSArray *)processedExceptionInformationSectionLines:(NSArray *)inLines error:(NSError **)outError +{ + if (inLines.count==0) + return inLines; + + NSMutableArray * tProcessedLines=[NSMutableArray array]; + + [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + NSUInteger tLineLength=bLine.length; + + // Skip Blank lines + + if (tLineLength==0) + { + [tProcessedLines addObject:bLine]; + return; + } + + // Find Key and Value + + NSScanner * tScanner=[NSScanner scannerWithString:bLine]; + + NSString * tKey; + + if ([tScanner scanUpToString:@":" intoString:&tKey]==NO || + tScanner.scanLocation==tLineLength) + { + [tProcessedLines addObject:bLine]; + + return; + } + + NSRange tKeyRange=NSMakeRange(0,tScanner.scanLocation+1); + + + tScanner.scanLocation=tScanner.scanLocation+1; + + tScanner.charactersToBeSkipped=nil; + + [tScanner scanCharactersFromSet:self.whitespaceCharacterSet intoString:NULL]; + + + + + + NSRange tValueRange=NSMakeRange(tScanner.scanLocation,bLine.length-1-tScanner.scanLocation+1); + + + + NSMutableAttributedString * tProcessedLine=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self.plainTextAttributes]; + + [tProcessedLine addAttributes:self.keyAttributes range:tKeyRange]; + + if (bLineNumber==0) + { + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Exception Information" + }; + + [tProcessedLine addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,bLine.length)]; + } + + if ([tKey isEqualToString:@"Exception Type"]==YES) + { + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + [tProcessedLine addAttributes:@{ + NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle|NSUnderlineStylePatternDash) + } + + range:tValueRange]; + + [tProcessedLine addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"a://exception_type"] + } + range:tValueRange]; + + break; + + default: + + break; + } + } + + if ([tKey isEqualToString:@"Termination Reason"]==YES) + { + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + if (self.crashlog.exceptionInformation.isQuickHelpAvailableForTerminationReason==YES) + { + [tProcessedLine addAttributes:@{ + NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle|NSUnderlineStylePatternDash) + } + + range:tValueRange]; + + [tProcessedLine addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"a://termination_reason"] + } + range:tValueRange]; + } + + break; + + default: + + break; + } + } + + if ([tKey isEqualToString:@"Crashed Thread"]==YES) + { + if ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==CUIDocumentBacktracesSection && + ((CUICrashLog *)self.input).backtraces.threads.count>0) + { + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + [tProcessedLine addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"a://crashed_thread"] + } + range:tKeyRange]; + + break; + + case CUIHyperlinksHTML: + + [tProcessedLine addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"sharp://crashed_thread"] + } + range:tKeyRange]; + + break; + + default: + + break; + } + } + + [tProcessedLine addAttributes:self.crashedThreadLabelAttributes range:tValueRange]; + } + + [tProcessedLines addObject:tProcessedLine]; + }]; + + + return tProcessedLines; +} + +#pragma mark - Diagnostic Messages + +- (NSArray *)processedDiagnosticMessagesSectionLines:(NSArray *)inLines error:(NSError **)outError +{ + if (inLines.count==0) + return inLines; + + NSMutableArray * tProcessedLines=[NSMutableArray array]; + + // First line + + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Diagnostic Messages" + }; + + NSMutableAttributedString * tAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:tJumpAnchorAttributes]; + + NSDictionary * tFirstLineAttributes=self.keyAttributes; + + [tAttributedString addAttributes:tFirstLineAttributes range:NSMakeRange(0,tAttributedString.length)]; + + [tProcessedLines addObject:tAttributedString]; + + // Other Lines + + NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); + + [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] + options:0 + usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + id tObject=bLine; + + NSUInteger tLineLength=bLine.length; + + if (tLineLength==0) + { + [tProcessedLines addObject:bLine]; + + return; + } + + if ([bLine characterAtIndex:tLineLength-1]==':') + { + if ([bLine isEqualToString:@"Application Specific Information:"]==YES || + [bLine isEqualToString:@"Dyld Error Message:"]==YES || + [bLine isEqualToString:@"Application Specific Signatures:"]==YES || + [bLine isEqualToString:@"CreationBacktrace:"]==YES || + [bLine isEqualToString:@" Ordered grouping begin/end backtraces:"]==YES) + { + NSAttributedString * tLineAttributedString=[[NSAttributedString alloc] initWithString:bLine attributes:self.keyAttributes]; + + tObject=tLineAttributedString; + } + } + + [tProcessedLines addObject:tObject]; + + }]; + + return tProcessedLines; +} + +#pragma mark - Backtraces + +- (NSArray *)processedBacktracesSectionLines:(NSArray *)inLines error:(NSError **)outError +{ + if (inLines.count==0) + return inLines; + + NSMutableArray * tProcessedLines=[NSMutableArray array]; + + __block NSInteger tThreadEntityLineStart=0; + __block NSInteger tThreadEntityLineEnd=0; + + [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL *bOutStop) { + + // Retrieve thread number, crashed status and dispatch queue name + + if (bLine.length!=0) + return; + + tThreadEntityLineEnd=bLineNumber; // Keep the blank line + + NSRange tThreadRange=NSMakeRange(tThreadEntityLineStart, tThreadEntityLineEnd-tThreadEntityLineStart+1); + + NSError * tError; + + NSArray * tFilteredThreadLines=[self processedThreadBacktraceLines:[inLines subarrayWithRange:tThreadRange] error:&tError]; + + [tProcessedLines addObjectsFromArray:tFilteredThreadLines]; + + tThreadEntityLineStart=bLineNumber+1; + }]; + + NSMutableAttributedString * tMutableAttributedString=tProcessedLines.firstObject; + + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Backtraces" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes + range:NSMakeRange(0, tMutableAttributedString.length)]; + + return tProcessedLines; +} + +- (NSArray *)processedThreadBacktraceLines:(NSArray *)inLines error:(NSError **)outError +{ + if (inLines.count==0) + return inLines; + + NSString * tHeaderLine=inLines.firstObject; + BOOL tCrashedThread=NO; + NSString * tName=nil; + + if ([tHeaderLine isEqualToString:@"Backtrace not available"]==YES) + { + NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:tHeaderLine attributes:self.plainTextAttributes]; + + NSMutableArray * tProcessedLines=[NSMutableArray arrayWithObject:tMutableAttributedString]; + + NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); + + [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] + options:0 + usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + [tProcessedLines addObject:bLine]; + }]; + + return [tProcessedLines copy]; + } + + CUICrashLogBacktraces * tBacktraces=((CUICrashLog *)self.input).backtraces; + + CUIThread * tThread=nil; + + if ([tHeaderLine hasPrefix:@"Application Specific Backtrace"]==YES) + { + tName=@"Application Specific Backtrace"; + + tThread=[tBacktraces threadNamed:tName]; + } + else + { + NSArray * tComponents=[tHeaderLine componentsSeparatedByString:@"::"]; + NSString * tLeftPart; + + if (tComponents.count==0) + { + // Uh oh + + // A COMPLETER + } + + tLeftPart=tComponents.firstObject; + + if (tComponents.count!=2) + tLeftPart=[tLeftPart stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@":"]]; + + NSArray * tThreadNumberComponents=[tLeftPart componentsSeparatedByString:@" "]; + + if (tThreadNumberComponents.count<2) + { + // Uh oh + + if (outError!=NULL) + *outError=[NSError errorWithDomain:CUIDataTransformErrorDomain code:CUIDataTransformUnknownError userInfo:@{}]; + + return nil; + } + + tName=tThreadNumberComponents[1]; // <- it's actually the number + + if (tThreadNumberComponents.count==3) + { + if ([tThreadNumberComponents[2] caseInsensitiveCompare:@"Crashed"]==NSOrderedSame) + tCrashedThread=YES; + } + + if ((self.displaySettings.visibleSections & CUIDocumentBacktraceCrashedThreadSubSection)!=0) + { + if (tCrashedThread==NO) + return @[]; + } + + tThread=[tBacktraces threadWithNumber:[tName integerValue]]; + } + + + NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:self.plainTextAttributes]; + + NSRange tStringRange=NSMakeRange(0, tMutableAttributedString.length); + + [tMutableAttributedString addAttributes:@{ + CUIThreadAnchorAttributeName:[NSString stringWithFormat:@"thread:%@",tName] + } + range:tStringRange]; + + + + + if (tCrashedThread==YES) + { + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + [tMutableAttributedString addAttributes:@{ + CUIGenericAnchorAttributeName:@"a:crashed_thread" + } + range:tStringRange]; + + break; + + case CUIHyperlinksHTML: + { + NSURL * tURL=[NSURL URLWithString:@"anchor://crashed_thread"]; + + if (tURL!=nil) + [tMutableAttributedString addAttributes:@{NSLinkAttributeName:tURL} + range:tStringRange]; + + break; + } + default: + + break; + } + } + + NSDictionary * tAttributes=(tCrashedThread==YES) ? self.crashedThreadLabelAttributes : self.threadLabelAttributes; + + [tMutableAttributedString addAttributes:tAttributes + range:tStringRange]; + + NSMutableArray * tProcessedLines=[NSMutableArray arrayWithObject:tMutableAttributedString]; + + NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); + + __block NSUInteger tStackFrameIndex=0; + + [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] + options:0 + usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + if (bLine.length==0) + { + [tProcessedLines addObject:bLine]; + return; + } + + NSString * tProcessedStackFrameLine=[self processedStackFrameLine:bLine stackFrame:tThread.callStackBacktrace.stackFrames[tStackFrameIndex]]; + + if (tProcessedStackFrameLine!=nil) + { + [tProcessedLines addObject:tProcessedStackFrameLine]; + } + else + { + NSLog(@"Error transforming line: %@",bLine); + + [tProcessedLines addObject:bLine]; + } + + tStackFrameIndex+=1; + + }]; + + return tProcessedLines; +} + +#pragma mark - Thread State + +- (NSArray *)processedThreadStateSectionLines:(NSArray *)inLines error:(NSError **)outError +{ + if (inLines.count==0) + return inLines; + + NSMutableArray * tProcessedLines=[NSMutableArray array]; + + // First line + + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Thread State" + }; + + NSMutableAttributedString * tAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:tJumpAnchorAttributes]; + + NSDictionary * tFirstLineAttributes=self.keyAttributes; + + [tAttributedString addAttributes:tFirstLineAttributes range:NSMakeRange(0,tAttributedString.length)]; + + + [tProcessedLines addObject:tAttributedString]; + + // Other Lines + + NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); + + __block NSUInteger tLastLine=0; + + + + [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] + options:0 + usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self.keyAttributes]; + + if (bLine.length<4) + { + tLastLine=bLineNumber+1; + + [tProcessedLines addObject:tMutableAttributedString]; + + *bOutStop=YES; + return; + } + + NSScanner * tRegistersScanner=[NSScanner scannerWithString:bLine]; + + tRegistersScanner.charactersToBeSkipped=self.whitespaceCharacterSet; + + while (tRegistersScanner.isAtEnd==NO) + { + tRegistersScanner.charactersToBeSkipped=nil; + + [tRegistersScanner scanCharactersFromSet:self.whitespaceCharacterSet intoString:nil]; + + NSString * tRegisterName; + + tRegistersScanner.charactersToBeSkipped=self.whitespaceCharacterSet; + + if ([tRegistersScanner scanUpToString:@":" intoString:&tRegisterName]==NO) + return; + + if ([tRegistersScanner scanString:@": " intoString:NULL]==NO) + return; + + NSRange tValueRange=NSMakeRange(tRegistersScanner.scanLocation, 0); + + if ([tRegistersScanner scanHexLongLong:NULL]==NO) + return; + + tValueRange.length=tRegistersScanner.scanLocation-1-tValueRange.location+1; + + tRegistersScanner.charactersToBeSkipped=nil; + + [tRegistersScanner scanCharactersFromSet:self.whitespaceCharacterSet intoString:nil]; + + [tMutableAttributedString addAttributes:self.registerValueAttributes range:tValueRange]; + } + + [tProcessedLines addObject:tMutableAttributedString]; + + }]; + + // Remaining lines + + [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tLastLine,inLines.count-1-tLastLine+1)] options:0 usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + NSUInteger tLineLength=bLine.length; + + // Skip Blank lines + + if (tLineLength==0) + { + [tProcessedLines addObject:[[NSAttributedString alloc] initWithString:bLine attributes:self.plainTextAttributes]]; + return; + } + + // Find Key and Value + + NSScanner * tScanner=[NSScanner scannerWithString:bLine]; + + NSString * tKey; + + if ([tScanner scanUpToString:@":" intoString:&tKey]==NO) + { + // A COMPLETER + + [tProcessedLines addObject:[[NSAttributedString alloc] initWithString:bLine attributes:self.plainTextAttributes]]; + + return; + } + + NSRange tKeyRange=NSMakeRange(0,tScanner.scanLocation+1); + + + NSMutableAttributedString * tMutableAttributedString=nil; + + if (tScanner.scanLocation1) + { + // User Code + + tIsUserCode=YES; + } + + NSMutableAttributedString * tNewLine=[[NSMutableAttributedString alloc] initWithString:inLine attributes:self.plainTextAttributes]; + + tScanner.scanLocation=tIdentifierStart+tIdentifierRealLength; + + NSRange tIdentifierRange=NSMakeRange(tIdentifierStart, tIdentifierRealLength); + + if (inReportVersion==6) + { + tScanner.scanLocation+=1; + } + else + { + if (tIsMissingVersion==NO) + { + if ([tScanner scanUpToString:@"(" intoString:NULL]==NO) + return nil; + } + else + { + if ([tScanner scanUpToString:@"<" intoString:NULL]==NO) + return nil; + } + } + + // Version + + NSUInteger tVersionStart=NSNotFound; + NSUInteger tVersionEnd=NSNotFound; + + if (tIsMissingVersion==NO) + { + tVersionStart=tScanner.scanLocation; + + if ([tScanner scanUpToString:@")" intoString:NULL]==NO) + return nil; + + tVersionEnd=tScanner.scanLocation; + } + + // UUID can be missing // A COMPLETER + + if (tIsMissingVersion==NO) + { + tScanner.scanLocation+=2; + } + + NSUInteger tUUIDStart=NSNotFound; + NSUInteger tUUIDEnd=NSNotFound; + + if ([inLine characterAtIndex:tScanner.scanLocation]=='<') + { + tUUIDStart=tScanner.scanLocation; + + if ([tScanner scanUpToString:@">" intoString:NULL]==NO) + return nil; + + tUUIDEnd=tScanner.scanLocation; + } + else + { + tScanner.scanLocation-=2; + } + + if ([tScanner scanUpToString:@"/" intoString:NULL]==NO) + return nil; + + if (tUUIDEnd!=NSNotFound) + { + NSString * tBinaryImageUUID=[inLine substringWithRange:NSMakeRange(tUUIDStart+1, tUUIDEnd-tUUIDStart-1)]; + + switch(self.hyperlinksStyle) + { + case CUIHyperlinksHTML: + { + NSURL * tURL=[NSURL URLWithString:[NSString stringWithFormat:@"anchor://%@",tBinaryImageUUID]]; + + if (tURL!=nil) + [tNewLine addAttributes:@{NSLinkAttributeName:tURL} + range:NSMakeRange(0, tNewLine.length)]; + + break; + } + + default: + + [tNewLine addAttributes:@{ + CUIBinaryAnchorAttributeName:[NSString stringWithFormat:@"bin:%@",tBinaryImageUUID] + } + range:NSMakeRange(0, tNewLine.length)]; + + break; + } + } + + NSRange tPathRange=NSMakeRange(tScanner.scanLocation,inLine.length-1-tScanner.scanLocation+1); + + NSDictionary * tIdentifierAttributes=self.plainTextAttributes; + + if (self.themesProvider.currentTheme.isMonochrome==NO) + { + tIdentifierAttributes=@{ + NSForegroundColorAttributeName:(tIsUserCode==YES) ? [CUIBinaryImageUtility colorForUserCode]: [CUIBinaryImageUtility colorForIdentifier:tIdentifier] + }; + } + + [tNewLine addAttributes:tIdentifierAttributes + range:tIdentifierRange]; + + [tNewLine addAttributes:self.memoryAddressAttributes + range:NSMakeRange(tMinAddressStart, tMinAddressEnd-tMinAddressStart+1)]; + + [tNewLine addAttributes:self.memoryAddressAttributes + range:NSMakeRange(tMaxAddressStart, tMaxAddressEnd-tMaxAddressStart+1)]; + + if (tUUIDStart!=NSNotFound) + { + [tNewLine addAttributes:self.UUIDAttributes + range:NSMakeRange(tUUIDStart,tUUIDEnd-tUUIDStart+1)]; + } + + if (tVersionEnd!=NSNotFound && tVersionStart!=NSNotFound) + { + [tNewLine addAttributes:self.versionAttributes + range:NSMakeRange(tVersionStart,tVersionEnd-tVersionStart+1)]; + } + + [tNewLine addAttributes:self.pathAttributes + range:tPathRange]; + + return tNewLine; +} + +#pragma mark - + +- (NSAttributedString *)joinLines:(NSArray *)inLines withString:(NSString *)inNewLineFeed +{ + NSMutableAttributedString * tMutableAttributedString=[NSMutableAttributedString new]; + + [inLines enumerateObjectsUsingBlock:^(id bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + if ([bLine isKindOfClass:NSString.class]==YES) + { + NSAttributedString * tAttributedString=[[NSAttributedString alloc] initWithString:bLine + attributes:self.plainTextAttributes]; + + [tMutableAttributedString appendAttributedString:tAttributedString]; + + if (bLineNumber * threads; - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError; + - (CUIThread *)threadNamed:(NSString *)inName; - (CUIThread *)threadWithNumber:(NSUInteger)inThreadNumber; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogBacktraces.m b/app_unexpectedly/app_unexpectedly/CUICrashLogBacktraces.m index 44730cc..c9966f6 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogBacktraces.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogBacktraces.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,26 +15,24 @@ #import "CUIParsingErrors.h" +#import "NSArray+WBExtensions.h" + @interface CUICrashLogBacktraces () { NSMutableArray * _threads; } -@property BOOL hasApplicationSpecificBacktrace; - -@property NSUInteger relativeCrashedThreadLine; +@property (readwrite) BOOL hasApplicationSpecificBacktrace; -- (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError; +- (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError; @end @implementation CUICrashLogBacktraces - - - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -46,8 +44,6 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( if (self!=nil) { - _relativeCrashedThreadLine=NSNotFound; - _threads=[NSMutableArray array]; if ([self parseTextualRepresentation:inLines outError:outError]==NO) @@ -59,6 +55,121 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( return self; } +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError +{ + if ([inIncident isKindOfClass:IPSIncident.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + NSMutableArray * tApplicationBacktracesThreads=[NSMutableArray array]; + + _hasApplicationSpecificBacktrace=NO; + + IPSIncidentExceptionInformation * tExceptionInformation=inIncident.exceptionInformation; + + if (tExceptionInformation!=nil) + { + NSArray * tLastExceptionBacktrace=tExceptionInformation.lastExceptionBacktrace; + + if (tLastExceptionBacktrace.count>0) + { + NSError * tError; + + CUIThread * tThread=[[CUIThread alloc] initApplicationSpecificBacktraceWithThreadFrames:tLastExceptionBacktrace binaryImages:inIncident.binaryImages error:&tError]; + + if (tThread==nil) + { + return nil; + } + + [tApplicationBacktracesThreads addObject:tThread]; + + _hasApplicationSpecificBacktrace=YES; + } + } + + if (_hasApplicationSpecificBacktrace==NO) + { + IPSIncidentDiagnosticMessage * tDiagnosticMessage=inIncident.diagnosticMessage; + + if (tDiagnosticMessage!=nil) + { + IPSApplicationSpecificInformation * tApplicationSpecificInformation=tDiagnosticMessage.asi; + + if (tApplicationSpecificInformation.backtraces.count>0) + { + NSArray * tApplicationSpecificBacktraces=tApplicationSpecificInformation.backtraces; + + [tApplicationSpecificBacktraces enumerateObjectsUsingBlock:^(NSString * bString, NSUInteger bIndex, BOOL * bOutStop) { + + NSMutableArray * tLines=[NSMutableArray arrayWithObject:@"Application Specific Backtrace 1"]; + + [bString enumerateLinesUsingBlock:^(NSString * bLine, BOOL * bOutStop) { + + [tLines addObject:bLine]; + }]; + + NSError * tError; + + CUIThread * tThread=[[CUIThread alloc] initApplicationSpecificBacktraceWithTextualRepresentation:tLines error:&tError]; + + if (tThread==nil) + { + *bOutStop=YES; + + return; + } + + [tApplicationBacktracesThreads addObject:tThread]; + + }]; + + // A COMPLETER + + _hasApplicationSpecificBacktrace=YES; + } + } + } + + + NSArray * tThreads=inIncident.threads; + + if (tThreads==nil) + { + // A COMPLETER + + return nil; + } + + _threads=[[tThreads WB_arrayByMappingObjectsUsingBlock:^CUIThread *(IPSThread * bThread, NSUInteger bIndex) { + + CUIThread * tThread=[[CUIThread alloc] initWithIPSThread:bThread atIndex:bIndex binaryImages:inIncident.binaryImages error:NULL]; + + if (tThread==nil) + { + // A COMPLETER + } + + return tThread; + }] mutableCopy]; + + if (tApplicationBacktracesThreads.count>0) + { + [_threads insertObjects:tApplicationBacktracesThreads atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,tApplicationBacktracesThreads.count)]]; + } + } + + return self; +} + #pragma mark - - (CUIThread *)threadNamed:(NSString *)inName @@ -88,46 +199,43 @@ - (CUIThread *)threadWithNumber:(NSUInteger)inThreadNumber #pragma mark - -- (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError +- (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError { if ([inLines.firstObject isEqualToString:@"Backtrace not available"]==YES) return YES; __block NSError * tError=nil; - __block NSInteger tThreadEntityLineStart=0; - __block NSInteger tThreadEntityLineEnd=0; + // Probably not as fast as block enumeration but the code is easier to follow. + NSUInteger tLinesCount=inLines.count; + NSUInteger tIndex=0; - [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL *bOutStop) { - - // Retrieve thread number, crashed status and dispatch queue name + while (tIndex_threads addObject:tThread]; - - - tThreadEntityLineStart=bLineNumber+1; - }]; + while (tIndex * binaryImages; + @property (readonly) NSArray * binaryImages; @property (nonatomic,readonly) NSArray * allUUIDs; @@ -25,6 +27,8 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError; + - (CUIBinaryImage *)binaryImageWithIdentifier:(NSString *)inIdentifier; - (CUIBinaryImage *)binaryImageForMemoryAddress:(NSUInteger)inMemoryAddress; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogBinaryImages.m b/app_unexpectedly/app_unexpectedly/CUICrashLogBinaryImages.m index 38c771c..e6921b8 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogBinaryImages.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogBinaryImages.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -19,8 +19,6 @@ @interface CUICrashLogBinaryImages () { - NSMutableArray * _binaryImages; - NSMutableDictionary * _binaryImagesRegistry; NSMutableDictionary * _binaryNamesRegistry; @@ -28,6 +26,8 @@ @interface CUICrashLogBinaryImages () NSMutableDictionary * _binaryNameToIdentifierRosettaStone; } +@property (readwrite) NSArray * binaryImages; + - (BOOL)parseTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion outError:(NSError **)outError; @end @@ -37,7 +37,7 @@ @implementation CUICrashLogBinaryImages - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -49,7 +49,7 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( if (self!=nil) { - _binaryImages=[NSMutableArray array]; + _binaryImages=[NSArray array]; _binaryImagesRegistry=[NSMutableDictionary dictionary]; @@ -66,6 +66,62 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( return self; } +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError +{ + if ([inIncident isKindOfClass:IPSIncident.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + NSMutableDictionary * tBinaryImagesRegistry=[NSMutableDictionary dictionary]; + + NSMutableDictionary * tBinaryNamesRegistry=[NSMutableDictionary dictionary]; + + NSMutableDictionary * tBinaryNameToIdentifierRosettaStone=[NSMutableDictionary dictionary]; + + _binaryImages=(NSArray *)[inIncident.binaryImages WB_arrayByMappingObjectsLenientlyUsingBlock:^CUIBinaryImage *(IPSImage * bImage, NSUInteger bIndex) { + + if ([bImage.source isEqualToString:@"A"]==YES) + return nil; + + CUIBinaryImage * tBinaryImage=[[CUIBinaryImage alloc] initWithImage:bImage error:NULL]; + + if (tBinaryImage==nil) + { + // A COMPLETER + } + else + { + tBinaryImagesRegistry[tBinaryImage.identifier]=tBinaryImage; + + NSString * tBinartName=tBinaryImage.path.lastPathComponent; + + tBinaryNamesRegistry[tBinartName]=tBinaryImage; + + tBinaryNameToIdentifierRosettaStone[tBinartName]=tBinaryImage.identifier; + } + + return tBinaryImage; + + }]; + + _binaryImagesRegistry=tBinaryImagesRegistry; + + _binaryNamesRegistry=tBinaryNamesRegistry; + + _binaryNameToIdentifierRosettaStone=tBinaryNameToIdentifierRosettaStone; + } + + return self; +} + #pragma mark - - (BOOL)parseTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion outError:(NSError **)outError @@ -77,6 +133,8 @@ - (BOOL)parseTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger) NSArray * tImagesLines=[inLines subarrayWithRange:NSMakeRange(1, inLines.count-1)]; + NSMutableArray * tBinaryImages=[NSMutableArray array]; + [tImagesLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL *bOutStop) { NSUInteger tLineLength=bLine.length; @@ -99,10 +157,7 @@ - (BOOL)parseTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger) return; } - if (bLineNumber==0) - tBinaryImage.mainImage=YES; - - [self->_binaryImages addObject:tBinaryImage]; + [tBinaryImages addObject:tBinaryImage]; self->_binaryImagesRegistry[tBinaryImage.identifier]=tBinaryImage; @@ -114,6 +169,8 @@ - (BOOL)parseTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger) }]; + _binaryImages=[tBinaryImages copy]; + if (outError!=NULL && tError!=nil) *outError=tError; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogContentsViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogContentsViewController.m index 3905ed8..63fef07 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogContentsViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogContentsViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -27,7 +27,7 @@ NSString * const CUICrashLogContentsViewPresentationModeDidChangeNotification=@"CUICrashLogContentsViewPresentationModeDidChangeNotification"; -@interface CUICrashLogContentsViewController () +@interface CUICrashLogContentsViewController () { CUICrashLogPresentationTextViewController * _textViewController; @@ -90,7 +90,7 @@ - (void)viewDidLoad // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(huntDidFinish:) name:CUIdSYMHunterHuntDidFinishNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(huntDidFinish:) name:CUIdSYMHunterHuntDidFinishNotification object:nil]; } #pragma mark - @@ -146,7 +146,7 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tAction==@selector(CUI_MENUACTION_switchPresentationMode:)) { - inMenuItem.state=(inMenuItem.tag==self.presentationMode) ? NSOnState : NSOffState; + inMenuItem.state=(inMenuItem.tag==self.presentationMode) ? NSControlStateValueOn : NSControlStateValueOff; return YES; } @@ -195,7 +195,7 @@ - (IBAction)CUI_MENUACTION_switchPresentationMode:(id)sender { NSSegmentedControl * tSegmentedControl=(NSSegmentedControl *)sender; - tPresentationMode=tSegmentedControl.selectedSegment; + tPresentationMode=[tSegmentedControl tagForSegment:tSegmentedControl.selectedSegment]; } else { @@ -358,7 +358,7 @@ - (void)setPresentationMode:(CUIPresentationMode)inPresentationMode transferCras // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogContentsViewPresentationModeDidChangeNotification object:self userInfo:@{@"mode":@(_presentationMode)}]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogContentsViewPresentationModeDidChangeNotification object:self userInfo:@{@"mode":@(_presentationMode)}]; // Save presentation mode in defaults @@ -379,35 +379,36 @@ - (IBAction)showHideBottomView:(id)sender #pragma mark - CUIFileDeadDropViewDelegate -- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView validateDropFiles:(NSArray *)inFilenames +- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView validateDropFileURLs:(NSArray *)inURLArray { - if (inFilenames==nil) + if (inURLArray==nil) return NO; - NSFileManager * tFileManager=[NSFileManager defaultManager]; + if ([self.crashLog isMemberOfClass:[CUICrashLog class]]==NO) + return NO; CUIdSYMBundlesManager * tBundlesManager=[CUIdSYMBundlesManager sharedManager]; NSArray * tAllUUIDs=self.crashLog.binaryImages.allUUIDs; - NSArray * tFilteredArray=[inFilenames WB_filteredArrayUsingBlock:^BOOL(NSString * bPath, NSUInteger bIndex) { + NSArray * tFilteredArray=[inURLArray WB_filteredArrayUsingBlock:^BOOL(NSURL * bURL, NSUInteger bIndex) { - BOOL tIsDirectory; + NSNumber *tIsDirectoryNumber; - if ([tFileManager fileExistsAtPath:bPath isDirectory:&tIsDirectory]==NO) + if ([bURL getResourceValue:&tIsDirectoryNumber forKey:NSURLIsDirectoryKey error:NULL]==NO) return NO; - if (tIsDirectory==NO) + if (tIsDirectoryNumber.boolValue==NO) return NO; // Should have .crash extension - if ([bPath.pathExtension caseInsensitiveCompare:@"dSYM"]!=NSOrderedSame) + if ([bURL.pathExtension caseInsensitiveCompare:@"dSYM"]!=NSOrderedSame) return NO; // Check that these are dSYM bundles and that the UUIDs are not already listed - CUIdSYMBundle * tBundle=[[CUIdSYMBundle alloc] initWithPath:bPath]; + CUIdSYMBundle * tBundle=[[CUIdSYMBundle alloc] initWithURL:bURL]; if (tBundle.isDSYMBundle==NO) return NO; @@ -415,9 +416,7 @@ - (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView validateDropFiles:(NSArra if ([tBundlesManager containsBundle:tBundle]==YES) return NO; - // Check that one the UUIDs is the one of a binary of the crash log - - + // Check that one of the UUIDs is the one of a binary of the crash log NSUInteger tIndex=[tBundle.binaryUUIDs indexOfObjectPassingTest:^BOOL(NSString * bUUID, NSUInteger bIndex, BOOL * bOutStop) { @@ -431,35 +430,33 @@ - (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView validateDropFiles:(NSArra return (tFilteredArray.count>0); } -- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView acceptDropFiles:(NSArray *)inFilenames +- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView acceptDropFileURLs:(NSArray *)inURLArray { - if (inFilenames==nil) + if (inURLArray==nil) return NO; - NSFileManager * tFileManager=[NSFileManager defaultManager]; - CUIdSYMBundlesManager * tBundlesManager=[CUIdSYMBundlesManager sharedManager]; NSArray * tAllUUIDs=self.crashLog.binaryImages.allUUIDs; - NSArray * tMappedArray=[inFilenames WB_arrayByMappingObjectsLenientlyUsingBlock:^CUIdSYMBundle *(NSString * bPath, NSUInteger bIndex) { + NSArray * tMappedArray=[inURLArray WB_arrayByMappingObjectsLenientlyUsingBlock:^CUIdSYMBundle *(NSURL * bURL, NSUInteger bIndex) { - BOOL tIsDirectory; + NSNumber *tIsDirectoryNumber; - if ([tFileManager fileExistsAtPath:bPath isDirectory:&tIsDirectory]==NO) + if ([bURL getResourceValue:&tIsDirectoryNumber forKey:NSURLIsDirectoryKey error:NULL]==NO) return nil; - if (tIsDirectory==NO) + if (tIsDirectoryNumber.boolValue==NO) return nil; // Should have .crash extension - if ([bPath.pathExtension caseInsensitiveCompare:@"dSYM"]!=NSOrderedSame) + if ([bURL.pathExtension caseInsensitiveCompare:@"dSYM"]!=NSOrderedSame) return nil; // Check that these are dSYM bundles and that the UUIDs are not already listed - CUIdSYMBundle * tBundle=[[CUIdSYMBundle alloc] initWithPath:bPath]; + CUIdSYMBundle * tBundle=[[CUIdSYMBundle alloc] initWithURL:bURL]; if (tBundle.isDSYMBundle==NO) return nil; @@ -469,8 +466,6 @@ - (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView acceptDropFiles:(NSArray // Check that one the UUIDs is the one of a binary of the crash log - - NSUInteger tIndex=[tBundle.binaryUUIDs indexOfObjectPassingTest:^BOOL(NSString * bUUID, NSUInteger bIndex, BOOL * bOutStop) { return [tAllUUIDs containsObject:bUUID]; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.h b/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.h index 42634ba..d768c60 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.h @@ -13,10 +13,14 @@ #import +#import "IPSIncident.h" + @interface CUICrashLogDianosticMessages : NSObject @property (readonly,copy) NSString * messages; - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.m b/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.m index 5969d2b..d9de8e3 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogDianosticMessages.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,6 +13,8 @@ #import "CUICrashLogDianosticMessages.h" +#import "IPSIncident+ApplicationSpecificInformation.h" + #import "CUIParsingErrors.h" @interface CUICrashLogDianosticMessages () @@ -25,7 +27,7 @@ @implementation CUICrashLogDianosticMessages - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -45,6 +47,67 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( return self; } +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError +{ + if ([inIncident isKindOfClass:IPSIncident.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + IPSIncidentDiagnosticMessage * tDiagnosticMessage=inIncident.diagnosticMessage; + + if (tDiagnosticMessage!=nil) + { + NSMutableString * tMessages=[NSMutableString string]; + + // VM Region Info + + if (tDiagnosticMessage.vmregioninfo!=nil) + { + [tMessages appendFormat:@"VM Region Info: %@\n",tDiagnosticMessage.vmregioninfo]; + + [tMessages appendString:@"\n"]; + } + + // Application Specific Information + + NSArray * tApplicationSpecificInformationMessage = [inIncident applicationSpecificInformationMessage]; + + if (tApplicationSpecificInformationMessage.count>0) + { + [tMessages appendString:@"Application Specific Information:\n"]; + + [tMessages appendString:[tApplicationSpecificInformationMessage componentsJoinedByString:@"\n"]]; + + [tMessages appendString:@"\n"]; + } + + // Application Specific Signatures + + NSArray * tSignatures = tDiagnosticMessage.asi.signatures; + + if (tSignatures) + { + [tMessages appendString:@"Application Specific Signatures:\n"]; + + for(NSString * tSignature in tSignatures) + [tMessages appendFormat:@"%@\n",tSignature]; + } + + _messages=[tMessages copy]; + } + } + + return self; +} + #pragma mark - - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation+QuickHelp.h b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation+QuickHelp.h new file mode 100644 index 0000000..3203bce --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation+QuickHelp.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUICrashLogExceptionInformation.h" + +@interface CUICrashLogExceptionInformation (QuickHelp) + +@property (nonatomic,readonly,getter=isQuickHelpAvailableForTerminationReason) BOOL quickHelpAvailableForTerminationReason; + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation+QuickHelp.m b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation+QuickHelp.m new file mode 100644 index 0000000..6228290 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation+QuickHelp.m @@ -0,0 +1,133 @@ +/* + Copyright (c) 2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUICrashLogExceptionInformation+QuickHelp.h" + +NSString * const CUITerminationReasonSignalNamespace=@"SIGNAL"; // OS_REASON_SIGNAL +NSString * const CUITerminationReasonCodesigningNamespace=@"CODESIGNING"; // OS_REASON_CODESIGNING +NSString * const CUITerminationReasonDyldNamespace=@"DYLD"; // OS_REASON_DYLD +NSString * const CUITerminationReasonLibXPCNamespace=@"LIBXPC"; // OS_REASON_LIBXPC +NSString * const CUITerminationReasonLibSystemNamespace=@"LIBSYSTEM"; // OS_REASON_LIBSYSTEM +NSString * const CUITerminationReasonWatchdogNamespace=@"WATCHDOG"; // OS_REASON_WATCHDOG +NSString * const CUITerminationReasonEndpointSecurityNamespace=@"ENDPOINTSECURITY"; // OS_REASON_ENDPOINTSECURITY + +typedef NS_ENUM(NSUInteger, CUITerminationReasonEndpointSecurityCode) +{ + CUITerminationReasonEndpointSecurityProcessBlockedByESClient = 1, + CUITerminationReasonEndpointSecurityESClientRequestTimedOut = 2 +}; + +@implementation CUICrashLogExceptionInformation (QuickHelp) + +- (BOOL)isQuickHelpAvailableForTerminationReason +{ + if ([self.terminationNamespace isEqualToString:CUITerminationReasonEndpointSecurityNamespace]==YES) + { + switch(self.terminationCode) + { + case 2: + return YES; + + default: + + break; + } + + return NO; + } + + if ([self.terminationNamespace isEqualToString:CUITerminationReasonLibSystemNamespace]==YES) // libkern/os/reason_private.h + { + switch(self.terminationCode) + { + case 2: // OS_REASON_LIBSYSTEM_CODE_FAULT + return NO; // A COMPLETER + + default: + + break; + } + + return NO; + } + + if ([self.terminationNamespace isEqualToString:CUITerminationReasonWatchdogNamespace]==YES) + { + switch(self.terminationCode) + { + case 1: + return NO; // A COMPLETER + + default: + + break; + } + + return NO; + } + + if ([self.terminationNamespace isEqualToString:CUITerminationReasonCodesigningNamespace]==YES) // bsd/sys/reason.h + { + switch(self.terminationCode) + { + case 1: // CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG + return NO; // A COMPLETER + + case 2: // CODESIGNING_EXIT_REASON_INVALID_PAGE + return NO; // A COMPLETER + + default: + + break; + } + + return NO; + } + + if ([self.terminationNamespace isEqualToString:CUITerminationReasonDyldNamespace]==YES) // dyld/include/mach-o/dyld_priv.h + { + switch(self.terminationCode) + { + case 1: // DYLD_EXIT_REASON_DYLIB_MISSING + return NO; // A COMPLETER + + case 2: // DYLD_EXIT_REASON_DYLIB_WRONG_ARCH + return NO; // A COMPLETER + + default: + + break; + } + + return NO; + } + + if ([self.terminationNamespace isEqualToString:CUITerminationReasonLibXPCNamespace]==YES) // dyld/include/mach-o/dyld_priv.h + { + switch(self.terminationCode) + { + case 4: + return NO; // A COMPLETER + + default: + + break; + } + + return NO; + } + + return NO; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.h b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.h index 78c5760..b4aca4a 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,6 +13,8 @@ #import +#import "IPSIncident.h" + @interface CUICrashLogExceptionInformation : NSObject @property (readonly) NSInteger crashedThreadIndex; // -1 -> Unknown @@ -29,8 +31,14 @@ @property (readonly,copy) NSString * exceptionNote; // Can be nil + @property (readonly,copy) NSString * terminationNamespace; // Can be nil + + @property (readonly) NSUInteger terminationCode; + - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError; + - (NSString *)displayedExceptionType; @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.m b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.m index b47da39..5faca0d 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogExceptionInformation.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,6 +15,8 @@ #import "CUIParsingErrors.h" +#import "NSArray+WBExtensions.h" + @interface CUICrashLogExceptionInformation () @property NSInteger crashedThreadIndex; // -1 -> Unknown @@ -31,6 +33,10 @@ @interface CUICrashLogExceptionInformation () @property (copy) NSString * exceptionNote; + @property (copy) NSString * terminationNamespace; + + @property NSUInteger terminationCode; + + (BOOL)parseString:(NSString *)inString threadIndex:(NSInteger *)outThreadIndex threadName:(NSString **)outThreadName; + (BOOL)parseString:(NSString *)inString exceptionType:(NSString **)outExceptionType signal:(NSString **)outExceptionSignal; @@ -129,11 +135,58 @@ + (BOOL)parseString:(NSString *)inString exceptionCodes:(NSArray **)outException return YES; } ++ (BOOL)parseString:(NSString *)inString terminationReasonNamespace:(NSString **)outNamespace code:(NSUInteger *)outCode +{ + NSScanner * tScanner=[NSScanner scannerWithString:inString]; + + BOOL tSimpleFormat=YES; + + if ([inString hasPrefix:@"Namespace "]==YES) + { + tSimpleFormat=NO; + tScanner.scanLocation+=@"Namespace ".length; + } + + NSString * tNamespace=nil; + + if (tSimpleFormat==YES) + { + if ([tScanner scanUpToString:@", [" intoString:&tNamespace]==NO) + { + return NO; + } + + tScanner.scanLocation+=@", [".length; + } + else + { + if ([tScanner scanUpToString:@", Code " intoString:&tNamespace]==NO) + { + return NO; + } + + tScanner.scanLocation+=@", Code ".length; + } + + if (outNamespace!=NULL) + *outNamespace=tNamespace; + + unsigned long long tHexValue; + + if ([tScanner scanHexLongLong:&tHexValue]==NO) + return NO; + + if (outCode!=NULL) + *outCode=tHexValue; + + return YES; +} + #pragma mark - - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -156,6 +209,48 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( return self; } +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError +{ + if ([inIncident isKindOfClass:IPSIncident.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + IPSIncidentExceptionInformation * tExceptionInformation=inIncident.exceptionInformation; + + _crashedThreadIndex=tExceptionInformation.faultingThread; + + if (tExceptionInformation.legacyInfo.threadTriggered.queue!=nil) + _crashedThreadName=[NSString stringWithFormat:@"Dispatch queue: %@",tExceptionInformation.legacyInfo.threadTriggered.queue]; + + _exceptionType=tExceptionInformation.exception.type; + + _exceptionSignal=tExceptionInformation.exception.signal; + + _exceptionSubtype=tExceptionInformation.exception.codes; + + _exceptionCodes=[tExceptionInformation.exception.rawCodes WB_arrayByMappingObjectsUsingBlock:^NSString *(NSNumber * bNumber, NSUInteger bIndex) { + + return @"A COMPLETER"; + }]; + + _exceptionNote=(tExceptionInformation.isCorpse==YES) ? @"EXC_CORPSE_NOTIFY" : nil; + + _terminationNamespace=[tExceptionInformation.termination.namespace copy]; + + _terminationCode=tExceptionInformation.termination.code; + } + + return self; +} + #pragma mark - - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError @@ -277,6 +372,26 @@ - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outEr return; } + + if ([tKey isEqualToString:@"Termination Reason"]==YES) + { + NSString * tNamespace=nil; + NSUInteger tCode=0; + + if ([CUICrashLogExceptionInformation parseString:tValue terminationReasonNamespace:&tNamespace code:&tCode]==NO) + { + tError=[NSError errorWithDomain:CUIParsingErrorDomain code:CUIParsingUnknownError userInfo:@{CUIParsingErrorLineKey:@(bLineNumber)}]; + + *bOutStop=YES; + + return; + } + + self.terminationNamespace=tNamespace; + self.terminationCode=tCode; + + return; + } }]; if (outError!=NULL && tError!=nil) diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.h b/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.h index 03db3de..f927505 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.h @@ -13,6 +13,8 @@ #import +#import "IPSIncident.h" + #import "CUIOperatingSystemVersion.h" #include "CUICodeType.h" @@ -69,4 +71,6 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError; +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.m b/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.m index 747dec4..64a175d 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogHeader.m @@ -168,7 +168,7 @@ + (BOOL)parseString:(NSString *)inString codeType:(CUICodeType *)outCodeType nat - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -191,6 +191,100 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError return self; } +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError +{ + if ([inIncident isKindOfClass:IPSIncident.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + IPSIncidentHeader * tIPSHeader=inIncident.header; + + _reportVersion=12; + + _dateTime=tIPSHeader.captureTime; + + NSString * tSystemVersionTrain=tIPSHeader.operatingSystemVersion.train; + + NSString * tPrefix=@"Mac OS X "; + + // A COMPLETER (Think iOS) + + if ([tSystemVersionTrain hasPrefix:tPrefix]==NO) + { + tPrefix=@"macOS "; + + if ([tSystemVersionTrain hasPrefix:tPrefix]==NO) + { + tPrefix=@""; + } + } + + _operatingSystemVersion=[[CUIOperatingSystemVersion alloc] initWithString:[tSystemVersionTrain substringFromIndex:tPrefix.length]]; + + _systemIntegrityProtectionEnabled=tIPSHeader.systemIntegrityProtectionEnable; + + _bridgeOSVersion=nil; + + if ([tIPSHeader.crashReporterKey isKindOfClass:NSUUID.class]==YES) + _anonymousUUID=[tIPSHeader.crashReporterKey UUIDString]; + else + _anonymousUUID=tIPSHeader.crashReporterKey; + + + _codeType=CUICodeTypeARM_64; + + if ([tIPSHeader.cpuType isEqualToString:@"X86-64"]==YES) + { + _codeType=CUICodeTypeX86_64; + } + else if ([tIPSHeader.cpuType isEqualToString:@"ARM-64"]==YES) + { + _codeType=CUICodeTypeARM_64; + } + + _native=(tIPSHeader.translated==NO); + + + _executablePath=tIPSHeader.processPath; + + IPSBundleInfo * tBundleInfo=tIPSHeader.bundleInfo; + + _bundleIdentifier=tBundleInfo.bundleIdentifier; + + if (tBundleInfo.bundleVersion!=nil) + { + _executableVersion=[NSString stringWithFormat:@"%@ (%@)",tBundleInfo.bundleShortVersionString,tBundleInfo.bundleVersion]; + } + else + { + _executableVersion=tIPSHeader.bundleInfo.bundleShortVersionString; + } + + + _responsibleProcessName=tIPSHeader.responsibleProcessName; + _responsibleProcessIdentifier=tIPSHeader.responsibleProcessID; + + _processName=tIPSHeader.processName; + _processIdentifier=tIPSHeader.processID; + + _parentProcessName=tIPSHeader.parentProcessName; + _parentProcessIdentifier=tIPSHeader.parentProcessID; + + + _userIdentifier=tIPSHeader.userID; + } + + return self; +} + #pragma mark - - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError @@ -418,8 +512,8 @@ - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outEr if ([tKey isEqualToString:@"Code Type"]==YES) { - CUICodeType tCodeType; - BOOL tNative; + CUICodeType tCodeType=CUICodeTypeUnknown; + BOOL tNative=NO; // X86-64 (Native) // X86 (Native) diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationOutlineViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationOutlineViewController.m index 37b8daf..497c264 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationOutlineViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationOutlineViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -58,7 +58,7 @@ typedef NS_ENUM(NSUInteger, CUIThreadsModeView) #define CUIThreadsViewMinimumHeight 200.0 #define CUIBinaryImagesViewMinimumHeight 190.0 -@interface CUICrashLogPresentationOutlineViewController () +@interface CUICrashLogPresentationOutlineViewController () { IBOutlet NSTextField * _exceptionTypeValue; @@ -169,27 +169,27 @@ - (void)viewDidLoad _diagnosticMessageTextView.textContainerInset=NSMakeSize(8.0, 8.0); - _listModeButton.state=NSOffState; - _columnModeButton.state=NSOffState; - _lightTableModeButton.state=NSOffState; + _listModeButton.state=NSControlStateValueOff; + _columnModeButton.state=NSControlStateValueOff; + _lightTableModeButton.state=NSControlStateValueOff; switch(_threadsViewMode) { case CUIThreadsModeViewList: - _listModeButton.state=NSOnState; + _listModeButton.state=NSControlStateValueOn; break; case CUIThreadsModeViewColumn: - _columnModeButton.state=NSOnState; + _columnModeButton.state=NSControlStateValueOn; break; case CUIThreadsModeViewLightTable: - _lightTableModeButton.state=NSOnState; + _lightTableModeButton.state=NSControlStateValueOn; break; @@ -199,13 +199,13 @@ - (void)viewDidLoad } - _showOnlyCrashedThreadButton.state=(self.showOnlyCrashedThread==YES) ? NSOnState : NSOffState; + _showOnlyCrashedThreadButton.state=(self.showOnlyCrashedThread==YES) ? NSControlStateValueOn : NSControlStateValueOff; - _showByteOffsetButton.state=((self.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSOnState : NSOffState; + _showByteOffsetButton.state=((self.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showMachineInstructionAddressButton.state=((self.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSOnState : NSOffState; + _showMachineInstructionAddressButton.state=((self.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showBinaryNameButton.state=((self.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSOnState : NSOffState; + _showBinaryNameButton.state=((self.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; [self showThreadsViewForMode:_threadsViewMode]; @@ -238,11 +238,14 @@ - (void)viewDidAppear tTopViewHeight=[tNumber doubleValue]; - + BOOL tIsCollapsed=NO; tNumber=[tUserDefaults objectForKey:CUIDefaultsBottomViewCollapsedKey]; if (tNumber==nil || [tNumber boolValue]==YES) + tIsCollapsed=YES; + + if (tIsCollapsed==YES) [_splitView setPosition:[_splitView maxPossiblePositionOfDividerAtIndex:1] ofDividerAtIndex:1]; CGFloat tBottomViewWHeight=CUIBinaryImagesViewMinimumHeight; @@ -253,6 +256,10 @@ - (void)viewDidAppear tBottomViewWHeight=[tNumber doubleValue]; [self _splitView:_splitView resizeSubviewsWithTopViewHeight:tTopViewHeight bottomViewHeight:tBottomViewWHeight]; + + [NSNotificationCenter.defaultCenter postNotificationName:CUIBottomViewCollapseStateDidChangeNotification + object:self.view.window + userInfo:@{@"Collapsed":@(tIsCollapsed)}]; } - (void)viewWillDisappear @@ -358,23 +365,23 @@ - (void)setCrashLog:(CUICrashLog *)inCrashLog if (tIsRawCrashLog==NO && tAreBacktracesAvailable==YES) { - _showOnlyCrashedThreadButton.state=(self.displaySettings.showOnlyCrashedThread==YES) ? NSOnState : NSOffState; + _showOnlyCrashedThreadButton.state=(self.displaySettings.showOnlyCrashedThread==YES) ? NSControlStateValueOn : NSControlStateValueOff; - _showByteOffsetButton.state=((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==CUIStackFrameByteOffsetComponent) ? NSOnState : NSOffState; + _showByteOffsetButton.state=((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==CUIStackFrameByteOffsetComponent) ? NSControlStateValueOn : NSControlStateValueOff; - _showMachineInstructionAddressButton.state=((self.displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)==CUIStackFrameMachineInstructionAddressComponent) ? NSOnState : NSOffState; + _showMachineInstructionAddressButton.state=((self.displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)==CUIStackFrameMachineInstructionAddressComponent) ? NSControlStateValueOn : NSControlStateValueOff; - _showBinaryNameButton.state=(((self.displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)==CUIStackFrameBinaryNameComponent)!=0) ? NSOnState : NSOffState; + _showBinaryNameButton.state=(((self.displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)==CUIStackFrameBinaryNameComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; } else { - _showOnlyCrashedThreadButton.state=NSOffState; + _showOnlyCrashedThreadButton.state=NSControlStateValueOff; - _showByteOffsetButton.state=NSOffState; + _showByteOffsetButton.state=NSControlStateValueOff; - _showMachineInstructionAddressButton.state=NSOffState; + _showMachineInstructionAddressButton.state=NSControlStateValueOff; - _showBinaryNameButton.state=NSOffState; + _showBinaryNameButton.state=NSControlStateValueOff; } _binaryImagesViewController.crashLog=(tIsRawCrashLog==NO) ? inCrashLog : nil; @@ -421,12 +428,14 @@ - (void)showThreadsViewForMode:(CUIThreadsModeView)inMode { case CUIThreadsModeViewList: - _threadsViewController=[CUIThreadsListViewController new]; + _threadsViewController=[[CUIThreadsListViewController alloc] initWithUserInterfaceLayoutDirection:self.view.userInterfaceLayoutDirection]; + break; case CUIThreadsModeViewColumn: - _threadsViewController=[CUIThreadsColumnViewController new]; + _threadsViewController=[[CUIThreadsColumnViewController alloc] initWithUserInterfaceLayoutDirection:self.view.userInterfaceLayoutDirection]; + break; default: @@ -547,6 +556,8 @@ - (IBAction)showMoreExceptionInfo:(id)sender tExceptionTypeLookUpPopOver.contentViewController=tPopUpViewController; NSView * tTrick=tPopUpViewController.view; // This is used to trigger the viewDidLoad method of the contentViewController. + + (void)tTrick; } - (IBAction)showInFinder:(id)sender @@ -571,25 +582,52 @@ - (IBAction)showHideBottomView:(id)sender - (IBAction)switchViewMode:(NSButton *)sender { if (sender.tag==_threadsViewMode) + { + switch(_threadsViewMode) + { + case CUIThreadsModeViewList: + + _listModeButton.state=WBControlStateValueOn; + + break; + + case CUIThreadsModeViewColumn: + + _columnModeButton.state=WBControlStateValueOn; + + break; + + case CUIThreadsModeViewLightTable: + + _lightTableModeButton.state=WBControlStateValueOn; + + break; + + default: + + break; + } + return; + } switch(_threadsViewMode) { case CUIThreadsModeViewList: - _listModeButton.state=NSOffState; + _listModeButton.state=NSControlStateValueOff; break; case CUIThreadsModeViewColumn: - _columnModeButton.state=NSOffState; + _columnModeButton.state=NSControlStateValueOff; break; case CUIThreadsModeViewLightTable: - _lightTableModeButton.state=NSOffState; + _lightTableModeButton.state=NSControlStateValueOff; break; @@ -607,16 +645,16 @@ - (IBAction)switchViewMode:(NSButton *)sender - (IBAction)CUI_MENUACTION_switchShowOnlyCrashedThread:(NSButton *)sender { - BOOL tShow=(sender.state==NSOnState); + BOOL tShow=(sender.state==NSControlStateValueOn); self.showOnlyCrashedThread=tShow; _threadsViewController.showOnlyCrashedThread=tShow; } -#pragma mark - CUIExceptionTypePopUpViewControllerDelegate +#pragma mark - CUIQuickHelpPopUpViewControllerDelegate -- (void)exceptionTypePopUpViewController:(CUIExceptionTypePopUpViewController *)inController didComputeSizeOfPopover:(NSPopover *)inPopover +- (void)quickHelpPopUpViewController:(CUIQuickHelpPopUpViewController *)inController didComputeSizeOfPopover:(NSPopover *)inPopover { // Compute the coordinates for the popover @@ -772,12 +810,23 @@ - (NSRect)splitView:(NSSplitView *)inSplitView effectiveRect:(NSRect)proposedEff if (inDividerIndex==1) { - proposedEffectiveRect.size.height=CUIThreadsBottomBarHeight+inSplitView.dividerThickness+4.0; - proposedEffectiveRect.origin.y-=CUIThreadsBottomBarHeight; - - proposedEffectiveRect.origin.x=NSMaxX(_columnModeButton.frame); - proposedEffectiveRect.size.width=NSMinX(_showOnlyCrashedThreadButton.frame)-proposedEffectiveRect.origin.x; - + proposedEffectiveRect.size.height=CUIThreadsBottomBarHeight+inSplitView.dividerThickness+4.0; + proposedEffectiveRect.origin.y-=CUIThreadsBottomBarHeight; + + switch(self.view.userInterfaceLayoutDirection) + { + case NSUserInterfaceLayoutDirectionLeftToRight: + + proposedEffectiveRect.origin.x=NSMaxX(_columnModeButton.frame); + proposedEffectiveRect.size.width=NSMinX(_showOnlyCrashedThreadButton.frame)-proposedEffectiveRect.origin.x; + break; + case NSUserInterfaceLayoutDirectionRightToLeft: + + proposedEffectiveRect.origin.x=NSMaxX(_showOnlyCrashedThreadButton.frame); + proposedEffectiveRect.size.width=NSMinX(_columnModeButton.frame)-proposedEffectiveRect.origin.x; + break; + } + return proposedEffectiveRect; } @@ -788,11 +837,11 @@ - (void)splitViewDidResizeSubviews:(NSNotification *)inNotification { BOOL tIsCollapsed=self.isBinaryImagesViewCollapsed; - _showBinaryImagesButton.state=(tIsCollapsed==NO) ? NSOnState : NSOffState; + _showBinaryImagesButton.state=(tIsCollapsed==NO) ? NSControlStateValueOn : NSControlStateValueOff; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIBottomViewCollapseStateDidChangeNotification - object:self.view.window - userInfo:@{@"Collapsed":@(tIsCollapsed)}]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIBottomViewCollapseStateDidChangeNotification + object:self.view.window + userInfo:@{@"Collapsed":@(tIsCollapsed)}]; } /* Given a divider index, return an additional rectangular area (in the coordinate system established by the split view's bounds) in which mouse clicks should also initiate divider dragging, or NSZeroRect to not add one. If a split view has no delegate, or if its delegate does not respond to this message, only mouse clicks within the effective frame of a divider initiate divider dragging. diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationTextViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationTextViewController.m index c66e025..8342df5 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationTextViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationTextViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,7 +17,7 @@ -#import "CUIBinaryImage+UI.h" +#import "CUIBinaryImageUtility.h" #import "CUIApplicationPreferences.h" #import "CUIApplicationPreferences+Themes.h" @@ -25,9 +25,11 @@ #import "CUIThemesManager.h" #import "CUIThemeItemsGroup+UI.h" -#import "CUIRawTextTransformation.h" +#import "CUIIPSTransform.h" +#import "CUICrashDataTransform.h" #import "CUIExceptionTypePopUpViewController.h" +#import "CUITerminationReasonPopUpViewController.h" #import "CUICrashLogTextView.h" @@ -39,6 +41,11 @@ #import "CUIExportAccessoryViewController.h" +// Obfuscation + +#import "IPSObfuscator.h" +#import "IPSReport+Obfuscating.h" + // Noodle #import "NoodleLineNumberView.h" @@ -50,7 +57,7 @@ NSString * const CUICrashLogPresentationTextViewFontSizeDelta=@"ui.text.fontSize.delta"; -@interface CUICrashLogPresentationTextViewController () +@interface CUICrashLogPresentationTextViewController () { IBOutlet CUICrashLogTextView * _textView; @@ -60,21 +67,12 @@ @interface CUICrashLogPresentationTextViewController () = 101600 + if (@available(*, macOS 11.0)) + { + [[NSWorkspace sharedWorkspace] openURLs:@[tFileURL] + withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL + configuration:[NSWorkspaceOpenConfiguration configuration] + completionHandler:^(NSRunningApplication * _Nullable app, NSError * _Nullable error) { + + }]; + } + else +#endif + { + [[NSWorkspace sharedWorkspace] openURLs:@[tFileURL] + withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL + options:NSWorkspaceLaunchDefault + configuration:@{} + error:NULL]; + } + return YES; } } @@ -837,7 +898,7 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem /*if (tAction==@selector(CUI_MENUACTION_switchSyntaxHighlighting:)) { - inMenuItem.state=(self.displaySettings.highlightSyntax==YES) ? NSOnState : NSOffState; + inMenuItem.state=(self.displaySettings.highlightSyntax==YES) ? NSControlStateValueOn : NSControlStateValueOff; }*/ if (tAction==@selector(performTextFinderAction:)) @@ -928,9 +989,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tIsRawCrashLog==YES) return NO; - BOOL tEnabled=(tCrashLog.headerRange.location!=NSNotFound); + BOOL tEnabled=tCrashLog.isHeaderAvailable; - inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentHeaderSection)==CUIDocumentHeaderSection) : NSOffState; + inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentHeaderSection)==CUIDocumentHeaderSection) : NSControlStateValueOff; return tEnabled; } @@ -940,9 +1001,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tIsRawCrashLog==YES) return NO; - BOOL tEnabled=(tCrashLog.exceptionInformationRange.location!=NSNotFound); + BOOL tEnabled=tCrashLog.isExceptionInformationAvailable; - inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentExceptionInformationSection)==CUIDocumentExceptionInformationSection) : NSOffState; + inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentExceptionInformationSection)==CUIDocumentExceptionInformationSection) : NSControlStateValueOff; return tEnabled; } @@ -952,9 +1013,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tIsRawCrashLog==YES) return NO; - BOOL tEnabled=(tCrashLog.diagnosticMessagesRange.location!=NSNotFound); + BOOL tEnabled=tCrashLog.isDiagnosticMessageAvailable; - inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)==CUIDocumentDiagnosticMessagesSection) : NSOffState; + inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)==CUIDocumentDiagnosticMessagesSection) : NSControlStateValueOff; return tEnabled; } @@ -964,9 +1025,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tIsRawCrashLog==YES) return NO; - BOOL tEnabled=(tCrashLog.backtracesRange.location!=NSNotFound); + BOOL tEnabled=tCrashLog.isBacktracesAvailable; - inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==CUIDocumentBacktracesSection) : NSOffState; + inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==CUIDocumentBacktracesSection) : NSControlStateValueOff; return tEnabled; } @@ -976,9 +1037,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tIsRawCrashLog==YES) return NO; - BOOL tEnabled=(tCrashLog.threadStateRange.location!=NSNotFound); + BOOL tEnabled=tCrashLog.isThreadStateAvailable; - inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentThreadStateSection)==CUIDocumentThreadStateSection) : NSOffState; + inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentThreadStateSection)==CUIDocumentThreadStateSection) : NSControlStateValueOff; return tEnabled; } @@ -988,9 +1049,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tIsRawCrashLog==YES) return NO; - BOOL tEnabled=(tCrashLog.binaryImagesRange.location!=NSNotFound); + BOOL tEnabled=tCrashLog.isBinaryImagesAvailable; - inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==CUIDocumentBinaryImagesSection) : NSOffState; + inMenuItem.state=(tEnabled==YES) ? ((self.displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==CUIDocumentBinaryImagesSection) : NSControlStateValueOff; return tEnabled; } @@ -1104,6 +1165,9 @@ - (IBAction)CUI_MENUACTION_exportCrashLog:(id)sender tAccessoryViewController.canSelectExportedContents=(tSelectionRange.length>0); // A COMPLETER (minimum length?) + IPSReport * tIPSReport=self.crashLog.ipsReport; + + tAccessoryViewController.canObfuscateContents=(tIPSReport!=nil); tExportPanel.accessoryView=tAccessoryViewController.view; @@ -1115,34 +1179,58 @@ - (IBAction)CUI_MENUACTION_exportCrashLog:(id)sender CUICrashLogExportFormat tSelectedExportFormat=tAccessoryViewController.exportFormat; - CUIRawTextTransformation * tRawTextTransformation=[CUIRawTextTransformation new]; + CUIDataTransform * tDataTransform=nil; - tRawTextTransformation.displaySettings=[tAccessoryViewController.displaySettings copy]; - tRawTextTransformation.fontSizeDelta=0; + if (tIPSReport!=nil) + { + IPSReport * tFinalIPSReport=tIPSReport; + + tDataTransform=[[CUIIPSTransform alloc] initWithThemesProvider:[CUIThemesManager sharedManager]]; + + if (tAccessoryViewController.obfuscateContents==YES) + { + IPSObfuscator * tObfuscator=[IPSObfuscator new]; + + tFinalIPSReport=[tIPSReport obfuscateWithObfuscator:tObfuscator]; + + tDataTransform.symbolicationMode=CUISymbolicationModeNone; + } + + tDataTransform.input=tFinalIPSReport; + ((CUIReportThemedTransform *)tDataTransform).crashlog=self.crashLog; + } + else + { + tDataTransform=[[CUICrashDataTransform alloc] initWithThemesProvider:[CUIThemesManager sharedManager]]; + tDataTransform.input=self.crashLog; + } + + tDataTransform.displaySettings=[tAccessoryViewController.displaySettings copy]; + tDataTransform.fontSizeDelta=0; switch(tSelectedExportFormat) { case CUICrashLogExportFormatHTML: - tRawTextTransformation.hyperlinksStyle=CUIHyperlinksHTML; + tDataTransform.hyperlinksStyle=CUIHyperlinksHTML; break; default: - tRawTextTransformation.hyperlinksStyle=CUIHyperlinksNone; + tDataTransform.hyperlinksStyle=CUIHyperlinksNone; break; } - NSAttributedString * tAttributedString=[tRawTextTransformation transformCrashLog:self.crashLog]; - - if (tAttributedString==nil) + if ([tDataTransform transform]==NO) { NSBeep(); return; } + NSAttributedString * tAttributedString=tDataTransform.output; + // Extract the selection if needed if (tAccessoryViewController.exportedContents==CUICrashLogExportedContentsSelection) @@ -1189,7 +1277,7 @@ - (IBAction)CUI_MENUACTION_exportCrashLog:(id)sender if (tAccessoryViewController.exportedContents==CUICrashLogExportedContentsSelection) { - NSRange tGlyphRange = [self->_textView.layoutManager glyphRangeForCharacterRange:tSelectionRange actualCharacterRange:NULL]; + NSRange tGlyphRange=[self->_textView.layoutManager glyphRangeForCharacterRange:tSelectionRange actualCharacterRange:NULL]; NSRect tBoundingRect=[self->_textView.layoutManager boundingRectForGlyphRange:tGlyphRange inTextContainer:self->_textView.textContainer]; @@ -1231,12 +1319,19 @@ - (IBAction)CUI_MENUACTION_exportCrashLog:(id)sender } else { - NSDictionary * tDocumentAttributes=@{ - NSDocumentTypeDocumentAttribute:tDocumenType, - NSBackgroundColorDocumentAttribute:self->_textView.backgroundColor - }; - - tData=[tAttributedString dataFromRange:NSMakeRange(0,tAttributedString.length) documentAttributes:tDocumentAttributes error:&tError]; + if (tSelectedExportFormat==CUICrashLogExportFormatText) + { + tData=[tAttributedString.string dataUsingEncoding:NSUTF8StringEncoding]; + } + else + { + NSDictionary * tDocumentAttributes=@{ + NSDocumentTypeDocumentAttribute:tDocumenType, + NSBackgroundColorDocumentAttribute:self->_textView.backgroundColor + }; + + tData=[tAttributedString dataFromRange:NSMakeRange(0,tAttributedString.length) documentAttributes:tDocumentAttributes error:&tError]; + } } if (tData==nil) @@ -1449,7 +1544,7 @@ - (void)_CUI_MENUACTION_switchVisibilityCommon // Update the Sections menu in the navigation bar - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogPresentationDisplayedSectionsDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogPresentationDisplayedSectionsDidChangeNotification object:nil]; // Update the selected item in the Sections menu if needed @@ -1615,7 +1710,7 @@ - (void)boundsDidChange:(NSNotification *)inNotification [tVisibleSections removeObjectsAtIndexes:tMutableIndexSet]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogPresentationVisibleSectionsDidChangeNotification object:tVisibleSections]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogPresentationVisibleSectionsDidChangeNotification object:tVisibleSections]; //NSLog(@"%@",NSStringFromRange(tVisibleRange)); diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationViewController.m index 9cae969..7b20fcc 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogPresentationViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,9 +21,11 @@ NSString * const CUICrashLogPresentationVisibleSectionsDidChangeNotification=@"CUICrashLogPresentationVisibleSectionsDidChangeNotification"; -@implementation CUICrashLogPresentationViewController +@interface CUICrashLogPresentationViewController () -#pragma mark - +@end + +@implementation CUICrashLogPresentationViewController - (void)viewDidLoad { @@ -52,11 +54,11 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem { if ([inMenuItem.title isEqualToString:[CUIThemesManager sharedManager].currentTheme.name]==YES) { - inMenuItem.state=NSOnState; + inMenuItem.state=NSControlStateValueOn; } else { - inMenuItem.state=NSOffState; + inMenuItem.state=NSControlStateValueOff; } return YES; @@ -64,15 +66,15 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tAction==@selector(CUI_MENUACTION_switchShowOffset:)) { - inMenuItem.state=((self.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSOnState : NSOffState; + inMenuItem.state=((self.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; } else if (tAction==@selector(CUI_MENUACTION_switchShowMemoryAddress:)) { - inMenuItem.state=((self.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSOnState : NSOffState; + inMenuItem.state=((self.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; } else if (tAction==@selector(CUI_MENUACTION_switchShowBinaryImageIdentifier:)) { - inMenuItem.state=((self.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSOnState : NSOffState; + inMenuItem.state=((self.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; } return YES; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogSectionsDetector.m b/app_unexpectedly/app_unexpectedly/CUICrashLogSectionsDetector.m index 90ca36d..205da95 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogSectionsDetector.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogSectionsDetector.m @@ -50,6 +50,7 @@ + (NSRange)detectExceptionInformationSectionRangeInTextualRepresentation:(NSArra if ([bLine hasPrefix:@"Application Specific Information:"]==YES || [bLine hasPrefix:@"VM Regions Near"]==YES || + [bLine hasPrefix:@"VM Region Info:"]==YES || [bLine isEqualToString:@"Backtrace not available"]==YES || @@ -108,8 +109,8 @@ + (NSRange)detectBacktracesSectionRangeInTextualRepresentation:(NSArray *)inLine [inLines enumerateObjectsAtIndexes:inIndexes options:0 usingBlock:^(NSString * bLine , NSUInteger bLineNumber, BOOL * bOutStop) { - if ((([bLine hasPrefix:@"Thread"]==YES || [bLine hasPrefix:@"Unknown"]==YES) && [bLine rangeOfString:@"crashed with"].location !=NSNotFound) || - + if ((([bLine hasPrefix:@"Thread"]==YES || [bLine hasPrefix:@"Unknown"]==YES) && [bLine rangeOfString:@"crashed with"].location!=NSNotFound) || + [bLine rangeOfString:@"Thread State" options:NSCaseInsensitiveSearch].location==0 || [bLine rangeOfString:@"Binary Images" options:NSCaseInsensitiveSearch].location==0 ) { diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogTableCellView.m b/app_unexpectedly/app_unexpectedly/CUICrashLogTableCellView.m index 979499c..64c68e3 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogTableCellView.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogTableCellView.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,64 +13,116 @@ #import "CUICrashLogTableCellView.h" -#define RESIZING_BORDER 400 +#define RESIZING_BORDER 400 -#define INTERSPACE_H 8 +#define INTERSPACE_H 8 -#define SMALL_WIDTH 71 -#define LARGE_WIDTH 100 +#define SMALL_WIDTH 71 +#define LARGE_WIDTH 100 @implementation CUICrashLogTableCellView - (void)layout { - NSRect tBounds=self.bounds; - NSRect tFrame=self.exceptionTypeLabel.frame; - - if (tBounds.size.width>RESIZING_BORDER) - { - if (tFrame.size.width<(LARGE_WIDTH+1)) - { - tFrame.origin.x=NSMaxX(tFrame)-LARGE_WIDTH; - tFrame.size.width=LARGE_WIDTH; - - self.exceptionTypeLabel.frame=tFrame; - - NSRect tOtherFrame=self.dateLabel.frame; - - tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); - - self.dateLabel.frame=tOtherFrame; - - tOtherFrame=self.textField.frame; - - tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); - - self.textField.frame=tOtherFrame; - } - } - else - { - if (tFrame.size.width>(SMALL_WIDTH+1)) - { - tFrame.origin.x=NSMaxX(tFrame)-SMALL_WIDTH; - tFrame.size.width=SMALL_WIDTH; - - self.exceptionTypeLabel.frame=tFrame; - - NSRect tOtherFrame=self.dateLabel.frame; - - tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); - - self.dateLabel.frame=tOtherFrame; - - tOtherFrame=self.textField.frame; - - tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); - - self.textField.frame=tOtherFrame; - } - } + NSRect tBounds=self.bounds; + NSRect tFrame=self.exceptionTypeLabel.frame; + + if (self.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft) + { + if (tBounds.size.width>RESIZING_BORDER) + { + if (tFrame.size.width<(LARGE_WIDTH+1)) + { + tFrame.size.width=LARGE_WIDTH; + + self.exceptionTypeLabel.frame=tFrame; + + NSRect tOtherFrame=self.dateLabel.frame; + + tOtherFrame.size.width=NSMaxX(tOtherFrame)-(NSMaxX(tFrame)+INTERSPACE_H); + tOtherFrame.origin.x=NSMaxX(tFrame)+INTERSPACE_H; + + self.dateLabel.frame=tOtherFrame; + + tOtherFrame=self.textField.frame; + + tOtherFrame.size.width=NSMaxX(tOtherFrame)-(NSMaxX(tFrame)+INTERSPACE_H); + tOtherFrame.origin.x=NSMaxX(tFrame)+INTERSPACE_H; + + self.textField.frame=tOtherFrame; + } + } + else + { + if (tFrame.size.width>(SMALL_WIDTH+1)) + { + tFrame.size.width=SMALL_WIDTH; + + self.exceptionTypeLabel.frame=tFrame; + + NSRect tOtherFrame=self.dateLabel.frame; + + tOtherFrame.size.width=NSMaxX(tOtherFrame)-(NSMaxX(tFrame)+INTERSPACE_H); + tOtherFrame.origin.x=NSMaxX(tFrame)+INTERSPACE_H; + + self.dateLabel.frame=tOtherFrame; + + tOtherFrame=self.textField.frame; + + tOtherFrame.size.width=NSMaxX(tOtherFrame)-(NSMaxX(tFrame)+INTERSPACE_H); + tOtherFrame.origin.x=NSMaxX(tFrame)+INTERSPACE_H; + + self.textField.frame=tOtherFrame; + } + } + } + else + { + if (tBounds.size.width>RESIZING_BORDER) + { + if (tFrame.size.width<(LARGE_WIDTH+1)) + { + tFrame.origin.x=NSMaxX(tFrame)-LARGE_WIDTH; + tFrame.size.width=LARGE_WIDTH; + + self.exceptionTypeLabel.frame=tFrame; + + NSRect tOtherFrame=self.dateLabel.frame; + + tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); + + self.dateLabel.frame=tOtherFrame; + + tOtherFrame=self.textField.frame; + + tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); + + self.textField.frame=tOtherFrame; + } + } + else + { + if (tFrame.size.width>(SMALL_WIDTH+1)) + { + tFrame.origin.x=NSMaxX(tFrame)-SMALL_WIDTH; + tFrame.size.width=SMALL_WIDTH; + + self.exceptionTypeLabel.frame=tFrame; + + NSRect tOtherFrame=self.dateLabel.frame; + + tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); + + self.dateLabel.frame=tOtherFrame; + + tOtherFrame=self.textField.frame; + + tOtherFrame.size.width=NSMinX(tFrame)-INTERSPACE_H-NSMinX(tOtherFrame); + + self.textField.frame=tOtherFrame; + } + } + } } @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.h b/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.h index 92f8287..f09b5ce 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.h @@ -15,6 +15,8 @@ @interface CUICrashLogTextView : NSTextView +@property BOOL wrapLines; + - (void) CUI_scrollPoint:(NSPoint)inPoint; @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.m b/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.m index 730b2bb..4aed56c 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogTextView.m @@ -23,8 +23,14 @@ - (void)_scrollUp:(CGFloat)inOffset; @implementation CUICrashLogTextView -- (void)CUI_scrollPoint:(NSPoint)inPoint +- (void)_scrollUp:(CGFloat)inOffset { + if (self.wrapLines==YES) + { + [super _scrollUp:inOffset]; + return; + } + NSScrollView * tScrollView=self.enclosingScrollView; NSView * tDocumentView=tScrollView.documentView; @@ -34,20 +40,35 @@ - (void)CUI_scrollPoint:(NSPoint)inPoint tVerticalRulerView==nil || tScrollView.horizontalScroller.isHidden==YES) { - [self scrollPoint:inPoint]; + [super _scrollUp:inOffset]; return; } - + + NSRect tOldFrame=tDocumentView.frame; + // Offset the text view frame to take into account the vertical ruler width - inPoint.x-=NSWidth(tVerticalRulerView.frame); + NSRect tNewFrame=tOldFrame; - [self scrollPoint:inPoint]; + tNewFrame.origin.x-=NSWidth(tVerticalRulerView.frame); + self.frame=tNewFrame; + + [super _scrollUp:inOffset]; + + // Restore the text view frame + + self.frame=tOldFrame; } -- (void)_scrollUp:(CGFloat)inOffset +- (void)_scrollDown:(CGFloat)inOffset { + if (self.wrapLines==YES) + { + [super _scrollDown:inOffset]; + return; + } + NSScrollView * tScrollView=self.enclosingScrollView; NSView * tDocumentView=tScrollView.documentView; @@ -57,30 +78,33 @@ - (void)_scrollUp:(CGFloat)inOffset tVerticalRulerView==nil || tScrollView.horizontalScroller.isHidden==YES) { - [super _scrollUp:inOffset]; + [super _scrollDown:inOffset]; return; } NSRect tOldFrame=tDocumentView.frame; - // Offset the text view frame to take into account the vertical ruler width - NSRect tNewFrame=tOldFrame; tNewFrame.origin.x-=NSWidth(tVerticalRulerView.frame); - self.frame=tNewFrame; - [super _scrollUp:inOffset]; + [super _scrollDown:inOffset]; // Restore the text view frame self.frame=tOldFrame; } -- (void)_scrollDown:(CGFloat)inOffset +- (void)CUI_scrollPoint:(NSPoint)inPoint { + if (self.wrapLines==YES) + { + [super scrollPoint:inPoint]; + return; + } + NSScrollView * tScrollView=self.enclosingScrollView; NSView * tDocumentView=tScrollView.documentView; @@ -90,26 +114,16 @@ - (void)_scrollDown:(CGFloat)inOffset tVerticalRulerView==nil || tScrollView.horizontalScroller.isHidden==YES) { - [super _scrollDown:inOffset]; + [self scrollPoint:inPoint]; return; } - NSRect tOldFrame=tDocumentView.frame; - // Offset the text view frame to take into account the vertical ruler width - - NSRect tNewFrame=tOldFrame; - - tNewFrame.origin.x-=NSWidth(tVerticalRulerView.frame); - - self.frame=tNewFrame; - [super _scrollDown:inOffset]; + inPoint.x-=NSWidth(tVerticalRulerView.frame); - // Restore the text view frame - - self.frame=tOldFrame; + [self scrollPoint:inPoint]; } - (NSPoint)textContainerOrigin diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState+UI.m b/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState+UI.m index 8eb76bb..ebf5e2d 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState+UI.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState+UI.m @@ -33,7 +33,7 @@ - (NSString *)displayedCPUType case CPU_TYPE_ARM64: - return @"ARM64"; + return @"ARM-64"; case CPU_TYPE_POWERPC: diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.h b/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.h index 9747505..fc67fec 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.h @@ -15,6 +15,8 @@ #import "CUIRegister.h" +#import "IPSIncident.h" + @interface CUICrashLogThreadState : NSObject @property (readonly) NSUInteger threadIndex; @@ -33,4 +35,6 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.m b/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.m index afdbdb2..67908c8 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogThreadState.m @@ -15,6 +15,12 @@ #import "CUIParsingErrors.h" +#import "IPSThreadState+RegisterDisplayName.h" + +#import "NSArray+WBExtensions.h" + +#import "NSString+CPU.h" + @interface CUICrashLogThreadState () @property NSUInteger threadIndex; @@ -37,7 +43,7 @@ @implementation CUICrashLogThreadState - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -60,6 +66,91 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines reportVersion:( return self; } +- (instancetype)initWithIPSIncident:(IPSIncident *)inIncident error:(NSError **)outError +{ + if ([inIncident isKindOfClass:IPSIncident.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + IPSThreadState * tThreadState=inIncident.threadState; + + if (tThreadState==nil) + { + if (outError!=NULL) + *outError=nil; + + return nil; + } + + _threadIndex=inIncident.exceptionInformation.faultingThread; + + IPSIncidentHeader * tHeader=inIncident.header; + + _CPUType=[tHeader.cpuType CUI_CPUType]; + + NSArray * tRegistersOrder; + + if ([tThreadState.flavor isEqualToString:@"x86_THREAD_STATE"]==YES) + { + tRegistersOrder=@[@"rax",@"rbx",@"rcx",@"rdx", + @"rdi",@"rsi",@"rbp",@"rsp", + @"r8",@"r9",@"r10",@"r11", + @"r12",@"r13",@"r14",@"r15", + @"rip",@"rflags",@"cr2" + ]; + } + else + { + tRegistersOrder=@[@"x0",@"x1",@"x2",@"x3", + @"x4",@"x5",@"x6",@"x7", + @"x8",@"x9",@"x10",@"x11", + @"x12",@"x13",@"x14",@"x15", + @"x16",@"x17",@"x18",@"x19", + @"x20",@"x21",@"x22",@"x23", + @"x24",@"x25",@"x26",@"x27", + @"x28",@"fp",@"lr", + @"sp",@"pc",@"cpsr", + @"far",@"esr" + ]; + } + + _registers=[tRegistersOrder WB_arrayByMappingObjectsUsingBlock:^id(NSString * bRegisterName, NSUInteger bIndex) { + + IPSRegisterState * tRegisterState=tThreadState.registersStates[bRegisterName]; + + if (tRegisterState!=nil) + { + CUIRegister * tRegister=[CUIRegister new]; + tRegister.name=[IPSThreadState displayNameForRegisterName:bRegisterName]; + tRegister.value=tRegisterState.value; + + return tRegister; + } + + return nil; + + }]; + + // A COMPLETER + + /*_logicalCPU=; + + _errorCode=; + + _trapNumber=;*/ + } + + return self; +} + - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outError { __block NSError * tError=nil; @@ -79,42 +170,51 @@ - (BOOL)parseTextualRepresentation:(NSArray *)inLines outError:(NSError **)outEr NSInteger tInteger=-1; - if ([tScanner scanInteger:&tInteger]==NO) - return NO; - - self.threadIndex=tInteger; - - if ([tScanner scanString:@"crashed with " intoString:NULL]==NO) - return NO; + if ([tScanner scanInteger:&tInteger]==YES) + { + self.threadIndex=tInteger; + + if ([tScanner scanString:@"crashed with " intoString:NULL]==NO) + return NO; - // Architecture + // Architecture - NSString * tString; + NSString * tString; - if ([tScanner scanUpToString:@"Thread State" intoString:&tString]==NO) - return NO; - - tString=[tString stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; - - if ([tString isEqualToString:@"ARM"]==YES) - { - self.CPUType=CPU_TYPE_ARM; + if ([tScanner scanUpToString:@"Thread State" intoString:&tString]==NO) + return NO; + + tString=[tString stringByTrimmingCharactersInSet:tWhitespaceCharacterSet]; + + if ([tString isEqualToString:@"ARM"]==YES) + { + self.CPUType=CPU_TYPE_ARM; + } + else if ([tString isEqualToString:@"X86"]==YES) + { + self.CPUType=CPU_TYPE_X86; + } + + tScanner.scanLocation+=[@"Thread State" length]; + + if ([tScanner scanUpToString:@":" intoString:&tString]==NO) + return NO; + + tString=[tString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"()"]]; + + if ([tString isEqualToString:@"64-bit"]==YES) + self.CPUType|=CPU_ARCH_ABI64; } - else if ([tString isEqualToString:@"X86"]==YES) + else { - self.CPUType=CPU_TYPE_X86; + if ([inLines.firstObject hasPrefix:@"Thread State"]==NO) + return NO; + + self.threadIndex=NSNotFound; + + self.CPUType=CPU_TYPE_ANY; } - tScanner.scanLocation+=[@"Thread State" length]; - - if ([tScanner scanUpToString:@":" intoString:&tString]==NO) - return NO; - - tString=[tString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"()"]]; - - if ([tString isEqualToString:@"64-bit"]==YES) - self.CPUType|=CPU_ARCH_ABI64; - // Registers values NSMutableArray * tMutableArray=[NSMutableArray array]; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.h b/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.h index e8258d5..e58a7ea 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.h @@ -20,4 +20,3 @@ @property (readonly) NSTableView * tableView; @end - diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.m index bcaf385..cb1549d 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsListViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -31,7 +31,7 @@ #import "CUICrashLogExceptionInformation+UI.h" -@interface CUICrashLogsListViewController () +@interface CUICrashLogsListViewController () { IBOutlet NSTableView * _tableView; @@ -51,6 +51,8 @@ @interface CUICrashLogsListViewController () _filterPattern options:NSCaseInsensitiveSearch].location!=NSNotFound) + if (self->_showsFileNames==NO) { - [self->_filteredAndSortedCrashLogsArray addObject:bCrashLog]; + NSString * tProcessName=bCrashLog.header.processName; - return; + if (tProcessName!=nil && [tProcessName rangeOfString:self->_filterPattern options:NSCaseInsensitiveSearch].location!=NSNotFound) + { + [self->_filteredAndSortedCrashLogsArray addObject:bCrashLog]; + + return; + } + + NSString * tResponsibleProcessName=bCrashLog.header.responsibleProcessName; + + if (tResponsibleProcessName!=nil && [tResponsibleProcessName rangeOfString:self->_filterPattern options:NSCaseInsensitiveSearch].location!=NSNotFound) + { + [self->_filteredAndSortedCrashLogsArray addObject:bCrashLog]; + + return; + } + } + else + { + NSString * tCrashLogFileName=bCrashLog.crashLogFilePath.lastPathComponent.stringByDeletingPathExtension; + + if (tCrashLogFileName!=nil && [tCrashLogFileName rangeOfString:self->_filterPattern options:NSCaseInsensitiveSearch].location!=NSNotFound) + { + [self->_filteredAndSortedCrashLogsArray addObject:bCrashLog]; + + return; + } } if ([bCrashLog.exceptionInformation.exceptionType rangeOfString:self->_filterPattern options:NSCaseInsensitiveSearch].location!=NSNotFound || @@ -207,8 +242,10 @@ - (void)refreshList case CUICrashLogsSortProcessNameAscending: - [_filteredAndSortedCrashLogsArray sortUsingSelector:@selector(compareProcessName:)]; - + if (_showsFileNames==NO) + [_filteredAndSortedCrashLogsArray sortUsingSelector:@selector(compareProcessName:)]; + else + [_filteredAndSortedCrashLogsArray sortUsingSelector:@selector(compareCrashLogFileName:)]; break; } @@ -263,6 +300,9 @@ - (void)refreshList - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem { + if (inMenuItem.tag==-1) + return NO; + SEL tAction=inMenuItem.action; if (tAction==@selector(showInFinder:) || @@ -319,13 +359,22 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem return YES; } + if (tAction==@selector(switchDisplayedName:)) + { + inMenuItem.state=(inMenuItem.tag==_showsFileNames) ? NSControlStateValueOn : NSControlStateValueOff; + + return YES; + } + if (tAction==@selector(switchSortType:)) { - inMenuItem.state=(inMenuItem.tag==_sortType) ? NSOnState : NSOffState; + inMenuItem.state=(inMenuItem.tag==_sortType) ? NSControlStateValueOn : NSControlStateValueOff; return YES; } + + return YES; } @@ -451,9 +500,19 @@ - (IBAction)takeFilterPatternFrom:(NSSearchField *)sender [self refreshList]; } -- (IBAction)switchSortType:(NSPopUpButton *)sender +- (IBAction)switchDisplayedName:(NSMenuItem *)sender { - NSInteger tTag=sender.selectedTag; + NSInteger tTag=sender.tag; + + if (tTag!=_showsFileNames) + { + [CUIApplicationPreferences sharedPreferences].crashLogsShowFileNames=tTag; + } +} + +- (IBAction)switchSortType:(NSMenuItem *)sender +{ + NSInteger tTag=sender.tag; if (tTag!=_sortType) { @@ -476,10 +535,27 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu CUIRawCrashLog * tCrashLog=_filteredAndSortedCrashLogsArray[inRow]; - tTableCellView.imageView.image=((CUICrashLog *)tCrashLog).processIcon; - + if (_showsFileNames==NO) + { + tTableCellView.imageView.image=((CUICrashLog *)tCrashLog).processIcon; - tTableCellView.textField.stringValue=tCrashLog.processName; + tTableCellView.textField.stringValue=tCrashLog.processName; + tTableCellView.textField.lineBreakMode=NSLineBreakByTruncatingTail; + } + else + { + static NSImage * sCrashLogFileIcon=nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + + sCrashLogFileIcon=[[NSWorkspace sharedWorkspace] iconForFileType:@"com.apple.crashreport"]; + + }); + + tTableCellView.imageView.image=sCrashLogFileIcon; + tTableCellView.textField.stringValue=tCrashLog.crashLogFilePath.lastPathComponent.stringByDeletingPathExtension; + tTableCellView.textField.lineBreakMode=NSLineBreakByTruncatingMiddle; + } tTableCellView.dateLabel.formatter=_crashLogDateFormatter; tTableCellView.dateLabel.objectValue=tCrashLog.dateTime; @@ -489,7 +565,7 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu NSString * tExceptionType=nil; CUICrashLogExceptionInformation * tExceptionInformation=nil; - if ([tCrashLog isKindOfClass:[CUICrashLog class]]==YES) + if ([tCrashLog isKindOfClass:CUICrashLog.class]==YES) { tExceptionInformation=((CUICrashLog *)tCrashLog).exceptionInformation; @@ -546,7 +622,7 @@ - (void)tableViewSelectionDidChange:(NSNotification *)inNotification { NSInteger tSelectedRow=_tableView.selectedRow; - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; // Stop observing @@ -588,7 +664,7 @@ - (void)crashLogsSourcesSelectionDidChange:(NSNotification *)inNotification { CUICrashLogsSourcesSelection * tSelection=inNotification.object; - if ([tSelection isKindOfClass:[CUICrashLogsSourcesSelection class]]==NO) + if ([tSelection isKindOfClass:CUICrashLogsSourcesSelection.class]==NO) return; CUICrashLogsSource * tFirstSource=tSelection.sources.allObjects.firstObject; @@ -596,7 +672,7 @@ - (void)crashLogsSourcesSelectionDidChange:(NSNotification *)inNotification if (tFirstSource==_source) return; - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter removeObserver:self name:CUICrashLogsSourceDidUpdateSourceNotification object:_source]; @@ -677,4 +753,11 @@ - (void)crashLogsSortTypeDidChange:(NSNotification *)inNotification [self refreshList]; } +- (void)showFileNamesDidChange:(NSNotification *)inNotification +{ + _showsFileNames=[CUIApplicationPreferences sharedPreferences].crashLogsShowFileNames; + + [self refreshList]; +} + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsMainViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsMainViewController.m index 85351f4..f5d6e94 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsMainViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsMainViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -29,9 +29,9 @@ typedef NS_ENUM(NSUInteger, CUISplitViewSubViewTag) { - CUISplitViewLeftViewTag=0, + CUISplitViewSidebarViewTag=0, CUISplitViewMiddleViewTag=1, - CUISplitViewRightViewTag=2, + CUISplitViewInspectorViewTag=2, }; @@ -40,12 +40,12 @@ typedef NS_ENUM(NSUInteger, CUISplitViewSubViewTag) NSString * const CUIDefaultsSidebarCollapsedKey=@"sidebar.collapsed"; -NSString * const CUIDefaultsRightViewWidthKey=@"rightView.width"; +NSString * const CUIDefaultsInspectorViewWidthKey=@"rightView.width"; -NSString * const CUIDefaultsRightViewCollapsedKey=@"rightView.collapsed"; +NSString * const CUIDefaultsInspectorViewCollapsedKey=@"rightView.collapsed"; -@interface CUICrashLogsMainViewController () +@interface CUICrashLogsMainViewController () { IBOutlet NSSplitView * _splitView; @@ -59,17 +59,17 @@ @interface CUICrashLogsMainViewController () CUIContentsViewController * _contentsViewController; - CUIRightViewController * _rightViewController; + CUIRightViewController * _inspectorViewController; } -- (void)updateNetKeyViews; +- (void)updateNextKeyViews; - (IBAction)showHideViews:(id)sender; //- (IBAction)switchPresentationMode:(NSMenuItem *)sender; -- (void)_splitView:(NSSplitView *)inSplitView resizeSubviewsWithSidebarWidth:(CGFloat)inSidebarWidth rightViewWidth:(CGFloat)inRightViewWidth; +- (void)_splitView:(NSSplitView *)inSplitView resizeSubviewsWithSidebarWidth:(CGFloat)inSidebarWidth inspectorViewWidth:(CGFloat)inInspectorViewWidth; @end @@ -85,13 +85,13 @@ - (instancetype)init _contentsViewController=[CUIContentsViewController new]; - _rightViewController=[CUIRightViewController new]; + _inspectorViewController=[CUIRightViewController new]; [self addChildViewController:_sidebarViewController]; [self addChildViewController:_contentsViewController]; - [self addChildViewController:_rightViewController]; + [self addChildViewController:_inspectorViewController]; } return self; @@ -99,7 +99,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - NSObject @@ -150,19 +150,35 @@ - (void)viewDidLoad { [super viewDidLoad]; - _rightViewController.view.frame=_rightView.bounds; + BOOL tIsLeftToRightLayout=(_splitView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight); - [_rightView addSubview:_rightViewController.view]; + NSView *tSidebarView; + NSView *tInspectorView; + + if (tIsLeftToRightLayout==YES) + { + tSidebarView=_leftView; + tInspectorView=_rightView; + } + else + { + tSidebarView=_rightView; + tInspectorView=_leftView; + } + + _inspectorViewController.view.frame=tInspectorView.bounds; + + [tInspectorView addSubview:_inspectorViewController.view]; _contentsViewController.view.frame=_middleView.bounds; [_middleView addSubview:_contentsViewController.view]; - _sidebarViewController.view.frame=_leftView.bounds; + _sidebarViewController.view.frame=tSidebarView.bounds; - [_leftView addSubview:_sidebarViewController.view]; + [tSidebarView addSubview:_sidebarViewController.view]; - [self updateNetKeyViews]; + [self updateNextKeyViews]; } - (void)viewDidAppear @@ -171,17 +187,28 @@ - (void)viewDidAppear // Restore SplitView divider position + BOOL tIsLeftToRightLayout=(_splitView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight); NSUserDefaults * tUserDefaults=[NSUserDefaults standardUserDefaults]; NSNumber * tNumber=[tUserDefaults objectForKey:CUIDefaultsSidebarCollapsedKey]; if ([tNumber boolValue]==YES) - [_splitView setPosition:[_splitView minPossiblePositionOfDividerAtIndex:0] ofDividerAtIndex:0]; + { + if (tIsLeftToRightLayout==YES) + [_splitView setPosition:[_splitView minPossiblePositionOfDividerAtIndex:0] ofDividerAtIndex:0]; + else + [_splitView setPosition:[_splitView maxPossiblePositionOfDividerAtIndex:1] ofDividerAtIndex:1]; + } - tNumber=[tUserDefaults objectForKey:CUIDefaultsRightViewCollapsedKey]; + tNumber=[tUserDefaults objectForKey:CUIDefaultsInspectorViewCollapsedKey]; if ([tNumber boolValue]==YES) - [_splitView setPosition:[_splitView maxPossiblePositionOfDividerAtIndex:1] ofDividerAtIndex:1]; + { + if (tIsLeftToRightLayout==NO) + [_splitView setPosition:[_splitView minPossiblePositionOfDividerAtIndex:0] ofDividerAtIndex:0]; + else + [_splitView setPosition:[_splitView maxPossiblePositionOfDividerAtIndex:1] ofDividerAtIndex:1]; + } CGFloat tSidebarWidth=CUISidebarMinimumWidth; @@ -190,23 +217,33 @@ - (void)viewDidAppear if (tNumber!=nil) tSidebarWidth=[tNumber doubleValue]; - CGFloat tRightViewWidth=CUIInspectorMinimumWidth; + CGFloat tInspectorViewWidth=CUIInspectorMinimumWidth; - tNumber=[tUserDefaults objectForKey:CUIDefaultsRightViewWidthKey]; + tNumber=[tUserDefaults objectForKey:CUIDefaultsInspectorViewWidthKey]; if (tNumber!=nil) - tRightViewWidth=[tNumber doubleValue]; + tInspectorViewWidth=[tNumber doubleValue]; - [self _splitView:_splitView resizeSubviewsWithSidebarWidth:tSidebarWidth rightViewWidth:tRightViewWidth]; + [self _splitView:_splitView resizeSubviewsWithSidebarWidth:tSidebarWidth inspectorViewWidth:tInspectorViewWidth]; } - (void)viewWillDisappear { // Save SplitView divider position - NSArray * tSubviews=_splitView.subviews; + NSView * tSidebarView=nil; + NSView * tInspectorView=nil; - NSView * tSidebarView=tSubviews[0]; + if (_splitView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + tSidebarView=_leftView; + tInspectorView=_rightView; + } + else + { + tSidebarView=_rightView; + tInspectorView=_leftView; + } NSUserDefaults * tUserDefaults=[NSUserDefaults standardUserDefaults]; @@ -214,16 +251,14 @@ - (void)viewWillDisappear [tUserDefaults setBool:[_splitView isSubviewCollapsed:tSidebarView] forKey:CUIDefaultsSidebarCollapsedKey]; - NSView * tRightView=tSubviews[2]; + [tUserDefaults setObject:@(NSWidth(tInspectorView.frame)) forKey:CUIDefaultsInspectorViewWidthKey]; - [tUserDefaults setObject:@(NSWidth(tRightView.frame)) forKey:CUIDefaultsRightViewWidthKey]; - - [tUserDefaults setBool:[_splitView isSubviewCollapsed:tRightView] forKey:CUIDefaultsRightViewCollapsedKey]; + [tUserDefaults setBool:[_splitView isSubviewCollapsed:tInspectorView] forKey:CUIDefaultsInspectorViewCollapsedKey]; } #pragma mark - -- (void)updateNetKeyViews +- (void)updateNextKeyViews { NSView * tContentsFirstKeyView=_contentsViewController.firstKeyView; @@ -263,11 +298,25 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem if (tAction==@selector(showHideViews:)==YES) { + NSView * sidebarView=nil; + NSView * inspectorView=nil; + + if (_splitView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + sidebarView=_leftView; + inspectorView=_rightView; + } + else + { + sidebarView=_rightView; + inspectorView=_leftView; + } + switch(inMenuItem.tag) { - case CUISplitViewLeftViewTag: + case CUISplitViewSidebarViewTag: - inMenuItem.title=([_splitView isSubviewCollapsed:_leftView]==YES) ? NSLocalizedString(@"Show Sidebar", @"") : NSLocalizedString(@"Hide Sidebar", @""); + inMenuItem.title=([_splitView isSubviewCollapsed:sidebarView]==YES) ? NSLocalizedString(@"Show Sidebar", @"") : NSLocalizedString(@"Hide Sidebar", @""); break; @@ -283,9 +332,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)inMenuItem break; - case CUISplitViewRightViewTag: + case CUISplitViewInspectorViewTag: - inMenuItem.title=([_splitView isSubviewCollapsed:_rightView]==YES) ? NSLocalizedString(@"Show Inspector", @"") : NSLocalizedString(@"Hide Inspector", @""); + inMenuItem.title=([_splitView isSubviewCollapsed:inspectorView]==YES) ? NSLocalizedString(@"Show Inspector", @"") : NSLocalizedString(@"Hide Inspector", @""); break; } @@ -303,15 +352,15 @@ - (IBAction)showHideViews:(id)sender if ([sender isKindOfClass:[NSSegmentedControl class]]==YES) { - tSwitchTag=CUISplitViewMiddleViewTag; + tSwitchTag=1; NSSegmentedControl * tSegmentedControl=(NSSegmentedControl *)sender; - if ([tSegmentedControl isSelectedForSegment:CUISplitViewLeftViewTag]==tIsLeftViewCollapsed) - tSwitchTag=CUISplitViewLeftViewTag; + if ([tSegmentedControl isSelectedForSegment:0]==tIsLeftViewCollapsed) + tSwitchTag=0; - if ([tSegmentedControl isSelectedForSegment:CUISplitViewRightViewTag]==tIsRightViewCollapsed) - tSwitchTag=CUISplitViewRightViewTag; + if ([tSegmentedControl isSelectedForSegment:2]==tIsRightViewCollapsed) + tSwitchTag=2; } else if ([sender isKindOfClass:[NSMenuItem class]]==YES) { @@ -322,7 +371,7 @@ - (IBAction)showHideViews:(id)sender switch(tSwitchTag) { - case CUISplitViewLeftViewTag: + case 0: if (tIsLeftViewCollapsed==NO) { @@ -342,13 +391,13 @@ - (IBAction)showHideViews:(id)sender break; - case CUISplitViewMiddleViewTag: + case 1: [_contentsViewController showHideBottomView:self]; break; - case CUISplitViewRightViewTag: + case 2: if (tIsRightViewCollapsed==NO) { @@ -379,61 +428,109 @@ - (IBAction)showHideViews:(id)sender #pragma mark - NSSplitViewDelegate -- (void)_splitView:(NSSplitView *)inSplitView resizeSubviewsWithSidebarWidth:(CGFloat)inSidebarWidth rightViewWidth:(CGFloat)inRightViewWidth +- (void)_splitView:(NSSplitView *)inSplitView resizeSubviewsWithSidebarWidth:(CGFloat)inSidebarWidth inspectorViewWidth:(CGFloat)inInspectorViewWidth { + BOOL tIsLeftToRightLayout=(_splitView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight); + + NSView * tSidebarView=nil; + NSView * tInspectorView=nil; + + if (tIsLeftToRightLayout==YES) + { + tSidebarView=_leftView; + tInspectorView=_rightView; + } + else + { + tSidebarView=_rightView; + tInspectorView=_leftView; + } + NSRect tSplitViewFrame=inSplitView.frame; - NSRect tLeftFrame=_leftView.frame; + NSRect tSidebarFrame=tSidebarView.frame; - tLeftFrame.size.width=inSidebarWidth; + tSidebarFrame.size.width=inSidebarWidth; - NSRect tMiddleFrame=_middleView.frame; - NSRect tRightFrame=_rightView.frame; + NSRect tContentsFrame=_middleView.frame; + NSRect tInspectorFrame=tInspectorView.frame; - tRightFrame.size.width=inRightViewWidth; + tInspectorFrame.size.width=inInspectorViewWidth; - CGFloat tLeftWidth=([inSplitView isSubviewCollapsed:_leftView]==NO) ? NSWidth(tLeftFrame) : 0.0; - CGFloat tRightWidth=([inSplitView isSubviewCollapsed:_rightView]==NO) ? NSWidth(tRightFrame) : 0.0; - tMiddleFrame.size.width=NSWidth(tSplitViewFrame)-tLeftWidth-tRightWidth-2*inSplitView.dividerThickness; + CGFloat tSidebarWidth=([inSplitView isSubviewCollapsed:tSidebarView]==NO) ? NSWidth(tSidebarFrame) : 0.0; + CGFloat tInspectorWidth=([inSplitView isSubviewCollapsed:tInspectorView]==NO) ? NSWidth(tInspectorFrame) : 0.0; - if (tMiddleFrame.size.width - + @@ -57,7 +57,7 @@ - + diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.h b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.h index 0de57ca..5f7f03c 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2021, Stephane Sudre + Copyright (c) 2021-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.m index 5fd31e4..206a295 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorPanel.m @@ -1,10 +1,15 @@ -// -// CUICrashLogsReadErrorPanel.m -// Unexpectedly -// -// Created by stephane on 10/06/2021. -// Copyright © 2021 Acme, Inc. All rights reserved. -// +/* + Copyright (c) 2021-2024, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #import "CUICrashLogsOpenErrorPanel.h" @@ -12,7 +17,7 @@ #import "NSTableView+Selection.h" -@interface CUICrashLogsOpenErrorWindowController : NSWindowController +@interface CUICrashLogsOpenErrorWindowController : NSWindowController { IBOutlet NSTextField * _messageLabel; @@ -44,6 +49,12 @@ - (void)windowDidLoad { [super windowDidLoad]; + NSTableColumn * tTableColumn=[_tableView tableColumnWithIdentifier:@"file"]; + tTableColumn.headerCell.title=NSLocalizedString(@"Name",@""); + + tTableColumn=[_tableView tableColumnWithIdentifier:@"reason"]; + tTableColumn.headerCell.title=NSLocalizedString(@"Reason",@""); + NSRect tButtonFrame=_defaultButton.frame; _defaultButton.title=NSLocalizedString(@"OK",@""); @@ -91,14 +102,14 @@ - (void)updateUI case 1: - tMessageString=NSLocalizedString(@"An error occurred when opening the file.", @""); + tMessageString=NSLocalizedString(@"An error occurred while opening the file.", @""); tInformativeString=NSLocalizedString(@"The file can't be opened for the following reason:", @""); break; default: - tMessageString=NSLocalizedString(@"An error occurred when opening some files.", @""); + tMessageString=NSLocalizedString(@"An error occurred while opening some files.", @""); tInformativeString=NSLocalizedString(@"These files can't be opened for the following reasons:", @""); break; @@ -153,7 +164,6 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu { CUICrashLogsOpenErrorRecord * tRecord=_errors[inRow]; - NSString * tTableColumnIdentifier=inTableColumn.identifier; NSTableCellView * tTableCellView=[inTableView makeViewWithIdentifier:tTableColumnIdentifier owner:self]; @@ -222,13 +232,15 @@ - (void)_sheetDidEndSelector:(CUICrashLogsOpenErrorPanel *)inPanel returnCode:(N [inPanel orderOut:self]; } -- (void)beginSheetModalForWindow:(NSWindow *)inWindow completionHandler:(void (^)(NSModalResponse response))handler +- (void)beginSheetModalForWindow:(NSWindow *)inWindow completionHandler:(void (^)(NSModalResponse))handler { - [NSApp beginSheet:self - modalForWindow:inWindow - modalDelegate:self - didEndSelector:@selector(_sheetDidEndSelector:returnCode:contextInfo:) - contextInfo:(__bridge_retained void*)[handler copy]]; + [inWindow beginSheet:self completionHandler:^(NSModalResponse bResponse) { + + if (handler!=nil) + handler(bResponse); + + self->retainedWindowController=nil; + }]; } - (NSModalResponse)runModal diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorRecord.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorRecord.m index eb90dc1..3bdaa76 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorRecord.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorRecord.m @@ -12,6 +12,7 @@ */ #import "CUICrashLogsOpenErrorRecord.h" +#import "IPSError.h" @implementation CUICrashLogsOpenErrorRecord @@ -22,7 +23,20 @@ - (NSString *)description if (tError==nil) return @"-"; - if ([tError.domain isEqualToString:CUICrashLogDomain]==YES) + if ([tError.domain isEqualToString:IPSErrorDomain]==YES) + { + switch(tError.code) + { + case IPSUnsupportedBugTypeError: + + return @"The format of this file is invalid or unsupported."; + + default: + + break; + } + } + else if ([tError.domain isEqualToString:CUICrashLogDomain]==YES) { switch(tError.code) { diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorWindowController.xib b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorWindowController.xib index d3ea7a6..4c6b389 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorWindowController.xib +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsOpenErrorWindowController.xib @@ -154,7 +154,7 @@ - + diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.h b/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.h index 58683f5..e84fd1c 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,6 +15,14 @@ #import "CUICrashLog.h" +extern NSString * const CUIRetiredPathComponent; + +typedef NS_ENUM(NSUInteger, CUICrashLogsProviderCollectOptions) +{ + CUICrashLogsProviderCollectRetired = 1 +}; + + @interface CUICrashLogsProvider : NSObject + (CUICrashLogsProvider *)defaultProvider; @@ -27,4 +35,6 @@ - (NSArray *)crashLogsForDirectory:(NSString *)inDirectoryPath error:(NSError **)outError; +- (NSArray *)crashLogsForDirectory:(NSString *)inDirectoryPath options:(CUICrashLogsProviderCollectOptions)inOptions error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.m index a8c42d5..a54fae0 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsProvider.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,6 +15,14 @@ #import "NSArray+WBExtensions.h" +NSString * const CUIRetiredPathComponent=@"Retired"; + +@interface CUICrashLogsProvider () + +- (NSArray *)crashLogsForDirectory:(NSString *)inDirectoryPath options:(CUICrashLogsProviderCollectOptions)options error:(NSError **)outError; + +@end + @implementation CUICrashLogsProvider + (CUICrashLogsProvider *)defaultProvider @@ -34,19 +42,19 @@ - (NSArray *)currentUserCrashLogs { NSString * tDirectoryPath=[@"~/Library/Logs/DiagnosticReports/" stringByExpandingTildeInPath]; - return [self crashLogsForDirectory:tDirectoryPath error:NULL]; + return [self crashLogsForDirectory:tDirectoryPath options:CUICrashLogsProviderCollectRetired error:NULL]; } - (NSArray *)systemCrashLogs { NSString * tDirectoryPath=@"/Library/Logs/DiagnosticReports/"; - return [self crashLogsForDirectory:tDirectoryPath error:NULL]; + return [self crashLogsForDirectory:tDirectoryPath options:CUICrashLogsProviderCollectRetired error:NULL]; } - (id)crashLogWithContentsOfFile:(NSString *)inPath error:(NSError **)outError { - if ([inPath isKindOfClass:[NSString class]]==NO) + if ([inPath isKindOfClass:NSString.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -54,7 +62,10 @@ - (id)crashLogWithContentsOfFile:(NSString *)inPath error:(NSError **)outError return nil; } - if ([inPath.pathExtension caseInsensitiveCompare:@"crash"]!=NSOrderedSame) + NSString * tExtension=inPath.pathExtension; + + if ([tExtension caseInsensitiveCompare:@"crash"]!=NSOrderedSame && + [tExtension caseInsensitiveCompare:@"ips"]!=NSOrderedSame) return nil; NSError * tError=nil; @@ -63,6 +74,8 @@ - (id)crashLogWithContentsOfFile:(NSString *)inPath error:(NSError **)outError if (tCrashLog==nil) { + BOOL tryAgainIfRawSucceed=NO; + if ([tError.domain isEqualToString:NSCocoaErrorDomain]==YES) { switch(tError.code) @@ -75,7 +88,24 @@ - (id)crashLogWithContentsOfFile:(NSString *)inPath error:(NSError **)outError return nil; - default: + case NSFileReadUnknownError: + { + NSError * tUnderlyingError=tError.userInfo[NSUnderlyingErrorKey]; + + if ([tUnderlyingError.domain isEqualToString:NSPOSIXErrorDomain]==YES && + tUnderlyingError.code==EINTR) + { + tryAgainIfRawSucceed=YES; + } + } + + case NSPropertyListReadCorruptError: // Invalid json file. + if (outError!=nil) + *outError=tError; + + return nil; + + default: break; } @@ -98,12 +128,17 @@ - (id)crashLogWithContentsOfFile:(NSString *)inPath error:(NSError **)outError } } - NSLog(@"Error when parsing report file \"%@\", will try to parse it as raw report",inPath); + NSLog(@"Error when parsing report file \"%@\", will try to parse it as raw report: %@",inPath,tError.description); tCrashLog=[[CUIRawCrashLog alloc] initWithContentsOfFile:inPath error:&tError]; - if (outError!=nil) - *outError=tError; + if (tCrashLog!=nil) + { + id newCrashLogAttempt=[[CUICrashLog alloc] initWithContentsOfFile:inPath error:&tError]; + + if (newCrashLogAttempt!=nil) + tCrashLog=newCrashLogAttempt; + } } return tCrashLog; @@ -111,7 +146,12 @@ - (id)crashLogWithContentsOfFile:(NSString *)inPath error:(NSError **)outError - (NSArray *)crashLogsForDirectory:(NSString *)inDirectoryPath error:(NSError **)outError { - if ([inDirectoryPath isKindOfClass:[NSString class]]==NO) + return [self crashLogsForDirectory:inDirectoryPath options:0 error:outError]; +} + +- (NSArray *)crashLogsForDirectory:(NSString *)inDirectoryPath options:(CUICrashLogsProviderCollectOptions)inOptions error:(NSError **)outError +{ + if ([inDirectoryPath isKindOfClass:NSString.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -120,10 +160,21 @@ - (NSArray *)crashLogsForDirectory:(NSString *)inDirectoryPath error:(NSError ** } NSArray * tArray=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:inDirectoryPath error:outError]; + + if ((inOptions & CUICrashLogsProviderCollectRetired) == CUICrashLogsProviderCollectRetired && [tArray containsObject:CUIRetiredPathComponent]==YES) + { + NSArray * tRetiredArray=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[inDirectoryPath stringByAppendingPathComponent:CUIRetiredPathComponent] error:NULL]; + + if (tRetiredArray.count>0) + tArray = [tArray arrayByAddingObjectsFromArray:tRetiredArray]; + } NSArray * tCrashLogsArray=[tArray WB_arrayByMappingObjectsLenientlyUsingBlock:^id(NSString * bComponent, NSUInteger bIndex) { - if ([bComponent.pathExtension caseInsensitiveCompare:@"crash"]!=NSOrderedSame) + NSString * tComponentExtension=bComponent.pathExtension; + + if ([tComponentExtension caseInsensitiveCompare:@"crash"]!=NSOrderedSame && + [tComponentExtension caseInsensitiveCompare:@"ips"]!=NSOrderedSame) return nil; NSString * tFilePath=[inDirectoryPath stringByAppendingPathComponent:bComponent]; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSelection.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSelection.m index f905103..b6508ab 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSelection.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSelection.m @@ -84,7 +84,7 @@ - (void)setSource:(CUICrashLogsSource *)inSource crashLogs:(NSArray *)inCrashLog _source=inSource; _crashLogs=inCrashLogs; - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogsSelectionDidChangeNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogsSelectionDidChangeNotification object:self]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSource.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSource.m index 984f3dc..3d84a6a 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSource.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSource.m @@ -44,7 +44,7 @@ - (instancetype)init - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation { - if ([inRepresentation isKindOfClass:[NSDictionary class]]==NO) + if ([inRepresentation isKindOfClass:NSDictionary.class]==NO) return nil; self=[super init]; @@ -53,14 +53,14 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation { NSString * tString=inRepresentation[CUICrashLogsSourceNameKey]; - if (tString!=nil && [tString isKindOfClass:[NSString class]]==NO) + if (tString!=nil && [tString isKindOfClass:NSString.class]==NO) return nil; _name=(tString!=nil) ? [tString copy] : @""; tString=inRepresentation[CUICrashLogsSourceDescription]; - if (tString!=nil && [tString isKindOfClass:[NSString class]]==NO) + if (tString!=nil && [tString isKindOfClass:NSString.class]==NO) return nil; _sourceDescription=(tString!=nil) ? [tString copy] : @""; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceAll.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceAll.m index 74c101f..5178aa0 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceAll.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceAll.m @@ -56,7 +56,7 @@ - (instancetype)init // Register for notifications - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter addObserver:self selector:@selector(crashLogsSourceDidAddSources:) name:CUICrashLogsSourceDidAddSourcesNotification object:nil]; [tNotificationCenter addObserver:self selector:@selector(crashLogsSourceDidUpdateSource:) name:CUICrashLogsSourceDidUpdateSourceNotification object:nil]; @@ -68,7 +68,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -114,7 +114,7 @@ - (void)refresh { _crashLogs=nil; - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogsSourceDidUpdateSourceNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogsSourceDidUpdateSourceNotification object:self]; } diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.h b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.h index 5f35fcc..9271d9b 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,4 +15,6 @@ @interface CUICrashLogsSourceDirectory : CUICrashLogsSourceFileSystemItem +- (instancetype)initWithContentsOfFileSystemItemAtPath:(NSString *)inPath collectRetired:(BOOL)inCollectRetired error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.m index 44fd798..cda8882 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceDirectory.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025 Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -28,6 +28,8 @@ @interface CUICrashLogsSourceDirectory () NSArray * _crashLogs; FSEventStreamRef _eventStreamRef; + + BOOL _collectRetired; } - (void)handleFileSystemEventIDs:(const FSEventStreamEventId[])inEventIDs paths:(NSArray *)inEventsPaths flags:(const FSEventStreamEventFlags[])inFlags; @@ -38,13 +40,23 @@ @implementation CUICrashLogsSourceDirectory - (BOOL)initCommonWithError:(NSError **)outError { - NSArray * tCrashLogs=[[CUICrashLogsProvider defaultProvider] crashLogsForDirectory:self.path error:outError]; + NSArray * tCrashLogs=[[CUICrashLogsProvider defaultProvider] crashLogsForDirectory:self.path options:(_collectRetired==YES) ? CUICrashLogsProviderCollectRetired : 0 error:outError]; if (tCrashLogs==nil) return NO; _crashLogs=tCrashLogs; + NSArray * tMonitoredPaths=nil; + + if (_collectRetired == YES) + { + tMonitoredPaths=@[self.path, [self.path stringByAppendingPathComponent:CUIRetiredPathComponent]]; + } + else + { + tMonitoredPaths=@[self.path]; + } FSEventStreamContext context; context.info = (__bridge void *)self; // !!! @@ -56,7 +68,7 @@ - (BOOL)initCommonWithError:(NSError **)outError CFAbsoluteTime latency = 3.0; /* Latency in seconds */ /* Create the stream, passing in a callback */ - _eventStreamRef = FSEventStreamCreate(kCFAllocatorDefault,&mycallback,&context,(__bridge CFArrayRef)@[self.path],kFSEventStreamEventIdSinceNow,latency,kFSEventStreamCreateFlagWatchRoot+kFSEventStreamCreateFlagUseCFTypes); + _eventStreamRef = FSEventStreamCreate(kCFAllocatorDefault,&mycallback,&context,(__bridge CFArrayRef)tMonitoredPaths,kFSEventStreamEventIdSinceNow,latency,kFSEventStreamCreateFlagWatchRoot+kFSEventStreamCreateFlagUseCFTypes); FSEventStreamScheduleWithRunLoop(_eventStreamRef, CFRunLoopGetCurrent(),kCFRunLoopDefaultMode); @@ -79,11 +91,26 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation } - (instancetype)initWithContentsOfFileSystemItemAtPath:(NSString *)inPath error:(NSError **)outError +{ + self = [super initWithContentsOfFileSystemItemAtPath:inPath error:outError]; + + if (self!=nil) + { + if ([self initCommonWithError:NULL]==NO) + return nil; + } + + return self; +} + +- (instancetype)initWithContentsOfFileSystemItemAtPath:(NSString *)inPath collectRetired:(BOOL)inCollectRetired error:(NSError **)outError { self=[super initWithContentsOfFileSystemItemAtPath:inPath error:outError]; if (self!=nil) { + _collectRetired=inCollectRetired; + if ([self initCommonWithError:outError]==NO) return nil; } @@ -159,13 +186,13 @@ - (void)handleFileSystemEventIDs:(const FSEventStreamEventId[])inEventIDs paths: return; }*/ - _crashLogs=nil; + _crashLogs=[[CUICrashLogsProvider defaultProvider] crashLogsForDirectory:self.path options:(_collectRetired==YES) ? CUICrashLogsProviderCollectRetired : 0 error:NULL]; } else { // Refresh the list of crash logs - NSArray * tCrashLogs=[[CUICrashLogsProvider defaultProvider] crashLogsForDirectory:self.path error:NULL]; + NSArray * tCrashLogs=[[CUICrashLogsProvider defaultProvider] crashLogsForDirectory:self.path options:(_collectRetired==YES) ? CUICrashLogsProviderCollectRetired : 0 error:NULL]; if (tCrashLogs==nil) return; @@ -173,7 +200,7 @@ - (void)handleFileSystemEventIDs:(const FSEventStreamEventId[])inEventIDs paths: _crashLogs=tCrashLogs; } - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogsSourceDidUpdateSourceNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogsSourceDidUpdateSourceNotification object:self]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceFileSystemItem.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceFileSystemItem.m index 0592ea6..6faeb3f 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceFileSystemItem.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceFileSystemItem.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -31,7 +31,7 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation { NSString * tString=inRepresentation[CUICrashLogSourcePathKey]; - if ([tString isKindOfClass:[NSString class]]==NO) + if ([tString isKindOfClass:NSString.class]==NO) return nil; if (tString.length==0) @@ -45,7 +45,7 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation - (instancetype)initWithContentsOfFileSystemItemAtPath:(NSString *)inPath error:(NSError **)outError { - if ([inPath isKindOfClass:[NSString class]]==NO) + if ([inPath isKindOfClass:NSString.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmart.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmart.m index e141a51..92fccd7 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmart.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmart.m @@ -16,6 +16,10 @@ #import "CUICrashLogsSourceAll.h" #define SMARTSOURCE_VERSION_1 1 +#define SMARTSOURCE_VERSION_2 2 + +#define SMARTSOURCE_CURRENTVERSION SMARTSOURCE_VERSION_2 +#define SMARTSOURCE_MAXIMUMSUPPORTEDVERSION SMARTSOURCE_VERSION_2 NSString * const CUICrashLogsSourcesSmartVersionKey=@"version"; @@ -40,11 +44,11 @@ - (instancetype)init if (self!=nil) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sourceAllDidUpdateSource:) name:CUICrashLogsSourceDidUpdateSourceNotification object:[CUICrashLogsSourceAll crashLogsSourceAll]]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(sourceAllDidUpdateSource:) name:CUICrashLogsSourceDidUpdateSourceNotification object:[CUICrashLogsSourceAll crashLogsSourceAll]]; self.name=NSLocalizedString(@"Untitled source", @""); - _version=SMARTSOURCE_VERSION_1; + _version=SMARTSOURCE_CURRENTVERSION; _predicate=[NSPredicate predicateWithFormat:@"processName = \"MyApplication\""]; } @@ -58,13 +62,13 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation if (self!=nil) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sourceAllDidUpdateSource:) name:CUICrashLogsSourceDidUpdateSourceNotification object:[CUICrashLogsSourceAll crashLogsSourceAll]]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(sourceAllDidUpdateSource:) name:CUICrashLogsSourceDidUpdateSourceNotification object:[CUICrashLogsSourceAll crashLogsSourceAll]]; NSNumber * tNumber=inRepresentation[CUICrashLogsSourcesSmartVersionKey]; if (tNumber!=nil) { - if ([tNumber isKindOfClass:[NSNumber class]]==NO) + if ([tNumber isKindOfClass:NSNumber.class]==NO) return nil; _version=tNumber.unsignedIntegerValue; @@ -74,9 +78,16 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation _version=SMARTSOURCE_VERSION_1; } + if (_version>SMARTSOURCE_MAXIMUMSUPPORTEDVERSION) + { + NSLog(@"Smart Source object version (%lu) is not supported by this version of Unexpectedly",(unsigned long)_version); + + return nil; + } + NSString * tString=inRepresentation[CUICrashLogsSourcesSmartPredicateKey]; - if ([tString isKindOfClass:[NSString class]]==NO) + if ([tString isKindOfClass:NSString.class]==NO) return nil; self.predicate=[NSPredicate predicateWithFormat:tString]; @@ -87,7 +98,7 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -130,7 +141,7 @@ - (void)sourceAllDidUpdateSource:(NSNotification *)inNotification { _filteredCrashLogs=[[CUICrashLogsSourceAll crashLogsSourceAll].crashLogs filteredArrayUsingPredicate:self.predicate]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogsSourceDidUpdateSourceNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogsSourceDidUpdateSourceNotification object:self]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmartEditorPanel.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmartEditorPanel.m index d4147e7..abcc8fe 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmartEditorPanel.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceSmartEditorPanel.m @@ -52,7 +52,9 @@ - (void)windowDidLoad NSArray *keyPaths = @[[NSExpression expressionForKeyPath:@"processName"], [NSExpression expressionForKeyPath:@"header.bundleIdentifier"], [NSExpression expressionForKeyPath:@"header.executablePath"], - [NSExpression expressionForKeyPath:@"exceptionInformation.crashedThreadName"]]; + [NSExpression expressionForKeyPath:@"header.executableVersion"], + [NSExpression expressionForKeyPath:@"exceptionInformation.crashedThreadName"], + [NSExpression expressionForKeyPath:@"header.operatingSystemVersion.stringValue"]]; NSPredicateEditorRowTemplate * tRowTemplate1 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions:keyPaths rightExpressionAttributeType:NSStringAttributeType @@ -97,6 +99,8 @@ - (void)windowDidLoad options:(NSCaseInsensitivePredicateOption | NSDiacriticInsensitivePredicateOption)]; + // Row Template 4 + NSPredicateEditorRowTemplate * tRowTemplate4 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions:@[[NSExpression expressionForKeyPath:@"exceptionSignal"]] rightExpressions:@[[NSExpression expressionForConstantValue:@"SIGABRT"], [NSExpression expressionForConstantValue:@"SIGBUS"], @@ -112,9 +116,24 @@ - (void)windowDidLoad options:(NSCaseInsensitivePredicateOption | NSDiacriticInsensitivePredicateOption)]; - // Row Template 4 + // Row Template 5 - NSPredicateEditorRowTemplate * tRowTemplate5 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions:@[[NSExpression expressionForKeyPath:@"reportSourceTypeNumber"]] + keyPaths = @[[NSExpression expressionForKeyPath:@"crashLogFileName"]]; + + NSPredicateEditorRowTemplate * tRowTemplate5 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions:keyPaths + rightExpressionAttributeType:NSStringAttributeType + modifier:NSDirectPredicateModifier + operators:@[@(NSEqualToPredicateOperatorType), + @(NSNotEqualToPredicateOperatorType), + @(NSBeginsWithPredicateOperatorType), + @(NSEndsWithPredicateOperatorType), + @(NSContainsPredicateOperatorType)] + options:(NSCaseInsensitivePredicateOption | + NSDiacriticInsensitivePredicateOption)]; + + // Row Template 6 + + NSPredicateEditorRowTemplate * tRowTemplate6 = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions:@[[NSExpression expressionForKeyPath:@"reportSourceTypeNumber"]] rightExpressions:@[[NSExpression expressionForConstantValue:@(CUICrashLogReportSourceTypeUser)], [NSExpression expressionForConstantValue:@(CUICrashLogReportSourceTypeSystem)], [NSExpression expressionForConstantValue:@(CUICrashLogReportSourceTypeOther)]] @@ -124,12 +143,14 @@ - (void)windowDidLoad NSDiacriticInsensitivePredicateOption)]; + + NSArray *compoundTypes = @[@(NSAndPredicateType), @(NSOrPredicateType)]; NSPredicateEditorRowTemplate * tRowTemplateCompound = [[NSPredicateEditorRowTemplate alloc] initWithCompoundTypes:compoundTypes]; - _predicatorEditor.rowTemplates=@[tRowTemplate1, tRowTemplate2,tRowTemplate3,tRowTemplate4,tRowTemplate5,tRowTemplateCompound]; + _predicatorEditor.rowTemplates=@[tRowTemplate1, tRowTemplate2,tRowTemplate3,tRowTemplate4,tRowTemplate5,tRowTemplate6,tRowTemplateCompound]; // Default button @@ -309,13 +330,15 @@ - (void)_sheetDidEndSelector:(CUICrashLogsSourceSmartEditorPanel *)inPanel retur [inPanel orderOut:self]; } -- (void)beginSheetModalForWindow:(NSWindow *)inWindow completionHandler:(void (^)(NSModalResponse response))handler +- (void)beginSheetModalForWindow:(NSWindow *)inWindow completionHandler:(void (^)(NSModalResponse bResponse))handler { - [NSApp beginSheet:self - modalForWindow:inWindow - modalDelegate:self - didEndSelector:@selector(_sheetDidEndSelector:returnCode:contextInfo:) - contextInfo:(__bridge_retained void*)[handler copy]]; + [inWindow beginSheet:self completionHandler:^(NSModalResponse bResponse) { + + if (handler!=nil) + handler(bResponse); + + self->retainedWindowController=nil; + }]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceStandardDirectory.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceStandardDirectory.m index 499bfec..588597e 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceStandardDirectory.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceStandardDirectory.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -29,7 +29,7 @@ + (CUICrashLogsSourceStandardDirectory *)sourceDiagnosticReportsInDomain:(NSSear NSString * tPath=[tArray.firstObject stringByAppendingPathComponent:@"Logs/DiagnosticReports"]; - CUICrashLogsSourceStandardDirectory * tSource=[[CUICrashLogsSourceStandardDirectory alloc] initWithContentsOfFileSystemItemAtPath:tPath error:outError]; + CUICrashLogsSourceStandardDirectory * tSource=[[CUICrashLogsSourceStandardDirectory alloc] initWithContentsOfFileSystemItemAtPath:tPath collectRetired:YES error:outError]; if (tSource!=nil) { diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceToday+UI.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceToday+UI.m index db17309..5dfc40a 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceToday+UI.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourceToday+UI.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,7 +21,7 @@ - (NSImage *)icon static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - sIcon=[[NSImage alloc] initWithContentsOfFile:@"/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/SidebarRecents.icns"]; + sIcon=[NSImage imageNamed:@"sidebar_recents_Template"]; sIcon.template=YES; }); diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.h b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.h index 82260f0..003853d 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.h +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -35,5 +35,7 @@ extern NSString * const CUICrashLogsSourcesManagerSourcesDidChangeNotification; - (void)removeSources:(NSArray *)inSources; +- (void)sortCustomSourcesByName; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.m index 6ebc5d2..a964d6f 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesManager.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -30,7 +30,7 @@ @interface CUICrashLogsSourcesManager () { - NSMutableArray * _sources; + NSMutableArray * _sources; NSUInteger _customSourcesCount; } @@ -119,7 +119,7 @@ - (instancetype)init NSNumber * tNumber=bRepresentation[CUICrashLogsSourceTypeKey]; - if ([tNumber isKindOfClass:[NSNumber class]]==NO) + if ([tNumber isKindOfClass:NSNumber.class]==NO) return nil; CUICrashLogsSourceType tType=[tNumber unsignedIntegerValue]; @@ -157,7 +157,7 @@ - (instancetype)init [tMutableArray addObjectsFromArray:tCustomSources]; } - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogsSourceDidAddSourcesNotification object:tMutableArray]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogsSourceDidAddSourcesNotification object:tMutableArray]; } return self; @@ -236,7 +236,7 @@ - (void)addSources:(NSArray *)inSources _customSourcesCount+=tPossibleSources.count; - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter postNotificationName:CUICrashLogsSourceDidAddSourcesNotification object:tPossibleSources]; @@ -283,7 +283,7 @@ - (void)removeSources:(NSArray *)inSources if (_customSourcesCount==0) [_sources removeObjectIdenticalTo:[CUICrashLogsSourceSeparator separator]]; - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter postNotificationName:CUICrashLogsSourceDidRemoveSourcesNotification object:tPossibleSources]; @@ -293,4 +293,26 @@ - (void)removeSources:(NSArray *)inSources } } +- (void)sortCustomSourcesByName +{ + NSRange tCustomSourcesRange=NSMakeRange(5, _customSourcesCount); + + NSMutableArray * tSortableArray=[[_sources objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tCustomSourcesRange]] mutableCopy]; + + [tSortableArray sortUsingComparator:^NSComparisonResult(CUICrashLogsSource * bSource1, CUICrashLogsSource * bSource2) { + + return [bSource1.name caseInsensitiveCompare:bSource2.name]; + }]; + + [_sources removeObjectsInRange:tCustomSourcesRange]; + + [_sources addObjectsFromArray:tSortableArray]; + + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; + + [tNotificationCenter postNotificationName:CUICrashLogsSourcesManagerSourcesDidChangeNotification object:self]; + + [self synchronizeDefaults]; +} + @end diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesSelection.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesSelection.m index cb2393f..e0a2a16 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesSelection.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesSelection.m @@ -40,7 +40,7 @@ - (void)setSources:(NSSet *)inSources _sources=inSources; - [[NSNotificationCenter defaultCenter] postNotificationName:CUICrashLogsSourcesSelectionDidChangeNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUICrashLogsSourcesSelectionDidChangeNotification object:self]; } - (NSArray *)crashLogs diff --git a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesViewController.m b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesViewController.m index a16cb2a..c65de30 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashLogsSourcesViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -41,7 +41,7 @@ NSString * const CUICrashLogsSourcesInternalPboardType=@"fr.whitebox.unexpectedly.sources.internal.array"; -@interface CUICrashLogsSourcesViewController () +@interface CUICrashLogsSourcesViewController () { IBOutlet NSTableView * _tableView; @@ -54,6 +54,10 @@ @interface CUICrashLogsSourcesViewController () =1); + } + return YES; } @@ -341,8 +389,26 @@ - (IBAction)CUI_MENUACTION_addSource:(id)sender NSMutableArray * tOpenErrors=[NSMutableArray array]; + CUICrashLogsSourceAll * tSourcesAll=[CUICrashLogsSourceAll crashLogsSourceAll]; + + _openPanelExistingSingleFiles=[NSSet setWithArray:[tSourcesAll.crashLogs WB_arrayByMappingObjectsLenientlyUsingBlock:^id(CUICrashLog *bCrashLog, NSUInteger bIndex) { + + return bCrashLog.crashLogFilePath; + }]]; + + _openPanelExistingDirectories=[NSSet setWithArray:[self->_sourcesManager.allSources WB_arrayByMappingObjectsLenientlyUsingBlock:^id(CUICrashLogsSourceDirectory *bCrashSource, NSUInteger bIndex) { + + if ([bCrashSource isKindOfClass:[CUICrashLogsSourceDirectory class]]==NO) + return nil; + + return bCrashSource.path; + }]]; + [tOpenPanel beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse bReturnCode) { + self->_openPanelExistingSingleFiles=nil; + self->_openPanelExistingDirectories=nil; + if (bReturnCode==NSModalResponseCancel) return; @@ -368,6 +434,10 @@ - (IBAction)CUI_MENUACTION_addSource:(id)sender else { tSource=[[CUICrashLogsSourceDirectory alloc] initWithContentsOfFileSystemItemAtPath:tURL.path error:NULL]; + + // Check if the directory is not already a source + + // A COMPLETER } if (tSource==nil) @@ -570,16 +640,10 @@ - (IBAction)removeSources:(id)sender NSUInteger tSelectionLastIndex=tSelectedRows.lastIndex; - CUICrashLogsSource * tNextSelectedSource=NULL; + CUICrashLogsSource * tNextSelectedSource=nil; - if ((tSelectionLastIndex+1)==_sourcesManager.allSources.count) - { - tSelectionLastIndex=NSNotFound; - } - else - { + if ((tSelectionLastIndex+1)!=_sourcesManager.allSources.count) tNextSelectedSource=_sourcesManager.allSources[tSelectionLastIndex+1]; - } NSArray * tArray=[_sourcesManager.allSources objectsAtIndexes:tSelectedRows]; @@ -591,7 +655,7 @@ - (IBAction)removeSources:(id)sender NSUInteger tNewSelectedIndex=NSNotFound; - if (tNextSelectedSource!=NULL) + if (tNextSelectedSource!=nil) tNewSelectedIndex=[_sourcesManager.allSources indexOfObject:tNextSelectedSource]; if (tNewSelectedIndex==NSNotFound) @@ -611,6 +675,11 @@ - (IBAction)showInFinder:(id)sender }]; } +- (IBAction)sortByName:(id)sender +{ + [_sourcesManager sortCustomSourcesByName]; +} + #pragma mark - NSTableViewDataSource - (NSInteger)numberOfRowsInTableView:(NSTableView *)inTableView @@ -663,7 +732,7 @@ - (BOOL)tableView:(NSTableView *)inTableView shouldSelectRow:(NSInteger)inRow #pragma mark - Drag and Drop support -- (BOOL)tableView:(NSTableView *)inTableView writeRowsWithIndexes:(NSIndexSet *)inRowIndexes toPasteboard:(NSPasteboard *)inPasteboard; +- (BOOL)tableView:(NSTableView *)inTableView writeRowsWithIndexes:(NSIndexSet *)inRowIndexes toPasteboard:(NSPasteboard *)inPasteboard { for(CUICrashLogsSource * tSource in [_sourcesManager.allSources objectsAtIndexes:inRowIndexes]) { @@ -728,84 +797,71 @@ - (NSDragOperation)tableView:(NSTableView *)inTableView validateDrop:(id *tClasses = @[NSURL.class]; + NSArray *tURLArray = [tPasteBoard readObjectsForClasses:tClasses + options:@{NSPasteboardURLReadingFileURLsOnlyKey:@(YES)}]; CUICrashLogsSourceAll * tSourcesAll=[CUICrashLogsSourceAll crashLogsSourceAll]; - for(NSString * tPath in tArray) + for (NSURL *tURL in tURLArray) { - if ([tFileManager fileExistsAtPath:tPath isDirectory:&tIsDirectory]==YES) + NSNumber *tIsDirectoryNumber; + + if ([tURL getResourceValue:&tIsDirectoryNumber forKey:NSURLIsDirectoryKey error:NULL]==NO) + continue; + + NSString *tPath=tURL.path; + + if (tIsDirectoryNumber.boolValue==YES) { - if (tIsDirectory==NO) + // Do not have the same directory twice + + for(CUICrashLogsSource * tSource in _sourcesManager.allSources) { - // Should have .crash or .smartsource extension - - if ([tPath.pathExtension caseInsensitiveCompare:@"crash"]==NSOrderedSame) + switch(tSource.type) { - // Do not have the same file twice - - for(CUIRawCrashLog * tCrashLog in tSourcesAll.crashLogs) + case CUICrashLogsSourceTypeStandardDirectory: + case CUICrashLogsSourceTypeDirectory: { - if ([tCrashLog.crashLogFilePath isEqualToString:tPath]==YES) - return NSDragOperationNone; + CUICrashLogsSourceDirectory * tSourceFile=(CUICrashLogsSourceDirectory *)tSource; + + if ([tSourceFile.path isEqualToString:tPath]==YES) + return NSDragOperationNone; + + break; } + default: + + break; } - else + } + } + else + { + // Should have .crash or .smartsource extension + NSString *tExtension=tPath.pathExtension; + + if ([tExtension caseInsensitiveCompare:@"crash"]==NSOrderedSame || + [tExtension caseInsensitiveCompare:@"ips"]==NSOrderedSame) + { + // Do not have the same file twice (as a single file source) + + for(CUIRawCrashLog * tCrashLog in tSourcesAll.crashLogs) { - if ([tPath.pathExtension caseInsensitiveCompare:@"smartsource"]!=NSOrderedSame) - return NSDragOperationNone; + if ([tCrashLog.crashLogFilePath isEqualToString:tPath]==YES) + return NSDragOperationNone; } } else { - // Do not have the same directory twice - - for(CUICrashLogsSource * tSource in _sourcesManager.allSources) - { - switch(tSource.type) - { - case CUICrashLogsSourceTypeStandardDirectory: - case CUICrashLogsSourceTypeDirectory: - { - CUICrashLogsSourceDirectory * tSourceFile=(CUICrashLogsSourceDirectory *)tSource; - - - - if ([tSourceFile.path isEqualToString:tPath]==YES) - return NSDragOperationNone; - - break; - } - default: - - break; - } - } + if ([tExtension caseInsensitiveCompare:@"smartsource"]!=NSOrderedSame) + return NSDragOperationNone; } } } - - - // A COMPLETER (Check that we don't already have the files/folder already in the list) - [inTableView setDropRow:-1 dropOperation:NSTableViewDropOn]; return NSDragOperationCopy; @@ -852,73 +908,89 @@ - (BOOL)tableView:(NSTableView *)inTableView acceptDrop:(id )inf return YES; } - if ([tPasteBoard availableTypeFromArray:@[NSFilenamesPboardType]]!=nil) + if ([tPasteBoard availableTypeFromArray:@[NSPasteboardTypeFileURL]]!=nil) { - NSArray * tArray=(NSArray *) [tPasteBoard propertyListForType:NSFilenamesPboardType]; - - NSFileManager * tFileManager=[NSFileManager defaultManager]; + NSArray *tClasses = @[NSURL.class]; + NSArray *tURLArray = [tPasteBoard readObjectsForClasses:tClasses + options:@{NSPasteboardURLReadingFileURLsOnlyKey:@(YES)}]; NSMutableArray * tDelayedSmartSources=[NSMutableArray array]; NSMutableArray * tOpenErrors=[NSMutableArray array]; - NSArray * tNewSources=[tArray WB_arrayByMappingObjectsLenientlyUsingBlock:^id(NSString * bPath, NSUInteger bIndex) { + NSArray * tNewSources=[tURLArray WB_arrayByMappingObjectsLenientlyUsingBlock:^id(NSURL * bURL, NSUInteger bIndex) { CUICrashLogsSource * tSource=nil; - BOOL tIsDirectory; + NSNumber *tIsDirectoryNumber; - if ([tFileManager fileExistsAtPath:bPath isDirectory:&tIsDirectory]==YES) + if ([bURL getResourceValue:&tIsDirectoryNumber forKey:NSURLIsDirectoryKey error:NULL]==NO) + return nil; + + NSError * tError; + + if (tIsDirectoryNumber.boolValue==NO) { - NSError * tError; + NSString * tPathExtension=bURL.pathExtension; - if (tIsDirectory==NO) + if ([tPathExtension caseInsensitiveCompare:@"crash"]==NSOrderedSame || + [tPathExtension caseInsensitiveCompare:@"ips"]==NSOrderedSame) { - if ([bPath.pathExtension caseInsensitiveCompare:@"crash"]==NSOrderedSame) + tSource=[[CUICrashLogsSourceFile alloc] initWithContentsOfFileSystemItemAtPath:bURL.path error:&tError]; + + if (tSource==nil) { - tSource=[[CUICrashLogsSourceFile alloc] initWithContentsOfFileSystemItemAtPath:bPath error:&tError]; - - if (tSource==nil) - { - CUICrashLogsOpenErrorRecord * tRecord=[CUICrashLogsOpenErrorRecord new]; - tRecord.sourceURL=[NSURL fileURLWithPath:bPath]; - tRecord.openError=tError; - - [tOpenErrors addObject:tRecord]; - } + CUICrashLogsOpenErrorRecord * tRecord=[CUICrashLogsOpenErrorRecord new]; + tRecord.sourceURL=bURL; + tRecord.openError=tError; + + [tOpenErrors addObject:tRecord]; } - else if ([bPath.pathExtension caseInsensitiveCompare:@"smartsource"]==NSOrderedSame) + } + else if ([tPathExtension caseInsensitiveCompare:@"smartsource"]==NSOrderedSame) + { + NSDictionary * tRepresentation=[NSDictionary dictionaryWithContentsOfURL:bURL error:NULL]; + + if (tRepresentation==nil) { - NSDictionary * tRepresentation=[NSDictionary dictionaryWithContentsOfFile:bPath]; - - tSource=[[CUICrashLogsSourceSmart alloc] initWithRepresentation:tRepresentation]; - - // Check that the name is not already used and offer to use a unique name + // A COMPLETER + return nil; + } + + tSource=[[CUICrashLogsSourceSmart alloc] initWithRepresentation:tRepresentation]; + + if (tSource==nil) + { + // A COMLETER - NSString * tName=tSource.name; + return nil; + } + + // Check that the name is not already used and offer to use a unique name + + NSString * tName=tSource.name; + + if (tName.length==0) + { + // A COMPLETER - if (tName.length==0) + return nil; + } + + NSArray * tExistingSmartSources=[[CUICrashLogsSourcesManager sharedManager] sourcesOfType:CUICrashLogsSourceTypeSmart]; + + for(CUICrashLogsSourceSmart * tSmartSource in tExistingSmartSources) + { + if ([tSmartSource.name isEqualToString:tName]==YES) { - // A COMPLETER - + [tDelayedSmartSources addObject:tSource]; return nil; } - - NSArray * tExistingSmartSources=[[CUICrashLogsSourcesManager sharedManager] sourcesOfType:CUICrashLogsSourceTypeSmart]; - - for(CUICrashLogsSourceSmart * tSmartSource in tExistingSmartSources) - { - if ([tSmartSource.name isEqualToString:tName]==YES) - { - [tDelayedSmartSources addObject:tSource]; - return nil; - } - } } } - else - { - tSource=[[CUICrashLogsSourceDirectory alloc] initWithContentsOfFileSystemItemAtPath:bPath error:&tError]; - } + } + else + { + tSource=[[CUICrashLogsSourceDirectory alloc] initWithContentsOfFileSystemItemAtPath:bURL.path error:&tError]; } return tSource; @@ -980,18 +1052,21 @@ - (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)inURL return NO; if (inURL.hasDirectoryPath==NO) - return ([inURL.pathExtension caseInsensitiveCompare:@"crash"]==NSOrderedSame); - - /*NSString * tPath=inURL.path; - - for(CUICrashLogsSourceFileSystemItem * tSource in _sources) { - if ([tSource isKindOfClass:[CUICrashLogsSourceFileSystemItem class]]==YES) - { - if ([tSource.path isEqualToString:tPath]==YES) - return NO; - } - }*/ + NSString * tPathExtension=inURL.pathExtension; + + if ([tPathExtension caseInsensitiveCompare:@"crash"]!=NSOrderedSame && + [tPathExtension caseInsensitiveCompare:@"ips"]!=NSOrderedSame) + return NO; + + if ([_openPanelExistingSingleFiles containsObject:inURL.path]==YES) + return NO; + } + else + { + if ([_openPanelExistingDirectories containsObject:inURL.path]==YES) + return NO; + } return YES; } @@ -1094,7 +1169,7 @@ - (void)sourceDidUpdateSource:(NSNotification *)inNotification - (void)sourcesSelectionDidChange:(NSNotification *)inNotification { - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; // Stop observing diff --git a/app_unexpectedly/app_unexpectedly/CUICrashReporterDefaults.m b/app_unexpectedly/app_unexpectedly/CUICrashReporterDefaults.m index a1e8107..5c710f9 100644 --- a/app_unexpectedly/app_unexpectedly/CUICrashReporterDefaults.m +++ b/app_unexpectedly/app_unexpectedly/CUICrashReporterDefaults.m @@ -53,7 +53,7 @@ + (CUICrashReporterDefaults *)standardCrashReporterDefaults + (CUICrashReporterDialogType)dialogTypeFromString:(NSString *)inString { - if ([inString isKindOfClass:[NSString class]]==NO) + if ([inString isKindOfClass:NSString.class]==NO) return CUICrashReporterDialogTypeBasic; static NSDictionary * sStringToEnumDictionary=nil; @@ -109,7 +109,7 @@ - (instancetype)init // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; } return self; @@ -117,7 +117,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -144,7 +144,7 @@ - (void)refresh NSString * tDialogTypeValue=tRepresentation[CUICrashReporterDefaultsDialogTypeKey]; - if ([tDialogTypeValue isKindOfClass:[NSString class]]==NO) + if ([tDialogTypeValue isKindOfClass:NSString.class]==NO) { if (tDialogTypeValue!=nil) NSLog(@"Unexpected value type for key: %@",CUICrashReporterDefaultsDialogTypeKey); @@ -160,7 +160,7 @@ - (void)refresh NSNumber * tNumber=tRepresentation[CUICrashReporterDefaultsNotificationModeKey]; - if ([tDialogTypeValue isKindOfClass:[NSString class]]==NO) + if ([tDialogTypeValue isKindOfClass:NSString.class]==NO) { self.notificationMode=CUICrashReporterNotificationModeDialog; } diff --git a/app_unexpectedly/app_unexpectedly/CUIRawTextTransformation.h b/app_unexpectedly/app_unexpectedly/CUIDataTransform.h similarity index 72% rename from app_unexpectedly/app_unexpectedly/CUIRawTextTransformation.h rename to app_unexpectedly/app_unexpectedly/CUIDataTransform.h index 99667e3..835b5aa 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRawTextTransformation.h +++ b/app_unexpectedly/app_unexpectedly/CUIDataTransform.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2021-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -11,34 +11,16 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - - -/* - - JIRA formatting - - {{monospaced text}} - - {color:#d04437}colored text{color} - - _Italic_ - - *bold* - - +underline+ - - ------------------------------------ - - */ - - #import #import "CUITextModeDisplaySettings.h" -#import "CUICrashLog.h" - +extern NSString * const CUIDataTransformErrorDomain; +typedef NS_ENUM(NSUInteger, CUIDataTransformError) +{ + CUIDataTransformUnknownError=1 +}; extern NSString * const CUIGenericAnchorAttributeName; @@ -48,7 +30,6 @@ extern NSString * const CUIThreadAnchorAttributeName; extern NSString * const CUIBinaryAnchorAttributeName; - typedef NS_ENUM(NSUInteger, CUIHyperlinksStyle) { CUIHyperlinksNone, @@ -56,18 +37,30 @@ typedef NS_ENUM(NSUInteger, CUIHyperlinksStyle) CUIHyperlinksHTML }; +typedef NS_ENUM(NSUInteger, CUISymbolicationMode) +{ + CUISymbolicationModeNone, + CUISymbolicationModeSymbolicate +}; + +@interface CUIDataTransform : NSObject + + @property CUISymbolicationMode symbolicationMode; + + @property (nonatomic) CUIHyperlinksStyle hyperlinksStyle; + + @property (nonatomic) CUITextModeDisplaySettings * displaySettings; + @property (nonatomic) CGFloat fontSizeDelta; -@interface CUIRawTextTransformation : NSObject - @property CUIHyperlinksStyle hyperlinksStyle; + @property (nonatomic) id input; - @property CUITextModeDisplaySettings * displaySettings; + @property (readonly) NSAttributedString * output; - @property CGFloat fontSizeDelta; -- (NSAttributedString *)transformCrashLog:(CUICrashLog *)inCrashLog; + @property (readonly) NSError * error; -- (NSAttributedString *)transformCrashLog:(CUICrashLog *)inCrashLog lines:(NSArray *)inLines; +- (BOOL)transform; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIDataTransform.m b/app_unexpectedly/app_unexpectedly/CUIDataTransform.m new file mode 100644 index 0000000..a75ba0d --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIDataTransform.m @@ -0,0 +1,97 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIDataTransform.h" + +NSString * const CUIDataTransformErrorDomain=@"fr.whitebox.data-tranform.error"; + + +NSString * const CUIGenericAnchorAttributeName=@"CUIGenericAnchorAttributeName"; + +NSString * const CUISectionAnchorAttributeName=@"CUISectionAnchorAttributeName"; + +NSString * const CUIThreadAnchorAttributeName=@"CUIThreadAnchorAttributeName"; + +NSString * const CUIBinaryAnchorAttributeName=@"CUIBinaryAnchorAttributeName"; + +@interface CUIDataTransform () + + @property (nonatomic,readwrite) NSAttributedString * output; + + @property (readwrite) NSError * error; + +- (void)setOutput:(NSAttributedString *)inOutput; + +@end + +@implementation CUIDataTransform + +- (instancetype)init +{ + self=[super init]; + + if (self!=nil) + { + _symbolicationMode=CUISymbolicationModeSymbolicate; + + _hyperlinksStyle=CUIHyperlinksInternal; + } + + return self; +} + +#pragma mark - + +- (void)setHyperlinksStyle:(CUIHyperlinksStyle)inHyperlinksStyle +{ + _output=nil; + + _hyperlinksStyle=inHyperlinksStyle; +} + +- (void)setDisplaySettings:(CUITextModeDisplaySettings *)inDisplaySettings +{ + _output=nil; + + _displaySettings=inDisplaySettings; +} + +- (void)setFontSizeDelta:(CGFloat)inFontSizeDelta +{ + _output=nil; + + _fontSizeDelta=inFontSizeDelta; +} + +- (void)setInput:(id)inInput +{ + _output=nil; + + _input=inInput; +} + +- (void)setOutput:(NSAttributedString *)inOutput +{ + _output=inOutput; +} + +#pragma mark - + +- (BOOL)transform +{ + self.output=nil; + + return YES; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.h b/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.h index 57996b5..3f570c5 100644 --- a/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.h +++ b/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -11,26 +11,14 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "CUIQuickHelpPopUpViewController.h" -@class CUIExceptionTypePopUpViewController; - -@protocol CUIExceptionTypePopUpViewControllerDelegate - -- (void)exceptionTypePopUpViewController:(CUIExceptionTypePopUpViewController *)inController didComputeSizeOfPopover:(NSPopover *)inPopover; - -@end - -@interface CUIExceptionTypePopUpViewController : NSViewController +@interface CUIExceptionTypePopUpViewController : CUIQuickHelpPopUpViewController @property (readonly,copy) NSString * exceptionType; @property (readonly,copy) NSString * exceptionSignal; - @property NSPopover * popover; - - @property (weak) id delegate; - - (void)setExceptionType:(NSString *)inType signal:(NSString *)inSignal; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.m b/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.m index df0399f..f8597ce 100644 --- a/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,150 +13,33 @@ #import "CUIExceptionTypePopUpViewController.h" -#import +@interface CUIExceptionTypePopUpViewController () -@interface CUINoScrollingWebView : WKWebView +@property (copy) NSString * exceptionType; -@end - -@implementation CUINoScrollingWebView - -- (void)scrollWheel:(NSEvent *)inEvent -{ - [self.nextResponder scrollWheel:inEvent]; -} - -@end - -@interface CUIExceptionTypePopUpViewController () /**/ -{ - IBOutlet CUINoScrollingWebView * _webView; - - NSBundle * _mainBundle; - - NSURL * _contentsFileURL; -} - - @property (copy) NSString * exceptionType; - - @property (copy) NSString * exceptionSignal; +@property (copy) NSString * exceptionSignal; @end @implementation CUIExceptionTypePopUpViewController -- (instancetype)init -{ - self=[super init]; - - if (self!=nil) - { - _mainBundle=[NSBundle mainBundle]; - } - - return self; -} - -#pragma mark - - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - _webView.navigationDelegate=self; - - [_webView setValue:@(NO) forKey:@"drawsBackground"]; - - NSError * tError=nil; - - NSString * tHTMLContents=[NSString stringWithContentsOfURL:_contentsFileURL encoding:NSUTF8StringEncoding error:&tError]; - - if (tHTMLContents==nil) - { - NSLog(@"HTML data could not be loaded from file \"%@\".",_contentsFileURL); - - return; - } - - [_webView loadHTMLString:tHTMLContents baseURL:_mainBundle.resourceURL]; -} - -- (NSString *)nibName -{ - return @"CUIExceptionTypePopUpViewController"; -} - -#pragma mark - - -- (void)webView:(WKWebView *)inWebView decidePolicyForNavigationAction:(WKNavigationAction *)inNavigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler -{ - if (inNavigationAction.navigationType==WKNavigationTypeLinkActivated) - { - decisionHandler(WKNavigationActionPolicyCancel); - - [[NSWorkspace sharedWorkspace] openURL:inNavigationAction.request.URL]; - } - else - { - decisionHandler(WKNavigationActionPolicyAllow); - } -} - -- (void)webView:(WKWebView *)inWebView didFinishNavigation:(WKNavigation *)inNavigation -{ - if (self.popover==nil) - return; - - __block NSSize tCurrentSize=self.popover.contentSize; - - [_webView evaluateJavaScript:@"document.body.scrollHeight;" completionHandler:^(NSString * bResult, NSError * bError) { - - tCurrentSize.height=[bResult integerValue]; - - dispatch_async(dispatch_get_main_queue(), ^{ - - self.popover.contentSize=tCurrentSize; - - [self.delegate exceptionTypePopUpViewController:self didComputeSizeOfPopover:self.popover]; - }); - }]; -} - -#pragma mark - - - (void)setExceptionType:(NSString *)inType signal:(NSString *)inSignal { - _contentsFileURL=nil; + NSURL * tURL=nil; if (inType!=nil && inSignal!=nil) { - _contentsFileURL=[_mainBundle URLForResource:[NSString stringWithFormat:@"%@_%@",inType,inSignal] withExtension:@"html"]; + tURL=[self.bundle URLForResource:[NSString stringWithFormat:@"%@_%@",inType,inSignal] withExtension:@"html"]; } - if (_contentsFileURL==nil) + if (tURL==nil) { // Use no documentation file - _contentsFileURL=[_mainBundle URLForResource:@"unknown_exception_type" withExtension:@"html"]; - } - - if (_webView==nil) - return; - - NSError * tError=nil; - - NSString * tHTMLContents=[NSString stringWithContentsOfURL:_contentsFileURL encoding:NSUTF8StringEncoding error:&tError]; - - if (tHTMLContents==nil) - { - NSLog(@"Missing HTML document at %@",_contentsFileURL.path); - - // A COMPLETER (Provide a basic HTML error report to display) - - return; + tURL=[self.bundle URLForResource:@"unknown_exception_type" withExtension:@"html"]; } - [_webView loadHTMLString:tHTMLContents baseURL:_mainBundle.resourceURL]; + self.contentsFileURL=tURL; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.h b/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.h index 3c0de12..41741e6 100644 --- a/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.h +++ b/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.h @@ -19,7 +19,8 @@ typedef NS_ENUM(NSUInteger, CUICrashLogExportFormat) { CUICrashLogExportFormatHTML=0, CUICrashLogExportFormatRTF, - CUICrashLogExportFormatPDF + CUICrashLogExportFormatPDF, + CUICrashLogExportFormatText }; typedef NS_ENUM(NSUInteger, CUICrashLogExportedContentsType) @@ -29,8 +30,7 @@ typedef NS_ENUM(NSUInteger, CUICrashLogExportedContentsType) }; @interface CUIExportAccessoryViewController : NSViewController -{ -} + @property NSSavePanel * savePanel; @property (nonatomic) CUICrashLogExportFormat exportFormat; @@ -39,6 +39,10 @@ typedef NS_ENUM(NSUInteger, CUICrashLogExportedContentsType) @property (nonatomic,readonly) CUICrashLogExportedContentsType exportedContents; + @property (nonatomic) BOOL canObfuscateContents; + + @property (readonly) BOOL obfuscateContents; + @property (nonatomic) CUITextModeDisplaySettings * displaySettings; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.m b/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.m index 03068b2..1c4b8bf 100644 --- a/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIExportAccessoryViewController.m @@ -25,8 +25,16 @@ @interface CUIExportAccessoryViewController () IBOutlet NSButton * _allContentsRadioButton; IBOutlet NSButton * _selectionOnlyRadioButton; + + // Obfuscate Contents + + IBOutlet NSButton * _obfuscateContentsRadioButton; + + IBOutlet NSTextField * _obfuscateDescriptionLabel; } +@property (readwrite) BOOL obfuscateContents; + - (IBAction)switchExportFormat:(id)sender; - (IBAction)switchExportedContents:(id)sender; @@ -35,6 +43,20 @@ - (IBAction)switchExportedContents:(id)sender; @implementation CUIExportAccessoryViewController +- (instancetype)init +{ + self=[super init]; + + if (self!=nil) + { + _obfuscateContents=NO; + } + + return self; +} + +#pragma mark - + - (NSString *)nibName { return @"CUIExportAccessoryViewController"; @@ -55,7 +77,16 @@ - (void)viewDidLoad _selectionOnlyRadioButton.enabled=tRadioButtonEnabled; _allContentsRadioButton.enabled=tRadioButtonEnabled; - _allContentsRadioButton.state=NSOnState; + _allContentsRadioButton.state=NSControlStateValueOn; + + // Obfuscate Contents + + tRadioButtonEnabled=(self.canObfuscateContents==YES); + + _obfuscateContentsRadioButton.enabled=tRadioButtonEnabled; + _obfuscateContentsRadioButton.state=NSControlStateValueOff; + + _obfuscateDescriptionLabel.textColor=(tRadioButtonEnabled==YES) ? [NSColor labelColor] : [NSColor disabledControlTextColor]; } #pragma mark - @@ -80,18 +111,33 @@ - (void)setCanSelectExportedContents:(BOOL)inCanSelectExportedContents else { _selectionOnlyRadioButton.enabled=NO; - _allContentsRadioButton.state=NSOnState; + _allContentsRadioButton.state=NSControlStateValueOn; } } - (CUICrashLogExportedContentsType)exportedContents { - if (_allContentsRadioButton.state==NSOnState) + if (_allContentsRadioButton.state==NSControlStateValueOn) return CUICrashLogExportedContentsAll; return CUICrashLogExportedContentsSelection; } +- (void)setCanObfuscateContents:(BOOL)inCanObfuscateContents +{ + _canObfuscateContents=inCanObfuscateContents; + + if (_canObfuscateContents==YES) + { + _obfuscateContentsRadioButton.enabled=YES; + } + else + { + _obfuscateContentsRadioButton.enabled=NO; + _obfuscateContentsRadioButton.state=NSControlStateValueOff; + } +} + #pragma mark - - (IBAction)switchExportFormat:(NSPopUpButton *)sender @@ -116,6 +162,12 @@ - (IBAction)switchExportFormat:(NSPopUpButton *)sender self.savePanel.allowedFileTypes=@[@"pdf"]; + break; + + case CUICrashLogExportFormatText: + + self.savePanel.allowedFileTypes=@[@"crash"]; + break; } } @@ -125,4 +177,23 @@ - (IBAction)switchExportedContents:(id)sender // Not used at this time } +- (IBAction)switchObfuscateContents:(NSButton *)sender +{ + BOOL tObfuscateContents=(sender.state==NSControlStateValueOn); + + if (tObfuscateContents==_obfuscateContents) + return; + + _obfuscateContents=tObfuscateContents; + + if (self.canSelectExportedContents==YES) + { + _selectionOnlyRadioButton.enabled=(_obfuscateContents==NO); + _allContentsRadioButton.enabled=(_obfuscateContents==NO); + + if (_obfuscateContents==YES) + _allContentsRadioButton.state=NSControlStateValueOn; + } +} + @end diff --git a/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.h b/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.h index 35e0047..2fd63e0 100644 --- a/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.h +++ b/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.h @@ -17,9 +17,9 @@ @protocol CUIFileDeadDropViewDelegate -- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView validateDropFiles:(NSArray *)inFilenames; +- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView validateDropFileURLs:(NSArray *)inFileURLs; -- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView acceptDropFiles:(NSArray *)inFilenames; +- (BOOL)fileDeadDropView:(CUIFileDeadDropView *)inView acceptDropFileURLs:(NSArray *)inFileURLs; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.m b/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.m index 6f281a1..6e8df54 100644 --- a/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.m +++ b/app_unexpectedly/app_unexpectedly/CUIFileDeadDropView.m @@ -29,7 +29,7 @@ - (instancetype)initWithFrame:(NSRect)inFrame { // Register for Drop - [self registerForDraggedTypes:@[NSFilenamesPboardType]]; + [self registerForDraggedTypes:@[NSPasteboardTypeFileURL]]; } return self; @@ -43,7 +43,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder { // Register for Drop - [self registerForDraggedTypes:@[NSFilenamesPboardType]]; + [self registerForDraggedTypes:@[NSPasteboardTypeFileURL]]; } return self; @@ -82,7 +82,7 @@ - (NSDragOperation)draggingEntered:(id )sender NSPasteboard * tPasteBoard=[sender draggingPasteboard]; - if ([[tPasteBoard types] containsObject:NSFilenamesPboardType]==NO) + if ([tPasteBoard.types containsObject:NSPasteboardTypeFileURL]==NO) return NSDragOperationNone; NSDragOperation tSourceDragMask = [sender draggingSourceOperationMask]; @@ -90,11 +90,13 @@ - (NSDragOperation)draggingEntered:(id )sender if ((tSourceDragMask & NSDragOperationCopy)==0) return NSDragOperationNone; - NSArray * tFiles=[tPasteBoard propertyListForType:NSFilenamesPboardType]; + NSArray *tClasses = @[NSURL.class]; + NSArray *tURLArray = [tPasteBoard readObjectsForClasses:tClasses + options:@{NSPasteboardURLReadingFileURLsOnlyKey:@(YES)}]; - if (tFiles!=nil) + if (tURLArray!=nil) { - if ([self.delegate fileDeadDropView:self validateDropFiles:tFiles]==YES) + if ([self.delegate fileDeadDropView:self validateDropFileURLs:tURLArray]==YES) { self.highlighted=YES; @@ -117,12 +119,14 @@ - (BOOL)performDragOperation:(id )sender NSPasteboard * tPasteBoard=[sender draggingPasteboard]; - if ([[tPasteBoard types] containsObject:NSFilenamesPboardType]==YES) + if ([tPasteBoard.types containsObject:NSPasteboardTypeFileURL]==YES) { - NSArray * tFiles = [tPasteBoard propertyListForType:NSFilenamesPboardType]; + NSArray *tClasses = @[NSURL.class]; + NSArray *tURLArray = [tPasteBoard readObjectsForClasses:tClasses + options:@{NSPasteboardURLReadingFileURLsOnlyKey:@(YES)}]; - if (tFiles!=nil) - return [self.delegate fileDeadDropView:self acceptDropFiles:tFiles]; + if (tURLArray!=nil) + return [self.delegate fileDeadDropView:self acceptDropFileURLs:tURLArray]; } return NO; diff --git a/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.h b/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.h index 019ef4a..73afd55 100644 --- a/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.h +++ b/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.h @@ -30,6 +30,6 @@ - (NSMenu *)availableApplicationsMenuWithTarget:(id)inTarget; -- (BOOL)openBinaryImage:(NSString *)inPath withApplicationAttributes:(CUIApplicationItemAttributes *)inApplicationAttributes codeType:(CUICodeType)inCodeType fileOffSet:(void *)inOffset; +- (void)openBinaryImage:(NSString *)inPath withApplicationAttributes:(CUIApplicationItemAttributes *)inApplicationAttributes codeType:(CUICodeType)inCodeType fileOffSet:(void *)inOffset; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.m b/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.m index c87d86a..ad641bc 100644 --- a/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.m +++ b/app_unexpectedly/app_unexpectedly/CUIHopperDisassemblerManager.m @@ -93,107 +93,126 @@ - (NSMenu *)availableApplicationsMenuWithTarget:(id= 101600 + if (@available(*, macOS 11.0)) + { + [[NSWorkspace sharedWorkspace] openApplicationAtURL:inApplicationAttributes.applicationURL + configuration:[NSWorkspaceOpenConfiguration configuration] completionHandler:^(NSRunningApplication * _Nullable bRunningApplication, NSError * _Nullable error) { + if (bRunningApplication==nil) + { + NSLog(@"No running instances of Hopper Disassembler and not able to launch one: %@",error); + + return; + } + + postLaunchActions(bRunningApplication); + }]; + } + else +#endif + { + NSRunningApplication * tRunningApplication=[[NSWorkspace sharedWorkspace] launchApplicationAtURL:inApplicationAttributes.applicationURL + options:0 + configuration:@{} + error:NULL]; + + if (tRunningApplication==nil) + { + NSLog(@"No running instances of Hopper Disassembler and not able to launch one."); + + return; + } + + postLaunchActions(tRunningApplication); + } } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIIPSTransform.h b/app_unexpectedly/app_unexpectedly/CUIIPSTransform.h new file mode 100644 index 0000000..aecce1c --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIIPSTransform.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2021-2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#import "CUIReportThemedTransform.h" + +@interface CUIIPSTransform : CUIReportThemedTransform + +@end + diff --git a/app_unexpectedly/app_unexpectedly/CUIIPSTransform.m b/app_unexpectedly/app_unexpectedly/CUIIPSTransform.m new file mode 100644 index 0000000..9e9f193 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIIPSTransform.m @@ -0,0 +1,1528 @@ +/* + Copyright (c) 2021-2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#import "CUIIPSTransform.h" + +#import "IPSReport.h" + +#import "IPSDateFormatter.h" + +#import "IPSIncident+ApplicationSpecificInformation.h" +#import "IPSThreadState+RegisterDisplayName.h" +#import "IPSImage+UserCode.h" + +#import "IPSImage+Offset.h" + +#import "CUIApplicationPreferences.h" +#import "CUIApplicationPreferences+Themes.h" + +#import "CUICrashLogBinaryImages.h" + +#import "CUIBinaryImageUtility.h" + +#import "CUIThemesManager.h" +#import "CUIThemeItemsGroup+UI.h" + +#ifndef __DISABLE_SYMBOLICATION_ +#import "CUIdSYMBundlesManager.h" + +#import "CUISymbolicationManager.h" +#endif + +#import "CUIStackFrame.h" + +#import "CUICrashLogExceptionInformation+QuickHelp.h" + +@interface CUIDataTransform (Private) + +- (void)setOutput:(NSAttributedString *)inOutput; + +@end + +@implementation CUIIPSTransform + ++ (NSString *)binaryImageStringForAddress:(NSUInteger)inAddress +{ + NSString * tString=[NSString stringWithFormat:@"0x%lx",inAddress]; + + NSUInteger tLength=tString.length; + + NSString * tSpaceString=@" "; + + return [[tSpaceString substringFromIndex:tLength] stringByAppendingString:tString]; +} + +#pragma mark - + +- (NSAttributedString *)attributedStringForKey:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.keyAttributes]; +} + +- (NSAttributedString *)attributedStringForKeyWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.keyAttributes]; +} + + +- (NSAttributedString *)attributedStringForPlainText:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.plainTextAttributes]; +} + +- (NSAttributedString *)attributedStringForPlainTextWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.plainTextAttributes]; +} + +- (NSAttributedString *)attributedStringForPath:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.pathAttributes]; +} + +- (NSAttributedString *)attributedStringForPathWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.pathAttributes]; +} + +- (NSAttributedString *)attributedStringForVersion:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.versionAttributes]; +} + +- (NSAttributedString *)attributedStringForVersionWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.versionAttributes]; +} + +- (NSAttributedString *)attributedStringForUUID:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.UUIDAttributes]; +} + +- (NSAttributedString *)attributedStringForUUIDWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.UUIDAttributes]; +} + +- (NSAttributedString *)attributedStringForThreadLabel:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.threadLabelAttributes]; +} + +- (NSAttributedString *)attributedStringForThreadLabelWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.threadLabelAttributes]; +} + +- (NSAttributedString *)attributedStringForCrashedThreadLabel:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.crashedThreadLabelAttributes]; +} + +- (NSAttributedString *)attributedStringForCrashedThreadLabelWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.crashedThreadLabelAttributes]; +} + +- (NSAttributedString *)attributedStringForMemoryAddress:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:self.memoryAddressAttributes]; +} + +- (NSAttributedString *)attributedStringForMemoryAddressWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.memoryAddressAttributes]; +} + +- (NSAttributedString *)attributedStringForUser:(BOOL)inUserCode code:(NSString *)inString +{ + if (inString==nil) + return nil; + + return [[NSAttributedString alloc] initWithString:inString attributes:(inUserCode==YES) ? self.executableCodeAttributes : self.OSCodeAttributes]; +} + +- (NSAttributedString *)attributedStringForUser:(BOOL)inUserCode codeWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:(inUserCode==YES) ? self.executableCodeAttributes : self.OSCodeAttributes]; +} + +- (NSAttributedString *)attributedStringForRegisterValueWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) +{ + if (format==nil) + return nil; + + va_list args; + va_start(args, format); + NSString * tString=[[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [[NSAttributedString alloc] initWithString:tString attributes:self.registerValueAttributes]; +} + +- (NSAttributedString *)attributedStringForUser:(BOOL)inUserCode binaryImageIdentifier:(NSString *)inIdentifier +{ + if (inIdentifier==nil) + return nil; + + NSMutableDictionary * tMutableDictionary=[self.plainTextAttributes mutableCopy]; + tMutableDictionary[NSForegroundColorAttributeName]=(inUserCode==YES) ? [CUIBinaryImageUtility colorForUserCode]: [CUIBinaryImageUtility colorForIdentifier:inIdentifier]; + + return [[NSAttributedString alloc] initWithString:(inUserCode==NO) ? inIdentifier : [NSString stringWithFormat:@"+%@",inIdentifier] + attributes:tMutableDictionary]; +} + +#pragma mark - + +- (NSArray *)attributedLinesForHeaderOfIncident:(IPSIncident *)inIncident +{ + IPSIncidentHeader * tHeader=inIncident.header; + + NSMutableArray * tMutableArray=[NSMutableArray array]; + NSMutableAttributedString * tMutableAttributedString; + + if ([tHeader.crashReporterKey isKindOfClass:NSString.class]) + { + tMutableAttributedString=[[self attributedStringForKey:@"CrashReporter Key:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:tHeader.crashReporterKey]]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + tMutableAttributedString=[[self attributedStringForKey:@"Process:"] mutableCopy]; + + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Header" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,tMutableAttributedString.length)]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@ [%d]",tHeader.processName,tHeader.processID]]; + + [tMutableArray addObject:tMutableAttributedString]; + + + tMutableAttributedString=[[self attributedStringForKey:@"Path:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPath:tHeader.processPath]]; + + [tMutableArray addObject:tMutableAttributedString]; + + + IPSBundleInfo * tBundleInfo=tHeader.bundleInfo; + + tMutableAttributedString=[[self attributedStringForKey:@"Identifier:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@",(tBundleInfo.bundleIdentifier!=nil) ? tBundleInfo.bundleIdentifier : tHeader.processName]]; + + [tMutableArray addObject:tMutableAttributedString]; + + + tMutableAttributedString=[[self attributedStringForKey:@"Version:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForVersion:(tBundleInfo.bundleShortVersionString!=nil) ? tBundleInfo.bundleShortVersionString : @"???"]]; + + if (tBundleInfo.bundleVersion!=nil) + [tMutableAttributedString appendAttributedString:[self attributedStringForVersionWithFormat:@" (%@)",tBundleInfo.bundleVersion]]; + + [tMutableArray addObject:tMutableAttributedString]; + + + tMutableAttributedString=[[self attributedStringForKey:@"Code Type:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@ (%@)",tHeader.cpuType,(tHeader.translated==NO) ? @"Native" : @"Translated"]]; + + [tMutableArray addObject:tMutableAttributedString]; + + + tMutableAttributedString=[[self attributedStringForKey:@"Parent Process:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@ [%d]",tHeader.parentProcessName,tHeader.parentProcessID]]; + + [tMutableArray addObject:tMutableAttributedString]; + + if (tHeader.responsibleProcessName!=nil) + { + tMutableAttributedString=[[self attributedStringForKey:@"Responsible:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@ [%d]",tHeader.responsibleProcessName,tHeader.responsibleProcessID]]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + tMutableAttributedString=[[self attributedStringForKey:@"User ID:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %d",tHeader.userID]]; + + [tMutableArray addObject:tMutableAttributedString]; + + [tMutableArray addObject:@""]; + + tMutableAttributedString=[[self attributedStringForKey:@"Date/Time:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@",[[IPSDateFormatter sharedFormatter] stringFromDate:tHeader.captureTime]]]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForKey:@"OS Version:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForVersionWithFormat:@"%@ (%@)",tHeader.operatingSystemVersion.train,tHeader.operatingSystemVersion.build]]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForKey:@"Report Version:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" 12"]]; + + [tMutableArray addObject:tMutableAttributedString]; + + if ([tHeader.crashReporterKey isKindOfClass:NSUUID.class]) + { + tMutableAttributedString=[[self attributedStringForKey:@"Anonymous UUID:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForUUID:[tHeader.crashReporterKey UUIDString]]]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + [tMutableArray addObject:@""]; + + if (tHeader.sleepWakeUUID!=nil) + { + tMutableAttributedString=[[self attributedStringForKey:@"Sleep/Wake UUID:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForUUID:tHeader.sleepWakeUUID.UUIDString]]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + tMutableAttributedString=[[self attributedStringForKey:@"Time Awake Since Boot:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %lu seconds",(unsigned long)tHeader.uptime]]; + + [tMutableArray addObject:tMutableAttributedString]; + + [tMutableArray addObject:@""]; + + tMutableAttributedString=[[self attributedStringForKey:@"System Integrity Protection:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@",(tHeader.systemIntegrityProtectionEnable==YES) ? @"enabled" : @"disabled"]]; + + [tMutableArray addObject:tMutableAttributedString]; + + [tMutableArray addObject:@""]; + + return tMutableArray; +} + +- (NSArray *)attributedLinesForExceptionInformationOfIncident:(IPSIncident *)inIncident +{ + IPSIncidentExceptionInformation * tExceptionInformation=inIncident.exceptionInformation; + + NSMutableArray * tMutableArray=[NSMutableArray array]; + + NSMutableAttributedString * tMutableAttributedString=[[self attributedStringForKey:@"Crashed Thread:"] mutableCopy]; + + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Exception Information" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,tMutableAttributedString.length)]; + + if ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==CUIDocumentBacktracesSection && + inIncident.threads.count>0) + { + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + [tMutableAttributedString addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"a://crashed_thread"] + } + range:NSMakeRange(0,tMutableAttributedString.length)]; + + break; + + case CUIHyperlinksHTML: + + [tMutableAttributedString addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"sharp://crashed_thread"] + } + range:NSMakeRange(0,tMutableAttributedString.length)]; + + break; + + default: + + break; + } + } + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForCrashedThreadLabelWithFormat:@"%lu",(unsigned long)tExceptionInformation.faultingThread]]; + + IPSLegacyInfo * tLegacyInfo=tExceptionInformation.legacyInfo; + + if (tLegacyInfo.threadTriggered.queue!=nil) + [tMutableAttributedString appendAttributedString:[self attributedStringForCrashedThreadLabelWithFormat:@" Dispatch queue: %@",tLegacyInfo.threadTriggered.queue]]; + + [tMutableArray addObject:tMutableAttributedString]; + + [tMutableArray addObject:@""]; + + IPSException * tException=tExceptionInformation.exception; + + tMutableAttributedString=[[self attributedStringForKey:@"Exception Type:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + NSAttributedString * tAttributedString; + + if (tException.signal!=nil) + tAttributedString=[self attributedStringForPlainTextWithFormat:@"%@ (%@)",tException.type,tException.signal]; + else + tAttributedString=[self attributedStringForPlainTextWithFormat:@"%@",tException.type]; + + NSMutableAttributedString * tValueAttributedString=[tAttributedString mutableCopy]; + + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + [tValueAttributedString addAttributes:@{ + NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle|NSUnderlineStylePatternDash) + } + + range:NSMakeRange(0, tValueAttributedString.length)]; + + [tValueAttributedString addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"a://exception_type"] + } + range:NSMakeRange(0, tValueAttributedString.length)]; + + break; + + default: + + break; + } + + [tMutableAttributedString appendAttributedString:tValueAttributedString]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForKey:@"Exception Codes:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@",(tException.subtype!=nil) ? tException.subtype : tException.codes]]; + + [tMutableArray addObject:tMutableAttributedString]; + + if (tExceptionInformation.isCorpse==YES) + { + tMutableAttributedString=[[self attributedStringForKey:@"Exception Note:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" EXC_CORPSE_NOTIFY"]]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + [tMutableArray addObject:@""]; + + IPSTermination * tTermination=tExceptionInformation.termination; + + if (tTermination!=nil) + { + tMutableAttributedString=[[self attributedStringForKey:@"Termination Reason:"] mutableCopy]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + tValueAttributedString=[[self attributedStringForPlainTextWithFormat:@"Namespace %@, Code 0x%lx",tTermination.namespace,(unsigned long)tTermination.code] mutableCopy]; + + if (self.crashlog.exceptionInformation.isQuickHelpAvailableForTerminationReason==YES) + { + [tValueAttributedString addAttributes:@{ + NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle|NSUnderlineStylePatternDash) + } + + range:NSMakeRange(0, tValueAttributedString.length)]; + + [tValueAttributedString addAttributes:@{ + NSLinkAttributeName:[NSURL URLWithString:@"a://termination_reason"] + } + range:NSMakeRange(0, tValueAttributedString.length)]; + } + + [tMutableAttributedString appendAttributedString:tValueAttributedString]; + + [tMutableArray addObject:tMutableAttributedString]; + + if (tTermination.byProc!=nil) + { + tMutableAttributedString=[[self attributedStringForKey:@"Terminating Process:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@ [%d]",tTermination.byProc,tTermination.byPid]]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + [tMutableArray addObject:@""]; + } + + return tMutableArray; +} + +- (NSArray *)attributedLinesForDiagnosticMessageOfIncident:(IPSIncident *)inIncident +{ + IPSIncidentDiagnosticMessage * tDiagnosticMessage=inIncident.diagnosticMessage; + + NSMutableArray * tMutableArray=[NSMutableArray array]; + + if (tDiagnosticMessage.vmregioninfo!=nil) + { + NSMutableAttributedString * tMutableAttributedString=[[self attributedStringForKey:@"VM Region Info:"] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@" %@",tDiagnosticMessage.vmregioninfo]]; + + [tMutableArray addObject:tMutableAttributedString]; + + [tMutableArray addObject:@""]; + } + + NSArray * tApplicationSpecificInformation=[inIncident applicationSpecificInformationMessage]; + + if (tApplicationSpecificInformation.count>0) + { + NSMutableAttributedString * tMutableAttributedString=[[self attributedStringForKey:@"Application Specific Information:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + for (NSString *tSring in tApplicationSpecificInformation) + [tMutableArray addObject:[self attributedStringForPlainText:tSring]]; + + [tMutableArray addObject:@""]; + } + + NSArray * tSignatures=tDiagnosticMessage.asi.signatures; + + if (tSignatures!=nil) + { + NSMutableAttributedString * tMutableAttributedString=[[self attributedStringForKey:@"Application Specific Signatures:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + [tSignatures enumerateObjectsUsingBlock:^(NSString * bSignature, NSUInteger bIndex, BOOL * bOutStop) { + + [tMutableArray addObject:[self attributedStringForPlainText:bSignature]]; + }]; + + [tMutableArray addObject:@""]; + } + + NSMutableAttributedString * tMutableAttributedString=tMutableArray.firstObject; + + if ([tMutableAttributedString isKindOfClass:[NSMutableAttributedString class]]==YES) + { + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Diagnostic Messages" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,tMutableAttributedString.length)]; + } + + return tMutableArray; +} + +- (NSArray *)attributedLinesForBacktracesOfIncident:(IPSIncident *)inIncident +{ + #define BINARYIMAGENAME_AND_SPACE_MAXLEN 34 + + NSMutableArray * tMutableArray=[NSMutableArray array]; + CUICrashLogBacktraces * tBacktraces=self.crashlog.backtraces; +#ifndef __DISABLE_SYMBOLICATION_ + NSInteger tThreadIndexOffset=0; +#endif + + NSString * tProcessPath=inIncident.header.processPath; + + NSArray * tSortedBinaryImages=[inIncident.binaryImages sortedArrayUsingSelector:@selector(compare:)]; + +#ifndef __DISABLE_SYMBOLICATION_ + NSArray * tBacktracesThreads=tBacktraces.threads; + __block CUIThread * tBacktraceThread; + __block NSArray * tStackFrames; +#endif + + void (^transformThreadFrame)(IPSThreadFrame*, NSUInteger, BOOL *) = ^(IPSThreadFrame * bFrame, NSUInteger bFrameIndex, BOOL * _Nonnull stop) { + + IPSImage * tBinaryImage=inIncident.binaryImages[bFrame.imageIndex]; + + BOOL tIsUserCode=tBinaryImage.isUserCode; + + if (tIsUserCode==NO) + { + if ([tSortedBinaryImages indexOfObjectIdenticalTo:tBinaryImage]==0) + { + tIsUserCode=YES; + } + else + { + NSString * tPath=tBinaryImage.path; + + tIsUserCode=(tPath!=nil && [tProcessPath isEqualToString:tPath]==YES); + } + } + + NSString * tFrameIndexString=[NSString stringWithFormat:@"%lu",(unsigned long)bFrameIndex]; + + NSString * tIndexSpace=[@" " substringFromIndex:tFrameIndexString.length]; + + NSMutableAttributedString * tMutableAttributedString=[[self attributedStringForUser:tIsUserCode code:tFrameIndexString] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode code:tIndexSpace]]; + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)==CUIStackFrameBinaryNameComponent) + { + NSString * tBinaryImageIdentifier=(tBinaryImage.bundleIdentifier!=nil) ? tBinaryImage.bundleIdentifier : tBinaryImage.name; + + if (tBinaryImageIdentifier==nil) + tBinaryImageIdentifier=@"???"; + + NSUInteger tImageNameLength=tBinaryImageIdentifier.length; + + NSMutableAttributedString * tMutableBinaryImageAttributedString=[[self attributedStringForUser:tIsUserCode code:tBinaryImageIdentifier] mutableCopy]; + + if (self.hyperlinksStyle!=CUIHyperlinksNone && ((self.displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==CUIDocumentBinaryImagesSection)) + { + NSURL * tURL=nil; + + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + tURL=[NSURL URLWithString:[NSString stringWithFormat:@"bin://%@",tBinaryImage.UUID.UUIDString]]; + + break; + + case CUIHyperlinksHTML: + + tURL=[NSURL URLWithString:[NSString stringWithFormat:@"sharp://%@",tBinaryImage.UUID.UUIDString]]; + + break; + + default: + + break; + } + + if (tURL!=nil) + [tMutableBinaryImageAttributedString addAttributes:@{NSLinkAttributeName:tURL} range:NSMakeRange(0,tMutableBinaryImageAttributedString.length)]; + } + + [tMutableAttributedString appendAttributedString:tMutableBinaryImageAttributedString]; + + if ((tImageNameLength+4)>BINARYIMAGENAME_AND_SPACE_MAXLEN) + { + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode code:@" "]]; + } + else + { + NSString * tImageSpace=[@" " substringFromIndex:tImageNameLength]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode code:tImageSpace]]; + } + } + + NSUInteger tMachineInstructionAddress=tBinaryImage.loadAddress+bFrame.imageOffset; + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)==CUIStackFrameMachineInstructionAddressComponent) + { + [tMutableAttributedString appendAttributedString:[self attributedStringForMemoryAddressWithFormat:@"0x%016lx ",(unsigned long)tMachineInstructionAddress]]; + } + +#ifndef __DISABLE_SYMBOLICATION_ + + BOOL tSymbolicateAutomatically=[CUIApplicationPreferences sharedPreferences].symbolicateAutomatically; + + if (self.symbolicationMode==CUISymbolicationModeNone) + tSymbolicateAutomatically=NO; + + CUIStackFrame * tStackFrame=tStackFrames[bFrameIndex]; + CUISymbolicationData * tSymbolicationData=nil; + + if (tSymbolicateAutomatically==YES) + { + tSymbolicationData=tStackFrame.symbolicationData; + } + + if (tSymbolicationData!=nil) + { + if (tSymbolicationData.stackFrameSymbol==nil) + NSLog(@"Missing stackFrameSymbol"); + + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode code:[self.symbolicationDataFormatter stringForObjectValue:tSymbolicationData]]]; + } + else + { + if (tSymbolicateAutomatically==YES) + { + // Default values + + __block NSAttributedString * tCachedResultedAttributedString=nil; + + [[CUISymbolicationManager sharedSymbolicationManager] lookUpSymbolicationDataForMachineInstructionAddress:tMachineInstructionAddress-tBinaryImage.binaryImageOffset + binaryUUID:tBinaryImage.UUID.UUIDString + completionHandler:^(CUISymbolicationDataLookUpResult bLookUpResult, CUISymbolicationData *bSymbolicationData) { + + switch(bLookUpResult) + { + case CUISymbolicationDataLookUpResultError: + case CUISymbolicationDataLookUpResultNotFound: + + break; + + case CUISymbolicationDataLookUpResultFound: + { + tStackFrame.symbolicationData=bSymbolicationData; + + [[NSNotificationCenter defaultCenter] postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification + object:self.crashlog]; + + break; + } + + case CUISymbolicationDataLookUpResultFoundInCache: + { + tStackFrame.symbolicationData=bSymbolicationData; + + tCachedResultedAttributedString=[self attributedStringForUser:tIsUserCode code:[self.symbolicationDataFormatter stringForObjectValue:bSymbolicationData]]; + + break; + } + + } + + }]; + + if (tCachedResultedAttributedString==nil) + { + if (bFrame.symbol!=nil) + { + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode code:bFrame.symbol]]; + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==CUIStackFrameByteOffsetComponent) + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@" + %lu",(unsigned long)bFrame.symbolLocation]]; + } + else + { + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@"0x%lx",(unsigned long)tBinaryImage.loadAddress]]; + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==CUIStackFrameByteOffsetComponent) + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@" + %lu",(unsigned long)bFrame.imageOffset]]; + } + + if (bFrame.sourceFile!=nil) + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@" (%@:%lu)",bFrame.sourceFile,(unsigned long)bFrame.sourceLine]]; + } + else + { + [tMutableAttributedString appendAttributedString:tCachedResultedAttributedString]; + } + } + else + { + if (bFrame.symbol!=nil && (tIsUserCode==NO || self.symbolicationMode==CUISymbolicationModeSymbolicate)) + { + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode code:bFrame.symbol]]; + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==CUIStackFrameByteOffsetComponent) + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@" + %lu",(unsigned long)bFrame.symbolLocation]]; + } + else + { + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@"0x%lx",(unsigned long)tBinaryImage.loadAddress]]; + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==CUIStackFrameByteOffsetComponent) + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@" + %lu",(unsigned long)bFrame.imageOffset]]; + } + + if (bFrame.sourceFile!=nil) + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:tIsUserCode codeWithFormat:@" (%@:%lu)",bFrame.sourceFile,(unsigned long)bFrame.sourceLine]]; + } + } + +#endif + + [tMutableArray addObject:tMutableAttributedString]; + + }; + + + if (tBacktraces.hasApplicationSpecificBacktrace==YES) + { +#ifndef __DISABLE_SYMBOLICATION_ + tThreadIndexOffset=1; +#endif + NSMutableAttributedString * tMutableAttributedString=nil; + + tMutableAttributedString=[[self attributedStringForThreadLabelWithFormat:@"Application Specific Backtrace %lu",(unsigned long)1] mutableCopy]; + + [tMutableAttributedString addAttributes:@{ + CUIThreadAnchorAttributeName:@"thread:Application Specific Backtrace" + } + range:NSMakeRange(0, tMutableAttributedString.length)]; + + [tMutableArray addObject:tMutableAttributedString]; + + NSArray * tFrames=inIncident.exceptionInformation.lastExceptionBacktrace; + + if (tFrames!=nil) + { +#ifndef __DISABLE_SYMBOLICATION_ + tBacktraceThread=tBacktracesThreads.firstObject; + tStackFrames=tBacktraceThread.callStackBacktrace.stackFrames; +#endif + + [tFrames enumerateObjectsUsingBlock:transformThreadFrame]; + } + else + { + NSArray * tBacktraces=inIncident.diagnosticMessage.asi.backtraces; + + if (tBacktraces!=nil) + { + [tBacktraces enumerateObjectsUsingBlock:^(NSString * bString, NSUInteger bIndex, BOOL * bOutStop) { + + CUIThread * tThread=self.crashlog.backtraces.threads.firstObject; + + NSMutableArray * tLines=[NSMutableArray array]; + + [bString enumerateLinesUsingBlock:^(NSString * bLine, BOOL * _Nonnull stop) { + + [tLines addObject:bLine]; + }]; + + __block NSUInteger tStackFrameIndex=0; + + [tLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + if (bLine.length==0) + { + [tMutableArray addObject:@""]; + return; + } + + NSString * tProcessedStackFrameLine=[self processedStackFrameLine:bLine stackFrame:tThread.callStackBacktrace.stackFrames[tStackFrameIndex]]; + + if (tProcessedStackFrameLine!=nil) + { + [tMutableArray addObject:tProcessedStackFrameLine]; + } + else + { + NSLog(@"Error transforming line: %@",bLine); + + [tMutableArray addObject:[[NSAttributedString alloc] initWithString:bLine]]; + } + + tStackFrameIndex+=1; + }]; + }]; + } + } + + [tMutableArray addObject:@""]; + } + + [inIncident.threads enumerateObjectsUsingBlock:^(IPSThread * bThread, NSUInteger bThreadIndex, BOOL * bOutStop) { + + NSString * tCrashedString=(bThread.triggered==YES) ? @" Crashed":@""; + + NSMutableString * tThreadLabel=[NSMutableString stringWithFormat:@"Thread %lu%@:",(unsigned long)bThreadIndex,tCrashedString]; + + if (bThread.name!=nil || bThread.queue!=nil) + { + [tThreadLabel appendString:@": "]; + + if (bThread.name!=nil) + [tThreadLabel appendString:bThread.name]; + + if (bThread.queue!=nil) + [tThreadLabel appendFormat:@"%@Dispatch queue: %@",(bThread.name!=nil) ? @" ": @"",bThread.queue]; + } + + NSMutableAttributedString * tMutableAttributedString=nil; + + if (bThread.triggered==YES) + { + tMutableAttributedString=[[self attributedStringForCrashedThreadLabel:tThreadLabel] mutableCopy]; + + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + [tMutableAttributedString addAttributes:@{ + CUIGenericAnchorAttributeName:@"a:crashed_thread" + } + range:NSMakeRange(0, tMutableAttributedString.length)]; + + break; + + case CUIHyperlinksHTML: + { + NSURL * tURL=[NSURL URLWithString:@"anchor://crashed_thread"]; + + if (tURL!=nil) + [tMutableAttributedString addAttributes:@{NSLinkAttributeName:tURL} + range:NSMakeRange(0, tMutableAttributedString.length)]; + + break; + } + default: + + break; + } + } + else + { + if ((self.displaySettings.visibleSections & CUIDocumentBacktraceCrashedThreadSubSection)!=0) + return; + + tMutableAttributedString=[[self attributedStringForThreadLabel:tThreadLabel] mutableCopy]; + } + + [tMutableAttributedString addAttributes:@{ + CUIThreadAnchorAttributeName:[NSString stringWithFormat:@"thread:%lu",(unsigned long)bThreadIndex] + } + range:NSMakeRange(0, tMutableAttributedString.length)]; + + [tMutableArray addObject:tMutableAttributedString]; + +#ifndef __DISABLE_SYMBOLICATION_ + tBacktraceThread=tBacktracesThreads[bThreadIndex + tThreadIndexOffset]; + tStackFrames=tBacktraceThread.callStackBacktrace.stackFrames; +#endif + + [bThread.frames enumerateObjectsUsingBlock:transformThreadFrame]; + + [tMutableArray addObject:@""]; + }]; + + NSMutableAttributedString * tMutableAttributedString=tMutableArray.firstObject; + + if ([tMutableAttributedString isKindOfClass:[NSMutableAttributedString class]]==YES) + { + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Backtraces" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,tMutableAttributedString.length)]; + } + + return tMutableArray; +} + +- (NSArray *)attributedLinesForThreadStateOfIncident:(IPSIncident *)inIncident +{ + IPSIncidentHeader * tHeader=inIncident.header; + IPSThreadState * tCrashedThreadState=nil; + IPSIncidentExceptionInformation * tExceptionInformation=inIncident.exceptionInformation; + + NSMutableArray * tMutableArray=[NSMutableArray array]; + + IPSThreadInstructionState * tCrashThreadInstructionState=nil; + + if (tExceptionInformation.faultingThread=32 && tByteValue<127) + tASCIIRepresentation[tASCIIIndex]=tByteValue; + } + + [tMutableString appendFormat:@" %s",tASCIIRepresentation]; + + if (tByteIndex==tOffset) + [tMutableString appendString:@" <=="]; + + tAttributedString=[self attributedStringForPlainText:tMutableString]; + + [tMutableArray addObject:tAttributedString]; + } + + [tMutableArray addObject:@""]; + } + } + + NSMutableAttributedString * tMutableAttributedString=tMutableArray.firstObject; + + if ([tMutableAttributedString isKindOfClass:[NSMutableAttributedString class]]==YES) + { + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Thread State" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,tMutableAttributedString.length)]; + } + + return tMutableArray; +} + +- (NSArray *)attributedLinesForBinaryImagesOfIncident:(IPSIncident *)inIncident +{ + NSMutableArray * tMutableArray=[NSMutableArray array]; + + __block NSMutableAttributedString * tMutableAttributedString=[[self attributedStringForKey:@"Binary Images:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + BOOL tIsMonochromeTheme=self.themesProvider.currentTheme.isMonochrome; + + [[inIncident.binaryImages sortedArrayUsingSelector:@selector(compare:)] enumerateObjectsUsingBlock:^(IPSImage * bImage, NSUInteger bIndex, BOOL * bOutStop) { + + NSString * tSpaceString=@" "; + + NSString * tAddressString=[NSString stringWithFormat:@"0x%lx",bImage.loadAddress]; + + NSUInteger tLength=tAddressString.length; + + tMutableAttributedString=[[self attributedStringForPlainText:[tSpaceString substringFromIndex:tLength]] mutableCopy]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForMemoryAddress:tAddressString]]; + + [tMutableAttributedString appendAttributedString:[[self attributedStringForPlainText:@" - "] mutableCopy]]; + + tAddressString=[NSString stringWithFormat:@"0x%lx",bImage.loadAddress+bImage.size]; + + tLength=tAddressString.length; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:[tSpaceString substringFromIndex:tLength]]]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForMemoryAddress:tAddressString]]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + NSString * tBinaryImageIdentifier=(bImage.bundleIdentifier!=nil) ? bImage.bundleIdentifier : bImage.name; + + if (tBinaryImageIdentifier==nil) + tBinaryImageIdentifier=@"???"; + + if (tIsMonochromeTheme==YES) + { + if (bImage.isUserCode==YES) + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@"+"]]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:tBinaryImageIdentifier]]; + } + else + { + [tMutableAttributedString appendAttributedString:[self attributedStringForUser:bImage.isUserCode binaryImageIdentifier:tBinaryImageIdentifier]]; + } + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + if (bImage.bundleShortVersionString!=nil || bImage.bundleVersion!=nil) + { + if (bImage.bundleVersion==nil) + [tMutableAttributedString appendAttributedString:[self attributedStringForVersionWithFormat:@"(%@)",bImage.bundleShortVersionString]]; + else + [tMutableAttributedString appendAttributedString:[self attributedStringForVersionWithFormat:@"(%@ - %@)",(bImage.bundleShortVersionString!=nil) ? bImage.bundleShortVersionString : @"???",bImage.bundleVersion]]; + } + else + { + [tMutableAttributedString appendAttributedString:[self attributedStringForVersion:@"(???)"]]; + + } + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + NSString * tUUIDString=bImage.UUID.UUIDString; + + [tMutableAttributedString appendAttributedString:[self attributedStringForUUIDWithFormat:@"<%@>",tUUIDString]]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + [tMutableAttributedString appendAttributedString:[self attributedStringForPath:(bImage.path!=nil) ? bImage.path : @"???"]]; + + switch(self.hyperlinksStyle) + { + case CUIHyperlinksHTML: + { + NSURL * tURL=[NSURL URLWithString:[NSString stringWithFormat:@"anchor://%@",tUUIDString]]; + + if (tURL!=nil) + [tMutableAttributedString addAttributes:@{NSLinkAttributeName:tURL} + range:NSMakeRange(0, tMutableAttributedString.length)]; + + break; + } + + default: + + [tMutableAttributedString addAttributes:@{CUIBinaryAnchorAttributeName:[NSString stringWithFormat:@"bin:%@",tUUIDString]} + range:NSMakeRange(0, tMutableAttributedString.length)]; + + break; + } + + + [tMutableArray addObject:tMutableAttributedString]; + + }]; + + [tMutableArray addObject:@""]; + + // External Modification Summary + + if (inIncident.extMods!=nil) + { + __auto_type (^processStatistics)(IPSExternalModificationStatistics *) = ^(IPSExternalModificationStatistics * inObject) { + + tMutableAttributedString=[[self attributedStringForPlainText:@" "] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForKey:@"task_for_pid:"]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@"%ld",(long)inObject.taskForPid]]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForPlainText:@" "] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForKey:@"thread_create:"]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@"%ld",(long)inObject.threadCreate]]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForPlainText:@" "] mutableCopy]; + [tMutableAttributedString appendAttributedString:[self attributedStringForKey:@"thread_set_state:"]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainTextWithFormat:@"%ld",(long)inObject.threadSetState]]; + [tMutableAttributedString appendAttributedString:[self attributedStringForPlainText:@" "]]; + + [tMutableArray addObject:tMutableAttributedString]; + }; + + tMutableAttributedString=[[self attributedStringForKey:@"External Modification Summary:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForKey:@" Calls made by other processes targeting this process:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + processStatistics(inIncident.extMods.targeted); + + tMutableAttributedString=[[self attributedStringForKey:@" Calls made by this process:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + processStatistics(inIncident.extMods.caller); + + tMutableAttributedString=[[self attributedStringForKey:@" Calls made by all processes on this machine:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + processStatistics(inIncident.extMods.system); + + [tMutableArray addObject:@""]; + } + + // VM Summary + + if (inIncident.vmSummary!=nil) + { + tMutableAttributedString=[[self attributedStringForKey:@"VM Region Summary:"] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + + tMutableAttributedString=[[self attributedStringForPlainText:inIncident.vmSummary] mutableCopy]; + + [tMutableArray addObject:tMutableAttributedString]; + } + + tMutableAttributedString=tMutableArray.firstObject; + + if ([tMutableAttributedString isKindOfClass:[NSMutableAttributedString class]]==YES) + { + NSDictionary * tJumpAnchorAttributes=@{ + CUISectionAnchorAttributeName:@"section:Binary Images" + }; + + [tMutableAttributedString addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,tMutableAttributedString.length)]; + } + + return tMutableArray; +} + +#pragma mark - + +- (BOOL)transform +{ + if ([super transform]==NO) + return NO; + + IPSReport * tReport=(IPSReport *)self.input; + + if ([tReport isKindOfClass:[IPSReport class]]==NO) + { + // A COMPLETER + + return NO; + } + + [self updatesCachedAttributes]; + + IPSIncident * tIncident=tReport.incident; + + self.processPath=tIncident.header.processPath; + + NSMutableArray * tMutableArray=[NSMutableArray array]; + + // Header + + if ((self.displaySettings.visibleSections & CUIDocumentHeaderSection)==CUIDocumentHeaderSection) + { + NSArray * tAttributedLines=[self attributedLinesForHeaderOfIncident:tIncident]; + + if (tAttributedLines==nil) + return NO; + + [tMutableArray addObjectsFromArray:tAttributedLines]; + } + + // Exception Information + + if ((self.displaySettings.visibleSections & CUIDocumentExceptionInformationSection)==CUIDocumentExceptionInformationSection) + { + NSArray * tAttributedLines=[self attributedLinesForExceptionInformationOfIncident:tIncident]; + + if (tAttributedLines==nil) + return NO; + + [tMutableArray addObjectsFromArray:tAttributedLines]; + } + + // Diagnostic Message + + if ((self.displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)==CUIDocumentDiagnosticMessagesSection) + { + NSArray * tAttributedLines=[self attributedLinesForDiagnosticMessageOfIncident:tIncident]; + + if (tAttributedLines==nil) + return NO; + + [tMutableArray addObjectsFromArray:tAttributedLines]; + } + + // Backtraces + + if ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==CUIDocumentBacktracesSection) + { + NSArray * tAttributedLines=[self attributedLinesForBacktracesOfIncident:tIncident]; + + if (tAttributedLines==nil) + return NO; + + [tMutableArray addObjectsFromArray:tAttributedLines]; + } + + // Thread State + + if ((self.displaySettings.visibleSections & CUIDocumentThreadStateSection)==CUIDocumentThreadStateSection) + { + NSArray * tAttributedLines=[self attributedLinesForThreadStateOfIncident:tIncident]; + + if (tAttributedLines==nil) + return NO; + + [tMutableArray addObjectsFromArray:tAttributedLines]; + } + + // Binary Images + + if ((self.displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==CUIDocumentBinaryImagesSection) + { + NSArray * tAttributedLines=[self attributedLinesForBinaryImagesOfIncident:tIncident]; + + if (tAttributedLines==nil) + return NO; + + [tMutableArray addObjectsFromArray:tAttributedLines]; + } + + self.output=[self joinLines:tMutableArray withString:@"\n"]; + + return YES; +} + +#pragma mark - + +- (NSAttributedString *)joinLines:(NSArray *)inLines withString:(NSString *)inNewLineFeed +{ + NSMutableAttributedString * tMutableAttributedString=[NSMutableAttributedString new]; + + [inLines enumerateObjectsUsingBlock:^(id bLine, NSUInteger bLineNumber, BOOL * bOutStop) { + + if ([bLine isKindOfClass:[NSString class]]==YES) + { + NSAttributedString * tAttributedString=[[NSAttributedString alloc] initWithString:bLine + attributes:self.plainTextAttributes]; + + [tMutableAttributedString appendAttributedString:tAttributedString]; + + if (bLineNumber { IBOutlet NSImageView * _executableIconView; IBOutlet NSTextField * _executableNameValue; + IBOutlet NSButton * _codeSigningButton; + IBOutlet NSTextField * _executableVersionValue; IBOutlet NSTextField * _executableArchitectureValue; @@ -34,6 +38,8 @@ @interface CUIInspectorExecutableViewController () - (void)layoutView; +- (IBAction)showCodeSigningInformation:(id)sender; + - (IBAction)showExecutableInFinder:(id)sender; @end @@ -43,6 +49,30 @@ @implementation CUIInspectorExecutableViewController - (void)viewDidLoad { [super viewDidLoad]; + + if (_executablePathShowButton.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft) + { + // Mirror image. + NSImage * tOriginalImage=_executablePathShowButton.image; + + NSImage * newTemplate=[NSImage imageWithSize:_executablePathShowButton.bounds.size + flipped:NO drawingHandler:^BOOL(NSRect dstRect) { + + NSAffineTransform * tTransform = [NSAffineTransform transform]; + + [tTransform translateXBy:NSWidth(self->_executablePathShowButton.bounds) yBy:0]; + [tTransform scaleXBy:-1.0 yBy:1.0]; + [tTransform concat]; + + [tOriginalImage drawInRect:dstRect fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; + + return YES; + }]; + + newTemplate.template=YES; + + _executablePathShowButton.image=newTemplate; + } } #pragma mark - @@ -57,21 +87,55 @@ - (void)refreshUI _executableNameValue.stringValue=tHeader.processName; - NSString * tVersion=tHeader.executableVersion; - - if ([tVersion isEqualToString:@"???"]==YES) - { - _executableVersionValue.stringValue=NSLocalizedString(@"Unknown version",@""); - } - else - { - _executableVersionValue.stringValue=[NSString stringWithFormat:NSLocalizedString(@"Version %@",@""),tVersion]; - } + _codeSigningButton.hidden=(tCrashLog.ipsReport.incident.header.codeSigningInfo==nil); + + IPSIncidentHeader * tIncidentHeader=tCrashLog.ipsReport.incident.header; + + if (tIncidentHeader!=nil) + { + NSString * tShorttVersionString=tIncidentHeader.bundleInfo.bundleShortVersionString; + + if (tShorttVersionString==nil || [tShorttVersionString isEqualToString:@"???"]==YES) + { + _executableVersionValue.stringValue=NSLocalizedString(@"Unknown version",@""); + } + else + { + NSString * tBundleVersion=tIncidentHeader.bundleInfo.bundleVersion; + + if (tBundleVersion!=nil) + { + _executableVersionValue.stringValue=[NSString stringWithFormat:NSLocalizedString(@"Version %@ (%@)",@""),tShorttVersionString, tBundleVersion]; + } + else + { + _executableVersionValue.stringValue=[NSString stringWithFormat:NSLocalizedString(@"Version %@",@""),tShorttVersionString]; + } + } + } + else + { + NSString * tVersion=tHeader.executableVersion; + + if (tVersion==nil || [tVersion isEqualToString:@"???"]==YES) + { + _executableVersionValue.stringValue=NSLocalizedString(@"Unknown version",@""); + } + else + { + _executableVersionValue.stringValue=[NSString stringWithFormat:NSLocalizedString(@"Version %@",@""),tVersion]; + } + } NSString * tArchitectureValue=@"-"; switch(tHeader.codeType) { + case CUICodeTypeX86: + + tArchitectureValue=@"i386"; + break; + case CUICodeTypeX86_64: tArchitectureValue=@"x86-64"; @@ -164,6 +228,33 @@ - (void)layoutView #pragma mark - +- (IBAction)showCodeSigningInformation:(id)sender +{ + NSPopover * tCodeSigningInformationPopOver = [NSPopover new]; + tCodeSigningInformationPopOver.contentSize=NSMakeSize(500.0, 20.0); + tCodeSigningInformationPopOver.behavior=NSPopoverBehaviorTransient; + tCodeSigningInformationPopOver.animates=NO; + tCodeSigningInformationPopOver.delegate=self; + + NSAppearanceName tAppearanceName = ([self.view WB_isEffectiveAppearanceDarkAqua] == NO) ? WB_NSAppearanceNameAqua : WB_NSAppearanceNameDarkAqua; + + tCodeSigningInformationPopOver.appearance = [NSAppearance appearanceNamed:tAppearanceName]; + + NSViewController * tPopUpViewController=[[CUICodeSigningInformationViewController alloc] initWithCodeSigningInfo:self.crashLog.ipsReport.incident.header.codeSigningInfo]; + + tCodeSigningInformationPopOver.contentViewController=tPopUpViewController; + + tCodeSigningInformationPopOver.contentSize=tPopUpViewController.view.bounds.size; + + NSView * tTrick=tPopUpViewController.view; // This is used to trigger the viewDidLoad method of the contentViewController. + + (void)tTrick; + + [tCodeSigningInformationPopOver showRelativeToRect:_codeSigningButton.bounds + ofView:_codeSigningButton + preferredEdge:NSMaxXEdge]; +} + - (IBAction)showExecutableInFinder:(id)sender { NSWorkspace * tSharedWorkspace=[NSWorkspace sharedWorkspace]; @@ -176,4 +267,14 @@ - (IBAction)showExecutableInFinder:(id)sender [tSharedWorkspace selectFile:tExecutablePath inFileViewerRootedAtPath:@""]; } +#pragma mark - NSPopoverDelegate + +- (void)popoverDidClose:(NSNotification *)inNotification +{ + NSWindow * tWindow=self.view.window; + + if (tWindow.firstResponder==tWindow.contentView) + [tWindow makeFirstResponder:self]; +} + @end diff --git a/app_unexpectedly/app_unexpectedly/CUIInspectorGeneralViewController.m b/app_unexpectedly/app_unexpectedly/CUIInspectorGeneralViewController.m index 8fb9116..157144a 100644 --- a/app_unexpectedly/app_unexpectedly/CUIInspectorGeneralViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIInspectorGeneralViewController.m @@ -45,18 +45,18 @@ - (void)viewDidAppear [self refreshDate]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(systemClockDidChange:) name:NSCurrentLocaleDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(systemClockDidChange:) name:NSCurrentLocaleDidChangeNotification object:nil]; } - (void)viewWillDisappear { [super viewWillDisappear]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewFrameDidChangeNotification object:self.view]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSViewFrameDidChangeNotification object:self.view]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; } #pragma mark - @@ -69,6 +69,7 @@ - (void)refreshDate dispatch_once(&onceToken, ^{ NSDateFormatter * tLongMediumFormatter=[NSDateFormatter new]; + tLongMediumFormatter.locale=[NSLocale autoupdatingCurrentLocale]; tLongMediumFormatter.formatterBehavior=NSDateFormatterBehavior10_4; tLongMediumFormatter.dateStyle=NSDateFormatterLongStyle; diff --git a/app_unexpectedly/app_unexpectedly/CUIInspectorProcessesViewController.m b/app_unexpectedly/app_unexpectedly/CUIInspectorProcessesViewController.m index 6d009b6..daaa5aa 100644 --- a/app_unexpectedly/app_unexpectedly/CUIInspectorProcessesViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIInspectorProcessesViewController.m @@ -35,19 +35,21 @@ - (void)refreshUI // Processes - _processNameValue.stringValue=[NSString stringWithFormat:@"%@ (%u)",tHeader.processName,tHeader.processIdentifier]; + NSString * tProcessFormatString=NSLocalizedString(@"%@ (%u)", @""); + + _processNameValue.stringValue=[NSString stringWithFormat:tProcessFormatString,tHeader.processName,tHeader.processIdentifier]; NSString * tParentProcessName=tHeader.parentProcessName; if ([tParentProcessName isEqualToString:@"???"]==YES && tHeader.parentProcessIdentifier==1) tParentProcessName=@"launchd"; - _parentProcessNameValue.stringValue=[NSString stringWithFormat:@"%@ (%u)",tParentProcessName,tHeader.parentProcessIdentifier]; + _parentProcessNameValue.stringValue=[NSString stringWithFormat:tProcessFormatString,tParentProcessName,tHeader.parentProcessIdentifier]; if (tHeader.responsibleProcessName==nil && tHeader.responsibleProcessIdentifier==0) _responsibleProcessNameValue.stringValue=@"-"; else - _responsibleProcessNameValue.stringValue=[NSString stringWithFormat:@"%@ (%u)",tHeader.responsibleProcessName,tHeader.responsibleProcessIdentifier]; + _responsibleProcessNameValue.stringValue=[NSString stringWithFormat:tProcessFormatString,tHeader.responsibleProcessName,tHeader.responsibleProcessIdentifier]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIInspectorViewController.m b/app_unexpectedly/app_unexpectedly/CUIInspectorViewController.m index 2499b6d..7d1e13e 100644 --- a/app_unexpectedly/app_unexpectedly/CUIInspectorViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIInspectorViewController.m @@ -84,7 +84,7 @@ - (void)viewDidLoad [self refreshLayout]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; } #pragma mark - diff --git a/app_unexpectedly/app_unexpectedly/CUILineJumperWindowController.m b/app_unexpectedly/app_unexpectedly/CUILineJumperWindowController.m index 9942bae..5c9fb22 100644 --- a/app_unexpectedly/app_unexpectedly/CUILineJumperWindowController.m +++ b/app_unexpectedly/app_unexpectedly/CUILineJumperWindowController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -178,7 +178,9 @@ - (IBAction)takeLineNumberFrom:(NSTextField *)sender NSUInteger tGlyphIndex = 0; - for (NSUInteger tLineNumber = 1; tGlyphIndex < tNumberOfGlyphs; tLineNumber++) + NSString *text = _targetedTextView.string; + + for (NSUInteger tLineNumber = 1; tGlyphIndex < tNumberOfGlyphs;) { NSRange tLineRange; @@ -207,7 +209,19 @@ - (IBAction)takeLineNumberFrom:(NSTextField *)sender return; } - tGlyphIndex = NSMaxRange(tLineRange); + tGlyphIndex=NSMaxRange(tLineRange); + + NSUInteger characterIndex=[tLayoutManager characterIndexForGlyphAtIndex:tGlyphIndex]; + + if (characterIndex > 0) + { + if ([text characterAtIndex:characterIndex-1]=='\n') + tLineNumber++; + } + else + { + tLineNumber++; + } } // Line not found (tLineNumberToJumpTo > number of lines) diff --git a/app_unexpectedly/app_unexpectedly/CUIMainWindowController.m b/app_unexpectedly/app_unexpectedly/CUIMainWindowController.m index 46f730a..639c382 100644 --- a/app_unexpectedly/app_unexpectedly/CUIMainWindowController.m +++ b/app_unexpectedly/app_unexpectedly/CUIMainWindowController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -25,7 +25,9 @@ extern NSString * const CUIBottomViewCollapseStateDidChangeNotification; -@interface CUIMainWindowController () +extern NSString * const CUIDefaultsBottomViewCollapsedKey; + +@interface CUIMainWindowController () { CUICrashLogsMainViewController * _mainViewController; @@ -54,7 +56,7 @@ @implementation CUIMainWindowController - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -70,7 +72,7 @@ - (void)windowDidLoad // Register for notifications - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; @@ -122,7 +124,7 @@ - (void)noResponderFor:(SEL)inEventSelector if (inEventSelector!=@selector(keyDown:)) return; - [[NSNotificationCenter defaultCenter] postNotificationName:@"windowDidNotHandleKeyEventNotification" object:self.window userInfo:@{@"Event":[NSApp currentEvent]}]; + [NSNotificationCenter.defaultCenter postNotificationName:@"windowDidNotHandleKeyEventNotification" object:self.window userInfo:@{@"Event":[NSApp currentEvent]}]; } - (IBAction)CUIMENUACTION_showHideRegisters:(id)sender @@ -137,7 +139,7 @@ - (IBAction)CUIMENUACTION_showHideRegisters:(id)sender { [tRegistersWindowController showWindow:nil]; - _registersWindowButton.state=NSOnState; + _registersWindowButton.state=NSControlStateValueOn; } } @@ -174,9 +176,27 @@ - (void)contentsViewPresentationModeDidChange:(NSNotification *)inNotification if (tNumber==nil) return; - [_presentationModeSegmentedControl selectSegmentWithTag:tNumber.integerValue]; + NSUInteger tMode=tNumber.integerValue; + + [_presentationModeSegmentedControl selectSegmentWithTag:tMode]; + + [_mainLayoutSegmentedControl setEnabled:(tMode==1) forSegment:1]; - [_mainLayoutSegmentedControl setEnabled:(tNumber.integerValue==1) forSegment:1]; + if (tMode!=1) + { + [_mainLayoutSegmentedControl setSelected:NO forSegment:1]; + } + else + { + BOOL tIsCollapsed=NO; + + tNumber=[[NSUserDefaults standardUserDefaults] objectForKey:CUIDefaultsBottomViewCollapsedKey]; + + if (tNumber==nil || [tNumber boolValue]==YES) + tIsCollapsed=YES; + + [_mainLayoutSegmentedControl setSelected:(tIsCollapsed==NO) forSegment:1]; + } } - (void)crashLogsSelectionDidChange:(NSNotification *)inNotification @@ -188,7 +208,7 @@ - (void)crashLogsSelectionDidChange:(NSNotification *)inNotification _presentationModeSegmentedControl.enabled=(tSelection.crashLogs.count>0); - if (_presentationModeSegmentedControl.selectedSegment==1) + if ([_presentationModeSegmentedControl tagForSegment:_presentationModeSegmentedControl.selectedSegment]==1) { [_mainLayoutSegmentedControl setEnabled:(tSelection.crashLogs.count>0) forSegment:1]; } @@ -205,7 +225,7 @@ - (void)crashLogsSelectionDidChange:(NSNotification *)inNotification NSString * tCrashLogFilePath=tCrashLog.crashLogFilePath; - self.window.title=[tCrashLogFilePath lastPathComponent]; + self.window.title=tCrashLogFilePath.lastPathComponent; self.window.representedFilename=tCrashLogFilePath; } @@ -223,7 +243,7 @@ - (void)windowWillClose:(NSNotification *)inNotification if ([tWindow.windowController isKindOfClass:[CUIRegistersWindowController class]]==YES) { - _registersWindowButton.state=NSOffState; + _registersWindowButton.state=NSControlStateValueOff; } } diff --git a/app_unexpectedly/app_unexpectedly/CUINavigationChevronView.m b/app_unexpectedly/app_unexpectedly/CUINavigationChevronView.m index 2de7918..2c40082 100644 --- a/app_unexpectedly/app_unexpectedly/CUINavigationChevronView.m +++ b/app_unexpectedly/app_unexpectedly/CUINavigationChevronView.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2023, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -24,9 +24,19 @@ - (void)drawRect:(NSRect)dirtyRect CGFloat tMidY=round(NSMidY(tBounds)); NSBezierPath * tBezierPath=[NSBezierPath bezierPath]; - [tBezierPath moveToPoint:NSMakePoint(NSMaxX(tBounds)-5,NSMaxY(tBounds))]; - [tBezierPath lineToPoint:NSMakePoint(NSMaxX(tBounds)-1,tMidY)]; - [tBezierPath lineToPoint:NSMakePoint(NSMaxX(tBounds)-5,NSMinY(tBounds))]; + + if (self.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + [tBezierPath moveToPoint:NSMakePoint(NSMaxX(tBounds)-5,NSMaxY(tBounds))]; + [tBezierPath lineToPoint:NSMakePoint(NSMaxX(tBounds)-1,tMidY)]; + [tBezierPath lineToPoint:NSMakePoint(NSMaxX(tBounds)-5,NSMinY(tBounds))]; + } + else + { + [tBezierPath moveToPoint:NSMakePoint(NSMaxX(tBounds)-5,NSMaxY(tBounds))]; + [tBezierPath lineToPoint:NSMakePoint(NSMaxX(tBounds)-9,tMidY)]; + [tBezierPath lineToPoint:NSMakePoint(NSMaxX(tBounds)-5,NSMinY(tBounds))]; + } [tBezierPath stroke]; } diff --git a/app_unexpectedly/app_unexpectedly/CUIOutlineModeDisplaySettings.m b/app_unexpectedly/app_unexpectedly/CUIOutlineModeDisplaySettings.m index 0f03750..8558bed 100644 --- a/app_unexpectedly/app_unexpectedly/CUIOutlineModeDisplaySettings.m +++ b/app_unexpectedly/app_unexpectedly/CUIOutlineModeDisplaySettings.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,7 +21,7 @@ @implementation CUIOutlineModeDisplaySettings - (instancetype)initWithRepresentation:(NSDictionary *)inDictionary { - if ([inDictionary isKindOfClass:[NSDictionary class]]==NO) + if ([inDictionary isKindOfClass:NSDictionary.class]==NO) return nil; self=[super init]; @@ -30,18 +30,18 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inDictionary { NSNumber * tNumber=inDictionary[CUIOutlineModeDisplaySettingsShowOnlyCrashedThreadKey]; - if ([tNumber isKindOfClass:[NSNumber class]]==NO) + if ([tNumber isKindOfClass:NSNumber.class]==NO) return nil; - _showOnlyCrashedThread=[tNumber boolValue]; + _showOnlyCrashedThread=tNumber.boolValue; tNumber=inDictionary[CUIOutlineModeDisplaySettingsVisibleStackFrameComponentsKey]; - if ([tNumber isKindOfClass:[NSNumber class]]==NO) + if ([tNumber isKindOfClass:NSNumber.class]==NO) return nil; - _visibleStackFrameComponents=[tNumber unsignedIntegerValue]; + _visibleStackFrameComponents=tNumber.unsignedIntegerValue; } return self; diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneAdvancedViewController.h b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneAdvancedViewController.h new file mode 100644 index 0000000..a0270fa --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneAdvancedViewController.h @@ -0,0 +1,22 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIPreferencePaneViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CUIPreferencePaneAdvancedViewController : CUIPreferencePaneViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneAdvancedViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneAdvancedViewController.m new file mode 100644 index 0000000..a262ad0 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneAdvancedViewController.m @@ -0,0 +1,75 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIPreferencePaneAdvancedViewController.h" + +#import "WBRemoteVersionChecker.h" + +extern NSString * const CUIApplicationShowDebugMenuKey; + +extern NSString * const CUIApplicationShowDebugDidChangeNotification; + +@interface CUIPreferencePaneAdvancedViewController () +{ + IBOutlet NSButton * _remoteVersionCheckerCheckbox; + + IBOutlet NSButton * _showDebugMenuCheckbox; +} + +- (IBAction)switchRemoteVersionCheck:(id)sender; + +- (IBAction)switchShowDebugMenu:(id)sender; + +@end + +@implementation CUIPreferencePaneAdvancedViewController + +- (NSString *)nibName +{ + return @"CUIPreferencePaneAdvancedViewController"; +} + +#pragma mark - + +- (void)viewWillAppear +{ + [super viewWillAppear]; + + // Remote Version Check + + _remoteVersionCheckerCheckbox.state=([WBRemoteVersionChecker sharedChecker].isCheckEnabled==YES) ? NSControlStateValueOn: NSControlStateValueOff; + + // Show Debug Menu + + NSUserDefaults * tDefaults=[NSUserDefaults standardUserDefaults]; + + _showDebugMenuCheckbox.state=([tDefaults boolForKey:CUIApplicationShowDebugMenuKey]==YES) ? NSControlStateValueOn: NSControlStateValueOff; +} + +#pragma mark - + +- (IBAction)switchRemoteVersionCheck:(NSButton *)sender +{ + [WBRemoteVersionChecker sharedChecker].checkEnabled=(sender.state==NSControlStateValueOn); +} + +- (IBAction)switchShowDebugMenu:(NSButton *)sender +{ + NSUserDefaults * tDefaults=[NSUserDefaults standardUserDefaults]; + + [tDefaults setBool:(sender.state==NSControlStateValueOn) forKey:CUIApplicationShowDebugMenuKey]; + + [NSNotificationCenter.defaultCenter postNotificationName:CUIApplicationShowDebugDidChangeNotification object:nil]; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneCrashreporterViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneCrashreporterViewController.m index d1e9e98..de11321 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneCrashreporterViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneCrashreporterViewController.m @@ -65,8 +65,8 @@ - (void)viewDidAppear // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:nil]; } - (void)viewWillDisappear @@ -80,8 +80,8 @@ - (void)viewWillDisappear // Remove observer - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidResignActiveNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSApplicationDidResignActiveNotification object:nil]; } #pragma mark - @@ -94,17 +94,17 @@ - (void)refresh NSButton * tRadioButton=[_dialogTypeGroup viewWithTag:tDefaults.dialogType]; - tRadioButton.state=NSOnState; + tRadioButton.state=NSControlStateValueOn; // Notification Mode tRadioButton=[_notificationModeGroup viewWithTag:tDefaults.notificationMode]; - tRadioButton.state=NSOnState; + tRadioButton.state=NSControlStateValueOn; // Report Uncaught Exceptions - _reportUncaughtExceptionsCheckbox.state=(tDefaults.reportUncaughtExceptions==YES) ? NSOnState : NSOffState; + _reportUncaughtExceptionsCheckbox.state=(tDefaults.reportUncaughtExceptions==YES) ? NSControlStateValueOn : NSControlStateValueOff; } #pragma mark - @@ -127,7 +127,7 @@ - (IBAction)switchReportUncaughtException:(NSButton *)sender { CUICrashReporterDefaults * tDefaults=[CUICrashReporterDefaults standardCrashReporterDefaults]; - tDefaults.reportUncaughtExceptions=(sender.state==NSOnState); + tDefaults.reportUncaughtExceptions=(sender.state==NSControlStateValueOn); } #pragma mark - Notifications diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneFontscolorsViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneFontscolorsViewController.m index 8034d45..88e5cb8 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneFontscolorsViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneFontscolorsViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -37,7 +37,7 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation newUUID: @end -@interface CUIPreferencePaneFontscolorsViewController () +@interface CUIPreferencePaneFontscolorsViewController () { IBOutlet NSTableView * _themesTableView; @@ -139,7 +139,7 @@ - (void)viewDidLoad _selectedPresentationMode=CUIPresentationModeText; - [((NSButton *)[_presentationModeTabHeaderView viewWithTag:_selectedPresentationMode]) setState:NSOnState]; + [((NSButton *)[_presentationModeTabHeaderView viewWithTag:_selectedPresentationMode]) setState:NSControlStateValueOn]; ((NSClipView *)_categoriesTableView.superview).drawsBackground=YES; @@ -178,18 +178,18 @@ - (void)viewDidAppear [self.view.window makeFirstResponder:_categoriesTableView]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(currentThemeDidChange:) name:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(currentThemeDidChange:) name:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; } - (void)viewWillDisappear { [super viewWillDisappear]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:CUIThemesManagerThemesListDidChangeNotification object:nil]; } #pragma mark - @@ -367,7 +367,7 @@ - (IBAction)delete:(id)sender NSAlert * tAlert=[NSAlert new]; tAlert.messageText=[NSString stringWithFormat:NSLocalizedString(@"Do you really want to remove the \"%@\" theme?", @""),tTheme.name]; - tAlert.informativeText=NSLocalizedString(@"This cannot be undone", @""); + tAlert.informativeText=NSLocalizedString(@"This cannot be undone.", @""); [tAlert addButtonWithTitle:NSLocalizedString(@"Remove",@"")]; [tAlert addButtonWithTitle:NSLocalizedString(@"Cancel",@"")]; diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneGeneralViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneGeneralViewController.m index 2de3743..85e123e 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneGeneralViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneGeneralViewController.m @@ -156,7 +156,7 @@ - (void)viewWillAppear CUIApplicationPreferences * tPreferences=[CUIApplicationPreferences sharedPreferences]; - _showsRegistersWindowAtLaunchCheckbox.state=(tPreferences.showsRegistersWindowAutomaticallyAtLaunch==YES) ? NSOnState : NSOffState; + _showsRegistersWindowAtLaunchCheckbox.state=(tPreferences.showsRegistersWindowAutomaticallyAtLaunch==YES) ? NSControlStateValueOn : NSControlStateValueOff; NSURL * tPreferedApplicationURL=tPreferences.preferedSourceCodeEditorURL; @@ -210,7 +210,7 @@ - (void)viewWillAppear - (IBAction)switchShowsRegisterWindowAtLaunch:(NSButton *)sender { - [CUIApplicationPreferences sharedPreferences].showsRegistersWindowAutomaticallyAtLaunch=(sender.state==NSOnState); + [CUIApplicationPreferences sharedPreferences].showsRegistersWindowAutomaticallyAtLaunch=(sender.state==NSControlStateValueOn); } - (IBAction)switchPreferedSourceCodeEditor:(NSPopUpButton *)sender @@ -230,6 +230,13 @@ - (IBAction)switchDefaultReportsViewer:(NSPopUpButton *)sender { // A VOIR (report error if we can figure out which error values this method can return) } + + tResult=LSSetDefaultRoleHandlerForContentType(CFSTR("com.apple.ips"),kLSRolesViewer,(__bridge CFStringRef) tAttributes.bundleIdentifier); + + if (tResult != noErr) + { + // A VOIR (report error if we can figure out which error values this method can return) + } } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationOutlineViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationOutlineViewController.m index 54768bc..942c469 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationOutlineViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationOutlineViewController.m @@ -75,11 +75,11 @@ - (void)viewWillAppear // Stack Frame - _showBinaryNameCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSOnState : NSOffState; + _showBinaryNameCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showMachineInstructionAddressCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSOnState : NSOffState; + _showMachineInstructionAddressCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showByteOffsetCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSOnState : NSOffState; + _showByteOffsetCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; } #pragma mark - @@ -98,17 +98,17 @@ - (void)_setStackFrameComponent:(CUIStackFrameComponents)inComponent visible:(BO - (IBAction)switchShowBinaryName:(NSButton *)sender { - [self _setStackFrameComponent:CUIStackFrameBinaryNameComponent visible:(sender.state==NSOnState)]; + [self _setStackFrameComponent:CUIStackFrameBinaryNameComponent visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowMachineInstructionAddress:(NSButton *)sender { - [self _setStackFrameComponent:CUIStackFrameMachineInstructionAddressComponent visible:(sender.state==NSOnState)]; + [self _setStackFrameComponent:CUIStackFrameMachineInstructionAddressComponent visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowByteOffset:(NSButton *)sender { - [self _setStackFrameComponent:CUIStackFrameByteOffsetComponent visible:(sender.state==NSOnState)]; + [self _setStackFrameComponent:CUIStackFrameByteOffsetComponent visible:(sender.state==NSControlStateValueOn)]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationTextViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationTextViewController.m index 8b6fc0b..ace71bc 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationTextViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationTextViewController.m @@ -103,31 +103,31 @@ - (void)viewWillAppear // Document - _showsLineNumbersCheckbox.state=(_applicationPreferences.showsLineNumbers==YES) ? NSOnState : NSOffState; + _showsLineNumbersCheckbox.state=(_applicationPreferences.showsLineNumbers==YES) ? NSControlStateValueOn : NSControlStateValueOff; - _lineWrappingCheckbox.state=(_applicationPreferences.lineWrapping==YES) ? NSOnState : NSOffState; + _lineWrappingCheckbox.state=(_applicationPreferences.lineWrapping==YES) ? NSControlStateValueOn : NSControlStateValueOff; // Sections - _showHeaderCheckbox.state=((_displaySettings.visibleSections & CUIDocumentHeaderSection)!=0) ? NSOnState : NSOffState; + _showHeaderCheckbox.state=((_displaySettings.visibleSections & CUIDocumentHeaderSection)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showExceptionInformationCheckbox.state=((_displaySettings.visibleSections & CUIDocumentExceptionInformationSection)!=0) ? NSOnState : NSOffState; + _showExceptionInformationCheckbox.state=((_displaySettings.visibleSections & CUIDocumentExceptionInformationSection)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showDiagnosticMessagesCheckbox.state=((_displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)!=0) ? NSOnState : NSOffState; + _showDiagnosticMessagesCheckbox.state=((_displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showBacktracesCheckbox.state=((_displaySettings.visibleSections & CUIDocumentBacktracesSection)!=0) ? NSOnState : NSOffState; + _showBacktracesCheckbox.state=((_displaySettings.visibleSections & CUIDocumentBacktracesSection)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showThreadStateCheckbox.state=((_displaySettings.visibleSections & CUIDocumentThreadStateSection)!=0) ? NSOnState : NSOffState; + _showThreadStateCheckbox.state=((_displaySettings.visibleSections & CUIDocumentThreadStateSection)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showBinaryImagesCheckbox.state=((_displaySettings.visibleSections & CUIDocumentBinaryImagesSection)!=0) ? NSOnState : NSOffState; + _showBinaryImagesCheckbox.state=((_displaySettings.visibleSections & CUIDocumentBinaryImagesSection)!=0) ? NSControlStateValueOn : NSControlStateValueOff; // Stack Frame - _showBinaryNameCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSOnState : NSOffState; + _showBinaryNameCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showMachineInstructionAddressCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSOnState : NSOffState; + _showMachineInstructionAddressCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; - _showByteOffsetCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSOnState : NSOffState; + _showByteOffsetCheckbox.state=((_displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)!=0) ? NSControlStateValueOn : NSControlStateValueOff; } #pragma mark - @@ -156,57 +156,57 @@ - (void)_setStackFrameComponent:(CUIStackFrameComponents)inComponent visible:(BO - (IBAction)switchShowsLineNumbers:(NSButton *)sender { - _applicationPreferences.showsLineNumbers=(sender.state==NSOnState); + _applicationPreferences.showsLineNumbers=(sender.state==NSControlStateValueOn); } - (IBAction)switchLineWrapping:(NSButton *)sender { - _applicationPreferences.lineWrapping=(sender.state==NSOnState); + _applicationPreferences.lineWrapping=(sender.state==NSControlStateValueOn); } - (IBAction)switchShowHeader:(NSButton *)sender { - [self _setSection:CUIDocumentHeaderSection visible:(sender.state==NSOnState)]; + [self _setSection:CUIDocumentHeaderSection visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowExceptionInformation:(NSButton *)sender { - [self _setSection:CUIDocumentExceptionInformationSection visible:(sender.state==NSOnState)]; + [self _setSection:CUIDocumentExceptionInformationSection visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowDiagnosticMessages:(NSButton *)sender { - [self _setSection:CUIDocumentDiagnosticMessagesSection visible:(sender.state==NSOnState)]; + [self _setSection:CUIDocumentDiagnosticMessagesSection visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowBacktraces:(NSButton *)sender { - [self _setSection:CUIDocumentBacktracesSection visible:(sender.state==NSOnState)]; + [self _setSection:CUIDocumentBacktracesSection visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowThreadState:(NSButton *)sender { - [self _setSection:CUIDocumentThreadStateSection visible:(sender.state==NSOnState)]; + [self _setSection:CUIDocumentThreadStateSection visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowBinaryImages:(NSButton *)sender { - [self _setSection:CUIDocumentBinaryImagesSection visible:(sender.state==NSOnState)]; + [self _setSection:CUIDocumentBinaryImagesSection visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowBinaryName:(NSButton *)sender { - [self _setStackFrameComponent:CUIStackFrameBinaryNameComponent visible:(sender.state==NSOnState)]; + [self _setStackFrameComponent:CUIStackFrameBinaryNameComponent visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowMachineInstructionAddress:(NSButton *)sender { - [self _setStackFrameComponent:CUIStackFrameMachineInstructionAddressComponent visible:(sender.state==NSOnState)]; + [self _setStackFrameComponent:CUIStackFrameMachineInstructionAddressComponent visible:(sender.state==NSControlStateValueOn)]; } - (IBAction)switchShowByteOffset:(NSButton *)sender { - [self _setStackFrameComponent:CUIStackFrameByteOffsetComponent visible:(sender.state==NSOnState)]; + [self _setStackFrameComponent:CUIStackFrameByteOffsetComponent visible:(sender.state==NSControlStateValueOn)]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationViewController.m index 8166b7f..9e3ae5e 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePanePresentationViewController.m @@ -47,7 +47,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - [((NSButton *)[_presentationModeTabHeaderView viewWithTag:CUIPresentationModeText]) setState:NSOnState]; + [((NSButton *)[_presentationModeTabHeaderView viewWithTag:CUIPresentationModeText]) setState:NSControlStateValueOn]; [self showPaneForPresentationMode:CUIPresentationModeText]; } diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneSymbolicationViewController.m b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneSymbolicationViewController.m index 1618d29..9f52573 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencePaneSymbolicationViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencePaneSymbolicationViewController.m @@ -58,9 +58,9 @@ - (void)viewWillAppear CUIApplicationPreferences * tPreferences=[CUIApplicationPreferences sharedPreferences]; - _symbolicateButton.state=(tPreferences.symbolicateAutomatically==YES) ? NSOnState : NSOffState; + _symbolicateButton.state=(tPreferences.symbolicateAutomatically==YES) ? NSControlStateValueOn : NSControlStateValueOff; - _searchForSymbolsFilesButton.state=(tPreferences.searchForSymbolsFilesAutomatically==YES) ? NSOnState : NSOffState; + _searchForSymbolsFilesButton.state=(tPreferences.searchForSymbolsFilesAutomatically==YES) ? NSControlStateValueOn : NSControlStateValueOff; } #pragma mark - @@ -79,12 +79,12 @@ - (CGFloat)maximumHeight - (IBAction)switchSymbolicate:(NSButton *)sender { - [CUIApplicationPreferences sharedPreferences].symbolicateAutomatically=(sender.state==NSOnState); + [CUIApplicationPreferences sharedPreferences].symbolicateAutomatically=(sender.state==NSControlStateValueOn); } - (IBAction)switchSearchForSymbolFiles:(NSButton *)sender { - [CUIApplicationPreferences sharedPreferences].searchForSymbolsFilesAutomatically=(sender.state==NSOnState); + [CUIApplicationPreferences sharedPreferences].searchForSymbolsFilesAutomatically=(sender.state==NSControlStateValueOn); } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIPreferencesTabButton.m b/app_unexpectedly/app_unexpectedly/CUIPreferencesTabButton.m index 71d0036..978f2ca 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPreferencesTabButton.m +++ b/app_unexpectedly/app_unexpectedly/CUIPreferencesTabButton.m @@ -45,9 +45,9 @@ - (void)mouseUp:(NSEvent *)inEvent { if (_pushed==YES) { - if ([self state]!=NSOnState) + if ([self state]!=NSControlStateValueOn) { - [self setState:NSOnState]; + [self setState:NSControlStateValueOn]; [self sendAction:[self action] to:[self target]]; } @@ -66,7 +66,7 @@ - (void)drawRect:(NSRect)inRect BOOL tIsDark=[self WB_isEffectiveAppearanceDarkAqua]; NSColor * tColor; - if (self.state==NSOnState) + if (self.state==NSControlStateValueOn) { if (tIsDark==NO) { diff --git a/app_unexpectedly/app_unexpectedly/CUIPresentationTextNavigationViewController.m b/app_unexpectedly/app_unexpectedly/CUIPresentationTextNavigationViewController.m index 2575a7c..0bf1aeb 100644 --- a/app_unexpectedly/app_unexpectedly/CUIPresentationTextNavigationViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIPresentationTextNavigationViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ #define GROSSE_CHIURE_APPKIT_VERSION_NUMBER 1894 #define GROSSE_CHIURE_EXTRA_WIDTH 5 -@interface CUIPresentationTextNavigationViewController () +@interface CUIPresentationTextNavigationViewController () { IBOutlet NSPopUpButton * _sourcesPopUpButton; @@ -127,6 +127,39 @@ - (void)viewDidLoad { [super viewDidLoad]; + // Set the autoresizing masks based on the layout direction + + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + _sourcesPopUpButton.autoresizingMask=NSViewMaxXMargin|NSViewMinYMargin; + _sourcesPopUpButton.imagePosition=NSImageLeading; + + _sourcesChevronView.autoresizingMask=NSViewMaxXMargin|NSViewMinYMargin; + + _crashLogsPopUpButton.autoresizingMask=NSViewMaxXMargin|NSViewMinYMargin; + _crashLogsPopUpButton.imagePosition=NSImageLeading; + + _crashLogsChevronView.autoresizingMask=NSViewMaxXMargin|NSViewMinYMargin; + + _sectionsPopUpButton.autoresizingMask=NSViewMaxXMargin|NSViewMinYMargin; + _sectionsPopUpButton.imagePosition=NSImageLeading; + } + else + { + _sourcesPopUpButton.autoresizingMask=NSViewMinXMargin|NSViewMinYMargin; + _sourcesPopUpButton.imagePosition=NSImageTrailing; + + _sourcesChevronView.autoresizingMask=NSViewMinXMargin|NSViewMinYMargin; + + _crashLogsPopUpButton.autoresizingMask=NSViewMinXMargin|NSViewMinYMargin; + _crashLogsPopUpButton.imagePosition=NSImageTrailing; + + _crashLogsChevronView.autoresizingMask=NSViewMinXMargin|NSViewMinYMargin; + + _sectionsPopUpButton.autoresizingMask=NSViewMinXMargin|NSViewMinYMargin; + _sectionsPopUpButton.imagePosition=NSImageTrailing; + } + } - (void)viewDidAppear @@ -143,7 +176,7 @@ - (void)viewDidAppear // Register for Notifications - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self.view]; @@ -172,7 +205,7 @@ - (void)viewWillDisappear { [super viewWillDisappear]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -193,6 +226,8 @@ - (void)setPresentationViewController:(CUICrashLogPresentationViewController *)i - (void)refreshSourcesMenu { + NSString * tTitleFormatString=NSLocalizedString(@"%@ - %@", @""); + [_sourcesPopUpButton removeAllItems]; _sourcesPopUpButton.action=@selector(switchSourceCrashLog:); @@ -261,7 +296,7 @@ - (void)refreshSourcesMenu for(CUIRawCrashLog * tCrashLog in tMutableCrashLogs) { - NSString * tTitle=[NSString stringWithFormat:@"%@ - %@",tCrashLog.processName,[self->_crashLogDateFormatter stringFromDate:tCrashLog.dateTime]]; + NSString * tTitle=[NSString localizedStringWithFormat:tTitleFormatString,tCrashLog.processName,[self->_crashLogDateFormatter stringFromDate:tCrashLog.dateTime]]; NSMenuItem * tSubMenuItem=[[NSMenuItem alloc] initWithTitle:tTitle action:@selector(switchSourceCrashLog:) keyEquivalent:@""]; @@ -297,6 +332,8 @@ - (void)refreshSourcesMenu - (void)refreshCrashLogsMenu { + NSString * tTitleFormatString=NSLocalizedString(@"%@ - %@", @""); + [_crashLogsPopUpButton removeAllItems]; NSMutableArray * tMutableCrashLogs=[_sourcesSelection.crashLogs mutableCopy]; @@ -334,7 +371,7 @@ - (void)refreshCrashLogsMenu for(CUIRawCrashLog * tCrashLog in tMutableCrashLogs) { - NSString * tTitle=[NSString stringWithFormat:@"%@ - %@",tCrashLog.processName,[_crashLogDateFormatter stringFromDate:tCrashLog.dateTime]]; + NSString * tTitle=[NSString localizedStringWithFormat:tTitleFormatString,tCrashLog.processName,[_crashLogDateFormatter stringFromDate:tCrashLog.dateTime]]; NSMenuItem * tSubMenuItem=[[NSMenuItem alloc] initWithTitle:tTitle action:@selector(switchCrashLog:) keyEquivalent:@""]; @@ -440,21 +477,21 @@ - (void)refreshSectionsMenu NSArray * tArray=@[ @{ @"title":NSLocalizedString(@"Header",@""), - @"range":[NSValue valueWithRange:tCrashLog.headerRange], + @"available":@(tCrashLog.isHeaderAvailable), @"tag":@"section:Header", @"visible":@(tDocumentSections&CUIDocumentHeaderSection), @"icon":@"menuHeader", }, @{ @"title":NSLocalizedString(@"Exception Information",@""), - @"range":[NSValue valueWithRange:tCrashLog.exceptionInformationRange], + @"available":@(tCrashLog.isExceptionInformationAvailable), @"tag":@"section:Exception Information", @"visible":@(tDocumentSections&CUIDocumentExceptionInformationSection), @"icon":@"menuException", }, @{ @"title":NSLocalizedString(@"Diagnostic Messages",@""), - @"range":[NSValue valueWithRange:tCrashLog.diagnosticMessagesRange], + @"available":@(tCrashLog.isDiagnosticMessageAvailable), @"tag":@"section:Diagnostic Messages", @"visible":@(tDocumentSections&CUIDocumentDiagnosticMessagesSection), @"icon":@"menuDiagnostic", @@ -468,10 +505,7 @@ - (void)refreshSectionsMenu if (tVisibleFlag==0) continue; - NSValue * tValue=tDictionary[@"range"]; - NSRange tRange=tValue.rangeValue; - - if (tRange.location!=NSNotFound) + if ([tDictionary[@"available"] boolValue]==YES) { tMenuItem=[[NSMenuItem alloc] initWithTitle:tDictionary[@"title"] action:@selector(switchSection:) keyEquivalent:@""]; @@ -564,14 +598,14 @@ - (void)refreshSectionsMenu tArray=@[ @{ @"title":NSLocalizedString(@"Thread State",@""), - @"range":[NSValue valueWithRange:tCrashLog.threadStateRange], + @"available":@(tCrashLog.isThreadStateAvailable), @"tag":@"section:Thread State", @"visible":@(tDocumentSections&CUIDocumentThreadStateSection), @"icon":@"menuThreadState", }, @{ @"title":NSLocalizedString(@"Binary Images",@""), - @"range":[NSValue valueWithRange:tCrashLog.binaryImagesRange], + @"available":@(tCrashLog.isBinaryImagesAvailable), @"tag":@"section:Binary Images", @"visible":@(tDocumentSections&CUIDocumentBinaryImagesSection), @"icon":@"menuBinaryImage", @@ -585,10 +619,7 @@ - (void)refreshSectionsMenu if (tVisibleFlag==0) continue; - NSValue * tValue=tDictionary[@"range"]; - NSRange tRange=tValue.rangeValue; - - if (tRange.location!=NSNotFound) + if ([tDictionary[@"available"] boolValue]==YES) { tMenuItem=[[NSMenuItem alloc] initWithTitle:tDictionary[@"title"] action:@selector(switchSection:) keyEquivalent:@""]; @@ -618,7 +649,9 @@ - (void)updateLayout #define MARGIN 0.0 -#define RIGHT_PADDING 10.0 +#define BEGIN_PADDING 3.0 + +#define END_PADDING 10.0 NSRect tBounds=self.view.bounds; @@ -673,7 +706,8 @@ - (void)updateLayout NSRect tChevronFrame=_sourcesChevronView.frame; - tTotalWidth+=NSMinX(_sourcesPopUpButton.frame)+(tMutableArray.count-1)*(NSWidth(tChevronFrame)+2.0*MARGIN)+RIGHT_PADDING; + + tTotalWidth+=BEGIN_PADDING+(tMutableArray.count-1)*(NSWidth(tChevronFrame)+2.0*MARGIN)+END_PADDING; CGFloat tDifference=tTotalWidth-NSWidth(tBounds); @@ -702,6 +736,11 @@ - (void)updateLayout tRect.size.width=tSize.width; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft) + { + tRect.origin.x=NSMaxX(tBounds)-NSWidth(tRect)-BEGIN_PADDING; + } + _sourcesPopUpButton.frame=tRect; return; @@ -729,20 +768,30 @@ - (void)updateLayout tRect.size.width=tSize.width; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft) + { + tRect.origin.x=NSMaxX(tBounds)-NSWidth(tRect)-BEGIN_PADDING; + } + _sourcesPopUpButton.frame=tRect; NSRect tFrame=_sourcesChevronView.frame; - tFrame.origin.x=NSMaxX(tRect)+MARGIN; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + tFrame.origin.x=NSMaxX(tRect)+MARGIN; + } + else + { + tFrame.origin.x=NSMinX(tRect)-MARGIN-NSWidth(tFrame); + } _sourcesChevronView.frame=tFrame; tRect=_crashLogsPopUpButton.frame; - tRect.origin.x=NSMaxX(_sourcesChevronView.frame)+MARGIN; - tSize=[_crashLogsPopUpButton sizeThatFits:tRect.size]; if (NSAppKitVersionNumber>GROSSE_CHIURE_APPKIT_VERSION_NUMBER) @@ -750,9 +799,25 @@ - (void)updateLayout tSize.width+=GROSSE_CHIURE_EXTRA_WIDTH; } - if (tDifference>0.0) + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) { - tSize.width=NSMaxX(tBounds)-NSMinX(tRect); + tRect.origin.x=NSMaxX(_sourcesChevronView.frame)+MARGIN; + + if (tDifference>0.0) + { + tSize.width=NSMaxX(tBounds)-NSMinX(tRect); + } + } + else + { + tRect.origin.x=NSMinX(_sourcesChevronView.frame)-MARGIN-tSize.width; + + if (tDifference>0.0) + { + tSize.width=NSMaxX(tRect)-NSMinX(tBounds); + + tRect.origin.x=NSMinX(tBounds); + } } tRect.size.width=tSize.width; @@ -782,12 +847,24 @@ - (void)updateLayout tRect.size.width=tSize.width; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft) + { + tRect.origin.x=NSMaxX(tBounds)-NSWidth(tRect)-BEGIN_PADDING; + } + _sourcesPopUpButton.frame=tRect; NSRect tFrame=_sourcesChevronView.frame; - tFrame.origin.x=NSMaxX(tRect)+MARGIN; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + tFrame.origin.x=NSMaxX(tRect)+MARGIN; + } + else + { + tFrame.origin.x=NSMinX(tRect)-MARGIN-NSWidth(tFrame); + } _sourcesChevronView.frame=tFrame; @@ -803,38 +880,49 @@ - (void)updateLayout tSize.width+=GROSSE_CHIURE_EXTRA_WIDTH; } - if (tDifference>0.0) + if (tDifference>(tSize.width-MIN_WIDTH)) { - if (tDifference>(tSize.width-MIN_WIDTH)) - { - tDifference-=(tSize.width-MIN_WIDTH); - - tSize.width=MIN_WIDTH; - } - else - { - tSize.width-=tDifference; - - tDifference=0.0; - } + tDifference-=(tSize.width-MIN_WIDTH); + + tSize.width=MIN_WIDTH; + } + else + { + tSize.width-=tDifference; + + tDifference=0.0; } tRect.size.width=tSize.width; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + tRect.origin.x=NSMaxX(_sourcesChevronView.frame)+MARGIN; + } + else + { + tRect.origin.x=NSMinX(_sourcesChevronView.frame)-MARGIN-tSize.width; + } + _crashLogsPopUpButton.frame=tRect; tFrame=_crashLogsChevronView.frame; - tFrame.origin.x=NSMaxX(tRect)+MARGIN; + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + tFrame.origin.x=NSMaxX(tRect)+MARGIN; + } + else + { + tFrame.origin.x=NSMinX(tRect)-MARGIN-NSWidth(tFrame); + } _crashLogsChevronView.frame=tFrame; tRect=_sectionsPopUpButton.frame; - tRect.origin.x=NSMaxX(_crashLogsChevronView.frame)+MARGIN; - tSize=[_sectionsPopUpButton sizeThatFits:tRect.size]; if (NSAppKitVersionNumber>GROSSE_CHIURE_APPKIT_VERSION_NUMBER) @@ -847,6 +935,15 @@ - (void)updateLayout tSize.width=NSMaxX(tBounds)-NSMinX(tRect); } + if (self.view.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) + { + tRect.origin.x=NSMaxX(_crashLogsChevronView.frame)+MARGIN; + } + else + { + tRect.origin.x=NSMinX(_crashLogsChevronView.frame)-MARGIN-tSize.width; + } + tRect.size.width=tSize.width; _sectionsPopUpButton.frame=tRect; @@ -942,7 +1039,7 @@ - (IBAction)switchSection:(NSMenuItem *)sender return; } - [[NSNotificationCenter defaultCenter] postNotificationName:@"jumpToSectionNotification" object:tRepresentedObject userInfo:@{}]; + [NSNotificationCenter.defaultCenter postNotificationName:@"jumpToSectionNotification" object:tRepresentedObject userInfo:@{}]; [self updateLayout]; } diff --git a/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.h b/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.h new file mode 100644 index 0000000..6b50dd2 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2020-2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +@class CUIQuickHelpPopUpViewController; + +@protocol CUIQuickHelpPopUpViewControllerDelegate + +- (void)quickHelpPopUpViewController:(CUIQuickHelpPopUpViewController *)inController didComputeSizeOfPopover:(NSPopover *)inPopover; + +@end + +@interface CUIQuickHelpPopUpViewController : NSViewController + + @property NSPopover * popover; + + @property (weak) id delegate; + + @property NSRange textRange; + + @property (nonatomic) NSURL * contentsFileURL; + + @property (readonly) NSBundle * bundle; + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.m b/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.m new file mode 100644 index 0000000..18306b8 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.m @@ -0,0 +1,144 @@ +/* + Copyright (c) 2020-2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIQuickHelpPopUpViewController.h" + +#import + +@interface CUINoScrollingWebView : WKWebView + +@end + +@implementation CUINoScrollingWebView + +- (void)scrollWheel:(NSEvent *)inEvent +{ + [self.nextResponder scrollWheel:inEvent]; +} + +@end + +@interface CUIQuickHelpPopUpViewController () /**/ +{ + IBOutlet CUINoScrollingWebView * _webView; +} + +@property (readwrite) NSBundle * bundle; + +@end + +@implementation CUIQuickHelpPopUpViewController + +- (instancetype)init +{ + self=[super init]; + + if (self!=nil) + { + _bundle=[NSBundle mainBundle]; + } + + return self; +} + +#pragma mark - + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + _webView.navigationDelegate=self; + + [_webView setValue:@(NO) forKey:@"drawsBackground"]; + + NSError * tError=nil; + + NSString * tHTMLContents=[NSString stringWithContentsOfURL:_contentsFileURL encoding:NSUTF8StringEncoding error:&tError]; + + if (tHTMLContents==nil) + { + NSLog(@"HTML data could not be loaded from file \"%@\".",_contentsFileURL); + + return; + } + + [_webView loadHTMLString:tHTMLContents baseURL:_bundle.resourceURL]; +} + +- (NSString *)nibName +{ + return @"CUIQuickHelpPopUpViewController"; +} + +#pragma mark - + +- (void)webView:(WKWebView *)inWebView decidePolicyForNavigationAction:(WKNavigationAction *)inNavigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler +{ + if (inNavigationAction.navigationType==WKNavigationTypeLinkActivated) + { + decisionHandler(WKNavigationActionPolicyCancel); + + [[NSWorkspace sharedWorkspace] openURL:inNavigationAction.request.URL]; + } + else + { + decisionHandler(WKNavigationActionPolicyAllow); + } +} + +- (void)webView:(WKWebView *)inWebView didFinishNavigation:(WKNavigation *)inNavigation +{ + if (self.popover==nil) + return; + + __block NSSize tCurrentSize=self.popover.contentSize; + + [_webView evaluateJavaScript:@"document.body.scrollHeight;" completionHandler:^(NSString * bResult, NSError * bError) { + + tCurrentSize.height=[bResult integerValue]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + self.popover.contentSize=tCurrentSize; + + [self.delegate quickHelpPopUpViewController:self didComputeSizeOfPopover:self.popover]; + }); + }]; +} + +#pragma mark - + +- (void)setContentsFileURL:(NSURL *)inURL +{ + _contentsFileURL=inURL; + + if (_webView==nil) + return; + + NSError * tError=nil; + + NSString * tHTMLContents=[NSString stringWithContentsOfURL:_contentsFileURL encoding:NSUTF8StringEncoding error:&tError]; + + if (tHTMLContents==nil) + { + NSLog(@"Missing HTML document at %@",_contentsFileURL.path); + + // A COMPLETER (Provide a basic HTML error report to display) + + return; + } + + [_webView loadHTMLString:tHTMLContents baseURL:_bundle.resourceURL]; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.xib b/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.xib similarity index 97% rename from app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.xib rename to app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.xib index ee69bc2..b4183cd 100644 --- a/app_unexpectedly/app_unexpectedly/CUIExceptionTypePopUpViewController.xib +++ b/app_unexpectedly/app_unexpectedly/CUIQuickHelpPopUpViewController.xib @@ -7,7 +7,7 @@ - + diff --git a/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.h b/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.h index 8378e09..83820de 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.h +++ b/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.h @@ -15,6 +15,8 @@ #import "CUICrashLogErrors.h" +#import "IPSReport.h" + typedef NS_ENUM(NSUInteger, CUICrashLogReportSourceType) { CUICrashLogReportSourceTypeSystem=0, @@ -26,7 +28,9 @@ typedef NS_ENUM(NSUInteger, CUICrashLogReportSourceType) @property (readonly) id resourceIdentifier; - @property (readonly,copy) NSString * rawText; + @property (readonly) IPSReport * ipsReport; // Can be nil + + @property (readonly,copy) NSString * rawText; // Can be nil @property (readonly,copy) NSString * crashLogFilePath; @@ -35,6 +39,20 @@ typedef NS_ENUM(NSUInteger, CUICrashLogReportSourceType) @property (nonatomic,readonly) BOOL isFullyParsed; + @property (nonatomic,readonly,getter=isHeaderAvailable) BOOL headerAvailable; + + @property (nonatomic,readonly,getter=isExceptionInformationAvailable) BOOL exceptionInformationAvailable; + + @property (nonatomic,readonly,getter=isDiagnosticMessageAvailable) BOOL diagnosticMessageAvailable; + + @property (nonatomic,readonly,getter=isBacktracesAvailable) BOOL backtracesAvailable; + + @property (nonatomic,readonly,getter=isThreadStateAvailable) BOOL threadStateAvailable; + + @property (nonatomic,readonly,getter=isBinaryImagesAvailable) BOOL binaryImagesAvailable; + + + @property (nonatomic,readonly,copy) NSString * processName; @property (nonatomic,readonly) NSDate * dateTime; @@ -62,6 +80,11 @@ typedef NS_ENUM(NSUInteger, CUICrashLogReportSourceType) - (BOOL)finalizeParsing; +@property (nonatomic,readonly,copy) NSString * crashLogFileName; + + +- (NSComparisonResult)compareCrashLogFileName:(CUIRawCrashLog *)otherCrashLog; + - (NSComparisonResult)compareProcessName:(CUIRawCrashLog *)otherCrashLog; - (NSComparisonResult)compareDateReverse:(CUIRawCrashLog *)otherCrashLog; diff --git a/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.m b/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.m index c870f18..334b580 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.m +++ b/app_unexpectedly/app_unexpectedly/CUIRawCrashLog.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -27,6 +27,8 @@ @interface CUIRawCrashLog () id _reserved2; // dateTime id _reserved3; // header.bundleIdentifier id _reserved4; // header.executablePath + id _reserved5; // header.executableVersion + id _reserved6; // header.operatingSystemVersion.stringValue } @property (copy) NSString * crashLogFilePath; @@ -46,7 +48,7 @@ @implementation CUIRawCrashLog - (instancetype)initWithContentsOfURL:(NSURL *)inURL error:(NSError **)outError { - if ([inURL isKindOfClass:[NSURL class]]==NO) + if ([inURL isKindOfClass:NSURL.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -103,7 +105,7 @@ - (instancetype)initWithContentsOfURL:(NSURL *)inURL error:(NSError **)outError - (instancetype)initWithContentsOfFile:(NSString *)inPath error:(NSError **)outError { - if ([inPath isKindOfClass:[NSString class]]==NO) + if ([inPath isKindOfClass:NSString.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -116,7 +118,7 @@ - (instancetype)initWithContentsOfFile:(NSString *)inPath error:(NSError **)outE - (instancetype)initWithData:(NSData *)inData error:(NSError **)outError { - if ([inData isKindOfClass:[NSData class]]==NO) + if ([inData isKindOfClass:NSData.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -142,7 +144,7 @@ - (instancetype)initWithData:(NSData *)inData error:(NSError **)outError - (instancetype)initWithString:(NSString *)inString error:(NSError **)outError { - if ([inString isKindOfClass:[NSString class]]==NO) + if ([inString isKindOfClass:NSString.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSCocoaErrorDomain code:EINVAL userInfo:@{}]; @@ -150,7 +152,41 @@ - (instancetype)initWithString:(NSString *)inString error:(NSError **)outError return nil; } - if ([inString hasPrefix:@"Process:"]==NO) + if ([inString hasPrefix:@"Process:"]==YES) + { + self=[super init]; + + if (self!=nil) + { + _rawText=[inString copy]; + + _resourceIdentifier=[NSUUID UUID]; + } + } + else if ([inString hasPrefix:@"{"]==YES) + { + self=[super init]; + + if (self!=nil) + { + NSError * tError=nil; + + _ipsReport=[[IPSReport alloc] initWithString:inString error:&tError]; + + if (_ipsReport==nil) + { + if (outError!=NULL) + *outError=tError; + + return nil; + } + + _rawText=nil; + + _resourceIdentifier=[NSUUID UUID]; + } + } + else { if (outError!=NULL) { @@ -167,20 +203,57 @@ - (instancetype)initWithString:(NSString *)inString error:(NSError **)outError return nil; } - self=[super init]; - - if (self!=nil) - { - _rawText=[inString copy]; - - _resourceIdentifier=[NSUUID UUID]; - } - return self; } #pragma mark - +- (BOOL)isHeaderAvailable +{ + return (self.ipsReport.incident.header!=nil); +} + +- (BOOL)isExceptionInformationAvailable +{ + return (self.ipsReport.incident.exceptionInformation!=nil); +} + +- (BOOL)isDiagnosticMessageAvailable +{ + return (self.ipsReport.incident.diagnosticMessage!=nil); +} + +- (BOOL)isBacktracesAvailable +{ + return (self.ipsReport.incident.threads!=nil); +} + +- (BOOL)isThreadStateAvailable +{ + NSUInteger tFaultingThreadIndex=self.ipsReport.incident.exceptionInformation.faultingThread; + + NSArray * tThreadsArray=self.ipsReport.incident.threads; + + if (tFaultingThreadIndex>=tThreadsArray.count) + return NO; + + IPSThread * tThread=tThreadsArray[tFaultingThreadIndex]; + + return (tThread.threadState!=nil); +} + +- (BOOL)isBinaryImagesAvailable +{ + return (self.ipsReport.incident.binaryImages!=nil); +} + +- (id)valueForUndefinedKey:(NSString *)inKey +{ + NSLog(@"Undefined key '%@'",inKey); + + return @""; +} + - (id)valueForKeyPath:(NSString *)inKeyPath { if ([inKeyPath isEqualToString:@"header.bundleIdentifier"]==YES) @@ -189,10 +262,28 @@ - (id)valueForKeyPath:(NSString *)inKeyPath if ([inKeyPath isEqualToString:@"header.executablePath"]==YES) return (_reserved4==nil) ? @"" : _reserved4; + if ([inKeyPath isEqualToString:@"header.executableVersion"]==YES) + return (_reserved5==nil) ? @"" : _reserved5; + + if ([inKeyPath isEqualToString:@"header.operatingSystemVersion.stringValue"]==YES) + return (_reserved6==nil) ? @"" : _reserved6; + if ([inKeyPath isEqualToString:@"exceptionInformation.crashedThreadName"]==YES) return @""; - return [super valueForKeyPath:inKeyPath]; + id tValue=nil; + + @try + { + tValue=[super valueForKeyPath:inKeyPath]; + } + + @catch(NSException * bException) + { + tValue=@""; + } + + return tValue; } - (NSString *)processName @@ -283,7 +374,6 @@ - (BOOL)finalizeParsing // Try to parse at least the header - tRange=[CUICrashLogSectionsDetector detectHeaderSectionRangeInTextualRepresentation:tLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tFirstLine,tLines.count-tFirstLine)]]; if (tRange.location==NSNotFound) @@ -305,6 +395,10 @@ - (BOOL)finalizeParsing _reserved3=[tHeader.bundleIdentifier copy]; _reserved4=[tHeader.executablePath copy]; + + _reserved5=[tHeader.executableVersion copy]; + + _reserved6=[tHeader.operatingSystemVersion.stringValue copy]; } return YES; @@ -312,6 +406,18 @@ - (BOOL)finalizeParsing #pragma mark - +- (NSString *)crashLogFileName +{ + return self.crashLogFilePath.lastPathComponent.stringByDeletingPathExtension; +} + +#pragma mark - + +- (NSComparisonResult)compareCrashLogFileName:(CUIRawCrashLog *)otherCrashLog +{ + return [self.crashLogFileName compare:otherCrashLog.crashLogFileName options:NSNumericSearch|NSCaseInsensitiveSearch]; +} + - (NSComparisonResult)compareProcessName:(CUIRawCrashLog *)otherCrashLog { NSComparisonResult tResult=[self.processName compare:otherCrashLog.processName options:NSNumericSearch|NSCaseInsensitiveSearch]; diff --git a/app_unexpectedly/app_unexpectedly/CUIRawTextTransformation.m b/app_unexpectedly/app_unexpectedly/CUIRawTextTransformation.m deleted file mode 100644 index 6846284..0000000 --- a/app_unexpectedly/app_unexpectedly/CUIRawTextTransformation.m +++ /dev/null @@ -1,1561 +0,0 @@ -/* - Copyright (c) 2020-2021, Stephane Sudre - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "CUIRawTextTransformation.h" - -#import "CUIApplicationPreferences.h" -#import "CUIApplicationPreferences+Themes.h" - -#import "CUICrashLogBinaryImages.h" - -#import "CUIBinaryImage+UI.h" - -#import "CUIThemesManager.h" -#import "CUIThemeItemsGroup+UI.h" - -#ifndef __DISABLE_SYMBOLICATION_ -#import "CUIdSYMBundlesManager.h" - -#import "CUISymbolicationManager.h" - -#import "CUISymbolicationDataFormatter.h" -#endif - -NSString * const CUIGenericAnchorAttributeName=@"CUIGenericAnchorAttributeName"; - -NSString * const CUISectionAnchorAttributeName=@"CUISectionAnchorAttributeName"; - -NSString * const CUIThreadAnchorAttributeName=@"CUIThreadAnchorAttributeName"; - -NSString * const CUIBinaryAnchorAttributeName=@"CUIBinaryAnchorAttributeName"; - -@interface CUIRawTextTransformation () -{ - NSDictionary * _cachedPlainTextAttributes; - - NSDictionary * _cachedKeyAttributes; - - NSDictionary * _cachedVersionAttributes; - - NSDictionary * _cachedPathAttributes; - - NSDictionary * _cachedUUIDAttributes; - - NSDictionary * _cachedCrashedThreadLabelAttributes; - - NSDictionary * _cachedThreadLabelAttributes; - - NSDictionary * _cachedExecutableCodeAttributes; - - NSDictionary * _cachedOSCodeAttributes; - - NSDictionary * _cachedMemoryAddressAttributes; - - - NSDictionary * _cachedRegisterValueAttributes; - - - NSDictionary * _cachedParsingErrorAttributes; - - NSColor * _cachedUnderlineColor; - - - NSCharacterSet * _whitespaceCharacterSet; - -#ifndef __DISABLE_SYMBOLICATION_ - CUISymbolicationDataFormatter * _symbolicationDataFormatter; -#endif -} - - @property CUICrashLog * crashLog; - - @property (copy) NSString * processPath; - - -- (void)updatesCachedAttributes; - -- (NSArray *)processedHeaderSectionLines:(NSArray *)inLines error:(NSError **)outError; - -- (NSArray *)processedExceptionInformationSectionLines:(NSArray *)inLines error:(NSError **)outError; - -- (NSArray *)processedDiagnosticMessagesSectionLines:(NSArray *)inLines error:(NSError **)outError; - -- (NSArray *)processedBacktracesSectionLines:(NSArray *)inLines error:(NSError **)outError; - -- (NSArray *)processedThreadStateSectionLines:(NSArray *)inLines error:(NSError **)outError; - -- (NSArray *)processedBinaryImagesSectionLines:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError; - -- (NSAttributedString *)joinLines:(NSArray *)inLines withString:(NSString *)inNewLineFeed; - -- (id)processedStackFrameLine:(NSString *)inLine stackFrame:(CUIStackFrame *)inStackFrame; - -- (NSArray *)processedThreadBacktraceLines:(NSArray *)inLines error:(NSError **)outError; - -- (id)processedBinaryImageLine:(NSString *)inLine reportVersion:(NSUInteger)inReportVersion; - -@end - -@implementation CUIRawTextTransformation - -- (instancetype)init -{ - self=[super init]; - - if (self!=nil) - { - _hyperlinksStyle=CUIHyperlinksInternal; - -#ifndef __DISABLE_SYMBOLICATION_ - _symbolicationDataFormatter=[CUISymbolicationDataFormatter new]; -#endif - - _whitespaceCharacterSet=[NSCharacterSet whitespaceCharacterSet]; - } - - return self; -} - -- (void)updatesCachedAttributes -{ - NSFontManager * tFontManager = [NSFontManager sharedFontManager]; - - CUIThemesManager * tThemesManager=[CUIThemesManager sharedManager]; - - CUIThemeItemsGroup * tItemsGroup=[tThemesManager.currentTheme itemsGroupWithIdentifier:[CUIApplicationPreferences groupIdentifierForPresentationMode:CUIPresentationModeText]]; - - NSMutableArray * tItemsNames=[tItemsGroup.itemsNames mutableCopy]; - - [tItemsNames removeObject:CUIThemeItemBackground]; - [tItemsNames removeObject:CUIThemeItemLineNumber]; - [tItemsNames removeObject:CUIThemeItemSelectionBackground]; - [tItemsNames removeObject:CUIThemeItemSelectionText]; - - // TabStops settings - - NSMutableParagraphStyle * tMutableParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - - tMutableParagraphStyle.tabStops=@[]; - - [tMutableParagraphStyle setLineSpacing:2.0]; - - for (NSUInteger tIndex = 1; tIndex <= 20; tIndex++) - { - NSTextTab *tabStop = [[NSTextTab alloc] initWithType:NSLeftTabStopType location: 40 * (tIndex)]; - [tMutableParagraphStyle addTabStop:tabStop]; - } - - NSMutableDictionary * tMutableDictionary=[NSMutableDictionary dictionary]; - - for(NSString * tItemName in tItemsNames) - { - CUIThemeItemAttributes * tItemAttributes=[tItemsGroup attributesForItem:tItemName]; - - NSFont * tFont=tItemAttributes.font; - - NSFont * tAdjustedFont=nil; - - tAdjustedFont=[tFontManager convertFont:tFont toSize:tFont.pointSize + self.fontSizeDelta]; - - if (tAdjustedFont==nil) - tAdjustedFont=tFont; - - tMutableDictionary[tItemName]=@{ - NSFontAttributeName:tAdjustedFont, - NSForegroundColorAttributeName:tItemAttributes.color, - NSParagraphStyleAttributeName:tMutableParagraphStyle - }; - } - - _cachedPlainTextAttributes=tMutableDictionary[CUIThemeItemPlainText]; - - NSColor * tForegroundColor=_cachedPlainTextAttributes[NSForegroundColorAttributeName]; - _cachedUnderlineColor=[tForegroundColor colorWithAlphaComponent:0.35]; - - _cachedKeyAttributes=tMutableDictionary[CUIThemeItemKey]; - _cachedThreadLabelAttributes=tMutableDictionary[CUIThemeItemThreadLabel]; - _cachedCrashedThreadLabelAttributes=tMutableDictionary[CUIThemeItemCrashedThreadLabel]; - - _cachedExecutableCodeAttributes=tMutableDictionary[CUIThemeItemExecutableCode]; - _cachedOSCodeAttributes=tMutableDictionary[CUIThemeItemOSCode]; - - _cachedVersionAttributes=tMutableDictionary[CUIThemeItemVersion]; - _cachedMemoryAddressAttributes=tMutableDictionary[CUIThemeItemMemoryAddress]; - _cachedPathAttributes=tMutableDictionary[CUIThemeItemPath]; - _cachedUUIDAttributes=tMutableDictionary[CUIThemeItemUUID]; - _cachedRegisterValueAttributes=tMutableDictionary[CUIThemeItemRegisterValue]; - - - NSMutableDictionary * tParsingErrorDictionary=[_cachedPlainTextAttributes mutableCopy]; - - tParsingErrorDictionary[NSForegroundColorAttributeName]=[NSColor redColor]; - - _cachedParsingErrorAttributes=[tParsingErrorDictionary copy]; -} - -- (NSAttributedString *)transformCrashLog:(CUICrashLog *)inCrashLog -{ - if (inCrashLog==nil) - return nil; - - if ([inCrashLog isMemberOfClass:[CUIRawCrashLog class]]==YES) - return [self transformCrashLog:inCrashLog lines:@[]]; - - NSMutableArray * tLines=[NSMutableArray array]; - - [inCrashLog.rawText enumerateLinesUsingBlock:^(NSString * bLine, BOOL * bOutStop) { - - [tLines addObject:bLine]; - }]; - - return [self transformCrashLog:inCrashLog lines:tLines]; -} - -- (NSAttributedString *)transformCrashLog:(CUICrashLog *)inCrashLog lines:(NSArray *)inLines -{ - if (inCrashLog==nil || inLines==nil) - return nil; - - [self updatesCachedAttributes]; - - - if ([inCrashLog isMemberOfClass:[CUIRawCrashLog class]]==YES) - { - NSAttributedString * tMutableAttributedString=[[NSAttributedString alloc] initWithString:inCrashLog.rawText - attributes:_cachedPlainTextAttributes]; - - return tMutableAttributedString; - } - - self.crashLog=inCrashLog; - - self.processPath=inCrashLog.header.executablePath; - - - - NSMutableArray * tMutableArray=[inLines mutableCopy]; - - - if (inCrashLog.binaryImagesRange.location!=NSNotFound) - { - if ((_displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==0) - { - [tMutableArray removeObjectsInRange:inCrashLog.binaryImagesRange]; - } - else - { - NSArray * tBacktracesLines=[inLines subarrayWithRange:inCrashLog.binaryImagesRange]; - - NSArray * tFilteredLines=[self processedBinaryImagesSectionLines:tBacktracesLines reportVersion:inCrashLog.reportVersion error:NULL]; - - [tMutableArray removeObjectsInRange:inCrashLog.binaryImagesRange]; - - [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(inCrashLog.binaryImagesRange.location,tFilteredLines.count)]]; - } - } - - if (inCrashLog.threadStateRange.location!=NSNotFound) - { - if ((_displaySettings.visibleSections & CUIDocumentThreadStateSection)==0) - { - [tMutableArray removeObjectsInRange:inCrashLog.threadStateRange]; - } - else - { - NSArray * tThreadStateLines=[inLines subarrayWithRange:inCrashLog.threadStateRange]; - - NSArray * tFilteredLines=[self processedThreadStateSectionLines:tThreadStateLines error:NULL]; - - [tMutableArray removeObjectsInRange:inCrashLog.threadStateRange]; - - [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(inCrashLog.threadStateRange.location,tFilteredLines.count)]]; - } - } - - if (inCrashLog.backtracesRange.location!=NSNotFound) - { - if ((_displaySettings.visibleSections & CUIDocumentBacktracesSection)==0) - { - [tMutableArray removeObjectsInRange:inCrashLog.backtracesRange]; - } - else - { - NSArray * tBacktracesLines=[inLines subarrayWithRange:inCrashLog.backtracesRange]; - - NSArray * tFilteredLines=[self processedBacktracesSectionLines:tBacktracesLines error:NULL]; - - [tMutableArray removeObjectsInRange:inCrashLog.backtracesRange]; - - [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(inCrashLog.backtracesRange.location,tFilteredLines.count)]]; - } - } - - - if (inCrashLog.diagnosticMessagesRange.location!=NSNotFound) - { - if ((_displaySettings.visibleSections & CUIDocumentDiagnosticMessagesSection)==0) - { - [tMutableArray removeObjectsInRange:inCrashLog.diagnosticMessagesRange]; - } - else - { - NSArray * tDiagnosticMessagesLines=[inLines subarrayWithRange:inCrashLog.diagnosticMessagesRange]; - - NSArray * tFilteredLines=[self processedDiagnosticMessagesSectionLines:tDiagnosticMessagesLines error:NULL]; - - [tMutableArray removeObjectsInRange:inCrashLog.diagnosticMessagesRange]; - - [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(inCrashLog.diagnosticMessagesRange.location,tFilteredLines.count)]]; - } - } - - - if (inCrashLog.exceptionInformationRange.location!=NSNotFound) - { - if ((_displaySettings.visibleSections & CUIDocumentExceptionInformationSection)==0) - { - [tMutableArray removeObjectsInRange:inCrashLog.exceptionInformationRange]; - } - else - { - NSArray * tExceptionInformationLines=[inLines subarrayWithRange:inCrashLog.exceptionInformationRange]; - - NSArray * tFilteredLines=[self processedExceptionInformationSectionLines:tExceptionInformationLines error:NULL]; - - [tMutableArray removeObjectsInRange:inCrashLog.exceptionInformationRange]; - - [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(inCrashLog.exceptionInformationRange.location,tFilteredLines.count)]]; - } - } - - - if (inCrashLog.headerRange.location!=NSNotFound) - { - if ((_displaySettings.visibleSections & CUIDocumentHeaderSection)==0) - { - [tMutableArray removeObjectsInRange:inCrashLog.headerRange]; - } - else - { - NSArray * tExceptionInformationLines=[inLines subarrayWithRange:inCrashLog.headerRange]; - - NSArray * tFilteredLines=[self processedHeaderSectionLines:tExceptionInformationLines error:NULL]; - - [tMutableArray removeObjectsInRange:inCrashLog.headerRange]; - - [tMutableArray insertObjects:tFilteredLines atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(inCrashLog.headerRange.location,tFilteredLines.count)]]; - } - } - - return [self joinLines:tMutableArray withString:@"\n"]; -} - -#pragma mark - Header - -- (NSArray *)processedHeaderSectionLines:(NSArray *)inLines error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSMutableArray * tProcessedLines=[NSMutableArray array]; - - [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - NSUInteger tLineLength=bLine.length; - - // Skip Blank lines - - if (tLineLength==0) - { - [tProcessedLines addObject:bLine]; - return; - } - - // Find Key and Value - - NSScanner * tScanner=[NSScanner scannerWithString:bLine]; - - NSString * tKey; - - if ([tScanner scanUpToString:@":" intoString:&tKey]==NO) - { - [tProcessedLines addObject:bLine]; - - *bOutStop=YES; - return; - } - - NSRange tKeyRange=NSMakeRange(0,tScanner.scanLocation+1); - - tScanner.scanLocation=tScanner.scanLocation+1; - - tScanner.charactersToBeSkipped=nil; - - [tScanner scanCharactersFromSet:self->_whitespaceCharacterSet intoString:NULL]; - - NSRange tValueRange=NSMakeRange(tScanner.scanLocation,bLine.length-1-tScanner.scanLocation+1); - - - NSMutableAttributedString * tProcessedLine=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self->_cachedPlainTextAttributes]; - - if (bLineNumber==0) - { - NSDictionary * tJumpAnchorAttributes=@{ - CUISectionAnchorAttributeName:@"section:Header" - }; - - [tProcessedLine addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,bLine.length)]; - } - - //if (self.displaySettings.highlightSyntax==YES) - { - [tProcessedLine addAttributes:self->_cachedKeyAttributes range:tKeyRange]; - - - if ([tKey isEqualToString:@"Path"]==YES) - { - [tProcessedLine addAttributes:self->_cachedPathAttributes range:tValueRange]; - } - else if ([tKey isEqualToString:@"Version"]==YES || - [tKey isEqualToString:@"OS Version"]==YES) - { - [tProcessedLine addAttributes:self->_cachedVersionAttributes range:tValueRange]; - } - else if ([tKey isEqualToString:@"Anonymous UUID"]==YES || - [tKey isEqualToString:@"Sleep/Wake UUID"]==YES) - { - [tProcessedLine addAttributes:self->_cachedUUIDAttributes range:tValueRange]; - } - } - - [tProcessedLines addObject:tProcessedLine]; - }]; - - return [tProcessedLines copy]; -} - -#pragma mark - Exception Information - -- (NSArray *)processedExceptionInformationSectionLines:(NSArray *)inLines error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSMutableArray * tProcessedLines=[NSMutableArray array]; - - [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - NSUInteger tLineLength=bLine.length; - - // Skip Blank lines - - if (tLineLength==0) - { - [tProcessedLines addObject:bLine]; - return; - } - - // Find Key and Value - - NSScanner * tScanner=[NSScanner scannerWithString:bLine]; - - NSString * tKey; - - if ([tScanner scanUpToString:@":" intoString:&tKey]==NO || - tScanner.scanLocation==tLineLength) - { - [tProcessedLines addObject:bLine]; - - return; - } - - NSRange tKeyRange=NSMakeRange(0,tScanner.scanLocation+1); - - - tScanner.scanLocation=tScanner.scanLocation+1; - - tScanner.charactersToBeSkipped=nil; - - [tScanner scanCharactersFromSet:self->_whitespaceCharacterSet intoString:NULL]; - - - - - - NSRange tValueRange=NSMakeRange(tScanner.scanLocation,bLine.length-1-tScanner.scanLocation+1); - - - - NSMutableAttributedString * tProcessedLine=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self->_cachedPlainTextAttributes]; - - //if (self.displaySettings.highlightSyntax==YES) - { - [tProcessedLine addAttributes:self->_cachedKeyAttributes range:tKeyRange]; - } - - if (bLineNumber==0) - { - NSDictionary * tJumpAnchorAttributes=@{ - CUISectionAnchorAttributeName:@"section:Exception Information" - }; - - [tProcessedLine addAttributes:tJumpAnchorAttributes range:NSMakeRange(0,bLine.length)]; - } - - if ([tKey isEqualToString:@"Exception Type"]==YES) - { - switch(self.hyperlinksStyle) - { - case CUIHyperlinksInternal: - - //if (self.displaySettings.highlightSyntax==YES) - { - [tProcessedLine addAttributes:@{ - NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle|NSUnderlineStylePatternDash) - } - - range:tValueRange]; - } - - [tProcessedLine addAttributes:@{ - NSLinkAttributeName:[NSURL URLWithString:@"a://exception_type"] - } - range:tValueRange]; - - break; - - default: - - break; - } - } - - if ([tKey isEqualToString:@"Crashed Thread"]==YES) - { - if ((self.displaySettings.visibleSections & CUIDocumentBacktracesSection)==CUIDocumentBacktracesSection && - self.crashLog.backtraces.threads.count>0) - { - switch(self.hyperlinksStyle) - { - case CUIHyperlinksInternal: - - [tProcessedLine addAttributes:@{ - NSLinkAttributeName:[NSURL URLWithString:@"a://crashed_thread"] - } - range:tKeyRange]; - - break; - - case CUIHyperlinksHTML: - - [tProcessedLine addAttributes:@{ - NSLinkAttributeName:[NSURL URLWithString:@"sharp://crashed_thread"] - } - range:tKeyRange]; - - break; - - default: - - break; - } - } - - //if (self.displaySettings.highlightSyntax==YES) - { - [tProcessedLine addAttributes:self->_cachedCrashedThreadLabelAttributes range:tValueRange]; - } - } - - [tProcessedLines addObject:tProcessedLine]; - }]; - - - return tProcessedLines; -} - -#pragma mark - Diagnostic Messages - -- (NSArray *)processedDiagnosticMessagesSectionLines:(NSArray *)inLines error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSMutableArray * tProcessedLines=[NSMutableArray array]; - - // First line - - NSDictionary * tJumpAnchorAttributes=@{ - CUISectionAnchorAttributeName:@"section:Diagnostic Messages" - }; - - NSMutableAttributedString * tAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:tJumpAnchorAttributes]; - - NSDictionary * tFirstLineAttributes=_cachedKeyAttributes; - - [tAttributedString addAttributes:tFirstLineAttributes range:NSMakeRange(0,tAttributedString.length)]; - - [tProcessedLines addObject:tAttributedString]; - - // Other Lines - - NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); - - [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] - options:0 - usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - id tObject=bLine; - - NSUInteger tLineLength=bLine.length; - - if (tLineLength==0) - { - [tProcessedLines addObject:bLine]; - - return; - } - - if ([bLine characterAtIndex:tLineLength-1]==':') - { - if ([bLine isEqualToString:@"Application Specific Information:"]==YES || - [bLine isEqualToString:@"Dyld Error Message:"]==YES || - [bLine isEqualToString:@"Application Specific Signatures:"]==YES || - [bLine isEqualToString:@"CreationBacktrace:"]==YES || - [bLine isEqualToString:@" Ordered grouping begin/end backtraces:"]==YES) - { - NSAttributedString * tLineAttributedString=[[NSAttributedString alloc] initWithString:bLine attributes:self->_cachedKeyAttributes]; - - tObject=tLineAttributedString; - } - } - - [tProcessedLines addObject:tObject]; - - }]; - - return tProcessedLines; -} - -#pragma mark - Backtraces - -- (NSArray *)processedBacktracesSectionLines:(NSArray *)inLines error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSMutableArray * tProcessedLines=[NSMutableArray array]; - - __block NSInteger tThreadEntityLineStart=0; - __block NSInteger tThreadEntityLineEnd=0; - - [inLines enumerateObjectsUsingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL *bOutStop) { - - // Retrieve thread number, crashed status and dispatch queue name - - if (bLine.length!=0) - return; - - tThreadEntityLineEnd=bLineNumber; // Keep the blank line - - NSRange tThreadRange=NSMakeRange(tThreadEntityLineStart, tThreadEntityLineEnd-tThreadEntityLineStart+1); - - NSError * tError; - - NSArray * tFilteredThreadLines=[self processedThreadBacktraceLines:[inLines subarrayWithRange:tThreadRange] error:&tError]; - - [tProcessedLines addObjectsFromArray:tFilteredThreadLines]; - - tThreadEntityLineStart=bLineNumber+1; - }]; - - NSMutableAttributedString * tMutableAttributedString=tProcessedLines.firstObject; - - NSDictionary * tJumpAnchorAttributes=@{ - CUISectionAnchorAttributeName:@"section:Backtraces" - }; - - [tMutableAttributedString addAttributes:tJumpAnchorAttributes - range:NSMakeRange(0, tMutableAttributedString.length)]; - - return tProcessedLines; -} - -- (NSArray *)processedThreadBacktraceLines:(NSArray *)inLines error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSString * tHeaderLine=inLines.firstObject; - BOOL tCrashedThread=NO; - NSString * tName=nil; - - if ([tHeaderLine isEqualToString:@"Backtrace not available"]==YES) - { - NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:tHeaderLine attributes:_cachedPlainTextAttributes]; - - NSMutableArray * tProcessedLines=[NSMutableArray arrayWithObject:tMutableAttributedString]; - - NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); - - [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] - options:0 - usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - [tProcessedLines addObject:bLine]; - }]; - - return [tProcessedLines copy]; - } - - CUICrashLogBacktraces * tBacktraces=self.crashLog.backtraces; - - CUIThread * tThread=nil; - - if ([tHeaderLine hasPrefix:@"Application Specific Backtrace"]==YES) - { - tName=@"Application Specific Backtrace"; - - tThread=[tBacktraces threadNamed:tName]; - } - else - { - NSArray * tComponents=[tHeaderLine componentsSeparatedByString:@"::"]; - NSString * tLeftPart; - - if (tComponents.count==0) - { - // Uh oh - - // A COMPLETER - } - - tLeftPart=tComponents.firstObject; - - if (tComponents.count!=2) - tLeftPart=[tLeftPart stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@":"]]; - - NSArray * tThreadNumberComponents=[tLeftPart componentsSeparatedByString:@" "]; - - if (tThreadNumberComponents.count<2) - { - // Uh oh - - // A COMPLETER - } - - tName=tThreadNumberComponents[1]; // <- it's actually the number - - if (tThreadNumberComponents.count==3) - { - if ([tThreadNumberComponents[2] caseInsensitiveCompare:@"Crashed"]==NSOrderedSame) - tCrashedThread=YES; - } - - if ((self.displaySettings.visibleSections & CUIDocumentBacktraceCrashedThreadSubSection)!=0) - { - if (tCrashedThread==NO) - return @[]; - } - - tThread=[tBacktraces threadWithNumber:[tName integerValue]]; - } - - - NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:_cachedPlainTextAttributes]; - - NSRange tStringRange=NSMakeRange(0, tMutableAttributedString.length); - - [tMutableAttributedString addAttributes:@{ - CUIThreadAnchorAttributeName:[NSString stringWithFormat:@"thread:%@",tName] - } - range:tStringRange]; - - - - - if (tCrashedThread==YES) - { - switch(self.hyperlinksStyle) - { - case CUIHyperlinksInternal: - - [tMutableAttributedString addAttributes:@{ - CUIGenericAnchorAttributeName:@"a:crashed_thread" - } - range:tStringRange]; - - break; - - case CUIHyperlinksHTML: - { - NSURL * tURL=[NSURL URLWithString:@"anchor://crashed_thread"]; - - if (tURL!=nil) - [tMutableAttributedString addAttributes:@{NSLinkAttributeName:tURL} - range:tStringRange]; - - break; - } - default: - - break; - } - } - - //if (self.displaySettings.highlightSyntax==YES) - { - NSDictionary * tAttributes=(tCrashedThread==YES) ? _cachedCrashedThreadLabelAttributes : _cachedThreadLabelAttributes; - - [tMutableAttributedString addAttributes:tAttributes - range:tStringRange]; - } - - - NSMutableArray * tProcessedLines=[NSMutableArray arrayWithObject:tMutableAttributedString]; - - NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); - - __block NSUInteger tStackFrameIndex=0; - - [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] - options:0 - usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - if (bLine.length==0) - { - [tProcessedLines addObject:bLine]; - return; - } - - NSString * tProcessedStackFrameLine=[self processedStackFrameLine:bLine stackFrame:tThread.callStackBacktrace.stackFrames[tStackFrameIndex]]; - - if (tProcessedStackFrameLine!=nil) - { - [tProcessedLines addObject:tProcessedStackFrameLine]; - } - else - { - NSLog(@"Error transforming line: %@",bLine); - - [tProcessedLines addObject:bLine]; - } - - tStackFrameIndex+=1; - - }]; - - return tProcessedLines; -} - -- (id)processedStackFrameLine:(NSString *)inLine stackFrame:(CUIStackFrame *)inStackFrame -{ - NSScanner * tScanner=[NSScanner scannerWithString:inLine]; - - if ([tScanner scanInteger:NULL]==NO) - return nil; - - __block NSString * tLine=inLine; - - tScanner.charactersToBeSkipped=nil; - - [tScanner scanCharactersFromSet:_whitespaceCharacterSet intoString:NULL]; - - tScanner.charactersToBeSkipped=_whitespaceCharacterSet; - - NSUInteger tBinaryImageIdentifierStart=tScanner.scanLocation; - - if ([tScanner scanUpToString:@"0x" intoString:nil]==NO) - return nil; - - NSRange tBinaryImageIdentifierRange; - - if (tScanner.scanLocation==tLine.length) - { - // try to find a \t - - tScanner.scanLocation=tBinaryImageIdentifierStart; - - if ([tScanner scanUpToString:@"\t" intoString:NULL]==NO) - return [[NSAttributedString alloc] initWithString:tLine attributes:_cachedParsingErrorAttributes]; - - if (tScanner.scanLocation==tLine.length) - return [[NSAttributedString alloc] initWithString:tLine attributes:_cachedParsingErrorAttributes]; - - tBinaryImageIdentifierRange=NSMakeRange(tBinaryImageIdentifierStart,tScanner.scanLocation-tBinaryImageIdentifierStart+1); - } - else - { - tBinaryImageIdentifierRange=NSMakeRange(tBinaryImageIdentifierStart,tScanner.scanLocation-1-tBinaryImageIdentifierStart+1); - } - - NSRange tBinEndRange=[[tLine substringWithRange:tBinaryImageIdentifierRange] rangeOfCharacterFromSet:_whitespaceCharacterSet.invertedSet options:NSBackwardsSearch]; - - NSString * tBinaryImageIdentifier=[tLine substringWithRange:NSMakeRange(tBinaryImageIdentifierRange.location, tBinEndRange.location+1)]; - - tScanner.charactersToBeSkipped=_whitespaceCharacterSet; - - unsigned long long tMachineInstructionAddress=0; - - if ([tScanner scanHexLongLong:&tMachineInstructionAddress]==NO) - return [[NSAttributedString alloc] initWithString:tLine]; - - BOOL tIsUserCode=NO; - - CUICrashLogBinaryImages * tBinaryImages=self.crashLog.binaryImages; - - CUIBinaryImage * tBinaryImage=[tBinaryImages binaryImageWithIdentifierOrName:tBinaryImageIdentifier identifier:&tBinaryImageIdentifier]; - - if (tBinaryImage!=nil) - { - NSString * tPath=tBinaryImage.path; - - if (tBinaryImage.isMainImage==YES) - { - tIsUserCode=YES; - } - else - { - if ([tPath isEqualToString:self.processPath]==YES) - tIsUserCode=YES; - } - } - - if (tIsUserCode==NO) - tIsUserCode=[tBinaryImages isUserCodeAtMemoryAddress:tMachineInstructionAddress inBinaryImage:tBinaryImageIdentifier]; - - NSRange tMemoryAddressRange=NSMakeRange(tBinaryImageIdentifierRange.location+tBinaryImageIdentifierRange.length,tScanner.scanLocation-(tBinaryImageIdentifierRange.location+tBinaryImageIdentifierRange.length)+1); - - NSString * tSymbol=nil; - - if ([tScanner scanUpToString:@" +" intoString:&tSymbol]==NO) - return [[NSAttributedString alloc] initWithString:tLine]; - - __block NSUInteger tSavedScanLocation=tScanner.scanLocation; - -#ifndef __DISABLE_SYMBOLICATION_ - - BOOL tSymbolicateAutomatically=[CUIApplicationPreferences sharedPreferences].symbolicateAutomatically; - - CUISymbolicationData * tSymbolicationData=nil; - - if (tSymbolicateAutomatically==YES) - { - tSymbolicationData=inStackFrame.symbolicationData; - } - - if (tSymbolicationData!=nil) - { - NSMutableString * tTemporaryLine=[[tLine substringToIndex:tScanner.scanLocation-tSymbol.length] mutableCopy]; - - if (tSymbolicationData.stackFrameSymbol==nil) - { - NSLog(@"Missing stackFrameSymbol"); - } - - tSavedScanLocation+=(tSymbolicationData.stackFrameSymbol.length-tSymbol.length); - - [tTemporaryLine appendString:[_symbolicationDataFormatter stringForObjectValue:tSymbolicationData]]; - - tLine=[tTemporaryLine copy]; - } - else - { - if (tSymbolicateAutomatically==YES) - { - // Default values - - NSUInteger tAddress=tMachineInstructionAddress-tBinaryImage.binaryImageOffset; - - [[CUISymbolicationManager sharedSymbolicationManager] lookUpSymbolicationDataForMachineInstructionAddress:tAddress - binaryUUID:tBinaryImage.UUID - completionHandler:^(CUISymbolicationDataLookUpResult bLookUpResult, CUISymbolicationData *bSymbolicationData) { - - switch(bLookUpResult) - { - case CUISymbolicationDataLookUpResultError: - case CUISymbolicationDataLookUpResultNotFound: - - break; - - case CUISymbolicationDataLookUpResultFound: - { - inStackFrame.symbolicationData=bSymbolicationData; - - [[NSNotificationCenter defaultCenter] postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification - object:self.crashLog]; - - break; - } - - case CUISymbolicationDataLookUpResultFoundInCache: - { - inStackFrame.symbolicationData=bSymbolicationData; - - NSMutableString * tTemporaryLine=[[tLine substringToIndex:tScanner.scanLocation-tSymbol.length] mutableCopy]; - - tSavedScanLocation+=(bSymbolicationData.stackFrameSymbol.length-tSymbol.length); - - [tTemporaryLine appendString:[self->_symbolicationDataFormatter stringForObjectValue:bSymbolicationData]]; - - tLine=[tTemporaryLine copy]; - - break; - } - - } - - }]; - } - } - -#endif - - NSMutableAttributedString * tProcessedLine=[[NSMutableAttributedString alloc] initWithString:tLine attributes:_cachedPlainTextAttributes]; - - NSRange tRange=NSMakeRange(0,tLine.length); - - NSDictionary * tDictionary=(tIsUserCode==YES) ? _cachedExecutableCodeAttributes : _cachedOSCodeAttributes; - - [tProcessedLine addAttributes:tDictionary range:tRange]; - - - if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==0) - { - [tProcessedLine deleteCharactersInRange:NSMakeRange(tSavedScanLocation, tLine.length-1-tSavedScanLocation+1)]; - } - else - { -#ifndef __DISABLE_SYMBOLICATION_ - if (tSymbolicationData!=nil) - { - NSString * tAbsolutePath=inStackFrame.symbolicationData.sourceFilePath; - NSString * tLastPathComponent=tAbsolutePath.lastPathComponent; - - if (tLastPathComponent!=nil) - { - NSRange tRange=[tLine rangeOfString:tLastPathComponent]; - - if (tRange.location!=0) - { - if ([[NSFileManager defaultManager] fileExistsAtPath:tAbsolutePath]==YES) - { - NSURLComponents * tURLComponents=[NSURLComponents new]; - tURLComponents.scheme=[NSString stringWithFormat:@"sourcecode-%lu",inStackFrame.symbolicationData.lineNumber]; - tURLComponents.path=tAbsolutePath; - - NSURL * tURL=tURLComponents.URL; - - if (tURL!=nil) - { - [tProcessedLine addAttributes:@{ - NSLinkAttributeName:tURL, - NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle), - NSUnderlineColorAttributeName:_cachedUnderlineColor - } - range:tRange]; - - - } - } - } - } - } -#endif - } - - - if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)==0) - { - [tProcessedLine deleteCharactersInRange:tMemoryAddressRange]; - } - else - { - //if (self.displaySettings.highlightSyntax==YES) - { - [tProcessedLine addAttributes:_cachedMemoryAddressAttributes range:tMemoryAddressRange]; - } - } - - if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)==0) - { - [tProcessedLine deleteCharactersInRange:tBinaryImageIdentifierRange]; - } - else - { - if (self.hyperlinksStyle!=CUIHyperlinksNone && ((_displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==CUIDocumentBinaryImagesSection)) - { - NSString * tCleanedUpIdenftifier=[tBinaryImageIdentifier stringByTrimmingCharactersInSet:_whitespaceCharacterSet]; - - CUIBinaryImage * tBinaryImage=[tBinaryImages binaryImageWithIdentifier:tBinaryImageIdentifier]; - - if (tBinaryImage==nil) - { - tBinaryImage=[tBinaryImages binaryImageWithIdentifier:tBinaryImageIdentifier]; - - if (tBinaryImage==nil) - { - tBinaryImageIdentifier=[tBinaryImages binaryImageIdentifierForName:tBinaryImageIdentifier]; - } - else - { - tBinaryImageIdentifier=nil; - } - } - - if (tBinaryImageIdentifier!=nil) - { - NSURL * tURL=nil; - - switch(self.hyperlinksStyle) - { - case CUIHyperlinksInternal: - - tURL=[NSURL URLWithString:[NSString stringWithFormat:@"bin://%@",tBinaryImageIdentifier]]; - - break; - - case CUIHyperlinksHTML: - - tURL=[NSURL URLWithString:[NSString stringWithFormat:@"sharp://%@",tBinaryImageIdentifier]]; - - break; - - default: - - break; - } - - if (tURL!=nil) - [tProcessedLine addAttributes:@{NSLinkAttributeName:tURL} range:NSMakeRange(tBinaryImageIdentifierRange.location,tCleanedUpIdenftifier.length)]; - - } - } - } - - return tProcessedLine; -} - -#pragma mark - Thread State - -- (NSArray *)processedThreadStateSectionLines:(NSArray *)inLines error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSMutableArray * tProcessedLines=[NSMutableArray array]; - - // First line - - NSDictionary * tJumpAnchorAttributes=@{ - CUISectionAnchorAttributeName:@"section:Thread State" - }; - - NSMutableAttributedString * tAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:tJumpAnchorAttributes]; - - NSDictionary * tFirstLineAttributes=_cachedKeyAttributes; - - [tAttributedString addAttributes:tFirstLineAttributes range:NSMakeRange(0,tAttributedString.length)]; - - - [tProcessedLines addObject:tAttributedString]; - - // Other Lines - - NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); - - __block NSUInteger tLastLine=0; - - - - [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] - options:0 - usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - NSMutableAttributedString * tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self->_cachedKeyAttributes]; - - if (bLine.length<4) - { - tLastLine=bLineNumber+1; - - [tProcessedLines addObject:tMutableAttributedString]; - - *bOutStop=YES; - return; - } - - NSScanner * tRegistersScanner=[NSScanner scannerWithString:bLine]; - - tRegistersScanner.charactersToBeSkipped=self->_whitespaceCharacterSet; - - while (tRegistersScanner.isAtEnd==NO) - { - tRegistersScanner.charactersToBeSkipped=nil; - - [tRegistersScanner scanCharactersFromSet:self->_whitespaceCharacterSet intoString:nil]; - - NSString * tRegisterName; - - tRegistersScanner.charactersToBeSkipped=self->_whitespaceCharacterSet; - - if ([tRegistersScanner scanUpToString:@":" intoString:&tRegisterName]==NO) - return; - - if ([tRegistersScanner scanString:@": " intoString:NULL]==NO) - return; - - NSRange tValueRange=NSMakeRange(tRegistersScanner.scanLocation, 0); - - if ([tRegistersScanner scanHexLongLong:NULL]==NO) - return; - - tValueRange.length=tRegistersScanner.scanLocation-1-tValueRange.location+1; - - tRegistersScanner.charactersToBeSkipped=nil; - - [tRegistersScanner scanCharactersFromSet:self->_whitespaceCharacterSet intoString:nil]; - - [tMutableAttributedString addAttributes:self->_cachedRegisterValueAttributes range:tValueRange]; - } - - [tProcessedLines addObject:tMutableAttributedString]; - - }]; - - // Remaining lines - - [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(tLastLine,inLines.count-1-tLastLine+1)] options:0 usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - NSUInteger tLineLength=bLine.length; - - // Skip Blank lines - - if (tLineLength==0) - { - [tProcessedLines addObject:[[NSAttributedString alloc] initWithString:bLine attributes:self->_cachedPlainTextAttributes]]; - return; - } - - // Find Key and Value - - NSScanner * tScanner=[NSScanner scannerWithString:bLine]; - - NSString * tKey; - - if ([tScanner scanUpToString:@":" intoString:&tKey]==NO) - { - // A COMPLETER - - [tProcessedLines addObject:[[NSAttributedString alloc] initWithString:bLine attributes:self->_cachedPlainTextAttributes]]; - - return; - } - - NSRange tKeyRange=NSMakeRange(0,tScanner.scanLocation+1); - - - NSMutableAttributedString * tMutableAttributedString=nil; - - if (tScanner.scanLocation_whitespaceCharacterSet intoString:NULL]; - - tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:[bLine substringWithRange:tKeyRange] attributes:self->_cachedKeyAttributes]; - - NSAttributedString * tOther=[[NSAttributedString alloc] initWithString:[bLine substringWithRange:NSMakeRange(tKeyRange.length,bLine.length-1-tKeyRange.length+1)] attributes:self->_cachedPlainTextAttributes]; - - [tMutableAttributedString appendAttributedString:tOther]; - } - else - { - tMutableAttributedString=[[NSMutableAttributedString alloc] initWithString:bLine attributes:self->_cachedPlainTextAttributes]; - } - - [tProcessedLines addObject:tMutableAttributedString]; - - }]; - - return tProcessedLines; -} - - -#pragma mark - Binary Images - -- (NSArray *)processedBinaryImagesSectionLines:(NSArray *)inLines reportVersion:(NSUInteger)inReportVersion error:(NSError **)outError -{ - if (inLines.count==0) - return inLines; - - NSMutableArray * tProcessedLines=[NSMutableArray array]; - - // First line - - NSDictionary * tJumpAnchorAttributes=@{ - CUISectionAnchorAttributeName:@"section:Binary Images" - }; - - NSMutableAttributedString * tAttributedString=[[NSMutableAttributedString alloc] initWithString:inLines.firstObject attributes:tJumpAnchorAttributes]; - - NSDictionary * tFirstLineAttributes=_cachedKeyAttributes; - - if (tFirstLineAttributes!=nil) - [tAttributedString addAttributes:tFirstLineAttributes range:NSMakeRange(0,tAttributedString.length)]; - - [tProcessedLines addObject:tAttributedString]; - - // Other Lines - - NSRange tOtherLinesRange=NSMakeRange(1,inLines.count-1); - - [inLines enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tOtherLinesRange] - options:0 - usingBlock:^(NSString * bLine, NSUInteger bLineNumber, BOOL *bOutStop) { - - if (bLine.length==0) - { - [tProcessedLines addObjectsFromArray:[inLines subarrayWithRange:NSMakeRange(bLineNumber,inLines.count-1-bLineNumber+1)]]; - - *bOutStop=YES; - - return; - } - - id tProcessedLine=[self processedBinaryImageLine:bLine reportVersion:inReportVersion]; - - if (tProcessedLine==nil) - { - tProcessedLine=[[NSAttributedString alloc] initWithString:bLine attributes:self->_cachedParsingErrorAttributes]; - - NSLog(@"Error transforming line: %@",bLine); - } - - [tProcessedLines addObject:tProcessedLine]; - }]; - - return tProcessedLines; -} - -- (id)processedBinaryImageLine:(NSString *)inLine reportVersion:(NSUInteger)inReportVersion -{ - NSScanner * tScanner=[NSScanner scannerWithString:inLine]; - - tScanner.charactersToBeSkipped=nil; - - [tScanner scanCharactersFromSet:_whitespaceCharacterSet intoString:NULL]; - - NSUInteger tMinAddressStart=tScanner.scanLocation; - - tScanner.charactersToBeSkipped=_whitespaceCharacterSet; - - if ([tScanner scanHexLongLong:NULL]==NO) - return nil; - - NSUInteger tMinAddressEnd=tScanner.scanLocation; - - [tScanner scanUpToString:@"0x" intoString:NULL]; - - NSUInteger tMaxAddressStart=tScanner.scanLocation; - - if ([tScanner scanHexLongLong:NULL]==NO) - return nil; - - NSUInteger tMaxAddressEnd=tScanner.scanLocation; - - tScanner.charactersToBeSkipped=nil; - - [tScanner scanCharactersFromSet:_whitespaceCharacterSet intoString:NULL]; - - NSUInteger tIdentifierStart=tScanner.scanLocation; - - NSString * tIdentifier=nil; - NSString * tOriginalString; - - if ([tScanner scanUpToString:@"(" intoString:&tOriginalString]==NO) - return nil; - - if (inReportVersion==6) - { - // Remove the version - - NSUInteger tLength=tOriginalString.length; - - NSRange tRange=[tOriginalString rangeOfCharacterFromSet:_whitespaceCharacterSet options:NSBackwardsSearch range:NSMakeRange(0,tLength-1)]; - - if (tRange.location==NSNotFound) - return nil; - - tIdentifier=[tOriginalString substringToIndex:tRange.location]; - } - else - { - tIdentifier=tOriginalString; - } - - BOOL tIsUserCode=NO; - - tIdentifier=[tIdentifier stringByTrimmingCharactersInSet:_whitespaceCharacterSet]; - - NSUInteger tIdentifierRealLength=tIdentifier.length; - - if ([tIdentifier hasPrefix:@"+"]==YES && tIdentifierRealLength>1) - { - // User Code - - tIsUserCode=YES; - - tIdentifier=[tIdentifier substringFromIndex:1]; - } - - NSMutableAttributedString * tNewLine=[[NSMutableAttributedString alloc] initWithString:inLine attributes:_cachedPlainTextAttributes]; - - switch(self.hyperlinksStyle) - { - case CUIHyperlinksHTML: - { - NSURL * tURL=[NSURL URLWithString:[NSString stringWithFormat:@"anchor://%@",tIdentifier]]; - - if (tURL!=nil) - [tNewLine addAttributes:@{NSLinkAttributeName:tURL} - range:NSMakeRange(0, tNewLine.length)]; - - break; - } - - default: - - [tNewLine addAttributes:@{ - CUIBinaryAnchorAttributeName:[NSString stringWithFormat:@"bin:%@",tIdentifier] - } - range:NSMakeRange(0, tNewLine.length)]; - - break; - } - - tScanner.scanLocation=tIdentifierStart+tIdentifierRealLength; - - NSRange tIdentifierRange=NSMakeRange(tIdentifierStart, tIdentifierRealLength); - - if (inReportVersion==6) - { - tScanner.scanLocation+=1; - } - else - { - if ([tScanner scanUpToString:@"(" intoString:NULL]==NO) - return nil; - } - - NSUInteger tVersionStart=tScanner.scanLocation; - - if ([tScanner scanUpToString:@")" intoString:NULL]==NO) - return nil; - - NSUInteger tVersionEnd=tScanner.scanLocation; - - // UUID can be missing // A COMPLETER - - tScanner.scanLocation+=2; - - NSUInteger tUUIDStart=NSNotFound; - NSUInteger tUUIDEnd=NSNotFound; - - if ([inLine characterAtIndex:tScanner.scanLocation]=='<') - { - tUUIDStart=tScanner.scanLocation; - - if ([tScanner scanUpToString:@">" intoString:NULL]==NO) - return nil; - - tUUIDEnd=tScanner.scanLocation; - } - else - { - tScanner.scanLocation-=2; - } - - if ([tScanner scanUpToString:@"/" intoString:NULL]==NO) - return nil; - - NSRange tPathRange=NSMakeRange(tScanner.scanLocation,inLine.length-1-tScanner.scanLocation+1); - - NSDictionary * tIdentifierAttributes=_cachedPlainTextAttributes; - - if ([CUIThemesManager sharedManager].currentTheme.isMonochrome==NO) - { - tIdentifierAttributes=@{ - NSForegroundColorAttributeName:(tIsUserCode==YES) ? [CUIBinaryImage colorForUserCode]: [CUIBinaryImage colorForIdentifier:tIdentifier] - }; - } - - [tNewLine addAttributes:tIdentifierAttributes - range:tIdentifierRange]; - - [tNewLine addAttributes:_cachedMemoryAddressAttributes - range:NSMakeRange(tMinAddressStart, tMinAddressEnd-tMinAddressStart+1)]; - - [tNewLine addAttributes:_cachedMemoryAddressAttributes - range:NSMakeRange(tMaxAddressStart, tMaxAddressEnd-tMaxAddressStart+1)]; - - if (tUUIDStart!=NSNotFound) - { - [tNewLine addAttributes:_cachedUUIDAttributes - range:NSMakeRange(tUUIDStart,tUUIDEnd-tUUIDStart+1)]; - } - - [tNewLine addAttributes:_cachedVersionAttributes - range:NSMakeRange(tVersionStart,tVersionEnd-tVersionStart+1)]; - - [tNewLine addAttributes:_cachedPathAttributes - range:tPathRange]; - - return tNewLine; -} - -#pragma mark - - -- (NSAttributedString *)joinLines:(NSArray *)inLines withString:(NSString *)inNewLineFeed -{ - NSMutableAttributedString * tMutableAttributedString=[NSMutableAttributedString new]; - - [inLines enumerateObjectsUsingBlock:^(id bLine, NSUInteger bLineNumber, BOOL * bOutStop) { - - if ([bLine isKindOfClass:[NSString class]]==YES) - { - NSAttributedString * tAttributedString=[[NSAttributedString alloc] initWithString:bLine - attributes:self->_cachedPlainTextAttributes]; - - [tMutableAttributedString appendAttributedString:tAttributedString]; - - if (bLineNumber_cachedPlainTextAttributes]]; - - return; - } - - if ([bLine isKindOfClass:[NSAttributedString class]]==YES) - { - [tMutableAttributedString appendAttributedString:bLine]; - - if (bLineNumber_cachedPlainTextAttributes]]; - } - }]; - - return tMutableAttributedString; -} - -@end diff --git a/app_unexpectedly/app_unexpectedly/CUIRegisterLabel.m b/app_unexpectedly/app_unexpectedly/CUIRegisterLabel.m index fa7903a..1e7314e 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRegisterLabel.m +++ b/app_unexpectedly/app_unexpectedly/CUIRegisterLabel.m @@ -139,11 +139,11 @@ - (IBAction)switchDisplayFormat:(NSPopUpButton *)sender // Post notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIRegisterLabelViewAsValueDidChangeNotification - object:self - userInfo:@{ - @"viewAs":@(tViewValueAs) - }]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIRegisterLabelViewAsValueDidChangeNotification + object:self + userInfo:@{ + @"viewAs":@(tViewValueAs) + }]; } #pragma mark - diff --git a/app_unexpectedly/app_unexpectedly/CUIRegistersMainViewController.m b/app_unexpectedly/app_unexpectedly/CUIRegistersMainViewController.m index 1702dab..2219da1 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRegistersMainViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIRegistersMainViewController.m @@ -66,7 +66,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -82,7 +82,7 @@ - (void)viewDidLoad // Register for Notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; } - (void)viewWillAppear @@ -93,7 +93,7 @@ - (void)viewWillAppear // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIRegistersMainViewContentsViewDidChangeNotificaton object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIRegistersMainViewContentsViewDidChangeNotificaton object:self]; } @@ -185,7 +185,7 @@ - (void)setSelection:(CUICrashLogsSelection *)inSelection // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIRegistersMainViewContentsViewDidChangeNotificaton object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIRegistersMainViewContentsViewDidChangeNotificaton object:self]; } - (NSSize)idealSizeForNumberOfColumns:(NSUInteger)inColumnsNumber diff --git a/app_unexpectedly/app_unexpectedly/CUIRegistersViewController.m b/app_unexpectedly/app_unexpectedly/CUIRegistersViewController.m index f8993e7..bfc6a95 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRegistersViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIRegistersViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -34,7 +34,7 @@ @implementation CUIRegistersViewController - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } - (NSString *)nibName @@ -57,7 +57,7 @@ - (void)viewDidLoad // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registerItemValueAsDidChange:) name:CUIRegisterItemViewAsValueDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(registerItemValueAsDidChange:) name:CUIRegisterItemViewAsValueDidChangeNotification object:nil]; } #pragma mark - @@ -116,40 +116,38 @@ - (void)refreshUI #pragma mark - NSCollectionViewDataSource -- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView +- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)inCollectionView { + NSAssert(inCollectionView==_collectionView, @"Unexpected collection view provided as parameter"); + return 1; } - (NSInteger)collectionView:(NSCollectionView *)inCollectionView numberOfItemsInSection:(NSInteger)inSection { - if (inCollectionView==_collectionView) - return _threadState.registers.count; + NSAssert(inCollectionView==_collectionView, @"Unexpected collection view provided as parameter"); - return 0; + return _threadState.registers.count; } - (NSCollectionViewItem *)collectionView:(NSCollectionView *)inCollectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)inIndexPath { - if (inCollectionView==_collectionView) - { - CUICollectionViewRegisterItem * tCollectionViewItem=(CUICollectionViewRegisterItem *)[inCollectionView makeItemWithIdentifier:@"register" forIndexPath:inIndexPath]; - - CUIRegister * tRegister=_threadState.registers[inIndexPath.item]; - - NSMutableDictionary * tRepresentedObject=[NSMutableDictionary dictionaryWithObject:tRegister forKey:@"register"]; - - NSNumber * tNumber=self.browsingState.registersViewValues[tRegister.name]; - - if (tNumber!=nil) - tRepresentedObject[@"viewAs"]=tNumber; - - tCollectionViewItem.representedObject=tRepresentedObject; - - return tCollectionViewItem; - } - - return nil; + NSAssert(inCollectionView==_collectionView, @"Unexpected collection view provided as parameter"); + + CUICollectionViewRegisterItem * tCollectionViewItem=(CUICollectionViewRegisterItem *)[inCollectionView makeItemWithIdentifier:@"register" forIndexPath:inIndexPath]; + + CUIRegister * tRegister=_threadState.registers[inIndexPath.item]; + + NSMutableDictionary * tRepresentedObject=[NSMutableDictionary dictionaryWithObject:tRegister forKey:@"register"]; + + NSNumber * tNumber=self.browsingState.registersViewValues[tRegister.name]; + + if (tNumber!=nil) + tRepresentedObject[@"viewAs"]=tNumber; + + tCollectionViewItem.representedObject=tRepresentedObject; + + return tCollectionViewItem; } #pragma mark - Notifications diff --git a/app_unexpectedly/app_unexpectedly/CUIRegistersWindowController.m b/app_unexpectedly/app_unexpectedly/CUIRegistersWindowController.m index e39319a..4c20554 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRegistersWindowController.m +++ b/app_unexpectedly/app_unexpectedly/CUIRegistersWindowController.m @@ -72,7 +72,7 @@ - (void)windowDidLoad // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registersMainViewContentsViewDidChange:) name:CUIRegistersMainViewContentsViewDidChangeNotificaton object:_mainViewController]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(registersMainViewContentsViewDidChange:) name:CUIRegistersMainViewContentsViewDidChangeNotificaton object:_mainViewController]; NSRect tContentsBounds=self.window.contentView.bounds; diff --git a/app_unexpectedly/app_unexpectedly/CUIReportThemedTransform.h b/app_unexpectedly/app_unexpectedly/CUIReportThemedTransform.h new file mode 100644 index 0000000..527a646 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIReportThemedTransform.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIDataTransform.h" + +#import + +#import "CUICrashLog.h" + +#import "CUITheme.h" + +#ifndef __DISABLE_SYMBOLICATION_ + +#import "CUISymbolicationManager.h" + +#import "CUISymbolicationDataFormatter.h" +#endif + +@interface CUIReportThemedTransform : CUIDataTransform + + @property (readonly) id themesProvider; + + + @property (readonly) NSDictionary * plainTextAttributes; + + @property (readonly) NSDictionary * keyAttributes; + + @property (readonly) NSDictionary * versionAttributes; + + @property (readonly) NSDictionary * pathAttributes; + + @property (readonly) NSDictionary * UUIDAttributes; + + @property (readonly) NSDictionary * crashedThreadLabelAttributes; + + @property (readonly) NSDictionary * threadLabelAttributes; + + @property (readonly) NSDictionary * executableCodeAttributes; + + @property (readonly) NSDictionary * OSCodeAttributes; + + @property (readonly) NSDictionary * memoryAddressAttributes; + + + @property (readonly) NSDictionary * registerValueAttributes; + + + @property (readonly) NSDictionary * parsingErrorAttributes; + + @property (readonly) NSColor * underlineColor; + + @property (readonly) NSCharacterSet * whitespaceCharacterSet; + +#ifndef __DISABLE_SYMBOLICATION_ + @property (readonly) CUISymbolicationDataFormatter * symbolicationDataFormatter; +#endif + + @property (copy) NSString * processPath; + + @property (nonatomic) CUICrashLog * crashlog; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithThemesProvider:(id )inThemesProvider NS_DESIGNATED_INITIALIZER; + +- (void)updatesCachedAttributes; + +- (id)processedStackFrameLine:(NSString *)inLine stackFrame:(CUIStackFrame *)inStackFrame; + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIReportThemedTransform.m b/app_unexpectedly/app_unexpectedly/CUIReportThemedTransform.m new file mode 100644 index 0000000..8063060 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIReportThemedTransform.m @@ -0,0 +1,426 @@ +/* + Copyright (c) 2022, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUIReportThemedTransform.h" + +#import "CUIApplicationPreferences.h" +#import "CUIApplicationPreferences+Themes.h" + +#import "CUIThemeItemsGroup+UI.h" + +@interface CUIReportThemedTransform () + + @property (readwrite) NSDictionary * plainTextAttributes; + + @property (readwrite) NSDictionary * keyAttributes; + + @property (readwrite) NSDictionary * versionAttributes; + + @property (readwrite) NSDictionary * pathAttributes; + + @property (readwrite) NSDictionary * UUIDAttributes; + + @property (readwrite) NSDictionary * crashedThreadLabelAttributes; + + @property (readwrite) NSDictionary * threadLabelAttributes; + + @property (readwrite) NSDictionary * executableCodeAttributes; + + @property (readwrite) NSDictionary * OSCodeAttributes; + + @property (readwrite) NSDictionary * memoryAddressAttributes; + + + @property (readwrite) NSDictionary * registerValueAttributes; + + + @property (readwrite) NSDictionary * parsingErrorAttributes; + + @property (readwrite) NSColor * underlineColor; + +@end + +@implementation CUIReportThemedTransform + +- (instancetype)initWithThemesProvider:(id )inThemesProvider; +{ + self=[super init]; + + if (self!=nil) + { + _themesProvider=inThemesProvider; + +#ifndef __DISABLE_SYMBOLICATION_ + _symbolicationDataFormatter=[CUISymbolicationDataFormatter new]; +#endif + + _whitespaceCharacterSet=[NSCharacterSet whitespaceCharacterSet]; + } + + return self; +} + +#pragma mark - + +- (void)updatesCachedAttributes +{ + NSFontManager * tFontManager = [NSFontManager sharedFontManager]; + + CUIThemeItemsGroup * tItemsGroup=[self.themesProvider.currentTheme itemsGroupWithIdentifier:[CUIApplicationPreferences groupIdentifierForPresentationMode:CUIPresentationModeText]]; + + NSMutableArray * tItemsNames=[tItemsGroup.itemsNames mutableCopy]; + + [tItemsNames removeObject:CUIThemeItemBackground]; + [tItemsNames removeObject:CUIThemeItemLineNumber]; + [tItemsNames removeObject:CUIThemeItemSelectionBackground]; + [tItemsNames removeObject:CUIThemeItemSelectionText]; + + // TabStops settings + + NSMutableParagraphStyle * tMutableParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + + tMutableParagraphStyle.tabStops=@[]; + + [tMutableParagraphStyle setLineSpacing:2.0]; + + for (NSUInteger tIndex = 1; tIndex <= 20; tIndex++) + { + NSTextTab *tabStop = [[NSTextTab alloc] initWithType:NSLeftTabStopType location: 40 * (tIndex)]; + [tMutableParagraphStyle addTabStop:tabStop]; + } + + NSMutableDictionary * tMutableDictionary=[NSMutableDictionary dictionary]; + + for(NSString * tItemName in tItemsNames) + { + CUIThemeItemAttributes * tItemAttributes=[tItemsGroup attributesForItem:tItemName]; + + NSFont * tFont=tItemAttributes.font; + + NSFont * tAdjustedFont=nil; + + tAdjustedFont=[tFontManager convertFont:tFont toSize:tFont.pointSize + self.fontSizeDelta]; + + if (tAdjustedFont==nil) + tAdjustedFont=tFont; + + tMutableDictionary[tItemName]=@{ + NSFontAttributeName:tAdjustedFont, + NSForegroundColorAttributeName:tItemAttributes.color, + NSParagraphStyleAttributeName:tMutableParagraphStyle + }; + } + + self.plainTextAttributes=tMutableDictionary[CUIThemeItemPlainText]; + + NSColor * tForegroundColor=self.plainTextAttributes[NSForegroundColorAttributeName]; + self.underlineColor=[tForegroundColor colorWithAlphaComponent:0.35]; + + self.keyAttributes=tMutableDictionary[CUIThemeItemKey]; + self.threadLabelAttributes=tMutableDictionary[CUIThemeItemThreadLabel]; + self.crashedThreadLabelAttributes=tMutableDictionary[CUIThemeItemCrashedThreadLabel]; + + self.executableCodeAttributes=tMutableDictionary[CUIThemeItemExecutableCode]; + self.OSCodeAttributes=tMutableDictionary[CUIThemeItemOSCode]; + + self.versionAttributes=tMutableDictionary[CUIThemeItemVersion]; + self.memoryAddressAttributes=tMutableDictionary[CUIThemeItemMemoryAddress]; + self.pathAttributes=tMutableDictionary[CUIThemeItemPath]; + self.UUIDAttributes=tMutableDictionary[CUIThemeItemUUID]; + self.registerValueAttributes=tMutableDictionary[CUIThemeItemRegisterValue]; + + + NSMutableDictionary * tParsingErrorDictionary=[self.plainTextAttributes mutableCopy]; + + tParsingErrorDictionary[NSForegroundColorAttributeName]=[NSColor redColor]; + + self.parsingErrorAttributes=[tParsingErrorDictionary copy]; +} + +#pragma mark - + +- (id)processedStackFrameLine:(NSString *)inLine stackFrame:(CUIStackFrame *)inStackFrame +{ + NSScanner * tScanner=[NSScanner scannerWithString:inLine]; + + if ([tScanner scanInteger:NULL]==NO) + return nil; + + __block NSString * tLine=inLine; + + tScanner.charactersToBeSkipped=nil; + + [tScanner scanCharactersFromSet:self.whitespaceCharacterSet intoString:NULL]; + + tScanner.charactersToBeSkipped=self.whitespaceCharacterSet; + + NSUInteger tBinaryImageIdentifierStart=tScanner.scanLocation; + + if ([tScanner scanUpToString:@"0x" intoString:nil]==NO) + return nil; + + NSRange tBinaryImageIdentifierRange; + + if (tScanner.scanLocation==tLine.length) + { + // try to find a \t + + tScanner.scanLocation=tBinaryImageIdentifierStart; + + if ([tScanner scanUpToString:@"\t" intoString:NULL]==NO) + return [[NSAttributedString alloc] initWithString:tLine attributes:self.parsingErrorAttributes]; + + if (tScanner.scanLocation==tLine.length) + return [[NSAttributedString alloc] initWithString:tLine attributes:self.parsingErrorAttributes]; + + tBinaryImageIdentifierRange=NSMakeRange(tBinaryImageIdentifierStart,tScanner.scanLocation-tBinaryImageIdentifierStart+1); + } + else + { + tBinaryImageIdentifierRange=NSMakeRange(tBinaryImageIdentifierStart,tScanner.scanLocation-1-tBinaryImageIdentifierStart+1); + } + + NSRange tBinEndRange=[[tLine substringWithRange:tBinaryImageIdentifierRange] rangeOfCharacterFromSet:self.whitespaceCharacterSet.invertedSet options:NSBackwardsSearch]; + + NSString * tBinaryImageIdentifier=[tLine substringWithRange:NSMakeRange(tBinaryImageIdentifierRange.location, tBinEndRange.location+1)]; + + tScanner.charactersToBeSkipped=self.whitespaceCharacterSet; + + unsigned long long tMachineInstructionAddress=0; + + if ([tScanner scanHexLongLong:&tMachineInstructionAddress]==NO) + return [[NSAttributedString alloc] initWithString:tLine]; + + BOOL tIsUserCode=NO; + + CUICrashLogBinaryImages * tBinaryImages=self.crashlog.binaryImages; + + CUIBinaryImage * tBinaryImage=[tBinaryImages binaryImageWithIdentifierOrName:tBinaryImageIdentifier identifier:&tBinaryImageIdentifier]; + + if (tBinaryImage!=nil) + { + tIsUserCode = tBinaryImage.isUserCode; + + if (tIsUserCode==NO && [tBinaryImage.path isEqualToString:self.processPath]==YES) + tIsUserCode=YES; + } + + if (tIsUserCode==NO) + tIsUserCode=[tBinaryImages isUserCodeAtMemoryAddress:tMachineInstructionAddress inBinaryImage:tBinaryImageIdentifier]; + + NSRange tMemoryAddressRange=NSMakeRange(tBinaryImageIdentifierRange.location+tBinaryImageIdentifierRange.length,tScanner.scanLocation-(tBinaryImageIdentifierRange.location+tBinaryImageIdentifierRange.length)+1); + + NSString * tSymbol=nil; + + if ([tScanner scanUpToString:@" +" intoString:&tSymbol]==NO) + return [[NSAttributedString alloc] initWithString:tLine]; + + __block NSUInteger tSavedScanLocation=tScanner.scanLocation; + +#ifndef __DISABLE_SYMBOLICATION_ + + BOOL tSymbolicateAutomatically=[CUIApplicationPreferences sharedPreferences].symbolicateAutomatically; + + if (self.symbolicationMode==CUISymbolicationModeNone) + tSymbolicateAutomatically=NO; + + CUISymbolicationData * tSymbolicationData=nil; + + if (tSymbolicateAutomatically==YES) + { + tSymbolicationData=inStackFrame.symbolicationData; + } + + if (tSymbolicationData!=nil) + { + NSMutableString * tTemporaryLine=[[tLine substringToIndex:tScanner.scanLocation-tSymbol.length] mutableCopy]; + + if (tSymbolicationData.stackFrameSymbol==nil) + { + NSLog(@"Missing stackFrameSymbol"); + } + + tSavedScanLocation+=(tSymbolicationData.stackFrameSymbol.length-tSymbol.length); + + [tTemporaryLine appendString:[self.symbolicationDataFormatter stringForObjectValue:tSymbolicationData]]; + + tLine=[tTemporaryLine copy]; + } + else + { + if (tSymbolicateAutomatically==YES) + { + // Default values + + NSUInteger tAddress=tMachineInstructionAddress-tBinaryImage.binaryImageOffset; + + [[CUISymbolicationManager sharedSymbolicationManager] lookUpSymbolicationDataForMachineInstructionAddress:tAddress + binaryUUID:tBinaryImage.UUID + completionHandler:^(CUISymbolicationDataLookUpResult bLookUpResult, CUISymbolicationData *bSymbolicationData) { + + switch(bLookUpResult) + { + case CUISymbolicationDataLookUpResultError: + case CUISymbolicationDataLookUpResultNotFound: + + break; + + case CUISymbolicationDataLookUpResultFound: + { + inStackFrame.symbolicationData=bSymbolicationData; + + [NSNotificationCenter.defaultCenter postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification + object:self.input]; + + break; + } + + case CUISymbolicationDataLookUpResultFoundInCache: + { + inStackFrame.symbolicationData=bSymbolicationData; + + NSMutableString * tTemporaryLine=[[tLine substringToIndex:tScanner.scanLocation-tSymbol.length] mutableCopy]; + + tSavedScanLocation+=(bSymbolicationData.stackFrameSymbol.length-tSymbol.length); + + [tTemporaryLine appendString:[self.symbolicationDataFormatter stringForObjectValue:bSymbolicationData]]; + + tLine=[tTemporaryLine copy]; + + break; + } + + } + + }]; + } + } + +#endif + + NSMutableAttributedString * tProcessedLine=[[NSMutableAttributedString alloc] initWithString:tLine attributes:self.plainTextAttributes]; + + NSRange tRange=NSMakeRange(0,tLine.length); + + NSDictionary * tDictionary=(tIsUserCode==YES) ? self.executableCodeAttributes : self.OSCodeAttributes; + + [tProcessedLine addAttributes:tDictionary range:tRange]; + + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameByteOffsetComponent)==0) + { + [tProcessedLine deleteCharactersInRange:NSMakeRange(tSavedScanLocation, tLine.length-1-tSavedScanLocation+1)]; + } + else + { +#ifndef __DISABLE_SYMBOLICATION_ + if (tSymbolicationData!=nil) + { + NSString * tAbsolutePath=inStackFrame.symbolicationData.sourceFilePath; + NSString * tLastPathComponent=tAbsolutePath.lastPathComponent; + + if (tLastPathComponent!=nil) + { + NSRange tRange=[tLine rangeOfString:tLastPathComponent]; + + if (tRange.location!=0) + { + if ([[NSFileManager defaultManager] fileExistsAtPath:tAbsolutePath]==YES) + { + NSURLComponents * tURLComponents=[NSURLComponents new]; + tURLComponents.scheme=[NSString stringWithFormat:@"sourcecode-%lu",inStackFrame.symbolicationData.lineNumber]; + tURLComponents.path=tAbsolutePath; + + NSURL * tURL=tURLComponents.URL; + + if (tURL!=nil) + { + [tProcessedLine addAttributes:@{ + NSLinkAttributeName:tURL, + NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle), + NSUnderlineColorAttributeName:self.underlineColor + } + range:tRange]; + + + } + } + } + } + } +#endif + } + + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameMachineInstructionAddressComponent)==0) + { + [tProcessedLine deleteCharactersInRange:tMemoryAddressRange]; + } + else + { + [tProcessedLine addAttributes:self.memoryAddressAttributes range:tMemoryAddressRange]; + } + + if ((self.displaySettings.visibleStackFrameComponents & CUIStackFrameBinaryNameComponent)==0) + { + [tProcessedLine deleteCharactersInRange:tBinaryImageIdentifierRange]; + } + else + { + if (self.hyperlinksStyle!=CUIHyperlinksNone && ((self.displaySettings.visibleSections & CUIDocumentBinaryImagesSection)==CUIDocumentBinaryImagesSection)) + { + NSString * tCleanedUpIdentifier=[tBinaryImageIdentifier stringByTrimmingCharactersInSet:self.whitespaceCharacterSet]; + + CUIBinaryImage * tBinaryImage=[tBinaryImages binaryImageWithIdentifier:tBinaryImageIdentifier]; + + if (tBinaryImage==nil) + { + tBinaryImage=[tBinaryImages binaryImageWithIdentifier:tBinaryImageIdentifier]; + } + + NSString * tBinaryImageUUID=tBinaryImage.UUID; + + if (tBinaryImageUUID!=nil) + { + NSURL * tURL=nil; + + switch(self.hyperlinksStyle) + { + case CUIHyperlinksInternal: + + tURL=[NSURL URLWithString:[NSString stringWithFormat:@"bin://%@",tBinaryImageUUID]]; + + break; + + case CUIHyperlinksHTML: + + tURL=[NSURL URLWithString:[NSString stringWithFormat:@"sharp://%@",tBinaryImageUUID]]; + + break; + + default: + + break; + } + + if (tURL!=nil) + [tProcessedLine addAttributes:@{NSLinkAttributeName:tURL} range:NSMakeRange(tBinaryImageIdentifierRange.location,tCleanedUpIdentifier.length)]; + + } + } + } + + return tProcessedLine; +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIRightViewController.m b/app_unexpectedly/app_unexpectedly/CUIRightViewController.m index 8d98880..946cbc9 100644 --- a/app_unexpectedly/app_unexpectedly/CUIRightViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIRightViewController.m @@ -60,7 +60,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -73,7 +73,7 @@ - (void)viewDidLoad // Register for Notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(crashLogsSelectionDidChange:) name:CUICrashLogsSelectionDidChangeNotification object:nil]; } #pragma mark - @@ -99,7 +99,7 @@ - (void)setSelection:(CUICrashLogsSelection *)inSelection { CUICrashLog * tCrashLog=_selection.crashLogs.firstObject; - if ([tCrashLog isMemberOfClass:[CUIRawCrashLog class]]==YES) + if ([tCrashLog isMemberOfClass:CUIRawCrashLog.class]==YES) { _unavailableViewController.view.frame=self.view.bounds; @@ -126,7 +126,7 @@ - (void)crashLogsSelectionDidChange:(NSNotification *)inNotification { CUICrashLogsSelection * tSelection=inNotification.object; - if ([tSelection isKindOfClass:[CUICrashLogsSelection class]]==NO) + if ([tSelection isKindOfClass:CUICrashLogsSelection.class]==NO) return; self.selection=tSelection; diff --git a/app_unexpectedly/app_unexpectedly/CUISidebarViewController.m b/app_unexpectedly/app_unexpectedly/CUISidebarViewController.m index 9b5be37..3af3adc 100644 --- a/app_unexpectedly/app_unexpectedly/CUISidebarViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUISidebarViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -24,7 +24,7 @@ NSString * const CUIDefaultsSidebarTopCollapsedKey=@"sidebar.top.collapsed"; -@interface CUISidebarViewController () +@interface CUISidebarViewController () { IBOutlet NSSplitView * _splitView; @@ -147,9 +147,7 @@ - (void)viewWillDisappear { // Save SplitView divider position - NSArray * tSubviews=_splitView.subviews; - - NSView * tViewTop=tSubviews[0]; + NSView * tViewTop=_splitView.subviews.firstObject; NSUserDefaults * tUserDefaults=[NSUserDefaults standardUserDefaults]; diff --git a/app_unexpectedly/app_unexpectedly/CUISourceFileTableCellView.m b/app_unexpectedly/app_unexpectedly/CUISourceFileTableCellView.m index 70b26b8..6eefb41 100644 --- a/app_unexpectedly/app_unexpectedly/CUISourceFileTableCellView.m +++ b/app_unexpectedly/app_unexpectedly/CUISourceFileTableCellView.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,4 +15,34 @@ @implementation CUISourceFileTableCellView +- (void)awakeFromNib +{ + [super awakeFromNib]; + + if (self.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft) + { + // Mirror image. + NSImage * tOriginalImage=self.openButton.image; + NSRect tBounds=self.openButton.bounds; + + NSImage * newTemplate=[NSImage imageWithSize:tBounds.size + flipped:NO drawingHandler:^BOOL(NSRect dstRect) { + + NSAffineTransform * tTransform = [NSAffineTransform transform]; + + [tTransform translateXBy:NSWidth(tBounds) yBy:0]; + [tTransform scaleXBy:-1.0 yBy:1.0]; + [tTransform concat]; + + [tOriginalImage drawInRect:dstRect fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; + + return YES; + }]; + + newTemplate.template=YES; + + self.openButton.image=newTemplate; + } +} + @end diff --git a/app_unexpectedly/app_unexpectedly/CUIStackFrame+UI.m b/app_unexpectedly/app_unexpectedly/CUIStackFrame+UI.m index 2da44b3..b8dbf84 100644 --- a/app_unexpectedly/app_unexpectedly/CUIStackFrame+UI.m +++ b/app_unexpectedly/app_unexpectedly/CUIStackFrame+UI.m @@ -13,13 +13,13 @@ #import "CUIStackFrame+UI.h" -#import "CUIBinaryImage+UI.h" +#import "CUIBinaryImageUtility.h" @implementation CUIStackFrame (UI) - (NSImage *)binaryImageIcon { - return [CUIBinaryImage iconForIdentifier:self.binaryImageIdentifier]; + return [CUIBinaryImageUtility iconForIdentifier:self.binaryImageIdentifier]; } - (NSString *)pasteboardRepresentationWithComponents:(CUIStackFrameComponents)inComponents diff --git a/app_unexpectedly/app_unexpectedly/CUIStackFrame.h b/app_unexpectedly/app_unexpectedly/CUIStackFrame.h index 5e169d6..bea2346 100644 --- a/app_unexpectedly/app_unexpectedly/CUIStackFrame.h +++ b/app_unexpectedly/app_unexpectedly/CUIStackFrame.h @@ -15,13 +15,17 @@ #import "CUISymbolicationData.h" +#import "IPSThreadFrame.h" + +#import "IPSImage.h" + extern NSString * const CUIStackFrameSymbolicationDidSucceedNotification; @interface CUIStackFrame : NSObject @property (readonly) NSUInteger index; - @property (readonly,copy) NSString * binaryImageIdentifier; + @property (nullable,readonly,copy) NSString * binaryImageIdentifier; @property (readonly) NSUInteger machineInstructionAddress; @@ -38,6 +42,8 @@ extern NSString * const CUIStackFrameSymbolicationDidSucceedNotification; - (instancetype)initWithString:(NSString *)inString error:(NSError **)outError; +- (instancetype)initWithThreadFrame:(IPSThreadFrame *)inFrame atIndex:(NSUInteger)inIndex image:(IPSImage *)inImage error:(NSError **)outError; + - (CUIStackFrame *)stackFrameCloneWithBinaryImageIdentifier:(NSString *)inBinaryImageIdentifier; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIStackFrame.m b/app_unexpectedly/app_unexpectedly/CUIStackFrame.m index 86e407c..e55cf6f 100644 --- a/app_unexpectedly/app_unexpectedly/CUIStackFrame.m +++ b/app_unexpectedly/app_unexpectedly/CUIStackFrame.m @@ -141,6 +141,47 @@ - (instancetype)initWithString:(NSString *)inString error:(NSError **)outError return self; } +- (instancetype)initWithThreadFrame:(IPSThreadFrame *)inFrame atIndex:(NSUInteger)inIndex image:(IPSImage *)inImage error:(NSError **)outError +{ + if ([inFrame isKindOfClass:[IPSThreadFrame class]]==NO || + [inImage isKindOfClass:[IPSImage class]]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + _index=inIndex; + + _binaryImageIdentifier=[(inImage.bundleIdentifier!=nil) ? inImage.bundleIdentifier : inImage.name copy]; + + _machineInstructionAddress=inImage.loadAddress+inFrame.imageOffset; + + if (inFrame.symbol!=nil) + { + _symbol=[inFrame.symbol copy]; + _byteOffset=inFrame.symbolLocation; + } + else + { + _symbol=[NSString stringWithFormat:@"0x%lx",(unsigned long)inImage.loadAddress]; + + _byteOffset=_machineInstructionAddress-inImage.loadAddress; + } + + _sourceFile=[inFrame.sourceFile copy]; + + _lineNumber=inFrame.sourceLine; + } + + return self; +} + #pragma mark - - (CUIStackFrame *)stackFrameCloneWithBinaryImageIdentifier:(NSString *)inBinaryImageIdentifier diff --git a/app_unexpectedly/app_unexpectedly/CUISymbolicationDataFormatter.m b/app_unexpectedly/app_unexpectedly/CUISymbolicationDataFormatter.m index 79a310f..2f01a01 100644 --- a/app_unexpectedly/app_unexpectedly/CUISymbolicationDataFormatter.m +++ b/app_unexpectedly/app_unexpectedly/CUISymbolicationDataFormatter.m @@ -47,7 +47,7 @@ - (instancetype)init - (NSString *)stringForObjectValue:(CUISymbolicationData *)inSymbolicationData { - if ([inSymbolicationData isKindOfClass:[CUISymbolicationData class]]==NO) + if ([inSymbolicationData isKindOfClass:CUISymbolicationData.class]==NO) return nil; NSMutableString * tMutableString=[NSMutableString string]; diff --git a/app_unexpectedly/app_unexpectedly/CUISymbolsFilesLibraryViewController.m b/app_unexpectedly/app_unexpectedly/CUISymbolsFilesLibraryViewController.m index 9159a9f..a92fc75 100644 --- a/app_unexpectedly/app_unexpectedly/CUISymbolsFilesLibraryViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUISymbolsFilesLibraryViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,7 +21,7 @@ #import "NSArray+WBExtensions.h" #import "NSTableView+Selection.h" -@interface CUISymbolsFilesLibraryViewController () +@interface CUISymbolsFilesLibraryViewController () { IBOutlet NSTableView * _tableView; @@ -83,7 +83,7 @@ - (void)viewDidLoad _cachedBundleIcon=[[NSWorkspace sharedWorkspace] iconForFileType:@"com.apple.xcode.dsym"]; - [_tableView registerForDraggedTypes:@[NSFilenamesPboardType]]; + [_tableView registerForDraggedTypes:@[NSPasteboardTypeFileURL]]; NSSortDescriptor *buildETASortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES selector:@selector(compareNameAndVersion:)]; @@ -115,16 +115,18 @@ - (void)viewDidAppear // Register for notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dSYMBundlesManagerDidAddBundles:) name:CUIdSYMBundlesManagerDidAddBundlesNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(dSYMBundlesManagerDidAddBundles:) name:CUIdSYMBundlesManagerDidAddBundlesNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dSYMBundlesManagerDidRemoveBundles:) name:CUIdSYMBundlesManagerDidRemoveBundlesNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(dSYMBundlesManagerDidRemoveBundles:) name:CUIdSYMBundlesManagerDidRemoveBundlesNotification object:nil]; } - (void)viewWillDisappear { - [[NSNotificationCenter defaultCenter] removeObserver:self name:CUIdSYMBundlesManagerDidAddBundlesNotification object:nil]; + [super viewWillDisappear]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:CUIdSYMBundlesManagerDidRemoveBundlesNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:CUIdSYMBundlesManagerDidAddBundlesNotification object:nil]; + + [NSNotificationCenter.defaultCenter removeObserver:self name:CUIdSYMBundlesManagerDidRemoveBundlesNotification object:nil]; } #pragma mark - @@ -392,12 +394,14 @@ - (NSDragOperation)tableView:(NSTableView *)inTableView validateDrop:(id *tClasses = @[NSURL.class]; + NSArray *tURLArray = [tPasteBoard readObjectsForClasses:tClasses + options:@{NSPasteboardURLReadingFileURLsOnlyKey:@(YES)}]; - if (tArray==nil || [tArray isKindOfClass:NSArray.class]==NO) + if (tURLArray==nil) { // We were provided invalid data @@ -406,32 +410,29 @@ - (NSDragOperation)tableView:(NSTableView *)inTableView validateDrop:(id )inf NSPasteboard * tPasteBoard=[info draggingPasteboard]; - if ([tPasteBoard availableTypeFromArray:@[NSFilenamesPboardType]]==nil) + if ([tPasteBoard availableTypeFromArray:@[NSPasteboardTypeFileURL]]==nil) return NO; - NSArray * tArray=(NSArray *) [tPasteBoard propertyListForType:NSFilenamesPboardType]; + NSArray *tClasses = @[NSURL.class]; + NSArray *tURLArray = [tPasteBoard readObjectsForClasses:tClasses + options:@{NSPasteboardURLReadingFileURLsOnlyKey:@(YES)}]; - NSArray * tNewBundles=[tArray WB_arrayByMappingObjectsUsingBlock:^id(NSString * bPath, NSUInteger bIndex) { + NSArray * tNewBundles=[tURLArray WB_arrayByMappingObjectsUsingBlock:^id(NSURL * bURL, NSUInteger bIndex) { - return [[CUIdSYMBundle alloc] initWithPath:bPath]; + return [[CUIdSYMBundle alloc] initWithURL:bURL]; }]; if (tNewBundles==nil) diff --git a/app_unexpectedly/app_unexpectedly/CUITableViewNoSpace.h b/app_unexpectedly/app_unexpectedly/CUITableViewNoSpace.h new file mode 100644 index 0000000..218dc1d --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUITableViewNoSpace.h @@ -0,0 +1,22 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CUITableViewNoSpace : NSTableView + +@end + +NS_ASSUME_NONNULL_END diff --git a/app_unexpectedly/app_unexpectedly/CUITableViewNoSpace.m b/app_unexpectedly/app_unexpectedly/CUITableViewNoSpace.m new file mode 100644 index 0000000..8a65824 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUITableViewNoSpace.m @@ -0,0 +1,41 @@ +/* + Copyright (c) 2021, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "CUITableViewNoSpace.h" + +@implementation CUITableViewNoSpace + +- (void)keyDown:(NSEvent *)inEvent +{ + NSString * tTypedText=inEvent.characters; + + NSUInteger tLength=tTypedText.length; + + for(NSUInteger tIndex=0;tIndex + +- (NSArray *)allThemes; + +- (CUITheme *)currentTheme; + +@end + @protocol CUIThemeDelegate - (void)theme:(CUITheme *)inTheme didRenameTo:(NSString *)inNewName; diff --git a/app_unexpectedly/app_unexpectedly/CUIThemeItemAttributes.m b/app_unexpectedly/app_unexpectedly/CUIThemeItemAttributes.m index 1222035..625eb92 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThemeItemAttributes.m +++ b/app_unexpectedly/app_unexpectedly/CUIThemeItemAttributes.m @@ -27,7 +27,7 @@ @implementation CUIThemeItemAttributes - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation { - if ([inRepresentation isKindOfClass:[NSDictionary class]]==NO) + if ([inRepresentation isKindOfClass:NSDictionary.class]==NO) return nil; self=[super init]; @@ -36,7 +36,7 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation { NSString * tString=inRepresentation[CUIThemeAttributeColorKey]; - if ([tString isKindOfClass:[NSString class]]==NO) + if ([tString isKindOfClass:NSString.class]==NO) return nil; _color=[NSColor colorFromString:tString]; @@ -45,7 +45,7 @@ - (instancetype)initWithRepresentation:(NSDictionary *)inRepresentation if (tString!=nil) { - if ([tString isKindOfClass:[NSString class]]==NO) + if ([tString isKindOfClass:NSString.class]==NO) return nil; @@ -80,7 +80,7 @@ - (void)setFont:(NSFont *)inFont { _font=inFont; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemeItemAttributesDidChangeNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemeItemAttributesDidChangeNotification object:self]; } } @@ -90,7 +90,7 @@ - (void)setColor:(NSColor *)inColor { _color=inColor; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemeItemAttributesDidChangeNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemeItemAttributesDidChangeNotification object:self]; } } diff --git a/app_unexpectedly/app_unexpectedly/CUIThemesManager.h b/app_unexpectedly/app_unexpectedly/CUIThemesManager.h index f9c06e6..75016eb 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThemesManager.h +++ b/app_unexpectedly/app_unexpectedly/CUIThemesManager.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,12 +15,10 @@ #import "CUITheme.h" -@interface CUIThemesManager : NSObject +@interface CUIThemesManager : NSObject + (CUIThemesManager *)sharedManager; -@property (nonatomic,readonly) NSArray * allThemes; - @property (nonatomic) CUITheme * currentTheme; diff --git a/app_unexpectedly/app_unexpectedly/CUIThemesManager.m b/app_unexpectedly/app_unexpectedly/CUIThemesManager.m index 8ef5665..cde6f01 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThemesManager.m +++ b/app_unexpectedly/app_unexpectedly/CUIThemesManager.m @@ -49,7 +49,7 @@ @implementation CUIThemesManager + (void)initialize { - NSArray * tThemesArray=[NSArray arrayWithContentsOfURL:[[NSBundle bundleForClass:[CUIThemesManager class]] URLForResource:@"default_themes" withExtension:@"plist"]]; + NSArray * tThemesArray=[NSArray arrayWithContentsOfURL:[[NSBundle bundleForClass:CUIThemesManager.class] URLForResource:@"default_themes" withExtension:@"plist"]]; [[NSUserDefaults standardUserDefaults] registerDefaults:@{ CUIThemesListKey:tThemesArray, @@ -115,9 +115,9 @@ - (instancetype)init _currentTheme=_themes.firstObject; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemAttributesDidChange:) name:CUIThemeItemAttributesDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(itemAttributesDidChange:) name:CUIThemeItemAttributesDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; } return self; @@ -125,7 +125,7 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -147,7 +147,7 @@ - (void)setCurrentTheme:(CUITheme *)inTheme { _currentTheme=inTheme; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; [_defaults setObject:_currentTheme.UUID forKey:CUIThemesCurrentThemeUUIDKey]; } @@ -170,7 +170,7 @@ - (BOOL)renameTheme:(CUITheme *)inTheme withName:(NSString *)inNewName inTheme.name=inNewName; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; return YES; } @@ -187,7 +187,7 @@ - (void)addTheme:(CUITheme *)inTheme [_themes addObject:inTheme]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; } - (CUITheme *)duplicateTheme:(CUITheme *)inTheme @@ -211,7 +211,7 @@ - (CUITheme *)duplicateTheme:(CUITheme *)inTheme [_themes addObject:nTheme]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; return nTheme; } @@ -233,21 +233,21 @@ - (void)removeTheme:(CUITheme *)inTheme self.currentTheme=_themes[tIndex]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; } [_cachedThemeUUIDsRegistry removeObjectForKey:inTheme.UUID]; [_themes removeObject:inTheme]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; } - (void)reset { - [[NSNotificationCenter defaultCenter] removeObserver:self name:CUIThemeItemAttributesDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:CUIThemeItemAttributesDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self name:CUIThemesManagerThemesListDidChangeNotification object:nil]; [_defaults removeObjectForKey:CUIThemesCurrentThemeUUIDKey]; @@ -283,13 +283,13 @@ - (void)reset _currentTheme=_themes.firstObject; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerThemesListDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIThemesManagerCurrentThemeDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemAttributesDidChange:) name:CUIThemeItemAttributesDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(itemAttributesDidChange:) name:CUIThemeItemAttributesDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(themesListDidChange:) name:CUIThemesManagerThemesListDidChangeNotification object:nil]; // Save defaults diff --git a/app_unexpectedly/app_unexpectedly/CUIThemesTableView.m b/app_unexpectedly/app_unexpectedly/CUIThemesTableView.m index ec4c65c..48938d1 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThemesTableView.m +++ b/app_unexpectedly/app_unexpectedly/CUIThemesTableView.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,7 +17,7 @@ @implementation CUIThemesTableView - (BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event { - if ([responder isKindOfClass:[NSTextField class]]) + if ([responder isKindOfClass:NSTextField.class]) { if (event.type==NSEventTypeRightMouseDown) { diff --git a/app_unexpectedly/app_unexpectedly/CUIThread.h b/app_unexpectedly/app_unexpectedly/CUIThread.h index 38821ba..bf5396d 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThread.h +++ b/app_unexpectedly/app_unexpectedly/CUIThread.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,6 +15,9 @@ #import "CUICallStackBacktrace.h" +#import "IPSThread.h" +#import "IPSImage.h" + @interface CUIThread : NSObject @property (readonly,getter=isApplicationSpecificBacktrace) BOOL applicationSpecificBackTrace; @@ -30,4 +33,10 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError; +- (instancetype)initApplicationSpecificBacktraceWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError; + +- (instancetype)initApplicationSpecificBacktraceWithThreadFrames:(NSArray *)inFrames binaryImages:(NSArray *)inImages error:(NSError **)outError; + +- (instancetype)initWithIPSThread:(IPSThread *)inThread atIndex:(NSUInteger)inIndex binaryImages:(NSArray *)inImages error:(NSError **)outError; + @end diff --git a/app_unexpectedly/app_unexpectedly/CUIThread.m b/app_unexpectedly/app_unexpectedly/CUIThread.m index e398d3e..17e3a75 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThread.m +++ b/app_unexpectedly/app_unexpectedly/CUIThread.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,16 +15,12 @@ @interface CUIThread () - @property BOOL applicationSpecificBackTrace; - @property BOOL crashed; - @property NSUInteger number; @property (copy) NSString * name; - @property CUICallStackBacktrace * callStackBacktrace; @end @@ -33,7 +29,7 @@ @implementation CUIThread - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError { - if ([inLines isKindOfClass:[NSArray class]]==NO) + if ([inLines isKindOfClass:NSArray.class]==NO) { if (outError!=NULL) *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; @@ -41,6 +37,14 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError return nil; } + if (inLines.count==0) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + self=[super init]; if (self!=nil) @@ -62,7 +66,18 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError { // Uh oh - // A COMPLETER + return nil; + } + + if (tComponents.count==1) + { + NSRange tRange=[tHeaderLine rangeOfString:@"Dispatch queue:"]; + + if (tRange.location!=NSNotFound) + { + tComponents=@[[tHeaderLine substringToIndex:tRange.location], + [tHeaderLine substringFromIndex:tRange.location]]; + } } tLeftPart=tComponents.firstObject; @@ -106,11 +121,85 @@ - (instancetype)initWithTextualRepresentation:(NSArray *)inLines error:(NSError return self; } +- (instancetype)initApplicationSpecificBacktraceWithTextualRepresentation:(NSArray *)inLines error:(NSError **)outError +{ + self=[self initWithTextualRepresentation:inLines error:outError]; + + if (self!=nil) + { + _crashed=NO; + + _applicationSpecificBackTrace=YES; + + _name=@"Application Specific Backtrace"; + } + + return self; +} + +- (instancetype)initApplicationSpecificBacktraceWithThreadFrames:(NSArray *)inFrames binaryImages:(NSArray *)inImages error:(NSError **)outError +{ + self=[super init]; + + if (self!=nil) + { + _crashed=NO; + + _applicationSpecificBackTrace=YES; + + _name=@"Application Specific Backtrace"; + + _callStackBacktrace=[[CUICallStackBacktrace alloc] initWithFrames:inFrames binaryImages:inImages error:outError]; + + if (_callStackBacktrace==nil) + { + return nil; + } + } + + return self; +} + +- (instancetype)initWithIPSThread:(IPSThread *)inThread atIndex:(NSUInteger)inIndex binaryImages:(NSArray *)inImages error:(NSError **)outError +{ + if ([inThread isKindOfClass:IPSThread.class]==NO) + { + if (outError!=NULL) + *outError=[NSError errorWithDomain:NSPOSIXErrorDomain code:EINVAL userInfo:@{}]; + + return nil; + } + + self=[super init]; + + if (self!=nil) + { + _crashed=inThread.triggered; + + _number=inIndex; + + if (inThread.queue!=nil) + _name=[NSString stringWithFormat:@"Dispatch queue: %@",inThread.queue]; + + _callStackBacktrace=[[CUICallStackBacktrace alloc] initWithFrames:inThread.frames binaryImages:inImages error:NULL]; + + if (_callStackBacktrace==nil) + { + // A COMPLETER + } + } + + return self; +} + #pragma mark - - (NSString *)description { - return [NSString stringWithFormat:@"Thread %ld %@ :: Dispatch queue: %@\n%@",self.number,(self.isCrashed==YES) ? @"(Crashed)": @"",self.name,self.callStackBacktrace]; + if (_applicationSpecificBackTrace==YES) + return [NSString stringWithFormat:@"%@ 1\n%@",self.name,self.callStackBacktrace]; + else + return [NSString stringWithFormat:@"Thread %ld %@ :: Dispatch queue: %@\n%@",self.number,(self.isCrashed==YES) ? @"(Crashed)": @"",self.name,self.callStackBacktrace]; } @end diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.h b/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.h index b3805d8..f1b5d95 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.h +++ b/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,6 +15,6 @@ @interface CUIThreadImageCell : NSImageCell - @property (getter=isCrashed) BOOL crashed; + @property (nonatomic,getter=isCrashed) BOOL crashed; @end diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.m b/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.m index 168b78d..c15724d 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.m +++ b/app_unexpectedly/app_unexpectedly/CUIThreadImageCell.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2022, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -50,6 +50,18 @@ - (instancetype)initWithCoder:(NSCoder *)inCoder return self; } +#pragma mark - + +- (void)setCrashed:(BOOL)inCrashed +{ + if (_crashed==inCrashed) + return; + + _crashed=inCrashed; + + [self.controlView setNeedsDisplay:YES]; +} + - (NSImage *)image { if (self.isCrashed==NO) diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadImageView.h b/app_unexpectedly/app_unexpectedly/CUIThreadImageView.h new file mode 100644 index 0000000..26b64b9 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIThreadImageView.h @@ -0,0 +1,18 @@ +/* + Copyright (c) 2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +@interface CUIThreadImageView : NSImageView + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadImageView.m b/app_unexpectedly/app_unexpectedly/CUIThreadImageView.m new file mode 100644 index 0000000..f52f5d9 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CUIThreadImageView.m @@ -0,0 +1,24 @@ +/* + Copyright (c) 2025, Stephane Sudre + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the WhiteBox nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#import "CUIThreadImageView.h" + +@implementation CUIThreadImageView + +- (void)viewDidChangeEffectiveAppearance +{ + [super viewDidChangeEffectiveAppearance]; + + self.cell.image=self.cell.image; // To refresh the icon when switching between Light and Dark Aqua. +} + +@end diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.m b/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.m index c187257..842e6f8 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.m @@ -64,11 +64,15 @@ - (void)delayedReloadSymbols; @implementation CUIThreadsColumnViewController -- (NSString *)nibName +- (instancetype)initWithUserInterfaceLayoutDirection:(NSUserInterfaceLayoutDirection)inUserInterfaceLayoutDirection { - return @"CUIThreadsColumnViewController"; + NSString *nibName=(inUserInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) ? @"CUIThreadsColumnViewController" : @"CUIThreadsColumnViewController_RTL"; + + return [super initWithNibName:nibName bundle:nil]; } +#pragma mark - + - (void)viewDidLoad { [super viewDidLoad]; @@ -287,11 +291,24 @@ - (IBAction)openSourceFile:(id)sender CUIStackFrame * tCall=(CUIStackFrame *)_selectedThread.callStackBacktrace.stackFrames[tRow]; - [[NSWorkspace sharedWorkspace] openURLs:@[[NSURL fileURLWithPath:tCall.symbolicationData.sourceFilePath]] - withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL - options:NSWorkspaceLaunchDefault - configuration:@{} - error:NULL]; +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101600 + if (@available(*, macOS 11.0)) + { + [[NSWorkspace sharedWorkspace] openURLs:@[[NSURL fileURLWithPath:tCall.symbolicationData.sourceFilePath]] + withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL + configuration:[NSWorkspaceOpenConfiguration configuration] + completionHandler:^(NSRunningApplication * _Nullable app, NSError * _Nullable error) { + }]; + } + else +#endif + { + [[NSWorkspace sharedWorkspace] openURLs:@[[NSURL fileURLWithPath:tCall.symbolicationData.sourceFilePath]] + withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL + options:NSWorkspaceLaunchDefault + configuration:@{} + error:NULL]; + } } #pragma mark - NSTableViewDataSource @@ -446,8 +463,8 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu { tCall.symbolicationData=bSymbolicationData; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification - object:self.crashLog]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification + object:self.crashLog]; break; } @@ -472,7 +489,7 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu } - + BOOL isRightToLeft=(inTableView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft); NSString * tBinaryImageIdentifier=tCall.binaryImageIdentifier; BOOL tIsUserCode=NO; @@ -483,17 +500,10 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu if (tBinaryImage!=nil) { - NSString * tPath=tBinaryImage.path; + tIsUserCode = tBinaryImage.isUserCode; - if (tBinaryImage.isMainImage==YES) - { + if (tIsUserCode==NO && [tBinaryImage.path isEqualToString:self.crashLog.header.executablePath]==YES) tIsUserCode=YES; - } - else - { - if ([tPath isEqualToString:self.crashLog.header.executablePath]==YES) - tIsUserCode=YES; - } } if (tIsUserCode==NO) @@ -525,6 +535,8 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu } else { + + if (_optimizedBinaryImageTextFieldWidth<0) { NSArray * tBinaryImageIdentifiers=[self.crashLog.backtraces allBinaryImagesIdentifiers]; @@ -551,9 +563,17 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu NSRect tFrame=tCallTableCellView.binaryImageLabel.frame; - tFrame.origin.x=NSMaxX(tLeftFrame)+8; tFrame.size.width=_optimizedBinaryImageTextFieldWidth; + if (isRightToLeft==NO) + { + tFrame.origin.x=NSMaxX(tLeftFrame)+8; + } + else + { + tFrame.origin.x=NSMinX(tLeftFrame)-8-NSWidth(tFrame); + } + tCallTableCellView.binaryImageLabel.frame=tFrame; tLeftFrame=tFrame; @@ -582,7 +602,14 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu NSRect tFrame=tCallTableCellView.addressLabel.frame; - tFrame.origin.x=NSMaxX(tLeftFrame)+8; + if (isRightToLeft==NO) + { + tFrame.origin.x=NSMaxX(tLeftFrame)+8; + } + else + { + tFrame.origin.x=NSMinX(tLeftFrame)-8-NSWidth(tFrame); + } tCallTableCellView.addressLabel.frame=tFrame; @@ -606,11 +633,22 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu NSRect tFrame=tCallTableCellView.textField.frame; - CGFloat tMaxX=NSMaxX(tFrame); - - tFrame.origin.x=NSMaxX(tLeftFrame)+8; - - tFrame.size.width=tMaxX-tFrame.origin.x; + if (isRightToLeft==NO) + { + CGFloat tMaxX=NSMaxX(tFrame); + + tFrame.origin.x=NSMaxX(tLeftFrame)+8; + + tFrame.size.width=tMaxX-tFrame.origin.x; + } + else + { + CGFloat tMinX=NSMinX(tFrame); + + tFrame.origin.x=tMinX; + + tFrame.size.width=(NSMinX(tLeftFrame)-8-tMinX); + } tCallTableCellView.textField.frame=tFrame; @@ -676,8 +714,8 @@ - (NSView *)tableView:(NSTableView *)inTableView viewForTableColumn:(NSTableColu { tCall.symbolicationData=bSymbolicationData; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification - object:self.crashLog]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification + object:self.crashLog]; break; } diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.xib b/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.xib index 0ee3a18..55e8e2f 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.xib +++ b/app_unexpectedly/app_unexpectedly/CUIThreadsColumnViewController.xib @@ -1,8 +1,8 @@ - + - + @@ -19,7 +19,7 @@ - + @@ -28,14 +28,13 @@ - + - + - @@ -50,7 +49,7 @@ - + @@ -59,7 +58,7 @@ - + @@ -74,7 +73,7 @@ - + @@ -83,12 +82,12 @@ - + - + @@ -123,7 +122,7 @@ - + @@ -132,14 +131,13 @@ - + - @@ -151,11 +149,11 @@ - + - - + + @@ -163,7 +161,7 @@ - + @@ -172,7 +170,7 @@ - + @@ -181,12 +179,12 @@ - + - + @@ -208,7 +206,6 @@ - + - @@ -286,10 +281,10 @@ - + - + @@ -298,7 +293,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.m b/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.m index 78c6823..4c6c169 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.m @@ -88,11 +88,15 @@ - (void)delayedReloadSymbols; @implementation CUIThreadsListViewController -- (NSString *)nibName +- (instancetype)initWithUserInterfaceLayoutDirection:(NSUserInterfaceLayoutDirection)inUserInterfaceLayoutDirection { - return @"CUIThreadsListViewController"; + NSString *nibName=(inUserInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionLeftToRight) ? @"CUIThreadsListViewController" : @"CUIThreadsListViewController_RTL"; + + return [super initWithNibName:nibName bundle:nil]; } +#pragma mark - + - (void)viewDidLoad { [super viewDidLoad]; @@ -105,7 +109,7 @@ - (void)viewDidLoad _outlineView.menu=tMenu; - //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:_outlineView]; + //[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:_outlineView]; } - (void)viewWillDisappear @@ -316,7 +320,20 @@ - (void)setVisibleStackFrameComponents:(CUIStackFrameComponents)inVisibleStackFr - (NSUInteger)numberOfSelectedStackFrames { - return [_outlineView WB_selectedOrClickedRowIndexes].count; + NSIndexSet * tSelectedRows=[_outlineView WB_selectedOrClickedRowIndexes]; + + __block BOOL tContainsThreadRows=NO; + + [tSelectedRows enumerateIndexesUsingBlock:^(NSUInteger bIndex, BOOL * bOutStop) { + + if ([[self->_outlineView itemAtRow:bIndex] class]==[CUIThread class]) + { + tContainsThreadRows=YES; + *bOutStop=YES; + } + }]; + + return (tContainsThreadRows==NO) ? [_outlineView WB_selectedOrClickedRowIndexes].count : 0; } - (NSArray *)selectedStackFrames @@ -332,7 +349,7 @@ - (NSUInteger)numberOfSelectedStackFrames CUIStackFrame * tStackFrame=[self->_outlineView itemAtRow:bRow]; - if ([tStackFrame isKindOfClass:[CUIStackFrame class]]==NO) + if ([tStackFrame isKindOfClass:CUIStackFrame.class]==NO) return; [tMutableArray addObject:tStackFrame]; @@ -352,11 +369,25 @@ - (IBAction)openSourceFile:(id)sender CUIStackFrame * tCall=(CUIStackFrame *)[_outlineView itemAtRow:tRow]; - [[NSWorkspace sharedWorkspace] openURLs:@[[NSURL fileURLWithPath:tCall.symbolicationData.sourceFilePath]] - withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL - options:NSWorkspaceLaunchDefault - configuration:@{} - error:NULL]; +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101600 + if (@available(*, macOS 11.0)) + { + [[NSWorkspace sharedWorkspace] openURLs:@[[NSURL fileURLWithPath:tCall.symbolicationData.sourceFilePath]] + withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL + configuration:[NSWorkspaceOpenConfiguration configuration] + completionHandler:^(NSRunningApplication * _Nullable app, NSError * _Nullable error) { + + }]; + } + else +#endif + { + [[NSWorkspace sharedWorkspace] openURLs:@[[NSURL fileURLWithPath:tCall.symbolicationData.sourceFilePath]] + withApplicationAtURL:[CUIApplicationPreferences sharedPreferences].preferedSourceCodeEditorURL + options:NSWorkspaceLaunchDefault + configuration:@{} + error:NULL]; + } } #pragma mark - @@ -529,10 +560,12 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab { // Default values + NSTextField * tLabel=tTableCellView.textField; + if (tCall.sourceFile==nil) - tTableCellView.textField.stringValue=@"-"; + tLabel.stringValue=@"-"; else - tTableCellView.textField.stringValue=[NSString stringWithFormat:@"%@ - line %lu",tCall.sourceFile,tCall.lineNumber]; + tLabel.stringValue=[NSString stringWithFormat:@"%@ - line %lu",tCall.sourceFile,tCall.lineNumber]; tTableCellView.openButton.hidden=YES; @@ -560,15 +593,21 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab { case CUISymbolicationDataLookUpResultError: case CUISymbolicationDataLookUpResultNotFound: + { + NSRect tFrame=tLabel.frame; - break; + tFrame.size.width=NSMaxX(tTableCellView.frame)-NSMinX(tFrame)-4; + tLabel.frame=tFrame; + + break; + } case CUISymbolicationDataLookUpResultFound: tCall.symbolicationData=bSymbolicationData; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification - object:self.crashLog]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification + object:self.crashLog]; break; @@ -583,6 +622,14 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab } }]; } + else + { + NSRect tFrame=tLabel.frame; + + tFrame.size.width=NSMaxX(tTableCellView.frame)-NSMinX(tFrame)-4; + + tLabel.frame=tFrame; + } } return tTableCellView; @@ -626,6 +673,7 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab if ([inItem isKindOfClass:[CUIStackFrame class]]==YES) { + BOOL isRightToLeft=(inOutlineView.userInterfaceLayoutDirection==NSUserInterfaceLayoutDirectionRightToLeft); CUIStackFrame * tCall=(CUIStackFrame *)inItem; NSString * tBinaryImageIdentifier=tCall.binaryImageIdentifier; @@ -638,17 +686,10 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab if (tBinaryImage!=nil) { - NSString * tPath=tBinaryImage.path; + tIsUserCode = tBinaryImage.isUserCode; - if (tBinaryImage.isMainImage==YES) - { + if (tIsUserCode==NO && [tBinaryImage.path isEqualToString:self.crashLog.header.executablePath]==YES) tIsUserCode=YES; - } - else - { - if ([tPath isEqualToString:self.crashLog.header.executablePath]==YES) - tIsUserCode=YES; - } } if (tIsUserCode==NO) @@ -702,13 +743,24 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab } + + tCallTableCellView.binaryImageLabel.hidden=NO; NSRect tFrame=tCallTableCellView.binaryImageLabel.frame; - tFrame.origin.x=NSMaxX(tLeftFrame)+8; tFrame.size.width=_optimizedBinaryImageTextFieldWidth; + if (isRightToLeft==NO) + { + tFrame.origin.x=NSMaxX(tLeftFrame)+8; + + } + else + { + tFrame.origin.x=NSMinX(tLeftFrame)-8-NSWidth(tFrame); + } + tCallTableCellView.binaryImageLabel.frame=tFrame; tLeftFrame=tFrame; @@ -737,7 +789,14 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab NSRect tFrame=tCallTableCellView.addressLabel.frame; - tFrame.origin.x=NSMaxX(tLeftFrame)+8; + if (isRightToLeft==NO) + { + tFrame.origin.x=NSMaxX(tLeftFrame)+8; + } + else + { + tFrame.origin.x=NSMinX(tLeftFrame)-8-NSWidth(tFrame); + } tCallTableCellView.addressLabel.frame=tFrame; @@ -761,11 +820,22 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab NSRect tFrame=tCallTableCellView.textField.frame; - CGFloat tMaxX=NSMaxX(tFrame); + if (isRightToLeft==NO) + { + CGFloat tMaxX=NSMaxX(tFrame); - tFrame.origin.x=NSMaxX(tLeftFrame)+8; + tFrame.origin.x=NSMaxX(tLeftFrame)+8; - tFrame.size.width=tMaxX-tFrame.origin.x; + tFrame.size.width=tMaxX-tFrame.origin.x; + } + else + { + CGFloat tMinX=NSMinX(tFrame); + + tFrame.origin.x=tMinX; + + tFrame.size.width=(NSMinX(tLeftFrame)-8-tMinX); + } tCallTableCellView.textField.frame=tFrame; @@ -831,7 +901,7 @@ - (NSView *)outlineView:(NSOutlineView *)inOutlineView viewForTableColumn:(NSTab { tCall.symbolicationData=bSymbolicationData; - [[NSNotificationCenter defaultCenter] postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification + [NSNotificationCenter.defaultCenter postNotificationName:CUIStackFrameSymbolicationDidSucceedNotification object:self.crashLog]; break; diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.xib b/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.xib index 0b9e88a..7808854 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.xib +++ b/app_unexpectedly/app_unexpectedly/CUIThreadsListViewController.xib @@ -1,8 +1,8 @@ - + - + @@ -18,23 +18,22 @@ - + - + - - + + - + - @@ -46,11 +45,11 @@ - + - - + + @@ -58,7 +57,7 @@ - + @@ -70,11 +69,11 @@ - + - - + + @@ -82,13 +81,13 @@ - + - - + + @@ -104,11 +103,11 @@ - + - - + + @@ -116,7 +115,7 @@ - + @@ -125,7 +124,7 @@ - + @@ -134,12 +133,12 @@ - + - + @@ -159,9 +158,8 @@ - + - @@ -173,10 +171,10 @@ - + - + @@ -185,7 +183,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.h b/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.h index b5700d7..105b7d5 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.h +++ b/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -45,7 +45,9 @@ @property (nonatomic) NSArray * selectedStackFrames; -- (NSMenu *)createFrameContextualMenu;; +- (instancetype)initWithUserInterfaceLayoutDirection:(NSUserInterfaceLayoutDirection)inUserInterfaceLayoutDirection; + +- (NSMenu *)createFrameContextualMenu; - (IBAction)copyMachineInstructionAddress:(id)sender; diff --git a/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.m b/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.m index 91e6e8f..be87c54 100644 --- a/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.m +++ b/app_unexpectedly/app_unexpectedly/CUIThreadsViewController.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2024, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,7 +21,7 @@ NSString * const CUIThreadsViewSelectedCallsDidChangeNotification=@"CUIThreadsViewSelectedCallsDidChangeNotification"; -@interface CUIThreadsViewController () +@interface CUIThreadsViewController () @property (readwrite) CUISymbolicationDataFormatter * symbolColumnFormatter; @@ -31,9 +31,14 @@ @interface CUIThreadsViewController () @implementation CUIThreadsViewController +- (instancetype)initWithUserInterfaceLayoutDirection:(NSUserInterfaceLayoutDirection)userInterfaceLayoutDirection +{ + return [super init]; +} + - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -69,7 +74,7 @@ - (void)viewDidAppear { [super viewDidAppear]; - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter addObserver:self selector:@selector(dSYMBundlesManagerDidAddBundles:) name:CUIdSYMBundlesManagerDidAddBundlesNotification object:nil]; @@ -82,7 +87,7 @@ - (void)viewWillDisappear { [super viewWillDisappear]; - NSNotificationCenter * tNotificationCenter=[NSNotificationCenter defaultCenter]; + NSNotificationCenter * tNotificationCenter=NSNotificationCenter.defaultCenter; [tNotificationCenter removeObserver:self name:CUIdSYMBundlesManagerDidAddBundlesNotification object:nil]; @@ -169,14 +174,29 @@ - (void)setUpSourceFileCellView:(CUISourceFileTableCellView *)inTableCellView wi else { CGFloat tWidth=[tLabel.attributedStringValue size].width; - - tFrame.size.width=tWidth+5; - - tLabel.frame=tFrame; - NSRect tButtonFrame=inTableCellView.openButton.frame; - tButtonFrame.origin.x=NSMaxX(tLabel.frame)+2; + switch(inTableCellView.userInterfaceLayoutDirection) + { + case NSUserInterfaceLayoutDirectionLeftToRight: + tFrame.size.width=tWidth+5; + + tLabel.frame=tFrame; + + tButtonFrame.origin.x=NSMaxX(tLabel.frame)+2; + + break; + + case NSUserInterfaceLayoutDirectionRightToLeft: + + tFrame.size.width=tWidth+5; + + tLabel.frame=tFrame; + + tButtonFrame.origin.x=NSMinX(tLabel.frame)-15; + + break; + } inTableCellView.openButton.frame=tButtonFrame; } @@ -250,8 +270,8 @@ - (IBAction)copy:(id)sender NSPasteboard * tPasteboard=[NSPasteboard generalPasteboard]; - [tPasteboard declareTypes:@[NSStringPboardType] owner:nil]; - [tPasteboard setString:tPasteboardString forType:NSStringPboardType]; + [tPasteboard declareTypes:@[WBPasteboardTypeString] owner:nil]; + [tPasteboard setString:tPasteboardString forType:WBPasteboardTypeString]; } - (IBAction)copyMachineInstructionAddress:(id)sender @@ -269,8 +289,8 @@ - (IBAction)copyMachineInstructionAddress:(id)sender NSPasteboard * tPasteboard=[NSPasteboard generalPasteboard]; - [tPasteboard declareTypes:@[NSStringPboardType] owner:nil]; - [tPasteboard setString:tPasteboardString forType:NSStringPboardType]; + [tPasteboard declareTypes:@[WBPasteboardTypeString] owner:nil]; + [tPasteboard setString:tPasteboardString forType:WBPasteboardTypeString]; } @@ -303,8 +323,8 @@ - (IBAction)copyBinaryImageOffset:(id)sender NSPasteboard * tPasteboard=[NSPasteboard generalPasteboard]; - [tPasteboard declareTypes:@[NSStringPboardType] owner:nil]; - [tPasteboard setString:tPasteboardString forType:NSStringPboardType]; + [tPasteboard declareTypes:@[WBPasteboardTypeString] owner:nil]; + [tPasteboard setString:tPasteboardString forType:WBPasteboardTypeString]; } - (IBAction)openWithHopperDisassembler:(NSMenuItem *)sender diff --git a/app_unexpectedly/app_unexpectedly/CUIdSYMBundlesManager.m b/app_unexpectedly/app_unexpectedly/CUIdSYMBundlesManager.m index 80c50be..49698f1 100644 --- a/app_unexpectedly/app_unexpectedly/CUIdSYMBundlesManager.m +++ b/app_unexpectedly/app_unexpectedly/CUIdSYMBundlesManager.m @@ -167,7 +167,7 @@ - (BOOL)_addBundles:(NSArray *)inBundles andNotify:(BOOL)inNotify // Post Notification? if (inNotify==YES) - [[NSNotificationCenter defaultCenter] postNotificationName:CUIdSYMBundlesManagerDidAddBundlesNotification object:tAllBinaryUUIDs]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIdSYMBundlesManagerDidAddBundlesNotification object:tAllBinaryUUIDs]; [self _synchronizeDefaults]; @@ -202,7 +202,7 @@ - (void)removeBundles:(NSArray *)inBundles // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIdSYMBundlesManagerDidRemoveBundlesNotification object:tAllBinaryUUIDs]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIdSYMBundlesManagerDidRemoveBundlesNotification object:tAllBinaryUUIDs]; [self _synchronizeDefaults]; } diff --git a/app_unexpectedly/app_unexpectedly/CUIdSYMDropView.m b/app_unexpectedly/app_unexpectedly/CUIdSYMDropView.m index 0cfaaf6..ee4abb4 100644 --- a/app_unexpectedly/app_unexpectedly/CUIdSYMDropView.m +++ b/app_unexpectedly/app_unexpectedly/CUIdSYMDropView.m @@ -28,7 +28,14 @@ - (void)drawRect:(NSRect)inRect tPath.lineWidth=3.0; - [[NSColor alternateSelectedControlColor] setStroke]; + if (@available(*, macOS 10.14)) + { + [[NSColor selectedContentBackgroundColor] setStroke]; + } + else + { + [[NSColor alternateSelectedControlColor] setStroke]; + } [tPath stroke]; } diff --git a/app_unexpectedly/app_unexpectedly/CUIdSYMHunter.m b/app_unexpectedly/app_unexpectedly/CUIdSYMHunter.m index 7ffcd6a..a2c3bd1 100644 --- a/app_unexpectedly/app_unexpectedly/CUIdSYMHunter.m +++ b/app_unexpectedly/app_unexpectedly/CUIdSYMHunter.m @@ -102,10 +102,10 @@ - (void)huntBundleWithUUIDs:(NSSet *)inBundleUUIDs NSMetadataQuery * tMetadataQuery=[NSMetadataQuery new]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(metadataQueryDidFinishGathering:) - name:NSMetadataQueryDidFinishGatheringNotification - object:tMetadataQuery]; + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(metadataQueryDidFinishGathering:) + name:NSMetadataQueryDidFinishGatheringNotification + object:tMetadataQuery]; // Look for dSYM with filtered UUIDs @@ -159,7 +159,7 @@ - (void)metadataQueryDidFinishGathering:(NSNotification *)inNotification [tMetadataQuery enumerateResultsUsingBlock:^(id bResult, NSUInteger idx, BOOL * _Nonnull stop) { - if ([bResult isKindOfClass:[NSMetadataItem class]]==YES) + if ([bResult isKindOfClass:NSMetadataItem.class]==YES) { NSMetadataItem * tMetaDataItem=(NSMetadataItem *)bResult; @@ -186,7 +186,7 @@ - (void)metadataQueryDidFinishGathering:(NSNotification *)inNotification // Post Notification - [[NSNotificationCenter defaultCenter] postNotificationName:CUIdSYMHunterHuntDidFinishNotification object:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:CUIdSYMHunterHuntDidFinishNotification object:nil]; }); } diff --git a/app_unexpectedly/app_unexpectedly/CodeSigningFlags.plist b/app_unexpectedly/app_unexpectedly/CodeSigningFlags.plist new file mode 100644 index 0000000..256d28c --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/CodeSigningFlags.plist @@ -0,0 +1,40 @@ + + + + + Host + 1 + Ad-hoc Signed + 2 + Get Task Allow + 4 + Installer + 8 + Forced Library Validation + 16 + Invalid Allowed + 32 + Force Hard + 256 + Force Kill + 512 + Force Expiration + 1024 + Restrict + 2048 + Enforcement + 4096 + Library Validation + 8192 + Runtime + 65536 + Linker Signed + 131072 + Platform Signed + 67108864 + Debugged + 268435456 + Signed + 536870912 + + diff --git a/app_unexpectedly/app_unexpectedly/DWARF/DWRFFileObject.m b/app_unexpectedly/app_unexpectedly/DWARF/DWRFFileObject.m index 2de8061..05bba34 100644 --- a/app_unexpectedly/app_unexpectedly/DWARF/DWRFFileObject.m +++ b/app_unexpectedly/app_unexpectedly/DWARF/DWRFFileObject.m @@ -237,9 +237,17 @@ - (void)lookUpSymbolicationDataForMachineInstructionAddress:(uint64_t)inAddress // A AMELIORER (path absolu à trouver) } + NSString * tFilePath=tLocation.fileName; + if (tFilePath.length>0 && [tFilePath characterAtIndex:0]!='/') + { + NSString * tCompilationDirectory=tCompilationUnit.compilationDirectory; + + if (tCompilationDirectory.length>0) + tFilePath=[tCompilationDirectory stringByAppendingPathComponent:tFilePath]; + } - tSymbolicationData.sourceFilePath=tLocation.fileName; + tSymbolicationData.sourceFilePath=tFilePath; tSymbolicationData.lineNumber=tLocation.lineNumber; tSymbolicationData.columnNumber=tLocation.columnNumber; diff --git a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_abbrev.m b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_abbrev.m index 850b135..19c182b 100644 --- a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_abbrev.m +++ b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_abbrev.m @@ -213,7 +213,7 @@ @implementation DWRFSection_debug_abbrev - (instancetype)initWithData:(NSData *)inData { - if (inData==nil || [inData isKindOfClass:[NSData class]]==NO) + if (inData==nil || [inData isKindOfClass:NSData.class]==NO) return nil; self=[super init]; diff --git a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_aranges.m b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_aranges.m index 6171418..05b4d47 100644 --- a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_aranges.m +++ b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_aranges.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -118,7 +118,7 @@ - (size_t)headerSize - (size_t)addressRangeDescriptorSize { - return _segmentSize+2*_addressSize;; + return _segmentSize+2*_addressSize; } - (size_t)paddingSize @@ -319,7 +319,7 @@ @implementation DWRFSection_debug_aranges - (instancetype)initWithData:(NSData *)inData { - if (inData==nil || [inData isKindOfClass:[NSData class]]==NO) + if (inData==nil || [inData isKindOfClass:NSData.class]==NO) return nil; self=[super init]; diff --git a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.h b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.h index 509e905..27b683f 100644 --- a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.h +++ b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.h @@ -31,6 +31,8 @@ @property (nonatomic,readonly) BOOL isConstant; + @property (nonatomic,readonly) BOOL isString; + @end @interface DWRFDebuggingInformationEntry : NSObject @@ -97,6 +99,8 @@ @property (nonatomic,readonly) DW_LANG language; + @property (nonatomic,readonly) NSString * compilationDirectory; + - (DWRFDebuggingInformationEntry *)entryAtAddress:(uint8_t *)inAddress; - (DWRFSubProgramEntry *)subProgramForMachineInstructionAddress:(uint64_t)inAddress; @@ -106,7 +110,7 @@ @interface DWRFSection_debug_info : NSObject -@property (readonly) DWRFFileObject * fileObject; + @property (readonly) DWRFFileObject * fileObject; - (instancetype)initWithData:(NSData *)inData fileObject:(DWRFFileObject *)inFileObject; diff --git a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.m b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.m index 0d1e808..46f473f 100644 --- a/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.m +++ b/app_unexpectedly/app_unexpectedly/DWARF/DWRFSection_debug_info.m @@ -1,5 +1,5 @@ /* - Copyright (c) 2020-2021, Stephane Sudre + Copyright (c) 2020-2025, Stephane Sudre All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -69,6 +69,29 @@ - (BOOL)isConstant return NO; } +- (BOOL)iString +{ + switch(self.form) + { + case DW_FORM_strp: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + + case DW_FORM_strx: + + return YES; + + + default: + + break; + } + + return NO; +} + - (NSString *)description { if (self.isAddress==YES) @@ -241,7 +264,7 @@ - (NSString *)nameForAttribute:(DW_AT)inAttribute @(0x3e00):@"DW_AT_LLVM_include_path", @(0x3fe1):@"DW_AT_APPLE_optimized", - @(0x3fe1):@"DW_AT_APPLE_flags", + @(0x3fe2):@"DW_AT_APPLE_flags", @(0x3fe5):@"DW_AT_APPLE_major_runtime_vers", @(0x3fe6):@"DW_AT_APPLE_runtime_class", }; @@ -356,7 +379,7 @@ - (uint64_t)machineInstructionAddress NSNumber * tNumber=[self.referencedEntry objectForAttribute:DW_AT_low_pc]; if (tNumber==nil) - tNumber=[self objectForAttribute:DW_AT_low_pc];; + tNumber=[self objectForAttribute:DW_AT_low_pc]; return [tNumber unsignedIntegerValue]; } @@ -1306,6 +1329,11 @@ -(DW_LANG)language return _compileUnitEntry.language; } +-(NSString *)compilationDirectory +{ + return _compileUnitEntry.compilationDirectory; +} + - (DWRFDebuggingInformationEntry *)entryAtAddress:(uint8_t *)inAddress { return [_compileUnitEntry entryAtAddress:inAddress]; diff --git a/app_unexpectedly/app_unexpectedly/DWARF/LEB128.h b/app_unexpectedly/app_unexpectedly/DWARF/LEB128.h index 082bdf2..99dd099 100644 --- a/app_unexpectedly/app_unexpectedly/DWARF/LEB128.h +++ b/app_unexpectedly/app_unexpectedly/DWARF/LEB128.h @@ -14,6 +14,7 @@ #ifndef LEB128_h #define LEB128_h +#include #include uint64_t DWRF_readULEB128(uint8_t * inBufferPtr,uint8_t ** outBufferPtr); diff --git a/app_unexpectedly/app_unexpectedly/Extemal/Line View Test/NoodleLineNumberView.m b/app_unexpectedly/app_unexpectedly/Extemal/Line View Test/NoodleLineNumberView.m index 9633a4b..ea8db61 100644 --- a/app_unexpectedly/app_unexpectedly/Extemal/Line View Test/NoodleLineNumberView.m +++ b/app_unexpectedly/app_unexpectedly/Extemal/Line View Test/NoodleLineNumberView.m @@ -76,7 +76,7 @@ - (void)awakeFromNib - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - @@ -120,11 +120,22 @@ - (NSColor *)alternateTextColor return _alternateTextColor; } + +- (BOOL)clipsToBounds +{ + return YES; +} + +- (BOOL)isOpaque +{ + return YES; +} + #pragma mark - - (void)setClientView:(NSView *)inClientView { - NSNotificationCenter *tNotificationCenter = [NSNotificationCenter defaultCenter]; + NSNotificationCenter *tNotificationCenter = NSNotificationCenter.defaultCenter; [tNotificationCenter removeObserver:self name:NSTextStorageDidProcessEditingNotification object:nil]; @@ -290,9 +301,21 @@ - (NSDictionary *)textAttributes if (tAdjustedFont==nil) tAdjustedFont=tFont; + static NSParagraphStyle * sLeftAlignedStyle=nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + + NSMutableParagraphStyle *mutableStyle=[[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + mutableStyle.alignment=NSTextAlignmentLeft; + + sLeftAlignedStyle = [mutableStyle copy]; + }); + return @{ NSFontAttributeName:tAdjustedFont, - NSForegroundColorAttributeName:self.textColor + NSForegroundColorAttributeName:self.textColor, + NSWritingDirectionAttributeName:@[@(NSWritingDirectionLeftToRight)], + NSParagraphStyleAttributeName:sLeftAlignedStyle }; } @@ -340,6 +363,11 @@ - (void)viewWillDraw [self calculateLines]; } +- (void)drawRect:(NSRect)dirtyRect +{ + [super drawRect:dirtyRect]; +} + - (void)drawSeparatorInRect:(NSRect)inRect { } @@ -397,9 +425,9 @@ - (void)drawHashMarksAndLabelsInRect:(NSRect)aRect NSUInteger rectCount; NSRectArray rects = [layoutManager rectArrayForCharacterRange:NSMakeRange(index, 0) - withinSelectedCharacterRange:nullRange - inTextContainer:container - rectCount:&rectCount]; + withinSelectedCharacterRange:nullRange + inTextContainer:container + rectCount:&rectCount]; if (rectCount > 0) { diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/ENDPOINTSECURITY_2.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/ENDPOINTSECURITY_2.html new file mode 100644 index 0000000..f5215a3 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/ENDPOINTSECURITY_2.html @@ -0,0 +1,14 @@ + + + + + + +Summary +

An ENDPOINTSECURITY termination reason with code 2 indicates that an Endpoint Security client took too long to respond to an event.

+ +Discussion +

An Endpoint Security client can be killed if it fails to respond to an authorization event before the deadline defined in the message for that event.

+ + + diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGBUS.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGBUS.html index 651f270..4b3db46 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGBUS.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGBUS.html @@ -11,7 +11,7 @@

The exception can happen when the process tries to access unmapped memory (KERN_INVALID_ADDRESS), misaligned memory (EXC_ARM_DA_ALIGN) or unavailable memory (KERN_MEMORY_ERROR). This can also happen when the process tries to write on read-only or protected memory (KERN_PROTECTION_FAILURE).

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGSEGV.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGSEGV.html index c32a33d..1fbf477 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGSEGV.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_ACCESS_SIGSEGV.html @@ -11,7 +11,7 @@

The exception can happen when the process tries to access unmapped memory (KERN_INVALID_ADDRESS), misaligned memory (EXC_ARM_DA_ALIGN) or unavailable memory (KERN_MEMORY_ERROR). This can also happen when the process tries to write on read-only or protected memory (KERN_PROTECTION_FAILURE).

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_INSTRUCTION_SIGILL.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_INSTRUCTION_SIGILL.html index 29de96e..134bbaa 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_INSTRUCTION_SIGILL.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BAD_INSTRUCTION_SIGILL.html @@ -11,7 +11,7 @@

The execution of this illegal instruction usually means that one of the compiler’s safety checks failed (e.g. when your code unwraps a nil optional in Swift).

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BREAKPOINT_SIGTRAP.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BREAKPOINT_SIGTRAP.html index 0093dad..dea0ec0 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BREAKPOINT_SIGTRAP.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_BREAKPOINT_SIGTRAP.html @@ -11,7 +11,7 @@

The execution of this illegal instruction usually means that one of the compiler’s safety checks failed (e.g. when your code unwraps a nil optional in Swift).

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_Code Signature Invalid.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_Code Signature Invalid.html index c7e5dcd..a7e8857 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_Code Signature Invalid.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_Code Signature Invalid.html @@ -5,7 +5,7 @@ Summary -

EXC_CRASH (Code Signature Invalid) indicates the operating system terminated the process because of problems related to code signing.

+

The EXC_CRASH (Code Signature Invalid) type indicates the operating system terminated the process because of problems related to code signing.

Discussion

The crash could have occurred because the application is using invalid entitlements or the code signing identity is incompatible with the running environment.

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGABRT.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGABRT.html index 8edb6be..e4e9c06 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGABRT.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGABRT.html @@ -5,13 +5,13 @@ Summary -

EXC_CRASH (SIGABRT) indicates the process terminated because it received the SIGABRT signal.

+

The EXC_CRASH (SIGABRT) type indicates the process terminated because it received the SIGABRT signal.

Discussion

Typically, this signal is sent because a function in the process called abort(), such as when an app encounters an uncaught Objective-C or C++ exception.

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGKILL.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGKILL.html index 95bdb56..157d912 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGKILL.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGKILL.html @@ -5,13 +5,13 @@ Summary -

EXC_CRASH (SIGKILL) indicates the operating system terminated the process.

+

The EXC_CRASH (SIGKILL) type indicates the operating system terminated the process.

Discussion

The crash report contains a Termination Reason field with a code that explains the reason for the crash.

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGQUIT.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGQUIT.html index e7c33b8..30be0eb 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGQUIT.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_CRASH_SIGQUIT.html @@ -5,13 +5,13 @@ Summary -

EXC_CRASH (SIGQUIT) indicates the process terminated at the request of another process with privileges to manage its lifetime.

+

The EXC_CRASH (SIGQUIT) type indicates the process terminated at the request of another process with privileges to manage its lifetime.

Discussion

This does not mean that the process crashed, but it likely misbehaved in a detectable manner.

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_GUARD.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_GUARD.html new file mode 100644 index 0000000..f1c72e6 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/EXC_GUARD.html @@ -0,0 +1,17 @@ + + + + + + +Summary +

The EXC_GUARD type indicates the process violated a system-enforced rule while using a guarded resource.

+ +Discussion +

Typically, this exception is raised when a process tries to use normal file descriptor APIs on guarded file descriptors.

+ + + + diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_exception_type.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_exception_type.html index 536aa01..14f6e5b 100644 --- a/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_exception_type.html +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_exception_type.html @@ -90,7 +90,7 @@

No Quick Help


-
Search Documentation
+
Search Documentation

diff --git a/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_termination_reason.html b/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_termination_reason.html new file mode 100644 index 0000000..e0190d2 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/en.lproj/unknown_termination_reason.html @@ -0,0 +1,95 @@ + + + + + + +

No Quick Help

+
+
+ + diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/ENDPOINTSECURITY_2.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/ENDPOINTSECURITY_2.html new file mode 100644 index 0000000..2c792d3 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/ENDPOINTSECURITY_2.html @@ -0,0 +1,14 @@ + + + + + + +Resumen +

Un motivo de terminación ENDPOINTSECURITY con el código 2 indica que un cliente de Endpoint Security tardó demasiado en responder a un evento.

+ +Discusión +

Un cliente de Endpoint Security puede terminarse si no responde a un evento de autorización antes de la fecha límite definida en el mensaje para ese evento.

+ + + diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGBUS.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGBUS.html index 3257c49..b8acb5a 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGBUS.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGBUS.html @@ -11,7 +11,7 @@

La excepción puede ocurrir cuando el proceso intenta acceder a memoria no asignada (KERN_INVALID_ADDRESS), memoria desalineada (EXC_ARM_DA_ALIGN) o memoria no disponible (KERN_MEMORY_ERROR). Esto también puede ocurrir cuando el proceso intenta escribir en una memoria protegida o de solo lectura (KERN_PROTECTION_FAILURE).

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGSEGV.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGSEGV.html index 251764c..09d4e63 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGSEGV.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_ACCESS_SIGSEGV.html @@ -11,7 +11,7 @@

La excepción puede ocurrir cuando el proceso intenta acceder a memoria no asignada (KERN_INVALID_ADDRESS), memoria desalineada (EXC_ARM_DA_ALIGN) o memoria no disponible (KERN_MEMORY_ERROR). Esto también puede ocurrir cuando el proceso intenta escribir en una memoria protegida o de solo lectura (KERN_PROTECTION_FAILURE).

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_INSTRUCTION_SIGILL.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_INSTRUCTION_SIGILL.html index 4992472..9df486d 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_INSTRUCTION_SIGILL.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BAD_INSTRUCTION_SIGILL.html @@ -11,7 +11,7 @@

La ejecución de esta instrucción ilegal generalmente significa que una de las comprobaciones de seguridad del compilador falló (por ejemplo, cuando su código desenvuelve un nil opcional en Swift).

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BREAKPOINT_SIGTRAP.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BREAKPOINT_SIGTRAP.html index ca3c384..2c88982 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BREAKPOINT_SIGTRAP.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_BREAKPOINT_SIGTRAP.html @@ -11,7 +11,7 @@

La ejecución de esta instrucción ilegal generalmente significa que una de las comprobaciones de seguridad del compilador falló (por ejemplo, cuando su código desenvuelve un nil opcional en Swift).

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGABRT.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGABRT.html index 886e0a0..80b1309 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGABRT.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGABRT.html @@ -11,7 +11,7 @@

Por lo general, esta señal se envía debido a una función en el proceso llamada abort(), como cuando una aplicación encuentra una excepción de Objective-C o C ++ no detectada.

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGKILL.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGKILL.html index dd91fde..5e24172 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGKILL.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGKILL.html @@ -11,7 +11,7 @@

El informe contiene un campo Termination Reason con un código que explica la razón de la falla.

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGQUIT.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGQUIT.html index 8e97b32..416b9b9 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGQUIT.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_CRASH_SIGQUIT.html @@ -11,7 +11,7 @@

Esto no significa que el proceso haya fallado, pero probablemente se haya comportado mal de una manera detectable.

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_GUARD.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_GUARD.html new file mode 100644 index 0000000..9367696 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/EXC_GUARD.html @@ -0,0 +1,17 @@ + + + + + + +Resumen +

El tipo EXC_GUARD indica que el proceso violó una regla impuesta por el sistema mientras usaba un recurso protegido.

+ +Discusión +

Normalmente, esta excepción se genera cuando un proceso intenta utilizar las API de descriptores de archivos normales en descriptores de archivos protegidos.

+ + + + diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_exception_type.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_exception_type.html index d4daab9..2cd8704 100644 --- a/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_exception_type.html +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_exception_type.html @@ -90,7 +90,7 @@

Ayuda rápida no disponible


-
Buscar documentación
+
Buscar documentación

diff --git a/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_termination_reason.html b/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_termination_reason.html new file mode 100644 index 0000000..d1a87c4 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/es.lproj/unknown_termination_reason.html @@ -0,0 +1,95 @@ + + + + + + +

Ayuda rápida no disponible

+
+
+ + diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/ENDPOINTSECURITY_2.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/ENDPOINTSECURITY_2.html new file mode 100644 index 0000000..6c25408 --- /dev/null +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/ENDPOINTSECURITY_2.html @@ -0,0 +1,14 @@ + + + + + + +Résumé +

Une raison de terminaison ENDPOINTSECURITY avec un code 2 indique qu'un client Endpoint Security a mis trop de temps à répondre à un événement.

+ +Discussion +

Un client Endpoint Security peut être tué s'il échoue à répondre à un événement d'autorisation avant l'échéance définie dans le message pour cet événement.

+ + + diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGBUS.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGBUS.html index 8abc851..adcca0a 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGBUS.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGBUS.html @@ -6,13 +6,13 @@ Résumé -

Le type d'exception EXC_BAD_ACCESS (SIGBUS) indique que l'opération a utilisé la mémoire d'une façon inattendue.

+

Le type d'exception EXC_BAD_ACCESS (SIGBUS) indique que le processus a utilisé la mémoire d'une façon inattendue.

Discussion -

Cette exception peut survenir lorsque l'opération essaye d'accèder à de la mémoire non mappée (KERN_INVALID_ADDRESS), de la mémoire non alignée (EXC_ARM_DA_ALIGN) ou de la mémoire non disponible (KERN_MEMORY_ERROR). Cela peut aussi survenir lors que l'opération tente d'écrire sur de la mémoire en lecture seule ou protégée (KERN_PROTECTION_FAILURE).

+

Cette exception peut survenir lorsque le processus essaye d'accèder à de la mémoire non mappée (KERN_INVALID_ADDRESS), de la mémoire non alignée (EXC_ARM_DA_ALIGN) ou de la mémoire non disponible (KERN_MEMORY_ERROR). Cela peut aussi survenir lorsque le processus tente d'écrire sur de la mémoire protégée ou en lecture seule (KERN_PROTECTION_FAILURE).

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGSEGV.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGSEGV.html index 85a0111..0cfde94 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGSEGV.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_ACCESS_SIGSEGV.html @@ -6,14 +6,14 @@ Résumé -

Le type d'exception EXC_BAD_ACCESS (SIGSEGV) indique que l'opération a utilisé la mémoire d'une façon inattendue.

+

Le type d'exception EXC_BAD_ACCESS (SIGSEGV) indique que le processus a utilisé la mémoire d'une façon inattendue.

Discussion -

Cette exception peut survenir lorsque l'opération essaye d'accèder à de la mémoire non mappée (KERN_INVALID_ADDRESS), de la mémoire non alignée (EXC_ARM_DA_ALIGN) ou de la mémoire non disponible (KERN_MEMORY_ERROR). Cela peut aussi survenir lors que l'opération tente d'écrire sur de la mémoire en lecture seule ou protégée (KERN_PROTECTION_FAILURE).

+

Cette exception peut survenir lorsque le processus essaye d'accèder à de la mémoire non mappée (KERN_INVALID_ADDRESS), de la mémoire non alignée (EXC_ARM_DA_ALIGN) ou de la mémoire non disponible (KERN_MEMORY_ERROR). Cela peut aussi survenir lorsque le processus tente d'écrire sur de la mémoire protégée ou en lecture seule (KERN_PROTECTION_FAILURE).

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_INSTRUCTION_SIGILL.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_INSTRUCTION_SIGILL.html index 0694ec1..efc107d 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_INSTRUCTION_SIGILL.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BAD_INSTRUCTION_SIGILL.html @@ -12,7 +12,7 @@

L'exécution d'une telle instruction indique généralement qu'une des procédures de vérifications insérées par le compilateur a détecté une erreur (e.g. quand votre code déballe un nil optionnel en Swift).

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BREAKPOINT_SIGTRAP.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BREAKPOINT_SIGTRAP.html index 8afeaa8..1fac496 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BREAKPOINT_SIGTRAP.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_BREAKPOINT_SIGTRAP.html @@ -6,13 +6,13 @@ Résumé -

Le type d'exception EXC_BREAKPOINT (SIGTRAP) indice qu'une instruction illégale (probablement insérée par le compilateur) a interrompu l'opération.

+

Le type d'exception EXC_BREAKPOINT (SIGTRAP) indice qu'une instruction illégale (probablement insérée par le compilateur) a interrompu le processus.

Discussion

L'exécution d'une telle instruction indique généralement qu'une des procédures de vérifications insérées par le compilateur a détecté une erreur (e.g. quand votre code déballe un nil optionnel en Swift).

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_Code Signature Invalid.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_Code Signature Invalid.html index 2bd50b7..0421197 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_Code Signature Invalid.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_Code Signature Invalid.html @@ -6,7 +6,7 @@ Résumé -

Le type d'exception EXC_CRASH (Code Signature Invalid) indique que le système d'exploitation a interrompu l'opération en raison de problèmes liés à la signature du code.

+

Le type d'exception EXC_CRASH (Code Signature Invalid) indique que le système d'exploitation a interrompu le processus en raison de problèmes liés à la signature du code.

Discussion

Le crash peut être survenu parce que l'application utilise des droits invalides ou que l'identité de la signature du code est incompatible avec l'environnement d'exécution.

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGABRT.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGABRT.html index 4becb78..82bfbcf 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGABRT.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGABRT.html @@ -6,13 +6,13 @@ Résumé -

Le type d'exception EXC_CRASH (SIGABRT) indique que l'opération s'est interrompue parce qu'elle a reçu le signal SIGABRT.

+

Le type d'exception EXC_CRASH (SIGABRT) indique que le processus s'est interrompu parce qu'il a reçu le signal SIGABRT.

Discussion -

Typiquement, ce signal est envoyé parce qu'une fonction de l'opération a appelé abort(), comme lorsqu'une application est confrontée à une exception Objective-C ou C++ non interceptée.

+

Typiquement, ce signal est envoyé parce qu'une fonction du processus a appelé abort(), comme lorsqu'une application est confrontée à une exception Objective-C ou C++ non interceptée.

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGKILL.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGKILL.html index 1740e35..082fd1e 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGKILL.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGKILL.html @@ -6,13 +6,13 @@ Résumé -

Le type d'exception EXC_CRASH (SIGKILL) indique que le système d'exploitation a interrompu l'opération.

+

Le type d'exception EXC_CRASH (SIGKILL) indique que le système d'exploitation a interrompu le processus.

Discussion

Le rapport de crash contient un champ "Termination Reason" (Raison de l'interruption) avec un code qui explique la raison du crash.

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGQUIT.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGQUIT.html index 2f0c513..7160f74 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGQUIT.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGQUIT.html @@ -6,13 +6,13 @@ Résumé -

Le type d'exception EXC_CRASH (SIGQUIT) indique que l'opération a été arrêtée par une autre opération disposant de droits sur la durée de vie de l'opération.

+

Le type d'exception EXC_CRASH (SIGQUIT) indique que le processus a été arrêté par un autre processus disposant de droits sur la durée de vie du processus.

Discussion -

Cela ne signifie pas que l'opération a planté mais plutôt qu'il a été repéré qu'elle se comportait de manière incorrecte.

+

Cela ne signifie pas que le processus a planté mais plutôt qu'il a été repéré qu'il se comportait de manière incorrecte.

diff --git a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGSEGV.html b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGSEGV.html index 8a4c75b..3e86029 100644 --- a/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGSEGV.html +++ b/app_unexpectedly/app_unexpectedly/Help/fr.lproj/EXC_CRASH_SIGSEGV.html @@ -6,10 +6,10 @@ Résumé -

Le type d'exception EXC_CRASH (SIGSEGV) indique que l'opération a utilisé la mémoire d'une façon inattendue.

+

Le type d'exception EXC_CRASH (SIGSEGV) indique que le processus a utilisé la mémoire d'une façon inattendue.

Discussion -

Cette exception peut survenir lorsque l'opération essaye d'accèder à de la mémoire non mappée, de la mémoire non alignée ou de la mémoire non disponible. Cela peut aussi survenir lors que l'opération tente d'écrire sur de la mémoire en lecture seule ou protégée.

+

Cette exception peut survenir lorsque le processus essaye d'accèder à de la mémoire non mappée, de la mémoire non alignée ou de la mémoire non disponible. Cela peut aussi survenir lorsque le processus tente d'écrire sur de la mémoire protégée ou en lecture seule.