311 lines
32 KiB
MQL5
311 lines
32 KiB
MQL5
#ifndef LIB_DBG_DEBUG_FUNCTIONS_MQH_INCLUDED
|
|
#define LIB_DBG_DEBUG_FUNCTIONS_MQH_INCLUDED
|
|
#property version "5.10"
|
|
/**********************************************************************************
|
|
* Copyright (C) 2020 Dominik Egert <info@freie-netze.de>
|
|
*
|
|
* This file is the debugger functions library include file.
|
|
*
|
|
* Lisence applied: GPLv2
|
|
* https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
*
|
|
* Author Dominik Egert / Freie Netze UG.
|
|
**********************************************************************************
|
|
*
|
|
* Version: 5.10
|
|
* State: public
|
|
*
|
|
* File information
|
|
* ================
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************************************************/
|
|
// Begin Debugging support functions
|
|
//
|
|
|
|
|
|
// Overloaded functions
|
|
#ifndef LIB_DEBUG_NAMESPACE
|
|
#ifdef __MQL5__
|
|
namespace dbg_lib
|
|
{
|
|
|
|
#endif
|
|
|
|
// Internal debuging code variables
|
|
|
|
static ulong LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_session_id) = LIB_DBG_GETTICKCOUNT();
|
|
static int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_uninit_reason) = -1;
|
|
static int LIB_DBG_NAMESPACE_DEF(dbg_lib, trace_call_depth) = NULL;
|
|
|
|
|
|
// Auto en/disable api call tracing
|
|
|
|
static bool LIB_DBG_NAMESPACE_DEF(dbg_lib, trace_api_calls) = false;
|
|
|
|
|
|
// Debug file loader trace function
|
|
|
|
const bool LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_print_file_trace)(const string _file) { static int cnt = NULL; LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("Loaded file: %s, count: %i", _file, cnt + 1); cnt++; return(true); }
|
|
|
|
|
|
// Debug strip mql-api function stubs
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_extract_mqlfunction_name)(const string p_in) //{ string out = p_in; int pos = StringFind(out, "trace_call_details"); if(pos == -1) { return(p_in); } out = StringSubstr(out, pos + 18); pos = StringFind(out, ")"); string out_arr[]; if(StringSplit(StringSubstr(out, 0, pos), 0x2C, out_arr) != 5) { return(p_in); } out = StringSubstr(out, pos); out = StringSubstr(out, StringFind(out, out_arr[4])); out = StringSubstr(out, StringFind(out, "(")); return(StringFormat("(%s%s", out_arr[4], out)); }
|
|
{
|
|
string out = p_in;
|
|
int pos = StringFind(out, "trace_call_details");
|
|
if(pos == -1) { return(p_in); }
|
|
out = StringSubstr(out, pos + 18);
|
|
pos = StringFind(out, ")");
|
|
string out_arr[];
|
|
if(StringSplit(StringSubstr(out, 0, pos), 0x2C, out_arr) != 5) { return(p_in); }
|
|
out = StringSubstr(out, pos);
|
|
out = StringSubstr(out, StringFind(out, out_arr[4]));
|
|
out = StringSubstr(out, StringFind(out, "("));
|
|
pos = StringSplit(out_arr[4], 0x005F, out_arr);
|
|
return(StringFormat("(%s%s", out_arr[pos - 1], out));
|
|
}
|
|
|
|
|
|
|
|
// MQL macro function replacement protection
|
|
|
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_Alert)(const string p_in) { Alert(p_in); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T& p_in[]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T& p_in[][]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T& p_in[][][]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T& p_in[][][][]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T*& p_in[]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T*& p_in[][]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T*& p_in[][][]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArraySize)(T*& p_in[][][][]) { return(ArraySize(p_in)); }
|
|
template <typename T>
|
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ArrayPrint)(const T& p_in[], const int digits, const int start) { ArrayPrint(p_in, digits, "", start); }
|
|
const long LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ChartID)() { return(ChartID()); }
|
|
const ulong LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_GetMicrosecondCount)() { return(GetMicrosecondCount()); }
|
|
const ulong LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_GetTickCount)() { return(LIB_DBG_GETTICKCOUNT()); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ColorToString)(const color p_in, const bool color_name = false) { return(ColorToString(p_in, color_name)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_IntegerToString)(const long p_in) { return(IntegerToString(p_in)); }
|
|
const long LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_MQLInfoInteger)(const ENUM_MQL_INFO_INTEGER p_in) { return(MQLInfoInteger(p_in)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_MQLInfoString)(const ENUM_MQL_INFO_STRING p_in) { return(MQLInfoString(p_in)); }
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringLen)(const string p_in) { return(StringLen(p_in)); }
|
|
const datetime LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringToTime)(const string p_in) { return(StringToTime(p_in)); }
|
|
const long LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TerminalInfoInteger)(const ENUM_TERMINAL_INFO_INTEGER p_in) { return(TerminalInfoInteger(p_in)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TerminalInfoString)(const ENUM_TERMINAL_INFO_STRING p_in) { return(TerminalInfoString(p_in)); }
|
|
const datetime LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TimeCurrent)() { return(TimeCurrent()); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TimeToString)(const datetime val) { const bool ms = ((val / TimeLocal()) > 100); datetime _val = val / ((ms) ? 1000 : 1); return(StringFormat("%s%s", TimeToString(_val, TIME_DATE | TIME_SECONDS), (ms) ? StringFormat(".%03i", val%1000) : "")); }
|
|
const bool LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_TimeToStruct)(const datetime dtm, MqlDateTime& tm) { return(TimeToStruct(dtm, tm)); }
|
|
template <typename T>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2) { return(StringFormat(p1, p2)); }
|
|
template <typename T, typename U>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2, const U p3) { return(StringFormat(p1, p2, p3)); }
|
|
template <typename T, typename U, typename V>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2, const U p3, const V p4) { return(StringFormat(p1, p2, p3, p4)); }
|
|
template <typename T, typename U, typename V, typename W>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2, const U p3, const V p4, const W p5) { return(StringFormat(p1, p2, p3, p4, p5)); }
|
|
template <typename T, typename U, typename V, typename W, typename X>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6) { return(StringFormat(p1, p2, p3, p4, p5, p6)); }
|
|
template <typename T, typename U, typename V, typename W, typename X, typename Y>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6, const Y p7) { return(StringFormat(p1, p2, p3, p4, p5, p6, p7)); }
|
|
template <typename T, typename U, typename V, typename W, typename X, typename Y, typename Z>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_StringFormat)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6, const Y p7, const Z p8) { return(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8)); }
|
|
|
|
|
|
// Unified string trim (MQL5/MQL4+)
|
|
|
|
#ifndef __MQL5__
|
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_string_trim)(string& p_in) { string out = StringTrimLeft(p_in); p_in = StringTrimRight(out); }
|
|
|
|
#else
|
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_string_trim)(string& p_in) { StringTrimLeft(p_in); StringTrimRight(p_in); }
|
|
|
|
#endif
|
|
|
|
|
|
// Consistent typename to string conversion
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_typename_to_string)(const string p_in, const bool enum_no_resolve = false) { static string last_call = NULL; static string tmp = NULL; if(last_call == p_in) { return(tmp); } else if((enum_no_resolve) && ((StringFind(p_in, " enum ") != -1) || (StringFind(p_in, " ENUM ") != -1))) { return("enum"); } last_call = p_in; tmp = " " + p_in + " "; StringReplace(tmp, " const ", " "); StringReplace(tmp, " class ", " "); StringReplace(tmp, " struct ", " "); StringReplace(tmp, " interface ", " "); StringReplace(tmp, " static ", " "); StringReplace(tmp, " ENUM ", " "); StringReplace(tmp, " enum ", " "); tmp = StringSubstr(tmp, NULL, StringFind(tmp, "[")); StringReplace(tmp, " *", "*"); LIB_DBG_NAMESPACE(dbg_lib, dbg_string_trim)(tmp); return(tmp); }
|
|
|
|
|
|
// Boolean return value print statement
|
|
|
|
const bool LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_eval_return)(const string file, const string func, const int line, const string msg, const bool retval, const bool _printf = true, const string cmnt = NULL)
|
|
{ if(_printf) { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)(LIB_DBG_NAMESPACE(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, file, func, line, (cmnt == NULL) ? StringFormat("(%s) => %s", msg, LIB_DBG_NAMESPACE(dbg_lib, dbg_to_string)(retval)) : StringFormat("(%s) => %s // %s", msg, LIB_DBG_NAMESPACE(dbg_lib, dbg_to_string)(retval), cmnt))); } return(retval); }
|
|
|
|
|
|
// Array index checking
|
|
|
|
template <typename T>
|
|
const T LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_eval_array_index)(const T& arr[], const int idx) { if(idx != -1) { return(arr[idx]); } return(NULL); }
|
|
const int LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_eval_array_index)(const int arr_size, const int idx, const string msg) { if((idx >= arr_size) || (idx < NULL)) { LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)(msg); return(-1); } return(idx); }
|
|
|
|
|
|
// To HEX-String helpers
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, flt_raw)(const float in, const bool hex = DBG_HEX_OUTPUT) { union conv { float f; uint u; } c; c.f = in; return((hex) ? StringFormat("0x%08X", c.u) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((ulong)c.u)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbl_raw)(const double in, const bool hex = DBG_HEX_OUTPUT) { union conv { double d; ulong u; } c; c.d = in; return((hex) ? StringFormat("0x%016llX", c.u) : LIB_DBG_NAMESPACE(dbg_lib, bits_out)((ulong)c.u)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_remove_leading_namespace)(const string in) { const int shift = (StringFind(in, "::", 0) == 0) ? 2 : 0; return((StringLen(in) > DBG_PRINT_VARNAME_MAX_LENGTH + shift) ? StringSubstr(in, shift, DBG_PRINT_VARNAME_MAX_LENGTH - 10 + shift) + "..." : StringSubstr(in, shift)); }
|
|
|
|
|
|
// Known basic types
|
|
|
|
const int typename_known(const string type) { return( (type == "bool") || (type == "float") || (type == "double") || (type == "datetime") || (type == "enum")
|
|
|| (type == "char") || (type == "short") || (type == "int") || (type == "long")
|
|
|| (type == "uchar") || (type == "ushort") ||(type == "uint") || (type == "ulong")
|
|
|| (type == "complex") || (type == "matrix") || (type == "matrixf") || (type == "matrixc")
|
|
|| (type == "vector") || (type == "vectorf") || (type == "vectorc")
|
|
|| (type == "string") ); };
|
|
|
|
|
|
// IEEE 754 compliant float to string conversion
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ieee754_to_string)(const float value) { string str = NULL; for(int sig = 6; sig <= 9; sig++) { if(value == float(str = StringFormat("%." + string(sig) + "g", value))) break; } return(str); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ieee754_to_string)(const double value) { string str = NULL; for(int sig = 14; sig <= 17; sig++) { if(value == double(str = StringFormat("%." + string(sig) + "g", value))) break; } return(str); }
|
|
|
|
|
|
// Value to string helpers
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const char val) { return(StringFormat("%hd", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const short val) { return(StringFormat("%hi", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const int val) { return(StringFormat("%i", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const long val) { return(StringFormat("%lli", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const uchar val) { return(StringFormat("%hu", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const ushort val) { return(StringFormat("%hu", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const uint val) { return(StringFormat("%u", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const ulong val) { return(StringFormat("%llu", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const string val) { return(StringFormat("%s", val)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const float val) { return(LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ieee754_to_string)(val)); }
|
|
#ifdef __MQL5__
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const double val) { return(string(val)); }
|
|
|
|
#else
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const double val) { return(LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_ieee754_to_string)(val)); }
|
|
|
|
#endif
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const datetime val) { return(TimeToString(val)); } //{ return(StringFormat("%s", TimeToString(val))); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const color val) { return(ColorToString(val, true)); } //{ return(StringFormat("%s", ColorToString(val, true))); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const bool val) { return(StringFormat("%s", val ? "true" : "false")); }
|
|
|
|
#ifdef LIB_DBG_INCLUDE_COMPLEX_TYPE
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const complex val) { return(StringFormat("r:%g;i:%g", val.real, val.imag)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const matrix& val) { return(StringFormat("%s, line: %i", "Not implemented: " + __FILE__, __LINE__)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const vector& val) { return(StringFormat("%s, line: %i", "Not implemented: " + __FILE__, __LINE__)); }
|
|
|
|
#endif
|
|
template <typename T>
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_to_string)(const T val) { return(EnumToString(val)); } // { return(StringFormat("%s", EnumToString(val))); }
|
|
|
|
|
|
// Get day of week
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_day_of_week)(const datetime val) { MqlDateTime tm; LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToStruct)(val / (((val / TimeLocal()) > 100) ? 1000 : 1), tm); switch(tm.day_of_week) { case 0: return("Sunday"); case 1: return("Monday"); case 2: return("Tuesday"); case 3: return("Wednesday"); case 4: return("Thursday"); case 5: return("Friday"); case 6: return("Saturday"); } return(NULL); }
|
|
|
|
|
|
// Literal to bit string
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, bits_out)(const ulong val) { return(StringFormat("%s %s", LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uint)(val>>32)), LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uint)val))); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, bits_out)(const uint val) { return(StringFormat("%s %s", LIB_DBG_NAMESPACE(dbg_lib, bits_out)((ushort)(val>>16)), LIB_DBG_NAMESPACE(dbg_lib, bits_out)((ushort)val))); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, bits_out)(const ushort val) { return(StringFormat("%s %s", LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uchar)(val>>8)), LIB_DBG_NAMESPACE(dbg_lib, bits_out)((uchar)val))); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, bits_out)(const uchar val) { return(StringFormat("%s%s%s%s%s%s%s%s", ((((uchar)val)&0x80) > NULL) ? "1" : "0", ((((uchar)val)&0x40) > NULL) ? "1" : "0", ((((uchar)val)&0x20) > NULL) ? "1" : "0", ((((uchar)val)&0x10) > NULL) ? "1" : "0", ((((uchar)val)&0x08) > NULL) ? "1" : "0", ((((uchar)val)&0x04) > NULL) ? "1" : "0", ((((uchar)val)&0x02) > NULL)? "1" : "0", ((((uchar)val)&0x01) > NULL) ? "1" : "0")); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, bits_out)(const float val) { union __flt_uint { float f; uint u; } tmp; tmp.f = val; return(LIB_DBG_NAMESPACE(dbg_lib, bits_out)(tmp.u)); }
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, bits_out)(const double val) { union __flt_uint { double f; ulong u; } tmp; tmp.f = val; return(LIB_DBG_NAMESPACE(dbg_lib, bits_out)(tmp.u)); }
|
|
|
|
|
|
// Uninit code to string
|
|
|
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, uninit_text)(const string func_name, const int custom_uninit_reason = -1)
|
|
{
|
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) = (LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) == -1) && ((_UninitReason != NULL) || (_StopFlag && (func_name == "OnDeinit"))) ? _UninitReason : LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason);
|
|
if(LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) == -1)
|
|
{ return(NULL); }
|
|
switch((custom_uninit_reason == -1) ? LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason) : custom_uninit_reason)
|
|
{
|
|
// Terminal built-in reasons
|
|
case REASON_PROGRAM: return(StringFormat("(_UninitReason) %i = REASON_PROGRAM: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Expert Advisor terminated its operation by calling the ExpertRemove() function.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_REMOVE: return(StringFormat("(_UninitReason) %i = REASON_REMOVE: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Program has been deleted from the chart.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_RECOMPILE: return(StringFormat("(_UninitReason) %i = REASON_RECOMPILE: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Program has been recompiled.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_CHARTCHANGE: return(StringFormat("(_UninitReason) %i = REASON_CHARTCHANGE: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Symbol or chart period has been changed.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_CHARTCLOSE: return(StringFormat("(_UninitReason) %i = REASON_CHARTCLOSE: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Chart has been closed.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_PARAMETERS: return(StringFormat("(_UninitReason) %i = REASON_PARAMETERS: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Input parameters have been changed by a user.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_ACCOUNT: return(StringFormat("(_UninitReason) %i = REASON_ACCOUNT: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_TEMPLATE: return(StringFormat("(_UninitReason) %i = REASON_TEMPLATE: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "A new template has been applied.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_INITFAILED: return(StringFormat("(_UninitReason) %i = REASON_INITFAILED: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "This value means that OnInit() handler has returned a nonzero value.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
case REASON_CLOSE: return(StringFormat("(_UninitReason) %i = REASON_CLOSE: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Terminal has been closed.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
|
|
// MQLplus extended reasons
|
|
case REASON_MQLPLUS_EXPERT_KILL: return(StringFormat("(_UninitReason) %i = REASON_MQLPLUS_EXPERT_KILL: %s (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), "Program terminated its operation by calling the ExpertKill() function.", LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
|
|
// Unknown reasons
|
|
default: return(StringFormat("Unknown reason: %i (session id: %llu)", (int)LIB_DBG_NAMESPACE(dbg_lib, dbg_uninit_reason), LIB_DBG_NAMESPACE(dbg_lib, dbg_session_id)));
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
// Return function results
|
|
|
|
template <typename T>
|
|
T LIB_DBG_NAMESPACE_DEF(dbg_lib, return_function_result_wrapper)(const string file, const string function, const int line, const string val_name, const T value)
|
|
{
|
|
LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_trace_end)(file, function, line, LIB_DBG_NAMESPACE(dbg_lib, var_out)(val_name, value));
|
|
return(value);
|
|
};
|
|
|
|
|
|
// Return function object
|
|
|
|
template <typename T>
|
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, return_function_object_wrapper)(const string file, const string function, const int line, const string val_name, const T& value)
|
|
{
|
|
LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_trace_end)(file, function, line, LIB_DBG_NAMESPACE(dbg_lib, var_out)(val_name, value));
|
|
return;
|
|
};
|
|
|
|
|
|
// Software inherited brakepoints
|
|
|
|
const bool LIB_DBG_NAMESPACE_DEF(dbg_lib, BreakPoint)(const int _line_, const string _file_, const long _timestamp_ = NULL)
|
|
{
|
|
#ifndef DBG_DEBUGGER_OVERWRITE
|
|
if(IS_DEBUG_MODE)
|
|
{ printf("##### Breakpoint set at line: %i in file: %s.", _line_, _file_); return(true); }
|
|
else
|
|
#endif
|
|
if(_timestamp_ <= ((TimeCurrent() - (TimeCurrent() % PeriodSeconds())) * (_timestamp_ > NULL)))
|
|
{ printf("##### Breakpoint set at line: %i in file: %s, waiting %i seconds.", _line_, _file_, DBG_SOFT_BKP_TIMEOUT); return(true); }
|
|
return(false);
|
|
}
|
|
const bool LIB_DBG_NAMESPACE_DEF(dbg_lib, ExecTime)(const uint _seconds_)
|
|
{
|
|
static ulong exec_time_start = GetMicrosecondCount();
|
|
exec_time_start = (exec_time_start * (ulong)((_seconds_ > 0x00) & 0x01)) + (GetMicrosecondCount() * (ulong)((_seconds_ == NULL) & 0x01));
|
|
return(((long)exec_time_start) < ((long)(GetMicrosecondCount() - (_seconds_ * 1000000))));
|
|
}
|
|
|
|
|
|
#ifdef __MQL5__
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// END Debugging support
|
|
//*********************************************************************************************************************************************************/
|
|
#endif // LIB_DBG_DEBUG_FUNCTIONS_MQH_INCLUDED
|