; #FUNCTION# ==================================================================================================================== ; Name ..........: StackTrace ; Description ...: Stack trace functions ; Syntax ........: _trace(_traceStart("funcName"), funcName()) ; Parameters ....: ; Return values .: Return value of function parameter ; Author ........: cosote (July-2016) ; Modified ......: ; Remarks .......: This file is part of MyBot, previously known as ClashGameBot. Copyright 2015-2016 ; MyBot is distributed under the terms of the GNU GPL ; Related .......: ; Link ..........: https://github.com/MyBotRun/MyBot/wiki ; Example .......: _traceStart(@ScriptName) ; Start trace in main script ; _trace(_traceStart(), funcName()) ; trace function call funcName() ; _traceFunc("funcName") ; first line in funcName() to start trace ; Return _traceLine($Result) ; return value of traced function ; ConsoleWrite(_traceLog() & @CRLF) ; print current stack trace ; ConsoleWrite(_traceLog(True) & @CRLF) ; print current stack trace with timestamp ; =============================================================================================================================== #include-once #include If IsDeclared("debugStackTrace") <> 1 Then Global $debugStackTrace = 1 EndIf If IsDeclared("_trace") <> 1 Then Global $_trace[1][4] = [[0, 0, 0, 0]] EndIf Func _trace($def = False, $call = Default, $debugFlag = Default, $iLineNumer = @ScriptLineNumber) If $def = False Then _traceLine(Default, $iLineNumer) Return $call EndIf If $debugFlag = Default Then $debugFlag = $debugStackTrace If $debugFlag Then SetDebugLog("< " & _traceLog() & ($call = Default ? "" : ":" & $call), Default, True) $_trace[0][0] -= 1 Return $call EndFunc ;==>_trace Func _traceStart($sFuncName = Default, $debugFlag = Default, $iLineNumer = @ScriptLineNumber) If $_trace[0][0] > 0 Then _traceLine(Default, $iLineNumer) $_trace[0][0] += 1 Local $stIdx = $_trace[0][0] If $stIdx > $_trace[0][1] Then ReDim $_trace[$stIdx + 1][4] $_trace[0][1] = $stIdx EndIf $_trace[$stIdx][0] = $sFuncName $_trace[$stIdx][1] = 0 $_trace[$stIdx][2] = 0 $_trace[$stIdx][3] = @HOUR & ":" & @MIN & ":" & @SEC & "." & @MSEC If $sFuncName <> Default Then If $debugFlag = Default Then $debugFlag = $debugStackTrace If $debugFlag Then SetDebugLog("> " & _traceLog(), Default, True) EndIf Return True EndFunc ;==>_traceStart Func _traceLine($call = Default, $iLineNumer = @ScriptLineNumber) If $_trace[$_trace[0][0]][1] = 0 Then $_trace[$_trace[0][0]][1] = $iLineNumer $_trace[$_trace[0][0]][2] = $iLineNumer Else $_trace[$_trace[0][0]][2] = $iLineNumer EndIf Return $call EndFunc ;==>_traceLine Func _traceLogWidth($i = 1) If $i > $_trace[0][0] Then Return 0 Local $w1 = StringLen($_trace[$i][0]) + $i * 3 Local $w2 = _traceLogWidth($i + 1) Return ($w2 > $w1 ? $w2 : $w1) EndFunc ;==>_traceLogWIdth Func _traceLog($bDetailedLog = False, $i = 1, $w = _traceLogWidth()) If $i > $_trace[0][0] Then Return "" Local $iFuncLineNumber = $_trace[$i][2] - $_trace[$i][1] + 1 Local $sLineInfo = ($_trace[$i][2] > 0 ? "[" & $_trace[$i][2] & "/" & $iFuncLineNumber & "]" : "") If $bDetailedLog = False Then Return ($i > 1 ? ">" : "") & ($_trace[$i][0] <> Default ? $_trace[$i][0] : "") & $sLineInfo & _traceLog($bDetailedLog, $i + 1, $w) Else Local $sFuncTag = _StringRepeat(" ", $i * 3) & ($_trace[$i][0] <> Default ? $_trace[$i][0] : "") Return ($i > 1 ? @CRLF : "") & $_trace[$i][3] & $sFuncTag & _StringRepeat(" ", $w - StringLen($sFuncTag)) & " Line Number " & $sLineInfo & _traceLog($bDetailedLog, $i + 1, $w) EndIf EndFunc ;==>_traceLog Func _traceFunc($sFuncName, $debugFlag = Default, $iLineNumer = @ScriptLineNumber) $_trace[$_trace[0][0]][0] = $sFuncName If $debugFlag = Default Then $debugFlag = $debugStackTrace If $debugFlag Then SetDebugLog("> " & _traceLog(), Default, True) _traceLine(Default, $iLineNumer) EndFunc ;==>_traceFunc ; tests ;#cs Func SetDebugLog($string, $color = Default, $quiet = False) ConsoleWrite($string & @CRLF) EndFunc ;==>SetDebugLog Func test() _trace() _trace() _trace(_traceStart("ConsoleWrite"), ConsoleWrite("test" & @CRLF)) _trace(False, ConsoleWrite("test" & @CRLF)) _trace() ; test() ; cause stack overflow Return _trace(False, "test-return-value") ;_traceLine() ;_traceLine(ConsoleWrite("test" & @CRLF)) EndFunc ;==>test Func test2() _traceFunc("test2") _trace(_traceStart(), ConsoleWrite("test1" & @CRLF)) _trace(False, ConsoleWrite("test2" & @CRLF)) _traceLine() SetDebugLog(_traceLog(True)) ; test2() ; cause stack overflow Return _traceLine("test2-return-value") ;_traceLine() ;_traceLine(ConsoleWrite("test" & @CRLF)) EndFunc ;==>test2 _traceStart(@ScriptName) _trace(_traceStart("test"), test()) _trace(_traceStart(), test2()) ;#ce