CallStack.swift (3313B)
1 // MIT License 2 // Copyright © 2018-2023 Marc Stibane 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 5 // and associated documentation files (the "Software"), to deal in the Software without restriction, 6 // including without limitation the rights to use, copy, modify, merge, publish, distribute, 7 // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in all copies or 11 // substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 16 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 // 19 import Foundation 20 21 struct CallStackItem { 22 #if DEBUG 23 let file: String 24 let function: String 25 #endif 26 let message: String 27 } 28 29 #if DEBUG 30 extension CallStackItem: Identifiable { 31 var id: String { file } 32 } 33 extension CallStackItem: Equatable { 34 static func == (lhs: CallStackItem, rhs: CallStackItem) -> Bool { 35 lhs.file == rhs.file 36 } 37 } 38 #endif 39 40 41 struct CallStack { 42 private var stack = [CallStackItem]() 43 func peek() -> CallStackItem? { stack.first } 44 func push(item: CallStackItem) -> CallStack { 45 return CallStack(stack: [item] + stack) 46 } 47 } 48 49 #if DEBUG 50 fileprivate func filePath2Name(_ file: String) -> String { 51 let filePath = NSString(string: file) 52 return filePath.lastPathComponent 53 } 54 #endif 55 56 extension CallStack { 57 #if DEBUG 58 init(_ message: String = EMPTYSTRING, 59 funcName: String = #function, 60 filePath: String = #file, 61 line: UInt = #line) { 62 let item = CallStackItem(file: filePath2Name(filePath) + ":\(line)", function: funcName, message: message) 63 self.stack = [item] 64 } 65 #else 66 init(_ message: String = EMPTYSTRING) { 67 let item = CallStackItem(message: message) 68 self.stack = [item] 69 } 70 #endif 71 #if DEBUG 72 public func push(_ message: String = EMPTYSTRING, 73 funcName: String = #function, 74 filePath: String = #file, 75 line: UInt = #line) -> CallStack { 76 let item = CallStackItem(file: filePath2Name(filePath) + ":\(line)", function: funcName, message: message) 77 return push(item: item) 78 } 79 #else 80 public func push(_ message: String = EMPTYSTRING) -> CallStack { 81 let item = CallStackItem(message: message) 82 return push(item: item) 83 } 84 #endif 85 public func print() -> String { 86 var result: String = EMPTYSTRING 87 for (item) in stack { 88 #if DEBUG 89 result += item.file + SPACE + item.function + "; " 90 #else 91 result += item.message + "; " 92 #endif 93 } 94 return result 95 } 96 } 97 98 //extension CallStack: Equatable { 99 // static func == (lhs: CallStack, rhs: CallStack) -> Bool { lhs.storage == rhs.storage } 100 //}