├── .gitignore ├── .gitmodules ├── .travis.yml ├── Assets ├── Console.ai └── MainWindow.png ├── Console.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── Console.xcscheme ├── Console ├── Classes │ ├── ASL │ │ ├── ASL.swift │ │ ├── ASLMessage.swift │ │ └── ASLSender.swift │ ├── AboutWindowController.swift │ ├── ApplicationDelegate.swift │ ├── Extensions │ │ └── NSArrayController.swift │ ├── MainWindowController.swift │ ├── Preferences.swift │ ├── PreferencesWindowController.swift │ └── Transformers │ │ ├── ArrayIsEmptyValueTransformer.swift │ │ ├── ArrayIsNotEmptyValueTransformer.swift │ │ └── NumberToStringValueTransformer.swift ├── Defaults.plist ├── Info.plist └── UI │ ├── Base.lproj │ ├── Console.AboutWindowController.xib │ ├── Console.MainWindowController.xib │ ├── Console.PreferencesWindowController.xib │ └── MainMenu.xib │ └── Images │ └── Console.icns ├── README.md └── Scripts ├── ccache-config.sh └── ccache.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac Finder 2 | .DS_Store 3 | .Trashes 4 | Icon? 5 | 6 | # Thumbnails 7 | ._* 8 | 9 | # Files that might appear on external disk 10 | .Spotlight-V100 11 | .Trashes 12 | 13 | # Xcode 14 | *.pbxuser 15 | *.mode1v3 16 | *.mode2v3 17 | *.perspectivev3 18 | *.xccheckout 19 | *.profraw 20 | !default.pbxuser 21 | !default.mode1v3 22 | !default.mode2v3 23 | !default.perspectivev3 24 | xcuserdata 25 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Submodules/GitHubUpdates"] 2 | path = Submodules/GitHubUpdates 3 | url = https://github.com/macmade/GitHubUpdates.git 4 | [submodule "Submodules/xcconfig"] 5 | path = Submodules/xcconfig 6 | url = https://github.com/macmade/xcconfig.git 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | xcode_project: Console.xcodeproj 3 | xcode_scheme: Console 4 | osx_image: xcode10 5 | script: 6 | - xcodebuild build -project Console.xcodeproj -scheme Console 7 | -------------------------------------------------------------------------------- /Assets/Console.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Console/bb92dce1a6aba41c0f0f54e453870e9dd827c3c7/Assets/Console.ai -------------------------------------------------------------------------------- /Assets/MainWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Console/bb92dce1a6aba41c0f0f54e453870e9dd827c3c7/Assets/MainWindow.png -------------------------------------------------------------------------------- /Console.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 052CAA3A1DA394D7001536E4 /* Console.icns in Resources */ = {isa = PBXBuildFile; fileRef = 052CAA391DA394D7001536E4 /* Console.icns */; }; 11 | 053291051DA44EF200E46312 /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 053291041DA44EF200E46312 /* Defaults.plist */; }; 12 | 055F18881F893A1D00EBDEE1 /* ArrayIsNotEmptyValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F18861F893A1D00EBDEE1 /* ArrayIsNotEmptyValueTransformer.swift */; }; 13 | 055F18891F893A1D00EBDEE1 /* ArrayIsEmptyValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F18871F893A1D00EBDEE1 /* ArrayIsEmptyValueTransformer.swift */; }; 14 | 055F188B1F893A4E00EBDEE1 /* NumberToStringValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F188A1F893A4E00EBDEE1 /* NumberToStringValueTransformer.swift */; }; 15 | 055F188F1F893C5600EBDEE1 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F188E1F893C5500EBDEE1 /* AboutWindowController.swift */; }; 16 | 055F18901F893CB100EBDEE1 /* Console.AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 055F188C1F893C4500EBDEE1 /* Console.AboutWindowController.xib */; }; 17 | 055F18921F893D0800EBDEE1 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F18911F893D0800EBDEE1 /* PreferencesWindowController.swift */; }; 18 | 055F18941F893D4E00EBDEE1 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F18931F893D4E00EBDEE1 /* Preferences.swift */; }; 19 | 055F18961F893E2E00EBDEE1 /* ApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F18951F893E2E00EBDEE1 /* ApplicationDelegate.swift */; }; 20 | 055F18981F893F5900EBDEE1 /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055F18971F893F5900EBDEE1 /* MainWindowController.swift */; }; 21 | 05A78D421BB058990070E7F0 /* Console.MainWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05A78D401BB058990070E7F0 /* Console.MainWindowController.xib */; }; 22 | 05BF80111BAC754400A88F65 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05BF800D1BAC754400A88F65 /* MainMenu.xib */; }; 23 | 05CD94DF1F8A620B00B60CFC /* NSArrayController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CD94DE1F8A61F100B60CFC /* NSArrayController.swift */; }; 24 | 05CD94E21F8A6B1800B60CFC /* ASLMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CD94E11F8A6B1800B60CFC /* ASLMessage.swift */; }; 25 | 05CD94E51F8A7A4E00B60CFC /* ASLSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CD94E41F8A7A4E00B60CFC /* ASLSender.swift */; }; 26 | 05CD94E71F8A817800B60CFC /* ASL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CD94E61F8A817800B60CFC /* ASL.swift */; }; 27 | 05CD94F31F8A8AB800B60CFC /* GitHubUpdates.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05CD94EE1F8A8AA700B60CFC /* GitHubUpdates.framework */; }; 28 | 05CD94F51F8A8AC000B60CFC /* GitHubUpdates.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 05CD94EE1F8A8AA700B60CFC /* GitHubUpdates.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 29 | 05D79B3B1E6E116D00A9467D /* Console.PreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05D79B391E6E116D00A9467D /* Console.PreferencesWindowController.xib */; }; 30 | 05EE15DB1EBCEBC8004AED58 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05EE15DA1EBCEBC8004AED58 /* Cocoa.framework */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXContainerItemProxy section */ 34 | 05CD94ED1F8A8AA700B60CFC /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 05CD94E81F8A8AA700B60CFC /* GitHubUpdates.xcodeproj */; 37 | proxyType = 2; 38 | remoteGlobalIDString = 05F82B251EF32EA700EC8A93; 39 | remoteInfo = GitHubUpdates; 40 | }; 41 | 05CD94EF1F8A8AA700B60CFC /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 05CD94E81F8A8AA700B60CFC /* GitHubUpdates.xcodeproj */; 44 | proxyType = 2; 45 | remoteGlobalIDString = 0555EBA01EF3DDA10016167F; 46 | remoteInfo = Relauncher; 47 | }; 48 | 05CD94F11F8A8AB500B60CFC /* PBXContainerItemProxy */ = { 49 | isa = PBXContainerItemProxy; 50 | containerPortal = 05CD94E81F8A8AA700B60CFC /* GitHubUpdates.xcodeproj */; 51 | proxyType = 1; 52 | remoteGlobalIDString = 05F82B241EF32EA700EC8A93; 53 | remoteInfo = GitHubUpdates; 54 | }; 55 | /* End PBXContainerItemProxy section */ 56 | 57 | /* Begin PBXCopyFilesBuildPhase section */ 58 | 05CD94F41F8A8ABB00B60CFC /* CopyFiles */ = { 59 | isa = PBXCopyFilesBuildPhase; 60 | buildActionMask = 2147483647; 61 | dstPath = ""; 62 | dstSubfolderSpec = 10; 63 | files = ( 64 | 05CD94F51F8A8AC000B60CFC /* GitHubUpdates.framework in CopyFiles */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXCopyFilesBuildPhase section */ 69 | 70 | /* Begin PBXFileReference section */ 71 | 052CAA391DA394D7001536E4 /* Console.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Console.icns; sourceTree = ""; }; 72 | 053291041DA44EF200E46312 /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = ""; }; 73 | 055F18861F893A1D00EBDEE1 /* ArrayIsNotEmptyValueTransformer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayIsNotEmptyValueTransformer.swift; sourceTree = ""; }; 74 | 055F18871F893A1D00EBDEE1 /* ArrayIsEmptyValueTransformer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayIsEmptyValueTransformer.swift; sourceTree = ""; }; 75 | 055F188A1F893A4E00EBDEE1 /* NumberToStringValueTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberToStringValueTransformer.swift; sourceTree = ""; }; 76 | 055F188D1F893C4500EBDEE1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Console.AboutWindowController.xib; sourceTree = ""; }; 77 | 055F188E1F893C5500EBDEE1 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; }; 78 | 055F18911F893D0800EBDEE1 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; 79 | 055F18931F893D4E00EBDEE1 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; 80 | 055F18951F893E2E00EBDEE1 /* ApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationDelegate.swift; sourceTree = ""; }; 81 | 055F18971F893F5900EBDEE1 /* MainWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindowController.swift; sourceTree = ""; }; 82 | 05A78D411BB058990070E7F0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Console.MainWindowController.xib; sourceTree = ""; }; 83 | 05BF7FF41BAC748800A88F65 /* Console.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Console.app; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | 05BF80021BAC748800A88F65 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85 | 05BF800E1BAC754400A88F65 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 86 | 05CD94DE1F8A61F100B60CFC /* NSArrayController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSArrayController.swift; sourceTree = ""; }; 87 | 05CD94E11F8A6B1800B60CFC /* ASLMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASLMessage.swift; sourceTree = ""; }; 88 | 05CD94E41F8A7A4E00B60CFC /* ASLSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASLSender.swift; sourceTree = ""; }; 89 | 05CD94E61F8A817800B60CFC /* ASL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASL.swift; sourceTree = ""; }; 90 | 05CD94E81F8A8AA700B60CFC /* GitHubUpdates.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GitHubUpdates.xcodeproj; path = Submodules/GitHubUpdates/GitHubUpdates.xcodeproj; sourceTree = ""; }; 91 | 05D79B381E6E081200A9467D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 92 | 05D79B3A1E6E116D00A9467D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Console.PreferencesWindowController.xib; sourceTree = ""; }; 93 | 05EB89E32141BFE800B769F5 /* Release - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - ccache.xcconfig"; sourceTree = ""; }; 94 | 05EB89E42141BFE800B769F5 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; 95 | 05EB89E52141BFE800B769F5 /* Debug - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - ccache.xcconfig"; sourceTree = ""; }; 96 | 05EB89E62141BFE800B769F5 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 97 | 05EB89E72141BFE800B769F5 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 98 | 05EB89E82141BFE800B769F5 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 99 | 05EB89EA2141BFE800B769F5 /* Signing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Signing.xcconfig; sourceTree = ""; }; 100 | 05EB89EB2141BFE800B769F5 /* Architectures.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Architectures.xcconfig; sourceTree = ""; }; 101 | 05EB89ED2141BFE800B769F5 /* Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Issues.xcconfig; sourceTree = ""; }; 102 | 05EB89EF2141BFE800B769F5 /* Apple-APIs.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-APIs.xcconfig"; sourceTree = ""; }; 103 | 05EB89F02141BFE800B769F5 /* Generic-Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Generic-Issues.xcconfig"; sourceTree = ""; }; 104 | 05EB89F12141BFE800B769F5 /* Security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Security.xcconfig; sourceTree = ""; }; 105 | 05EB89F22141BFE800B769F5 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 106 | 05EB89F32141BFE800B769F5 /* Analysis-Policy.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Analysis-Policy.xcconfig"; sourceTree = ""; }; 107 | 05EB89F42141BFE800B769F5 /* Deployment.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Deployment.xcconfig; sourceTree = ""; }; 108 | 05EB89F52141BFE800B769F5 /* Build-Options.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Build-Options.xcconfig"; sourceTree = ""; }; 109 | 05EB89F62141BFE800B769F5 /* Swift-Compiler.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Swift-Compiler.xcconfig"; sourceTree = ""; }; 110 | 05EB89F72141BFE800B769F5 /* Static-Analyzer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Static-Analyzer.xcconfig"; sourceTree = ""; }; 111 | 05EB89F92141BFE800B769F5 /* Warnings-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warnings-Policies.xcconfig"; sourceTree = ""; }; 112 | 05EB89FA2141BFE800B769F5 /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 113 | 05EB89FB2141BFE800B769F5 /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 114 | 05EB89FC2141BFE800B769F5 /* General.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; 115 | 05EB89FD2141BFE800B769F5 /* Search-Paths.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Search-Paths.xcconfig"; sourceTree = ""; }; 116 | 05EB89FE2141BFE800B769F5 /* Apple-LLVM.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-LLVM.xcconfig"; sourceTree = ""; }; 117 | 05EB8A012141BFE800B769F5 /* Modules.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Modules.xcconfig; sourceTree = ""; }; 118 | 05EB8A022141BFE800B769F5 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 119 | 05EB8A032141BFE800B769F5 /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 120 | 05EB8A042141BFE800B769F5 /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 121 | 05EB8A052141BFE800B769F5 /* Address-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Address-Sanitizer.xcconfig"; sourceTree = ""; }; 122 | 05EB8A062141BFE800B769F5 /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 123 | 05EB8A072141BFE800B769F5 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 124 | 05EB8A082141BFE800B769F5 /* Undefined-Behavior-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Undefined-Behavior-Sanitizer.xcconfig"; sourceTree = ""; }; 125 | 05EB8A092141BFE800B769F5 /* Warning-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warning-Policies.xcconfig"; sourceTree = ""; }; 126 | 05EB8A0B2141BFE800B769F5 /* Objective-C-ARC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C-ARC.xcconfig"; sourceTree = ""; }; 127 | 05EB8A0C2141BFE800B769F5 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 128 | 05EB8A0D2141BFE800B769F5 /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 129 | 05EB8A0E2141BFE800B769F5 /* All-Languages.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "All-Languages.xcconfig"; sourceTree = ""; }; 130 | 05EB8A0F2141BFE800B769F5 /* Preprocessing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Preprocessing.xcconfig; sourceTree = ""; }; 131 | 05EB8A102141BFE800B769F5 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 132 | 05EB8A122141BFE800B769F5 /* ccache-config.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "ccache-config.sh"; sourceTree = ""; }; 133 | 05EB8A132141BFE800B769F5 /* ccache.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ccache.sh; sourceTree = ""; }; 134 | 05EE15DA1EBCEBC8004AED58 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 135 | /* End PBXFileReference section */ 136 | 137 | /* Begin PBXFrameworksBuildPhase section */ 138 | 05BF7FF11BAC748800A88F65 /* Frameworks */ = { 139 | isa = PBXFrameworksBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | 05CD94F31F8A8AB800B60CFC /* GitHubUpdates.framework in Frameworks */, 143 | 05EE15DB1EBCEBC8004AED58 /* Cocoa.framework in Frameworks */, 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | /* End PBXFrameworksBuildPhase section */ 148 | 149 | /* Begin PBXGroup section */ 150 | 052CAA2E1DA38B40001536E4 /* Transformers */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 055F18871F893A1D00EBDEE1 /* ArrayIsEmptyValueTransformer.swift */, 154 | 055F18861F893A1D00EBDEE1 /* ArrayIsNotEmptyValueTransformer.swift */, 155 | 055F188A1F893A4E00EBDEE1 /* NumberToStringValueTransformer.swift */, 156 | ); 157 | path = Transformers; 158 | sourceTree = ""; 159 | }; 160 | 052CAA381DA394D7001536E4 /* Images */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 052CAA391DA394D7001536E4 /* Console.icns */, 164 | ); 165 | path = Images; 166 | sourceTree = ""; 167 | }; 168 | 05A78D361BB044F30070E7F0 /* ASL */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 05CD94E61F8A817800B60CFC /* ASL.swift */, 172 | 05CD94E11F8A6B1800B60CFC /* ASLMessage.swift */, 173 | 05CD94E41F8A7A4E00B60CFC /* ASLSender.swift */, 174 | ); 175 | path = ASL; 176 | sourceTree = ""; 177 | }; 178 | 05BF7FEB1BAC748800A88F65 = { 179 | isa = PBXGroup; 180 | children = ( 181 | 05D79B381E6E081200A9467D /* README.md */, 182 | 05CD94E81F8A8AA700B60CFC /* GitHubUpdates.xcodeproj */, 183 | 05EB89E22141BFE800B769F5 /* xcconfig */, 184 | 05BF7FF61BAC748800A88F65 /* Console */, 185 | 05BF7FF51BAC748800A88F65 /* Products */, 186 | 05EE15D91EBCEBC8004AED58 /* Frameworks */, 187 | ); 188 | sourceTree = ""; 189 | }; 190 | 05BF7FF51BAC748800A88F65 /* Products */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 05BF7FF41BAC748800A88F65 /* Console.app */, 194 | ); 195 | name = Products; 196 | sourceTree = ""; 197 | }; 198 | 05BF7FF61BAC748800A88F65 /* Console */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | 05BF80081BAC754400A88F65 /* Classes */, 202 | 05BF7FFA1BAC748800A88F65 /* Supporting Files */, 203 | 05BF800B1BAC754400A88F65 /* UI */, 204 | ); 205 | path = Console; 206 | sourceTree = ""; 207 | }; 208 | 05BF7FFA1BAC748800A88F65 /* Supporting Files */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 053291041DA44EF200E46312 /* Defaults.plist */, 212 | 05BF80021BAC748800A88F65 /* Info.plist */, 213 | ); 214 | name = "Supporting Files"; 215 | sourceTree = ""; 216 | }; 217 | 05BF80081BAC754400A88F65 /* Classes */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 055F188E1F893C5500EBDEE1 /* AboutWindowController.swift */, 221 | 055F18951F893E2E00EBDEE1 /* ApplicationDelegate.swift */, 222 | 05A78D361BB044F30070E7F0 /* ASL */, 223 | 05CD94DD1F8A61F100B60CFC /* Extensions */, 224 | 055F18971F893F5900EBDEE1 /* MainWindowController.swift */, 225 | 055F18931F893D4E00EBDEE1 /* Preferences.swift */, 226 | 055F18911F893D0800EBDEE1 /* PreferencesWindowController.swift */, 227 | 052CAA2E1DA38B40001536E4 /* Transformers */, 228 | ); 229 | path = Classes; 230 | sourceTree = ""; 231 | }; 232 | 05BF800B1BAC754400A88F65 /* UI */ = { 233 | isa = PBXGroup; 234 | children = ( 235 | 052CAA381DA394D7001536E4 /* Images */, 236 | 055F188C1F893C4500EBDEE1 /* Console.AboutWindowController.xib */, 237 | 05BF800D1BAC754400A88F65 /* MainMenu.xib */, 238 | 05A78D401BB058990070E7F0 /* Console.MainWindowController.xib */, 239 | 05D79B391E6E116D00A9467D /* Console.PreferencesWindowController.xib */, 240 | ); 241 | path = UI; 242 | sourceTree = ""; 243 | }; 244 | 05CD94DD1F8A61F100B60CFC /* Extensions */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | 05CD94DE1F8A61F100B60CFC /* NSArrayController.swift */, 248 | ); 249 | path = Extensions; 250 | sourceTree = ""; 251 | }; 252 | 05CD94E91F8A8AA700B60CFC /* Products */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | 05CD94EE1F8A8AA700B60CFC /* GitHubUpdates.framework */, 256 | 05CD94F01F8A8AA700B60CFC /* Relauncher */, 257 | ); 258 | name = Products; 259 | sourceTree = ""; 260 | }; 261 | 05EB89E22141BFE800B769F5 /* xcconfig */ = { 262 | isa = PBXGroup; 263 | children = ( 264 | 05EB89E32141BFE800B769F5 /* Release - ccache.xcconfig */, 265 | 05EB89E42141BFE800B769F5 /* Common.xcconfig */, 266 | 05EB89E52141BFE800B769F5 /* Debug - ccache.xcconfig */, 267 | 05EB89E62141BFE800B769F5 /* Debug.xcconfig */, 268 | 05EB89E72141BFE800B769F5 /* Release.xcconfig */, 269 | 05EB89E82141BFE800B769F5 /* README.md */, 270 | 05EB89E92141BFE800B769F5 /* Common */, 271 | 05EB8A102141BFE800B769F5 /* .gitignore */, 272 | 05EB8A112141BFE800B769F5 /* Scripts */, 273 | ); 274 | name = xcconfig; 275 | path = Submodules/xcconfig; 276 | sourceTree = ""; 277 | }; 278 | 05EB89E92141BFE800B769F5 /* Common */ = { 279 | isa = PBXGroup; 280 | children = ( 281 | 05EB89EA2141BFE800B769F5 /* Signing.xcconfig */, 282 | 05EB89EB2141BFE800B769F5 /* Architectures.xcconfig */, 283 | 05EB89EC2141BFE800B769F5 /* Static-Analyzer */, 284 | 05EB89F42141BFE800B769F5 /* Deployment.xcconfig */, 285 | 05EB89F52141BFE800B769F5 /* Build-Options.xcconfig */, 286 | 05EB89F62141BFE800B769F5 /* Swift-Compiler.xcconfig */, 287 | 05EB89F72141BFE800B769F5 /* Static-Analyzer.xcconfig */, 288 | 05EB89F82141BFE800B769F5 /* Swift-Compiler */, 289 | 05EB89FD2141BFE800B769F5 /* Search-Paths.xcconfig */, 290 | 05EB89FE2141BFE800B769F5 /* Apple-LLVM.xcconfig */, 291 | 05EB89FF2141BFE800B769F5 /* Apple-LLVM */, 292 | ); 293 | path = Common; 294 | sourceTree = ""; 295 | }; 296 | 05EB89EC2141BFE800B769F5 /* Static-Analyzer */ = { 297 | isa = PBXGroup; 298 | children = ( 299 | 05EB89ED2141BFE800B769F5 /* Issues.xcconfig */, 300 | 05EB89EE2141BFE800B769F5 /* Issues */, 301 | ); 302 | path = "Static-Analyzer"; 303 | sourceTree = ""; 304 | }; 305 | 05EB89EE2141BFE800B769F5 /* Issues */ = { 306 | isa = PBXGroup; 307 | children = ( 308 | 05EB89EF2141BFE800B769F5 /* Apple-APIs.xcconfig */, 309 | 05EB89F02141BFE800B769F5 /* Generic-Issues.xcconfig */, 310 | 05EB89F12141BFE800B769F5 /* Security.xcconfig */, 311 | 05EB89F22141BFE800B769F5 /* Objective-C.xcconfig */, 312 | 05EB89F32141BFE800B769F5 /* Analysis-Policy.xcconfig */, 313 | ); 314 | path = Issues; 315 | sourceTree = ""; 316 | }; 317 | 05EB89F82141BFE800B769F5 /* Swift-Compiler */ = { 318 | isa = PBXGroup; 319 | children = ( 320 | 05EB89F92141BFE800B769F5 /* Warnings-Policies.xcconfig */, 321 | 05EB89FA2141BFE800B769F5 /* Code-Generation.xcconfig */, 322 | 05EB89FB2141BFE800B769F5 /* Language.xcconfig */, 323 | 05EB89FC2141BFE800B769F5 /* General.xcconfig */, 324 | ); 325 | path = "Swift-Compiler"; 326 | sourceTree = ""; 327 | }; 328 | 05EB89FF2141BFE800B769F5 /* Apple-LLVM */ = { 329 | isa = PBXGroup; 330 | children = ( 331 | 05EB8A002141BFE800B769F5 /* Language */, 332 | 05EB8A042141BFE800B769F5 /* Code-Generation.xcconfig */, 333 | 05EB8A052141BFE800B769F5 /* Address-Sanitizer.xcconfig */, 334 | 05EB8A062141BFE800B769F5 /* Language.xcconfig */, 335 | 05EB8A072141BFE800B769F5 /* Warnings.xcconfig */, 336 | 05EB8A082141BFE800B769F5 /* Undefined-Behavior-Sanitizer.xcconfig */, 337 | 05EB8A092141BFE800B769F5 /* Warning-Policies.xcconfig */, 338 | 05EB8A0A2141BFE800B769F5 /* Warnings */, 339 | 05EB8A0F2141BFE800B769F5 /* Preprocessing.xcconfig */, 340 | ); 341 | path = "Apple-LLVM"; 342 | sourceTree = ""; 343 | }; 344 | 05EB8A002141BFE800B769F5 /* Language */ = { 345 | isa = PBXGroup; 346 | children = ( 347 | 05EB8A012141BFE800B769F5 /* Modules.xcconfig */, 348 | 05EB8A022141BFE800B769F5 /* Objective-C.xcconfig */, 349 | 05EB8A032141BFE800B769F5 /* C++.xcconfig */, 350 | ); 351 | path = Language; 352 | sourceTree = ""; 353 | }; 354 | 05EB8A0A2141BFE800B769F5 /* Warnings */ = { 355 | isa = PBXGroup; 356 | children = ( 357 | 05EB8A0B2141BFE800B769F5 /* Objective-C-ARC.xcconfig */, 358 | 05EB8A0C2141BFE800B769F5 /* Objective-C.xcconfig */, 359 | 05EB8A0D2141BFE800B769F5 /* C++.xcconfig */, 360 | 05EB8A0E2141BFE800B769F5 /* All-Languages.xcconfig */, 361 | ); 362 | path = Warnings; 363 | sourceTree = ""; 364 | }; 365 | 05EB8A112141BFE800B769F5 /* Scripts */ = { 366 | isa = PBXGroup; 367 | children = ( 368 | 05EB8A122141BFE800B769F5 /* ccache-config.sh */, 369 | 05EB8A132141BFE800B769F5 /* ccache.sh */, 370 | ); 371 | path = Scripts; 372 | sourceTree = ""; 373 | }; 374 | 05EE15D91EBCEBC8004AED58 /* Frameworks */ = { 375 | isa = PBXGroup; 376 | children = ( 377 | 05EE15DA1EBCEBC8004AED58 /* Cocoa.framework */, 378 | ); 379 | name = Frameworks; 380 | sourceTree = ""; 381 | }; 382 | /* End PBXGroup section */ 383 | 384 | /* Begin PBXNativeTarget section */ 385 | 05BF7FF31BAC748800A88F65 /* Console */ = { 386 | isa = PBXNativeTarget; 387 | buildConfigurationList = 05BF80051BAC748800A88F65 /* Build configuration list for PBXNativeTarget "Console" */; 388 | buildPhases = ( 389 | 05BF7FF01BAC748800A88F65 /* Sources */, 390 | 05BF7FF11BAC748800A88F65 /* Frameworks */, 391 | 05CD94F71F8A8B3B00B60CFC /* ShellScript */, 392 | 05BF7FF21BAC748800A88F65 /* Resources */, 393 | 05CD94F41F8A8ABB00B60CFC /* CopyFiles */, 394 | ); 395 | buildRules = ( 396 | ); 397 | dependencies = ( 398 | 05CD94F21F8A8AB500B60CFC /* PBXTargetDependency */, 399 | ); 400 | name = Console; 401 | productName = Console; 402 | productReference = 05BF7FF41BAC748800A88F65 /* Console.app */; 403 | productType = "com.apple.product-type.application"; 404 | }; 405 | /* End PBXNativeTarget section */ 406 | 407 | /* Begin PBXProject section */ 408 | 05BF7FEC1BAC748800A88F65 /* Project object */ = { 409 | isa = PBXProject; 410 | attributes = { 411 | LastUpgradeCheck = 1220; 412 | ORGANIZATIONNAME = "XS-Labs"; 413 | TargetAttributes = { 414 | 05BF7FF31BAC748800A88F65 = { 415 | CreatedOnToolsVersion = 7.0; 416 | DevelopmentTeam = 326Y53CJMD; 417 | LastSwiftMigration = 0900; 418 | ProvisioningStyle = Automatic; 419 | }; 420 | }; 421 | }; 422 | buildConfigurationList = 05BF7FEF1BAC748800A88F65 /* Build configuration list for PBXProject "Console" */; 423 | compatibilityVersion = "Xcode 3.2"; 424 | developmentRegion = en; 425 | hasScannedForEncodings = 0; 426 | knownRegions = ( 427 | en, 428 | Base, 429 | ); 430 | mainGroup = 05BF7FEB1BAC748800A88F65; 431 | productRefGroup = 05BF7FF51BAC748800A88F65 /* Products */; 432 | projectDirPath = ""; 433 | projectReferences = ( 434 | { 435 | ProductGroup = 05CD94E91F8A8AA700B60CFC /* Products */; 436 | ProjectRef = 05CD94E81F8A8AA700B60CFC /* GitHubUpdates.xcodeproj */; 437 | }, 438 | ); 439 | projectRoot = ""; 440 | targets = ( 441 | 05BF7FF31BAC748800A88F65 /* Console */, 442 | ); 443 | }; 444 | /* End PBXProject section */ 445 | 446 | /* Begin PBXReferenceProxy section */ 447 | 05CD94EE1F8A8AA700B60CFC /* GitHubUpdates.framework */ = { 448 | isa = PBXReferenceProxy; 449 | fileType = wrapper.framework; 450 | path = GitHubUpdates.framework; 451 | remoteRef = 05CD94ED1F8A8AA700B60CFC /* PBXContainerItemProxy */; 452 | sourceTree = BUILT_PRODUCTS_DIR; 453 | }; 454 | 05CD94F01F8A8AA700B60CFC /* Relauncher */ = { 455 | isa = PBXReferenceProxy; 456 | fileType = "compiled.mach-o.executable"; 457 | path = Relauncher; 458 | remoteRef = 05CD94EF1F8A8AA700B60CFC /* PBXContainerItemProxy */; 459 | sourceTree = BUILT_PRODUCTS_DIR; 460 | }; 461 | /* End PBXReferenceProxy section */ 462 | 463 | /* Begin PBXResourcesBuildPhase section */ 464 | 05BF7FF21BAC748800A88F65 /* Resources */ = { 465 | isa = PBXResourcesBuildPhase; 466 | buildActionMask = 2147483647; 467 | files = ( 468 | 05D79B3B1E6E116D00A9467D /* Console.PreferencesWindowController.xib in Resources */, 469 | 052CAA3A1DA394D7001536E4 /* Console.icns in Resources */, 470 | 055F18901F893CB100EBDEE1 /* Console.AboutWindowController.xib in Resources */, 471 | 053291051DA44EF200E46312 /* Defaults.plist in Resources */, 472 | 05A78D421BB058990070E7F0 /* Console.MainWindowController.xib in Resources */, 473 | 05BF80111BAC754400A88F65 /* MainMenu.xib in Resources */, 474 | ); 475 | runOnlyForDeploymentPostprocessing = 0; 476 | }; 477 | /* End PBXResourcesBuildPhase section */ 478 | 479 | /* Begin PBXShellScriptBuildPhase section */ 480 | 05CD94F71F8A8B3B00B60CFC /* ShellScript */ = { 481 | isa = PBXShellScriptBuildPhase; 482 | buildActionMask = 2147483647; 483 | files = ( 484 | ); 485 | inputPaths = ( 486 | ); 487 | outputPaths = ( 488 | ); 489 | runOnlyForDeploymentPostprocessing = 0; 490 | shellPath = /bin/sh; 491 | shellScript = "#!/bin/bash\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n plist=\"Console/Info.plist\"\n rev=$(git rev-list `git branch | grep -e \"^*\" | cut -d' ' -f 2` | wc -l)\n /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $rev\" \"$plist\"\nfi"; 492 | }; 493 | /* End PBXShellScriptBuildPhase section */ 494 | 495 | /* Begin PBXSourcesBuildPhase section */ 496 | 05BF7FF01BAC748800A88F65 /* Sources */ = { 497 | isa = PBXSourcesBuildPhase; 498 | buildActionMask = 2147483647; 499 | files = ( 500 | 05CD94E71F8A817800B60CFC /* ASL.swift in Sources */, 501 | 055F18881F893A1D00EBDEE1 /* ArrayIsNotEmptyValueTransformer.swift in Sources */, 502 | 055F18941F893D4E00EBDEE1 /* Preferences.swift in Sources */, 503 | 055F18961F893E2E00EBDEE1 /* ApplicationDelegate.swift in Sources */, 504 | 055F18921F893D0800EBDEE1 /* PreferencesWindowController.swift in Sources */, 505 | 05CD94E21F8A6B1800B60CFC /* ASLMessage.swift in Sources */, 506 | 055F18891F893A1D00EBDEE1 /* ArrayIsEmptyValueTransformer.swift in Sources */, 507 | 055F188F1F893C5600EBDEE1 /* AboutWindowController.swift in Sources */, 508 | 055F18981F893F5900EBDEE1 /* MainWindowController.swift in Sources */, 509 | 055F188B1F893A4E00EBDEE1 /* NumberToStringValueTransformer.swift in Sources */, 510 | 05CD94DF1F8A620B00B60CFC /* NSArrayController.swift in Sources */, 511 | 05CD94E51F8A7A4E00B60CFC /* ASLSender.swift in Sources */, 512 | ); 513 | runOnlyForDeploymentPostprocessing = 0; 514 | }; 515 | /* End PBXSourcesBuildPhase section */ 516 | 517 | /* Begin PBXTargetDependency section */ 518 | 05CD94F21F8A8AB500B60CFC /* PBXTargetDependency */ = { 519 | isa = PBXTargetDependency; 520 | name = GitHubUpdates; 521 | targetProxy = 05CD94F11F8A8AB500B60CFC /* PBXContainerItemProxy */; 522 | }; 523 | /* End PBXTargetDependency section */ 524 | 525 | /* Begin PBXVariantGroup section */ 526 | 055F188C1F893C4500EBDEE1 /* Console.AboutWindowController.xib */ = { 527 | isa = PBXVariantGroup; 528 | children = ( 529 | 055F188D1F893C4500EBDEE1 /* Base */, 530 | ); 531 | name = Console.AboutWindowController.xib; 532 | sourceTree = ""; 533 | }; 534 | 05A78D401BB058990070E7F0 /* Console.MainWindowController.xib */ = { 535 | isa = PBXVariantGroup; 536 | children = ( 537 | 05A78D411BB058990070E7F0 /* Base */, 538 | ); 539 | name = Console.MainWindowController.xib; 540 | sourceTree = ""; 541 | }; 542 | 05BF800D1BAC754400A88F65 /* MainMenu.xib */ = { 543 | isa = PBXVariantGroup; 544 | children = ( 545 | 05BF800E1BAC754400A88F65 /* Base */, 546 | ); 547 | name = MainMenu.xib; 548 | sourceTree = ""; 549 | }; 550 | 05D79B391E6E116D00A9467D /* Console.PreferencesWindowController.xib */ = { 551 | isa = PBXVariantGroup; 552 | children = ( 553 | 05D79B3A1E6E116D00A9467D /* Base */, 554 | ); 555 | name = Console.PreferencesWindowController.xib; 556 | sourceTree = ""; 557 | }; 558 | /* End PBXVariantGroup section */ 559 | 560 | /* Begin XCBuildConfiguration section */ 561 | 05BF80031BAC748800A88F65 /* Debug */ = { 562 | isa = XCBuildConfiguration; 563 | baseConfigurationReference = 05EB89E62141BFE800B769F5 /* Debug.xcconfig */; 564 | buildSettings = { 565 | MACOSX_DEPLOYMENT_TARGET = 10.11; 566 | }; 567 | name = Debug; 568 | }; 569 | 05BF80041BAC748800A88F65 /* Release */ = { 570 | isa = XCBuildConfiguration; 571 | baseConfigurationReference = 05EB89E72141BFE800B769F5 /* Release.xcconfig */; 572 | buildSettings = { 573 | CODE_SIGN_IDENTITY = "Mac Developer"; 574 | MACOSX_DEPLOYMENT_TARGET = 10.11; 575 | }; 576 | name = Release; 577 | }; 578 | 05BF80061BAC748800A88F65 /* Debug */ = { 579 | isa = XCBuildConfiguration; 580 | buildSettings = { 581 | INFOPLIST_FILE = Console/Info.plist; 582 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 583 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.Console"; 584 | PRODUCT_NAME = "$(TARGET_NAME)"; 585 | }; 586 | name = Debug; 587 | }; 588 | 05BF80071BAC748800A88F65 /* Release */ = { 589 | isa = XCBuildConfiguration; 590 | buildSettings = { 591 | INFOPLIST_FILE = Console/Info.plist; 592 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 593 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.Console"; 594 | PRODUCT_NAME = "$(TARGET_NAME)"; 595 | }; 596 | name = Release; 597 | }; 598 | /* End XCBuildConfiguration section */ 599 | 600 | /* Begin XCConfigurationList section */ 601 | 05BF7FEF1BAC748800A88F65 /* Build configuration list for PBXProject "Console" */ = { 602 | isa = XCConfigurationList; 603 | buildConfigurations = ( 604 | 05BF80031BAC748800A88F65 /* Debug */, 605 | 05BF80041BAC748800A88F65 /* Release */, 606 | ); 607 | defaultConfigurationIsVisible = 0; 608 | defaultConfigurationName = Release; 609 | }; 610 | 05BF80051BAC748800A88F65 /* Build configuration list for PBXNativeTarget "Console" */ = { 611 | isa = XCConfigurationList; 612 | buildConfigurations = ( 613 | 05BF80061BAC748800A88F65 /* Debug */, 614 | 05BF80071BAC748800A88F65 /* Release */, 615 | ); 616 | defaultConfigurationIsVisible = 0; 617 | defaultConfigurationName = Release; 618 | }; 619 | /* End XCConfigurationList section */ 620 | }; 621 | rootObject = 05BF7FEC1BAC748800A88F65 /* Project object */; 622 | } 623 | -------------------------------------------------------------------------------- /Console.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Console.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Console.xcodeproj/xcshareddata/xcschemes/Console.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Console/Classes/ASL/ASL.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import asl 27 | 28 | @objc class ASL: NSObject 29 | { 30 | @objc public private( set ) dynamic var messages: [ ASLMessage ] = [] 31 | @objc public private( set ) dynamic var senders: [ ASLSender ] = [] 32 | 33 | @objc private dynamic var sender: String = "" 34 | @objc private dynamic var run: Bool = false 35 | @objc private dynamic var runing: Bool = false 36 | @objc private dynamic var exit: Bool = false 37 | @objc private dynamic var inited: Bool = false 38 | 39 | @objc convenience override init() 40 | { 41 | self.init( sender: nil ) 42 | } 43 | 44 | @objc init( sender: String? ) 45 | { 46 | super.init() 47 | 48 | self.sender = sender ?? "" 49 | 50 | Thread.detachNewThreadSelector( #selector( processMessages ), toTarget: self, with: nil ) 51 | } 52 | 53 | deinit 54 | { 55 | for sender in self.senders 56 | { 57 | sender.removeObserver( self, forKeyPath: "messages" ) 58 | } 59 | 60 | self.exit = true 61 | 62 | while self.runing 63 | {} 64 | } 65 | 66 | override func observeValue( forKeyPath keyPath: String?, of object: Any?, change: [ NSKeyValueChangeKey : Any ]?, context: UnsafeMutableRawPointer? ) 67 | { 68 | if( keyPath == "messages" && object is ASLSender ) 69 | { 70 | DispatchQueue.main.async 71 | { 72 | if( self.senders.contains( object as! ASLSender ) ) 73 | { 74 | var allMessages = [ ASLMessage ]() 75 | 76 | for sender in self.senders 77 | { 78 | allMessages.append( contentsOf: sender.messages as! [ ASLMessage ] ) 79 | } 80 | 81 | self.messages = allMessages 82 | } 83 | } 84 | } 85 | else 86 | { 87 | super.observeValue( forKeyPath: keyPath, of: object, change: change, context: context ) 88 | } 89 | } 90 | 91 | @objc public func start() 92 | { 93 | self.run = true 94 | } 95 | 96 | @objc public func stop() 97 | { 98 | self.run = false 99 | } 100 | 101 | @objc private func processMessages() 102 | { 103 | var lastID = self.messages.last?.messageID ?? 0 104 | let client = asl_open( nil, nil, 0 ) 105 | 106 | while( self.exit == false ) 107 | { 108 | self.runing = true 109 | 110 | let query = asl_new( UInt32( ASL_TYPE_QUERY ) ) 111 | 112 | if( self.sender.count > 0 ) 113 | { 114 | asl_set_query( query, ASL_KEY_MSG, ( self.sender as NSString ).utf8String, UInt32( ASL_QUERY_OP_EQUAL ) ) 115 | } 116 | 117 | asl_set_query( query, ASL_KEY_MSG, nil, UInt32( ASL_QUERY_OP_NOT_EQUAL ) ) 118 | asl_set_query( query, ASL_KEY_MSG_ID, ( String( format: "%lu", lastID ) as NSString ).utf8String, UInt32( ASL_QUERY_OP_GREATER ) ) 119 | 120 | let response = asl_search( client, query ) 121 | 122 | asl_free( query ) 123 | 124 | var msg = asl_next( response ) 125 | 126 | if( msg != nil ) 127 | { 128 | var newMessages = [ ASLMessage ]() 129 | 130 | while( msg != nil ) 131 | { 132 | let message = ASLMessage( msg ) 133 | 134 | if( message.messageID <= lastID ) 135 | { 136 | continue 137 | } 138 | 139 | lastID = ( message.messageID > lastID ) ? message.messageID : lastID 140 | 141 | newMessages.append( message ) 142 | 143 | msg = asl_next( response ) 144 | } 145 | 146 | var senders = [ ASLSender ]( self.senders ) 147 | 148 | for message in newMessages 149 | { 150 | var sender: ASLSender? 151 | 152 | for s in senders 153 | { 154 | if( s.name == message.sender && s.facility == message.facility ) 155 | { 156 | sender = s 157 | 158 | break 159 | } 160 | } 161 | 162 | if( sender == nil ) 163 | { 164 | sender = ASLSender( name: message.sender, facility: message.facility ) 165 | 166 | senders.append( sender! ) 167 | sender?.addObserver( self, forKeyPath: "messages", options: .new, context: nil ) 168 | } 169 | 170 | sender?.addMessage( message ) 171 | } 172 | 173 | var allMessages: [ ASLMessage ]? 174 | 175 | if( newMessages.count == 0 ) 176 | { 177 | allMessages = nil 178 | } 179 | else 180 | { 181 | allMessages = [] 182 | 183 | for sender in senders 184 | { 185 | allMessages?.append( contentsOf: sender.messages as! [ ASLMessage ] ) 186 | } 187 | } 188 | 189 | DispatchQueue.main.sync 190 | { 191 | if( allMessages != nil ) 192 | { 193 | self.messages = allMessages! 194 | } 195 | 196 | self.senders = senders 197 | } 198 | } 199 | } 200 | } 201 | 202 | private func sender( with name: String, facility: String ) -> ASLSender 203 | { 204 | for sender in self.senders 205 | { 206 | if( sender.name == name && sender.facility == facility ) 207 | { 208 | return sender 209 | } 210 | } 211 | 212 | let sender = ASLSender( name: name, facility: facility ) 213 | var senders = [ ASLSender ]( self.senders ) 214 | 215 | senders.append( sender ) 216 | 217 | DispatchQueue.main.sync 218 | { 219 | self.senders = senders 220 | } 221 | 222 | return sender 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /Console/Classes/ASL/ASLMessage.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Foundation 26 | import asl 27 | 28 | @objc class ASLMessage: NSObject 29 | { 30 | @objc public private( set ) dynamic var pid: UInt = 0 31 | @objc public private( set ) dynamic var pidNumber: NSNumber = 0 32 | @objc public private( set ) dynamic var uid: UInt = 0 33 | @objc public private( set ) dynamic var uidNumber: NSNumber = 0 34 | @objc public private( set ) dynamic var gid: UInt = 0 35 | @objc public private( set ) dynamic var gidNumber: NSNumber = 0 36 | @objc public private( set ) dynamic var facility: String = "" 37 | @objc public private( set ) dynamic var host: String = "" 38 | @objc public private( set ) dynamic var sender: String = "" 39 | @objc public private( set ) dynamic var senderUUID: UUID = UUID() 40 | @objc public private( set ) dynamic var time: Date = Date( timeIntervalSince1970: 0 ) 41 | @objc public private( set ) dynamic var level: UInt = 0 42 | @objc public private( set ) dynamic var levelNumber: NSNumber = 0 43 | @objc public private( set ) dynamic var levelString: String = "" 44 | @objc public private( set ) dynamic var message: String = "" 45 | @objc public private( set ) dynamic var messageID: UInt = 0 46 | @objc public private( set ) dynamic var messageIDNumber: NSNumber = 0 47 | 48 | static func ==( lhs: ASLMessage, rhs: ASLMessage ) -> Bool 49 | { 50 | return lhs.messageID == rhs.messageID 51 | } 52 | 53 | @objc public convenience override init() 54 | { 55 | self.init( nil ) 56 | } 57 | 58 | @objc public init( _ message: aslmsg? ) 59 | { 60 | super.init() 61 | 62 | guard let msg = message else 63 | { 64 | return 65 | } 66 | 67 | self.pid = self.valueToUnsignedInteger( asl_get( msg, ASL_KEY_PID ) ) 68 | self.pidNumber = NSNumber( value: self.pid ) 69 | self.uid = self.valueToUnsignedInteger( asl_get( msg, ASL_KEY_UID ) ) 70 | self.uidNumber = NSNumber( value: self.uid ) 71 | self.gid = self.valueToUnsignedInteger( asl_get( msg, ASL_KEY_GID ) ) 72 | self.gidNumber = NSNumber( value: self.gid ) 73 | self.facility = self.valueToString( asl_get( msg, ASL_KEY_FACILITY ) ) 74 | self.host = self.valueToString( asl_get( msg, ASL_KEY_HOST ) ) 75 | self.sender = self.valueToString( asl_get( msg, ASL_KEY_SENDER ) ) 76 | self.senderUUID = self.valueToUUID( asl_get( msg, ASL_KEY_SENDER_MACH_UUID ) ) 77 | self.time = self.valueToDate( asl_get( msg, ASL_KEY_TIME ) ) 78 | self.level = self.valueToUnsignedInteger( asl_get( msg, ASL_KEY_LEVEL ) ) 79 | self.levelNumber = NSNumber( value: self.level ) 80 | self.message = self.valueToString( asl_get( msg, ASL_KEY_MSG ) ) 81 | self.messageID = self.valueToUnsignedInteger( asl_get( msg, ASL_KEY_MSG_ID ) ) 82 | self.messageIDNumber = NSNumber( value: self.messageID ) 83 | 84 | switch( Int32( self.level ) ) 85 | { 86 | case ASL_LEVEL_EMERG: self.levelString = "Emergency" 87 | case ASL_LEVEL_ALERT: self.levelString = "Alert" 88 | case ASL_LEVEL_CRIT: self.levelString = "Critical" 89 | case ASL_LEVEL_ERR: self.levelString = "Error"; 90 | case ASL_LEVEL_WARNING: self.levelString = "Warning" 91 | case ASL_LEVEL_NOTICE: self.levelString = "Notice" 92 | case ASL_LEVEL_INFO: self.levelString = "Info" 93 | case ASL_LEVEL_DEBUG: self.levelString = "Debug" 94 | default: self.levelString = "Unknown" 95 | } 96 | } 97 | 98 | override func isEqual( _ object: Any? ) -> Bool 99 | { 100 | guard let o = object as? ASLMessage else 101 | { 102 | return false 103 | } 104 | 105 | if( o === self ) 106 | { 107 | return true 108 | } 109 | 110 | return self == o 111 | } 112 | 113 | override func isEqual( to object: Any? ) -> Bool 114 | { 115 | return self.isEqual( object ) 116 | } 117 | 118 | override public var hash: Int 119 | { 120 | get 121 | { 122 | return Int( self.messageID ) 123 | } 124 | } 125 | 126 | public override var description: String 127 | { 128 | return String( format: "%@ %@[ %u ] - %@: %@", super.description, self.sender, self.pid, self.levelString, self.message ) 129 | } 130 | 131 | private func valueToString( _ value: UnsafePointer< Int8 >! ) -> String 132 | { 133 | if( value == nil ) 134 | { 135 | return "" 136 | } 137 | 138 | return NSString( utf8String: value ) as String? ?? "" 139 | } 140 | 141 | private func valueToDate( _ value: UnsafePointer< Int8 >! ) -> Date 142 | { 143 | return Date( timeIntervalSince1970: TimeInterval( self.valueToUnsignedInteger( value ) ) ) 144 | } 145 | 146 | private func valueToUUID( _ value: UnsafePointer< Int8 >! ) -> UUID 147 | { 148 | return UUID( uuidString: self.valueToString( value ) ) ?? UUID() 149 | } 150 | 151 | private func valueToUnsignedInteger( _ value: UnsafePointer< Int8 >! ) -> UInt 152 | { 153 | if( value == nil ) 154 | { 155 | return 0 156 | } 157 | 158 | return UInt( ( self.valueToString( value ) as NSString ).integerValue ) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /Console/Classes/ASL/ASLSender.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import asl 27 | 28 | @objc class ASLSender: NSObject, NSCopying 29 | { 30 | @objc public private( set ) dynamic var name: String = "" 31 | @objc public private( set ) dynamic var facility: String = "" 32 | @objc public private( set ) dynamic var messages: NSArray = NSArray() 33 | @objc public private( set ) dynamic var messagesMutable: NSMutableArray = NSMutableArray() 34 | @objc public private( set ) dynamic var icon: NSImage? 35 | 36 | static func ==( lhs: ASLSender, rhs: ASLSender ) -> Bool 37 | { 38 | if( lhs.name != rhs.name ) 39 | { 40 | return false 41 | } 42 | 43 | if( lhs.facility != rhs.facility ) 44 | { 45 | return false 46 | } 47 | 48 | return true 49 | } 50 | 51 | @objc convenience override init() 52 | { 53 | self.init( name: "", facility: "" ) 54 | } 55 | 56 | @objc init( name: String, facility: String ) 57 | { 58 | super.init() 59 | 60 | self.name = name 61 | self.facility = facility 62 | 63 | var paths = [ String ]() 64 | 65 | let apps = NSSearchPathForDirectoriesInDomains( .applicationDirectory, .localDomainMask, true ).first 66 | let userApps = NSSearchPathForDirectoriesInDomains( .applicationDirectory, .userDomainMask, true ).first 67 | 68 | if( apps != nil ) 69 | { 70 | paths.append( ( apps! as NSString ).appendingPathComponent( String( format: "%@.app", self.name ) ) ) 71 | } 72 | 73 | if( userApps != nil ) 74 | { 75 | paths.append( ( userApps! as NSString ).appendingPathComponent( String( format: "%@.app", self.name ) ) ) 76 | } 77 | 78 | paths.append( String( format: "/bin/%@", self.name ) ) 79 | paths.append( String( format: "/sbin/%@", self.name ) ) 80 | paths.append( String( format: "/usr/bin/%@", self.name ) ) 81 | paths.append( String( format: "/usr/sbin/%@", self.name ) ) 82 | paths.append( String( format: "/usr/libexec/%@", self.name ) ) 83 | paths.append( String( format: "/usr/local/bin/%@", self.name ) ) 84 | paths.append( String( format: "/usr/local/sbin/%@", self.name ) ) 85 | paths.append( String( format: "/usr/local/libexec/%@", self.name ) ) 86 | 87 | for path in paths 88 | { 89 | if( FileManager.default.fileExists(atPath: path ) ) 90 | { 91 | self.icon = NSWorkspace.shared.icon( forFile: path ) 92 | 93 | break 94 | } 95 | } 96 | 97 | if( self.icon == nil ) 98 | { 99 | self.icon = NSWorkspace.shared.icon( forFile: "/bin/ls" ) 100 | } 101 | } 102 | 103 | override func isEqual( _ object: Any? ) -> Bool 104 | { 105 | guard let o = object as? ASLMessage else 106 | { 107 | return false 108 | } 109 | 110 | if( o === self ) 111 | { 112 | return true 113 | } 114 | 115 | return self == o 116 | } 117 | 118 | override func isEqual( to object: Any? ) -> Bool 119 | { 120 | return self.isEqual( object ) 121 | } 122 | 123 | override public var hash: Int 124 | { 125 | get 126 | { 127 | return ( self.name + self.facility ).hash 128 | } 129 | } 130 | 131 | func copy( with zone: NSZone? = nil ) -> Any 132 | { 133 | return ASLSender( name: self.name, facility: self.facility ) 134 | } 135 | 136 | @objc public func addMessage( _ message: ASLMessage ) 137 | { 138 | self.messagesMutable.add( message ) 139 | 140 | self.messages = self.messagesMutable 141 | } 142 | 143 | @objc public func clear() 144 | { 145 | self.messagesMutable = NSMutableArray() 146 | self.messages = self.messagesMutable 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Console/Classes/AboutWindowController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2020 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class AboutWindowController: NSWindowController 28 | { 29 | @objc private dynamic var name: String? 30 | @objc private dynamic var version: String? 31 | @objc private dynamic var copyright: String? 32 | 33 | public override var windowNibName: NSNib.Name? 34 | { 35 | return NSNib.Name( NSStringFromClass( type( of: self ) ) ) 36 | } 37 | 38 | override public func windowDidLoad() 39 | { 40 | super.windowDidLoad() 41 | 42 | let version = Bundle.main.object( forInfoDictionaryKey: "CFBundleShortVersionString" ) as? String ?? "0.0.0" 43 | 44 | if let build = Bundle.main.object( forInfoDictionaryKey: "CFBundleVersion" ) as? String 45 | { 46 | self.version = "\(version) (\(build))" 47 | } 48 | else 49 | { 50 | self.version = version 51 | } 52 | 53 | self.name = Bundle.main.object( forInfoDictionaryKey: "CFBundleName" ) as? String 54 | self.copyright = Bundle.main.object( forInfoDictionaryKey: "NSHumanReadableCopyright" ) as? String 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Console/Classes/ApplicationDelegate.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @NSApplicationMain @objc public class ApplicationDelegate: NSObject, NSApplicationDelegate 28 | { 29 | @objc private dynamic var aboutWindowController: AboutWindowController? 30 | @objc private dynamic var preferencesWindowController: PreferencesWindowController? 31 | @objc private dynamic var mainWindowControllers: [ MainWindowController ] = [] 32 | 33 | @objc public func applicationDidFinishLaunching( _ notification: Notification ) 34 | { 35 | NotificationCenter.default.addObserver( self, selector: #selector( windowWillClose ), name: NSWindow.willCloseNotification, object: nil ) 36 | self.newDocument( nil ) 37 | 38 | Preferences.shared.lastStart = Date() 39 | } 40 | 41 | @objc public func applicationWillTerminate( _ notification: Notification ) 42 | { 43 | NotificationCenter.default.removeObserver( self ) 44 | } 45 | 46 | @objc public func applicationShouldTerminateAfterLastWindowClosed( _ sender: NSApplication ) -> Bool 47 | { 48 | return false 49 | } 50 | 51 | @IBAction func showAboutWindow( _ sender: Any? ) 52 | { 53 | if( self.aboutWindowController == nil ) 54 | { 55 | self.aboutWindowController = AboutWindowController() 56 | 57 | self.aboutWindowController?.window?.layoutIfNeeded() 58 | self.aboutWindowController?.window?.center() 59 | } 60 | 61 | self.aboutWindowController?.window?.makeKeyAndOrderFront( sender ) 62 | } 63 | 64 | @IBAction func showPreferencesWindow( _ sender: Any? ) 65 | { 66 | if( self.preferencesWindowController == nil ) 67 | { 68 | self.preferencesWindowController = PreferencesWindowController() 69 | 70 | self.preferencesWindowController?.window?.center() 71 | } 72 | 73 | self.preferencesWindowController?.window?.makeKeyAndOrderFront( sender ) 74 | } 75 | 76 | @IBAction func newDocument( _ sender: Any? ) 77 | { 78 | let controller = MainWindowController() 79 | 80 | if( Preferences.shared.lastStart == nil ) 81 | { 82 | controller.window?.center() 83 | } 84 | 85 | self.mainWindowControllers.append( controller ) 86 | controller.window?.makeKeyAndOrderFront( sender ) 87 | } 88 | 89 | @objc public func windowWillClose( _ notification: Notification ) 90 | { 91 | guard let window = ( notification.object as AnyObject? ) as? NSWindow else 92 | { 93 | return 94 | } 95 | 96 | if( window == self.preferencesWindowController?.window ) 97 | { 98 | self.preferencesWindowController = nil 99 | } 100 | 101 | self.mainWindowControllers = self.mainWindowControllers.filter{ $0 != window.windowController } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Console/Classes/Extensions/NSArrayController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | extension NSArrayController 28 | { 29 | public func arrangedObjectsArray< Type >() -> [ Type ] 30 | { 31 | guard let array = self.arrangedObjects as? NSArray else 32 | { 33 | return [] 34 | } 35 | 36 | var objects = [ Type ]() 37 | 38 | for object in array 39 | { 40 | if( object is Type ) 41 | { 42 | objects.append( object as! Type ) 43 | } 44 | } 45 | 46 | return objects 47 | } 48 | 49 | public func selectedObjectsArray< Type >() -> [ Type ] 50 | { 51 | var objects = [ Type ]() 52 | 53 | for object in self.selectedObjects 54 | { 55 | if( object is Type ) 56 | { 57 | objects.append( object as! Type ) 58 | } 59 | } 60 | 61 | return objects 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Console/Classes/MainWindowController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc class MainWindowController: NSWindowController, NSTableViewDataSource 28 | { 29 | @objc private dynamic var asl: ASL? 30 | @objc private dynamic var observations: [ NSKeyValueObservation ] = [] 31 | @objc private dynamic var textViewContainerHiddenConstraint: NSLayoutConstraint? 32 | @objc private dynamic var textViewContainerVisibleConstraint: NSLayoutConstraint? 33 | 34 | @objc @IBOutlet private dynamic var sendersArrayController: NSArrayController? 35 | @objc @IBOutlet private dynamic var messagesArrayController: NSArrayController? 36 | @objc @IBOutlet private dynamic var textView: NSTextView? 37 | @objc @IBOutlet private dynamic var textViewContainer: NSView? 38 | 39 | convenience init() 40 | { 41 | self.init( sender: nil ) 42 | } 43 | 44 | convenience init( sender: String? ) 45 | { 46 | self.init( windowNibName: NSNib.Name( NSStringFromClass( type( of: self ) ) ) ) 47 | 48 | self.asl = ASL( sender: sender ) 49 | } 50 | 51 | override var windowNibName: NSNib.Name? 52 | { 53 | return NSNib.Name( NSStringFromClass( type( of: self ) ) ) 54 | } 55 | 56 | override func windowDidLoad() 57 | { 58 | super.windowDidLoad() 59 | 60 | self.window?.titlebarAppearsTransparent = true 61 | self.window?.titleVisibility = .hidden 62 | 63 | self.asl?.start() 64 | 65 | self.sendersArrayController?.sortDescriptors = [ NSSortDescriptor( key: "name", ascending: true ) ] 66 | self.messagesArrayController?.sortDescriptors = [ NSSortDescriptor( key: "time", ascending: false ) ] 67 | 68 | let o1 = self.asl?.observe( \.messages ) 69 | { 70 | ( o, c ) in 71 | 72 | if( self.sendersArrayController?.selectedObjects.count == 0 ) 73 | { 74 | self.messagesArrayController?.content = self.asl?.messages 75 | } 76 | else 77 | { 78 | self.messagesArrayController?.content = self.sendersArrayController?.value( forKeyPath: "selection.@unionOfArrays.messages" ) 79 | } 80 | } 81 | 82 | let o2 = self.sendersArrayController?.observe( \.selection ) 83 | { 84 | ( o, c ) in 85 | 86 | if( self.sendersArrayController?.selectionIndexes.count == 0 ) 87 | { 88 | self.messagesArrayController?.content = self.asl?.messages 89 | } 90 | else 91 | { 92 | self.messagesArrayController?.content = self.sendersArrayController?.value( forKeyPath: "selection.@unionOfArrays.messages" ) 93 | } 94 | } 95 | 96 | let o3 = self.messagesArrayController?.observe( \.selection ) 97 | { 98 | ( o, c ) in 99 | 100 | if( self.messagesArrayController?.selectionIndexes.count != 1 ) 101 | { 102 | self.textViewContainerVisibleConstraint?.isActive = false 103 | self.textViewContainerHiddenConstraint?.isActive = true 104 | } 105 | else 106 | { 107 | self.textViewContainerHiddenConstraint?.isActive = false 108 | self.textViewContainerVisibleConstraint?.isActive = true 109 | } 110 | } 111 | 112 | if( o1 != nil ) { self.observations.append( o1! ) } 113 | if( o2 != nil ) { self.observations.append( o2! ) } 114 | if( o3 != nil ) { self.observations.append( o3! ) } 115 | 116 | self.messagesArrayController?.content = self.asl?.messages 117 | self.textView?.textContainerInset = NSMakeSize( 10.0, 15.0 ) 118 | 119 | let o4 = Preferences.shared.observe( \.fontName ) { ( o, c ) in self.updateDisplaySettings() } 120 | let o5 = Preferences.shared.observe( \.fontSize ) { ( o, c ) in self.updateDisplaySettings() } 121 | let o6 = Preferences.shared.observe( \.backgroundColorR ) { ( o, c ) in self.updateDisplaySettings() } 122 | let o7 = Preferences.shared.observe( \.backgroundColorG ) { ( o, c ) in self.updateDisplaySettings() } 123 | let o8 = Preferences.shared.observe( \.backgroundColorB ) { ( o, c ) in self.updateDisplaySettings() } 124 | let o9 = Preferences.shared.observe( \.foregroundColorR ) { ( o, c ) in self.updateDisplaySettings() } 125 | let o10 = Preferences.shared.observe( \.foregroundColorG ) { ( o, c ) in self.updateDisplaySettings() } 126 | let o11 = Preferences.shared.observe( \.foregroundColorB ) { ( o, c ) in self.updateDisplaySettings() } 127 | 128 | self.observations.append( contentsOf: [ o4, o5, o6, o7, o8, o9, o10, o11 ] ) 129 | 130 | self.updateDisplaySettings() 131 | 132 | for constraint in self.textViewContainer?.constraints ?? [] 133 | { 134 | if( constraint.firstAttribute == .height ) 135 | { 136 | constraint.isActive = false 137 | self.textViewContainerVisibleConstraint = constraint 138 | self.textViewContainerHiddenConstraint = NSLayoutConstraint( item: self.textViewContainer!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0.0, constant: 0.0 ) 139 | 140 | self.textViewContainer?.addConstraint( self.textViewContainerHiddenConstraint! ) 141 | 142 | break 143 | } 144 | } 145 | } 146 | 147 | @IBAction func clearAllMessages( _ sender: Any? ) 148 | { 149 | var senders: [ ASLSender ]? 150 | 151 | if( self.sendersArrayController?.selectedObjects.count != 0 ) 152 | { 153 | senders = self.sendersArrayController?.selectedObjectsArray() 154 | } 155 | else 156 | { 157 | senders = self.sendersArrayController?.arrangedObjectsArray() 158 | } 159 | 160 | for s in senders ?? [] 161 | { 162 | s.clear() 163 | } 164 | } 165 | 166 | @objc private func updateDisplaySettings() 167 | { 168 | var font: NSFont? 169 | 170 | let fontName = Preferences.shared.fontName 171 | 172 | if( fontName != nil && fontName!.count > 0 ) 173 | { 174 | font = NSFont( name: fontName!, size: Preferences.shared.fontSize ) 175 | } 176 | 177 | if( font == nil ) 178 | { 179 | font = NSFont( name: "Consolas", size: Preferences.shared.fontSize ) 180 | } 181 | 182 | if( font == nil ) 183 | { 184 | font = NSFont( name: "Menlo", size: Preferences.shared.fontSize ) 185 | } 186 | 187 | if( font == nil ) 188 | { 189 | font = NSFont( name: "Monaco", size: Preferences.shared.fontSize ) 190 | } 191 | 192 | if( font == nil ) 193 | { 194 | font = NSFont.systemFont( ofSize: Preferences.shared.fontSize ) 195 | } 196 | 197 | self.textView?.font = font 198 | 199 | let background = NSColor( deviceRed: Preferences.shared.backgroundColorR, green: Preferences.shared.backgroundColorG, blue: Preferences.shared.backgroundColorB, alpha: 1.0 ) 200 | let foreground = NSColor( deviceRed: Preferences.shared.foregroundColorR, green: Preferences.shared.foregroundColorG, blue: Preferences.shared.foregroundColorB, alpha: 1.0 ) 201 | 202 | self.textView?.backgroundColor = background 203 | self.textView?.textColor = foreground 204 | } 205 | 206 | // MARK: - NSTableViewDataSource 207 | 208 | func tableView( _ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard ) -> Bool 209 | { 210 | tableView.setDraggingSourceOperationMask( .copy, forLocal: false ) 211 | 212 | guard let messages = ( self.messagesArrayController?.arrangedObjects as? NSArray )?.objects( at: rowIndexes ) else 213 | { 214 | return false 215 | } 216 | 217 | var contents = [ String ]() 218 | 219 | for message in messages as! [ ASLMessage ] 220 | { 221 | contents.append( message.message ) 222 | } 223 | 224 | if( contents.count > 0 ) 225 | { 226 | pboard.setString( contents.joined( separator: "\n\n--------------------------------------------------------------------------------\n\n" ), forType: .string ) 227 | 228 | return true 229 | } 230 | 231 | return false 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /Console/Classes/Preferences.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc public class Preferences: NSObject 28 | { 29 | @objc public dynamic var lastStart: Date? 30 | @objc public dynamic var fontName: String? 31 | @objc public dynamic var fontSize: CGFloat = 0 32 | @objc public dynamic var backgroundColorR: CGFloat = 0 33 | @objc public dynamic var backgroundColorG: CGFloat = 0 34 | @objc public dynamic var backgroundColorB: CGFloat = 0 35 | @objc public dynamic var foregroundColorR: CGFloat = 0 36 | @objc public dynamic var foregroundColorG: CGFloat = 0 37 | @objc public dynamic var foregroundColorB: CGFloat = 0 38 | 39 | @objc public static let shared = Preferences() 40 | 41 | override init() 42 | { 43 | super.init() 44 | 45 | guard let path = Bundle.main.path( forResource: "Defaults", ofType: "plist" ) else 46 | { 47 | return 48 | } 49 | 50 | UserDefaults.standard.register( defaults: NSDictionary( contentsOfFile: path ) as? [ String : Any ] ?? [ : ] ) 51 | 52 | for c in Mirror( reflecting: self ).children 53 | { 54 | guard let key = c.label else 55 | { 56 | continue 57 | } 58 | 59 | self.setValue( UserDefaults.standard.object( forKey: key ), forKey: key ) 60 | self.addObserver( self, forKeyPath: key, options: .new, context: nil ) 61 | } 62 | } 63 | 64 | deinit 65 | { 66 | for c in Mirror( reflecting: self ).children 67 | { 68 | guard let key = c.label else 69 | { 70 | continue 71 | } 72 | 73 | self.removeObserver( self, forKeyPath: key ) 74 | } 75 | } 76 | 77 | @objc public override func observeValue( forKeyPath keyPath: String?, of object: Any?, change: [ NSKeyValueChangeKey : Any ]?, context: UnsafeMutableRawPointer? ) 78 | { 79 | for c in Mirror( reflecting: self ).children 80 | { 81 | guard let key = c.label else 82 | { 83 | continue 84 | } 85 | 86 | if( key == keyPath ) 87 | { 88 | UserDefaults.standard.set( change?[ NSKeyValueChangeKey.newKey ], forKey: key ) 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Console/Classes/PreferencesWindowController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc class PreferencesWindowController: NSWindowController 28 | { 29 | @objc private dynamic var fontDescription: String = "" 30 | @objc private dynamic var backgroundColor: NSColor = NSColor.white 31 | @objc private dynamic var foregroundColor: NSColor = NSColor.black 32 | @objc private dynamic var selectedTheme: Int = 0 33 | @objc private dynamic var observations: [ NSKeyValueObservation ] = [] 34 | 35 | override var windowNibName: NSNib.Name? 36 | { 37 | return NSNib.Name( NSStringFromClass( type( of: self ) ) ) 38 | } 39 | 40 | override func windowDidLoad() 41 | { 42 | super.windowDidLoad() 43 | 44 | self.fontDescription = String( format: "%@ %.0f", Preferences.shared.fontName ?? "-", Preferences.shared.fontSize ) 45 | self.backgroundColor = NSColor( deviceRed: Preferences.shared.backgroundColorR, green: Preferences.shared.backgroundColorG, blue: Preferences.shared.backgroundColorB, alpha: 1.0 ) 46 | self.foregroundColor = NSColor( deviceRed: Preferences.shared.foregroundColorR, green: Preferences.shared.foregroundColorG, blue: Preferences.shared.foregroundColorB, alpha: 1.0 ) 47 | 48 | let o1 = Preferences.shared.observe( \.fontName ) 49 | { 50 | ( o, c ) in self.fontDescription = String( format: "%@ %.0f", o.fontName ?? "-", o.fontSize ) 51 | } 52 | 53 | let o2 = Preferences.shared.observe( \.fontSize ) 54 | { 55 | ( o, c ) in self.fontDescription = String( format: "%@ %.0f", o.fontName ?? "-", o.fontSize ) 56 | } 57 | 58 | let o3 = self.observe( \.backgroundColor ) 59 | { 60 | ( o, c ) in 61 | 62 | var r: CGFloat = 0.0 63 | var g: CGFloat = 0.0 64 | var b: CGFloat = 0.0 65 | 66 | self.backgroundColor.usingColorSpace( .deviceRGB )?.getRed( &r, green: &g, blue: &b, alpha: nil ) 67 | 68 | Preferences.shared.backgroundColorR = r 69 | Preferences.shared.backgroundColorG = g 70 | Preferences.shared.backgroundColorB = b 71 | } 72 | 73 | let o4 = self.observe( \.foregroundColor ) 74 | { 75 | ( o, c ) in 76 | 77 | var r: CGFloat = 0.0 78 | var g: CGFloat = 0.0 79 | var b: CGFloat = 0.0 80 | 81 | self.foregroundColor.usingColorSpace( .deviceRGB )?.getRed( &r, green: &g, blue: &b, alpha: nil ) 82 | 83 | Preferences.shared.foregroundColorR = r 84 | Preferences.shared.foregroundColorG = g 85 | Preferences.shared.foregroundColorB = b 86 | } 87 | 88 | let o5 = self.observe( \.selectedTheme ) 89 | { 90 | ( o, c ) in 91 | 92 | switch( self.selectedTheme ) 93 | { 94 | case 1: 95 | 96 | self.backgroundColor = self.hexColor( 0xFFFFFF, alpha: 1.0 ); 97 | self.foregroundColor = self.hexColor( 0x000000, alpha: 1.0 ); 98 | 99 | break; 100 | 101 | case 2: 102 | 103 | self.backgroundColor = self.hexColor( 0x000000, alpha: 1.0 ); 104 | self.foregroundColor = self.hexColor( 0xFFFFFF, alpha: 1.0 ); 105 | 106 | break; 107 | 108 | case 3: 109 | 110 | self.backgroundColor = self.hexColor( 0xFFFCE5, alpha: 1.0 ); 111 | self.foregroundColor = self.hexColor( 0xC3741C, alpha: 1.0 ); 112 | 113 | break; 114 | 115 | case 4: 116 | 117 | self.backgroundColor = self.hexColor( 0x161A1D, alpha: 1.0 ); 118 | self.foregroundColor = self.hexColor( 0xBFBFBF, alpha: 1.0 ); 119 | 120 | break; 121 | 122 | default: 123 | 124 | break; 125 | } 126 | } 127 | 128 | self.observations.append( contentsOf: [ o1, o2, o3, o4, o5 ] ) 129 | } 130 | 131 | private func hexColor( _ hex: UInt, alpha: CGFloat ) -> NSColor 132 | { 133 | let r: CGFloat = CGFloat( ( ( hex >> 16 ) & 0x0000FF ) ) / 255.0 134 | let g: CGFloat = CGFloat( ( ( hex >> 8 ) & 0x0000FF ) ) / 255.0 135 | let b: CGFloat = CGFloat( ( ( hex ) & 0x0000FF ) ) / 255.0 136 | 137 | return NSColor( deviceRed: r, green: g, blue: b, alpha: alpha ) 138 | } 139 | 140 | @IBAction func chooseFont( _ sender: Any? ) 141 | { 142 | let font = NSFont( name: Preferences.shared.fontName as String? ?? "", size: Preferences.shared.fontSize ) 143 | let manager = NSFontManager.shared 144 | let panel = manager.fontPanel( true ) 145 | 146 | if( font != nil ) 147 | { 148 | manager.setSelectedFont( font!, isMultiple: false ) 149 | } 150 | 151 | panel?.makeKeyAndOrderFront( sender ) 152 | } 153 | 154 | @IBAction func changeFont( _ sender: Any? ) 155 | { 156 | guard let manager = ( sender as AnyObject? ) as? NSFontManager else 157 | { 158 | return 159 | } 160 | 161 | guard let selected = manager.selectedFont else 162 | { 163 | return 164 | } 165 | 166 | let font = manager.convert( selected ) 167 | 168 | Preferences.shared.fontName = font.fontName 169 | Preferences.shared.fontSize = font.pointSize 170 | } 171 | } 172 | 173 | -------------------------------------------------------------------------------- /Console/Classes/Transformers/ArrayIsEmptyValueTransformer.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Foundation 26 | 27 | @objc class ArrayIsEmptyValueTransformer: ValueTransformer 28 | { 29 | @objc public override static func allowsReverseTransformation() -> Bool 30 | { 31 | return false 32 | } 33 | 34 | @objc public override static func transformedValueClass() -> Swift.AnyClass 35 | { 36 | return NSNumber.self 37 | } 38 | 39 | @objc public override func transformedValue( _ value: Any? ) -> Any? 40 | { 41 | guard let array = value as? NSArray else 42 | { 43 | return NSNumber( booleanLiteral: true ) 44 | } 45 | 46 | return NSNumber( booleanLiteral: ( array.count == 0 ) ? true : false ) 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Console/Classes/Transformers/ArrayIsNotEmptyValueTransformer.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Foundation 26 | 27 | @objc class ArrayIsNotEmptyValueTransformer: ValueTransformer 28 | { 29 | @objc public override static func allowsReverseTransformation() -> Bool 30 | { 31 | return false 32 | } 33 | 34 | @objc public override static func transformedValueClass() -> Swift.AnyClass 35 | { 36 | return NSNumber.self 37 | } 38 | 39 | @objc public override func transformedValue( _ value: Any? ) -> Any? 40 | { 41 | guard let array = value as? NSArray else 42 | { 43 | return NSNumber( booleanLiteral: false ) 44 | } 45 | 46 | return NSNumber( booleanLiteral: ( array.count > 0 ) ? true : false ) 47 | } 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /Console/Classes/Transformers/NumberToStringValueTransformer.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Foundation 26 | 27 | @objc class NumberToStringValueTransformer: ValueTransformer 28 | { 29 | @objc public override static func allowsReverseTransformation() -> Bool 30 | { 31 | return true 32 | } 33 | 34 | @objc public override static func transformedValueClass() -> Swift.AnyClass 35 | { 36 | return NSString.self 37 | } 38 | 39 | @objc public override func transformedValue( _ value: Any? ) -> Any? 40 | { 41 | guard let number = value as? NSNumber else 42 | { 43 | return "" as NSString 44 | } 45 | 46 | return number.stringValue 47 | } 48 | 49 | @objc public override func reverseTransformedValue( _ value: Any? ) -> Any? 50 | { 51 | guard let string = value as? NSString else 52 | { 53 | return NSNumber( value: 0 ) 54 | } 55 | 56 | return NSNumber( value: string.doubleValue ) 57 | } 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Console/Defaults.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fontName 6 | Menlo 7 | fontSize 8 | 12 9 | backgroundColorR 10 | 1 11 | backgroundColorG 12 | 1 13 | backgroundColorB 14 | 1 15 | foregroundColorR 16 | 0 17 | foregroundColorG 18 | 0 19 | foregroundColorB 20 | 0 21 | 22 | 23 | -------------------------------------------------------------------------------- /Console/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | Console.icns 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.3.1 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 98 25 | LSApplicationCategoryType 26 | public.app-category.developer-tools 27 | LSMinimumSystemVersion 28 | $(MACOSX_DEPLOYMENT_TARGET) 29 | NSHumanReadableCopyright 30 | Copyright © 2016 XS-Labs. All rights reserved. 31 | NSMainNibFile 32 | MainMenu 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /Console/UI/Base.lproj/Console.AboutWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Console/UI/Base.lproj/Console.PreferencesWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /Console/UI/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | Default 547 | 548 | 549 | 550 | 551 | 552 | 553 | Left to Right 554 | 555 | 556 | 557 | 558 | 559 | 560 | Right to Left 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | Default 572 | 573 | 574 | 575 | 576 | 577 | 578 | Left to Right 579 | 580 | 581 | 582 | 583 | 584 | 585 | Right to Left 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | -------------------------------------------------------------------------------- /Console/UI/Images/Console.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Console/bb92dce1a6aba41c0f0f54e453870e9dd827c3c7/Console/UI/Images/Console.icns -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Console 2 | ======= 3 | 4 | [![Build Status](https://img.shields.io/travis/macmade/Console.svg?branch=master&style=flat)](https://travis-ci.org/macmade/Console) 5 | [![Issues](http://img.shields.io/github/issues/macmade/Console.svg?style=flat)](https://github.com/macmade/Console/issues) 6 | ![Status](https://img.shields.io/badge/status-active-brightgreen.svg?style=flat) 7 | ![License](https://img.shields.io/badge/license-mit-brightgreen.svg?style=flat) 8 | [![Contact](https://img.shields.io/badge/contact-@macmade-blue.svg?style=flat)](https://twitter.com/macmade) 9 | [![Donate-Patreon](https://img.shields.io/badge/donate-patreon-yellow.svg?style=flat)](https://patreon.com/macmade) 10 | [![Donate-Gratipay](https://img.shields.io/badge/donate-gratipay-yellow.svg?style=flat)](https://www.gratipay.com/macmade) 11 | [![Donate-Paypal](https://img.shields.io/badge/donate-paypal-yellow.svg?style=flat)](https://paypal.me/xslabs) 12 | 13 | ### About 14 | 15 | A replacement for the default macOS console application, which I find completely broken since macOS 10.12 Sierra. 16 | 17 | ![Main Window](Assets/MainWindow.png "Main Window") 18 | 19 | License 20 | ------- 21 | 22 | Project is released under the terms of the MIT License. 23 | 24 | Repository Infos 25 | ---------------- 26 | 27 | Owner: Jean-David Gadina - XS-Labs 28 | Web: www.xs-labs.com 29 | Blog: www.noxeos.com 30 | Twitter: @macmade 31 | GitHub: github.com/macmade 32 | LinkedIn: ch.linkedin.com/in/macmade/ 33 | StackOverflow: stackoverflow.com/users/182676/macmade 34 | -------------------------------------------------------------------------------- /Scripts/ccache-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This setting should be an absolute path to a directory. ccache then 4 | # rewrites absolute paths into relative paths before computing the hash that 5 | # identifies the compilation, but only for paths under the specified 6 | # directory. If set to the empty string (which is the default), no rewriting 7 | # is done. See also the discussion under COMPILING IN DIFFERENT DIRECTORIES. 8 | # If using GCC or newer versions of Clang, you might want to look into the 9 | # -fdebug-prefix-map=old=new option for relocating debug info to a common 10 | # prefix (mapping prefix with old=new). 11 | export CCACHE_BASEDIR= 12 | 13 | # This setting specifies where ccache will keep its cached compiler outputs. 14 | # It will only take effect if set in the system-wide configuration file or 15 | # as an environment variable. The default is $HOME/.ccache. 16 | export CCACHE_DIR=$HOME/.ccache 17 | 18 | # This setting allows you to choose the number of directory levels in the 19 | # cache directory. The default is 2. The minimum is 1 and the maximum is 8. 20 | export CCACHE_NLEVELS=2 21 | 22 | # This setting can be used to force the name of the compiler to use. If set 23 | # to the empty string (which is the default), ccache works it out from the 24 | # command line. 25 | export CCACHE_CC= 26 | 27 | # By default, ccache includes the modification time (“mtime”) and size of 28 | # the compiler in the hash to ensure that results retrieved from the cache 29 | # are accurate. This setting can be used to select another strategy. 30 | export CCACHE_COMPILERCHECK=mtime 31 | 32 | # If true, ccache will compress object files and other compiler output it 33 | # puts in the cache. However, this setting has no effect on how files are 34 | # retrieved from the cache; compressed and uncompressed results will still 35 | # be usable regardless of this setting. The default is false. 36 | # export CACHE_COMPRESS 37 | export CCACHE_NOCOMPRESS=1 38 | 39 | # This setting determines the level at which ccache will compress object 40 | # files. It only has effect if compression is enabled. The value defaults 41 | # to 6, and must be no lower than 1 (fastest, worst compression) and no 42 | # higher than 9 (slowest, best compression). 43 | export CCACHE_COMPRESSLEVEL=6 44 | 45 | # This setting can be used to force a certain extension for the intermediate 46 | # preprocessed file. The default is to automatically determine the extension 47 | # to use for intermediate preprocessor files based on the type of file being 48 | # compiled, but that sometimes doesn’t work. For example, when using the 49 | # “aCC” compiler on HP-UX, set the cpp extension to i. 50 | export CCACHE_EXTENSION= 51 | 52 | # If true, the direct mode will be used. The default is true. 53 | export CCACHE_DIRECT 54 | # export CCACHE_NODIRECT 55 | 56 | # When true, ccache will just call the real compiler, bypassing the cache 57 | # completely. The default is false. 58 | #export CCACHE_DISABLE 59 | export CCACHE_NODISABLE=1 60 | 61 | # This setting is a list of paths to files that ccache will include in the 62 | # the hash sum that identifies the build. The list separator is semicolon 63 | # on Windows systems and colon on other systems. 64 | export CCACHE_EXTRAFILES= 65 | 66 | # If true, ccache will attempt to use hard links from the cache directory 67 | # when creating the compiler output rather than using a file copy. Using 68 | # hard links may be slightly faster in some situations, but can confuse 69 | # programs like “make” that rely on modification times. Another thing to 70 | # keep in mind is that if the resulting object file is modified in any way, 71 | # this corrupts the cached object file as well. Hard links are never made 72 | # for compressed cache files. This means that you should not enable 73 | # compression if you want to use hard links. The default is false. 74 | export CCACHE_HARDLINK=1 75 | # export CCACHE_NOHARDLINK 76 | 77 | # If true (which is the default), ccache will include the current working 78 | # directory (CWD) in the hash that is used to distinguish two compilations 79 | # when generating debug info (compiler option -g with variations). 80 | # Exception: The CWD will not be included in the hash if base_dir is set 81 | # (and matches the CWD) and the compiler option -fdebug-prefix-map is used. 82 | # The reason for including the CWD in the hash by default is to prevent a 83 | # problem with the storage of the current working directory in the debug 84 | # info of an object file, which can lead ccache to return a cached object 85 | # file that has the working directory in the debug info set incorrectly. 86 | # You can disable this setting to get cache hits when compiling the same 87 | # source code in different directories if you don’t mind that CWD in the 88 | # debug info might be incorrect. 89 | export CCACHE_HASHDIR=1 90 | # export CCACHE_NOHASHDIR 91 | 92 | # This setting is a list of paths to files (or directories with headers) 93 | # that ccache will not include in the manifest list that makes up the direct 94 | # mode. Note that this can cause stale cache hits if those headers do indeed 95 | # change. The list separator is semicolon on Windows systems and colon on 96 | # other systems. 97 | export CCACHE_IGNOREHEADERS= 98 | 99 | # If true, ccache will not discard the comments before hashing preprocessor 100 | # output. This can be used to check documentation with -Wdocumentation. 101 | export CCACHE_COMMENTS=1 102 | # export CCACHE_NOCOMMENTS 103 | 104 | # Sets the limit when cleaning up. Files are deleted (in LRU order) until 105 | # the levels are below the limit. The default is 0.8 (= 80%). 106 | export CCACHE_LIMIT_MULTIPLE=0.8 107 | 108 | # If set to a file path, ccache will write information on what it is doing 109 | # to the specified file. This is useful for tracking down problems. 110 | export CCACHE_LOGFILE= 111 | 112 | # This option specifies the maximum number of files to keep in the cache. 113 | # Use 0 for no limit (which is the default). 114 | export CCACHE_MAXFILES=0 115 | 116 | # This option specifies the maximum size of the cache. Use 0 for no limit. 117 | # The default value is 5G. Available suffixes: k, M, G, T (decimal) and Ki, 118 | # Mi, Gi, Ti (binary). The default suffix is "G". 119 | export CCACHE_MAXSIZE=10G 120 | 121 | # If set, ccache will search directories in this list when looking for the 122 | # real compiler. The list separator is semicolon on Windows systems and 123 | # colon on other systems. If not set, ccache will look for the first 124 | # executable matching the compiler name in the normal PATH that isn’t a 125 | # symbolic link to ccache itself. 126 | export CCACHE_PATH= 127 | 128 | # This option adds a list of prefixes (separated by space) to the command 129 | # line that ccache uses when invoking the compiler. 130 | export CCACHE_PREFIX= 131 | 132 | # This option adds a list of prefixes (separated by space) to the command 133 | # line that ccache uses when invoking the preprocessor. 134 | export CCACHE_PREFIX_CPP= 135 | 136 | # If true, ccache will attempt to use existing cached object files, but it 137 | # will not to try to add anything new to the cache. If you are using this 138 | # because your ccache directory is read-only, then you need to set 139 | # temporary_dir as otherwise ccache will fail to create temporary files. 140 | # export CCACHE_READONLY 141 | export CCACHE_NOREADONLY=1 142 | 143 | # Just like read_only except that ccache will only try to retrieve results 144 | # from the cache using the direct mode, not the preprocessor mode. See 145 | # documentation for read_only regarding using a read-only ccache directory. 146 | # export CCACHE_READONLY_DIRECT 147 | export CCACHE_NOREADONLY_DIRECT=1 148 | 149 | # If true, ccache will not use any previously stored result. New results 150 | # will still be cached, possibly overwriting any pre-existing results. 151 | # export CCACHE_RECACHE 152 | export CCACHE_NORECACHE=1 153 | 154 | # If true, ccache will first run the preprocessor to preprocess the source 155 | # code (see THE PREPROCESSOR MODE) and then on a cache miss run the compiler 156 | # on the source code to get hold of the object file. This is the default. 157 | # If false, ccache will first run preprocessor to preprocess the source code 158 | # and then on a cache miss run the compiler on the preprocessed source code 159 | # instead of the original source code. This makes cache misses slightly 160 | # faster since the source code only has to be preprocessed once. The 161 | # downside is that some compilers won’t produce the same result (for 162 | # instance diagnostics warnings) when compiling preprocessed source code. 163 | export CCACHE_CPP2=1 164 | # export CCACHE_NOCPP2 165 | 166 | # By default, ccache tries to give as few false cache hits as possible. 167 | # However, in certain situations it’s possible that you know things that 168 | # ccache can’t take for granted. This setting makes it possible to tell 169 | # ccache to relax some checks in order to increase the hit rate. The value 170 | # should be a comma-separated string with options. 171 | export CCACHE_SLOPPINESS=file_macro,time_macros,include_file_mtime,include_file_ctime,file_stat_matches 172 | 173 | # If true, ccache will update the statistics counters on each compilation. 174 | # The default is true. 175 | export CCACHE_STATS=1 176 | # export CCACHE_NOSTATS 177 | 178 | # This setting specifies where ccache will put temporary files. 179 | # The default is /tmp. 180 | export CCACHE_TEMPDIR=$CCACHE_DIR/tmp 181 | 182 | # This setting specifies the umask for ccache and all child processes 183 | # (such as the compiler). This is mostly useful when you wish to share your 184 | # cache with other users. Note that this also affects the file permissions 185 | # set on the object files created from your compilations. 186 | export CCACHE_UMASK=002 187 | 188 | # If true, ccache will use a C/C++ unifier when hashing the preprocessor 189 | # output if the -g option is not used. The unifier is slower than a normal 190 | # hash, so setting this environment variable loses a little bit of speed, 191 | # but it means that ccache can take advantage of not recompiling when the 192 | # changes to the source code consist of reformatting only. Note that 193 | # enabling the unifier changes the hash, so cached compilations produced 194 | # when the unifier is enabled cannot be reused when the unifier is disabled, 195 | # and vice versa. Enabling the unifier may result in incorrect line number 196 | # information in compiler warning messages and expansions of the __LINE__ 197 | # macro. Also note that enabling the unifier implies turning off the 198 | # direct mode. 199 | # export CCACHE_UNIFY 200 | export CCACHE_NOUNIFY=1 201 | -------------------------------------------------------------------------------- /Scripts/ccache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | source $(dirname $0)/ccache-config.sh 4 | 5 | if [ -z "$DEVELOPER_DIR" ]; then 6 | 7 | CLANG=/usr/bin/clang 8 | 9 | else 10 | 11 | CLANG=$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang 12 | 13 | fi 14 | 15 | if type -p ccache > /dev/null 2>&1; then 16 | 17 | exec ccache $CLANG "$@" 18 | 19 | else 20 | 21 | exec $CLANG "$@" 22 | 23 | fi 24 | --------------------------------------------------------------------------------