489 lines
20 KiB
MQL5
489 lines
20 KiB
MQL5
|
#ifndef LIB_DBG_DEBUG_PRINTF_MQH_INCLUDED
|
||
|
#define LIB_DBG_DEBUG_PRINTF_MQH_INCLUDED
|
||
|
#property version "5.10"
|
||
|
/**********************************************************************************
|
||
|
* Copyright (C) 2020 Dominik Egert <info@freie-netze.de>
|
||
|
*
|
||
|
* This file is the debugger printf replacement 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
|
||
|
|
||
|
//#define _DBG_CODE_LOCATION_STRING file, function, line
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// Debug printf composer
|
||
|
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_trace_begin)(const string file, const string function, const int line, ulong& call_counter)
|
||
|
{
|
||
|
// Update lib_debug state
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = LIB_DBG_API_CALL_TRACE_DEFAULT;
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth)++;
|
||
|
call_counter++;
|
||
|
|
||
|
// Construct trace details
|
||
|
string trace_details = StringFormat(DBG_OUTPUT_TRACE_BEGIN_FORMAT, LIB_DBG_NAMESPACE(dbg_lib, dbg_ChartID)(), LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth), function, call_counter);
|
||
|
|
||
|
// Print details
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("\r\n%"+ IntegerToString(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s", "", StringFormat("%s" + DBG_OUTPUT_STRING, DBG_OUTPUT_PREFIX, DBG_TRACE_BEGIN_MSG_TXT, DBG_CODE_LOCATION_STRING, trace_details));
|
||
|
};
|
||
|
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_trace_end)(const string file, const string function, const int line, const string value_msg = NULL)
|
||
|
{
|
||
|
// Return value
|
||
|
string msg = NULL;
|
||
|
if(value_msg != NULL)
|
||
|
{
|
||
|
int split_1 = StringFind(value_msg, "(");
|
||
|
msg = StringSubstr(value_msg, 0, split_1) + ">>> return" + StringSubstr(value_msg, split_1);
|
||
|
}
|
||
|
else
|
||
|
{ msg = ">>> return(void)"; }
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, file, function, line, msg, "=", DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER - 10));
|
||
|
|
||
|
// Close trace
|
||
|
string trace_details = StringFormat(DBG_OUTPUT_TRACE_END_FORMAT, LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth), function);
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s\r\n", LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_TRACE_END_MSG_TXT, file, function, line, trace_details));
|
||
|
|
||
|
// Check uninit state
|
||
|
if(_StopFlag)
|
||
|
{ LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, file, function, line, LIB_DBG_NAMESPACE(dbg_lib, var_out)(__DBG_STRINGIFY_MACRO((_StopFlag)), _StopFlag), "=", DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER)); }
|
||
|
msg = LIB_DBG_NAMESPACE(dbg_lib, uninit_text)(function, -1);
|
||
|
if(msg != NULL)
|
||
|
{ LIB_DBG_NAMESPACE(dbg_lib, dbg_printf)("%s", LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(DBG_OUTPUT_PREFIX, file, function, line, msg)); }
|
||
|
|
||
|
// Update lib_debug state
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, trace_api_calls) = false;
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth)--;
|
||
|
DBG_TRACE_EXEC_DELAY;
|
||
|
};
|
||
|
|
||
|
const string LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_context_msg)(const string prefix, const string file, const string function, const int line, const string _msg, const string msg2_token = NULL, const int msg2_column = NULL)
|
||
|
{
|
||
|
// Prevalidate input
|
||
|
if(_msg == NULL)
|
||
|
{ return(NULL); }
|
||
|
|
||
|
// Check for multiline output
|
||
|
string result = NULL;
|
||
|
string ml_out[];
|
||
|
string msg = NULL;
|
||
|
int lines = StringSplit(_msg, 0x0A, ml_out);
|
||
|
|
||
|
// Rejoin string containing linebreaks
|
||
|
for(int out_msgs = 0; (out_msgs < lines); out_msgs++)
|
||
|
{
|
||
|
int is_str = StringFind(ml_out[out_msgs], "[str]");
|
||
|
if( (is_str > 0)
|
||
|
&& (StringFind(ml_out[0], "'") > is_str)
|
||
|
&& (StringFind(ml_out[0], "(length: ") < 0) )
|
||
|
{
|
||
|
for(int cnt = 1; (cnt < lines) && (StringFind(ml_out[out_msgs], "(length: ") < 0); cnt++)
|
||
|
{
|
||
|
ml_out[out_msgs] += "\n" + ml_out[cnt];
|
||
|
ml_out[cnt] = NULL;
|
||
|
}
|
||
|
int ptr = NULL;
|
||
|
for(int cnt = NULL; (cnt < lines); cnt++)
|
||
|
{
|
||
|
ml_out[ptr] = ml_out[cnt];
|
||
|
ptr += (ml_out[cnt] != NULL);
|
||
|
}
|
||
|
lines = ptr + (ml_out[ptr] != NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// First line
|
||
|
string insert = (msg2_token == NULL) ? ml_out[0] : "%s";
|
||
|
string pre_out = StringFormat("%"+ IntegerToString(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s" + DBG_OUTPUT_STRING, "", DBG_OUTPUT_PREFIX, prefix, DBG_CODE_LOCATION_STRING, insert);
|
||
|
|
||
|
string out = "";
|
||
|
if( (msg2_token != NULL)
|
||
|
&& (msg2_column != NULL) )
|
||
|
{
|
||
|
string substr = StringSubstr(ml_out[0], 0, StringFind(ml_out[0], msg2_token));
|
||
|
#ifdef __MQL5__
|
||
|
StringTrimRight(substr);
|
||
|
StringTrimLeft(substr);
|
||
|
|
||
|
#else
|
||
|
substr = StringTrimRight(substr);
|
||
|
substr = StringTrimLeft(substr);
|
||
|
|
||
|
#endif
|
||
|
out = StringFormat(pre_out, substr + "%s ");
|
||
|
int len = StringLen(out);
|
||
|
out = StringFormat(out, "%" + IntegerToString(msg2_column - len) + "s%s");
|
||
|
substr = StringSubstr(ml_out[0], StringFind(ml_out[0], msg2_token));
|
||
|
#ifdef __MQL5__
|
||
|
StringTrimRight(substr);
|
||
|
StringTrimLeft(substr);
|
||
|
|
||
|
#else
|
||
|
substr = StringTrimRight(substr);
|
||
|
substr = StringTrimLeft(substr);
|
||
|
|
||
|
#endif
|
||
|
result += StringFormat(out + "\n", "", substr);
|
||
|
}
|
||
|
else
|
||
|
{ result += pre_out + "\n"; }
|
||
|
|
||
|
|
||
|
// Consecutive lines
|
||
|
bool mtx_hdr = false;
|
||
|
bool mtx_out = (lines > 2) && (StringFind(result, "[mtx]") > -1);
|
||
|
bool new_set = (lines < 2) || (StringLen(ml_out[2]) < 2);
|
||
|
int pos = -1;
|
||
|
string substr = NULL;
|
||
|
string _shift = StringFormat("%"+ IntegerToString(MathMax(0, StringFind(result, StringSubstr(ml_out[0], 0, MathMin(5, StringLen(ml_out[0])))))) +"s", " ");
|
||
|
|
||
|
// Clearings for matrix output
|
||
|
if(mtx_out)
|
||
|
{
|
||
|
StringReplace(result, "=", "");
|
||
|
StringReplace(result, "}", "");
|
||
|
}
|
||
|
|
||
|
// Process each line
|
||
|
for(int cnt = 1; (cnt < lines); cnt++)
|
||
|
{
|
||
|
msg = ml_out[cnt];
|
||
|
if(StringLen(msg) < 2)
|
||
|
{
|
||
|
new_set = true;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Add new set marker
|
||
|
pre_out = StringFormat("%"+ IntegerToString(LIB_DBG_NAMESPACE(dbg_lib, trace_call_depth) * 2) +"s%s", "", insert);
|
||
|
out = "";
|
||
|
|
||
|
if( (msg2_token != NULL)
|
||
|
&& (msg2_column != NULL) )
|
||
|
{
|
||
|
substr = StringSubstr(msg, 0, StringFind(msg, msg2_token));
|
||
|
mtx_hdr = ((StringFind(msg, "][") > -1) && (StringFind(msg, "{") == -1));
|
||
|
if(mtx_hdr)
|
||
|
{ substr = StringSubstr(substr, 1); }
|
||
|
else
|
||
|
#ifdef __MQL5__
|
||
|
{ StringTrimLeft(substr); }
|
||
|
StringTrimRight(substr);
|
||
|
#else
|
||
|
{ substr = StringTrimLeft(substr); }
|
||
|
substr = StringTrimRight(substr);
|
||
|
#endif
|
||
|
out = StringFormat(pre_out, substr + "%s ");
|
||
|
pos = StringLen(out);
|
||
|
out = StringFormat(out, "%" + IntegerToString(msg2_column - pos - StringLen(_shift) - ((new_set) ? 2 : 0)) + "s%s");
|
||
|
substr = StringSubstr(msg, StringFind(msg, msg2_token));
|
||
|
#ifdef __MQL5__
|
||
|
StringTrimRight(substr);
|
||
|
StringTrimLeft(substr);
|
||
|
|
||
|
#else
|
||
|
substr = StringTrimRight(substr);
|
||
|
substr = StringTrimLeft(substr);
|
||
|
|
||
|
#endif
|
||
|
out = StringFormat("%s" + out, _shift, "", (StringLen(substr) < 2) ? "" : substr);
|
||
|
|
||
|
#ifdef __MQL5__
|
||
|
StringTrimRight(out);
|
||
|
|
||
|
#else
|
||
|
out = StringTrimRight(out);
|
||
|
|
||
|
#endif
|
||
|
result += out + "\n";
|
||
|
}
|
||
|
else
|
||
|
{ result += pre_out + "\n"; }
|
||
|
|
||
|
// Trace new set state
|
||
|
new_set = (new_set) ? false : new_set;
|
||
|
}
|
||
|
return(StringSubstr(result, 0, StringLen(result) - 1));
|
||
|
};
|
||
|
|
||
|
|
||
|
// Self destructing file handle
|
||
|
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
struct __dbg_file_handle
|
||
|
{
|
||
|
int obj;
|
||
|
__dbg_file_handle() : obj(INVALID_HANDLE) { obj = FileOpen(DBG_LOG_FILENAME, FILE_COMMON | FILE_TXT | FILE_ANSI | FILE_WRITE | FILE_SHARE_READ, CP_ACP); };
|
||
|
~__dbg_file_handle() { if(obj != INVALID_HANDLE) { FileClose(obj); } }
|
||
|
} __dbg_f_h;
|
||
|
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_print_to_file)(const string out)
|
||
|
{ FileWriteString(__dbg_f_h.obj, out + "\r\n", StringLen(out)); FileFlush(__dbg_f_h.obj); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Debug get true system time
|
||
|
|
||
|
const datetime LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_true_system_time)()
|
||
|
{
|
||
|
if(FileIsExist("time.tmp", FILE_COMMON))
|
||
|
{ FileDelete("time.tmp", FILE_COMMON); }
|
||
|
const int f_h = FileOpen("time.tmp", FILE_COMMON | FILE_WRITE, CP_ACP);
|
||
|
const datetime tm = (f_h != INVALID_HANDLE) ? (datetime)FileGetInteger(f_h, FILE_CREATE_DATE) : LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeCurrent)();
|
||
|
FileClose(f_h);
|
||
|
FileDelete("time.tmp", FILE_COMMON);
|
||
|
return(tm);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Debug printf functions
|
||
|
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(string p1)
|
||
|
{
|
||
|
string ml_out[];
|
||
|
const int lines = StringSplit(p1, 0x0A, ml_out);
|
||
|
|
||
|
for(int cnt = NULL; (cnt < lines); cnt++)
|
||
|
{ printf("%s", ml_out[cnt]); }
|
||
|
}
|
||
|
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(p1);
|
||
|
|
||
|
#endif
|
||
|
#ifndef LIB_DBG_NO_JOURNAL
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf("%s", p1); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(p1); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2));
|
||
|
|
||
|
#endif
|
||
|
#ifndef LIB_DBG_NO_JOURNAL
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3));
|
||
|
|
||
|
#endif
|
||
|
#ifndef LIB_DBG_NO_JOURNAL
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V, typename W>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4, const W p5)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4, p5));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4, p5); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4, p5)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V, typename W, typename X>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4, p5, p6));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4, p5, p6); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4, p5, p6)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V, typename W, typename X, typename Y>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6, const Y p7)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4, p5, p6, p7));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4, p5, p6, p7); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4, p5, p6, p7)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V, typename W, typename X, typename Y, typename Z>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6, const Y p7, const Z p8)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4, p5, p6, p7, p8); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename Z2>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6, const Y p7, const Z p8, const Z2 p9)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8, p9));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8, p9)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
template <typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename Z2, typename Z3>
|
||
|
void LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_printf)(const string p1, const T p2, const U p3, const V p4, const W p5, const X p6, const Y p7, const Z p8, const Z2 p9, const Z3 p10)
|
||
|
{
|
||
|
#ifdef LIB_DBG_LOG_TO_FILE
|
||
|
LIB_DBG_NAMESPACE(dbg_lib, dbg_print_to_file)(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10));
|
||
|
|
||
|
#endif
|
||
|
#ifndef DBG_NO_JOURNAL_OUTPUT
|
||
|
if((p1 != NULL) && (p1 != ""))
|
||
|
#ifdef __MQL5__
|
||
|
{ printf(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
|
||
|
|
||
|
#else
|
||
|
{ LIB_DBG_NAMESPACE_DEF(dbg_lib, dbg_mq4_ml_printf)(StringFormat(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); }
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef __MQL5__
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//
|
||
|
// END Debugging support
|
||
|
//*********************************************************************************************************************************************************/
|
||
|
#endif // LIB_DBG_DEBUG_PRINTF_MQH_INCLUDED
|